aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2013-07-03 22:52:22 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2013-07-03 22:52:22 -0400
commit1286da8bc009cb2aee7f285e94623fc974c0c983 (patch)
tree51ec0a79c3de63fa809b831ae0cbb5b85e44482f
parent9e220385c4eb8b7e66174a60ea0e15b6b296f228 (diff)
parent1ba65ae4bdbd43265c51ee4c30ff21a48124b6d8 (diff)
Merge tag 'sound-3.11' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound
Pull sound updates from Takashi Iwai: "A relative calm release at this time with a flat diffstat. The only significant change in the ALSA core side is the support for more than 32 card instances, configurable via kconfig. Other than that, in both ASoC and other parts, mostly some improvements and fixes on the driver side. - hda: More quirks for ALC269-variants on Dell & co, VIA codec fixes - hda: Haswell HDMI audio fixes, runtime PM improvements - hda: Intel BayTrail support, ALC5505 DSP support - es1968: MediaForte M56VAP support - usb-audio: Improved support for Yamaha/Roland devices - usb-audio: M2Tech hiFace, Audio Advantage Micro II support - hdspm: wordclock fixes - ASoC: Pending fixes for WM8962 - ASoC: Cleanups and fixes for Blackfin, SGTL5000 and UX500 - ASoC: Generalisation of the Bluetooth and HDMI stub drivers - ASoC: SSM2518 and RT5640 codec drivers. - ASoC: Tegra CPUs with RT5640 machine driver - ASoC: AC'97 refactoring bug fixes - ASoC: ADAU1701 driver fixes - Clean up of *_set_drvdata() in a wide range of drivers" * tag 'sound-3.11' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound: (284 commits) ALSA: vmaster: Fix the regression of missing vmaster hook call ALSA: hda - Add Dell SSID to support Headset Mic recording ASoC: adau1701: remove control_data assignment ASoC: adau1701: more direct regmap usage ASoC: ac97: fixup multi-platform AC'97 module build failure ASoC: pxa2xx: fixup multi-platform AC'97 build failures ASoC: tegra20-ac97: Remove unused variable ASoC: tegra20-ac97: Remove duplicate error message ALSA: usb-audio: Add Audio Advantage Micro II ASoC: tas5086: fix Mid-Z implementation ASoC: tas5086: fix TAS5086_CLOCK_CONTROL register size ALSA: Replace the magic number 44 with const ALSA: hda - Fix the max length of control name in generic parser ALSA: hda - Guess what, it's two more Dell headset mic quirks ALSA: hda - Yet another Dell headset mic quirk ALSA: hda - Add support for ALC5505 DSP power-save mode ASoC: mfld: Remove unused variable ALSA: usb-audio: add quirks for Roland QUAD/OCTO-CAPTURE ALSA: usb-audio: claim autodetected PCM interfaces all at once ALSA: usb-audio: remove superfluous Roland quirks ...
-rw-r--r--Documentation/devicetree/bindings/mfd/arizona.txt62
-rw-r--r--Documentation/devicetree/bindings/sound/adi,adau1701.txt35
-rw-r--r--Documentation/devicetree/bindings/sound/imx-audio-wm8962.txt46
-rw-r--r--Documentation/devicetree/bindings/sound/mxs-saif.txt17
-rw-r--r--Documentation/devicetree/bindings/sound/nvidia,tegra-audio-rt5640.txt71
-rw-r--r--Documentation/devicetree/bindings/sound/rt5640.txt30
-rw-r--r--Documentation/devicetree/bindings/sound/sgtl5000.txt3
-rw-r--r--Documentation/devicetree/bindings/sound/spdif-receiver.txt10
-rw-r--r--Documentation/devicetree/bindings/sound/spdif-transmitter.txt10
-rw-r--r--Documentation/devicetree/bindings/sound/ssm2518.txt20
-rw-r--r--Documentation/devicetree/bindings/sound/ti,tas5086.txt11
-rw-r--r--Documentation/devicetree/bindings/sound/wm8962.txt23
-rw-r--r--Documentation/sound/alsa/HD-Audio-Models.txt40
-rw-r--r--arch/blackfin/mach-bf527/boards/ad7160eval.c12
-rw-r--r--arch/blackfin/mach-bf527/boards/ezkit.c32
-rw-r--r--arch/blackfin/mach-bf533/boards/ezkit.c12
-rw-r--r--arch/blackfin/mach-bf533/boards/stamp.c35
-rw-r--r--arch/blackfin/mach-bf537/boards/stamp.c30
-rw-r--r--arch/blackfin/mach-bf548/boards/ezkit.c28
-rw-r--r--arch/blackfin/mach-bf561/boards/ezkit.c14
-rw-r--r--arch/blackfin/mach-bf609/boards/ezkit.c2
-rw-r--r--drivers/mfd/arizona-core.c234
-rw-r--r--drivers/mfd/arizona-i2c.c10
-rw-r--r--drivers/mfd/arizona-spi.c10
-rw-r--r--drivers/mfd/arizona.h12
-rw-r--r--drivers/mfd/wm5102-tables.c9
-rw-r--r--drivers/mfd/wm5110-tables.c8
-rw-r--r--drivers/misc/atmel-ssc.c8
-rw-r--r--include/linux/mfd/arizona/core.h2
-rw-r--r--include/linux/mfd/arizona/pdata.h2
-rw-r--r--include/linux/mfd/arizona/registers.h47
-rw-r--r--include/linux/mfd/twl6040.h7
-rw-r--r--include/linux/mfd/wm8994/pdata.h5
-rw-r--r--include/linux/mfd/wm8994/registers.h8
-rw-r--r--include/linux/platform_data/ssm2518.h22
-rw-r--r--include/sound/control.h3
-rw-r--r--include/sound/core.h2
-rw-r--r--include/sound/pcm.h5
-rw-r--r--include/sound/rt5640.h22
-rw-r--r--include/sound/soc-dapm.h3
-rw-r--r--include/sound/soc.h4
-rw-r--r--include/uapi/sound/asound.h2
-rw-r--r--sound/arm/aaci.c2
-rw-r--r--sound/arm/pxa2xx-ac97.c1
-rw-r--r--sound/core/Kconfig9
-rw-r--r--sound/core/init.c55
-rw-r--r--sound/core/pcm_lib.c3
-rw-r--r--sound/core/vmaster.c65
-rw-r--r--sound/drivers/aloop.c1
-rw-r--r--sound/drivers/dummy.c1
-rw-r--r--sound/drivers/ml403-ac97cr.c1
-rw-r--r--sound/drivers/mpu401/mpu401.c1
-rw-r--r--sound/drivers/mtpav.c1
-rw-r--r--sound/drivers/pcsp/pcsp.c1
-rw-r--r--sound/drivers/serial-u16550.c1
-rw-r--r--sound/drivers/virmidi.c1
-rw-r--r--sound/drivers/vx/vx_core.c2
-rw-r--r--sound/firewire/amdtp.h1
-rw-r--r--sound/firewire/scs1x.c4
-rw-r--r--sound/i2c/other/ak4xxx-adda.c2
-rw-r--r--sound/isa/ad1848/ad1848.c1
-rw-r--r--sound/isa/adlib.c1
-rw-r--r--sound/isa/cmi8328.c1
-rw-r--r--sound/isa/cmi8330.c1
-rw-r--r--sound/isa/cs423x/cs4231.c1
-rw-r--r--sound/isa/cs423x/cs4236.c2
-rw-r--r--sound/isa/es1688/es1688.c1
-rw-r--r--sound/isa/es18xx.c2
-rw-r--r--sound/isa/galaxy/galaxy.c1
-rw-r--r--sound/isa/gus/gusclassic.c1
-rw-r--r--sound/isa/gus/gusextreme.c1
-rw-r--r--sound/isa/gus/gusmax.c1
-rw-r--r--sound/isa/gus/interwave.c1
-rw-r--r--sound/isa/msnd/msnd_pinnacle.c1
-rw-r--r--sound/isa/opl3sa2.c2
-rw-r--r--sound/isa/opti9xx/miro.c1
-rw-r--r--sound/isa/opti9xx/opti92x-ad1848.c1
-rw-r--r--sound/isa/sb/jazz16.c1
-rw-r--r--sound/isa/sb/sb16.c1
-rw-r--r--sound/isa/sb/sb8.c1
-rw-r--r--sound/isa/sc6000.c1
-rw-r--r--sound/isa/sscape.c1
-rw-r--r--sound/isa/wavefront/wavefront.c1
-rw-r--r--sound/oss/kahlua.c2
-rw-r--r--sound/parisc/harmony.c3
-rw-r--r--sound/pci/ac97/ac97_codec.c2
-rw-r--r--sound/pci/ad1889.c1
-rw-r--r--sound/pci/ali5451/ali5451.c1
-rw-r--r--sound/pci/als300.c1
-rw-r--r--sound/pci/als4000.c1
-rw-r--r--sound/pci/asihpi/asihpi.c2
-rw-r--r--sound/pci/asihpi/hpioctl.c1
-rw-r--r--sound/pci/atiixp.c1
-rw-r--r--sound/pci/atiixp_modem.c1
-rw-r--r--sound/pci/au88x0/au88x0.c1
-rw-r--r--sound/pci/aw2/aw2-alsa.c1
-rw-r--r--sound/pci/azt3328.c1
-rw-r--r--sound/pci/bt87x.c1
-rw-r--r--sound/pci/ca0106/ca0106_main.c1
-rw-r--r--sound/pci/cmipci.c1
-rw-r--r--sound/pci/cs4281.c3
-rw-r--r--sound/pci/cs46xx/cs46xx.c1
-rw-r--r--sound/pci/cs5530.c1
-rw-r--r--sound/pci/cs5535audio/cs5535audio.c1
-rw-r--r--sound/pci/ctxfi/xfi.c1
-rw-r--r--sound/pci/echoaudio/echoaudio.c1
-rw-r--r--sound/pci/emu10k1/emu10k1.c1
-rw-r--r--sound/pci/emu10k1/emu10k1x.c1
-rw-r--r--sound/pci/ens1370.c3
-rw-r--r--sound/pci/es1938.c1
-rw-r--r--sound/pci/es1968.c74
-rw-r--r--sound/pci/fm801.c1
-rw-r--r--sound/pci/hda/Kconfig1
-rw-r--r--sound/pci/hda/hda_codec.c67
-rw-r--r--sound/pci/hda/hda_codec.h11
-rw-r--r--sound/pci/hda/hda_generic.c59
-rw-r--r--sound/pci/hda/hda_generic.h4
-rw-r--r--sound/pci/hda/hda_intel.c53
-rw-r--r--sound/pci/hda/hda_jack.c2
-rw-r--r--sound/pci/hda/hda_local.h10
-rw-r--r--sound/pci/hda/hda_proc.c15
-rw-r--r--sound/pci/hda/patch_ca0132.c8
-rw-r--r--sound/pci/hda/patch_conexant.c2
-rw-r--r--sound/pci/hda/patch_hdmi.c128
-rw-r--r--sound/pci/hda/patch_realtek.c117
-rw-r--r--sound/pci/hda/patch_sigmatel.c14
-rw-r--r--sound/pci/hda/patch_via.c15
-rw-r--r--sound/pci/ice1712/ice1712.c1
-rw-r--r--sound/pci/ice1712/ice1724.c1
-rw-r--r--sound/pci/intel8x0.c1
-rw-r--r--sound/pci/intel8x0m.c1
-rw-r--r--sound/pci/korg1212/korg1212.c1
-rw-r--r--sound/pci/lola/lola.c1
-rw-r--r--sound/pci/lx6464es/lx6464es.c1
-rw-r--r--sound/pci/maestro3.c1
-rw-r--r--sound/pci/mixart/mixart.c1
-rw-r--r--sound/pci/nm256/nm256.c1
-rw-r--r--sound/pci/oxygen/oxygen_lib.c1
-rw-r--r--sound/pci/pcxhr/pcxhr.c1
-rw-r--r--sound/pci/riptide/riptide.c2
-rw-r--r--sound/pci/rme32.c1
-rw-r--r--sound/pci/rme96.c1
-rw-r--r--sound/pci/rme9652/hdsp.c1
-rw-r--r--sound/pci/rme9652/hdspm.c59
-rw-r--r--sound/pci/rme9652/rme9652.c1
-rw-r--r--sound/pci/sis7019.c1
-rw-r--r--sound/pci/sonicvibes.c1
-rw-r--r--sound/pci/trident/trident.c1
-rw-r--r--sound/pci/via82xx.c1
-rw-r--r--sound/pci/via82xx_modem.c1
-rw-r--r--sound/pci/vx222/vx222.c1
-rw-r--r--sound/pci/ymfpci/ymfpci.c1
-rw-r--r--sound/pci/ymfpci/ymfpci_main.c2
-rw-r--r--sound/ppc/powermac.c1
-rw-r--r--sound/sh/aica.c1
-rw-r--r--sound/sh/sh_dac_audio.c2
-rw-r--r--sound/soc/Kconfig1
-rw-r--r--sound/soc/Makefile1
-rw-r--r--sound/soc/atmel/sam9g20_wm8731.c9
-rw-r--r--sound/soc/au1x/ac97c.c21
-rw-r--r--sound/soc/au1x/psc-ac97.c33
-rw-r--r--sound/soc/blackfin/Kconfig47
-rw-r--r--sound/soc/blackfin/Makefile4
-rw-r--r--sound/soc/blackfin/bf5xx-ac97-pcm.c1
-rw-r--r--sound/soc/blackfin/bf5xx-ac97-pcm.h26
-rw-r--r--sound/soc/blackfin/bf5xx-ac97.c37
-rw-r--r--sound/soc/blackfin/bf5xx-ad1836.c19
-rw-r--r--sound/soc/blackfin/bf5xx-ad193x.c40
-rw-r--r--sound/soc/blackfin/bf5xx-ad1980.c1
-rw-r--r--sound/soc/blackfin/bf5xx-ad73311.c1
-rw-r--r--sound/soc/blackfin/bf5xx-i2s-pcm.c183
-rw-r--r--sound/soc/blackfin/bf5xx-i2s-pcm.h21
-rw-r--r--sound/soc/blackfin/bf5xx-i2s.c129
-rw-r--r--sound/soc/blackfin/bf5xx-sport.c10
-rw-r--r--sound/soc/blackfin/bf5xx-sport.h2
-rw-r--r--sound/soc/blackfin/bf5xx-ssm2602.c1
-rw-r--r--sound/soc/blackfin/bf5xx-tdm-pcm.c345
-rw-r--r--sound/soc/blackfin/bf5xx-tdm-pcm.h18
-rw-r--r--sound/soc/blackfin/bf5xx-tdm.c328
-rw-r--r--sound/soc/blackfin/bf5xx-tdm.h23
-rw-r--r--sound/soc/cirrus/Kconfig2
-rw-r--r--sound/soc/cirrus/ep93xx-ac97.c28
-rw-r--r--sound/soc/cirrus/ep93xx-i2s.c16
-rw-r--r--sound/soc/cirrus/ep93xx-pcm.c138
-rw-r--r--sound/soc/codecs/88pm860x-codec.c15
-rw-r--r--sound/soc/codecs/Kconfig18
-rw-r--r--sound/soc/codecs/Makefile14
-rw-r--r--sound/soc/codecs/ab8500-codec.c85
-rw-r--r--sound/soc/codecs/ab8500-codec.h42
-rw-r--r--sound/soc/codecs/ac97.c7
-rw-r--r--sound/soc/codecs/ad1980.c12
-rw-r--r--sound/soc/codecs/adau1701.c321
-rw-r--r--sound/soc/codecs/arizona.c7
-rw-r--r--sound/soc/codecs/arizona.h3
-rw-r--r--sound/soc/codecs/bt-sco.c (renamed from sound/soc/codecs/dfbmcs320.c)37
-rw-r--r--sound/soc/codecs/hdmi.c (renamed from sound/soc/codecs/omap-hdmi.c)26
-rw-r--r--sound/soc/codecs/jz4740.c2
-rw-r--r--sound/soc/codecs/max98090.c24
-rw-r--r--sound/soc/codecs/rt5640.c2128
-rw-r--r--sound/soc/codecs/rt5640.h2092
-rw-r--r--sound/soc/codecs/sgtl5000.c267
-rw-r--r--sound/soc/codecs/sgtl5000.h2
-rw-r--r--sound/soc/codecs/sn95031.c2
-rw-r--r--sound/soc/codecs/spdif_receiver.c10
-rw-r--r--sound/soc/codecs/spdif_transmitter.c (renamed from sound/soc/codecs/spdif_transciever.c)10
-rw-r--r--sound/soc/codecs/ssm2518.c856
-rw-r--r--sound/soc/codecs/ssm2518.h20
-rw-r--r--sound/soc/codecs/stac9766.c26
-rw-r--r--sound/soc/codecs/tas5086.c330
-rw-r--r--sound/soc/codecs/tlv320aic3x.c6
-rw-r--r--sound/soc/codecs/twl6040.c109
-rw-r--r--sound/soc/codecs/wm0010.c10
-rw-r--r--sound/soc/codecs/wm5102.c205
-rw-r--r--sound/soc/codecs/wm5110.c192
-rw-r--r--sound/soc/codecs/wm8400.c9
-rw-r--r--sound/soc/codecs/wm8903.c6
-rw-r--r--sound/soc/codecs/wm8904.c9
-rw-r--r--sound/soc/codecs/wm8962.c143
-rw-r--r--sound/soc/codecs/wm8990.c11
-rw-r--r--sound/soc/codecs/wm8991.h9
-rw-r--r--sound/soc/codecs/wm8994.c200
-rw-r--r--sound/soc/codecs/wm8994.h3
-rw-r--r--sound/soc/codecs/wm8995.h7
-rw-r--r--sound/soc/codecs/wm9705.c16
-rw-r--r--sound/soc/codecs/wm9712.c18
-rw-r--r--sound/soc/codecs/wm9713.c18
-rw-r--r--sound/soc/codecs/wm_adsp.c461
-rw-r--r--sound/soc/codecs/wm_adsp.h13
-rw-r--r--sound/soc/codecs/wm_hubs.c6
-rw-r--r--sound/soc/davinci/Kconfig10
-rw-r--r--sound/soc/davinci/Makefile2
-rw-r--r--sound/soc/davinci/davinci-mcasp.c4
-rw-r--r--sound/soc/davinci/davinci-sffsdr.c181
-rw-r--r--sound/soc/dwc/designware_i2s.c6
-rw-r--r--sound/soc/fsl/Kconfig17
-rw-r--r--sound/soc/fsl/Makefile13
-rw-r--r--sound/soc/fsl/eukrea-tlv320.c2
-rw-r--r--sound/soc/fsl/fsl_ssi.c13
-rw-r--r--sound/soc/fsl/imx-audmux.c8
-rw-r--r--sound/soc/fsl/imx-mc13783.c2
-rw-r--r--sound/soc/fsl/imx-pcm-dma.c2
-rw-r--r--sound/soc/fsl/imx-pcm-fiq.c92
-rw-r--r--sound/soc/fsl/imx-pcm.c145
-rw-r--r--sound/soc/fsl/imx-pcm.h10
-rw-r--r--sound/soc/fsl/imx-sgtl5000.c39
-rw-r--r--sound/soc/fsl/imx-ssi.c55
-rw-r--r--sound/soc/fsl/imx-ssi.h3
-rw-r--r--sound/soc/fsl/imx-wm8962.c323
-rw-r--r--sound/soc/fsl/mpc5200_psc_ac97.c10
-rw-r--r--sound/soc/fsl/mx27vis-aic32x4.c2
-rw-r--r--sound/soc/fsl/phycore-ac97.c2
-rw-r--r--sound/soc/fsl/wm1133-ev1.c2
-rw-r--r--sound/soc/jz4740/jz4740-i2s.c17
-rw-r--r--sound/soc/kirkwood/kirkwood-dma.c2
-rw-r--r--sound/soc/mid-x86/mfld_machine.c32
-rw-r--r--sound/soc/mxs/mxs-pcm.c18
-rw-r--r--sound/soc/mxs/mxs-pcm.h7
-rw-r--r--sound/soc/mxs/mxs-saif.c37
-rw-r--r--sound/soc/mxs/mxs-saif.h1
-rw-r--r--sound/soc/mxs/mxs-sgtl5000.c10
-rw-r--r--sound/soc/nuc900/nuc900-ac97.c60
-rw-r--r--sound/soc/omap/Kconfig2
-rw-r--r--sound/soc/omap/Makefile1
-rw-r--r--sound/soc/omap/omap-hdmi-card.c2
-rw-r--r--sound/soc/omap/omap-mcbsp.c2
-rw-r--r--sound/soc/pxa/Kconfig20
-rw-r--r--sound/soc/pxa/Makefile4
-rw-r--r--sound/soc/pxa/mmp-pcm.c6
-rw-r--r--sound/soc/pxa/mmp-sspa.c2
-rw-r--r--sound/soc/pxa/pxa2xx-ac97.c10
-rw-r--r--sound/soc/pxa/pxa2xx-ac97.h3
-rw-r--r--sound/soc/pxa/saarb.c190
-rw-r--r--sound/soc/pxa/tavorevb3.c189
-rw-r--r--sound/soc/pxa/zylonite.c1
-rw-r--r--sound/soc/samsung/Kconfig2
-rw-r--r--sound/soc/samsung/ac97.c42
-rw-r--r--sound/soc/samsung/bells.c14
-rw-r--r--sound/soc/samsung/neo1973_wm8753.c2
-rw-r--r--sound/soc/samsung/smdk_wm8580pcm.c1
-rw-r--r--sound/soc/samsung/smdk_wm8994pcm.c1
-rw-r--r--sound/soc/sh/fsi.c10
-rw-r--r--sound/soc/sh/hac.c8
-rw-r--r--sound/soc/soc-core.c123
-rw-r--r--sound/soc/soc-dapm.c110
-rw-r--r--sound/soc/soc-pcm.c91
-rw-r--r--sound/soc/soc-utils.c13
-rw-r--r--sound/soc/spear/Kconfig9
-rw-r--r--sound/soc/spear/Makefile8
-rw-r--r--sound/soc/spear/spdif_in.c31
-rw-r--r--sound/soc/spear/spdif_out.c43
-rw-r--r--sound/soc/spear/spear_pcm.c152
-rw-r--r--sound/soc/tegra/Kconfig10
-rw-r--r--sound/soc/tegra/Makefile2
-rw-r--r--sound/soc/tegra/tegra20_ac97.c67
-rw-r--r--sound/soc/tegra/tegra30_ahub.c25
-rw-r--r--sound/soc/tegra/tegra30_i2s.c26
-rw-r--r--sound/soc/tegra/tegra_asoc_utils.c23
-rw-r--r--sound/soc/tegra/tegra_rt5640.c257
-rw-r--r--sound/soc/txx9/txx9aclc-ac97.c17
-rw-r--r--sound/soc/ux500/mop500.c2
-rw-r--r--sound/soc/ux500/mop500_ab8500.c62
-rw-r--r--sound/soc/ux500/ux500_msp_dai.c11
-rw-r--r--sound/soc/ux500/ux500_msp_dai.h4
-rw-r--r--sound/soc/ux500/ux500_msp_i2s.c88
-rw-r--r--sound/soc/ux500/ux500_msp_i2s.h74
-rw-r--r--sound/soc/ux500/ux500_pcm.c30
-rw-r--r--sound/sparc/dbri.c2
-rw-r--r--sound/spi/at73c213.c1
-rw-r--r--sound/usb/6fire/chip.c2
-rw-r--r--sound/usb/6fire/pcm.c12
-rw-r--r--sound/usb/Kconfig31
-rw-r--r--sound/usb/Makefile2
-rw-r--r--sound/usb/caiaq/audio.c14
-rw-r--r--sound/usb/caiaq/device.c31
-rw-r--r--sound/usb/card.h1
-rw-r--r--sound/usb/clock.c4
-rw-r--r--sound/usb/format.c34
-rw-r--r--sound/usb/format.h2
-rw-r--r--sound/usb/hiface/Makefile2
-rw-r--r--sound/usb/hiface/chip.c297
-rw-r--r--sound/usb/hiface/chip.h30
-rw-r--r--sound/usb/hiface/pcm.c621
-rw-r--r--sound/usb/hiface/pcm.h24
-rw-r--r--sound/usb/midi.c74
-rw-r--r--sound/usb/misc/ua101.c2
-rw-r--r--sound/usb/mixer_quirks.c212
-rw-r--r--sound/usb/pcm.c45
-rw-r--r--sound/usb/quirks-table.h509
-rw-r--r--sound/usb/quirks.c209
-rw-r--r--sound/usb/stream.c18
-rw-r--r--sound/usb/usbaudio.h2
-rw-r--r--sound/usb/usx2y/usbusx2y.c2
-rw-r--r--sound/usb/usx2y/usbusx2yaudio.c3
333 files changed, 12029 insertions, 4219 deletions
diff --git a/Documentation/devicetree/bindings/mfd/arizona.txt b/Documentation/devicetree/bindings/mfd/arizona.txt
new file mode 100644
index 000000000000..0e295c9d8937
--- /dev/null
+++ b/Documentation/devicetree/bindings/mfd/arizona.txt
@@ -0,0 +1,62 @@
1Wolfson Arizona class audio SoCs
2
3These devices are audio SoCs with extensive digital capabilites and a range
4of analogue I/O.
5
6Required properties:
7
8 - compatible : one of the following chip-specific strings:
9 "wlf,wm5102"
10 "wlf,wm5110"
11 - reg : I2C slave address when connected using I2C, chip select number when
12 using SPI.
13
14 - interrupts : The interrupt line the /IRQ signal for the device is
15 connected to.
16 - interrupt-controller : Arizona class devices contain interrupt controllers
17 and may provide interrupt services to other devices.
18 - interrupt-parent : The parent interrupt controller.
19 - #interrupt-cells: the number of cells to describe an IRQ, this should be 2.
20 The first cell is the IRQ number.
21 The second cell is the flags, encoded as the trigger masks from
22 Documentation/devicetree/bindings/interrupts.txt
23
24 - gpio-controller : Indicates this device is a GPIO controller.
25 - #gpio-cells : Must be 2. The first cell is the pin number and the
26 second cell is used to specify optional parameters (currently unused).
27
28 - AVDD1-supply, DBVDD1-supply, DBVDD2-supply, DBVDD3-supply, CPVDD-supply,
29 SPKVDDL-supply, SPKVDDR-supply : power supplies for the device, as covered
30 in Documentation/devicetree/bindings/regulator/regulator.txt
31
32Optional properties:
33
34 - wlf,reset : GPIO specifier for the GPIO controlling /RESET
35 - wlf,ldoena : GPIO specifier for the GPIO controlling LDOENA
36
37 - wlf,gpio-defaults : A list of GPIO configuration register values. If
38 absent, no configuration of these registers is performed. If any
39 entry has a value that is out of range for a 16 bit register then
40 the chip default will be used. If present exactly five values must
41 be specified.
42
43Example:
44
45codec: wm5102@1a {
46 compatible = "wlf,wm5102";
47 reg = <0x1a>;
48 interrupts = <347>;
49 #interrupt-cells = <2>;
50 interrupt-parent = <&gic>;
51
52 gpio-controller;
53 #gpio-cells = <2>;
54
55 wlf,gpio-defaults = <
56 0x00000000, /* AIF1TXLRCLK */
57 0xffffffff,
58 0xffffffff,
59 0xffffffff,
60 0xffffffff,
61 >;
62};
diff --git a/Documentation/devicetree/bindings/sound/adi,adau1701.txt b/Documentation/devicetree/bindings/sound/adi,adau1701.txt
new file mode 100644
index 000000000000..547a49b56a62
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/adi,adau1701.txt
@@ -0,0 +1,35 @@
1Analog Devices ADAU1701
2
3Required properties:
4
5 - compatible: Should contain "adi,adau1701"
6 - reg: The i2c address. Value depends on the state of ADDR0
7 and ADDR1, as wired in hardware.
8
9Optional properties:
10
11 - reset-gpio: A GPIO spec to define which pin is connected to the
12 chip's !RESET pin. If specified, the driver will
13 assert a hardware reset at probe time.
14 - adi,pll-mode-gpios: An array of two GPIO specs to describe the GPIOs
15 the ADAU's PLL config pins are connected to.
16 The state of the pins are set according to the
17 configured clock divider on ASoC side before the
18 firmware is loaded.
19 - adi,pin-config: An array of 12 numerical values selecting one of the
20 pin configurations as described in the datasheet,
21 table 53. Note that the value of this property has
22 to be prefixed with '/bits/ 8'.
23
24Examples:
25
26 i2c_bus {
27 adau1701@34 {
28 compatible = "adi,adau1701";
29 reg = <0x34>;
30 reset-gpio = <&gpio 23 0>;
31 adi,pll-mode-gpios = <&gpio 24 0 &gpio 25 0>;
32 adi,pin-config = /bits/ 8 <0x4 0x7 0x5 0x5 0x4 0x4
33 0x4 0x4 0x4 0x4 0x4 0x4>;
34 };
35 };
diff --git a/Documentation/devicetree/bindings/sound/imx-audio-wm8962.txt b/Documentation/devicetree/bindings/sound/imx-audio-wm8962.txt
new file mode 100644
index 000000000000..f49450a87890
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/imx-audio-wm8962.txt
@@ -0,0 +1,46 @@
1Freescale i.MX audio complex with WM8962 codec
2
3Required properties:
4- compatible : "fsl,imx-audio-wm8962"
5- model : The user-visible name of this sound complex
6- ssi-controller : The phandle of the i.MX SSI controller
7- audio-codec : The phandle of the WM8962 audio codec
8- audio-routing : A list of the connections between audio components.
9 Each entry is a pair of strings, the first being the connection's sink,
10 the second being the connection's source. Valid names could be power
11 supplies, WM8962 pins, and the jacks on the board:
12
13 Power supplies:
14 * Mic Bias
15
16 Board connectors:
17 * Mic Jack
18 * Headphone Jack
19 * Ext Spk
20
21- mux-int-port : The internal port of the i.MX audio muxer (AUDMUX)
22- mux-ext-port : The external port of the i.MX audio muxer
23
24Note: The AUDMUX port numbering should start at 1, which is consistent with
25hardware manual.
26
27Example:
28
29sound {
30 compatible = "fsl,imx6q-sabresd-wm8962",
31 "fsl,imx-audio-wm8962";
32 model = "wm8962-audio";
33 ssi-controller = <&ssi2>;
34 audio-codec = <&codec>;
35 audio-routing =
36 "Headphone Jack", "HPOUTL",
37 "Headphone Jack", "HPOUTR",
38 "Ext Spk", "SPKOUTL",
39 "Ext Spk", "SPKOUTR",
40 "MICBIAS", "AMIC",
41 "IN3R", "MICBIAS",
42 "DMIC", "MICBIAS",
43 "DMICDAT", "DMIC";
44 mux-int-port = <2>;
45 mux-ext-port = <3>;
46};
diff --git a/Documentation/devicetree/bindings/sound/mxs-saif.txt b/Documentation/devicetree/bindings/sound/mxs-saif.txt
index c37ba6143d9b..7ba07a118e37 100644
--- a/Documentation/devicetree/bindings/sound/mxs-saif.txt
+++ b/Documentation/devicetree/bindings/sound/mxs-saif.txt
@@ -3,8 +3,11 @@
3Required properties: 3Required properties:
4- compatible: Should be "fsl,<chip>-saif" 4- compatible: Should be "fsl,<chip>-saif"
5- reg: Should contain registers location and length 5- reg: Should contain registers location and length
6- interrupts: Should contain ERROR and DMA interrupts 6- interrupts: Should contain ERROR interrupt number
7- fsl,saif-dma-channel: APBX DMA channel for the SAIF 7- dmas: DMA specifier, consisting of a phandle to DMA controller node
8 and SAIF DMA channel ID.
9 Refer to dma.txt and fsl-mxs-dma.txt for details.
10- dma-names: Must be "rx-tx".
8 11
9Optional properties: 12Optional properties:
10- fsl,saif-master: phandle to the master SAIF. It's only required for 13- fsl,saif-master: phandle to the master SAIF. It's only required for
@@ -23,14 +26,16 @@ aliases {
23saif0: saif@80042000 { 26saif0: saif@80042000 {
24 compatible = "fsl,imx28-saif"; 27 compatible = "fsl,imx28-saif";
25 reg = <0x80042000 2000>; 28 reg = <0x80042000 2000>;
26 interrupts = <59 80>; 29 interrupts = <59>;
27 fsl,saif-dma-channel = <4>; 30 dmas = <&dma_apbx 4>;
31 dma-names = "rx-tx";
28}; 32};
29 33
30saif1: saif@80046000 { 34saif1: saif@80046000 {
31 compatible = "fsl,imx28-saif"; 35 compatible = "fsl,imx28-saif";
32 reg = <0x80046000 2000>; 36 reg = <0x80046000 2000>;
33 interrupts = <58 81>; 37 interrupts = <58>;
34 fsl,saif-dma-channel = <5>; 38 dmas = <&dma_apbx 5>;
39 dma-names = "rx-tx";
35 fsl,saif-master = <&saif0>; 40 fsl,saif-master = <&saif0>;
36}; 41};
diff --git a/Documentation/devicetree/bindings/sound/nvidia,tegra-audio-rt5640.txt b/Documentation/devicetree/bindings/sound/nvidia,tegra-audio-rt5640.txt
new file mode 100644
index 000000000000..d130818700b2
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/nvidia,tegra-audio-rt5640.txt
@@ -0,0 +1,71 @@
1NVIDIA Tegra audio complex, with RT5640 CODEC
2
3Required properties:
4- compatible : "nvidia,tegra-audio-rt5640"
5- clocks : Must contain an entry for each entry in clock-names.
6- clock-names : Must include the following entries:
7 "pll_a" (The Tegra clock of that name),
8 "pll_a_out0" (The Tegra clock of that name),
9 "mclk" (The Tegra cdev1/extern1 clock, which feeds the CODEC's mclk)
10- nvidia,model : The user-visible name of this sound complex.
11- nvidia,audio-routing : A list of the connections between audio components.
12 Each entry is a pair of strings, the first being the connection's sink,
13 the second being the connection's source. Valid names for sources and
14 sinks are the RT5640's pins, and the jacks on the board:
15
16 RT5640 pins:
17
18 * DMIC1
19 * DMIC2
20 * MICBIAS1
21 * IN1P
22 * IN1R
23 * IN2P
24 * IN2R
25 * HPOL
26 * HPOR
27 * LOUTL
28 * LOUTR
29 * MONOP
30 * MONON
31 * SPOLP
32 * SPOLN
33 * SPORP
34 * SPORN
35
36 Board connectors:
37
38 * Headphones
39 * Speakers
40
41- nvidia,i2s-controller : The phandle of the Tegra I2S controller that's
42 connected to the CODEC.
43- nvidia,audio-codec : The phandle of the RT5640 audio codec. This binding
44 assumes that AIF1 on the CODEC is connected to Tegra.
45
46Optional properties:
47- nvidia,hp-det-gpios : The GPIO that detects headphones are plugged in
48
49Example:
50
51sound {
52 compatible = "nvidia,tegra-audio-rt5640-dalmore",
53 "nvidia,tegra-audio-rt5640";
54 nvidia,model = "NVIDIA Tegra Dalmore";
55
56 nvidia,audio-routing =
57 "Headphones", "HPOR",
58 "Headphones", "HPOL",
59 "Speakers", "SPORP",
60 "Speakers", "SPORN",
61 "Speakers", "SPOLP",
62 "Speakers", "SPOLN";
63
64 nvidia,i2s-controller = <&tegra_i2s1>;
65 nvidia,audio-codec = <&rt5640>;
66
67 nvidia,hp-det-gpios = <&gpio 143 0>; /* GPIO PR7 */
68
69 clocks = <&tegra_car 216>, <&tegra_car 217>, <&tegra_car 120>;
70 clock-names = "pll_a", "pll_a_out0", "mclk";
71};
diff --git a/Documentation/devicetree/bindings/sound/rt5640.txt b/Documentation/devicetree/bindings/sound/rt5640.txt
new file mode 100644
index 000000000000..005bcb24d72d
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/rt5640.txt
@@ -0,0 +1,30 @@
1RT5640 audio CODEC
2
3This device supports I2C only.
4
5Required properties:
6
7- compatible : "realtek,rt5640".
8
9- reg : The I2C address of the device.
10
11- interrupts : The CODEC's interrupt output.
12
13Optional properties:
14
15- realtek,in1-differential
16- realtek,in2-differential
17 Boolean. Indicate MIC1/2 input are differential, rather than single-ended.
18
19- realtek,ldo1-en-gpios : The GPIO that controls the CODEC's LDO1_EN pin.
20
21Example:
22
23rt5640 {
24 compatible = "realtek,rt5640";
25 reg = <0x1c>;
26 interrupt-parent = <&gpio>;
27 interrupts = <TEGRA_GPIO(W, 3) GPIO_ACTIVE_HIGH>;
28 realtek,ldo1-en-gpios =
29 <&gpio TEGRA_GPIO(V, 3) GPIO_ACTIVE_HIGH>;
30};
diff --git a/Documentation/devicetree/bindings/sound/sgtl5000.txt b/Documentation/devicetree/bindings/sound/sgtl5000.txt
index 9cc44449508d..955df60a118c 100644
--- a/Documentation/devicetree/bindings/sound/sgtl5000.txt
+++ b/Documentation/devicetree/bindings/sound/sgtl5000.txt
@@ -5,9 +5,12 @@ Required properties:
5 5
6- reg : the I2C address of the device 6- reg : the I2C address of the device
7 7
8- clocks : the clock provider of SYS_MCLK
9
8Example: 10Example:
9 11
10codec: sgtl5000@0a { 12codec: sgtl5000@0a {
11 compatible = "fsl,sgtl5000"; 13 compatible = "fsl,sgtl5000";
12 reg = <0x0a>; 14 reg = <0x0a>;
15 clocks = <&clks 150>;
13}; 16};
diff --git a/Documentation/devicetree/bindings/sound/spdif-receiver.txt b/Documentation/devicetree/bindings/sound/spdif-receiver.txt
new file mode 100644
index 000000000000..80f807bf8a1d
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/spdif-receiver.txt
@@ -0,0 +1,10 @@
1Device-Tree bindings for dummy spdif receiver
2
3Required properties:
4 - compatible: should be "linux,spdif-dir".
5
6Example node:
7
8 codec: spdif-receiver {
9 compatible = "linux,spdif-dir";
10 };
diff --git a/Documentation/devicetree/bindings/sound/spdif-transmitter.txt b/Documentation/devicetree/bindings/sound/spdif-transmitter.txt
new file mode 100644
index 000000000000..55a85841dd85
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/spdif-transmitter.txt
@@ -0,0 +1,10 @@
1Device-Tree bindings for dummy spdif transmitter
2
3Required properties:
4 - compatible: should be "linux,spdif-dit".
5
6Example node:
7
8 codec: spdif-transmitter {
9 compatible = "linux,spdif-dit";
10 };
diff --git a/Documentation/devicetree/bindings/sound/ssm2518.txt b/Documentation/devicetree/bindings/sound/ssm2518.txt
new file mode 100644
index 000000000000..59381a778c79
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/ssm2518.txt
@@ -0,0 +1,20 @@
1SSM2518 audio amplifier
2
3This device supports I2C only.
4
5Required properties:
6 - compatible : Must be "adi,ssm2518"
7 - reg : the I2C address of the device. This will either be 0x34 (ADDR pin low)
8 or 0x35 (ADDR pin high)
9
10Optional properties:
11 - gpios : GPIO connected to the nSD pin. If the property is not present it is
12 assumed that the nSD pin is hardwired to always on.
13
14Example:
15
16 ssm2518: ssm2518@34 {
17 compatible = "adi,ssm2518";
18 reg = <0x34>;
19 gpios = <&gpio 5 0>;
20 };
diff --git a/Documentation/devicetree/bindings/sound/ti,tas5086.txt b/Documentation/devicetree/bindings/sound/ti,tas5086.txt
index 8ea4f5b4818d..d2866a0d6a26 100644
--- a/Documentation/devicetree/bindings/sound/ti,tas5086.txt
+++ b/Documentation/devicetree/bindings/sound/ti,tas5086.txt
@@ -20,6 +20,17 @@ Optional properties:
20 When not specified, the hardware default of 1300ms 20 When not specified, the hardware default of 1300ms
21 is retained. 21 is retained.
22 22
23 - ti,mid-z-channel-X: Boolean properties, X being a number from 1 to 6.
24 If given, channel X will start with the Mid-Z start
25 sequence, otherwise the default Low-Z scheme is used.
26
27 The correct configuration depends on how the power
28 stages connected to the PWM output pins work. Not all
29 power stages are compatible to Mid-Z - please refer
30 to the datasheets for more details.
31
32 Most systems should not set any of these properties.
33
23Examples: 34Examples:
24 35
25 i2c_bus { 36 i2c_bus {
diff --git a/Documentation/devicetree/bindings/sound/wm8962.txt b/Documentation/devicetree/bindings/sound/wm8962.txt
index dceb3b1c2bb7..7f82b59ec8f9 100644
--- a/Documentation/devicetree/bindings/sound/wm8962.txt
+++ b/Documentation/devicetree/bindings/sound/wm8962.txt
@@ -8,9 +8,32 @@ Required properties:
8 8
9 - reg : the I2C address of the device. 9 - reg : the I2C address of the device.
10 10
11Optional properties:
12 - spk-mono: This is a boolean property. If present, the SPK_MONO bit
13 of R51 (Class D Control 2) gets set, indicating that the speaker is
14 in mono mode.
15
16 - mic-cfg : Default register value for R48 (Additional Control 4).
17 If absent, the default should be the register default.
18
19 - gpio-cfg : A list of GPIO configuration register values. The list must
20 be 6 entries long. If absent, no configuration of these registers is
21 performed. And note that only the value within [0x0, 0xffff] is valid.
22 Any other value is regarded as setting the GPIO register by its reset
23 value 0x0.
24
11Example: 25Example:
12 26
13codec: wm8962@1a { 27codec: wm8962@1a {
14 compatible = "wlf,wm8962"; 28 compatible = "wlf,wm8962";
15 reg = <0x1a>; 29 reg = <0x1a>;
30
31 gpio-cfg = <
32 0x0000 /* 0:Default */
33 0x0000 /* 1:Default */
34 0x0013 /* 2:FN_DMICCLK */
35 0x0000 /* 3:Default */
36 0x8014 /* 4:FN_DMICCDAT */
37 0x0000 /* 5:Default */
38 >;
16}; 39};
diff --git a/Documentation/sound/alsa/HD-Audio-Models.txt b/Documentation/sound/alsa/HD-Audio-Models.txt
index 77d68e23b247..809d72b8eff1 100644
--- a/Documentation/sound/alsa/HD-Audio-Models.txt
+++ b/Documentation/sound/alsa/HD-Audio-Models.txt
@@ -21,41 +21,41 @@ ALC267/268
21========== 21==========
22 inv-dmic Inverted internal mic workaround 22 inv-dmic Inverted internal mic workaround
23 23
24ALC269/270/275/276/280/282 24ALC269/270/275/276/28x/29x
25====== 25======
26 laptop-amic Laptops with analog-mic input 26 laptop-amic Laptops with analog-mic input
27 laptop-dmic Laptops with digital-mic input 27 laptop-dmic Laptops with digital-mic input
28 alc269-dmic Enable ALC269(VA) digital mic workaround 28 alc269-dmic Enable ALC269(VA) digital mic workaround
29 alc271-dmic Enable ALC271X digital mic workaround 29 alc271-dmic Enable ALC271X digital mic workaround
30 inv-dmic Inverted internal mic workaround 30 inv-dmic Inverted internal mic workaround
31 lenovo-dock Enables docking station I/O for some Lenovos 31 lenovo-dock Enables docking station I/O for some Lenovos
32 dell-headset-multi Headset jack, which can also be used as mic-in 32 dell-headset-multi Headset jack, which can also be used as mic-in
33 dell-headset-dock Headset jack (without mic-in), and also dock I/O 33 dell-headset-dock Headset jack (without mic-in), and also dock I/O
34 34
35ALC662/663/272 35ALC66x/67x/892
36============== 36==============
37 mario Chromebook mario model fixup 37 mario Chromebook mario model fixup
38 asus-mode1 ASUS 38 asus-mode1 ASUS
39 asus-mode2 ASUS 39 asus-mode2 ASUS
40 asus-mode3 ASUS 40 asus-mode3 ASUS
41 asus-mode4 ASUS 41 asus-mode4 ASUS
42 asus-mode5 ASUS 42 asus-mode5 ASUS
43 asus-mode6 ASUS 43 asus-mode6 ASUS
44 asus-mode7 ASUS 44 asus-mode7 ASUS
45 asus-mode8 ASUS 45 asus-mode8 ASUS
46 inv-dmic Inverted internal mic workaround 46 inv-dmic Inverted internal mic workaround
47 dell-headset-multi Headset jack, which can also be used as mic-in 47 dell-headset-multi Headset jack, which can also be used as mic-in
48 48
49ALC680 49ALC680
50====== 50======
51 N/A 51 N/A
52 52
53ALC882/883/885/888/889 53ALC88x/898/1150
54====================== 54======================
55 acer-aspire-4930g Acer Aspire 4930G/5930G/6530G/6930G/7730G 55 acer-aspire-4930g Acer Aspire 4930G/5930G/6530G/6930G/7730G
56 acer-aspire-8930g Acer Aspire 8330G/6935G 56 acer-aspire-8930g Acer Aspire 8330G/6935G
57 acer-aspire Acer Aspire others 57 acer-aspire Acer Aspire others
58 inv-dmic Inverted internal mic workaround 58 inv-dmic Inverted internal mic workaround
59 no-primary-hp VAIO Z/VGC-LN51JGB workaround (for fixed speaker DAC) 59 no-primary-hp VAIO Z/VGC-LN51JGB workaround (for fixed speaker DAC)
60 60
61ALC861/660 61ALC861/660
diff --git a/arch/blackfin/mach-bf527/boards/ad7160eval.c b/arch/blackfin/mach-bf527/boards/ad7160eval.c
index d58f50e5aa4b..1e7be62fccb6 100644
--- a/arch/blackfin/mach-bf527/boards/ad7160eval.c
+++ b/arch/blackfin/mach-bf527/boards/ad7160eval.c
@@ -283,14 +283,6 @@ static struct platform_device bfin_i2s = {
283}; 283};
284#endif 284#endif
285 285
286#if defined(CONFIG_SND_BF5XX_TDM) || defined(CONFIG_SND_BF5XX_TDM_MODULE)
287static struct platform_device bfin_tdm = {
288 .name = "bfin-tdm",
289 .id = CONFIG_SND_BF5XX_SPORT_NUM,
290 /* TODO: add platform data here */
291};
292#endif
293
294static struct spi_board_info bfin_spi_board_info[] __initdata = { 286static struct spi_board_info bfin_spi_board_info[] __initdata = {
295#if defined(CONFIG_MTD_M25P80) \ 287#if defined(CONFIG_MTD_M25P80) \
296 || defined(CONFIG_MTD_M25P80_MODULE) 288 || defined(CONFIG_MTD_M25P80_MODULE)
@@ -800,10 +792,6 @@ static struct platform_device *stamp_devices[] __initdata = {
800#if defined(CONFIG_SND_BF5XX_I2S) || defined(CONFIG_SND_BF5XX_I2S_MODULE) 792#if defined(CONFIG_SND_BF5XX_I2S) || defined(CONFIG_SND_BF5XX_I2S_MODULE)
801 &bfin_i2s, 793 &bfin_i2s,
802#endif 794#endif
803
804#if defined(CONFIG_SND_BF5XX_TDM) || defined(CONFIG_SND_BF5XX_TDM_MODULE)
805 &bfin_tdm,
806#endif
807}; 795};
808 796
809static int __init ad7160eval_init(void) 797static int __init ad7160eval_init(void)
diff --git a/arch/blackfin/mach-bf527/boards/ezkit.c b/arch/blackfin/mach-bf527/boards/ezkit.c
index 29f16e5c37b9..d0a0c5e527cd 100644
--- a/arch/blackfin/mach-bf527/boards/ezkit.c
+++ b/arch/blackfin/mach-bf527/boards/ezkit.c
@@ -493,8 +493,7 @@ static const struct ad7879_platform_data bfin_ad7879_ts_info = {
493}; 493};
494#endif 494#endif
495 495
496#if defined(CONFIG_SND_BF5XX_I2S) || defined(CONFIG_SND_BF5XX_I2S_MODULE) || \ 496#if defined(CONFIG_SND_BF5XX_I2S) || defined(CONFIG_SND_BF5XX_I2S_MODULE)
497 defined(CONFIG_SND_BF5XX_TDM) || defined(CONFIG_SND_BF5XX_TDM_MODULE)
498 497
499static const u16 bfin_snd_pin[][7] = { 498static const u16 bfin_snd_pin[][7] = {
500 {P_SPORT0_DTPRI, P_SPORT0_TSCLK, P_SPORT0_RFS, 499 {P_SPORT0_DTPRI, P_SPORT0_TSCLK, P_SPORT0_RFS,
@@ -549,13 +548,6 @@ static struct platform_device bfin_i2s_pcm = {
549}; 548};
550#endif 549#endif
551 550
552#if defined(CONFIG_SND_BF5XX_TDM) || defined(CONFIG_SND_BF5XX_TDM_MODULE)
553static struct platform_device bfin_tdm_pcm = {
554 .name = "bfin-tdm-pcm-audio",
555 .id = -1,
556};
557#endif
558
559#if defined(CONFIG_SND_BF5XX_AC97) || defined(CONFIG_SND_BF5XX_AC97_MODULE) 551#if defined(CONFIG_SND_BF5XX_AC97) || defined(CONFIG_SND_BF5XX_AC97_MODULE)
560static struct platform_device bfin_ac97_pcm = { 552static struct platform_device bfin_ac97_pcm = {
561 .name = "bfin-ac97-pcm-audio", 553 .name = "bfin-ac97-pcm-audio",
@@ -575,22 +567,10 @@ static struct platform_device bfin_i2s = {
575}; 567};
576#endif 568#endif
577 569
578#if defined(CONFIG_SND_BF5XX_TDM) || defined(CONFIG_SND_BF5XX_TDM_MODULE)
579static struct platform_device bfin_tdm = {
580 .name = "bfin-tdm",
581 .id = CONFIG_SND_BF5XX_SPORT_NUM,
582 .num_resources = ARRAY_SIZE(bfin_snd_resources[CONFIG_SND_BF5XX_SPORT_NUM]),
583 .resource = bfin_snd_resources[CONFIG_SND_BF5XX_SPORT_NUM],
584 .dev = {
585 .platform_data = &bfin_snd_data[CONFIG_SND_BF5XX_SPORT_NUM],
586 },
587};
588#endif
589
590#if defined(CONFIG_SND_BF5XX_SOC_AD1836) \ 570#if defined(CONFIG_SND_BF5XX_SOC_AD1836) \
591 || defined(CONFIG_SND_BF5XX_SOC_AD1836_MODULE) 571 || defined(CONFIG_SND_BF5XX_SOC_AD1836_MODULE)
592static const char * const ad1836_link[] = { 572static const char * const ad1836_link[] = {
593 "bfin-tdm.0", 573 "bfin-i2s.0",
594 "spi0.4", 574 "spi0.4",
595}; 575};
596static struct platform_device bfin_ad1836_machine = { 576static struct platform_device bfin_ad1836_machine = {
@@ -1269,10 +1249,6 @@ static struct platform_device *stamp_devices[] __initdata = {
1269 &bfin_i2s_pcm, 1249 &bfin_i2s_pcm,
1270#endif 1250#endif
1271 1251
1272#if defined(CONFIG_SND_BF5XX_TDM) || defined(CONFIG_SND_BF5XX_TDM_MODULE)
1273 &bfin_tdm_pcm,
1274#endif
1275
1276#if defined(CONFIG_SND_BF5XX_AC97) || defined(CONFIG_SND_BF5XX_AC97_MODULE) 1252#if defined(CONFIG_SND_BF5XX_AC97) || defined(CONFIG_SND_BF5XX_AC97_MODULE)
1277 &bfin_ac97_pcm, 1253 &bfin_ac97_pcm,
1278#endif 1254#endif
@@ -1281,10 +1257,6 @@ static struct platform_device *stamp_devices[] __initdata = {
1281 &bfin_i2s, 1257 &bfin_i2s,
1282#endif 1258#endif
1283 1259
1284#if defined(CONFIG_SND_BF5XX_TDM) || defined(CONFIG_SND_BF5XX_TDM_MODULE)
1285 &bfin_tdm,
1286#endif
1287
1288#if defined(CONFIG_SND_BF5XX_SOC_AD1836) || \ 1260#if defined(CONFIG_SND_BF5XX_SOC_AD1836) || \
1289 defined(CONFIG_SND_BF5XX_SOC_AD1836_MODULE) 1261 defined(CONFIG_SND_BF5XX_SOC_AD1836_MODULE)
1290 &bfin_ad1836_machine, 1262 &bfin_ad1836_machine,
diff --git a/arch/blackfin/mach-bf533/boards/ezkit.c b/arch/blackfin/mach-bf533/boards/ezkit.c
index 07811c209b9d..90fb0d14b147 100644
--- a/arch/blackfin/mach-bf533/boards/ezkit.c
+++ b/arch/blackfin/mach-bf533/boards/ezkit.c
@@ -450,14 +450,6 @@ static struct platform_device bfin_i2s = {
450}; 450};
451#endif 451#endif
452 452
453#if defined(CONFIG_SND_BF5XX_TDM) || defined(CONFIG_SND_BF5XX_TDM_MODULE)
454static struct platform_device bfin_tdm = {
455 .name = "bfin-tdm",
456 .id = CONFIG_SND_BF5XX_SPORT_NUM,
457 /* TODO: add platform data here */
458};
459#endif
460
461#if defined(CONFIG_SND_BF5XX_AC97) || defined(CONFIG_SND_BF5XX_AC97_MODULE) 453#if defined(CONFIG_SND_BF5XX_AC97) || defined(CONFIG_SND_BF5XX_AC97_MODULE)
462static struct platform_device bfin_ac97 = { 454static struct platform_device bfin_ac97 = {
463 .name = "bfin-ac97", 455 .name = "bfin-ac97",
@@ -516,10 +508,6 @@ static struct platform_device *ezkit_devices[] __initdata = {
516 &bfin_i2s, 508 &bfin_i2s,
517#endif 509#endif
518 510
519#if defined(CONFIG_SND_BF5XX_TDM) || defined(CONFIG_SND_BF5XX_TDM_MODULE)
520 &bfin_tdm,
521#endif
522
523#if defined(CONFIG_SND_BF5XX_AC97) || defined(CONFIG_SND_BF5XX_AC97_MODULE) 511#if defined(CONFIG_SND_BF5XX_AC97) || defined(CONFIG_SND_BF5XX_AC97_MODULE)
524 &bfin_ac97, 512 &bfin_ac97,
525#endif 513#endif
diff --git a/arch/blackfin/mach-bf533/boards/stamp.c b/arch/blackfin/mach-bf533/boards/stamp.c
index 6fca8698bf3b..4a8c2e3fd7e5 100644
--- a/arch/blackfin/mach-bf533/boards/stamp.c
+++ b/arch/blackfin/mach-bf533/boards/stamp.c
@@ -542,8 +542,7 @@ static struct platform_device bfin_dpmc = {
542}; 542};
543 543
544#if defined(CONFIG_SND_BF5XX_I2S) || defined(CONFIG_SND_BF5XX_I2S_MODULE) || \ 544#if defined(CONFIG_SND_BF5XX_I2S) || defined(CONFIG_SND_BF5XX_I2S_MODULE) || \
545 defined(CONFIG_SND_BF5XX_TDM) || defined(CONFIG_SND_BF5XX_TDM_MODULE) \ 545 defined(CONFIG_SND_BF5XX_AC97) || \
546 || defined(CONFIG_SND_BF5XX_AC97) || \
547 defined(CONFIG_SND_BF5XX_AC97_MODULE) 546 defined(CONFIG_SND_BF5XX_AC97_MODULE)
548 547
549#include <asm/bfin_sport.h> 548#include <asm/bfin_sport.h>
@@ -603,13 +602,6 @@ static struct platform_device bfin_i2s_pcm = {
603}; 602};
604#endif 603#endif
605 604
606#if defined(CONFIG_SND_BF5XX_TDM) || defined(CONFIG_SND_BF5XX_TDM_MODULE)
607static struct platform_device bfin_tdm_pcm = {
608 .name = "bfin-tdm-pcm-audio",
609 .id = -1,
610};
611#endif
612
613#if defined(CONFIG_SND_BF5XX_AC97) || defined(CONFIG_SND_BF5XX_AC97_MODULE) 605#if defined(CONFIG_SND_BF5XX_AC97) || defined(CONFIG_SND_BF5XX_AC97_MODULE)
614static struct platform_device bfin_ac97_pcm = { 606static struct platform_device bfin_ac97_pcm = {
615 .name = "bfin-ac97-pcm-audio", 607 .name = "bfin-ac97-pcm-audio",
@@ -620,7 +612,7 @@ static struct platform_device bfin_ac97_pcm = {
620#if defined(CONFIG_SND_BF5XX_SOC_AD1836) \ 612#if defined(CONFIG_SND_BF5XX_SOC_AD1836) \
621 || defined(CONFIG_SND_BF5XX_SOC_AD1836_MODULE) 613 || defined(CONFIG_SND_BF5XX_SOC_AD1836_MODULE)
622static const char * const ad1836_link[] = { 614static const char * const ad1836_link[] = {
623 "bfin-tdm.0", 615 "bfin-i2s.0",
624 "spi0.4", 616 "spi0.4",
625}; 617};
626static struct platform_device bfin_ad1836_machine = { 618static struct platform_device bfin_ad1836_machine = {
@@ -675,20 +667,6 @@ static struct platform_device bfin_i2s = {
675}; 667};
676#endif 668#endif
677 669
678#if defined(CONFIG_SND_BF5XX_SOC_TDM) || \
679 defined(CONFIG_SND_BF5XX_SOC_TDM_MODULE)
680static struct platform_device bfin_tdm = {
681 .name = "bfin-tdm",
682 .id = CONFIG_SND_BF5XX_SPORT_NUM,
683 .num_resources =
684 ARRAY_SIZE(bfin_snd_resources[CONFIG_SND_BF5XX_SPORT_NUM]),
685 .resource = bfin_snd_resources[CONFIG_SND_BF5XX_SPORT_NUM],
686 .dev = {
687 .platform_data = &bfin_snd_data[CONFIG_SND_BF5XX_SPORT_NUM],
688 },
689};
690#endif
691
692#if defined(CONFIG_SND_BF5XX_SOC_AC97) || \ 670#if defined(CONFIG_SND_BF5XX_SOC_AC97) || \
693 defined(CONFIG_SND_BF5XX_SOC_AC97_MODULE) 671 defined(CONFIG_SND_BF5XX_SOC_AC97_MODULE)
694static struct platform_device bfin_ac97 = { 672static struct platform_device bfin_ac97 = {
@@ -761,10 +739,6 @@ static struct platform_device *stamp_devices[] __initdata = {
761 &bfin_i2s_pcm, 739 &bfin_i2s_pcm,
762#endif 740#endif
763 741
764#if defined(CONFIG_SND_BF5XX_TDM) || defined(CONFIG_SND_BF5XX_TDM_MODULE)
765 &bfin_tdm_pcm,
766#endif
767
768#if defined(CONFIG_SND_BF5XX_AC97) || defined(CONFIG_SND_BF5XX_AC97_MODULE) 742#if defined(CONFIG_SND_BF5XX_AC97) || defined(CONFIG_SND_BF5XX_AC97_MODULE)
769 &bfin_ac97_pcm, 743 &bfin_ac97_pcm,
770#endif 744#endif
@@ -792,11 +766,6 @@ static struct platform_device *stamp_devices[] __initdata = {
792 &bfin_i2s, 766 &bfin_i2s,
793#endif 767#endif
794 768
795#if defined(CONFIG_SND_BF5XX_SOC_TDM) || \
796 defined(CONFIG_SND_BF5XX_SOC_TDM_MODULE)
797 &bfin_tdm,
798#endif
799
800#if defined(CONFIG_SND_BF5XX_SOC_AC97) || \ 769#if defined(CONFIG_SND_BF5XX_SOC_AC97) || \
801 defined(CONFIG_SND_BF5XX_SOC_AC97_MODULE) 770 defined(CONFIG_SND_BF5XX_SOC_AC97_MODULE)
802 &bfin_ac97, 771 &bfin_ac97,
diff --git a/arch/blackfin/mach-bf537/boards/stamp.c b/arch/blackfin/mach-bf537/boards/stamp.c
index 6a3a14bcd3a1..44fd1d4682ac 100644
--- a/arch/blackfin/mach-bf537/boards/stamp.c
+++ b/arch/blackfin/mach-bf537/boards/stamp.c
@@ -2570,7 +2570,6 @@ static struct platform_device bfin_dpmc = {
2570}; 2570};
2571 2571
2572#if defined(CONFIG_SND_BF5XX_I2S) || defined(CONFIG_SND_BF5XX_I2S_MODULE) || \ 2572#if defined(CONFIG_SND_BF5XX_I2S) || defined(CONFIG_SND_BF5XX_I2S_MODULE) || \
2573 defined(CONFIG_SND_BF5XX_TDM) || defined(CONFIG_SND_BF5XX_TDM_MODULE) || \
2574 defined(CONFIG_SND_BF5XX_AC97) || defined(CONFIG_SND_BF5XX_AC97_MODULE) 2573 defined(CONFIG_SND_BF5XX_AC97) || defined(CONFIG_SND_BF5XX_AC97_MODULE)
2575 2574
2576#define SPORT_REQ(x) \ 2575#define SPORT_REQ(x) \
@@ -2628,13 +2627,6 @@ static struct platform_device bfin_i2s_pcm = {
2628}; 2627};
2629#endif 2628#endif
2630 2629
2631#if defined(CONFIG_SND_BF5XX_TDM) || defined(CONFIG_SND_BF5XX_TDM_MODULE)
2632static struct platform_device bfin_tdm_pcm = {
2633 .name = "bfin-tdm-pcm-audio",
2634 .id = -1,
2635};
2636#endif
2637
2638#if defined(CONFIG_SND_BF5XX_AC97) || defined(CONFIG_SND_BF5XX_AC97_MODULE) 2630#if defined(CONFIG_SND_BF5XX_AC97) || defined(CONFIG_SND_BF5XX_AC97_MODULE)
2639static struct platform_device bfin_ac97_pcm = { 2631static struct platform_device bfin_ac97_pcm = {
2640 .name = "bfin-ac97-pcm-audio", 2632 .name = "bfin-ac97-pcm-audio",
@@ -2645,7 +2637,7 @@ static struct platform_device bfin_ac97_pcm = {
2645#if defined(CONFIG_SND_BF5XX_SOC_AD1836) \ 2637#if defined(CONFIG_SND_BF5XX_SOC_AD1836) \
2646 || defined(CONFIG_SND_BF5XX_SOC_AD1836_MODULE) 2638 || defined(CONFIG_SND_BF5XX_SOC_AD1836_MODULE)
2647static const char * const ad1836_link[] = { 2639static const char * const ad1836_link[] = {
2648 "bfin-tdm.0", 2640 "bfin-i2s.0",
2649 "spi0.4", 2641 "spi0.4",
2650}; 2642};
2651static struct platform_device bfin_ad1836_machine = { 2643static struct platform_device bfin_ad1836_machine = {
@@ -2699,18 +2691,6 @@ static struct platform_device bfin_i2s = {
2699}; 2691};
2700#endif 2692#endif
2701 2693
2702#if defined(CONFIG_SND_BF5XX_SOC_TDM) || defined(CONFIG_SND_BF5XX_SOC_TDM_MODULE)
2703static struct platform_device bfin_tdm = {
2704 .name = "bfin-tdm",
2705 .id = CONFIG_SND_BF5XX_SPORT_NUM,
2706 .num_resources = ARRAY_SIZE(bfin_snd_resources[CONFIG_SND_BF5XX_SPORT_NUM]),
2707 .resource = bfin_snd_resources[CONFIG_SND_BF5XX_SPORT_NUM],
2708 .dev = {
2709 .platform_data = &bfin_snd_data[CONFIG_SND_BF5XX_SPORT_NUM],
2710 },
2711};
2712#endif
2713
2714#if defined(CONFIG_SND_BF5XX_SOC_AC97) || defined(CONFIG_SND_BF5XX_SOC_AC97_MODULE) 2694#if defined(CONFIG_SND_BF5XX_SOC_AC97) || defined(CONFIG_SND_BF5XX_SOC_AC97_MODULE)
2715static struct platform_device bfin_ac97 = { 2695static struct platform_device bfin_ac97 = {
2716 .name = "bfin-ac97", 2696 .name = "bfin-ac97",
@@ -2935,10 +2915,6 @@ static struct platform_device *stamp_devices[] __initdata = {
2935 &bfin_i2s_pcm, 2915 &bfin_i2s_pcm,
2936#endif 2916#endif
2937 2917
2938#if defined(CONFIG_SND_BF5XX_TDM) || defined(CONFIG_SND_BF5XX_TDM_MODULE)
2939 &bfin_tdm_pcm,
2940#endif
2941
2942#if defined(CONFIG_SND_BF5XX_AC97) || defined(CONFIG_SND_BF5XX_AC97_MODULE) 2918#if defined(CONFIG_SND_BF5XX_AC97) || defined(CONFIG_SND_BF5XX_AC97_MODULE)
2943 &bfin_ac97_pcm, 2919 &bfin_ac97_pcm,
2944#endif 2920#endif
@@ -2961,10 +2937,6 @@ static struct platform_device *stamp_devices[] __initdata = {
2961 &bfin_i2s, 2937 &bfin_i2s,
2962#endif 2938#endif
2963 2939
2964#if defined(CONFIG_SND_BF5XX_SOC_TDM) || defined(CONFIG_SND_BF5XX_SOC_TDM_MODULE)
2965 &bfin_tdm,
2966#endif
2967
2968#if defined(CONFIG_SND_BF5XX_SOC_AC97) || defined(CONFIG_SND_BF5XX_SOC_AC97_MODULE) 2940#if defined(CONFIG_SND_BF5XX_SOC_AC97) || defined(CONFIG_SND_BF5XX_SOC_AC97_MODULE)
2969 &bfin_ac97, 2941 &bfin_ac97,
2970#endif 2942#endif
diff --git a/arch/blackfin/mach-bf548/boards/ezkit.c b/arch/blackfin/mach-bf548/boards/ezkit.c
index c4d07f040947..372eb54944ef 100644
--- a/arch/blackfin/mach-bf548/boards/ezkit.c
+++ b/arch/blackfin/mach-bf548/boards/ezkit.c
@@ -1393,7 +1393,6 @@ static struct platform_device bfin_dpmc = {
1393}; 1393};
1394 1394
1395#if defined(CONFIG_SND_BF5XX_I2S) || defined(CONFIG_SND_BF5XX_I2S_MODULE) || \ 1395#if defined(CONFIG_SND_BF5XX_I2S) || defined(CONFIG_SND_BF5XX_I2S_MODULE) || \
1396 defined(CONFIG_SND_BF5XX_TDM) || defined(CONFIG_SND_BF5XX_TDM_MODULE) || \
1397 defined(CONFIG_SND_BF5XX_AC97) || defined(CONFIG_SND_BF5XX_AC97_MODULE) 1396 defined(CONFIG_SND_BF5XX_AC97) || defined(CONFIG_SND_BF5XX_AC97_MODULE)
1398 1397
1399#define SPORT_REQ(x) \ 1398#define SPORT_REQ(x) \
@@ -1461,13 +1460,6 @@ static struct platform_device bfin_i2s_pcm = {
1461}; 1460};
1462#endif 1461#endif
1463 1462
1464#if defined(CONFIG_SND_BF5XX_TDM) || defined(CONFIG_SND_BF5XX_TDM_MODULE)
1465static struct platform_device bfin_tdm_pcm = {
1466 .name = "bfin-tdm-pcm-audio",
1467 .id = -1,
1468};
1469#endif
1470
1471#if defined(CONFIG_SND_BF5XX_AC97) || defined(CONFIG_SND_BF5XX_AC97_MODULE) 1463#if defined(CONFIG_SND_BF5XX_AC97) || defined(CONFIG_SND_BF5XX_AC97_MODULE)
1472static struct platform_device bfin_ac97_pcm = { 1464static struct platform_device bfin_ac97_pcm = {
1473 .name = "bfin-ac97-pcm-audio", 1465 .name = "bfin-ac97-pcm-audio",
@@ -1501,18 +1493,6 @@ static struct platform_device bfin_i2s = {
1501}; 1493};
1502#endif 1494#endif
1503 1495
1504#if defined(CONFIG_SND_BF5XX_SOC_TDM) || defined(CONFIG_SND_BF5XX_SOC_TDM_MODULE)
1505static struct platform_device bfin_tdm = {
1506 .name = "bfin-tdm",
1507 .id = CONFIG_SND_BF5XX_SPORT_NUM,
1508 .num_resources = ARRAY_SIZE(bfin_snd_resources[CONFIG_SND_BF5XX_SPORT_NUM]),
1509 .resource = bfin_snd_resources[CONFIG_SND_BF5XX_SPORT_NUM],
1510 .dev = {
1511 .platform_data = &bfin_snd_data[CONFIG_SND_BF5XX_SPORT_NUM],
1512 },
1513};
1514#endif
1515
1516#if defined(CONFIG_SND_BF5XX_SOC_AC97) || defined(CONFIG_SND_BF5XX_SOC_AC97_MODULE) 1496#if defined(CONFIG_SND_BF5XX_SOC_AC97) || defined(CONFIG_SND_BF5XX_SOC_AC97_MODULE)
1517static struct platform_device bfin_ac97 = { 1497static struct platform_device bfin_ac97 = {
1518 .name = "bfin-ac97", 1498 .name = "bfin-ac97",
@@ -1646,9 +1626,7 @@ static struct platform_device *ezkit_devices[] __initdata = {
1646#if defined(CONFIG_SND_BF5XX_I2S) || defined(CONFIG_SND_BF5XX_I2S_MODULE) 1626#if defined(CONFIG_SND_BF5XX_I2S) || defined(CONFIG_SND_BF5XX_I2S_MODULE)
1647 &bfin_i2s_pcm, 1627 &bfin_i2s_pcm,
1648#endif 1628#endif
1649#if defined(CONFIG_SND_BF5XX_TDM) || defined(CONFIG_SND_BF5XX_TDM_MODULE) 1629
1650 &bfin_tdm_pcm,
1651#endif
1652#if defined(CONFIG_SND_BF5XX_AC97) || defined(CONFIG_SND_BF5XX_AC97_MODULE) 1630#if defined(CONFIG_SND_BF5XX_AC97) || defined(CONFIG_SND_BF5XX_AC97_MODULE)
1653 &bfin_ac97_pcm, 1631 &bfin_ac97_pcm,
1654#endif 1632#endif
@@ -1661,10 +1639,6 @@ static struct platform_device *ezkit_devices[] __initdata = {
1661 &bfin_i2s, 1639 &bfin_i2s,
1662#endif 1640#endif
1663 1641
1664#if defined(CONFIG_SND_BF5XX_TDM) || defined(CONFIG_SND_BF5XX_TDM_MODULE)
1665 &bfin_tdm,
1666#endif
1667
1668#if defined(CONFIG_SND_BF5XX_AC97) || defined(CONFIG_SND_BF5XX_AC97_MODULE) 1642#if defined(CONFIG_SND_BF5XX_AC97) || defined(CONFIG_SND_BF5XX_AC97_MODULE)
1669 &bfin_ac97, 1643 &bfin_ac97,
1670#endif 1644#endif
diff --git a/arch/blackfin/mach-bf561/boards/ezkit.c b/arch/blackfin/mach-bf561/boards/ezkit.c
index 551f866172cf..92938e79b9e3 100644
--- a/arch/blackfin/mach-bf561/boards/ezkit.c
+++ b/arch/blackfin/mach-bf561/boards/ezkit.c
@@ -523,14 +523,6 @@ static struct platform_device bfin_i2s = {
523}; 523};
524#endif 524#endif
525 525
526#if defined(CONFIG_SND_BF5XX_TDM) || defined(CONFIG_SND_BF5XX_TDM_MODULE)
527static struct platform_device bfin_tdm = {
528 .name = "bfin-tdm",
529 .id = CONFIG_SND_BF5XX_SPORT_NUM,
530 /* TODO: add platform data here */
531};
532#endif
533
534#if defined(CONFIG_SND_BF5XX_AC97) || defined(CONFIG_SND_BF5XX_AC97_MODULE) 526#if defined(CONFIG_SND_BF5XX_AC97) || defined(CONFIG_SND_BF5XX_AC97_MODULE)
535static struct platform_device bfin_ac97 = { 527static struct platform_device bfin_ac97 = {
536 .name = "bfin-ac97", 528 .name = "bfin-ac97",
@@ -542,7 +534,7 @@ static struct platform_device bfin_ac97 = {
542#if defined(CONFIG_SND_BF5XX_SOC_AD1836) \ 534#if defined(CONFIG_SND_BF5XX_SOC_AD1836) \
543 || defined(CONFIG_SND_BF5XX_SOC_AD1836_MODULE) 535 || defined(CONFIG_SND_BF5XX_SOC_AD1836_MODULE)
544static const char * const ad1836_link[] = { 536static const char * const ad1836_link[] = {
545 "bfin-tdm.0", 537 "bfin-i2s.0",
546 "spi0.4", 538 "spi0.4",
547}; 539};
548static struct platform_device bfin_ad1836_machine = { 540static struct platform_device bfin_ad1836_machine = {
@@ -611,10 +603,6 @@ static struct platform_device *ezkit_devices[] __initdata = {
611 &bfin_i2s, 603 &bfin_i2s,
612#endif 604#endif
613 605
614#if defined(CONFIG_SND_BF5XX_TDM) || defined(CONFIG_SND_BF5XX_TDM_MODULE)
615 &bfin_tdm,
616#endif
617
618#if defined(CONFIG_SND_BF5XX_AC97) || defined(CONFIG_SND_BF5XX_AC97_MODULE) 606#if defined(CONFIG_SND_BF5XX_AC97) || defined(CONFIG_SND_BF5XX_AC97_MODULE)
619 &bfin_ac97, 607 &bfin_ac97,
620#endif 608#endif
diff --git a/arch/blackfin/mach-bf609/boards/ezkit.c b/arch/blackfin/mach-bf609/boards/ezkit.c
index 97d701639585..bba40aed4273 100644
--- a/arch/blackfin/mach-bf609/boards/ezkit.c
+++ b/arch/blackfin/mach-bf609/boards/ezkit.c
@@ -821,7 +821,7 @@ static struct platform_device bfin_i2s = {
821#if defined(CONFIG_SND_BF5XX_SOC_AD1836) \ 821#if defined(CONFIG_SND_BF5XX_SOC_AD1836) \
822 || defined(CONFIG_SND_BF5XX_SOC_AD1836_MODULE) 822 || defined(CONFIG_SND_BF5XX_SOC_AD1836_MODULE)
823static const char * const ad1836_link[] = { 823static const char * const ad1836_link[] = {
824 "bfin-tdm.0", 824 "bfin-i2s.0",
825 "spi0.76", 825 "spi0.76",
826}; 826};
827static struct platform_device bfin_ad1836_machine = { 827static struct platform_device bfin_ad1836_machine = {
diff --git a/drivers/mfd/arizona-core.c b/drivers/mfd/arizona-core.c
index 6ab03043fd60..74b4481754fd 100644
--- a/drivers/mfd/arizona-core.c
+++ b/drivers/mfd/arizona-core.c
@@ -16,9 +16,13 @@
16#include <linux/interrupt.h> 16#include <linux/interrupt.h>
17#include <linux/mfd/core.h> 17#include <linux/mfd/core.h>
18#include <linux/module.h> 18#include <linux/module.h>
19#include <linux/of.h>
20#include <linux/of_device.h>
21#include <linux/of_gpio.h>
19#include <linux/pm_runtime.h> 22#include <linux/pm_runtime.h>
20#include <linux/regmap.h> 23#include <linux/regmap.h>
21#include <linux/regulator/consumer.h> 24#include <linux/regulator/consumer.h>
25#include <linux/regulator/machine.h>
22#include <linux/slab.h> 26#include <linux/slab.h>
23 27
24#include <linux/mfd/arizona/core.h> 28#include <linux/mfd/arizona/core.h>
@@ -344,6 +348,17 @@ static int arizona_runtime_resume(struct device *dev)
344 348
345 switch (arizona->type) { 349 switch (arizona->type) {
346 case WM5102: 350 case WM5102:
351 if (arizona->external_dcvdd) {
352 ret = regmap_update_bits(arizona->regmap,
353 ARIZONA_ISOLATION_CONTROL,
354 ARIZONA_ISOLATE_DCVDD1, 0);
355 if (ret != 0) {
356 dev_err(arizona->dev,
357 "Failed to connect DCVDD: %d\n", ret);
358 goto err;
359 }
360 }
361
347 ret = wm5102_patch(arizona); 362 ret = wm5102_patch(arizona);
348 if (ret != 0) { 363 if (ret != 0) {
349 dev_err(arizona->dev, "Failed to apply patch: %d\n", 364 dev_err(arizona->dev, "Failed to apply patch: %d\n",
@@ -365,6 +380,28 @@ static int arizona_runtime_resume(struct device *dev)
365 goto err; 380 goto err;
366 } 381 }
367 382
383 if (arizona->external_dcvdd) {
384 ret = regmap_update_bits(arizona->regmap,
385 ARIZONA_ISOLATION_CONTROL,
386 ARIZONA_ISOLATE_DCVDD1, 0);
387 if (ret != 0) {
388 dev_err(arizona->dev,
389 "Failed to connect DCVDD: %d\n", ret);
390 goto err;
391 }
392 }
393 break;
394 }
395
396 switch (arizona->type) {
397 case WM5102:
398 ret = wm5102_patch(arizona);
399 if (ret != 0) {
400 dev_err(arizona->dev, "Failed to apply patch: %d\n",
401 ret);
402 goto err;
403 }
404 default:
368 break; 405 break;
369 } 406 }
370 407
@@ -385,9 +422,22 @@ err:
385static int arizona_runtime_suspend(struct device *dev) 422static int arizona_runtime_suspend(struct device *dev)
386{ 423{
387 struct arizona *arizona = dev_get_drvdata(dev); 424 struct arizona *arizona = dev_get_drvdata(dev);
425 int ret;
388 426
389 dev_dbg(arizona->dev, "Entering AoD mode\n"); 427 dev_dbg(arizona->dev, "Entering AoD mode\n");
390 428
429 if (arizona->external_dcvdd) {
430 ret = regmap_update_bits(arizona->regmap,
431 ARIZONA_ISOLATION_CONTROL,
432 ARIZONA_ISOLATE_DCVDD1,
433 ARIZONA_ISOLATE_DCVDD1);
434 if (ret != 0) {
435 dev_err(arizona->dev, "Failed to isolate DCVDD: %d\n",
436 ret);
437 return ret;
438 }
439 }
440
391 regulator_disable(arizona->dcvdd); 441 regulator_disable(arizona->dcvdd);
392 regcache_cache_only(arizona->regmap, true); 442 regcache_cache_only(arizona->regmap, true);
393 regcache_mark_dirty(arizona->regmap); 443 regcache_mark_dirty(arizona->regmap);
@@ -397,6 +447,26 @@ static int arizona_runtime_suspend(struct device *dev)
397#endif 447#endif
398 448
399#ifdef CONFIG_PM_SLEEP 449#ifdef CONFIG_PM_SLEEP
450static int arizona_suspend(struct device *dev)
451{
452 struct arizona *arizona = dev_get_drvdata(dev);
453
454 dev_dbg(arizona->dev, "Suspend, disabling IRQ\n");
455 disable_irq(arizona->irq);
456
457 return 0;
458}
459
460static int arizona_suspend_late(struct device *dev)
461{
462 struct arizona *arizona = dev_get_drvdata(dev);
463
464 dev_dbg(arizona->dev, "Late suspend, reenabling IRQ\n");
465 enable_irq(arizona->irq);
466
467 return 0;
468}
469
400static int arizona_resume_noirq(struct device *dev) 470static int arizona_resume_noirq(struct device *dev)
401{ 471{
402 struct arizona *arizona = dev_get_drvdata(dev); 472 struct arizona *arizona = dev_get_drvdata(dev);
@@ -422,13 +492,78 @@ const struct dev_pm_ops arizona_pm_ops = {
422 SET_RUNTIME_PM_OPS(arizona_runtime_suspend, 492 SET_RUNTIME_PM_OPS(arizona_runtime_suspend,
423 arizona_runtime_resume, 493 arizona_runtime_resume,
424 NULL) 494 NULL)
425 SET_SYSTEM_SLEEP_PM_OPS(NULL, arizona_resume) 495 SET_SYSTEM_SLEEP_PM_OPS(arizona_suspend, arizona_resume)
426#ifdef CONFIG_PM_SLEEP 496#ifdef CONFIG_PM_SLEEP
497 .suspend_late = arizona_suspend_late,
427 .resume_noirq = arizona_resume_noirq, 498 .resume_noirq = arizona_resume_noirq,
428#endif 499#endif
429}; 500};
430EXPORT_SYMBOL_GPL(arizona_pm_ops); 501EXPORT_SYMBOL_GPL(arizona_pm_ops);
431 502
503#ifdef CONFIG_OF
504int arizona_of_get_type(struct device *dev)
505{
506 const struct of_device_id *id = of_match_device(arizona_of_match, dev);
507
508 if (id)
509 return (int)id->data;
510 else
511 return 0;
512}
513EXPORT_SYMBOL_GPL(arizona_of_get_type);
514
515static int arizona_of_get_core_pdata(struct arizona *arizona)
516{
517 int ret, i;
518
519 arizona->pdata.reset = of_get_named_gpio(arizona->dev->of_node,
520 "wlf,reset", 0);
521 if (arizona->pdata.reset < 0)
522 arizona->pdata.reset = 0;
523
524 arizona->pdata.ldoena = of_get_named_gpio(arizona->dev->of_node,
525 "wlf,ldoena", 0);
526 if (arizona->pdata.ldoena < 0)
527 arizona->pdata.ldoena = 0;
528
529 ret = of_property_read_u32_array(arizona->dev->of_node,
530 "wlf,gpio-defaults",
531 arizona->pdata.gpio_defaults,
532 ARRAY_SIZE(arizona->pdata.gpio_defaults));
533 if (ret >= 0) {
534 /*
535 * All values are literal except out of range values
536 * which are chip default, translate into platform
537 * data which uses 0 as chip default and out of range
538 * as zero.
539 */
540 for (i = 0; i < ARRAY_SIZE(arizona->pdata.gpio_defaults); i++) {
541 if (arizona->pdata.gpio_defaults[i] > 0xffff)
542 arizona->pdata.gpio_defaults[i] = 0;
543 if (arizona->pdata.gpio_defaults[i] == 0)
544 arizona->pdata.gpio_defaults[i] = 0x10000;
545 }
546 } else {
547 dev_err(arizona->dev, "Failed to parse GPIO defaults: %d\n",
548 ret);
549 }
550
551 return 0;
552}
553
554const struct of_device_id arizona_of_match[] = {
555 { .compatible = "wlf,wm5102", .data = (void *)WM5102 },
556 { .compatible = "wlf,wm5110", .data = (void *)WM5110 },
557 {},
558};
559EXPORT_SYMBOL_GPL(arizona_of_match);
560#else
561static inline int arizona_of_get_core_pdata(struct arizona *arizona)
562{
563 return 0;
564}
565#endif
566
432static struct mfd_cell early_devs[] = { 567static struct mfd_cell early_devs[] = {
433 { .name = "arizona-ldo1" }, 568 { .name = "arizona-ldo1" },
434}; 569};
@@ -462,6 +597,8 @@ int arizona_dev_init(struct arizona *arizona)
462 dev_set_drvdata(arizona->dev, arizona); 597 dev_set_drvdata(arizona->dev, arizona);
463 mutex_init(&arizona->clk_lock); 598 mutex_init(&arizona->clk_lock);
464 599
600 arizona_of_get_core_pdata(arizona);
601
465 if (dev_get_platdata(arizona->dev)) 602 if (dev_get_platdata(arizona->dev))
466 memcpy(&arizona->pdata, dev_get_platdata(arizona->dev), 603 memcpy(&arizona->pdata, dev_get_platdata(arizona->dev),
467 sizeof(arizona->pdata)); 604 sizeof(arizona->pdata));
@@ -536,51 +673,22 @@ int arizona_dev_init(struct arizona *arizona)
536 673
537 regcache_cache_only(arizona->regmap, false); 674 regcache_cache_only(arizona->regmap, false);
538 675
676 /* Verify that this is a chip we know about */
539 ret = regmap_read(arizona->regmap, ARIZONA_SOFTWARE_RESET, &reg); 677 ret = regmap_read(arizona->regmap, ARIZONA_SOFTWARE_RESET, &reg);
540 if (ret != 0) { 678 if (ret != 0) {
541 dev_err(dev, "Failed to read ID register: %d\n", ret); 679 dev_err(dev, "Failed to read ID register: %d\n", ret);
542 goto err_reset; 680 goto err_reset;
543 } 681 }
544 682
545 ret = regmap_read(arizona->regmap, ARIZONA_DEVICE_REVISION,
546 &arizona->rev);
547 if (ret != 0) {
548 dev_err(dev, "Failed to read revision register: %d\n", ret);
549 goto err_reset;
550 }
551 arizona->rev &= ARIZONA_DEVICE_REVISION_MASK;
552
553 switch (reg) { 683 switch (reg) {
554#ifdef CONFIG_MFD_WM5102
555 case 0x5102: 684 case 0x5102:
556 type_name = "WM5102";
557 if (arizona->type != WM5102) {
558 dev_err(arizona->dev, "WM5102 registered as %d\n",
559 arizona->type);
560 arizona->type = WM5102;
561 }
562 apply_patch = wm5102_patch;
563 arizona->rev &= 0x7;
564 break;
565#endif
566#ifdef CONFIG_MFD_WM5110
567 case 0x5110: 685 case 0x5110:
568 type_name = "WM5110";
569 if (arizona->type != WM5110) {
570 dev_err(arizona->dev, "WM5110 registered as %d\n",
571 arizona->type);
572 arizona->type = WM5110;
573 }
574 apply_patch = wm5110_patch;
575 break; 686 break;
576#endif
577 default: 687 default:
578 dev_err(arizona->dev, "Unknown device ID %x\n", reg); 688 dev_err(arizona->dev, "Unknown device ID: %x\n", reg);
579 goto err_reset; 689 goto err_reset;
580 } 690 }
581 691
582 dev_info(dev, "%s revision %c\n", type_name, arizona->rev + 'A');
583
584 /* If we have a /RESET GPIO we'll already be reset */ 692 /* If we have a /RESET GPIO we'll already be reset */
585 if (!arizona->pdata.reset) { 693 if (!arizona->pdata.reset) {
586 regcache_mark_dirty(arizona->regmap); 694 regcache_mark_dirty(arizona->regmap);
@@ -600,6 +708,7 @@ int arizona_dev_init(struct arizona *arizona)
600 } 708 }
601 } 709 }
602 710
711 /* Ensure device startup is complete */
603 switch (arizona->type) { 712 switch (arizona->type) {
604 case WM5102: 713 case WM5102:
605 ret = regmap_read(arizona->regmap, 0x19, &val); 714 ret = regmap_read(arizona->regmap, 0x19, &val);
@@ -620,6 +729,52 @@ int arizona_dev_init(struct arizona *arizona)
620 break; 729 break;
621 } 730 }
622 731
732 /* Read the device ID information & do device specific stuff */
733 ret = regmap_read(arizona->regmap, ARIZONA_SOFTWARE_RESET, &reg);
734 if (ret != 0) {
735 dev_err(dev, "Failed to read ID register: %d\n", ret);
736 goto err_reset;
737 }
738
739 ret = regmap_read(arizona->regmap, ARIZONA_DEVICE_REVISION,
740 &arizona->rev);
741 if (ret != 0) {
742 dev_err(dev, "Failed to read revision register: %d\n", ret);
743 goto err_reset;
744 }
745 arizona->rev &= ARIZONA_DEVICE_REVISION_MASK;
746
747 switch (reg) {
748#ifdef CONFIG_MFD_WM5102
749 case 0x5102:
750 type_name = "WM5102";
751 if (arizona->type != WM5102) {
752 dev_err(arizona->dev, "WM5102 registered as %d\n",
753 arizona->type);
754 arizona->type = WM5102;
755 }
756 apply_patch = wm5102_patch;
757 arizona->rev &= 0x7;
758 break;
759#endif
760#ifdef CONFIG_MFD_WM5110
761 case 0x5110:
762 type_name = "WM5110";
763 if (arizona->type != WM5110) {
764 dev_err(arizona->dev, "WM5110 registered as %d\n",
765 arizona->type);
766 arizona->type = WM5110;
767 }
768 apply_patch = wm5110_patch;
769 break;
770#endif
771 default:
772 dev_err(arizona->dev, "Unknown device ID %x\n", reg);
773 goto err_reset;
774 }
775
776 dev_info(dev, "%s revision %c\n", type_name, arizona->rev + 'A');
777
623 if (apply_patch) { 778 if (apply_patch) {
624 ret = apply_patch(arizona); 779 ret = apply_patch(arizona);
625 if (ret != 0) { 780 if (ret != 0) {
@@ -651,6 +806,14 @@ int arizona_dev_init(struct arizona *arizona)
651 arizona->pdata.gpio_defaults[i]); 806 arizona->pdata.gpio_defaults[i]);
652 } 807 }
653 808
809 /*
810 * LDO1 can only be used to supply DCVDD so if it has no
811 * consumers then DCVDD is supplied externally.
812 */
813 if (arizona->pdata.ldo1 &&
814 arizona->pdata.ldo1->num_consumer_supplies == 0)
815 arizona->external_dcvdd = true;
816
654 pm_runtime_set_autosuspend_delay(arizona->dev, 100); 817 pm_runtime_set_autosuspend_delay(arizona->dev, 100);
655 pm_runtime_use_autosuspend(arizona->dev); 818 pm_runtime_use_autosuspend(arizona->dev);
656 pm_runtime_enable(arizona->dev); 819 pm_runtime_enable(arizona->dev);
@@ -697,7 +860,7 @@ int arizona_dev_init(struct arizona *arizona)
697 if (arizona->pdata.micbias[i].discharge) 860 if (arizona->pdata.micbias[i].discharge)
698 val |= ARIZONA_MICB1_DISCH; 861 val |= ARIZONA_MICB1_DISCH;
699 862
700 if (arizona->pdata.micbias[i].fast_start) 863 if (arizona->pdata.micbias[i].soft_start)
701 val |= ARIZONA_MICB1_RATE; 864 val |= ARIZONA_MICB1_RATE;
702 865
703 if (arizona->pdata.micbias[i].bypass) 866 if (arizona->pdata.micbias[i].bypass)
@@ -809,6 +972,11 @@ int arizona_dev_exit(struct arizona *arizona)
809 arizona_free_irq(arizona, ARIZONA_IRQ_CLKGEN_ERR, arizona); 972 arizona_free_irq(arizona, ARIZONA_IRQ_CLKGEN_ERR, arizona);
810 pm_runtime_disable(arizona->dev); 973 pm_runtime_disable(arizona->dev);
811 arizona_irq_exit(arizona); 974 arizona_irq_exit(arizona);
975 if (arizona->pdata.reset)
976 gpio_set_value_cansleep(arizona->pdata.reset, 0);
977 regulator_disable(arizona->dcvdd);
978 regulator_bulk_disable(ARRAY_SIZE(arizona->core_supplies),
979 arizona->core_supplies);
812 return 0; 980 return 0;
813} 981}
814EXPORT_SYMBOL_GPL(arizona_dev_exit); 982EXPORT_SYMBOL_GPL(arizona_dev_exit);
diff --git a/drivers/mfd/arizona-i2c.c b/drivers/mfd/arizona-i2c.c
index 44a1bb969841..deb267ebf84e 100644
--- a/drivers/mfd/arizona-i2c.c
+++ b/drivers/mfd/arizona-i2c.c
@@ -27,9 +27,14 @@ static int arizona_i2c_probe(struct i2c_client *i2c,
27{ 27{
28 struct arizona *arizona; 28 struct arizona *arizona;
29 const struct regmap_config *regmap_config; 29 const struct regmap_config *regmap_config;
30 int ret; 30 int ret, type;
31 31
32 switch (id->driver_data) { 32 if (i2c->dev.of_node)
33 type = arizona_of_get_type(&i2c->dev);
34 else
35 type = id->driver_data;
36
37 switch (type) {
33#ifdef CONFIG_MFD_WM5102 38#ifdef CONFIG_MFD_WM5102
34 case WM5102: 39 case WM5102:
35 regmap_config = &wm5102_i2c_regmap; 40 regmap_config = &wm5102_i2c_regmap;
@@ -84,6 +89,7 @@ static struct i2c_driver arizona_i2c_driver = {
84 .name = "arizona", 89 .name = "arizona",
85 .owner = THIS_MODULE, 90 .owner = THIS_MODULE,
86 .pm = &arizona_pm_ops, 91 .pm = &arizona_pm_ops,
92 .of_match_table = of_match_ptr(arizona_of_match),
87 }, 93 },
88 .probe = arizona_i2c_probe, 94 .probe = arizona_i2c_probe,
89 .remove = arizona_i2c_remove, 95 .remove = arizona_i2c_remove,
diff --git a/drivers/mfd/arizona-spi.c b/drivers/mfd/arizona-spi.c
index b57e642d2b4a..47be7b35b5c5 100644
--- a/drivers/mfd/arizona-spi.c
+++ b/drivers/mfd/arizona-spi.c
@@ -27,9 +27,14 @@ static int arizona_spi_probe(struct spi_device *spi)
27 const struct spi_device_id *id = spi_get_device_id(spi); 27 const struct spi_device_id *id = spi_get_device_id(spi);
28 struct arizona *arizona; 28 struct arizona *arizona;
29 const struct regmap_config *regmap_config; 29 const struct regmap_config *regmap_config;
30 int ret; 30 int ret, type;
31 31
32 switch (id->driver_data) { 32 if (spi->dev.of_node)
33 type = arizona_of_get_type(&spi->dev);
34 else
35 type = id->driver_data;
36
37 switch (type) {
33#ifdef CONFIG_MFD_WM5102 38#ifdef CONFIG_MFD_WM5102
34 case WM5102: 39 case WM5102:
35 regmap_config = &wm5102_spi_regmap; 40 regmap_config = &wm5102_spi_regmap;
@@ -84,6 +89,7 @@ static struct spi_driver arizona_spi_driver = {
84 .name = "arizona", 89 .name = "arizona",
85 .owner = THIS_MODULE, 90 .owner = THIS_MODULE,
86 .pm = &arizona_pm_ops, 91 .pm = &arizona_pm_ops,
92 .of_match_table = of_match_ptr(arizona_of_match),
87 }, 93 },
88 .probe = arizona_spi_probe, 94 .probe = arizona_spi_probe,
89 .remove = arizona_spi_remove, 95 .remove = arizona_spi_remove,
diff --git a/drivers/mfd/arizona.h b/drivers/mfd/arizona.h
index 9798ae5da67b..db55d9854a55 100644
--- a/drivers/mfd/arizona.h
+++ b/drivers/mfd/arizona.h
@@ -13,6 +13,7 @@
13#ifndef _WM5102_H 13#ifndef _WM5102_H
14#define _WM5102_H 14#define _WM5102_H
15 15
16#include <linux/of.h>
16#include <linux/regmap.h> 17#include <linux/regmap.h>
17#include <linux/pm.h> 18#include <linux/pm.h>
18 19
@@ -26,6 +27,8 @@ extern const struct regmap_config wm5110_spi_regmap;
26 27
27extern const struct dev_pm_ops arizona_pm_ops; 28extern const struct dev_pm_ops arizona_pm_ops;
28 29
30extern const struct of_device_id arizona_of_match[];
31
29extern const struct regmap_irq_chip wm5102_aod; 32extern const struct regmap_irq_chip wm5102_aod;
30extern const struct regmap_irq_chip wm5102_irq; 33extern const struct regmap_irq_chip wm5102_irq;
31 34
@@ -37,4 +40,13 @@ int arizona_dev_exit(struct arizona *arizona);
37int arizona_irq_init(struct arizona *arizona); 40int arizona_irq_init(struct arizona *arizona);
38int arizona_irq_exit(struct arizona *arizona); 41int arizona_irq_exit(struct arizona *arizona);
39 42
43#ifdef CONFIG_OF
44int arizona_of_get_type(struct device *dev);
45#else
46static inline int arizona_of_get_type(struct device *dev)
47{
48 return 0;
49}
50#endif
51
40#endif 52#endif
diff --git a/drivers/mfd/wm5102-tables.c b/drivers/mfd/wm5102-tables.c
index 155c4a1a6a99..802dd3cb18cf 100644
--- a/drivers/mfd/wm5102-tables.c
+++ b/drivers/mfd/wm5102-tables.c
@@ -65,7 +65,8 @@ static const struct reg_default wm5102_revb_patch[] = {
65 { 0x418, 0xa080 }, 65 { 0x418, 0xa080 },
66 { 0x420, 0xa080 }, 66 { 0x420, 0xa080 },
67 { 0x428, 0xe000 }, 67 { 0x428, 0xe000 },
68 { 0x443, 0xDC1A }, 68 { 0x442, 0x3F0A },
69 { 0x443, 0xDC1F },
69 { 0x4B0, 0x0066 }, 70 { 0x4B0, 0x0066 },
70 { 0x458, 0x000b }, 71 { 0x458, 0x000b },
71 { 0x212, 0x0000 }, 72 { 0x212, 0x0000 },
@@ -424,6 +425,9 @@ static const struct reg_default wm5102_reg_default[] = {
424 { 0x00000435, 0x0180 }, /* R1077 - DAC Digital Volume 5R */ 425 { 0x00000435, 0x0180 }, /* R1077 - DAC Digital Volume 5R */
425 { 0x00000436, 0x0081 }, /* R1078 - DAC Volume Limit 5R */ 426 { 0x00000436, 0x0081 }, /* R1078 - DAC Volume Limit 5R */
426 { 0x00000437, 0x0200 }, /* R1079 - Noise Gate Select 5R */ 427 { 0x00000437, 0x0200 }, /* R1079 - Noise Gate Select 5R */
428 { 0x00000440, 0x8FFF }, /* R1088 - DRE Enable */
429 { 0x00000442, 0x3F0A }, /* R1090 - DRE Control 2 */
430 { 0x00000443, 0xDC1F }, /* R1090 - DRE Control 3 */
427 { 0x00000450, 0x0000 }, /* R1104 - DAC AEC Control 1 */ 431 { 0x00000450, 0x0000 }, /* R1104 - DAC AEC Control 1 */
428 { 0x00000458, 0x000B }, /* R1112 - Noise Gate Control */ 432 { 0x00000458, 0x000B }, /* R1112 - Noise Gate Control */
429 { 0x00000490, 0x0069 }, /* R1168 - PDM SPK1 CTRL 1 */ 433 { 0x00000490, 0x0069 }, /* R1168 - PDM SPK1 CTRL 1 */
@@ -1197,6 +1201,9 @@ static bool wm5102_readable_register(struct device *dev, unsigned int reg)
1197 case ARIZONA_DAC_DIGITAL_VOLUME_5R: 1201 case ARIZONA_DAC_DIGITAL_VOLUME_5R:
1198 case ARIZONA_DAC_VOLUME_LIMIT_5R: 1202 case ARIZONA_DAC_VOLUME_LIMIT_5R:
1199 case ARIZONA_NOISE_GATE_SELECT_5R: 1203 case ARIZONA_NOISE_GATE_SELECT_5R:
1204 case ARIZONA_DRE_ENABLE:
1205 case ARIZONA_DRE_CONTROL_2:
1206 case ARIZONA_DRE_CONTROL_3:
1200 case ARIZONA_DAC_AEC_CONTROL_1: 1207 case ARIZONA_DAC_AEC_CONTROL_1:
1201 case ARIZONA_NOISE_GATE_CONTROL: 1208 case ARIZONA_NOISE_GATE_CONTROL:
1202 case ARIZONA_PDM_SPK1_CTRL_1: 1209 case ARIZONA_PDM_SPK1_CTRL_1:
diff --git a/drivers/mfd/wm5110-tables.c b/drivers/mfd/wm5110-tables.c
index c41599815299..2a7972349159 100644
--- a/drivers/mfd/wm5110-tables.c
+++ b/drivers/mfd/wm5110-tables.c
@@ -2273,18 +2273,22 @@ static bool wm5110_readable_register(struct device *dev, unsigned int reg)
2273 case ARIZONA_DSP1_CLOCKING_1: 2273 case ARIZONA_DSP1_CLOCKING_1:
2274 case ARIZONA_DSP1_STATUS_1: 2274 case ARIZONA_DSP1_STATUS_1:
2275 case ARIZONA_DSP1_STATUS_2: 2275 case ARIZONA_DSP1_STATUS_2:
2276 case ARIZONA_DSP1_STATUS_3:
2276 case ARIZONA_DSP2_CONTROL_1: 2277 case ARIZONA_DSP2_CONTROL_1:
2277 case ARIZONA_DSP2_CLOCKING_1: 2278 case ARIZONA_DSP2_CLOCKING_1:
2278 case ARIZONA_DSP2_STATUS_1: 2279 case ARIZONA_DSP2_STATUS_1:
2279 case ARIZONA_DSP2_STATUS_2: 2280 case ARIZONA_DSP2_STATUS_2:
2281 case ARIZONA_DSP2_STATUS_3:
2280 case ARIZONA_DSP3_CONTROL_1: 2282 case ARIZONA_DSP3_CONTROL_1:
2281 case ARIZONA_DSP3_CLOCKING_1: 2283 case ARIZONA_DSP3_CLOCKING_1:
2282 case ARIZONA_DSP3_STATUS_1: 2284 case ARIZONA_DSP3_STATUS_1:
2283 case ARIZONA_DSP3_STATUS_2: 2285 case ARIZONA_DSP3_STATUS_2:
2286 case ARIZONA_DSP3_STATUS_3:
2284 case ARIZONA_DSP4_CONTROL_1: 2287 case ARIZONA_DSP4_CONTROL_1:
2285 case ARIZONA_DSP4_CLOCKING_1: 2288 case ARIZONA_DSP4_CLOCKING_1:
2286 case ARIZONA_DSP4_STATUS_1: 2289 case ARIZONA_DSP4_STATUS_1:
2287 case ARIZONA_DSP4_STATUS_2: 2290 case ARIZONA_DSP4_STATUS_2:
2291 case ARIZONA_DSP4_STATUS_3:
2288 return true; 2292 return true;
2289 default: 2293 default:
2290 return false; 2294 return false;
@@ -2334,12 +2338,16 @@ static bool wm5110_volatile_register(struct device *dev, unsigned int reg)
2334 case ARIZONA_DSP1_CLOCKING_1: 2338 case ARIZONA_DSP1_CLOCKING_1:
2335 case ARIZONA_DSP1_STATUS_1: 2339 case ARIZONA_DSP1_STATUS_1:
2336 case ARIZONA_DSP1_STATUS_2: 2340 case ARIZONA_DSP1_STATUS_2:
2341 case ARIZONA_DSP1_STATUS_3:
2337 case ARIZONA_DSP2_STATUS_1: 2342 case ARIZONA_DSP2_STATUS_1:
2338 case ARIZONA_DSP2_STATUS_2: 2343 case ARIZONA_DSP2_STATUS_2:
2344 case ARIZONA_DSP2_STATUS_3:
2339 case ARIZONA_DSP3_STATUS_1: 2345 case ARIZONA_DSP3_STATUS_1:
2340 case ARIZONA_DSP3_STATUS_2: 2346 case ARIZONA_DSP3_STATUS_2:
2347 case ARIZONA_DSP3_STATUS_3:
2341 case ARIZONA_DSP4_STATUS_1: 2348 case ARIZONA_DSP4_STATUS_1:
2342 case ARIZONA_DSP4_STATUS_2: 2349 case ARIZONA_DSP4_STATUS_2:
2350 case ARIZONA_DSP4_STATUS_3:
2343 return true; 2351 return true;
2344 default: 2352 default:
2345 return false; 2353 return false;
diff --git a/drivers/misc/atmel-ssc.c b/drivers/misc/atmel-ssc.c
index 1abd5ad59925..f7b90661e321 100644
--- a/drivers/misc/atmel-ssc.c
+++ b/drivers/misc/atmel-ssc.c
@@ -58,7 +58,7 @@ struct ssc_device *ssc_request(unsigned int ssc_num)
58 ssc->user++; 58 ssc->user++;
59 spin_unlock(&user_lock); 59 spin_unlock(&user_lock);
60 60
61 clk_enable(ssc->clk); 61 clk_prepare_enable(ssc->clk);
62 62
63 return ssc; 63 return ssc;
64} 64}
@@ -69,7 +69,7 @@ void ssc_free(struct ssc_device *ssc)
69 spin_lock(&user_lock); 69 spin_lock(&user_lock);
70 if (ssc->user) { 70 if (ssc->user) {
71 ssc->user--; 71 ssc->user--;
72 clk_disable(ssc->clk); 72 clk_disable_unprepare(ssc->clk);
73 } else { 73 } else {
74 dev_dbg(&ssc->pdev->dev, "device already free\n"); 74 dev_dbg(&ssc->pdev->dev, "device already free\n");
75 } 75 }
@@ -167,10 +167,10 @@ static int ssc_probe(struct platform_device *pdev)
167 } 167 }
168 168
169 /* disable all interrupts */ 169 /* disable all interrupts */
170 clk_enable(ssc->clk); 170 clk_prepare_enable(ssc->clk);
171 ssc_writel(ssc->regs, IDR, -1); 171 ssc_writel(ssc->regs, IDR, -1);
172 ssc_readl(ssc->regs, SR); 172 ssc_readl(ssc->regs, SR);
173 clk_disable(ssc->clk); 173 clk_disable_unprepare(ssc->clk);
174 174
175 ssc->irq = platform_get_irq(pdev, 0); 175 ssc->irq = platform_get_irq(pdev, 0);
176 if (!ssc->irq) { 176 if (!ssc->irq) {
diff --git a/include/linux/mfd/arizona/core.h b/include/linux/mfd/arizona/core.h
index cc281368dc55..f797bb9b8b56 100644
--- a/include/linux/mfd/arizona/core.h
+++ b/include/linux/mfd/arizona/core.h
@@ -95,6 +95,8 @@ struct arizona {
95 95
96 struct arizona_pdata pdata; 96 struct arizona_pdata pdata;
97 97
98 unsigned int external_dcvdd:1;
99
98 int irq; 100 int irq;
99 struct irq_domain *virq; 101 struct irq_domain *virq;
100 struct regmap_irq_chip_data *aod_irq_chip; 102 struct regmap_irq_chip_data *aod_irq_chip;
diff --git a/include/linux/mfd/arizona/pdata.h b/include/linux/mfd/arizona/pdata.h
index 80dead1f7100..12a5c135c746 100644
--- a/include/linux/mfd/arizona/pdata.h
+++ b/include/linux/mfd/arizona/pdata.h
@@ -77,7 +77,7 @@ struct arizona_micbias {
77 int mV; /** Regulated voltage */ 77 int mV; /** Regulated voltage */
78 unsigned int ext_cap:1; /** External capacitor fitted */ 78 unsigned int ext_cap:1; /** External capacitor fitted */
79 unsigned int discharge:1; /** Actively discharge */ 79 unsigned int discharge:1; /** Actively discharge */
80 unsigned int fast_start:1; /** Enable aggressive startup ramp rate */ 80 unsigned int soft_start:1; /** Disable aggressive startup ramp rate */
81 unsigned int bypass:1; /** Use bypass mode */ 81 unsigned int bypass:1; /** Use bypass mode */
82}; 82};
83 83
diff --git a/include/linux/mfd/arizona/registers.h b/include/linux/mfd/arizona/registers.h
index 715b6ba3d52a..4706d3d46e56 100644
--- a/include/linux/mfd/arizona/registers.h
+++ b/include/linux/mfd/arizona/registers.h
@@ -215,6 +215,9 @@
215#define ARIZONA_DAC_DIGITAL_VOLUME_6R 0x43D 215#define ARIZONA_DAC_DIGITAL_VOLUME_6R 0x43D
216#define ARIZONA_DAC_VOLUME_LIMIT_6R 0x43E 216#define ARIZONA_DAC_VOLUME_LIMIT_6R 0x43E
217#define ARIZONA_NOISE_GATE_SELECT_6R 0x43F 217#define ARIZONA_NOISE_GATE_SELECT_6R 0x43F
218#define ARIZONA_DRE_ENABLE 0x440
219#define ARIZONA_DRE_CONTROL_2 0x442
220#define ARIZONA_DRE_CONTROL_3 0x443
218#define ARIZONA_DAC_AEC_CONTROL_1 0x450 221#define ARIZONA_DAC_AEC_CONTROL_1 0x450
219#define ARIZONA_NOISE_GATE_CONTROL 0x458 222#define ARIZONA_NOISE_GATE_CONTROL 0x458
220#define ARIZONA_PDM_SPK1_CTRL_1 0x490 223#define ARIZONA_PDM_SPK1_CTRL_1 0x490
@@ -1002,6 +1005,7 @@
1002#define ARIZONA_DSP2_CLOCKING_1 0x1201 1005#define ARIZONA_DSP2_CLOCKING_1 0x1201
1003#define ARIZONA_DSP2_STATUS_1 0x1204 1006#define ARIZONA_DSP2_STATUS_1 0x1204
1004#define ARIZONA_DSP2_STATUS_2 0x1205 1007#define ARIZONA_DSP2_STATUS_2 0x1205
1008#define ARIZONA_DSP2_STATUS_3 0x1206
1005#define ARIZONA_DSP2_SCRATCH_0 0x1240 1009#define ARIZONA_DSP2_SCRATCH_0 0x1240
1006#define ARIZONA_DSP2_SCRATCH_1 0x1241 1010#define ARIZONA_DSP2_SCRATCH_1 0x1241
1007#define ARIZONA_DSP2_SCRATCH_2 0x1242 1011#define ARIZONA_DSP2_SCRATCH_2 0x1242
@@ -1010,6 +1014,7 @@
1010#define ARIZONA_DSP3_CLOCKING_1 0x1301 1014#define ARIZONA_DSP3_CLOCKING_1 0x1301
1011#define ARIZONA_DSP3_STATUS_1 0x1304 1015#define ARIZONA_DSP3_STATUS_1 0x1304
1012#define ARIZONA_DSP3_STATUS_2 0x1305 1016#define ARIZONA_DSP3_STATUS_2 0x1305
1017#define ARIZONA_DSP3_STATUS_3 0x1306
1013#define ARIZONA_DSP3_SCRATCH_0 0x1340 1018#define ARIZONA_DSP3_SCRATCH_0 0x1340
1014#define ARIZONA_DSP3_SCRATCH_1 0x1341 1019#define ARIZONA_DSP3_SCRATCH_1 0x1341
1015#define ARIZONA_DSP3_SCRATCH_2 0x1342 1020#define ARIZONA_DSP3_SCRATCH_2 0x1342
@@ -1018,6 +1023,7 @@
1018#define ARIZONA_DSP4_CLOCKING_1 0x1401 1023#define ARIZONA_DSP4_CLOCKING_1 0x1401
1019#define ARIZONA_DSP4_STATUS_1 0x1404 1024#define ARIZONA_DSP4_STATUS_1 0x1404
1020#define ARIZONA_DSP4_STATUS_2 0x1405 1025#define ARIZONA_DSP4_STATUS_2 0x1405
1026#define ARIZONA_DSP4_STATUS_3 0x1406
1021#define ARIZONA_DSP4_SCRATCH_0 0x1440 1027#define ARIZONA_DSP4_SCRATCH_0 0x1440
1022#define ARIZONA_DSP4_SCRATCH_1 0x1441 1028#define ARIZONA_DSP4_SCRATCH_1 0x1441
1023#define ARIZONA_DSP4_SCRATCH_2 0x1442 1029#define ARIZONA_DSP4_SCRATCH_2 0x1442
@@ -3130,6 +3136,47 @@
3130#define ARIZONA_OUT6R_NGATE_SRC_WIDTH 12 /* OUT6R_NGATE_SRC - [11:0] */ 3136#define ARIZONA_OUT6R_NGATE_SRC_WIDTH 12 /* OUT6R_NGATE_SRC - [11:0] */
3131 3137
3132/* 3138/*
3139 * R1088 (0x440) - DRE Enable
3140 */
3141#define ARIZONA_DRE3L_ENA 0x0010 /* DRE3L_ENA */
3142#define ARIZONA_DRE3L_ENA_MASK 0x0010 /* DRE3L_ENA */
3143#define ARIZONA_DRE3L_ENA_SHIFT 4 /* DRE3L_ENA */
3144#define ARIZONA_DRE3L_ENA_WIDTH 1 /* DRE3L_ENA */
3145#define ARIZONA_DRE2R_ENA 0x0008 /* DRE2R_ENA */
3146#define ARIZONA_DRE2R_ENA_MASK 0x0008 /* DRE2R_ENA */
3147#define ARIZONA_DRE2R_ENA_SHIFT 3 /* DRE2R_ENA */
3148#define ARIZONA_DRE2R_ENA_WIDTH 1 /* DRE2R_ENA */
3149#define ARIZONA_DRE2L_ENA 0x0004 /* DRE2L_ENA */
3150#define ARIZONA_DRE2L_ENA_MASK 0x0004 /* DRE2L_ENA */
3151#define ARIZONA_DRE2L_ENA_SHIFT 2 /* DRE2L_ENA */
3152#define ARIZONA_DRE2L_ENA_WIDTH 1 /* DRE2L_ENA */
3153#define ARIZONA_DRE1R_ENA 0x0002 /* DRE1R_ENA */
3154#define ARIZONA_DRE1R_ENA_MASK 0x0002 /* DRE1R_ENA */
3155#define ARIZONA_DRE1R_ENA_SHIFT 1 /* DRE1R_ENA */
3156#define ARIZONA_DRE1R_ENA_WIDTH 1 /* DRE1R_ENA */
3157#define ARIZONA_DRE1L_ENA 0x0001 /* DRE1L_ENA */
3158#define ARIZONA_DRE1L_ENA_MASK 0x0001 /* DRE1L_ENA */
3159#define ARIZONA_DRE1L_ENA_SHIFT 0 /* DRE1L_ENA */
3160#define ARIZONA_DRE1L_ENA_WIDTH 1 /* DRE1L_ENA */
3161
3162/*
3163 * R1090 (0x442) - DRE Control 2
3164 */
3165#define ARIZONA_DRE_T_LOW_MASK 0x3F00 /* DRE_T_LOW - [13:8] */
3166#define ARIZONA_DRE_T_LOW_SHIFT 8 /* DRE_T_LOW - [13:8] */
3167#define ARIZONA_DRE_T_LOW_WIDTH 6 /* DRE_T_LOW - [13:8] */
3168
3169/*
3170 * R1091 (0x443) - DRE Control 3
3171 */
3172#define ARIZONA_DRE_GAIN_SHIFT_MASK 0xC000 /* DRE_GAIN_SHIFT - [15:14] */
3173#define ARIZONA_DRE_GAIN_SHIFT_SHIFT 14 /* DRE_GAIN_SHIFT - [15:14] */
3174#define ARIZONA_DRE_GAIN_SHIFT_WIDTH 2 /* DRE_GAIN_SHIFT - [15:14] */
3175#define ARIZONA_DRE_LOW_LEVEL_ABS_MASK 0x000F /* LOW_LEVEL_ABS - [3:0] */
3176#define ARIZONA_DRE_LOW_LEVEL_ABS_SHIFT 0 /* LOW_LEVEL_ABS - [3:0] */
3177#define ARIZONA_DRE_LOW_LEVEL_ABS_WIDTH 4 /* LOW_LEVEL_ABS - [3:0] */
3178
3179/*
3133 * R1104 (0x450) - DAC AEC Control 1 3180 * R1104 (0x450) - DAC AEC Control 1
3134 */ 3181 */
3135#define ARIZONA_AEC_LOOPBACK_SRC_MASK 0x003C /* AEC_LOOPBACK_SRC - [5:2] */ 3182#define ARIZONA_AEC_LOOPBACK_SRC_MASK 0x003C /* AEC_LOOPBACK_SRC - [5:2] */
diff --git a/include/linux/mfd/twl6040.h b/include/linux/mfd/twl6040.h
index 94ac944d12f0..7e7fbce7a308 100644
--- a/include/linux/mfd/twl6040.h
+++ b/include/linux/mfd/twl6040.h
@@ -125,8 +125,15 @@
125 125
126#define TWL6040_HSDACENA (1 << 0) 126#define TWL6040_HSDACENA (1 << 0)
127#define TWL6040_HSDACMODE (1 << 1) 127#define TWL6040_HSDACMODE (1 << 1)
128#define TWL6040_HSDRVENA (1 << 2)
128#define TWL6040_HSDRVMODE (1 << 3) 129#define TWL6040_HSDRVMODE (1 << 3)
129 130
131/* HFLCTL/R (0x14/0x16) fields */
132
133#define TWL6040_HFDACENA (1 << 0)
134#define TWL6040_HFPGAENA (1 << 1)
135#define TWL6040_HFDRVENA (1 << 4)
136
130/* VIBCTLL/R (0x18/0x1A) fields */ 137/* VIBCTLL/R (0x18/0x1A) fields */
131 138
132#define TWL6040_VIBENA (1 << 0) 139#define TWL6040_VIBENA (1 << 0)
diff --git a/include/linux/mfd/wm8994/pdata.h b/include/linux/mfd/wm8994/pdata.h
index 68e776594889..b5046f6313a9 100644
--- a/include/linux/mfd/wm8994/pdata.h
+++ b/include/linux/mfd/wm8994/pdata.h
@@ -182,6 +182,11 @@ struct wm8994_pdata {
182 */ 182 */
183 int micdet_delay; 183 int micdet_delay;
184 184
185 /* Delay between microphone detect completing and reporting on
186 * insert (specified in ms)
187 */
188 int mic_id_delay;
189
185 /* IRQ for microphone detection if brought out directly as a 190 /* IRQ for microphone detection if brought out directly as a
186 * signal. 191 * signal.
187 */ 192 */
diff --git a/include/linux/mfd/wm8994/registers.h b/include/linux/mfd/wm8994/registers.h
index 053548961c15..db8cef3d5321 100644
--- a/include/linux/mfd/wm8994/registers.h
+++ b/include/linux/mfd/wm8994/registers.h
@@ -2668,6 +2668,10 @@
2668/* 2668/*
2669 * R772 (0x304) - AIF1ADC LRCLK 2669 * R772 (0x304) - AIF1ADC LRCLK
2670 */ 2670 */
2671#define WM8958_AIF1_LRCLK_INV 0x1000 /* AIF1_LRCLK_INV */
2672#define WM8958_AIF1_LRCLK_INV_MASK 0x1000 /* AIF1_LRCLK_INV */
2673#define WM8958_AIF1_LRCLK_INV_SHIFT 12 /* AIF1_LRCLK_INV */
2674#define WM8958_AIF1_LRCLK_INV_WIDTH 1 /* AIF1_LRCLK_INV */
2671#define WM8994_AIF1ADC_LRCLK_DIR 0x0800 /* AIF1ADC_LRCLK_DIR */ 2675#define WM8994_AIF1ADC_LRCLK_DIR 0x0800 /* AIF1ADC_LRCLK_DIR */
2672#define WM8994_AIF1ADC_LRCLK_DIR_MASK 0x0800 /* AIF1ADC_LRCLK_DIR */ 2676#define WM8994_AIF1ADC_LRCLK_DIR_MASK 0x0800 /* AIF1ADC_LRCLK_DIR */
2673#define WM8994_AIF1ADC_LRCLK_DIR_SHIFT 11 /* AIF1ADC_LRCLK_DIR */ 2677#define WM8994_AIF1ADC_LRCLK_DIR_SHIFT 11 /* AIF1ADC_LRCLK_DIR */
@@ -2679,6 +2683,10 @@
2679/* 2683/*
2680 * R773 (0x305) - AIF1DAC LRCLK 2684 * R773 (0x305) - AIF1DAC LRCLK
2681 */ 2685 */
2686#define WM8958_AIF1_LRCLK_INV 0x1000 /* AIF1_LRCLK_INV */
2687#define WM8958_AIF1_LRCLK_INV_MASK 0x1000 /* AIF1_LRCLK_INV */
2688#define WM8958_AIF1_LRCLK_INV_SHIFT 12 /* AIF1_LRCLK_INV */
2689#define WM8958_AIF1_LRCLK_INV_WIDTH 1 /* AIF1_LRCLK_INV */
2682#define WM8994_AIF1DAC_LRCLK_DIR 0x0800 /* AIF1DAC_LRCLK_DIR */ 2690#define WM8994_AIF1DAC_LRCLK_DIR 0x0800 /* AIF1DAC_LRCLK_DIR */
2683#define WM8994_AIF1DAC_LRCLK_DIR_MASK 0x0800 /* AIF1DAC_LRCLK_DIR */ 2691#define WM8994_AIF1DAC_LRCLK_DIR_MASK 0x0800 /* AIF1DAC_LRCLK_DIR */
2684#define WM8994_AIF1DAC_LRCLK_DIR_SHIFT 11 /* AIF1DAC_LRCLK_DIR */ 2692#define WM8994_AIF1DAC_LRCLK_DIR_SHIFT 11 /* AIF1DAC_LRCLK_DIR */
diff --git a/include/linux/platform_data/ssm2518.h b/include/linux/platform_data/ssm2518.h
new file mode 100644
index 000000000000..9a8e3ea287e3
--- /dev/null
+++ b/include/linux/platform_data/ssm2518.h
@@ -0,0 +1,22 @@
1/*
2 * SSM2518 amplifier audio driver
3 *
4 * Copyright 2013 Analog Devices Inc.
5 * Author: Lars-Peter Clausen <lars@metafoo.de>
6 *
7 * Licensed under the GPL-2.
8 */
9
10#ifndef __LINUX_PLATFORM_DATA_SSM2518_H__
11#define __LINUX_PLATFORM_DATA_SSM2518_H__
12
13/**
14 * struct ssm2518_platform_data - Platform data for the ssm2518 driver
15 * @enable_gpio: GPIO connected to the nSD pin. Set to -1 if the nSD pin is
16 * hardwired.
17 */
18struct ssm2518_platform_data {
19 int enable_gpio;
20};
21
22#endif
diff --git a/include/sound/control.h b/include/sound/control.h
index 34bc93d80d55..5358892b1b39 100644
--- a/include/sound/control.h
+++ b/include/sound/control.h
@@ -233,7 +233,8 @@ snd_ctl_add_slave_uncached(struct snd_kcontrol *master,
233int snd_ctl_add_vmaster_hook(struct snd_kcontrol *kctl, 233int snd_ctl_add_vmaster_hook(struct snd_kcontrol *kctl,
234 void (*hook)(void *private_data, int), 234 void (*hook)(void *private_data, int),
235 void *private_data); 235 void *private_data);
236void snd_ctl_sync_vmaster_hook(struct snd_kcontrol *kctl); 236void snd_ctl_sync_vmaster(struct snd_kcontrol *kctl, bool hook_only);
237#define snd_ctl_sync_vmaster_hook(kctl) snd_ctl_sync_vmaster(kctl, true)
237 238
238/* 239/*
239 * Helper functions for jack-detection controls 240 * Helper functions for jack-detection controls
diff --git a/include/sound/core.h b/include/sound/core.h
index 5bfe5136441c..c586617cfa0d 100644
--- a/include/sound/core.h
+++ b/include/sound/core.h
@@ -30,7 +30,7 @@
30 30
31/* number of supported soundcards */ 31/* number of supported soundcards */
32#ifdef CONFIG_SND_DYNAMIC_MINORS 32#ifdef CONFIG_SND_DYNAMIC_MINORS
33#define SNDRV_CARDS 32 33#define SNDRV_CARDS CONFIG_SND_MAX_CARDS
34#else 34#else
35#define SNDRV_CARDS 8 /* don't change - minor numbers */ 35#define SNDRV_CARDS 8 /* don't change - minor numbers */
36#endif 36#endif
diff --git a/include/sound/pcm.h b/include/sound/pcm.h
index b48792fe386b..84b10f9a2832 100644
--- a/include/sound/pcm.h
+++ b/include/sound/pcm.h
@@ -384,7 +384,7 @@ struct snd_pcm_substream {
384 unsigned int dma_buf_id; 384 unsigned int dma_buf_id;
385 size_t dma_max; 385 size_t dma_max;
386 /* -- hardware operations -- */ 386 /* -- hardware operations -- */
387 struct snd_pcm_ops *ops; 387 const struct snd_pcm_ops *ops;
388 /* -- runtime information -- */ 388 /* -- runtime information -- */
389 struct snd_pcm_runtime *runtime; 389 struct snd_pcm_runtime *runtime;
390 /* -- timer section -- */ 390 /* -- timer section -- */
@@ -871,7 +871,8 @@ const unsigned char *snd_pcm_format_silence_64(snd_pcm_format_t format);
871int snd_pcm_format_set_silence(snd_pcm_format_t format, void *buf, unsigned int frames); 871int snd_pcm_format_set_silence(snd_pcm_format_t format, void *buf, unsigned int frames);
872snd_pcm_format_t snd_pcm_build_linear_format(int width, int unsigned, int big_endian); 872snd_pcm_format_t snd_pcm_build_linear_format(int width, int unsigned, int big_endian);
873 873
874void snd_pcm_set_ops(struct snd_pcm * pcm, int direction, struct snd_pcm_ops *ops); 874void snd_pcm_set_ops(struct snd_pcm * pcm, int direction,
875 const struct snd_pcm_ops *ops);
875void snd_pcm_set_sync(struct snd_pcm_substream *substream); 876void snd_pcm_set_sync(struct snd_pcm_substream *substream);
876int snd_pcm_lib_interleave_len(struct snd_pcm_substream *substream); 877int snd_pcm_lib_interleave_len(struct snd_pcm_substream *substream);
877int snd_pcm_lib_ioctl(struct snd_pcm_substream *substream, 878int snd_pcm_lib_ioctl(struct snd_pcm_substream *substream,
diff --git a/include/sound/rt5640.h b/include/sound/rt5640.h
new file mode 100644
index 000000000000..27cc75ed67f8
--- /dev/null
+++ b/include/sound/rt5640.h
@@ -0,0 +1,22 @@
1/*
2 * linux/sound/rt5640.h -- Platform data for RT5640
3 *
4 * Copyright 2011 Realtek Microelectronics
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 */
10
11#ifndef __LINUX_SND_RT5640_H
12#define __LINUX_SND_RT5640_H
13
14struct rt5640_platform_data {
15 /* IN1 & IN2 can optionally be differential */
16 bool in1_diff;
17 bool in2_diff;
18
19 int ldo1_en; /* GPIO for LDO1_EN */
20};
21
22#endif
diff --git a/include/sound/soc-dapm.h b/include/sound/soc-dapm.h
index 385c6329a967..3e479f4e15f5 100644
--- a/include/sound/soc-dapm.h
+++ b/include/sound/soc-dapm.h
@@ -311,6 +311,8 @@ struct device;
311#define SND_SOC_DAPM_POST_PMD 0x8 /* after widget power down */ 311#define SND_SOC_DAPM_POST_PMD 0x8 /* after widget power down */
312#define SND_SOC_DAPM_PRE_REG 0x10 /* before audio path setup */ 312#define SND_SOC_DAPM_PRE_REG 0x10 /* before audio path setup */
313#define SND_SOC_DAPM_POST_REG 0x20 /* after audio path setup */ 313#define SND_SOC_DAPM_POST_REG 0x20 /* after audio path setup */
314#define SND_SOC_DAPM_WILL_PMU 0x40 /* called at start of sequence */
315#define SND_SOC_DAPM_WILL_PMD 0x80 /* called at start of sequence */
314#define SND_SOC_DAPM_PRE_POST_PMD \ 316#define SND_SOC_DAPM_PRE_POST_PMD \
315 (SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD) 317 (SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD)
316 318
@@ -479,7 +481,6 @@ struct snd_soc_dapm_route {
479/* dapm audio path between two widgets */ 481/* dapm audio path between two widgets */
480struct snd_soc_dapm_path { 482struct snd_soc_dapm_path {
481 const char *name; 483 const char *name;
482 const char *long_name;
483 484
484 /* source (input) and sink (output) widgets */ 485 /* source (input) and sink (output) widgets */
485 struct snd_soc_dapm_widget *source; 486 struct snd_soc_dapm_widget *source;
diff --git a/include/sound/soc.h b/include/sound/soc.h
index 85c15226103b..6eabee7ec15a 100644
--- a/include/sound/soc.h
+++ b/include/sound/soc.h
@@ -340,7 +340,7 @@ struct snd_soc_jack_gpio;
340 340
341typedef int (*hw_write_t)(void *,const char* ,int); 341typedef int (*hw_write_t)(void *,const char* ,int);
342 342
343extern struct snd_ac97_bus_ops soc_ac97_ops; 343extern struct snd_ac97_bus_ops *soc_ac97_ops;
344 344
345enum snd_soc_control_type { 345enum snd_soc_control_type {
346 SND_SOC_I2C = 1, 346 SND_SOC_I2C = 1,
@@ -467,6 +467,8 @@ int snd_soc_new_ac97_codec(struct snd_soc_codec *codec,
467 struct snd_ac97_bus_ops *ops, int num); 467 struct snd_ac97_bus_ops *ops, int num);
468void snd_soc_free_ac97_codec(struct snd_soc_codec *codec); 468void snd_soc_free_ac97_codec(struct snd_soc_codec *codec);
469 469
470int snd_soc_set_ac97_ops(struct snd_ac97_bus_ops *ops);
471
470/* 472/*
471 *Controls 473 *Controls
472 */ 474 */
diff --git a/include/uapi/sound/asound.h b/include/uapi/sound/asound.h
index e3983d508272..041203f20f6d 100644
--- a/include/uapi/sound/asound.h
+++ b/include/uapi/sound/asound.h
@@ -817,6 +817,8 @@ typedef int __bitwise snd_ctl_elem_iface_t;
817#define SNDRV_CTL_POWER_D3hot (SNDRV_CTL_POWER_D3|0x0000) /* Off, with power */ 817#define SNDRV_CTL_POWER_D3hot (SNDRV_CTL_POWER_D3|0x0000) /* Off, with power */
818#define SNDRV_CTL_POWER_D3cold (SNDRV_CTL_POWER_D3|0x0001) /* Off, without power */ 818#define SNDRV_CTL_POWER_D3cold (SNDRV_CTL_POWER_D3|0x0001) /* Off, without power */
819 819
820#define SNDRV_CTL_ELEM_ID_NAME_MAXLEN 44
821
820struct snd_ctl_elem_id { 822struct snd_ctl_elem_id {
821 unsigned int numid; /* numeric identifier, zero = invalid */ 823 unsigned int numid; /* numeric identifier, zero = invalid */
822 snd_ctl_elem_iface_t iface; /* interface identifier */ 824 snd_ctl_elem_iface_t iface; /* interface identifier */
diff --git a/sound/arm/aaci.c b/sound/arm/aaci.c
index aa5d8034890b..1ca8dc2ccb89 100644
--- a/sound/arm/aaci.c
+++ b/sound/arm/aaci.c
@@ -1076,8 +1076,6 @@ static int aaci_remove(struct amba_device *dev)
1076{ 1076{
1077 struct snd_card *card = amba_get_drvdata(dev); 1077 struct snd_card *card = amba_get_drvdata(dev);
1078 1078
1079 amba_set_drvdata(dev, NULL);
1080
1081 if (card) { 1079 if (card) {
1082 struct aaci *aaci = card->private_data; 1080 struct aaci *aaci = card->private_data;
1083 writel(0, aaci->base + AACI_MAINCR); 1081 writel(0, aaci->base + AACI_MAINCR);
diff --git a/sound/arm/pxa2xx-ac97.c b/sound/arm/pxa2xx-ac97.c
index ec54be4efff0..ce431e6e07cf 100644
--- a/sound/arm/pxa2xx-ac97.c
+++ b/sound/arm/pxa2xx-ac97.c
@@ -230,7 +230,6 @@ static int pxa2xx_ac97_remove(struct platform_device *dev)
230 230
231 if (card) { 231 if (card) {
232 snd_card_free(card); 232 snd_card_free(card);
233 platform_set_drvdata(dev, NULL);
234 pxa2xx_ac97_hw_remove(dev); 233 pxa2xx_ac97_hw_remove(dev);
235 } 234 }
236 235
diff --git a/sound/core/Kconfig b/sound/core/Kconfig
index b413ed05e74d..c0c2f57a0d6f 100644
--- a/sound/core/Kconfig
+++ b/sound/core/Kconfig
@@ -157,6 +157,15 @@ config SND_DYNAMIC_MINORS
157 157
158 If you are unsure about this, say N here. 158 If you are unsure about this, say N here.
159 159
160config SND_MAX_CARDS
161 int "Max number of sound cards"
162 range 4 256
163 default 32
164 depends on SND_DYNAMIC_MINORS
165 help
166 Specify the max number of sound cards that can be assigned
167 on a single machine.
168
160config SND_SUPPORT_OLD_API 169config SND_SUPPORT_OLD_API
161 bool "Support old ALSA API" 170 bool "Support old ALSA API"
162 default y 171 default y
diff --git a/sound/core/init.c b/sound/core/init.c
index 6ef06400dfc8..6b9087115da2 100644
--- a/sound/core/init.c
+++ b/sound/core/init.c
@@ -46,7 +46,8 @@ static LIST_HEAD(shutdown_files);
46 46
47static const struct file_operations snd_shutdown_f_ops; 47static const struct file_operations snd_shutdown_f_ops;
48 48
49static unsigned int snd_cards_lock; /* locked for registering/using */ 49/* locked for registering/using */
50static DECLARE_BITMAP(snd_cards_lock, SNDRV_CARDS);
50struct snd_card *snd_cards[SNDRV_CARDS]; 51struct snd_card *snd_cards[SNDRV_CARDS];
51EXPORT_SYMBOL(snd_cards); 52EXPORT_SYMBOL(snd_cards);
52 53
@@ -167,29 +168,35 @@ int snd_card_create(int idx, const char *xid,
167 err = 0; 168 err = 0;
168 mutex_lock(&snd_card_mutex); 169 mutex_lock(&snd_card_mutex);
169 if (idx < 0) { 170 if (idx < 0) {
170 for (idx2 = 0; idx2 < SNDRV_CARDS; idx2++) 171 for (idx2 = 0; idx2 < SNDRV_CARDS; idx2++) {
171 /* idx == -1 == 0xffff means: take any free slot */ 172 /* idx == -1 == 0xffff means: take any free slot */
172 if (~snd_cards_lock & idx & 1<<idx2) { 173 if (idx2 < sizeof(int) && !(idx & (1U << idx2)))
174 continue;
175 if (!test_bit(idx2, snd_cards_lock)) {
173 if (module_slot_match(module, idx2)) { 176 if (module_slot_match(module, idx2)) {
174 idx = idx2; 177 idx = idx2;
175 break; 178 break;
176 } 179 }
177 } 180 }
181 }
178 } 182 }
179 if (idx < 0) { 183 if (idx < 0) {
180 for (idx2 = 0; idx2 < SNDRV_CARDS; idx2++) 184 for (idx2 = 0; idx2 < SNDRV_CARDS; idx2++) {
181 /* idx == -1 == 0xffff means: take any free slot */ 185 /* idx == -1 == 0xffff means: take any free slot */
182 if (~snd_cards_lock & idx & 1<<idx2) { 186 if (idx2 < sizeof(int) && !(idx & (1U << idx2)))
187 continue;
188 if (!test_bit(idx2, snd_cards_lock)) {
183 if (!slots[idx2] || !*slots[idx2]) { 189 if (!slots[idx2] || !*slots[idx2]) {
184 idx = idx2; 190 idx = idx2;
185 break; 191 break;
186 } 192 }
187 } 193 }
194 }
188 } 195 }
189 if (idx < 0) 196 if (idx < 0)
190 err = -ENODEV; 197 err = -ENODEV;
191 else if (idx < snd_ecards_limit) { 198 else if (idx < snd_ecards_limit) {
192 if (snd_cards_lock & (1 << idx)) 199 if (test_bit(idx, snd_cards_lock))
193 err = -EBUSY; /* invalid */ 200 err = -EBUSY; /* invalid */
194 } else if (idx >= SNDRV_CARDS) 201 } else if (idx >= SNDRV_CARDS)
195 err = -ENODEV; 202 err = -ENODEV;
@@ -199,7 +206,7 @@ int snd_card_create(int idx, const char *xid,
199 idx, snd_ecards_limit - 1, err); 206 idx, snd_ecards_limit - 1, err);
200 goto __error; 207 goto __error;
201 } 208 }
202 snd_cards_lock |= 1 << idx; /* lock it */ 209 set_bit(idx, snd_cards_lock); /* lock it */
203 if (idx >= snd_ecards_limit) 210 if (idx >= snd_ecards_limit)
204 snd_ecards_limit = idx + 1; /* increase the limit */ 211 snd_ecards_limit = idx + 1; /* increase the limit */
205 mutex_unlock(&snd_card_mutex); 212 mutex_unlock(&snd_card_mutex);
@@ -249,7 +256,7 @@ int snd_card_locked(int card)
249 int locked; 256 int locked;
250 257
251 mutex_lock(&snd_card_mutex); 258 mutex_lock(&snd_card_mutex);
252 locked = snd_cards_lock & (1 << card); 259 locked = test_bit(card, snd_cards_lock);
253 mutex_unlock(&snd_card_mutex); 260 mutex_unlock(&snd_card_mutex);
254 return locked; 261 return locked;
255} 262}
@@ -361,7 +368,7 @@ int snd_card_disconnect(struct snd_card *card)
361 /* phase 1: disable fops (user space) operations for ALSA API */ 368 /* phase 1: disable fops (user space) operations for ALSA API */
362 mutex_lock(&snd_card_mutex); 369 mutex_lock(&snd_card_mutex);
363 snd_cards[card->number] = NULL; 370 snd_cards[card->number] = NULL;
364 snd_cards_lock &= ~(1 << card->number); 371 clear_bit(card->number, snd_cards_lock);
365 mutex_unlock(&snd_card_mutex); 372 mutex_unlock(&snd_card_mutex);
366 373
367 /* phase 2: replace file->f_op with special dummy operations */ 374 /* phase 2: replace file->f_op with special dummy operations */
@@ -549,7 +556,6 @@ static void snd_card_set_id_no_lock(struct snd_card *card, const char *src,
549 const char *nid) 556 const char *nid)
550{ 557{
551 int len, loops; 558 int len, loops;
552 bool with_suffix;
553 bool is_default = false; 559 bool is_default = false;
554 char *id; 560 char *id;
555 561
@@ -565,26 +571,23 @@ static void snd_card_set_id_no_lock(struct snd_card *card, const char *src,
565 is_default = true; 571 is_default = true;
566 } 572 }
567 573
568 with_suffix = false; 574 len = strlen(id);
569 for (loops = 0; loops < SNDRV_CARDS; loops++) { 575 for (loops = 0; loops < SNDRV_CARDS; loops++) {
576 char *spos;
577 char sfxstr[5]; /* "_012" */
578 int sfxlen;
579
570 if (card_id_ok(card, id)) 580 if (card_id_ok(card, id))
571 return; /* OK */ 581 return; /* OK */
572 582
573 len = strlen(id); 583 /* Add _XYZ suffix */
574 if (!with_suffix) { 584 sprintf(sfxstr, "_%X", loops + 1);
575 /* add the "_X" suffix */ 585 sfxlen = strlen(sfxstr);
576 char *spos = id + len; 586 if (len + sfxlen >= sizeof(card->id))
577 if (len > sizeof(card->id) - 3) 587 spos = id + sizeof(card->id) - sfxlen - 1;
578 spos = id + sizeof(card->id) - 3; 588 else
579 strcpy(spos, "_1"); 589 spos = id + len;
580 with_suffix = true; 590 strcpy(spos, sfxstr);
581 } else {
582 /* modify the existing suffix */
583 if (id[len - 1] != '9')
584 id[len - 1]++;
585 else
586 id[len - 1] = 'A';
587 }
588 } 591 }
589 /* fallback to the default id */ 592 /* fallback to the default id */
590 if (!is_default) { 593 if (!is_default) {
diff --git a/sound/core/pcm_lib.c b/sound/core/pcm_lib.c
index 41b3dfe68698..82bb029d4414 100644
--- a/sound/core/pcm_lib.c
+++ b/sound/core/pcm_lib.c
@@ -568,7 +568,8 @@ int snd_pcm_update_hw_ptr(struct snd_pcm_substream *substream)
568 * 568 *
569 * Sets the given PCM operators to the pcm instance. 569 * Sets the given PCM operators to the pcm instance.
570 */ 570 */
571void snd_pcm_set_ops(struct snd_pcm *pcm, int direction, struct snd_pcm_ops *ops) 571void snd_pcm_set_ops(struct snd_pcm *pcm, int direction,
572 const struct snd_pcm_ops *ops)
572{ 573{
573 struct snd_pcm_str *stream = &pcm->streams[direction]; 574 struct snd_pcm_str *stream = &pcm->streams[direction];
574 struct snd_pcm_substream *substream; 575 struct snd_pcm_substream *substream;
diff --git a/sound/core/vmaster.c b/sound/core/vmaster.c
index 02f90b4f8b86..842a97d5fc3a 100644
--- a/sound/core/vmaster.c
+++ b/sound/core/vmaster.c
@@ -310,20 +310,10 @@ static int master_get(struct snd_kcontrol *kcontrol,
310 return 0; 310 return 0;
311} 311}
312 312
313static int master_put(struct snd_kcontrol *kcontrol, 313static int sync_slaves(struct link_master *master, int old_val, int new_val)
314 struct snd_ctl_elem_value *ucontrol)
315{ 314{
316 struct link_master *master = snd_kcontrol_chip(kcontrol);
317 struct link_slave *slave; 315 struct link_slave *slave;
318 struct snd_ctl_elem_value *uval; 316 struct snd_ctl_elem_value *uval;
319 int err, old_val;
320
321 err = master_init(master);
322 if (err < 0)
323 return err;
324 old_val = master->val;
325 if (ucontrol->value.integer.value[0] == old_val)
326 return 0;
327 317
328 uval = kmalloc(sizeof(*uval), GFP_KERNEL); 318 uval = kmalloc(sizeof(*uval), GFP_KERNEL);
329 if (!uval) 319 if (!uval)
@@ -332,11 +322,33 @@ static int master_put(struct snd_kcontrol *kcontrol,
332 master->val = old_val; 322 master->val = old_val;
333 uval->id = slave->slave.id; 323 uval->id = slave->slave.id;
334 slave_get_val(slave, uval); 324 slave_get_val(slave, uval);
335 master->val = ucontrol->value.integer.value[0]; 325 master->val = new_val;
336 slave_put_val(slave, uval); 326 slave_put_val(slave, uval);
337 } 327 }
338 kfree(uval); 328 kfree(uval);
339 if (master->hook && !err) 329 return 0;
330}
331
332static int master_put(struct snd_kcontrol *kcontrol,
333 struct snd_ctl_elem_value *ucontrol)
334{
335 struct link_master *master = snd_kcontrol_chip(kcontrol);
336 int err, new_val, old_val;
337 bool first_init;
338
339 err = master_init(master);
340 if (err < 0)
341 return err;
342 first_init = err;
343 old_val = master->val;
344 new_val = ucontrol->value.integer.value[0];
345 if (new_val == old_val)
346 return 0;
347
348 err = sync_slaves(master, old_val, new_val);
349 if (err < 0)
350 return err;
351 if (master->hook && !first_init)
340 master->hook(master->hook_private_data, master->val); 352 master->hook(master->hook_private_data, master->val);
341 return 1; 353 return 1;
342} 354}
@@ -442,20 +454,33 @@ int snd_ctl_add_vmaster_hook(struct snd_kcontrol *kcontrol,
442EXPORT_SYMBOL_GPL(snd_ctl_add_vmaster_hook); 454EXPORT_SYMBOL_GPL(snd_ctl_add_vmaster_hook);
443 455
444/** 456/**
445 * snd_ctl_sync_vmaster_hook - Sync the vmaster hook 457 * snd_ctl_sync_vmaster - Sync the vmaster slaves and hook
446 * @kcontrol: vmaster kctl element 458 * @kcontrol: vmaster kctl element
459 * @hook_only: sync only the hook
447 * 460 *
448 * Call the hook function to synchronize with the current value of the given 461 * Forcibly call the put callback of each slave and call the hook function
449 * vmaster element. NOP when NULL is passed to @kcontrol or the hook doesn't 462 * to synchronize with the current value of the given vmaster element.
450 * exist. 463 * NOP when NULL is passed to @kcontrol.
451 */ 464 */
452void snd_ctl_sync_vmaster_hook(struct snd_kcontrol *kcontrol) 465void snd_ctl_sync_vmaster(struct snd_kcontrol *kcontrol, bool hook_only)
453{ 466{
454 struct link_master *master; 467 struct link_master *master;
468 bool first_init = false;
469
455 if (!kcontrol) 470 if (!kcontrol)
456 return; 471 return;
457 master = snd_kcontrol_chip(kcontrol); 472 master = snd_kcontrol_chip(kcontrol);
458 if (master->hook) 473 if (!hook_only) {
474 int err = master_init(master);
475 if (err < 0)
476 return;
477 first_init = err;
478 err = sync_slaves(master, master->val, master->val);
479 if (err < 0)
480 return;
481 }
482
483 if (master->hook && !first_init)
459 master->hook(master->hook_private_data, master->val); 484 master->hook(master->hook_private_data, master->val);
460} 485}
461EXPORT_SYMBOL_GPL(snd_ctl_sync_vmaster_hook); 486EXPORT_SYMBOL_GPL(snd_ctl_sync_vmaster);
diff --git a/sound/drivers/aloop.c b/sound/drivers/aloop.c
index 6f78de9c6fb6..f7589923effa 100644
--- a/sound/drivers/aloop.c
+++ b/sound/drivers/aloop.c
@@ -1183,7 +1183,6 @@ static int loopback_probe(struct platform_device *devptr)
1183static int loopback_remove(struct platform_device *devptr) 1183static int loopback_remove(struct platform_device *devptr)
1184{ 1184{
1185 snd_card_free(platform_get_drvdata(devptr)); 1185 snd_card_free(platform_get_drvdata(devptr));
1186 platform_set_drvdata(devptr, NULL);
1187 return 0; 1186 return 0;
1188} 1187}
1189 1188
diff --git a/sound/drivers/dummy.c b/sound/drivers/dummy.c
index fd798f753609..11048cc744d0 100644
--- a/sound/drivers/dummy.c
+++ b/sound/drivers/dummy.c
@@ -1129,7 +1129,6 @@ static int snd_dummy_probe(struct platform_device *devptr)
1129static int snd_dummy_remove(struct platform_device *devptr) 1129static int snd_dummy_remove(struct platform_device *devptr)
1130{ 1130{
1131 snd_card_free(platform_get_drvdata(devptr)); 1131 snd_card_free(platform_get_drvdata(devptr));
1132 platform_set_drvdata(devptr, NULL);
1133 return 0; 1132 return 0;
1134} 1133}
1135 1134
diff --git a/sound/drivers/ml403-ac97cr.c b/sound/drivers/ml403-ac97cr.c
index 8125a7e95ee4..95ea4a153ea4 100644
--- a/sound/drivers/ml403-ac97cr.c
+++ b/sound/drivers/ml403-ac97cr.c
@@ -1325,7 +1325,6 @@ static int snd_ml403_ac97cr_probe(struct platform_device *pfdev)
1325static int snd_ml403_ac97cr_remove(struct platform_device *pfdev) 1325static int snd_ml403_ac97cr_remove(struct platform_device *pfdev)
1326{ 1326{
1327 snd_card_free(platform_get_drvdata(pfdev)); 1327 snd_card_free(platform_get_drvdata(pfdev));
1328 platform_set_drvdata(pfdev, NULL);
1329 return 0; 1328 return 0;
1330} 1329}
1331 1330
diff --git a/sound/drivers/mpu401/mpu401.c b/sound/drivers/mpu401/mpu401.c
index da1a29bfc85d..90a3a7b38a2a 100644
--- a/sound/drivers/mpu401/mpu401.c
+++ b/sound/drivers/mpu401/mpu401.c
@@ -129,7 +129,6 @@ static int snd_mpu401_probe(struct platform_device *devptr)
129static int snd_mpu401_remove(struct platform_device *devptr) 129static int snd_mpu401_remove(struct platform_device *devptr)
130{ 130{
131 snd_card_free(platform_get_drvdata(devptr)); 131 snd_card_free(platform_get_drvdata(devptr));
132 platform_set_drvdata(devptr, NULL);
133 return 0; 132 return 0;
134} 133}
135 134
diff --git a/sound/drivers/mtpav.c b/sound/drivers/mtpav.c
index 9f1815b99a15..e5ec7eb27dec 100644
--- a/sound/drivers/mtpav.c
+++ b/sound/drivers/mtpav.c
@@ -749,7 +749,6 @@ static int snd_mtpav_probe(struct platform_device *dev)
749static int snd_mtpav_remove(struct platform_device *devptr) 749static int snd_mtpav_remove(struct platform_device *devptr)
750{ 750{
751 snd_card_free(platform_get_drvdata(devptr)); 751 snd_card_free(platform_get_drvdata(devptr));
752 platform_set_drvdata(devptr, NULL);
753 return 0; 752 return 0;
754} 753}
755 754
diff --git a/sound/drivers/pcsp/pcsp.c b/sound/drivers/pcsp/pcsp.c
index 7a5fdb9b0afc..1c19cd7ad26e 100644
--- a/sound/drivers/pcsp/pcsp.c
+++ b/sound/drivers/pcsp/pcsp.c
@@ -189,7 +189,6 @@ static int pcsp_remove(struct platform_device *dev)
189 struct snd_pcsp *chip = platform_get_drvdata(dev); 189 struct snd_pcsp *chip = platform_get_drvdata(dev);
190 alsa_card_pcsp_exit(chip); 190 alsa_card_pcsp_exit(chip);
191 pcspkr_input_remove(chip->input_dev); 191 pcspkr_input_remove(chip->input_dev);
192 platform_set_drvdata(dev, NULL);
193 return 0; 192 return 0;
194} 193}
195 194
diff --git a/sound/drivers/serial-u16550.c b/sound/drivers/serial-u16550.c
index 7425dd8c1f09..e0bf5e77b43a 100644
--- a/sound/drivers/serial-u16550.c
+++ b/sound/drivers/serial-u16550.c
@@ -985,7 +985,6 @@ static int snd_serial_probe(struct platform_device *devptr)
985static int snd_serial_remove(struct platform_device *devptr) 985static int snd_serial_remove(struct platform_device *devptr)
986{ 986{
987 snd_card_free(platform_get_drvdata(devptr)); 987 snd_card_free(platform_get_drvdata(devptr));
988 platform_set_drvdata(devptr, NULL);
989 return 0; 988 return 0;
990} 989}
991 990
diff --git a/sound/drivers/virmidi.c b/sound/drivers/virmidi.c
index cc4be88d7318..ace3879e8d96 100644
--- a/sound/drivers/virmidi.c
+++ b/sound/drivers/virmidi.c
@@ -132,7 +132,6 @@ static int snd_virmidi_probe(struct platform_device *devptr)
132static int snd_virmidi_remove(struct platform_device *devptr) 132static int snd_virmidi_remove(struct platform_device *devptr)
133{ 133{
134 snd_card_free(platform_get_drvdata(devptr)); 134 snd_card_free(platform_get_drvdata(devptr));
135 platform_set_drvdata(devptr, NULL);
136 return 0; 135 return 0;
137} 136}
138 137
diff --git a/sound/drivers/vx/vx_core.c b/sound/drivers/vx/vx_core.c
index c39961c11401..83596891cde4 100644
--- a/sound/drivers/vx/vx_core.c
+++ b/sound/drivers/vx/vx_core.c
@@ -205,7 +205,7 @@ static int vx_read_status(struct vx_core *chip, struct vx_rmh *rmh)
205 205
206 if (size < 1) 206 if (size < 1)
207 return 0; 207 return 0;
208 if (snd_BUG_ON(size > SIZE_MAX_STATUS)) 208 if (snd_BUG_ON(size >= SIZE_MAX_STATUS))
209 return -EINVAL; 209 return -EINVAL;
210 210
211 for (i = 1; i <= size; i++) { 211 for (i = 1; i <= size; i++) {
diff --git a/sound/firewire/amdtp.h b/sound/firewire/amdtp.h
index b680c5ef01d6..f6103d68c4b1 100644
--- a/sound/firewire/amdtp.h
+++ b/sound/firewire/amdtp.h
@@ -3,7 +3,6 @@
3 3
4#include <linux/interrupt.h> 4#include <linux/interrupt.h>
5#include <linux/mutex.h> 5#include <linux/mutex.h>
6#include <linux/spinlock.h>
7#include "packets-buffer.h" 6#include "packets-buffer.h"
8 7
9/** 8/**
diff --git a/sound/firewire/scs1x.c b/sound/firewire/scs1x.c
index 844a555c3b1e..b252c21b6d13 100644
--- a/sound/firewire/scs1x.c
+++ b/sound/firewire/scs1x.c
@@ -405,8 +405,10 @@ static int scs_probe(struct device *unit_dev)
405 scs->output_idle = true; 405 scs->output_idle = true;
406 406
407 scs->buffer = kmalloc(HSS1394_MAX_PACKET_SIZE, GFP_KERNEL); 407 scs->buffer = kmalloc(HSS1394_MAX_PACKET_SIZE, GFP_KERNEL);
408 if (!scs->buffer) 408 if (!scs->buffer) {
409 err = -ENOMEM;
409 goto err_card; 410 goto err_card;
411 }
410 412
411 scs->hss_handler.length = HSS1394_MAX_PACKET_SIZE; 413 scs->hss_handler.length = HSS1394_MAX_PACKET_SIZE;
412 scs->hss_handler.address_callback = handle_hss; 414 scs->hss_handler.address_callback = handle_hss;
diff --git a/sound/i2c/other/ak4xxx-adda.c b/sound/i2c/other/ak4xxx-adda.c
index cef813d23641..ed726d1569e8 100644
--- a/sound/i2c/other/ak4xxx-adda.c
+++ b/sound/i2c/other/ak4xxx-adda.c
@@ -571,7 +571,7 @@ static int ak4xxx_capture_source_info(struct snd_kcontrol *kcontrol,
571 struct snd_akm4xxx *ak = snd_kcontrol_chip(kcontrol); 571 struct snd_akm4xxx *ak = snd_kcontrol_chip(kcontrol);
572 int mixer_ch = AK_GET_SHIFT(kcontrol->private_value); 572 int mixer_ch = AK_GET_SHIFT(kcontrol->private_value);
573 const char **input_names; 573 const char **input_names;
574 int num_names, idx; 574 unsigned int num_names, idx;
575 575
576 num_names = ak4xxx_capture_num_inputs(ak, mixer_ch); 576 num_names = ak4xxx_capture_num_inputs(ak, mixer_ch);
577 if (!num_names) 577 if (!num_names)
diff --git a/sound/isa/ad1848/ad1848.c b/sound/isa/ad1848/ad1848.c
index c214ecf45400..e3f455bd85cd 100644
--- a/sound/isa/ad1848/ad1848.c
+++ b/sound/isa/ad1848/ad1848.c
@@ -135,7 +135,6 @@ out: snd_card_free(card);
135static int snd_ad1848_remove(struct device *dev, unsigned int n) 135static int snd_ad1848_remove(struct device *dev, unsigned int n)
136{ 136{
137 snd_card_free(dev_get_drvdata(dev)); 137 snd_card_free(dev_get_drvdata(dev));
138 dev_set_drvdata(dev, NULL);
139 return 0; 138 return 0;
140} 139}
141 140
diff --git a/sound/isa/adlib.c b/sound/isa/adlib.c
index d26545543732..35659218710f 100644
--- a/sound/isa/adlib.c
+++ b/sound/isa/adlib.c
@@ -101,7 +101,6 @@ out: snd_card_free(card);
101static int snd_adlib_remove(struct device *dev, unsigned int n) 101static int snd_adlib_remove(struct device *dev, unsigned int n)
102{ 102{
103 snd_card_free(dev_get_drvdata(dev)); 103 snd_card_free(dev_get_drvdata(dev));
104 dev_set_drvdata(dev, NULL);
105 return 0; 104 return 0;
106} 105}
107 106
diff --git a/sound/isa/cmi8328.c b/sound/isa/cmi8328.c
index a7369fe19a6f..f84f073fc1e8 100644
--- a/sound/isa/cmi8328.c
+++ b/sound/isa/cmi8328.c
@@ -418,7 +418,6 @@ static int snd_cmi8328_remove(struct device *pdev, unsigned int dev)
418 snd_cmi8328_cfg_write(cmi->port, CFG2, 0); 418 snd_cmi8328_cfg_write(cmi->port, CFG2, 0);
419 snd_cmi8328_cfg_write(cmi->port, CFG3, 0); 419 snd_cmi8328_cfg_write(cmi->port, CFG3, 0);
420 snd_card_free(card); 420 snd_card_free(card);
421 dev_set_drvdata(pdev, NULL);
422 return 0; 421 return 0;
423} 422}
424 423
diff --git a/sound/isa/cmi8330.c b/sound/isa/cmi8330.c
index c707c52268ab..270b9659ef7f 100644
--- a/sound/isa/cmi8330.c
+++ b/sound/isa/cmi8330.c
@@ -651,7 +651,6 @@ static int snd_cmi8330_isa_remove(struct device *devptr,
651 unsigned int dev) 651 unsigned int dev)
652{ 652{
653 snd_card_free(dev_get_drvdata(devptr)); 653 snd_card_free(dev_get_drvdata(devptr));
654 dev_set_drvdata(devptr, NULL);
655 return 0; 654 return 0;
656} 655}
657 656
diff --git a/sound/isa/cs423x/cs4231.c b/sound/isa/cs423x/cs4231.c
index aa7a5d86e480..ba9a74eff3e0 100644
--- a/sound/isa/cs423x/cs4231.c
+++ b/sound/isa/cs423x/cs4231.c
@@ -151,7 +151,6 @@ out: snd_card_free(card);
151static int snd_cs4231_remove(struct device *dev, unsigned int n) 151static int snd_cs4231_remove(struct device *dev, unsigned int n)
152{ 152{
153 snd_card_free(dev_get_drvdata(dev)); 153 snd_card_free(dev_get_drvdata(dev));
154 dev_set_drvdata(dev, NULL);
155 return 0; 154 return 0;
156} 155}
157 156
diff --git a/sound/isa/cs423x/cs4236.c b/sound/isa/cs423x/cs4236.c
index 252e9fb37db3..69614acb2052 100644
--- a/sound/isa/cs423x/cs4236.c
+++ b/sound/isa/cs423x/cs4236.c
@@ -504,7 +504,6 @@ static int snd_cs423x_isa_remove(struct device *pdev,
504 unsigned int dev) 504 unsigned int dev)
505{ 505{
506 snd_card_free(dev_get_drvdata(pdev)); 506 snd_card_free(dev_get_drvdata(pdev));
507 dev_set_drvdata(pdev, NULL);
508 return 0; 507 return 0;
509} 508}
510 509
@@ -600,7 +599,6 @@ static int snd_cs423x_pnpbios_detect(struct pnp_dev *pdev,
600static void snd_cs423x_pnp_remove(struct pnp_dev *pdev) 599static void snd_cs423x_pnp_remove(struct pnp_dev *pdev)
601{ 600{
602 snd_card_free(pnp_get_drvdata(pdev)); 601 snd_card_free(pnp_get_drvdata(pdev));
603 pnp_set_drvdata(pdev, NULL);
604} 602}
605 603
606#ifdef CONFIG_PM 604#ifdef CONFIG_PM
diff --git a/sound/isa/es1688/es1688.c b/sound/isa/es1688/es1688.c
index 102874a703d4..cdcfb57f1f0a 100644
--- a/sound/isa/es1688/es1688.c
+++ b/sound/isa/es1688/es1688.c
@@ -213,7 +213,6 @@ out:
213static int snd_es1688_isa_remove(struct device *dev, unsigned int n) 213static int snd_es1688_isa_remove(struct device *dev, unsigned int n)
214{ 214{
215 snd_card_free(dev_get_drvdata(dev)); 215 snd_card_free(dev_get_drvdata(dev));
216 dev_set_drvdata(dev, NULL);
217 return 0; 216 return 0;
218} 217}
219 218
diff --git a/sound/isa/es18xx.c b/sound/isa/es18xx.c
index 24380efe31a1..12978b864c3a 100644
--- a/sound/isa/es18xx.c
+++ b/sound/isa/es18xx.c
@@ -2235,7 +2235,6 @@ static int snd_es18xx_isa_remove(struct device *devptr,
2235 unsigned int dev) 2235 unsigned int dev)
2236{ 2236{
2237 snd_card_free(dev_get_drvdata(devptr)); 2237 snd_card_free(dev_get_drvdata(devptr));
2238 dev_set_drvdata(devptr, NULL);
2239 return 0; 2238 return 0;
2240} 2239}
2241 2240
@@ -2305,7 +2304,6 @@ static int snd_audiodrive_pnp_detect(struct pnp_dev *pdev,
2305static void snd_audiodrive_pnp_remove(struct pnp_dev *pdev) 2304static void snd_audiodrive_pnp_remove(struct pnp_dev *pdev)
2306{ 2305{
2307 snd_card_free(pnp_get_drvdata(pdev)); 2306 snd_card_free(pnp_get_drvdata(pdev));
2308 pnp_set_drvdata(pdev, NULL);
2309} 2307}
2310 2308
2311#ifdef CONFIG_PM 2309#ifdef CONFIG_PM
diff --git a/sound/isa/galaxy/galaxy.c b/sound/isa/galaxy/galaxy.c
index 672184e3221a..81244e7cea5b 100644
--- a/sound/isa/galaxy/galaxy.c
+++ b/sound/isa/galaxy/galaxy.c
@@ -623,7 +623,6 @@ error:
623static int snd_galaxy_remove(struct device *dev, unsigned int n) 623static int snd_galaxy_remove(struct device *dev, unsigned int n)
624{ 624{
625 snd_card_free(dev_get_drvdata(dev)); 625 snd_card_free(dev_get_drvdata(dev));
626 dev_set_drvdata(dev, NULL);
627 return 0; 626 return 0;
628} 627}
629 628
diff --git a/sound/isa/gus/gusclassic.c b/sound/isa/gus/gusclassic.c
index 16bca4e96c08..1adc1b924f39 100644
--- a/sound/isa/gus/gusclassic.c
+++ b/sound/isa/gus/gusclassic.c
@@ -215,7 +215,6 @@ out: snd_card_free(card);
215static int snd_gusclassic_remove(struct device *dev, unsigned int n) 215static int snd_gusclassic_remove(struct device *dev, unsigned int n)
216{ 216{
217 snd_card_free(dev_get_drvdata(dev)); 217 snd_card_free(dev_get_drvdata(dev));
218 dev_set_drvdata(dev, NULL);
219 return 0; 218 return 0;
220} 219}
221 220
diff --git a/sound/isa/gus/gusextreme.c b/sound/isa/gus/gusextreme.c
index 0b9c2426b49f..38e1e3260c24 100644
--- a/sound/isa/gus/gusextreme.c
+++ b/sound/isa/gus/gusextreme.c
@@ -344,7 +344,6 @@ out: snd_card_free(card);
344static int snd_gusextreme_remove(struct device *dev, unsigned int n) 344static int snd_gusextreme_remove(struct device *dev, unsigned int n)
345{ 345{
346 snd_card_free(dev_get_drvdata(dev)); 346 snd_card_free(dev_get_drvdata(dev));
347 dev_set_drvdata(dev, NULL);
348 return 0; 347 return 0;
349} 348}
350 349
diff --git a/sound/isa/gus/gusmax.c b/sound/isa/gus/gusmax.c
index c309a5d0e7e1..652d5d834620 100644
--- a/sound/isa/gus/gusmax.c
+++ b/sound/isa/gus/gusmax.c
@@ -357,7 +357,6 @@ static int snd_gusmax_probe(struct device *pdev, unsigned int dev)
357static int snd_gusmax_remove(struct device *devptr, unsigned int dev) 357static int snd_gusmax_remove(struct device *devptr, unsigned int dev)
358{ 358{
359 snd_card_free(dev_get_drvdata(devptr)); 359 snd_card_free(dev_get_drvdata(devptr));
360 dev_set_drvdata(devptr, NULL);
361 return 0; 360 return 0;
362} 361}
363 362
diff --git a/sound/isa/gus/interwave.c b/sound/isa/gus/interwave.c
index 78bc5744e89a..9942691cc0ca 100644
--- a/sound/isa/gus/interwave.c
+++ b/sound/isa/gus/interwave.c
@@ -849,7 +849,6 @@ static int snd_interwave_isa_probe(struct device *pdev,
849static int snd_interwave_isa_remove(struct device *devptr, unsigned int dev) 849static int snd_interwave_isa_remove(struct device *devptr, unsigned int dev)
850{ 850{
851 snd_card_free(dev_get_drvdata(devptr)); 851 snd_card_free(dev_get_drvdata(devptr));
852 dev_set_drvdata(devptr, NULL);
853 return 0; 852 return 0;
854} 853}
855 854
diff --git a/sound/isa/msnd/msnd_pinnacle.c b/sound/isa/msnd/msnd_pinnacle.c
index ddabb406b14c..81aeb934261a 100644
--- a/sound/isa/msnd/msnd_pinnacle.c
+++ b/sound/isa/msnd/msnd_pinnacle.c
@@ -1064,7 +1064,6 @@ cfg_error:
1064static int snd_msnd_isa_remove(struct device *pdev, unsigned int dev) 1064static int snd_msnd_isa_remove(struct device *pdev, unsigned int dev)
1065{ 1065{
1066 snd_msnd_unload(dev_get_drvdata(pdev)); 1066 snd_msnd_unload(dev_get_drvdata(pdev));
1067 dev_set_drvdata(pdev, NULL);
1068 return 0; 1067 return 0;
1069} 1068}
1070 1069
diff --git a/sound/isa/opl3sa2.c b/sound/isa/opl3sa2.c
index 075777a6cf0b..cc01c419b7e9 100644
--- a/sound/isa/opl3sa2.c
+++ b/sound/isa/opl3sa2.c
@@ -757,7 +757,6 @@ static int snd_opl3sa2_pnp_detect(struct pnp_dev *pdev,
757static void snd_opl3sa2_pnp_remove(struct pnp_dev *pdev) 757static void snd_opl3sa2_pnp_remove(struct pnp_dev *pdev)
758{ 758{
759 snd_card_free(pnp_get_drvdata(pdev)); 759 snd_card_free(pnp_get_drvdata(pdev));
760 pnp_set_drvdata(pdev, NULL);
761} 760}
762 761
763#ifdef CONFIG_PM 762#ifdef CONFIG_PM
@@ -900,7 +899,6 @@ static int snd_opl3sa2_isa_remove(struct device *devptr,
900 unsigned int dev) 899 unsigned int dev)
901{ 900{
902 snd_card_free(dev_get_drvdata(devptr)); 901 snd_card_free(dev_get_drvdata(devptr));
903 dev_set_drvdata(devptr, NULL);
904 return 0; 902 return 0;
905} 903}
906 904
diff --git a/sound/isa/opti9xx/miro.c b/sound/isa/opti9xx/miro.c
index c3da1df9371d..619753d96ca5 100644
--- a/sound/isa/opti9xx/miro.c
+++ b/sound/isa/opti9xx/miro.c
@@ -1495,7 +1495,6 @@ static int snd_miro_isa_remove(struct device *devptr,
1495 unsigned int dev) 1495 unsigned int dev)
1496{ 1496{
1497 snd_card_free(dev_get_drvdata(devptr)); 1497 snd_card_free(dev_get_drvdata(devptr));
1498 dev_set_drvdata(devptr, NULL);
1499 return 0; 1498 return 0;
1500} 1499}
1501 1500
diff --git a/sound/isa/opti9xx/opti92x-ad1848.c b/sound/isa/opti9xx/opti92x-ad1848.c
index b41ed8661b23..103b33373fd4 100644
--- a/sound/isa/opti9xx/opti92x-ad1848.c
+++ b/sound/isa/opti9xx/opti92x-ad1848.c
@@ -1035,7 +1035,6 @@ static int snd_opti9xx_isa_remove(struct device *devptr,
1035 unsigned int dev) 1035 unsigned int dev)
1036{ 1036{
1037 snd_card_free(dev_get_drvdata(devptr)); 1037 snd_card_free(dev_get_drvdata(devptr));
1038 dev_set_drvdata(devptr, NULL);
1039 return 0; 1038 return 0;
1040} 1039}
1041 1040
diff --git a/sound/isa/sb/jazz16.c b/sound/isa/sb/jazz16.c
index 4961da4e627c..356a6308392f 100644
--- a/sound/isa/sb/jazz16.c
+++ b/sound/isa/sb/jazz16.c
@@ -345,7 +345,6 @@ static int snd_jazz16_remove(struct device *devptr, unsigned int dev)
345{ 345{
346 struct snd_card *card = dev_get_drvdata(devptr); 346 struct snd_card *card = dev_get_drvdata(devptr);
347 347
348 dev_set_drvdata(devptr, NULL);
349 snd_card_free(card); 348 snd_card_free(card);
350 return 0; 349 return 0;
351} 350}
diff --git a/sound/isa/sb/sb16.c b/sound/isa/sb/sb16.c
index 50dbec454f98..a4130993955f 100644
--- a/sound/isa/sb/sb16.c
+++ b/sound/isa/sb/sb16.c
@@ -566,7 +566,6 @@ static int snd_sb16_isa_probe(struct device *pdev, unsigned int dev)
566static int snd_sb16_isa_remove(struct device *pdev, unsigned int dev) 566static int snd_sb16_isa_remove(struct device *pdev, unsigned int dev)
567{ 567{
568 snd_card_free(dev_get_drvdata(pdev)); 568 snd_card_free(dev_get_drvdata(pdev));
569 dev_set_drvdata(pdev, NULL);
570 return 0; 569 return 0;
571} 570}
572 571
diff --git a/sound/isa/sb/sb8.c b/sound/isa/sb/sb8.c
index 237d964ff8a6..a806ae90a944 100644
--- a/sound/isa/sb/sb8.c
+++ b/sound/isa/sb/sb8.c
@@ -208,7 +208,6 @@ static int snd_sb8_probe(struct device *pdev, unsigned int dev)
208static int snd_sb8_remove(struct device *pdev, unsigned int dev) 208static int snd_sb8_remove(struct device *pdev, unsigned int dev)
209{ 209{
210 snd_card_free(dev_get_drvdata(pdev)); 210 snd_card_free(dev_get_drvdata(pdev));
211 dev_set_drvdata(pdev, NULL);
212 return 0; 211 return 0;
213} 212}
214 213
diff --git a/sound/isa/sc6000.c b/sound/isa/sc6000.c
index 5376ebff845e..09d481b3ba7f 100644
--- a/sound/isa/sc6000.c
+++ b/sound/isa/sc6000.c
@@ -698,7 +698,6 @@ static int snd_sc6000_remove(struct device *devptr, unsigned int dev)
698 release_region(port[dev], 0x10); 698 release_region(port[dev], 0x10);
699 release_region(mss_port[dev], 4); 699 release_region(mss_port[dev], 4);
700 700
701 dev_set_drvdata(devptr, NULL);
702 snd_card_free(card); 701 snd_card_free(card);
703 return 0; 702 return 0;
704} 703}
diff --git a/sound/isa/sscape.c b/sound/isa/sscape.c
index 42a009720b29..57b338973ede 100644
--- a/sound/isa/sscape.c
+++ b/sound/isa/sscape.c
@@ -1200,7 +1200,6 @@ _release_card:
1200static int snd_sscape_remove(struct device *devptr, unsigned int dev) 1200static int snd_sscape_remove(struct device *devptr, unsigned int dev)
1201{ 1201{
1202 snd_card_free(dev_get_drvdata(devptr)); 1202 snd_card_free(dev_get_drvdata(devptr));
1203 dev_set_drvdata(devptr, NULL);
1204 return 0; 1203 return 0;
1205} 1204}
1206 1205
diff --git a/sound/isa/wavefront/wavefront.c b/sound/isa/wavefront/wavefront.c
index fe5dd982bd23..82dd76939fa0 100644
--- a/sound/isa/wavefront/wavefront.c
+++ b/sound/isa/wavefront/wavefront.c
@@ -581,7 +581,6 @@ static int snd_wavefront_isa_remove(struct device *devptr,
581 unsigned int dev) 581 unsigned int dev)
582{ 582{
583 snd_card_free(dev_get_drvdata(devptr)); 583 snd_card_free(dev_get_drvdata(devptr));
584 dev_set_drvdata(devptr, NULL);
585 return 0; 584 return 0;
586} 585}
587 586
diff --git a/sound/oss/kahlua.c b/sound/oss/kahlua.c
index 2a44cc106459..12be1fb512dd 100644
--- a/sound/oss/kahlua.c
+++ b/sound/oss/kahlua.c
@@ -178,7 +178,6 @@ static int probe_one(struct pci_dev *pdev, const struct pci_device_id *ent)
178 return 0; 178 return 0;
179 179
180err_out_free: 180err_out_free:
181 pci_set_drvdata(pdev, NULL);
182 kfree(hw_config); 181 kfree(hw_config);
183 return 1; 182 return 1;
184} 183}
@@ -187,7 +186,6 @@ static void remove_one(struct pci_dev *pdev)
187{ 186{
188 struct address_info *hw_config = pci_get_drvdata(pdev); 187 struct address_info *hw_config = pci_get_drvdata(pdev);
189 sb_dsp_unload(hw_config, 0); 188 sb_dsp_unload(hw_config, 0);
190 pci_set_drvdata(pdev, NULL);
191 kfree(hw_config); 189 kfree(hw_config);
192} 190}
193 191
diff --git a/sound/parisc/harmony.c b/sound/parisc/harmony.c
index 0e66ba48d453..67f56a2cee6a 100644
--- a/sound/parisc/harmony.c
+++ b/sound/parisc/harmony.c
@@ -902,8 +902,6 @@ snd_harmony_free(struct snd_harmony *h)
902 if (h->iobase) 902 if (h->iobase)
903 iounmap(h->iobase); 903 iounmap(h->iobase);
904 904
905 parisc_set_drvdata(h->dev, NULL);
906
907 kfree(h); 905 kfree(h);
908 return 0; 906 return 0;
909} 907}
@@ -1016,7 +1014,6 @@ static int
1016snd_harmony_remove(struct parisc_device *padev) 1014snd_harmony_remove(struct parisc_device *padev)
1017{ 1015{
1018 snd_card_free(parisc_get_drvdata(padev)); 1016 snd_card_free(parisc_get_drvdata(padev));
1019 parisc_set_drvdata(padev, NULL);
1020 return 0; 1017 return 0;
1021} 1018}
1022 1019
diff --git a/sound/pci/ac97/ac97_codec.c b/sound/pci/ac97/ac97_codec.c
index d37c683cfd7a..445ca481d8d3 100644
--- a/sound/pci/ac97/ac97_codec.c
+++ b/sound/pci/ac97/ac97_codec.c
@@ -1296,7 +1296,7 @@ static int snd_ac97_cmix_new_stereo(struct snd_card *card, const char *pfx,
1296 struct snd_ac97 *ac97) 1296 struct snd_ac97 *ac97)
1297{ 1297{
1298 int err; 1298 int err;
1299 char name[44]; 1299 char name[SNDRV_CTL_ELEM_ID_NAME_MAXLEN];
1300 unsigned char lo_max, hi_max; 1300 unsigned char lo_max, hi_max;
1301 1301
1302 if (! snd_ac97_valid_reg(ac97, reg)) 1302 if (! snd_ac97_valid_reg(ac97, reg))
diff --git a/sound/pci/ad1889.c b/sound/pci/ad1889.c
index ad8a31173939..d2b9d617aee5 100644
--- a/sound/pci/ad1889.c
+++ b/sound/pci/ad1889.c
@@ -1046,7 +1046,6 @@ static void
1046snd_ad1889_remove(struct pci_dev *pci) 1046snd_ad1889_remove(struct pci_dev *pci)
1047{ 1047{
1048 snd_card_free(pci_get_drvdata(pci)); 1048 snd_card_free(pci_get_drvdata(pci));
1049 pci_set_drvdata(pci, NULL);
1050} 1049}
1051 1050
1052static DEFINE_PCI_DEVICE_TABLE(snd_ad1889_ids) = { 1051static DEFINE_PCI_DEVICE_TABLE(snd_ad1889_ids) = {
diff --git a/sound/pci/ali5451/ali5451.c b/sound/pci/ali5451/ali5451.c
index 53754f5edeb1..3dfa12b670eb 100644
--- a/sound/pci/ali5451/ali5451.c
+++ b/sound/pci/ali5451/ali5451.c
@@ -2298,7 +2298,6 @@ static int snd_ali_probe(struct pci_dev *pci,
2298static void snd_ali_remove(struct pci_dev *pci) 2298static void snd_ali_remove(struct pci_dev *pci)
2299{ 2299{
2300 snd_card_free(pci_get_drvdata(pci)); 2300 snd_card_free(pci_get_drvdata(pci));
2301 pci_set_drvdata(pci, NULL);
2302} 2301}
2303 2302
2304static struct pci_driver ali5451_driver = { 2303static struct pci_driver ali5451_driver = {
diff --git a/sound/pci/als300.c b/sound/pci/als300.c
index 864c4310366b..591efb6eef05 100644
--- a/sound/pci/als300.c
+++ b/sound/pci/als300.c
@@ -282,7 +282,6 @@ static void snd_als300_remove(struct pci_dev *pci)
282{ 282{
283 snd_als300_dbgcallenter(); 283 snd_als300_dbgcallenter();
284 snd_card_free(pci_get_drvdata(pci)); 284 snd_card_free(pci_get_drvdata(pci));
285 pci_set_drvdata(pci, NULL);
286 snd_als300_dbgcallleave(); 285 snd_als300_dbgcallleave();
287} 286}
288 287
diff --git a/sound/pci/als4000.c b/sound/pci/als4000.c
index 61efda2a4d94..ffc821b0139e 100644
--- a/sound/pci/als4000.c
+++ b/sound/pci/als4000.c
@@ -984,7 +984,6 @@ out:
984static void snd_card_als4000_remove(struct pci_dev *pci) 984static void snd_card_als4000_remove(struct pci_dev *pci)
985{ 985{
986 snd_card_free(pci_get_drvdata(pci)); 986 snd_card_free(pci_get_drvdata(pci));
987 pci_set_drvdata(pci, NULL);
988} 987}
989 988
990#ifdef CONFIG_PM_SLEEP 989#ifdef CONFIG_PM_SLEEP
diff --git a/sound/pci/asihpi/asihpi.c b/sound/pci/asihpi/asihpi.c
index fbc17203613c..185d54a5cb1a 100644
--- a/sound/pci/asihpi/asihpi.c
+++ b/sound/pci/asihpi/asihpi.c
@@ -1278,7 +1278,7 @@ struct hpi_control {
1278 u16 dst_node_type; 1278 u16 dst_node_type;
1279 u16 dst_node_index; 1279 u16 dst_node_index;
1280 u16 band; 1280 u16 band;
1281 char name[44]; /* copied to snd_ctl_elem_id.name[44]; */ 1281 char name[SNDRV_CTL_ELEM_ID_NAME_MAXLEN]; /* copied to snd_ctl_elem_id.name[44]; */
1282}; 1282};
1283 1283
1284static const char * const asihpi_tuner_band_names[] = { 1284static const char * const asihpi_tuner_band_names[] = {
diff --git a/sound/pci/asihpi/hpioctl.c b/sound/pci/asihpi/hpioctl.c
index ef5019fe5193..7f0272032fbb 100644
--- a/sound/pci/asihpi/hpioctl.c
+++ b/sound/pci/asihpi/hpioctl.c
@@ -445,7 +445,6 @@ void asihpi_adapter_remove(struct pci_dev *pci_dev)
445 if (pa->p_buffer) 445 if (pa->p_buffer)
446 vfree(pa->p_buffer); 446 vfree(pa->p_buffer);
447 447
448 pci_set_drvdata(pci_dev, NULL);
449 if (1) 448 if (1)
450 dev_info(&pci_dev->dev, 449 dev_info(&pci_dev->dev,
451 "remove %04x:%04x,%04x:%04x,%04x, HPI index %d\n", 450 "remove %04x:%04x,%04x:%04x,%04x, HPI index %d\n",
diff --git a/sound/pci/atiixp.c b/sound/pci/atiixp.c
index 6e78c6789858..fe4c61bdb8ba 100644
--- a/sound/pci/atiixp.c
+++ b/sound/pci/atiixp.c
@@ -1714,7 +1714,6 @@ static int snd_atiixp_probe(struct pci_dev *pci,
1714static void snd_atiixp_remove(struct pci_dev *pci) 1714static void snd_atiixp_remove(struct pci_dev *pci)
1715{ 1715{
1716 snd_card_free(pci_get_drvdata(pci)); 1716 snd_card_free(pci_get_drvdata(pci));
1717 pci_set_drvdata(pci, NULL);
1718} 1717}
1719 1718
1720static struct pci_driver atiixp_driver = { 1719static struct pci_driver atiixp_driver = {
diff --git a/sound/pci/atiixp_modem.c b/sound/pci/atiixp_modem.c
index d0bec7ba3b0d..cf29b9a1d65d 100644
--- a/sound/pci/atiixp_modem.c
+++ b/sound/pci/atiixp_modem.c
@@ -1334,7 +1334,6 @@ static int snd_atiixp_probe(struct pci_dev *pci,
1334static void snd_atiixp_remove(struct pci_dev *pci) 1334static void snd_atiixp_remove(struct pci_dev *pci)
1335{ 1335{
1336 snd_card_free(pci_get_drvdata(pci)); 1336 snd_card_free(pci_get_drvdata(pci));
1337 pci_set_drvdata(pci, NULL);
1338} 1337}
1339 1338
1340static struct pci_driver atiixp_modem_driver = { 1339static struct pci_driver atiixp_modem_driver = {
diff --git a/sound/pci/au88x0/au88x0.c b/sound/pci/au88x0/au88x0.c
index b157e1fadd8f..7059dd69e5e6 100644
--- a/sound/pci/au88x0/au88x0.c
+++ b/sound/pci/au88x0/au88x0.c
@@ -371,7 +371,6 @@ snd_vortex_probe(struct pci_dev *pci, const struct pci_device_id *pci_id)
371static void snd_vortex_remove(struct pci_dev *pci) 371static void snd_vortex_remove(struct pci_dev *pci)
372{ 372{
373 snd_card_free(pci_get_drvdata(pci)); 373 snd_card_free(pci_get_drvdata(pci));
374 pci_set_drvdata(pci, NULL);
375} 374}
376 375
377// pci_driver definition 376// pci_driver definition
diff --git a/sound/pci/aw2/aw2-alsa.c b/sound/pci/aw2/aw2-alsa.c
index 08e9a4702cbc..2925220d3fcf 100644
--- a/sound/pci/aw2/aw2-alsa.c
+++ b/sound/pci/aw2/aw2-alsa.c
@@ -392,7 +392,6 @@ static int snd_aw2_probe(struct pci_dev *pci,
392static void snd_aw2_remove(struct pci_dev *pci) 392static void snd_aw2_remove(struct pci_dev *pci)
393{ 393{
394 snd_card_free(pci_get_drvdata(pci)); 394 snd_card_free(pci_get_drvdata(pci));
395 pci_set_drvdata(pci, NULL);
396} 395}
397 396
398/* open callback */ 397/* open callback */
diff --git a/sound/pci/azt3328.c b/sound/pci/azt3328.c
index 1204a0fa3368..c8e121611593 100644
--- a/sound/pci/azt3328.c
+++ b/sound/pci/azt3328.c
@@ -2725,7 +2725,6 @@ snd_azf3328_remove(struct pci_dev *pci)
2725{ 2725{
2726 snd_azf3328_dbgcallenter(); 2726 snd_azf3328_dbgcallenter();
2727 snd_card_free(pci_get_drvdata(pci)); 2727 snd_card_free(pci_get_drvdata(pci));
2728 pci_set_drvdata(pci, NULL);
2729 snd_azf3328_dbgcallleave(); 2728 snd_azf3328_dbgcallleave();
2730} 2729}
2731 2730
diff --git a/sound/pci/bt87x.c b/sound/pci/bt87x.c
index 9febe5509748..18802039497a 100644
--- a/sound/pci/bt87x.c
+++ b/sound/pci/bt87x.c
@@ -953,7 +953,6 @@ _error:
953static void snd_bt87x_remove(struct pci_dev *pci) 953static void snd_bt87x_remove(struct pci_dev *pci)
954{ 954{
955 snd_card_free(pci_get_drvdata(pci)); 955 snd_card_free(pci_get_drvdata(pci));
956 pci_set_drvdata(pci, NULL);
957} 956}
958 957
959/* default entries for all Bt87x cards - it's not exported */ 958/* default entries for all Bt87x cards - it's not exported */
diff --git a/sound/pci/ca0106/ca0106_main.c b/sound/pci/ca0106/ca0106_main.c
index 1610a5705970..f4db5587e86e 100644
--- a/sound/pci/ca0106/ca0106_main.c
+++ b/sound/pci/ca0106/ca0106_main.c
@@ -1896,7 +1896,6 @@ static int snd_ca0106_probe(struct pci_dev *pci,
1896static void snd_ca0106_remove(struct pci_dev *pci) 1896static void snd_ca0106_remove(struct pci_dev *pci)
1897{ 1897{
1898 snd_card_free(pci_get_drvdata(pci)); 1898 snd_card_free(pci_get_drvdata(pci));
1899 pci_set_drvdata(pci, NULL);
1900} 1899}
1901 1900
1902#ifdef CONFIG_PM_SLEEP 1901#ifdef CONFIG_PM_SLEEP
diff --git a/sound/pci/cmipci.c b/sound/pci/cmipci.c
index c617435db6e6..2755ec5bcc25 100644
--- a/sound/pci/cmipci.c
+++ b/sound/pci/cmipci.c
@@ -3317,7 +3317,6 @@ static int snd_cmipci_probe(struct pci_dev *pci,
3317static void snd_cmipci_remove(struct pci_dev *pci) 3317static void snd_cmipci_remove(struct pci_dev *pci)
3318{ 3318{
3319 snd_card_free(pci_get_drvdata(pci)); 3319 snd_card_free(pci_get_drvdata(pci));
3320 pci_set_drvdata(pci, NULL);
3321} 3320}
3322 3321
3323 3322
diff --git a/sound/pci/cs4281.c b/sound/pci/cs4281.c
index 6a8695069941..1dc793e742d7 100644
--- a/sound/pci/cs4281.c
+++ b/sound/pci/cs4281.c
@@ -1312,7 +1312,7 @@ static int snd_cs4281_free(struct cs4281 *chip)
1312 /* Sound System Power Management - Turn Everything OFF */ 1312 /* Sound System Power Management - Turn Everything OFF */
1313 snd_cs4281_pokeBA0(chip, BA0_SSPM, 0); 1313 snd_cs4281_pokeBA0(chip, BA0_SSPM, 0);
1314 /* PCI interface - D3 state */ 1314 /* PCI interface - D3 state */
1315 pci_set_power_state(chip->pci, 3); 1315 pci_set_power_state(chip->pci, PCI_D3hot);
1316 1316
1317 if (chip->irq >= 0) 1317 if (chip->irq >= 0)
1318 free_irq(chip->irq, chip); 1318 free_irq(chip->irq, chip);
@@ -1971,7 +1971,6 @@ static int snd_cs4281_probe(struct pci_dev *pci,
1971static void snd_cs4281_remove(struct pci_dev *pci) 1971static void snd_cs4281_remove(struct pci_dev *pci)
1972{ 1972{
1973 snd_card_free(pci_get_drvdata(pci)); 1973 snd_card_free(pci_get_drvdata(pci));
1974 pci_set_drvdata(pci, NULL);
1975} 1974}
1976 1975
1977/* 1976/*
diff --git a/sound/pci/cs46xx/cs46xx.c b/sound/pci/cs46xx/cs46xx.c
index 6b0d8b50a305..b03498325d66 100644
--- a/sound/pci/cs46xx/cs46xx.c
+++ b/sound/pci/cs46xx/cs46xx.c
@@ -158,7 +158,6 @@ static int snd_card_cs46xx_probe(struct pci_dev *pci,
158static void snd_card_cs46xx_remove(struct pci_dev *pci) 158static void snd_card_cs46xx_remove(struct pci_dev *pci)
159{ 159{
160 snd_card_free(pci_get_drvdata(pci)); 160 snd_card_free(pci_get_drvdata(pci));
161 pci_set_drvdata(pci, NULL);
162} 161}
163 162
164static struct pci_driver cs46xx_driver = { 163static struct pci_driver cs46xx_driver = {
diff --git a/sound/pci/cs5530.c b/sound/pci/cs5530.c
index dace827b45d1..c6b82c85e044 100644
--- a/sound/pci/cs5530.c
+++ b/sound/pci/cs5530.c
@@ -91,7 +91,6 @@ static int snd_cs5530_dev_free(struct snd_device *device)
91static void snd_cs5530_remove(struct pci_dev *pci) 91static void snd_cs5530_remove(struct pci_dev *pci)
92{ 92{
93 snd_card_free(pci_get_drvdata(pci)); 93 snd_card_free(pci_get_drvdata(pci));
94 pci_set_drvdata(pci, NULL);
95} 94}
96 95
97static u8 snd_cs5530_mixer_read(unsigned long io, u8 reg) 96static u8 snd_cs5530_mixer_read(unsigned long io, u8 reg)
diff --git a/sound/pci/cs5535audio/cs5535audio.c b/sound/pci/cs5535audio/cs5535audio.c
index 7e4b13e2d12a..902bebd3b3fb 100644
--- a/sound/pci/cs5535audio/cs5535audio.c
+++ b/sound/pci/cs5535audio/cs5535audio.c
@@ -391,7 +391,6 @@ static void snd_cs5535audio_remove(struct pci_dev *pci)
391{ 391{
392 olpc_quirks_cleanup(); 392 olpc_quirks_cleanup();
393 snd_card_free(pci_get_drvdata(pci)); 393 snd_card_free(pci_get_drvdata(pci));
394 pci_set_drvdata(pci, NULL);
395} 394}
396 395
397static struct pci_driver cs5535audio_driver = { 396static struct pci_driver cs5535audio_driver = {
diff --git a/sound/pci/ctxfi/xfi.c b/sound/pci/ctxfi/xfi.c
index d01ffcb2b2f5..d464ad2fc7b7 100644
--- a/sound/pci/ctxfi/xfi.c
+++ b/sound/pci/ctxfi/xfi.c
@@ -122,7 +122,6 @@ error:
122static void ct_card_remove(struct pci_dev *pci) 122static void ct_card_remove(struct pci_dev *pci)
123{ 123{
124 snd_card_free(pci_get_drvdata(pci)); 124 snd_card_free(pci_get_drvdata(pci));
125 pci_set_drvdata(pci, NULL);
126} 125}
127 126
128#ifdef CONFIG_PM_SLEEP 127#ifdef CONFIG_PM_SLEEP
diff --git a/sound/pci/echoaudio/echoaudio.c b/sound/pci/echoaudio/echoaudio.c
index 760cbff53210..05cfe551ce42 100644
--- a/sound/pci/echoaudio/echoaudio.c
+++ b/sound/pci/echoaudio/echoaudio.c
@@ -2323,7 +2323,6 @@ static void snd_echo_remove(struct pci_dev *pci)
2323 chip = pci_get_drvdata(pci); 2323 chip = pci_get_drvdata(pci);
2324 if (chip) 2324 if (chip)
2325 snd_card_free(chip->card); 2325 snd_card_free(chip->card);
2326 pci_set_drvdata(pci, NULL);
2327} 2326}
2328 2327
2329 2328
diff --git a/sound/pci/emu10k1/emu10k1.c b/sound/pci/emu10k1/emu10k1.c
index 8c5010f7889c..9e1bd0c39a8c 100644
--- a/sound/pci/emu10k1/emu10k1.c
+++ b/sound/pci/emu10k1/emu10k1.c
@@ -202,7 +202,6 @@ static int snd_card_emu10k1_probe(struct pci_dev *pci,
202static void snd_card_emu10k1_remove(struct pci_dev *pci) 202static void snd_card_emu10k1_remove(struct pci_dev *pci)
203{ 203{
204 snd_card_free(pci_get_drvdata(pci)); 204 snd_card_free(pci_get_drvdata(pci));
205 pci_set_drvdata(pci, NULL);
206} 205}
207 206
208 207
diff --git a/sound/pci/emu10k1/emu10k1x.c b/sound/pci/emu10k1/emu10k1x.c
index cdff11d48ebd..56ad9d6f200d 100644
--- a/sound/pci/emu10k1/emu10k1x.c
+++ b/sound/pci/emu10k1/emu10k1x.c
@@ -1623,7 +1623,6 @@ static int snd_emu10k1x_probe(struct pci_dev *pci,
1623static void snd_emu10k1x_remove(struct pci_dev *pci) 1623static void snd_emu10k1x_remove(struct pci_dev *pci)
1624{ 1624{
1625 snd_card_free(pci_get_drvdata(pci)); 1625 snd_card_free(pci_get_drvdata(pci));
1626 pci_set_drvdata(pci, NULL);
1627} 1626}
1628 1627
1629// PCI IDs 1628// PCI IDs
diff --git a/sound/pci/ens1370.c b/sound/pci/ens1370.c
index db2dc835171d..ca8929b9a5d6 100644
--- a/sound/pci/ens1370.c
+++ b/sound/pci/ens1370.c
@@ -1939,7 +1939,7 @@ static int snd_ensoniq_free(struct ensoniq *ensoniq)
1939#endif 1939#endif
1940 if (ensoniq->irq >= 0) 1940 if (ensoniq->irq >= 0)
1941 synchronize_irq(ensoniq->irq); 1941 synchronize_irq(ensoniq->irq);
1942 pci_set_power_state(ensoniq->pci, 3); 1942 pci_set_power_state(ensoniq->pci, PCI_D3hot);
1943 __hw_end: 1943 __hw_end:
1944#ifdef CHIP1370 1944#ifdef CHIP1370
1945 if (ensoniq->dma_bug.area) 1945 if (ensoniq->dma_bug.area)
@@ -2497,7 +2497,6 @@ static int snd_audiopci_probe(struct pci_dev *pci,
2497static void snd_audiopci_remove(struct pci_dev *pci) 2497static void snd_audiopci_remove(struct pci_dev *pci)
2498{ 2498{
2499 snd_card_free(pci_get_drvdata(pci)); 2499 snd_card_free(pci_get_drvdata(pci));
2500 pci_set_drvdata(pci, NULL);
2501} 2500}
2502 2501
2503static struct pci_driver ens137x_driver = { 2502static struct pci_driver ens137x_driver = {
diff --git a/sound/pci/es1938.c b/sound/pci/es1938.c
index 8423403954ab..9213fb38921c 100644
--- a/sound/pci/es1938.c
+++ b/sound/pci/es1938.c
@@ -1881,7 +1881,6 @@ static int snd_es1938_probe(struct pci_dev *pci,
1881static void snd_es1938_remove(struct pci_dev *pci) 1881static void snd_es1938_remove(struct pci_dev *pci)
1882{ 1882{
1883 snd_card_free(pci_get_drvdata(pci)); 1883 snd_card_free(pci_get_drvdata(pci));
1884 pci_set_drvdata(pci, NULL);
1885} 1884}
1886 1885
1887static struct pci_driver es1938_driver = { 1886static struct pci_driver es1938_driver = {
diff --git a/sound/pci/es1968.c b/sound/pci/es1968.c
index a1f32b5ae0d1..5e2ec9687731 100644
--- a/sound/pci/es1968.c
+++ b/sound/pci/es1968.c
@@ -564,6 +564,7 @@ struct es1968 {
564#ifdef CONFIG_SND_ES1968_RADIO 564#ifdef CONFIG_SND_ES1968_RADIO
565 struct v4l2_device v4l2_dev; 565 struct v4l2_device v4l2_dev;
566 struct snd_tea575x tea; 566 struct snd_tea575x tea;
567 unsigned int tea575x_tuner;
567#endif 568#endif
568}; 569};
569 570
@@ -2557,37 +2558,47 @@ static int snd_es1968_input_register(struct es1968 *chip)
2557 bits 1=unmask write to given bit */ 2558 bits 1=unmask write to given bit */
2558#define IO_DIR 8 /* direction register offset from GPIO_DATA 2559#define IO_DIR 8 /* direction register offset from GPIO_DATA
2559 bits 0/1=read/write direction */ 2560 bits 0/1=read/write direction */
2560/* mask bits for GPIO lines */ 2561
2561#define STR_DATA 0x0040 /* GPIO6 */ 2562/* GPIO to TEA575x maps */
2562#define STR_CLK 0x0080 /* GPIO7 */ 2563struct snd_es1968_tea575x_gpio {
2563#define STR_WREN 0x0100 /* GPIO8 */ 2564 u8 data, clk, wren, most;
2564#define STR_MOST 0x0200 /* GPIO9 */ 2565 char *name;
2566};
2567
2568static struct snd_es1968_tea575x_gpio snd_es1968_tea575x_gpios[] = {
2569 { .data = 6, .clk = 7, .wren = 8, .most = 9, .name = "SF64-PCE2" },
2570 { .data = 7, .clk = 8, .wren = 6, .most = 10, .name = "M56VAP" },
2571};
2572
2573#define get_tea575x_gpio(chip) \
2574 (&snd_es1968_tea575x_gpios[(chip)->tea575x_tuner])
2575
2565 2576
2566static void snd_es1968_tea575x_set_pins(struct snd_tea575x *tea, u8 pins) 2577static void snd_es1968_tea575x_set_pins(struct snd_tea575x *tea, u8 pins)
2567{ 2578{
2568 struct es1968 *chip = tea->private_data; 2579 struct es1968 *chip = tea->private_data;
2569 unsigned long io = chip->io_port + GPIO_DATA; 2580 struct snd_es1968_tea575x_gpio gpio = *get_tea575x_gpio(chip);
2570 u16 val = 0; 2581 u16 val = 0;
2571 2582
2572 val |= (pins & TEA575X_DATA) ? STR_DATA : 0; 2583 val |= (pins & TEA575X_DATA) ? (1 << gpio.data) : 0;
2573 val |= (pins & TEA575X_CLK) ? STR_CLK : 0; 2584 val |= (pins & TEA575X_CLK) ? (1 << gpio.clk) : 0;
2574 val |= (pins & TEA575X_WREN) ? STR_WREN : 0; 2585 val |= (pins & TEA575X_WREN) ? (1 << gpio.wren) : 0;
2575 2586
2576 outw(val, io); 2587 outw(val, chip->io_port + GPIO_DATA);
2577} 2588}
2578 2589
2579static u8 snd_es1968_tea575x_get_pins(struct snd_tea575x *tea) 2590static u8 snd_es1968_tea575x_get_pins(struct snd_tea575x *tea)
2580{ 2591{
2581 struct es1968 *chip = tea->private_data; 2592 struct es1968 *chip = tea->private_data;
2582 unsigned long io = chip->io_port + GPIO_DATA; 2593 struct snd_es1968_tea575x_gpio gpio = *get_tea575x_gpio(chip);
2583 u16 val = inw(io); 2594 u16 val = inw(chip->io_port + GPIO_DATA);
2584 u8 ret; 2595 u8 ret = 0;
2585 2596
2586 ret = 0; 2597 if (val & (1 << gpio.data))
2587 if (val & STR_DATA)
2588 ret |= TEA575X_DATA; 2598 ret |= TEA575X_DATA;
2589 if (val & STR_MOST) 2599 if (val & (1 << gpio.most))
2590 ret |= TEA575X_MOST; 2600 ret |= TEA575X_MOST;
2601
2591 return ret; 2602 return ret;
2592} 2603}
2593 2604
@@ -2596,13 +2607,18 @@ static void snd_es1968_tea575x_set_direction(struct snd_tea575x *tea, bool outpu
2596 struct es1968 *chip = tea->private_data; 2607 struct es1968 *chip = tea->private_data;
2597 unsigned long io = chip->io_port + GPIO_DATA; 2608 unsigned long io = chip->io_port + GPIO_DATA;
2598 u16 odir = inw(io + IO_DIR); 2609 u16 odir = inw(io + IO_DIR);
2610 struct snd_es1968_tea575x_gpio gpio = *get_tea575x_gpio(chip);
2599 2611
2600 if (output) { 2612 if (output) {
2601 outw(~(STR_DATA | STR_CLK | STR_WREN), io + IO_MASK); 2613 outw(~((1 << gpio.data) | (1 << gpio.clk) | (1 << gpio.wren)),
2602 outw(odir | STR_DATA | STR_CLK | STR_WREN, io + IO_DIR); 2614 io + IO_MASK);
2615 outw(odir | (1 << gpio.data) | (1 << gpio.clk) | (1 << gpio.wren),
2616 io + IO_DIR);
2603 } else { 2617 } else {
2604 outw(~(STR_CLK | STR_WREN | STR_DATA | STR_MOST), io + IO_MASK); 2618 outw(~((1 << gpio.clk) | (1 << gpio.wren) | (1 << gpio.data) | (1 << gpio.most)),
2605 outw((odir & ~(STR_DATA | STR_MOST)) | STR_CLK | STR_WREN, io + IO_DIR); 2619 io + IO_MASK);
2620 outw((odir & ~((1 << gpio.data) | (1 << gpio.most)))
2621 | (1 << gpio.clk) | (1 << gpio.wren), io + IO_DIR);
2606 } 2622 }
2607} 2623}
2608 2624
@@ -2772,6 +2788,9 @@ static int snd_es1968_create(struct snd_card *card,
2772 snd_card_set_dev(card, &pci->dev); 2788 snd_card_set_dev(card, &pci->dev);
2773 2789
2774#ifdef CONFIG_SND_ES1968_RADIO 2790#ifdef CONFIG_SND_ES1968_RADIO
2791 /* don't play with GPIOs on laptops */
2792 if (chip->pci->subsystem_vendor != 0x125d)
2793 goto no_radio;
2775 err = v4l2_device_register(&pci->dev, &chip->v4l2_dev); 2794 err = v4l2_device_register(&pci->dev, &chip->v4l2_dev);
2776 if (err < 0) { 2795 if (err < 0) {
2777 snd_es1968_free(chip); 2796 snd_es1968_free(chip);
@@ -2781,10 +2800,18 @@ static int snd_es1968_create(struct snd_card *card,
2781 chip->tea.private_data = chip; 2800 chip->tea.private_data = chip;
2782 chip->tea.radio_nr = radio_nr; 2801 chip->tea.radio_nr = radio_nr;
2783 chip->tea.ops = &snd_es1968_tea_ops; 2802 chip->tea.ops = &snd_es1968_tea_ops;
2784 strlcpy(chip->tea.card, "SF64-PCE2", sizeof(chip->tea.card));
2785 sprintf(chip->tea.bus_info, "PCI:%s", pci_name(pci)); 2803 sprintf(chip->tea.bus_info, "PCI:%s", pci_name(pci));
2786 if (!snd_tea575x_init(&chip->tea, THIS_MODULE)) 2804 for (i = 0; i < ARRAY_SIZE(snd_es1968_tea575x_gpios); i++) {
2787 printk(KERN_INFO "es1968: detected TEA575x radio\n"); 2805 chip->tea575x_tuner = i;
2806 if (!snd_tea575x_init(&chip->tea, THIS_MODULE)) {
2807 snd_printk(KERN_INFO "es1968: detected TEA575x radio type %s\n",
2808 get_tea575x_gpio(chip)->name);
2809 strlcpy(chip->tea.card, get_tea575x_gpio(chip)->name,
2810 sizeof(chip->tea.card));
2811 break;
2812 }
2813 }
2814no_radio:
2788#endif 2815#endif
2789 2816
2790 *chip_ret = chip; 2817 *chip_ret = chip;
@@ -2909,7 +2936,6 @@ static int snd_es1968_probe(struct pci_dev *pci,
2909static void snd_es1968_remove(struct pci_dev *pci) 2936static void snd_es1968_remove(struct pci_dev *pci)
2910{ 2937{
2911 snd_card_free(pci_get_drvdata(pci)); 2938 snd_card_free(pci_get_drvdata(pci));
2912 pci_set_drvdata(pci, NULL);
2913} 2939}
2914 2940
2915static struct pci_driver es1968_driver = { 2941static struct pci_driver es1968_driver = {
diff --git a/sound/pci/fm801.c b/sound/pci/fm801.c
index 4f07fda5adf2..706c5b67b708 100644
--- a/sound/pci/fm801.c
+++ b/sound/pci/fm801.c
@@ -1370,7 +1370,6 @@ static int snd_card_fm801_probe(struct pci_dev *pci,
1370static void snd_card_fm801_remove(struct pci_dev *pci) 1370static void snd_card_fm801_remove(struct pci_dev *pci)
1371{ 1371{
1372 snd_card_free(pci_get_drvdata(pci)); 1372 snd_card_free(pci_get_drvdata(pci));
1373 pci_set_drvdata(pci, NULL);
1374} 1373}
1375 1374
1376#ifdef CONFIG_PM_SLEEP 1375#ifdef CONFIG_PM_SLEEP
diff --git a/sound/pci/hda/Kconfig b/sound/pci/hda/Kconfig
index 80a7d44bcf81..0c5371abecd2 100644
--- a/sound/pci/hda/Kconfig
+++ b/sound/pci/hda/Kconfig
@@ -140,7 +140,6 @@ config SND_HDA_CODEC_VIA
140 140
141config SND_HDA_CODEC_HDMI 141config SND_HDA_CODEC_HDMI
142 bool "Build HDMI/DisplayPort HD-audio codec support" 142 bool "Build HDMI/DisplayPort HD-audio codec support"
143 select SND_DYNAMIC_MINORS
144 default y 143 default y
145 help 144 help
146 Say Y here to include HDMI and DisplayPort HD-audio codec 145 Say Y here to include HDMI and DisplayPort HD-audio codec
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c
index 55108b5fb291..35090b3acbac 100644
--- a/sound/pci/hda/hda_codec.c
+++ b/sound/pci/hda/hda_codec.c
@@ -185,20 +185,19 @@ EXPORT_SYMBOL_HDA(snd_hda_get_jack_type);
185 * Compose a 32bit command word to be sent to the HD-audio controller 185 * Compose a 32bit command word to be sent to the HD-audio controller
186 */ 186 */
187static inline unsigned int 187static inline unsigned int
188make_codec_cmd(struct hda_codec *codec, hda_nid_t nid, int direct, 188make_codec_cmd(struct hda_codec *codec, hda_nid_t nid, int flags,
189 unsigned int verb, unsigned int parm) 189 unsigned int verb, unsigned int parm)
190{ 190{
191 u32 val; 191 u32 val;
192 192
193 if ((codec->addr & ~0xf) || (direct & ~1) || (nid & ~0x7f) || 193 if ((codec->addr & ~0xf) || (nid & ~0x7f) ||
194 (verb & ~0xfff) || (parm & ~0xffff)) { 194 (verb & ~0xfff) || (parm & ~0xffff)) {
195 printk(KERN_ERR "hda-codec: out of range cmd %x:%x:%x:%x:%x\n", 195 printk(KERN_ERR "hda-codec: out of range cmd %x:%x:%x:%x\n",
196 codec->addr, direct, nid, verb, parm); 196 codec->addr, nid, verb, parm);
197 return ~0; 197 return ~0;
198 } 198 }
199 199
200 val = (u32)codec->addr << 28; 200 val = (u32)codec->addr << 28;
201 val |= (u32)direct << 27;
202 val |= (u32)nid << 20; 201 val |= (u32)nid << 20;
203 val |= verb << 8; 202 val |= verb << 8;
204 val |= parm; 203 val |= parm;
@@ -209,7 +208,7 @@ make_codec_cmd(struct hda_codec *codec, hda_nid_t nid, int direct,
209 * Send and receive a verb 208 * Send and receive a verb
210 */ 209 */
211static int codec_exec_verb(struct hda_codec *codec, unsigned int cmd, 210static int codec_exec_verb(struct hda_codec *codec, unsigned int cmd,
212 unsigned int *res) 211 int flags, unsigned int *res)
213{ 212{
214 struct hda_bus *bus = codec->bus; 213 struct hda_bus *bus = codec->bus;
215 int err; 214 int err;
@@ -222,6 +221,8 @@ static int codec_exec_verb(struct hda_codec *codec, unsigned int cmd,
222 again: 221 again:
223 snd_hda_power_up(codec); 222 snd_hda_power_up(codec);
224 mutex_lock(&bus->cmd_mutex); 223 mutex_lock(&bus->cmd_mutex);
224 if (flags & HDA_RW_NO_RESPONSE_FALLBACK)
225 bus->no_response_fallback = 1;
225 for (;;) { 226 for (;;) {
226 trace_hda_send_cmd(codec, cmd); 227 trace_hda_send_cmd(codec, cmd);
227 err = bus->ops.command(bus, cmd); 228 err = bus->ops.command(bus, cmd);
@@ -234,6 +235,7 @@ static int codec_exec_verb(struct hda_codec *codec, unsigned int cmd,
234 *res = bus->ops.get_response(bus, codec->addr); 235 *res = bus->ops.get_response(bus, codec->addr);
235 trace_hda_get_response(codec, *res); 236 trace_hda_get_response(codec, *res);
236 } 237 }
238 bus->no_response_fallback = 0;
237 mutex_unlock(&bus->cmd_mutex); 239 mutex_unlock(&bus->cmd_mutex);
238 snd_hda_power_down(codec); 240 snd_hda_power_down(codec);
239 if (!codec_in_pm(codec) && res && *res == -1 && bus->rirb_error) { 241 if (!codec_in_pm(codec) && res && *res == -1 && bus->rirb_error) {
@@ -255,7 +257,7 @@ static int codec_exec_verb(struct hda_codec *codec, unsigned int cmd,
255 * snd_hda_codec_read - send a command and get the response 257 * snd_hda_codec_read - send a command and get the response
256 * @codec: the HDA codec 258 * @codec: the HDA codec
257 * @nid: NID to send the command 259 * @nid: NID to send the command
258 * @direct: direct flag 260 * @flags: optional bit flags
259 * @verb: the verb to send 261 * @verb: the verb to send
260 * @parm: the parameter for the verb 262 * @parm: the parameter for the verb
261 * 263 *
@@ -264,12 +266,12 @@ static int codec_exec_verb(struct hda_codec *codec, unsigned int cmd,
264 * Returns the obtained response value, or -1 for an error. 266 * Returns the obtained response value, or -1 for an error.
265 */ 267 */
266unsigned int snd_hda_codec_read(struct hda_codec *codec, hda_nid_t nid, 268unsigned int snd_hda_codec_read(struct hda_codec *codec, hda_nid_t nid,
267 int direct, 269 int flags,
268 unsigned int verb, unsigned int parm) 270 unsigned int verb, unsigned int parm)
269{ 271{
270 unsigned cmd = make_codec_cmd(codec, nid, direct, verb, parm); 272 unsigned cmd = make_codec_cmd(codec, nid, flags, verb, parm);
271 unsigned int res; 273 unsigned int res;
272 if (codec_exec_verb(codec, cmd, &res)) 274 if (codec_exec_verb(codec, cmd, flags, &res))
273 return -1; 275 return -1;
274 return res; 276 return res;
275} 277}
@@ -279,7 +281,7 @@ EXPORT_SYMBOL_HDA(snd_hda_codec_read);
279 * snd_hda_codec_write - send a single command without waiting for response 281 * snd_hda_codec_write - send a single command without waiting for response
280 * @codec: the HDA codec 282 * @codec: the HDA codec
281 * @nid: NID to send the command 283 * @nid: NID to send the command
282 * @direct: direct flag 284 * @flags: optional bit flags
283 * @verb: the verb to send 285 * @verb: the verb to send
284 * @parm: the parameter for the verb 286 * @parm: the parameter for the verb
285 * 287 *
@@ -287,12 +289,12 @@ EXPORT_SYMBOL_HDA(snd_hda_codec_read);
287 * 289 *
288 * Returns 0 if successful, or a negative error code. 290 * Returns 0 if successful, or a negative error code.
289 */ 291 */
290int snd_hda_codec_write(struct hda_codec *codec, hda_nid_t nid, int direct, 292int snd_hda_codec_write(struct hda_codec *codec, hda_nid_t nid, int flags,
291 unsigned int verb, unsigned int parm) 293 unsigned int verb, unsigned int parm)
292{ 294{
293 unsigned int cmd = make_codec_cmd(codec, nid, direct, verb, parm); 295 unsigned int cmd = make_codec_cmd(codec, nid, flags, verb, parm);
294 unsigned int res; 296 unsigned int res;
295 return codec_exec_verb(codec, cmd, 297 return codec_exec_verb(codec, cmd, flags,
296 codec->bus->sync_write ? &res : NULL); 298 codec->bus->sync_write ? &res : NULL);
297} 299}
298EXPORT_SYMBOL_HDA(snd_hda_codec_write); 300EXPORT_SYMBOL_HDA(snd_hda_codec_write);
@@ -3582,7 +3584,7 @@ EXPORT_SYMBOL_HDA(snd_hda_create_spdif_in_ctls);
3582 * snd_hda_codec_write_cache - send a single command with caching 3584 * snd_hda_codec_write_cache - send a single command with caching
3583 * @codec: the HDA codec 3585 * @codec: the HDA codec
3584 * @nid: NID to send the command 3586 * @nid: NID to send the command
3585 * @direct: direct flag 3587 * @flags: optional bit flags
3586 * @verb: the verb to send 3588 * @verb: the verb to send
3587 * @parm: the parameter for the verb 3589 * @parm: the parameter for the verb
3588 * 3590 *
@@ -3591,7 +3593,7 @@ EXPORT_SYMBOL_HDA(snd_hda_create_spdif_in_ctls);
3591 * Returns 0 if successful, or a negative error code. 3593 * Returns 0 if successful, or a negative error code.
3592 */ 3594 */
3593int snd_hda_codec_write_cache(struct hda_codec *codec, hda_nid_t nid, 3595int snd_hda_codec_write_cache(struct hda_codec *codec, hda_nid_t nid,
3594 int direct, unsigned int verb, unsigned int parm) 3596 int flags, unsigned int verb, unsigned int parm)
3595{ 3597{
3596 int err; 3598 int err;
3597 struct hda_cache_head *c; 3599 struct hda_cache_head *c;
@@ -3600,7 +3602,7 @@ int snd_hda_codec_write_cache(struct hda_codec *codec, hda_nid_t nid,
3600 3602
3601 cache_only = codec->cached_write; 3603 cache_only = codec->cached_write;
3602 if (!cache_only) { 3604 if (!cache_only) {
3603 err = snd_hda_codec_write(codec, nid, direct, verb, parm); 3605 err = snd_hda_codec_write(codec, nid, flags, verb, parm);
3604 if (err < 0) 3606 if (err < 0)
3605 return err; 3607 return err;
3606 } 3608 }
@@ -3624,7 +3626,7 @@ EXPORT_SYMBOL_HDA(snd_hda_codec_write_cache);
3624 * snd_hda_codec_update_cache - check cache and write the cmd only when needed 3626 * snd_hda_codec_update_cache - check cache and write the cmd only when needed
3625 * @codec: the HDA codec 3627 * @codec: the HDA codec
3626 * @nid: NID to send the command 3628 * @nid: NID to send the command
3627 * @direct: direct flag 3629 * @flags: optional bit flags
3628 * @verb: the verb to send 3630 * @verb: the verb to send
3629 * @parm: the parameter for the verb 3631 * @parm: the parameter for the verb
3630 * 3632 *
@@ -3635,7 +3637,7 @@ EXPORT_SYMBOL_HDA(snd_hda_codec_write_cache);
3635 * Returns 0 if successful, or a negative error code. 3637 * Returns 0 if successful, or a negative error code.
3636 */ 3638 */
3637int snd_hda_codec_update_cache(struct hda_codec *codec, hda_nid_t nid, 3639int snd_hda_codec_update_cache(struct hda_codec *codec, hda_nid_t nid,
3638 int direct, unsigned int verb, unsigned int parm) 3640 int flags, unsigned int verb, unsigned int parm)
3639{ 3641{
3640 struct hda_cache_head *c; 3642 struct hda_cache_head *c;
3641 u32 key; 3643 u32 key;
@@ -3651,7 +3653,7 @@ int snd_hda_codec_update_cache(struct hda_codec *codec, hda_nid_t nid,
3651 return 0; 3653 return 0;
3652 } 3654 }
3653 mutex_unlock(&codec->bus->cmd_mutex); 3655 mutex_unlock(&codec->bus->cmd_mutex);
3654 return snd_hda_codec_write_cache(codec, nid, direct, verb, parm); 3656 return snd_hda_codec_write_cache(codec, nid, flags, verb, parm);
3655} 3657}
3656EXPORT_SYMBOL_HDA(snd_hda_codec_update_cache); 3658EXPORT_SYMBOL_HDA(snd_hda_codec_update_cache);
3657 3659
@@ -3806,11 +3808,13 @@ static unsigned int hda_set_power_state(struct hda_codec *codec,
3806 hda_nid_t fg = codec->afg ? codec->afg : codec->mfg; 3808 hda_nid_t fg = codec->afg ? codec->afg : codec->mfg;
3807 int count; 3809 int count;
3808 unsigned int state; 3810 unsigned int state;
3811 int flags = 0;
3809 3812
3810 /* this delay seems necessary to avoid click noise at power-down */ 3813 /* this delay seems necessary to avoid click noise at power-down */
3811 if (power_state == AC_PWRST_D3) { 3814 if (power_state == AC_PWRST_D3) {
3812 /* transition time less than 10ms for power down */ 3815 /* transition time less than 10ms for power down */
3813 msleep(codec->epss ? 10 : 100); 3816 msleep(codec->epss ? 10 : 100);
3817 flags = HDA_RW_NO_RESPONSE_FALLBACK;
3814 } 3818 }
3815 3819
3816 /* repeat power states setting at most 10 times*/ 3820 /* repeat power states setting at most 10 times*/
@@ -3819,7 +3823,7 @@ static unsigned int hda_set_power_state(struct hda_codec *codec,
3819 codec->patch_ops.set_power_state(codec, fg, 3823 codec->patch_ops.set_power_state(codec, fg,
3820 power_state); 3824 power_state);
3821 else { 3825 else {
3822 snd_hda_codec_read(codec, fg, 0, 3826 snd_hda_codec_read(codec, fg, flags,
3823 AC_VERB_SET_POWER_STATE, 3827 AC_VERB_SET_POWER_STATE,
3824 power_state); 3828 power_state);
3825 snd_hda_codec_set_power_to_all(codec, fg, power_state); 3829 snd_hda_codec_set_power_to_all(codec, fg, power_state);
@@ -4461,12 +4465,13 @@ const char *snd_hda_pcm_type_name[HDA_PCM_NTYPES] = {
4461 4465
4462/* 4466/*
4463 * get the empty PCM device number to assign 4467 * get the empty PCM device number to assign
4464 *
4465 * note the max device number is limited by HDA_MAX_PCMS, currently 10
4466 */ 4468 */
4467static int get_empty_pcm_device(struct hda_bus *bus, int type) 4469static int get_empty_pcm_device(struct hda_bus *bus, unsigned int type)
4468{ 4470{
4469 /* audio device indices; not linear to keep compatibility */ 4471 /* audio device indices; not linear to keep compatibility */
4472 /* assigned to static slots up to dev#10; if more needed, assign
4473 * the later slot dynamically (when CONFIG_SND_DYNAMIC_MINORS=y)
4474 */
4470 static int audio_idx[HDA_PCM_NTYPES][5] = { 4475 static int audio_idx[HDA_PCM_NTYPES][5] = {
4471 [HDA_PCM_TYPE_AUDIO] = { 0, 2, 4, 5, -1 }, 4476 [HDA_PCM_TYPE_AUDIO] = { 0, 2, 4, 5, -1 },
4472 [HDA_PCM_TYPE_SPDIF] = { 1, -1 }, 4477 [HDA_PCM_TYPE_SPDIF] = { 1, -1 },
@@ -4480,18 +4485,28 @@ static int get_empty_pcm_device(struct hda_bus *bus, int type)
4480 return -EINVAL; 4485 return -EINVAL;
4481 } 4486 }
4482 4487
4483 for (i = 0; audio_idx[type][i] >= 0 ; i++) 4488 for (i = 0; audio_idx[type][i] >= 0; i++) {
4489#ifndef CONFIG_SND_DYNAMIC_MINORS
4490 if (audio_idx[type][i] >= 8)
4491 break;
4492#endif
4484 if (!test_and_set_bit(audio_idx[type][i], bus->pcm_dev_bits)) 4493 if (!test_and_set_bit(audio_idx[type][i], bus->pcm_dev_bits))
4485 return audio_idx[type][i]; 4494 return audio_idx[type][i];
4495 }
4486 4496
4497#ifdef CONFIG_SND_DYNAMIC_MINORS
4487 /* non-fixed slots starting from 10 */ 4498 /* non-fixed slots starting from 10 */
4488 for (i = 10; i < 32; i++) { 4499 for (i = 10; i < 32; i++) {
4489 if (!test_and_set_bit(i, bus->pcm_dev_bits)) 4500 if (!test_and_set_bit(i, bus->pcm_dev_bits))
4490 return i; 4501 return i;
4491 } 4502 }
4503#endif
4492 4504
4493 snd_printk(KERN_WARNING "Too many %s devices\n", 4505 snd_printk(KERN_WARNING "Too many %s devices\n",
4494 snd_hda_pcm_type_name[type]); 4506 snd_hda_pcm_type_name[type]);
4507#ifndef CONFIG_SND_DYNAMIC_MINORS
4508 snd_printk(KERN_WARNING "Consider building the kernel with CONFIG_SND_DYNAMIC_MINORS=y\n");
4509#endif
4495 return -EAGAIN; 4510 return -EAGAIN;
4496} 4511}
4497 4512
diff --git a/sound/pci/hda/hda_codec.h b/sound/pci/hda/hda_codec.h
index c93f9021f452..701c2e069b10 100644
--- a/sound/pci/hda/hda_codec.h
+++ b/sound/pci/hda/hda_codec.h
@@ -679,6 +679,7 @@ struct hda_bus {
679 unsigned int response_reset:1; /* controller was reset */ 679 unsigned int response_reset:1; /* controller was reset */
680 unsigned int in_reset:1; /* during reset operation */ 680 unsigned int in_reset:1; /* during reset operation */
681 unsigned int power_keep_link_on:1; /* don't power off HDA link */ 681 unsigned int power_keep_link_on:1; /* don't power off HDA link */
682 unsigned int no_response_fallback:1; /* don't fallback at RIRB error */
682 683
683 int primary_dig_out_type; /* primary digital out PCM type */ 684 int primary_dig_out_type; /* primary digital out PCM type */
684}; 685};
@@ -930,6 +931,8 @@ enum {
930 HDA_INPUT, HDA_OUTPUT 931 HDA_INPUT, HDA_OUTPUT
931}; 932};
932 933
934/* snd_hda_codec_read/write optional flags */
935#define HDA_RW_NO_RESPONSE_FALLBACK (1 << 0)
933 936
934/* 937/*
935 * constructors 938 * constructors
@@ -945,9 +948,9 @@ int snd_hda_codec_update_widgets(struct hda_codec *codec);
945 * low level functions 948 * low level functions
946 */ 949 */
947unsigned int snd_hda_codec_read(struct hda_codec *codec, hda_nid_t nid, 950unsigned int snd_hda_codec_read(struct hda_codec *codec, hda_nid_t nid,
948 int direct, 951 int flags,
949 unsigned int verb, unsigned int parm); 952 unsigned int verb, unsigned int parm);
950int snd_hda_codec_write(struct hda_codec *codec, hda_nid_t nid, int direct, 953int snd_hda_codec_write(struct hda_codec *codec, hda_nid_t nid, int flags,
951 unsigned int verb, unsigned int parm); 954 unsigned int verb, unsigned int parm);
952#define snd_hda_param_read(codec, nid, param) \ 955#define snd_hda_param_read(codec, nid, param) \
953 snd_hda_codec_read(codec, nid, 0, AC_VERB_PARAMETERS, param) 956 snd_hda_codec_read(codec, nid, 0, AC_VERB_PARAMETERS, param)
@@ -986,11 +989,11 @@ int snd_hda_queue_unsol_event(struct hda_bus *bus, u32 res, u32 res_ex);
986 989
987/* cached write */ 990/* cached write */
988int snd_hda_codec_write_cache(struct hda_codec *codec, hda_nid_t nid, 991int snd_hda_codec_write_cache(struct hda_codec *codec, hda_nid_t nid,
989 int direct, unsigned int verb, unsigned int parm); 992 int flags, unsigned int verb, unsigned int parm);
990void snd_hda_sequence_write_cache(struct hda_codec *codec, 993void snd_hda_sequence_write_cache(struct hda_codec *codec,
991 const struct hda_verb *seq); 994 const struct hda_verb *seq);
992int snd_hda_codec_update_cache(struct hda_codec *codec, hda_nid_t nid, 995int snd_hda_codec_update_cache(struct hda_codec *codec, hda_nid_t nid,
993 int direct, unsigned int verb, unsigned int parm); 996 int flags, unsigned int verb, unsigned int parm);
994void snd_hda_codec_resume_cache(struct hda_codec *codec); 997void snd_hda_codec_resume_cache(struct hda_codec *codec);
995/* both for cmd & amp caches */ 998/* both for cmd & amp caches */
996void snd_hda_codec_flush_cache(struct hda_codec *codec); 999void snd_hda_codec_flush_cache(struct hda_codec *codec);
diff --git a/sound/pci/hda/hda_generic.c b/sound/pci/hda/hda_generic.c
index 4b1524a861f3..8e77cbbad871 100644
--- a/sound/pci/hda/hda_generic.c
+++ b/sound/pci/hda/hda_generic.c
@@ -133,6 +133,9 @@ static void parse_user_hints(struct hda_codec *codec)
133 val = snd_hda_get_bool_hint(codec, "line_in_auto_switch"); 133 val = snd_hda_get_bool_hint(codec, "line_in_auto_switch");
134 if (val >= 0) 134 if (val >= 0)
135 spec->line_in_auto_switch = !!val; 135 spec->line_in_auto_switch = !!val;
136 val = snd_hda_get_bool_hint(codec, "auto_mute_via_amp");
137 if (val >= 0)
138 spec->auto_mute_via_amp = !!val;
136 val = snd_hda_get_bool_hint(codec, "need_dac_fix"); 139 val = snd_hda_get_bool_hint(codec, "need_dac_fix");
137 if (val >= 0) 140 if (val >= 0)
138 spec->need_dac_fix = !!val; 141 spec->need_dac_fix = !!val;
@@ -808,6 +811,9 @@ static void resume_path_from_idx(struct hda_codec *codec, int path_idx)
808 * Helper functions for creating mixer ctl elements 811 * Helper functions for creating mixer ctl elements
809 */ 812 */
810 813
814static int hda_gen_mixer_mute_put(struct snd_kcontrol *kcontrol,
815 struct snd_ctl_elem_value *ucontrol);
816
811enum { 817enum {
812 HDA_CTL_WIDGET_VOL, 818 HDA_CTL_WIDGET_VOL,
813 HDA_CTL_WIDGET_MUTE, 819 HDA_CTL_WIDGET_MUTE,
@@ -815,7 +821,15 @@ enum {
815}; 821};
816static const struct snd_kcontrol_new control_templates[] = { 822static const struct snd_kcontrol_new control_templates[] = {
817 HDA_CODEC_VOLUME(NULL, 0, 0, 0), 823 HDA_CODEC_VOLUME(NULL, 0, 0, 0),
818 HDA_CODEC_MUTE(NULL, 0, 0, 0), 824 /* only the put callback is replaced for handling the special mute */
825 {
826 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
827 .subdevice = HDA_SUBDEV_AMP_FLAG,
828 .info = snd_hda_mixer_amp_switch_info,
829 .get = snd_hda_mixer_amp_switch_get,
830 .put = hda_gen_mixer_mute_put, /* replaced */
831 .private_value = HDA_COMPOSE_AMP_VAL(0, 3, 0, 0),
832 },
819 HDA_BIND_MUTE(NULL, 0, 0, 0), 833 HDA_BIND_MUTE(NULL, 0, 0, 0),
820}; 834};
821 835
@@ -840,7 +854,7 @@ static int add_control_with_pfx(struct hda_gen_spec *spec, int type,
840 const char *pfx, const char *dir, 854 const char *pfx, const char *dir,
841 const char *sfx, int cidx, unsigned long val) 855 const char *sfx, int cidx, unsigned long val)
842{ 856{
843 char name[32]; 857 char name[SNDRV_CTL_ELEM_ID_NAME_MAXLEN];
844 snprintf(name, sizeof(name), "%s %s %s", pfx, dir, sfx); 858 snprintf(name, sizeof(name), "%s %s %s", pfx, dir, sfx);
845 if (!add_control(spec, type, name, cidx, val)) 859 if (!add_control(spec, type, name, cidx, val))
846 return -ENOMEM; 860 return -ENOMEM;
@@ -922,6 +936,23 @@ static int add_stereo_sw(struct hda_codec *codec, const char *pfx,
922 return add_sw_ctl(codec, pfx, cidx, chs, path); 936 return add_sw_ctl(codec, pfx, cidx, chs, path);
923} 937}
924 938
939/* playback mute control with the software mute bit check */
940static int hda_gen_mixer_mute_put(struct snd_kcontrol *kcontrol,
941 struct snd_ctl_elem_value *ucontrol)
942{
943 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
944 struct hda_gen_spec *spec = codec->spec;
945
946 if (spec->auto_mute_via_amp) {
947 hda_nid_t nid = get_amp_nid(kcontrol);
948 bool enabled = !((spec->mute_bits >> nid) & 1);
949 ucontrol->value.integer.value[0] &= enabled;
950 ucontrol->value.integer.value[1] &= enabled;
951 }
952
953 return snd_hda_mixer_amp_switch_put(kcontrol, ucontrol);
954}
955
925/* any ctl assigned to the path with the given index? */ 956/* any ctl assigned to the path with the given index? */
926static bool path_has_mixer(struct hda_codec *codec, int path_idx, int ctl_type) 957static bool path_has_mixer(struct hda_codec *codec, int path_idx, int ctl_type)
927{ 958{
@@ -1900,7 +1931,7 @@ static int create_extra_outs(struct hda_codec *codec, int num_pins,
1900 1931
1901 for (i = 0; i < num_pins; i++) { 1932 for (i = 0; i < num_pins; i++) {
1902 const char *name; 1933 const char *name;
1903 char tmp[44]; 1934 char tmp[SNDRV_CTL_ELEM_ID_NAME_MAXLEN];
1904 int err, idx = 0; 1935 int err, idx = 0;
1905 1936
1906 if (num_pins == 2 && i == 1 && !strcmp(pfx, "Speaker")) 1937 if (num_pins == 2 && i == 1 && !strcmp(pfx, "Speaker"))
@@ -2453,7 +2484,7 @@ static int create_out_jack_modes(struct hda_codec *codec, int num_pins,
2453 } 2484 }
2454 if (get_out_jack_num_items(codec, pin) > 1) { 2485 if (get_out_jack_num_items(codec, pin) > 1) {
2455 struct snd_kcontrol_new *knew; 2486 struct snd_kcontrol_new *knew;
2456 char name[44]; 2487 char name[SNDRV_CTL_ELEM_ID_NAME_MAXLEN];
2457 get_jack_mode_name(codec, pin, name, sizeof(name)); 2488 get_jack_mode_name(codec, pin, name, sizeof(name));
2458 knew = snd_hda_gen_add_kctl(spec, name, 2489 knew = snd_hda_gen_add_kctl(spec, name,
2459 &out_jack_mode_enum); 2490 &out_jack_mode_enum);
@@ -2585,7 +2616,7 @@ static int create_in_jack_mode(struct hda_codec *codec, hda_nid_t pin)
2585{ 2616{
2586 struct hda_gen_spec *spec = codec->spec; 2617 struct hda_gen_spec *spec = codec->spec;
2587 struct snd_kcontrol_new *knew; 2618 struct snd_kcontrol_new *knew;
2588 char name[44]; 2619 char name[SNDRV_CTL_ELEM_ID_NAME_MAXLEN];
2589 unsigned int defcfg; 2620 unsigned int defcfg;
2590 2621
2591 if (pin == spec->hp_mic_pin) 2622 if (pin == spec->hp_mic_pin)
@@ -3285,7 +3316,7 @@ static int add_single_cap_ctl(struct hda_codec *codec, const char *label,
3285 bool inv_dmic) 3316 bool inv_dmic)
3286{ 3317{
3287 struct hda_gen_spec *spec = codec->spec; 3318 struct hda_gen_spec *spec = codec->spec;
3288 char tmpname[44]; 3319 char tmpname[SNDRV_CTL_ELEM_ID_NAME_MAXLEN];
3289 int type = is_switch ? HDA_CTL_WIDGET_MUTE : HDA_CTL_WIDGET_VOL; 3320 int type = is_switch ? HDA_CTL_WIDGET_MUTE : HDA_CTL_WIDGET_VOL;
3290 const char *sfx = is_switch ? "Switch" : "Volume"; 3321 const char *sfx = is_switch ? "Switch" : "Volume";
3291 unsigned int chs = inv_dmic ? 1 : 3; 3322 unsigned int chs = inv_dmic ? 1 : 3;
@@ -3547,7 +3578,7 @@ static int parse_mic_boost(struct hda_codec *codec)
3547 struct nid_path *path; 3578 struct nid_path *path;
3548 unsigned int val; 3579 unsigned int val;
3549 int idx; 3580 int idx;
3550 char boost_label[44]; 3581 char boost_label[SNDRV_CTL_ELEM_ID_NAME_MAXLEN];
3551 3582
3552 idx = imux->items[i].index; 3583 idx = imux->items[i].index;
3553 if (idx >= imux->num_items) 3584 if (idx >= imux->num_items)
@@ -3719,6 +3750,16 @@ static void do_automute(struct hda_codec *codec, int num_pins, hda_nid_t *pins,
3719 unsigned int val, oldval; 3750 unsigned int val, oldval;
3720 if (!nid) 3751 if (!nid)
3721 break; 3752 break;
3753
3754 if (spec->auto_mute_via_amp) {
3755 if (mute)
3756 spec->mute_bits |= (1ULL << nid);
3757 else
3758 spec->mute_bits &= ~(1ULL << nid);
3759 set_pin_eapd(codec, nid, !mute);
3760 continue;
3761 }
3762
3722 oldval = snd_hda_codec_get_pin_target(codec, nid); 3763 oldval = snd_hda_codec_get_pin_target(codec, nid);
3723 if (oldval & PIN_IN) 3764 if (oldval & PIN_IN)
3724 continue; /* no mute for inputs */ 3765 continue; /* no mute for inputs */
@@ -3786,6 +3827,10 @@ static void call_update_outputs(struct hda_codec *codec)
3786 spec->automute_hook(codec); 3827 spec->automute_hook(codec);
3787 else 3828 else
3788 snd_hda_gen_update_outputs(codec); 3829 snd_hda_gen_update_outputs(codec);
3830
3831 /* sync the whole vmaster slaves to reflect the new auto-mute status */
3832 if (spec->auto_mute_via_amp && !codec->bus->shutdown)
3833 snd_ctl_sync_vmaster(spec->vmaster_mute.sw_kctl, false);
3789} 3834}
3790 3835
3791/* standard HP-automute helper */ 3836/* standard HP-automute helper */
diff --git a/sound/pci/hda/hda_generic.h b/sound/pci/hda/hda_generic.h
index 76200314ee95..e199a852388b 100644
--- a/sound/pci/hda/hda_generic.h
+++ b/sound/pci/hda/hda_generic.h
@@ -209,6 +209,7 @@ struct hda_gen_spec {
209 unsigned int master_mute:1; /* master mute over all */ 209 unsigned int master_mute:1; /* master mute over all */
210 unsigned int keep_vref_in_automute:1; /* Don't clear VREF in automute */ 210 unsigned int keep_vref_in_automute:1; /* Don't clear VREF in automute */
211 unsigned int line_in_auto_switch:1; /* allow line-in auto switch */ 211 unsigned int line_in_auto_switch:1; /* allow line-in auto switch */
212 unsigned int auto_mute_via_amp:1; /* auto-mute via amp instead of pinctl */
212 213
213 /* parser behavior flags; set before snd_hda_gen_parse_auto_config() */ 214 /* parser behavior flags; set before snd_hda_gen_parse_auto_config() */
214 unsigned int suppress_auto_mute:1; /* suppress input jack auto mute */ 215 unsigned int suppress_auto_mute:1; /* suppress input jack auto mute */
@@ -237,6 +238,9 @@ struct hda_gen_spec {
237 unsigned int have_aamix_ctl:1; 238 unsigned int have_aamix_ctl:1;
238 unsigned int hp_mic_jack_modes:1; 239 unsigned int hp_mic_jack_modes:1;
239 240
241 /* additional mute flags (only effective with auto_mute_via_amp=1) */
242 u64 mute_bits;
243
240 /* badness tables for output path evaluations */ 244 /* badness tables for output path evaluations */
241 const struct badness_table *main_out_badness; 245 const struct badness_table *main_out_badness;
242 const struct badness_table *extra_out_badness; 246 const struct badness_table *extra_out_badness;
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c
index de18722c4873..f39de9055097 100644
--- a/sound/pci/hda/hda_intel.c
+++ b/sound/pci/hda/hda_intel.c
@@ -942,6 +942,9 @@ static unsigned int azx_rirb_get_response(struct hda_bus *bus,
942 } 942 }
943 } 943 }
944 944
945 if (!bus->no_response_fallback)
946 return -1;
947
945 if (!chip->polling_mode && chip->poll_count < 2) { 948 if (!chip->polling_mode && chip->poll_count < 2) {
946 snd_printdd(SFX "%s: azx_get_response timeout, " 949 snd_printdd(SFX "%s: azx_get_response timeout, "
947 "polling the codec once: last cmd=0x%08x\n", 950 "polling the codec once: last cmd=0x%08x\n",
@@ -1117,37 +1120,52 @@ static void azx_load_dsp_cleanup(struct hda_bus *bus,
1117 struct snd_dma_buffer *dmab); 1120 struct snd_dma_buffer *dmab);
1118#endif 1121#endif
1119 1122
1120/* reset codec link */ 1123/* enter link reset */
1121static int azx_reset(struct azx *chip, int full_reset) 1124static void azx_enter_link_reset(struct azx *chip)
1122{ 1125{
1123 unsigned long timeout; 1126 unsigned long timeout;
1124 1127
1125 if (!full_reset)
1126 goto __skip;
1127
1128 /* clear STATESTS */
1129 azx_writeb(chip, STATESTS, STATESTS_INT_MASK);
1130
1131 /* reset controller */ 1128 /* reset controller */
1132 azx_writel(chip, GCTL, azx_readl(chip, GCTL) & ~ICH6_GCTL_RESET); 1129 azx_writel(chip, GCTL, azx_readl(chip, GCTL) & ~ICH6_GCTL_RESET);
1133 1130
1134 timeout = jiffies + msecs_to_jiffies(100); 1131 timeout = jiffies + msecs_to_jiffies(100);
1135 while (azx_readb(chip, GCTL) && 1132 while ((azx_readb(chip, GCTL) & ICH6_GCTL_RESET) &&
1136 time_before(jiffies, timeout)) 1133 time_before(jiffies, timeout))
1137 usleep_range(500, 1000); 1134 usleep_range(500, 1000);
1135}
1138 1136
1139 /* delay for >= 100us for codec PLL to settle per spec 1137/* exit link reset */
1140 * Rev 0.9 section 5.5.1 1138static void azx_exit_link_reset(struct azx *chip)
1141 */ 1139{
1142 usleep_range(500, 1000); 1140 unsigned long timeout;
1143 1141
1144 /* Bring controller out of reset */
1145 azx_writeb(chip, GCTL, azx_readb(chip, GCTL) | ICH6_GCTL_RESET); 1142 azx_writeb(chip, GCTL, azx_readb(chip, GCTL) | ICH6_GCTL_RESET);
1146 1143
1147 timeout = jiffies + msecs_to_jiffies(100); 1144 timeout = jiffies + msecs_to_jiffies(100);
1148 while (!azx_readb(chip, GCTL) && 1145 while (!azx_readb(chip, GCTL) &&
1149 time_before(jiffies, timeout)) 1146 time_before(jiffies, timeout))
1150 usleep_range(500, 1000); 1147 usleep_range(500, 1000);
1148}
1149
1150/* reset codec link */
1151static int azx_reset(struct azx *chip, int full_reset)
1152{
1153 if (!full_reset)
1154 goto __skip;
1155
1156 /* clear STATESTS */
1157 azx_writeb(chip, STATESTS, STATESTS_INT_MASK);
1158
1159 /* reset controller */
1160 azx_enter_link_reset(chip);
1161
1162 /* delay for >= 100us for codec PLL to settle per spec
1163 * Rev 0.9 section 5.5.1
1164 */
1165 usleep_range(500, 1000);
1166
1167 /* Bring controller out of reset */
1168 azx_exit_link_reset(chip);
1151 1169
1152 /* Brent Chartrand said to wait >= 540us for codecs to initialize */ 1170 /* Brent Chartrand said to wait >= 540us for codecs to initialize */
1153 usleep_range(1000, 1200); 1171 usleep_range(1000, 1200);
@@ -2891,6 +2909,7 @@ static int azx_suspend(struct device *dev)
2891 if (chip->initialized) 2909 if (chip->initialized)
2892 snd_hda_suspend(chip->bus); 2910 snd_hda_suspend(chip->bus);
2893 azx_stop_chip(chip); 2911 azx_stop_chip(chip);
2912 azx_enter_link_reset(chip);
2894 if (chip->irq >= 0) { 2913 if (chip->irq >= 0) {
2895 free_irq(chip->irq, chip); 2914 free_irq(chip->irq, chip);
2896 chip->irq = -1; 2915 chip->irq = -1;
@@ -2943,6 +2962,7 @@ static int azx_runtime_suspend(struct device *dev)
2943 struct azx *chip = card->private_data; 2962 struct azx *chip = card->private_data;
2944 2963
2945 azx_stop_chip(chip); 2964 azx_stop_chip(chip);
2965 azx_enter_link_reset(chip);
2946 azx_clear_irq_pending(chip); 2966 azx_clear_irq_pending(chip);
2947 return 0; 2967 return 0;
2948} 2968}
@@ -3764,7 +3784,6 @@ static int azx_probe(struct pci_dev *pci,
3764 3784
3765out_free: 3785out_free:
3766 snd_card_free(card); 3786 snd_card_free(card);
3767 pci_set_drvdata(pci, NULL);
3768 return err; 3787 return err;
3769} 3788}
3770 3789
@@ -3834,7 +3853,6 @@ static void azx_remove(struct pci_dev *pci)
3834 3853
3835 if (card) 3854 if (card)
3836 snd_card_free(card); 3855 snd_card_free(card);
3837 pci_set_drvdata(pci, NULL);
3838} 3856}
3839 3857
3840/* PCI IDs */ 3858/* PCI IDs */
@@ -3878,6 +3896,9 @@ static DEFINE_PCI_DEVICE_TABLE(azx_ids) = {
3878 /* Oaktrail */ 3896 /* Oaktrail */
3879 { PCI_DEVICE(0x8086, 0x080a), 3897 { PCI_DEVICE(0x8086, 0x080a),
3880 .driver_data = AZX_DRIVER_SCH | AZX_DCAPS_INTEL_PCH_NOPM }, 3898 .driver_data = AZX_DRIVER_SCH | AZX_DCAPS_INTEL_PCH_NOPM },
3899 /* BayTrail */
3900 { PCI_DEVICE(0x8086, 0x0f04),
3901 .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_PCH_NOPM },
3881 /* ICH */ 3902 /* ICH */
3882 { PCI_DEVICE(0x8086, 0x2668), 3903 { PCI_DEVICE(0x8086, 0x2668),
3883 .driver_data = AZX_DRIVER_ICH | AZX_DCAPS_OLD_SSYNC | 3904 .driver_data = AZX_DRIVER_ICH | AZX_DCAPS_OLD_SSYNC |
diff --git a/sound/pci/hda/hda_jack.c b/sound/pci/hda/hda_jack.c
index 9e0a95288f46..3fd2973183e2 100644
--- a/sound/pci/hda/hda_jack.c
+++ b/sound/pci/hda/hda_jack.c
@@ -398,7 +398,7 @@ static int add_jack_kctl(struct hda_codec *codec, hda_nid_t nid,
398 const char *base_name) 398 const char *base_name)
399{ 399{
400 unsigned int def_conf, conn; 400 unsigned int def_conf, conn;
401 char name[44]; 401 char name[SNDRV_CTL_ELEM_ID_NAME_MAXLEN];
402 int idx, err; 402 int idx, err;
403 bool phantom_jack; 403 bool phantom_jack;
404 404
diff --git a/sound/pci/hda/hda_local.h b/sound/pci/hda/hda_local.h
index e0bf7534fa1f..2e7493ef8ee0 100644
--- a/sound/pci/hda/hda_local.h
+++ b/sound/pci/hda/hda_local.h
@@ -562,6 +562,14 @@ static inline unsigned int get_wcaps_channels(u32 wcaps)
562 return chans; 562 return chans;
563} 563}
564 564
565static inline void snd_hda_override_wcaps(struct hda_codec *codec,
566 hda_nid_t nid, u32 val)
567{
568 if (nid >= codec->start_nid &&
569 nid < codec->start_nid + codec->num_nodes)
570 codec->wcaps[nid - codec->start_nid] = val;
571}
572
565u32 query_amp_caps(struct hda_codec *codec, hda_nid_t nid, int direction); 573u32 query_amp_caps(struct hda_codec *codec, hda_nid_t nid, int direction);
566int snd_hda_override_amp_caps(struct hda_codec *codec, hda_nid_t nid, int dir, 574int snd_hda_override_amp_caps(struct hda_codec *codec, hda_nid_t nid, int dir,
567 unsigned int caps); 575 unsigned int caps);
@@ -667,7 +675,7 @@ snd_hda_check_power_state(struct hda_codec *codec, hda_nid_t nid,
667 if (state & AC_PWRST_ERROR) 675 if (state & AC_PWRST_ERROR)
668 return true; 676 return true;
669 state = (state >> 4) & 0x0f; 677 state = (state >> 4) & 0x0f;
670 return (state != target_state); 678 return (state == target_state);
671} 679}
672 680
673unsigned int snd_hda_codec_eapd_power_filter(struct hda_codec *codec, 681unsigned int snd_hda_codec_eapd_power_filter(struct hda_codec *codec,
diff --git a/sound/pci/hda/hda_proc.c b/sound/pci/hda/hda_proc.c
index 0fee8fae590a..9760f001916d 100644
--- a/sound/pci/hda/hda_proc.c
+++ b/sound/pci/hda/hda_proc.c
@@ -504,6 +504,8 @@ static void print_conn_list(struct snd_info_buffer *buffer,
504 int conn_len) 504 int conn_len)
505{ 505{
506 int c, curr = -1; 506 int c, curr = -1;
507 const hda_nid_t *list;
508 int cache_len;
507 509
508 if (conn_len > 1 && 510 if (conn_len > 1 &&
509 wid_type != AC_WID_AUD_MIX && 511 wid_type != AC_WID_AUD_MIX &&
@@ -521,6 +523,19 @@ static void print_conn_list(struct snd_info_buffer *buffer,
521 } 523 }
522 snd_iprintf(buffer, "\n"); 524 snd_iprintf(buffer, "\n");
523 } 525 }
526
527 /* Get Cache connections info */
528 cache_len = snd_hda_get_conn_list(codec, nid, &list);
529 if (cache_len != conn_len
530 || memcmp(list, conn, conn_len)) {
531 snd_iprintf(buffer, " In-driver Connection: %d\n", cache_len);
532 if (cache_len > 0) {
533 snd_iprintf(buffer, " ");
534 for (c = 0; c < cache_len; c++)
535 snd_iprintf(buffer, " 0x%02x", list[c]);
536 snd_iprintf(buffer, "\n");
537 }
538 }
524} 539}
525 540
526static void print_gpio(struct snd_info_buffer *buffer, 541static void print_gpio(struct snd_info_buffer *buffer,
diff --git a/sound/pci/hda/patch_ca0132.c b/sound/pci/hda/patch_ca0132.c
index 90ff7a3f72df..6e9876f27d95 100644
--- a/sound/pci/hda/patch_ca0132.c
+++ b/sound/pci/hda/patch_ca0132.c
@@ -139,7 +139,7 @@ enum {
139#define DSP_SPEAKER_OUT_LATENCY 7 139#define DSP_SPEAKER_OUT_LATENCY 7
140 140
141struct ct_effect { 141struct ct_effect {
142 char name[44]; 142 char name[SNDRV_CTL_ELEM_ID_NAME_MAXLEN];
143 hda_nid_t nid; 143 hda_nid_t nid;
144 int mid; /*effect module ID*/ 144 int mid; /*effect module ID*/
145 int reqs[EFFECT_VALS_MAX_COUNT]; /*effect module request*/ 145 int reqs[EFFECT_VALS_MAX_COUNT]; /*effect module request*/
@@ -270,7 +270,7 @@ enum {
270}; 270};
271 271
272struct ct_tuning_ctl { 272struct ct_tuning_ctl {
273 char name[44]; 273 char name[SNDRV_CTL_ELEM_ID_NAME_MAXLEN];
274 hda_nid_t parent_nid; 274 hda_nid_t parent_nid;
275 hda_nid_t nid; 275 hda_nid_t nid;
276 int mid; /*effect module ID*/ 276 int mid; /*effect module ID*/
@@ -3103,7 +3103,7 @@ static int add_tuning_control(struct hda_codec *codec,
3103 hda_nid_t pnid, hda_nid_t nid, 3103 hda_nid_t pnid, hda_nid_t nid,
3104 const char *name, int dir) 3104 const char *name, int dir)
3105{ 3105{
3106 char namestr[44]; 3106 char namestr[SNDRV_CTL_ELEM_ID_NAME_MAXLEN];
3107 int type = dir ? HDA_INPUT : HDA_OUTPUT; 3107 int type = dir ? HDA_INPUT : HDA_OUTPUT;
3108 struct snd_kcontrol_new knew = 3108 struct snd_kcontrol_new knew =
3109 HDA_CODEC_VOLUME_MONO(namestr, nid, 1, 0, type); 3109 HDA_CODEC_VOLUME_MONO(namestr, nid, 1, 0, type);
@@ -3935,7 +3935,7 @@ static int ca0132_volume_tlv(struct snd_kcontrol *kcontrol, int op_flag,
3935static int add_fx_switch(struct hda_codec *codec, hda_nid_t nid, 3935static int add_fx_switch(struct hda_codec *codec, hda_nid_t nid,
3936 const char *pfx, int dir) 3936 const char *pfx, int dir)
3937{ 3937{
3938 char namestr[44]; 3938 char namestr[SNDRV_CTL_ELEM_ID_NAME_MAXLEN];
3939 int type = dir ? HDA_INPUT : HDA_OUTPUT; 3939 int type = dir ? HDA_INPUT : HDA_OUTPUT;
3940 struct snd_kcontrol_new knew = 3940 struct snd_kcontrol_new knew =
3941 CA0132_CODEC_MUTE_MONO(namestr, nid, 1, type); 3941 CA0132_CODEC_MUTE_MONO(namestr, nid, 1, type);
diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c
index b314d3e6d7fa..de00ce166470 100644
--- a/sound/pci/hda/patch_conexant.c
+++ b/sound/pci/hda/patch_conexant.c
@@ -2947,7 +2947,6 @@ static const struct snd_pci_quirk cxt5066_cfg_tbl[] = {
2947 SND_PCI_QUIRK(0x17aa, 0x20f2, "Lenovo T400s", CXT5066_THINKPAD), 2947 SND_PCI_QUIRK(0x17aa, 0x20f2, "Lenovo T400s", CXT5066_THINKPAD),
2948 SND_PCI_QUIRK(0x17aa, 0x21c5, "Thinkpad Edge 13", CXT5066_THINKPAD), 2948 SND_PCI_QUIRK(0x17aa, 0x21c5, "Thinkpad Edge 13", CXT5066_THINKPAD),
2949 SND_PCI_QUIRK(0x17aa, 0x21c6, "Thinkpad Edge 13", CXT5066_ASUS), 2949 SND_PCI_QUIRK(0x17aa, 0x21c6, "Thinkpad Edge 13", CXT5066_ASUS),
2950 SND_PCI_QUIRK(0x17aa, 0x21db, "Lenovo X220-tablet", CXT5066_THINKPAD),
2951 SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo U350", CXT5066_ASUS), 2950 SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo U350", CXT5066_ASUS),
2952 SND_PCI_QUIRK(0x17aa, 0x38af, "Lenovo G560", CXT5066_ASUS), 2951 SND_PCI_QUIRK(0x17aa, 0x38af, "Lenovo G560", CXT5066_ASUS),
2953 {} 2952 {}
@@ -3318,6 +3317,7 @@ static const struct snd_pci_quirk cxt5066_fixups[] = {
3318 SND_PCI_QUIRK(0x17aa, 0x21ce, "Lenovo T420", CXT_PINCFG_LENOVO_TP410), 3317 SND_PCI_QUIRK(0x17aa, 0x21ce, "Lenovo T420", CXT_PINCFG_LENOVO_TP410),
3319 SND_PCI_QUIRK(0x17aa, 0x21cf, "Lenovo T520", CXT_PINCFG_LENOVO_TP410), 3318 SND_PCI_QUIRK(0x17aa, 0x21cf, "Lenovo T520", CXT_PINCFG_LENOVO_TP410),
3320 SND_PCI_QUIRK(0x17aa, 0x21da, "Lenovo X220", CXT_PINCFG_LENOVO_TP410), 3319 SND_PCI_QUIRK(0x17aa, 0x21da, "Lenovo X220", CXT_PINCFG_LENOVO_TP410),
3320 SND_PCI_QUIRK(0x17aa, 0x21db, "Lenovo X220-tablet", CXT_PINCFG_LENOVO_TP410),
3321 SND_PCI_QUIRK(0x17aa, 0x3975, "Lenovo U300s", CXT_FIXUP_STEREO_DMIC), 3321 SND_PCI_QUIRK(0x17aa, 0x3975, "Lenovo U300s", CXT_FIXUP_STEREO_DMIC),
3322 SND_PCI_QUIRK(0x17aa, 0x3977, "Lenovo IdeaPad U310", CXT_FIXUP_STEREO_DMIC), 3322 SND_PCI_QUIRK(0x17aa, 0x3977, "Lenovo IdeaPad U310", CXT_FIXUP_STEREO_DMIC),
3323 SND_PCI_QUIRK(0x17aa, 0x397b, "Lenovo S205", CXT_FIXUP_STEREO_DMIC), 3323 SND_PCI_QUIRK(0x17aa, 0x397b, "Lenovo S205", CXT_FIXUP_STEREO_DMIC),
diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c
index e12f7a030c58..540bdef2f904 100644
--- a/sound/pci/hda/patch_hdmi.c
+++ b/sound/pci/hda/patch_hdmi.c
@@ -1018,13 +1018,18 @@ static void hdmi_unsol_event(struct hda_codec *codec, unsigned int res)
1018 hdmi_non_intrinsic_event(codec, res); 1018 hdmi_non_intrinsic_event(codec, res);
1019} 1019}
1020 1020
1021static void haswell_verify_pin_D0(struct hda_codec *codec, hda_nid_t nid) 1021static void haswell_verify_pin_D0(struct hda_codec *codec,
1022 hda_nid_t cvt_nid, hda_nid_t nid)
1022{ 1023{
1023 int pwr, lamp, ramp; 1024 int pwr, lamp, ramp;
1024 1025
1025 pwr = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_POWER_STATE, 0); 1026 /* For Haswell, the converter 1/2 may keep in D3 state after bootup,
1026 pwr = (pwr & AC_PWRST_ACTUAL) >> AC_PWRST_ACTUAL_SHIFT; 1027 * thus pins could only choose converter 0 for use. Make sure the
1027 if (pwr != AC_PWRST_D0) { 1028 * converters are in correct power state */
1029 if (!snd_hda_check_power_state(codec, cvt_nid, AC_PWRST_D0))
1030 snd_hda_codec_write(codec, cvt_nid, 0, AC_VERB_SET_POWER_STATE, AC_PWRST_D0);
1031
1032 if (!snd_hda_check_power_state(codec, nid, AC_PWRST_D0)) {
1028 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_POWER_STATE, 1033 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_POWER_STATE,
1029 AC_PWRST_D0); 1034 AC_PWRST_D0);
1030 msleep(40); 1035 msleep(40);
@@ -1068,7 +1073,7 @@ static int hdmi_setup_stream(struct hda_codec *codec, hda_nid_t cvt_nid,
1068 int new_pinctl = 0; 1073 int new_pinctl = 0;
1069 1074
1070 if (codec->vendor_id == 0x80862807) 1075 if (codec->vendor_id == 0x80862807)
1071 haswell_verify_pin_D0(codec, pin_nid); 1076 haswell_verify_pin_D0(codec, cvt_nid, pin_nid);
1072 1077
1073 if (snd_hda_query_pin_caps(codec, pin_nid) & AC_PINCAP_HBR) { 1078 if (snd_hda_query_pin_caps(codec, pin_nid) & AC_PINCAP_HBR) {
1074 pinctl = snd_hda_codec_read(codec, pin_nid, 0, 1079 pinctl = snd_hda_codec_read(codec, pin_nid, 0,
@@ -1101,26 +1106,15 @@ static int hdmi_setup_stream(struct hda_codec *codec, hda_nid_t cvt_nid,
1101 return 0; 1106 return 0;
1102} 1107}
1103 1108
1104/* 1109static int hdmi_choose_cvt(struct hda_codec *codec,
1105 * HDA PCM callbacks 1110 int pin_idx, int *cvt_id, int *mux_id)
1106 */
1107static int hdmi_pcm_open(struct hda_pcm_stream *hinfo,
1108 struct hda_codec *codec,
1109 struct snd_pcm_substream *substream)
1110{ 1111{
1111 struct hdmi_spec *spec = codec->spec; 1112 struct hdmi_spec *spec = codec->spec;
1112 struct snd_pcm_runtime *runtime = substream->runtime;
1113 int pin_idx, cvt_idx, mux_idx = 0;
1114 struct hdmi_spec_per_pin *per_pin; 1113 struct hdmi_spec_per_pin *per_pin;
1115 struct hdmi_eld *eld;
1116 struct hdmi_spec_per_cvt *per_cvt = NULL; 1114 struct hdmi_spec_per_cvt *per_cvt = NULL;
1115 int cvt_idx, mux_idx = 0;
1117 1116
1118 /* Validate hinfo */
1119 pin_idx = hinfo_to_pin_index(spec, hinfo);
1120 if (snd_BUG_ON(pin_idx < 0))
1121 return -EINVAL;
1122 per_pin = get_pin(spec, pin_idx); 1117 per_pin = get_pin(spec, pin_idx);
1123 eld = &per_pin->sink_eld;
1124 1118
1125 /* Dynamically assign converter to stream */ 1119 /* Dynamically assign converter to stream */
1126 for (cvt_idx = 0; cvt_idx < spec->num_cvts; cvt_idx++) { 1120 for (cvt_idx = 0; cvt_idx < spec->num_cvts; cvt_idx++) {
@@ -1138,17 +1132,89 @@ static int hdmi_pcm_open(struct hda_pcm_stream *hinfo,
1138 continue; 1132 continue;
1139 break; 1133 break;
1140 } 1134 }
1135
1141 /* No free converters */ 1136 /* No free converters */
1142 if (cvt_idx == spec->num_cvts) 1137 if (cvt_idx == spec->num_cvts)
1143 return -ENODEV; 1138 return -ENODEV;
1144 1139
1140 if (cvt_id)
1141 *cvt_id = cvt_idx;
1142 if (mux_id)
1143 *mux_id = mux_idx;
1144
1145 return 0;
1146}
1147
1148static void haswell_config_cvts(struct hda_codec *codec,
1149 int pin_id, int mux_id)
1150{
1151 struct hdmi_spec *spec = codec->spec;
1152 struct hdmi_spec_per_pin *per_pin;
1153 int pin_idx, mux_idx;
1154 int curr;
1155 int err;
1156
1157 for (pin_idx = 0; pin_idx < spec->num_pins; pin_idx++) {
1158 per_pin = get_pin(spec, pin_idx);
1159
1160 if (pin_idx == pin_id)
1161 continue;
1162
1163 curr = snd_hda_codec_read(codec, per_pin->pin_nid, 0,
1164 AC_VERB_GET_CONNECT_SEL, 0);
1165
1166 /* Choose another unused converter */
1167 if (curr == mux_id) {
1168 err = hdmi_choose_cvt(codec, pin_idx, NULL, &mux_idx);
1169 if (err < 0)
1170 return;
1171 snd_printdd("HDMI: choose converter %d for pin %d\n", mux_idx, pin_idx);
1172 snd_hda_codec_write_cache(codec, per_pin->pin_nid, 0,
1173 AC_VERB_SET_CONNECT_SEL,
1174 mux_idx);
1175 }
1176 }
1177}
1178
1179/*
1180 * HDA PCM callbacks
1181 */
1182static int hdmi_pcm_open(struct hda_pcm_stream *hinfo,
1183 struct hda_codec *codec,
1184 struct snd_pcm_substream *substream)
1185{
1186 struct hdmi_spec *spec = codec->spec;
1187 struct snd_pcm_runtime *runtime = substream->runtime;
1188 int pin_idx, cvt_idx, mux_idx = 0;
1189 struct hdmi_spec_per_pin *per_pin;
1190 struct hdmi_eld *eld;
1191 struct hdmi_spec_per_cvt *per_cvt = NULL;
1192 int err;
1193
1194 /* Validate hinfo */
1195 pin_idx = hinfo_to_pin_index(spec, hinfo);
1196 if (snd_BUG_ON(pin_idx < 0))
1197 return -EINVAL;
1198 per_pin = get_pin(spec, pin_idx);
1199 eld = &per_pin->sink_eld;
1200
1201 err = hdmi_choose_cvt(codec, pin_idx, &cvt_idx, &mux_idx);
1202 if (err < 0)
1203 return err;
1204
1205 per_cvt = get_cvt(spec, cvt_idx);
1145 /* Claim converter */ 1206 /* Claim converter */
1146 per_cvt->assigned = 1; 1207 per_cvt->assigned = 1;
1147 hinfo->nid = per_cvt->cvt_nid; 1208 hinfo->nid = per_cvt->cvt_nid;
1148 1209
1149 snd_hda_codec_write(codec, per_pin->pin_nid, 0, 1210 snd_hda_codec_write_cache(codec, per_pin->pin_nid, 0,
1150 AC_VERB_SET_CONNECT_SEL, 1211 AC_VERB_SET_CONNECT_SEL,
1151 mux_idx); 1212 mux_idx);
1213
1214 /* configure unused pins to choose other converters */
1215 if (codec->vendor_id == 0x80862807)
1216 haswell_config_cvts(codec, pin_idx, mux_idx);
1217
1152 snd_hda_spdif_ctls_assign(codec, pin_idx, per_cvt->cvt_nid); 1218 snd_hda_spdif_ctls_assign(codec, pin_idx, per_cvt->cvt_nid);
1153 1219
1154 /* Initially set the converter's capabilities */ 1220 /* Initially set the converter's capabilities */
@@ -1798,12 +1864,33 @@ static void generic_hdmi_free(struct hda_codec *codec)
1798 kfree(spec); 1864 kfree(spec);
1799} 1865}
1800 1866
1867#ifdef CONFIG_PM
1868static int generic_hdmi_resume(struct hda_codec *codec)
1869{
1870 struct hdmi_spec *spec = codec->spec;
1871 int pin_idx;
1872
1873 generic_hdmi_init(codec);
1874 snd_hda_codec_resume_amp(codec);
1875 snd_hda_codec_resume_cache(codec);
1876
1877 for (pin_idx = 0; pin_idx < spec->num_pins; pin_idx++) {
1878 struct hdmi_spec_per_pin *per_pin = get_pin(spec, pin_idx);
1879 hdmi_present_sense(per_pin, 1);
1880 }
1881 return 0;
1882}
1883#endif
1884
1801static const struct hda_codec_ops generic_hdmi_patch_ops = { 1885static const struct hda_codec_ops generic_hdmi_patch_ops = {
1802 .init = generic_hdmi_init, 1886 .init = generic_hdmi_init,
1803 .free = generic_hdmi_free, 1887 .free = generic_hdmi_free,
1804 .build_pcms = generic_hdmi_build_pcms, 1888 .build_pcms = generic_hdmi_build_pcms,
1805 .build_controls = generic_hdmi_build_controls, 1889 .build_controls = generic_hdmi_build_controls,
1806 .unsol_event = hdmi_unsol_event, 1890 .unsol_event = hdmi_unsol_event,
1891#ifdef CONFIG_PM
1892 .resume = generic_hdmi_resume,
1893#endif
1807}; 1894};
1808 1895
1809 1896
@@ -1821,7 +1908,6 @@ static void intel_haswell_fixup_connect_list(struct hda_codec *codec,
1821 1908
1822 /* override pins connection list */ 1909 /* override pins connection list */
1823 snd_printdd("hdmi: haswell: override pin connection 0x%x\n", nid); 1910 snd_printdd("hdmi: haswell: override pin connection 0x%x\n", nid);
1824 nconns = max(spec->num_cvts, 4);
1825 snd_hda_override_conn_list(codec, nid, spec->num_cvts, spec->cvt_nids); 1911 snd_hda_override_conn_list(codec, nid, spec->num_cvts, spec->cvt_nids);
1826} 1912}
1827 1913
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index 403010c9e82e..14ac9b0e740c 100644
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -115,6 +115,7 @@ struct alc_spec {
115 115
116 int init_amp; 116 int init_amp;
117 int codec_variant; /* flag for other variants */ 117 int codec_variant; /* flag for other variants */
118 bool has_alc5505_dsp;
118 119
119 /* for PLL fix */ 120 /* for PLL fix */
120 hda_nid_t pll_nid; 121 hda_nid_t pll_nid;
@@ -2580,7 +2581,96 @@ static void alc269_shutup(struct hda_codec *codec)
2580 } 2581 }
2581} 2582}
2582 2583
2584static void alc5505_coef_set(struct hda_codec *codec, unsigned int index_reg,
2585 unsigned int val)
2586{
2587 snd_hda_codec_write(codec, 0x51, 0, AC_VERB_SET_COEF_INDEX, index_reg >> 1);
2588 snd_hda_codec_write(codec, 0x51, 0, AC_VERB_SET_PROC_COEF, val & 0xffff); /* LSB */
2589 snd_hda_codec_write(codec, 0x51, 0, AC_VERB_SET_PROC_COEF, val >> 16); /* MSB */
2590}
2591
2592static int alc5505_coef_get(struct hda_codec *codec, unsigned int index_reg)
2593{
2594 unsigned int val;
2595
2596 snd_hda_codec_write(codec, 0x51, 0, AC_VERB_SET_COEF_INDEX, index_reg >> 1);
2597 val = snd_hda_codec_read(codec, 0x51, 0, AC_VERB_GET_PROC_COEF, 0)
2598 & 0xffff;
2599 val |= snd_hda_codec_read(codec, 0x51, 0, AC_VERB_GET_PROC_COEF, 0)
2600 << 16;
2601 return val;
2602}
2603
2604static void alc5505_dsp_halt(struct hda_codec *codec)
2605{
2606 unsigned int val;
2607
2608 alc5505_coef_set(codec, 0x3000, 0x000c); /* DSP CPU stop */
2609 alc5505_coef_set(codec, 0x880c, 0x0008); /* DDR enter self refresh */
2610 alc5505_coef_set(codec, 0x61c0, 0x11110080); /* Clock control for PLL and CPU */
2611 alc5505_coef_set(codec, 0x6230, 0xfc0d4011); /* Disable Input OP */
2612 alc5505_coef_set(codec, 0x61b4, 0x040a2b03); /* Stop PLL2 */
2613 alc5505_coef_set(codec, 0x61b0, 0x00005b17); /* Stop PLL1 */
2614 alc5505_coef_set(codec, 0x61b8, 0x04133303); /* Stop PLL3 */
2615 val = alc5505_coef_get(codec, 0x6220);
2616 alc5505_coef_set(codec, 0x6220, (val | 0x3000)); /* switch Ringbuffer clock to DBUS clock */
2617}
2618
2619static void alc5505_dsp_back_from_halt(struct hda_codec *codec)
2620{
2621 alc5505_coef_set(codec, 0x61b8, 0x04133302);
2622 alc5505_coef_set(codec, 0x61b0, 0x00005b16);
2623 alc5505_coef_set(codec, 0x61b4, 0x040a2b02);
2624 alc5505_coef_set(codec, 0x6230, 0xf80d4011);
2625 alc5505_coef_set(codec, 0x6220, 0x2002010f);
2626 alc5505_coef_set(codec, 0x880c, 0x00000004);
2627}
2628
2629static void alc5505_dsp_init(struct hda_codec *codec)
2630{
2631 unsigned int val;
2632
2633 alc5505_dsp_halt(codec);
2634 alc5505_dsp_back_from_halt(codec);
2635 alc5505_coef_set(codec, 0x61b0, 0x5b14); /* PLL1 control */
2636 alc5505_coef_set(codec, 0x61b0, 0x5b16);
2637 alc5505_coef_set(codec, 0x61b4, 0x04132b00); /* PLL2 control */
2638 alc5505_coef_set(codec, 0x61b4, 0x04132b02);
2639 alc5505_coef_set(codec, 0x61b8, 0x041f3300); /* PLL3 control*/
2640 alc5505_coef_set(codec, 0x61b8, 0x041f3302);
2641 snd_hda_codec_write(codec, 0x51, 0, AC_VERB_SET_CODEC_RESET, 0); /* Function reset */
2642 alc5505_coef_set(codec, 0x61b8, 0x041b3302);
2643 alc5505_coef_set(codec, 0x61b8, 0x04173302);
2644 alc5505_coef_set(codec, 0x61b8, 0x04163302);
2645 alc5505_coef_set(codec, 0x8800, 0x348b328b); /* DRAM control */
2646 alc5505_coef_set(codec, 0x8808, 0x00020022); /* DRAM control */
2647 alc5505_coef_set(codec, 0x8818, 0x00000400); /* DRAM control */
2648
2649 val = alc5505_coef_get(codec, 0x6200) >> 16; /* Read revision ID */
2650 if (val <= 3)
2651 alc5505_coef_set(codec, 0x6220, 0x2002010f); /* I/O PAD Configuration */
2652 else
2653 alc5505_coef_set(codec, 0x6220, 0x6002018f);
2654
2655 alc5505_coef_set(codec, 0x61ac, 0x055525f0); /**/
2656 alc5505_coef_set(codec, 0x61c0, 0x12230080); /* Clock control */
2657 alc5505_coef_set(codec, 0x61b4, 0x040e2b02); /* PLL2 control */
2658 alc5505_coef_set(codec, 0x61bc, 0x010234f8); /* OSC Control */
2659 alc5505_coef_set(codec, 0x880c, 0x00000004); /* DRAM Function control */
2660 alc5505_coef_set(codec, 0x880c, 0x00000003);
2661 alc5505_coef_set(codec, 0x880c, 0x00000010);
2662}
2663
2583#ifdef CONFIG_PM 2664#ifdef CONFIG_PM
2665static int alc269_suspend(struct hda_codec *codec)
2666{
2667 struct alc_spec *spec = codec->spec;
2668
2669 if (spec->has_alc5505_dsp)
2670 alc5505_dsp_halt(codec);
2671 return alc_suspend(codec);
2672}
2673
2584static int alc269_resume(struct hda_codec *codec) 2674static int alc269_resume(struct hda_codec *codec)
2585{ 2675{
2586 struct alc_spec *spec = codec->spec; 2676 struct alc_spec *spec = codec->spec;
@@ -2603,7 +2693,10 @@ static int alc269_resume(struct hda_codec *codec)
2603 2693
2604 snd_hda_codec_resume_amp(codec); 2694 snd_hda_codec_resume_amp(codec);
2605 snd_hda_codec_resume_cache(codec); 2695 snd_hda_codec_resume_cache(codec);
2696 alc_inv_dmic_sync(codec, true);
2606 hda_call_check_power_status(codec, 0x01); 2697 hda_call_check_power_status(codec, 0x01);
2698 if (spec->has_alc5505_dsp)
2699 alc5505_dsp_back_from_halt(codec);
2607 return 0; 2700 return 0;
2608} 2701}
2609#endif /* CONFIG_PM */ 2702#endif /* CONFIG_PM */
@@ -3225,6 +3318,7 @@ enum {
3225 ALC271_FIXUP_HP_GATE_MIC_JACK, 3318 ALC271_FIXUP_HP_GATE_MIC_JACK,
3226 ALC269_FIXUP_ACER_AC700, 3319 ALC269_FIXUP_ACER_AC700,
3227 ALC269_FIXUP_LIMIT_INT_MIC_BOOST, 3320 ALC269_FIXUP_LIMIT_INT_MIC_BOOST,
3321 ALC269VB_FIXUP_ORDISSIMO_EVE2,
3228}; 3322};
3229 3323
3230static const struct hda_fixup alc269_fixups[] = { 3324static const struct hda_fixup alc269_fixups[] = {
@@ -3467,6 +3561,15 @@ static const struct hda_fixup alc269_fixups[] = {
3467 .type = HDA_FIXUP_FUNC, 3561 .type = HDA_FIXUP_FUNC,
3468 .v.func = alc269_fixup_limit_int_mic_boost, 3562 .v.func = alc269_fixup_limit_int_mic_boost,
3469 }, 3563 },
3564 [ALC269VB_FIXUP_ORDISSIMO_EVE2] = {
3565 .type = HDA_FIXUP_PINS,
3566 .v.pins = (const struct hda_pintbl[]) {
3567 { 0x12, 0x99a3092f }, /* int-mic */
3568 { 0x18, 0x03a11d20 }, /* mic */
3569 { 0x19, 0x411111f0 }, /* Unused bogus pin */
3570 { }
3571 },
3572 },
3470}; 3573};
3471 3574
3472static const struct snd_pci_quirk alc269_fixup_tbl[] = { 3575static const struct snd_pci_quirk alc269_fixup_tbl[] = {
@@ -3482,6 +3585,8 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
3482 SND_PCI_QUIRK(0x1028, 0x05c9, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), 3585 SND_PCI_QUIRK(0x1028, 0x05c9, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE),
3483 SND_PCI_QUIRK(0x1028, 0x05ca, "Dell", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE), 3586 SND_PCI_QUIRK(0x1028, 0x05ca, "Dell", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE),
3484 SND_PCI_QUIRK(0x1028, 0x05cb, "Dell", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE), 3587 SND_PCI_QUIRK(0x1028, 0x05cb, "Dell", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE),
3588 SND_PCI_QUIRK(0x1028, 0x05cc, "Dell X5 Precision", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE),
3589 SND_PCI_QUIRK(0x1028, 0x05cd, "Dell X5 Precision", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE),
3485 SND_PCI_QUIRK(0x1028, 0x05de, "Dell", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE), 3590 SND_PCI_QUIRK(0x1028, 0x05de, "Dell", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE),
3486 SND_PCI_QUIRK(0x1028, 0x05e0, "Dell", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE), 3591 SND_PCI_QUIRK(0x1028, 0x05e0, "Dell", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE),
3487 SND_PCI_QUIRK(0x1028, 0x05e9, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), 3592 SND_PCI_QUIRK(0x1028, 0x05e9, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE),
@@ -3495,9 +3600,14 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
3495 SND_PCI_QUIRK(0x1028, 0x05f5, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), 3600 SND_PCI_QUIRK(0x1028, 0x05f5, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE),
3496 SND_PCI_QUIRK(0x1028, 0x05f6, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), 3601 SND_PCI_QUIRK(0x1028, 0x05f6, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE),
3497 SND_PCI_QUIRK(0x1028, 0x05f8, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), 3602 SND_PCI_QUIRK(0x1028, 0x05f8, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE),
3603 SND_PCI_QUIRK(0x1028, 0x05f9, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE),
3604 SND_PCI_QUIRK(0x1028, 0x05fb, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE),
3498 SND_PCI_QUIRK(0x1028, 0x0606, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), 3605 SND_PCI_QUIRK(0x1028, 0x0606, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE),
3499 SND_PCI_QUIRK(0x1028, 0x0608, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), 3606 SND_PCI_QUIRK(0x1028, 0x0608, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE),
3500 SND_PCI_QUIRK(0x1028, 0x0609, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), 3607 SND_PCI_QUIRK(0x1028, 0x0609, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE),
3608 SND_PCI_QUIRK(0x1028, 0x0613, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE),
3609 SND_PCI_QUIRK(0x1028, 0x15cc, "Dell X5 Precision", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE),
3610 SND_PCI_QUIRK(0x1028, 0x15cd, "Dell X5 Precision", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE),
3501 SND_PCI_QUIRK(0x103c, 0x1586, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC2), 3611 SND_PCI_QUIRK(0x103c, 0x1586, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC2),
3502 SND_PCI_QUIRK(0x103c, 0x18e6, "HP", ALC269_FIXUP_HP_GPIO_LED), 3612 SND_PCI_QUIRK(0x103c, 0x18e6, "HP", ALC269_FIXUP_HP_GPIO_LED),
3503 SND_PCI_QUIRK(0x103c, 0x1973, "HP Pavilion", ALC269_FIXUP_HP_MUTE_LED_MIC1), 3613 SND_PCI_QUIRK(0x103c, 0x1973, "HP Pavilion", ALC269_FIXUP_HP_MUTE_LED_MIC1),
@@ -3539,6 +3649,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
3539 SND_PCI_QUIRK(0x17aa, 0x2203, "Thinkpad X230 Tablet", ALC269_FIXUP_LENOVO_DOCK), 3649 SND_PCI_QUIRK(0x17aa, 0x2203, "Thinkpad X230 Tablet", ALC269_FIXUP_LENOVO_DOCK),
3540 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_FIXUP_PCM_44K), 3650 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_FIXUP_PCM_44K),
3541 SND_PCI_QUIRK(0x17aa, 0x9e54, "LENOVO NB", ALC269_FIXUP_LENOVO_EAPD), 3651 SND_PCI_QUIRK(0x17aa, 0x9e54, "LENOVO NB", ALC269_FIXUP_LENOVO_EAPD),
3652 SND_PCI_QUIRK(0x1b7d, 0xa831, "Ordissimo EVE2 ", ALC269VB_FIXUP_ORDISSIMO_EVE2), /* Also known as Malata PC-B1303 */
3542 3653
3543#if 0 3654#if 0
3544 /* Below is a quirk table taken from the old code. 3655 /* Below is a quirk table taken from the old code.
@@ -3718,6 +3829,11 @@ static int patch_alc269(struct hda_codec *codec)
3718 break; 3829 break;
3719 } 3830 }
3720 3831
3832 if (snd_hda_codec_read(codec, 0x51, 0, AC_VERB_PARAMETERS, 0) == 0x10ec5505) {
3833 spec->has_alc5505_dsp = true;
3834 spec->init_hook = alc5505_dsp_init;
3835 }
3836
3721 /* automatic parse from the BIOS config */ 3837 /* automatic parse from the BIOS config */
3722 err = alc269_parse_auto_config(codec); 3838 err = alc269_parse_auto_config(codec);
3723 if (err < 0) 3839 if (err < 0)
@@ -3728,6 +3844,7 @@ static int patch_alc269(struct hda_codec *codec)
3728 3844
3729 codec->patch_ops = alc_patch_ops; 3845 codec->patch_ops = alc_patch_ops;
3730#ifdef CONFIG_PM 3846#ifdef CONFIG_PM
3847 codec->patch_ops.suspend = alc269_suspend;
3731 codec->patch_ops.resume = alc269_resume; 3848 codec->patch_ops.resume = alc269_resume;
3732#endif 3849#endif
3733 spec->shutup = alc269_shutup; 3850 spec->shutup = alc269_shutup;
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c
index 1d9d6427e0bf..e2f83591161b 100644
--- a/sound/pci/hda/patch_sigmatel.c
+++ b/sound/pci/hda/patch_sigmatel.c
@@ -2233,6 +2233,10 @@ static const struct snd_pci_quirk stac92hd83xxx_fixup_tbl[] = {
2233 "HP Folio", STAC_92HD83XXX_HP_MIC_LED), 2233 "HP Folio", STAC_92HD83XXX_HP_MIC_LED),
2234 SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_HP, 0xff00, 0x1900, 2234 SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_HP, 0xff00, 0x1900,
2235 "HP", STAC_92HD83XXX_HP_MIC_LED), 2235 "HP", STAC_92HD83XXX_HP_MIC_LED),
2236 SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_HP, 0xff00, 0x2000,
2237 "HP", STAC_92HD83XXX_HP_MIC_LED),
2238 SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_HP, 0xff00, 0x2100,
2239 "HP", STAC_92HD83XXX_HP_MIC_LED),
2236 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x3388, 2240 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x3388,
2237 "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD), 2241 "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
2238 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x3389, 2242 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x3389,
@@ -3707,14 +3711,6 @@ static void stac927x_proc_hook(struct snd_info_buffer *buffer,
3707#endif 3711#endif
3708 3712
3709#ifdef CONFIG_PM 3713#ifdef CONFIG_PM
3710static int stac_resume(struct hda_codec *codec)
3711{
3712 codec->patch_ops.init(codec);
3713 snd_hda_codec_resume_amp(codec);
3714 snd_hda_codec_resume_cache(codec);
3715 return 0;
3716}
3717
3718static int stac_suspend(struct hda_codec *codec) 3714static int stac_suspend(struct hda_codec *codec)
3719{ 3715{
3720 stac_shutup(codec); 3716 stac_shutup(codec);
@@ -3743,7 +3739,6 @@ static void stac_set_power_state(struct hda_codec *codec, hda_nid_t fg,
3743} 3739}
3744#else 3740#else
3745#define stac_suspend NULL 3741#define stac_suspend NULL
3746#define stac_resume NULL
3747#define stac_set_power_state NULL 3742#define stac_set_power_state NULL
3748#endif /* CONFIG_PM */ 3743#endif /* CONFIG_PM */
3749 3744
@@ -3755,7 +3750,6 @@ static const struct hda_codec_ops stac_patch_ops = {
3755 .unsol_event = snd_hda_jack_unsol_event, 3750 .unsol_event = snd_hda_jack_unsol_event,
3756#ifdef CONFIG_PM 3751#ifdef CONFIG_PM
3757 .suspend = stac_suspend, 3752 .suspend = stac_suspend,
3758 .resume = stac_resume,
3759#endif 3753#endif
3760 .reboot_notify = stac_shutup, 3754 .reboot_notify = stac_shutup,
3761}; 3755};
diff --git a/sound/pci/hda/patch_via.c b/sound/pci/hda/patch_via.c
index e5245544eb52..e2481baddc70 100644
--- a/sound/pci/hda/patch_via.c
+++ b/sound/pci/hda/patch_via.c
@@ -480,14 +480,9 @@ static int via_suspend(struct hda_codec *codec)
480 struct via_spec *spec = codec->spec; 480 struct via_spec *spec = codec->spec;
481 vt1708_stop_hp_work(codec); 481 vt1708_stop_hp_work(codec);
482 482
483 if (spec->codec_type == VT1802) { 483 /* Fix pop noise on headphones */
484 /* Fix pop noise on headphones */ 484 if (spec->codec_type == VT1802)
485 int i; 485 snd_hda_shutup_pins(codec);
486 for (i = 0; i < spec->gen.autocfg.hp_outs; i++)
487 snd_hda_codec_write(codec, spec->gen.autocfg.hp_pins[i],
488 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
489 0x00);
490 }
491 486
492 return 0; 487 return 0;
493} 488}
@@ -746,6 +741,8 @@ static int patch_vt1708(struct hda_codec *codec)
746 /* don't support the input jack switching due to lack of unsol event */ 741 /* don't support the input jack switching due to lack of unsol event */
747 /* (it may work with polling, though, but it needs testing) */ 742 /* (it may work with polling, though, but it needs testing) */
748 spec->gen.suppress_auto_mic = 1; 743 spec->gen.suppress_auto_mic = 1;
744 /* Some machines show the broken speaker mute */
745 spec->gen.auto_mute_via_amp = 1;
749 746
750 /* Add HP and CD pin config connect bit re-config action */ 747 /* Add HP and CD pin config connect bit re-config action */
751 vt1708_set_pinconfig_connect(codec, VT1708_HP_PIN_NID); 748 vt1708_set_pinconfig_connect(codec, VT1708_HP_PIN_NID);
@@ -910,6 +907,8 @@ static const struct hda_verb vt1708S_init_verbs[] = {
910static void override_mic_boost(struct hda_codec *codec, hda_nid_t pin, 907static void override_mic_boost(struct hda_codec *codec, hda_nid_t pin,
911 int offset, int num_steps, int step_size) 908 int offset, int num_steps, int step_size)
912{ 909{
910 snd_hda_override_wcaps(codec, pin,
911 get_wcaps(codec, pin) | AC_WCAP_IN_AMP);
913 snd_hda_override_amp_caps(codec, pin, HDA_INPUT, 912 snd_hda_override_amp_caps(codec, pin, HDA_INPUT,
914 (offset << AC_AMPCAP_OFFSET_SHIFT) | 913 (offset << AC_AMPCAP_OFFSET_SHIFT) |
915 (num_steps << AC_AMPCAP_NUM_STEPS_SHIFT) | 914 (num_steps << AC_AMPCAP_NUM_STEPS_SHIFT) |
diff --git a/sound/pci/ice1712/ice1712.c b/sound/pci/ice1712/ice1712.c
index 806407a3973e..28ec872e54c0 100644
--- a/sound/pci/ice1712/ice1712.c
+++ b/sound/pci/ice1712/ice1712.c
@@ -2807,7 +2807,6 @@ static void snd_ice1712_remove(struct pci_dev *pci)
2807 if (ice->card_info && ice->card_info->chip_exit) 2807 if (ice->card_info && ice->card_info->chip_exit)
2808 ice->card_info->chip_exit(ice); 2808 ice->card_info->chip_exit(ice);
2809 snd_card_free(card); 2809 snd_card_free(card);
2810 pci_set_drvdata(pci, NULL);
2811} 2810}
2812 2811
2813static struct pci_driver ice1712_driver = { 2812static struct pci_driver ice1712_driver = {
diff --git a/sound/pci/ice1712/ice1724.c b/sound/pci/ice1712/ice1724.c
index ce70e7f113e0..500471778291 100644
--- a/sound/pci/ice1712/ice1724.c
+++ b/sound/pci/ice1712/ice1724.c
@@ -2800,7 +2800,6 @@ static void snd_vt1724_remove(struct pci_dev *pci)
2800 if (ice->card_info && ice->card_info->chip_exit) 2800 if (ice->card_info && ice->card_info->chip_exit)
2801 ice->card_info->chip_exit(ice); 2801 ice->card_info->chip_exit(ice);
2802 snd_card_free(card); 2802 snd_card_free(card);
2803 pci_set_drvdata(pci, NULL);
2804} 2803}
2805 2804
2806#ifdef CONFIG_PM_SLEEP 2805#ifdef CONFIG_PM_SLEEP
diff --git a/sound/pci/intel8x0.c b/sound/pci/intel8x0.c
index b8fe40531b9c..59c8aaebb91e 100644
--- a/sound/pci/intel8x0.c
+++ b/sound/pci/intel8x0.c
@@ -3364,7 +3364,6 @@ static int snd_intel8x0_probe(struct pci_dev *pci,
3364static void snd_intel8x0_remove(struct pci_dev *pci) 3364static void snd_intel8x0_remove(struct pci_dev *pci)
3365{ 3365{
3366 snd_card_free(pci_get_drvdata(pci)); 3366 snd_card_free(pci_get_drvdata(pci));
3367 pci_set_drvdata(pci, NULL);
3368} 3367}
3369 3368
3370static struct pci_driver intel8x0_driver = { 3369static struct pci_driver intel8x0_driver = {
diff --git a/sound/pci/intel8x0m.c b/sound/pci/intel8x0m.c
index fea09e8ea608..3573c1193665 100644
--- a/sound/pci/intel8x0m.c
+++ b/sound/pci/intel8x0m.c
@@ -1328,7 +1328,6 @@ static int snd_intel8x0m_probe(struct pci_dev *pci,
1328static void snd_intel8x0m_remove(struct pci_dev *pci) 1328static void snd_intel8x0m_remove(struct pci_dev *pci)
1329{ 1329{
1330 snd_card_free(pci_get_drvdata(pci)); 1330 snd_card_free(pci_get_drvdata(pci));
1331 pci_set_drvdata(pci, NULL);
1332} 1331}
1333 1332
1334static struct pci_driver intel8x0m_driver = { 1333static struct pci_driver intel8x0m_driver = {
diff --git a/sound/pci/korg1212/korg1212.c b/sound/pci/korg1212/korg1212.c
index 43b4228d9afe..9cf9829555d4 100644
--- a/sound/pci/korg1212/korg1212.c
+++ b/sound/pci/korg1212/korg1212.c
@@ -2473,7 +2473,6 @@ snd_korg1212_probe(struct pci_dev *pci,
2473static void snd_korg1212_remove(struct pci_dev *pci) 2473static void snd_korg1212_remove(struct pci_dev *pci)
2474{ 2474{
2475 snd_card_free(pci_get_drvdata(pci)); 2475 snd_card_free(pci_get_drvdata(pci));
2476 pci_set_drvdata(pci, NULL);
2477} 2476}
2478 2477
2479static struct pci_driver korg1212_driver = { 2478static struct pci_driver korg1212_driver = {
diff --git a/sound/pci/lola/lola.c b/sound/pci/lola/lola.c
index 322b638e8ec4..7307d97186cb 100644
--- a/sound/pci/lola/lola.c
+++ b/sound/pci/lola/lola.c
@@ -759,7 +759,6 @@ out_free:
759static void lola_remove(struct pci_dev *pci) 759static void lola_remove(struct pci_dev *pci)
760{ 760{
761 snd_card_free(pci_get_drvdata(pci)); 761 snd_card_free(pci_get_drvdata(pci));
762 pci_set_drvdata(pci, NULL);
763} 762}
764 763
765/* PCI IDs */ 764/* PCI IDs */
diff --git a/sound/pci/lx6464es/lx6464es.c b/sound/pci/lx6464es/lx6464es.c
index 298bc9b72991..3230e57f246c 100644
--- a/sound/pci/lx6464es/lx6464es.c
+++ b/sound/pci/lx6464es/lx6464es.c
@@ -1139,7 +1139,6 @@ out_free:
1139static void snd_lx6464es_remove(struct pci_dev *pci) 1139static void snd_lx6464es_remove(struct pci_dev *pci)
1140{ 1140{
1141 snd_card_free(pci_get_drvdata(pci)); 1141 snd_card_free(pci_get_drvdata(pci));
1142 pci_set_drvdata(pci, NULL);
1143} 1142}
1144 1143
1145 1144
diff --git a/sound/pci/maestro3.c b/sound/pci/maestro3.c
index c76ac1411210..d5417360f51f 100644
--- a/sound/pci/maestro3.c
+++ b/sound/pci/maestro3.c
@@ -2775,7 +2775,6 @@ snd_m3_probe(struct pci_dev *pci, const struct pci_device_id *pci_id)
2775static void snd_m3_remove(struct pci_dev *pci) 2775static void snd_m3_remove(struct pci_dev *pci)
2776{ 2776{
2777 snd_card_free(pci_get_drvdata(pci)); 2777 snd_card_free(pci_get_drvdata(pci));
2778 pci_set_drvdata(pci, NULL);
2779} 2778}
2780 2779
2781static struct pci_driver m3_driver = { 2780static struct pci_driver m3_driver = {
diff --git a/sound/pci/mixart/mixart.c b/sound/pci/mixart/mixart.c
index 934dec98e2ce..1e0f6ee193f0 100644
--- a/sound/pci/mixart/mixart.c
+++ b/sound/pci/mixart/mixart.c
@@ -1377,7 +1377,6 @@ static int snd_mixart_probe(struct pci_dev *pci,
1377static void snd_mixart_remove(struct pci_dev *pci) 1377static void snd_mixart_remove(struct pci_dev *pci)
1378{ 1378{
1379 snd_mixart_free(pci_get_drvdata(pci)); 1379 snd_mixart_free(pci_get_drvdata(pci));
1380 pci_set_drvdata(pci, NULL);
1381} 1380}
1382 1381
1383static struct pci_driver mixart_driver = { 1382static struct pci_driver mixart_driver = {
diff --git a/sound/pci/nm256/nm256.c b/sound/pci/nm256/nm256.c
index 6febedb05936..fe79fff4c6dc 100644
--- a/sound/pci/nm256/nm256.c
+++ b/sound/pci/nm256/nm256.c
@@ -1746,7 +1746,6 @@ static int snd_nm256_probe(struct pci_dev *pci,
1746static void snd_nm256_remove(struct pci_dev *pci) 1746static void snd_nm256_remove(struct pci_dev *pci)
1747{ 1747{
1748 snd_card_free(pci_get_drvdata(pci)); 1748 snd_card_free(pci_get_drvdata(pci));
1749 pci_set_drvdata(pci, NULL);
1750} 1749}
1751 1750
1752 1751
diff --git a/sound/pci/oxygen/oxygen_lib.c b/sound/pci/oxygen/oxygen_lib.c
index 9562dc63ba60..b0cb48adddc7 100644
--- a/sound/pci/oxygen/oxygen_lib.c
+++ b/sound/pci/oxygen/oxygen_lib.c
@@ -722,7 +722,6 @@ EXPORT_SYMBOL(oxygen_pci_probe);
722void oxygen_pci_remove(struct pci_dev *pci) 722void oxygen_pci_remove(struct pci_dev *pci)
723{ 723{
724 snd_card_free(pci_get_drvdata(pci)); 724 snd_card_free(pci_get_drvdata(pci));
725 pci_set_drvdata(pci, NULL);
726} 725}
727EXPORT_SYMBOL(oxygen_pci_remove); 726EXPORT_SYMBOL(oxygen_pci_remove);
728 727
diff --git a/sound/pci/pcxhr/pcxhr.c b/sound/pci/pcxhr/pcxhr.c
index b97384ad946d..d379b284955b 100644
--- a/sound/pci/pcxhr/pcxhr.c
+++ b/sound/pci/pcxhr/pcxhr.c
@@ -1691,7 +1691,6 @@ static int pcxhr_probe(struct pci_dev *pci,
1691static void pcxhr_remove(struct pci_dev *pci) 1691static void pcxhr_remove(struct pci_dev *pci)
1692{ 1692{
1693 pcxhr_free(pci_get_drvdata(pci)); 1693 pcxhr_free(pci_get_drvdata(pci));
1694 pci_set_drvdata(pci, NULL);
1695} 1694}
1696 1695
1697static struct pci_driver pcxhr_driver = { 1696static struct pci_driver pcxhr_driver = {
diff --git a/sound/pci/riptide/riptide.c b/sound/pci/riptide/riptide.c
index 63c1c8041554..56cc891e395e 100644
--- a/sound/pci/riptide/riptide.c
+++ b/sound/pci/riptide/riptide.c
@@ -2066,7 +2066,6 @@ static void snd_riptide_joystick_remove(struct pci_dev *pci)
2066 if (gameport) { 2066 if (gameport) {
2067 release_region(gameport->io, 8); 2067 release_region(gameport->io, 8);
2068 gameport_unregister_port(gameport); 2068 gameport_unregister_port(gameport);
2069 pci_set_drvdata(pci, NULL);
2070 } 2069 }
2071} 2070}
2072#endif 2071#endif
@@ -2179,7 +2178,6 @@ snd_card_riptide_probe(struct pci_dev *pci, const struct pci_device_id *pci_id)
2179static void snd_card_riptide_remove(struct pci_dev *pci) 2178static void snd_card_riptide_remove(struct pci_dev *pci)
2180{ 2179{
2181 snd_card_free(pci_get_drvdata(pci)); 2180 snd_card_free(pci_get_drvdata(pci));
2182 pci_set_drvdata(pci, NULL);
2183} 2181}
2184 2182
2185static struct pci_driver driver = { 2183static struct pci_driver driver = {
diff --git a/sound/pci/rme32.c b/sound/pci/rme32.c
index 0ecd4100713e..cc26346ae66b 100644
--- a/sound/pci/rme32.c
+++ b/sound/pci/rme32.c
@@ -1981,7 +1981,6 @@ snd_rme32_probe(struct pci_dev *pci, const struct pci_device_id *pci_id)
1981static void snd_rme32_remove(struct pci_dev *pci) 1981static void snd_rme32_remove(struct pci_dev *pci)
1982{ 1982{
1983 snd_card_free(pci_get_drvdata(pci)); 1983 snd_card_free(pci_get_drvdata(pci));
1984 pci_set_drvdata(pci, NULL);
1985} 1984}
1986 1985
1987static struct pci_driver rme32_driver = { 1986static struct pci_driver rme32_driver = {
diff --git a/sound/pci/rme96.c b/sound/pci/rme96.c
index 5fb88ac82aa9..2a8ad9d1a2ae 100644
--- a/sound/pci/rme96.c
+++ b/sound/pci/rme96.c
@@ -2390,7 +2390,6 @@ snd_rme96_probe(struct pci_dev *pci,
2390static void snd_rme96_remove(struct pci_dev *pci) 2390static void snd_rme96_remove(struct pci_dev *pci)
2391{ 2391{
2392 snd_card_free(pci_get_drvdata(pci)); 2392 snd_card_free(pci_get_drvdata(pci));
2393 pci_set_drvdata(pci, NULL);
2394} 2393}
2395 2394
2396static struct pci_driver rme96_driver = { 2395static struct pci_driver rme96_driver = {
diff --git a/sound/pci/rme9652/hdsp.c b/sound/pci/rme9652/hdsp.c
index 94084cdb130c..4f255dfee450 100644
--- a/sound/pci/rme9652/hdsp.c
+++ b/sound/pci/rme9652/hdsp.c
@@ -5412,7 +5412,6 @@ static int snd_hdsp_probe(struct pci_dev *pci,
5412static void snd_hdsp_remove(struct pci_dev *pci) 5412static void snd_hdsp_remove(struct pci_dev *pci)
5413{ 5413{
5414 snd_card_free(pci_get_drvdata(pci)); 5414 snd_card_free(pci_get_drvdata(pci));
5415 pci_set_drvdata(pci, NULL);
5416} 5415}
5417 5416
5418static struct pci_driver hdsp_driver = { 5417static struct pci_driver hdsp_driver = {
diff --git a/sound/pci/rme9652/hdspm.c b/sound/pci/rme9652/hdspm.c
index 9ea05e956474..bd501931ee23 100644
--- a/sound/pci/rme9652/hdspm.c
+++ b/sound/pci/rme9652/hdspm.c
@@ -400,8 +400,8 @@ MODULE_SUPPORTED_DEVICE("{{RME HDSPM-MADI}}");
400 400
401#define HDSPM_wc_freq0 (1<<5) /* input freq detected via autosync */ 401#define HDSPM_wc_freq0 (1<<5) /* input freq detected via autosync */
402#define HDSPM_wc_freq1 (1<<6) /* 001=32, 010==44.1, 011=48, */ 402#define HDSPM_wc_freq1 (1<<6) /* 001=32, 010==44.1, 011=48, */
403#define HDSPM_wc_freq2 (1<<7) /* 100=64, 101=88.2, 110=96, */ 403#define HDSPM_wc_freq2 (1<<7) /* 100=64, 101=88.2, 110=96, 111=128 */
404/* missing Bit for 111=128, 1000=176.4, 1001=192 */ 404#define HDSPM_wc_freq3 0x800 /* 1000=176.4, 1001=192 */
405 405
406#define HDSPM_SyncRef0 0x10000 /* Sync Reference */ 406#define HDSPM_SyncRef0 0x10000 /* Sync Reference */
407#define HDSPM_SyncRef1 0x20000 407#define HDSPM_SyncRef1 0x20000
@@ -412,13 +412,17 @@ MODULE_SUPPORTED_DEVICE("{{RME HDSPM-MADI}}");
412 412
413#define HDSPM_wc_valid (HDSPM_wcLock|HDSPM_wcSync) 413#define HDSPM_wc_valid (HDSPM_wcLock|HDSPM_wcSync)
414 414
415#define HDSPM_wcFreqMask (HDSPM_wc_freq0|HDSPM_wc_freq1|HDSPM_wc_freq2) 415#define HDSPM_wcFreqMask (HDSPM_wc_freq0|HDSPM_wc_freq1|HDSPM_wc_freq2|\
416 HDSPM_wc_freq3)
416#define HDSPM_wcFreq32 (HDSPM_wc_freq0) 417#define HDSPM_wcFreq32 (HDSPM_wc_freq0)
417#define HDSPM_wcFreq44_1 (HDSPM_wc_freq1) 418#define HDSPM_wcFreq44_1 (HDSPM_wc_freq1)
418#define HDSPM_wcFreq48 (HDSPM_wc_freq0|HDSPM_wc_freq1) 419#define HDSPM_wcFreq48 (HDSPM_wc_freq0|HDSPM_wc_freq1)
419#define HDSPM_wcFreq64 (HDSPM_wc_freq2) 420#define HDSPM_wcFreq64 (HDSPM_wc_freq2)
420#define HDSPM_wcFreq88_2 (HDSPM_wc_freq0|HDSPM_wc_freq2) 421#define HDSPM_wcFreq88_2 (HDSPM_wc_freq0|HDSPM_wc_freq2)
421#define HDSPM_wcFreq96 (HDSPM_wc_freq1|HDSPM_wc_freq2) 422#define HDSPM_wcFreq96 (HDSPM_wc_freq1|HDSPM_wc_freq2)
423#define HDSPM_wcFreq128 (HDSPM_wc_freq0|HDSPM_wc_freq1|HDSPM_wc_freq2)
424#define HDSPM_wcFreq176_4 (HDSPM_wc_freq3)
425#define HDSPM_wcFreq192 (HDSPM_wc_freq0|HDSPM_wc_freq3)
422 426
423#define HDSPM_status1_F_0 0x0400000 427#define HDSPM_status1_F_0 0x0400000
424#define HDSPM_status1_F_1 0x0800000 428#define HDSPM_status1_F_1 0x0800000
@@ -1087,6 +1091,26 @@ static int hdspm_round_frequency(int rate)
1087 return 48000; 1091 return 48000;
1088} 1092}
1089 1093
1094/* QS and DS rates normally can not be detected
1095 * automatically by the card. Only exception is MADI
1096 * in 96k frame mode.
1097 *
1098 * So if we read SS values (32 .. 48k), check for
1099 * user-provided DS/QS bits in the control register
1100 * and multiply the base frequency accordingly.
1101 */
1102static int hdspm_rate_multiplier(struct hdspm *hdspm, int rate)
1103{
1104 if (rate <= 48000) {
1105 if (hdspm->control_register & HDSPM_QuadSpeed)
1106 return rate * 4;
1107 else if (hdspm->control_register &
1108 HDSPM_DoubleSpeed)
1109 return rate * 2;
1110 };
1111 return rate;
1112}
1113
1090static int hdspm_tco_sync_check(struct hdspm *hdspm); 1114static int hdspm_tco_sync_check(struct hdspm *hdspm);
1091static int hdspm_sync_in_sync_check(struct hdspm *hdspm); 1115static int hdspm_sync_in_sync_check(struct hdspm *hdspm);
1092 1116
@@ -1181,6 +1205,15 @@ static int hdspm_external_sample_rate(struct hdspm *hdspm)
1181 case HDSPM_wcFreq96: 1205 case HDSPM_wcFreq96:
1182 rate = 96000; 1206 rate = 96000;
1183 break; 1207 break;
1208 case HDSPM_wcFreq128:
1209 rate = 128000;
1210 break;
1211 case HDSPM_wcFreq176_4:
1212 rate = 176400;
1213 break;
1214 case HDSPM_wcFreq192:
1215 rate = 192000;
1216 break;
1184 default: 1217 default:
1185 rate = 0; 1218 rate = 0;
1186 break; 1219 break;
@@ -1192,7 +1225,7 @@ static int hdspm_external_sample_rate(struct hdspm *hdspm)
1192 */ 1225 */
1193 if (rate != 0 && 1226 if (rate != 0 &&
1194 (status2 & HDSPM_SelSyncRefMask) == HDSPM_SelSyncRef_WORD) 1227 (status2 & HDSPM_SelSyncRefMask) == HDSPM_SelSyncRef_WORD)
1195 return rate; 1228 return hdspm_rate_multiplier(hdspm, rate);
1196 1229
1197 /* maybe a madi input (which is taken if sel sync is madi) */ 1230 /* maybe a madi input (which is taken if sel sync is madi) */
1198 if (status & HDSPM_madiLock) { 1231 if (status & HDSPM_madiLock) {
@@ -1255,21 +1288,8 @@ static int hdspm_external_sample_rate(struct hdspm *hdspm)
1255 } 1288 }
1256 } 1289 }
1257 1290
1258 /* QS and DS rates normally can not be detected 1291 rate = hdspm_rate_multiplier(hdspm, rate);
1259 * automatically by the card. Only exception is MADI 1292
1260 * in 96k frame mode.
1261 *
1262 * So if we read SS values (32 .. 48k), check for
1263 * user-provided DS/QS bits in the control register
1264 * and multiply the base frequency accordingly.
1265 */
1266 if (rate <= 48000) {
1267 if (hdspm->control_register & HDSPM_QuadSpeed)
1268 rate *= 4;
1269 else if (hdspm->control_register &
1270 HDSPM_DoubleSpeed)
1271 rate *= 2;
1272 }
1273 break; 1293 break;
1274 } 1294 }
1275 1295
@@ -6737,7 +6757,6 @@ static int snd_hdspm_probe(struct pci_dev *pci,
6737static void snd_hdspm_remove(struct pci_dev *pci) 6757static void snd_hdspm_remove(struct pci_dev *pci)
6738{ 6758{
6739 snd_card_free(pci_get_drvdata(pci)); 6759 snd_card_free(pci_get_drvdata(pci));
6740 pci_set_drvdata(pci, NULL);
6741} 6760}
6742 6761
6743static struct pci_driver hdspm_driver = { 6762static struct pci_driver hdspm_driver = {
diff --git a/sound/pci/rme9652/rme9652.c b/sound/pci/rme9652/rme9652.c
index 773a67fff4cd..b96d9e1adf6d 100644
--- a/sound/pci/rme9652/rme9652.c
+++ b/sound/pci/rme9652/rme9652.c
@@ -2628,7 +2628,6 @@ static int snd_rme9652_probe(struct pci_dev *pci,
2628static void snd_rme9652_remove(struct pci_dev *pci) 2628static void snd_rme9652_remove(struct pci_dev *pci)
2629{ 2629{
2630 snd_card_free(pci_get_drvdata(pci)); 2630 snd_card_free(pci_get_drvdata(pci));
2631 pci_set_drvdata(pci, NULL);
2632} 2631}
2633 2632
2634static struct pci_driver rme9652_driver = { 2633static struct pci_driver rme9652_driver = {
diff --git a/sound/pci/sis7019.c b/sound/pci/sis7019.c
index 748e82d4d257..e413b4e2c819 100644
--- a/sound/pci/sis7019.c
+++ b/sound/pci/sis7019.c
@@ -1482,7 +1482,6 @@ error_out:
1482static void snd_sis7019_remove(struct pci_dev *pci) 1482static void snd_sis7019_remove(struct pci_dev *pci)
1483{ 1483{
1484 snd_card_free(pci_get_drvdata(pci)); 1484 snd_card_free(pci_get_drvdata(pci));
1485 pci_set_drvdata(pci, NULL);
1486} 1485}
1487 1486
1488static struct pci_driver sis7019_driver = { 1487static struct pci_driver sis7019_driver = {
diff --git a/sound/pci/sonicvibes.c b/sound/pci/sonicvibes.c
index a2e7686e7ae3..2a46bf98af30 100644
--- a/sound/pci/sonicvibes.c
+++ b/sound/pci/sonicvibes.c
@@ -1528,7 +1528,6 @@ static int snd_sonic_probe(struct pci_dev *pci,
1528static void snd_sonic_remove(struct pci_dev *pci) 1528static void snd_sonic_remove(struct pci_dev *pci)
1529{ 1529{
1530 snd_card_free(pci_get_drvdata(pci)); 1530 snd_card_free(pci_get_drvdata(pci));
1531 pci_set_drvdata(pci, NULL);
1532} 1531}
1533 1532
1534static struct pci_driver sonicvibes_driver = { 1533static struct pci_driver sonicvibes_driver = {
diff --git a/sound/pci/trident/trident.c b/sound/pci/trident/trident.c
index 1aefd6204a63..b3b588bc94c3 100644
--- a/sound/pci/trident/trident.c
+++ b/sound/pci/trident/trident.c
@@ -169,7 +169,6 @@ static int snd_trident_probe(struct pci_dev *pci,
169static void snd_trident_remove(struct pci_dev *pci) 169static void snd_trident_remove(struct pci_dev *pci)
170{ 170{
171 snd_card_free(pci_get_drvdata(pci)); 171 snd_card_free(pci_get_drvdata(pci));
172 pci_set_drvdata(pci, NULL);
173} 172}
174 173
175static struct pci_driver trident_driver = { 174static struct pci_driver trident_driver = {
diff --git a/sound/pci/via82xx.c b/sound/pci/via82xx.c
index d756a3562706..3c511d0caf9e 100644
--- a/sound/pci/via82xx.c
+++ b/sound/pci/via82xx.c
@@ -2646,7 +2646,6 @@ static int snd_via82xx_probe(struct pci_dev *pci,
2646static void snd_via82xx_remove(struct pci_dev *pci) 2646static void snd_via82xx_remove(struct pci_dev *pci)
2647{ 2647{
2648 snd_card_free(pci_get_drvdata(pci)); 2648 snd_card_free(pci_get_drvdata(pci));
2649 pci_set_drvdata(pci, NULL);
2650} 2649}
2651 2650
2652static struct pci_driver via82xx_driver = { 2651static struct pci_driver via82xx_driver = {
diff --git a/sound/pci/via82xx_modem.c b/sound/pci/via82xx_modem.c
index 4f5fd80b7e56..ca190283cbd7 100644
--- a/sound/pci/via82xx_modem.c
+++ b/sound/pci/via82xx_modem.c
@@ -1227,7 +1227,6 @@ static int snd_via82xx_probe(struct pci_dev *pci,
1227static void snd_via82xx_remove(struct pci_dev *pci) 1227static void snd_via82xx_remove(struct pci_dev *pci)
1228{ 1228{
1229 snd_card_free(pci_get_drvdata(pci)); 1229 snd_card_free(pci_get_drvdata(pci));
1230 pci_set_drvdata(pci, NULL);
1231} 1230}
1232 1231
1233static struct pci_driver via82xx_modem_driver = { 1232static struct pci_driver via82xx_modem_driver = {
diff --git a/sound/pci/vx222/vx222.c b/sound/pci/vx222/vx222.c
index e2f1ab37e154..ab8a9b1bfb8e 100644
--- a/sound/pci/vx222/vx222.c
+++ b/sound/pci/vx222/vx222.c
@@ -254,7 +254,6 @@ static int snd_vx222_probe(struct pci_dev *pci,
254static void snd_vx222_remove(struct pci_dev *pci) 254static void snd_vx222_remove(struct pci_dev *pci)
255{ 255{
256 snd_card_free(pci_get_drvdata(pci)); 256 snd_card_free(pci_get_drvdata(pci));
257 pci_set_drvdata(pci, NULL);
258} 257}
259 258
260#ifdef CONFIG_PM_SLEEP 259#ifdef CONFIG_PM_SLEEP
diff --git a/sound/pci/ymfpci/ymfpci.c b/sound/pci/ymfpci/ymfpci.c
index 01c49655a3c1..e8932b2e4a5d 100644
--- a/sound/pci/ymfpci/ymfpci.c
+++ b/sound/pci/ymfpci/ymfpci.c
@@ -347,7 +347,6 @@ static int snd_card_ymfpci_probe(struct pci_dev *pci,
347static void snd_card_ymfpci_remove(struct pci_dev *pci) 347static void snd_card_ymfpci_remove(struct pci_dev *pci)
348{ 348{
349 snd_card_free(pci_get_drvdata(pci)); 349 snd_card_free(pci_get_drvdata(pci));
350 pci_set_drvdata(pci, NULL);
351} 350}
352 351
353static struct pci_driver ymfpci_driver = { 352static struct pci_driver ymfpci_driver = {
diff --git a/sound/pci/ymfpci/ymfpci_main.c b/sound/pci/ymfpci/ymfpci_main.c
index 22056c50fe39..d591c154fc58 100644
--- a/sound/pci/ymfpci/ymfpci_main.c
+++ b/sound/pci/ymfpci/ymfpci_main.c
@@ -2258,7 +2258,7 @@ static int snd_ymfpci_free(struct snd_ymfpci *chip)
2258 /* FIXME: temporarily disabled, otherwise we cannot fire up 2258 /* FIXME: temporarily disabled, otherwise we cannot fire up
2259 * the chip again unless reboot. ACPI bug? 2259 * the chip again unless reboot. ACPI bug?
2260 */ 2260 */
2261 pci_set_power_state(chip->pci, 3); 2261 pci_set_power_state(chip->pci, PCI_D3hot);
2262#endif 2262#endif
2263 2263
2264#ifdef CONFIG_PM_SLEEP 2264#ifdef CONFIG_PM_SLEEP
diff --git a/sound/ppc/powermac.c b/sound/ppc/powermac.c
index 09fc848d32ec..8abb521b4814 100644
--- a/sound/ppc/powermac.c
+++ b/sound/ppc/powermac.c
@@ -139,7 +139,6 @@ __error:
139static int snd_pmac_remove(struct platform_device *devptr) 139static int snd_pmac_remove(struct platform_device *devptr)
140{ 140{
141 snd_card_free(platform_get_drvdata(devptr)); 141 snd_card_free(platform_get_drvdata(devptr));
142 platform_set_drvdata(devptr, NULL);
143 return 0; 142 return 0;
144} 143}
145 144
diff --git a/sound/sh/aica.c b/sound/sh/aica.c
index e59a73a9bc42..78a369785a9e 100644
--- a/sound/sh/aica.c
+++ b/sound/sh/aica.c
@@ -598,7 +598,6 @@ static int snd_aica_remove(struct platform_device *devptr)
598 return -ENODEV; 598 return -ENODEV;
599 snd_card_free(dreamcastcard->card); 599 snd_card_free(dreamcastcard->card);
600 kfree(dreamcastcard); 600 kfree(dreamcastcard);
601 platform_set_drvdata(devptr, NULL);
602 return 0; 601 return 0;
603} 602}
604 603
diff --git a/sound/sh/sh_dac_audio.c b/sound/sh/sh_dac_audio.c
index e68c4fc91a03..7c9422c4fc0f 100644
--- a/sound/sh/sh_dac_audio.c
+++ b/sound/sh/sh_dac_audio.c
@@ -290,8 +290,6 @@ static int snd_sh_dac_pcm(struct snd_sh_dac *chip, int device)
290static int snd_sh_dac_remove(struct platform_device *devptr) 290static int snd_sh_dac_remove(struct platform_device *devptr)
291{ 291{
292 snd_card_free(platform_get_drvdata(devptr)); 292 snd_card_free(platform_get_drvdata(devptr));
293 platform_set_drvdata(devptr, NULL);
294
295 return 0; 293 return 0;
296} 294}
297 295
diff --git a/sound/soc/Kconfig b/sound/soc/Kconfig
index 9e675c76436c..45eeaa9f7fec 100644
--- a/sound/soc/Kconfig
+++ b/sound/soc/Kconfig
@@ -51,6 +51,7 @@ source "sound/soc/pxa/Kconfig"
51source "sound/soc/samsung/Kconfig" 51source "sound/soc/samsung/Kconfig"
52source "sound/soc/s6000/Kconfig" 52source "sound/soc/s6000/Kconfig"
53source "sound/soc/sh/Kconfig" 53source "sound/soc/sh/Kconfig"
54source "sound/soc/spear/Kconfig"
54source "sound/soc/tegra/Kconfig" 55source "sound/soc/tegra/Kconfig"
55source "sound/soc/txx9/Kconfig" 56source "sound/soc/txx9/Kconfig"
56source "sound/soc/ux500/Kconfig" 57source "sound/soc/ux500/Kconfig"
diff --git a/sound/soc/Makefile b/sound/soc/Makefile
index 197b6ae54c8d..bc0261476d7a 100644
--- a/sound/soc/Makefile
+++ b/sound/soc/Makefile
@@ -29,6 +29,7 @@ obj-$(CONFIG_SND_SOC) += pxa/
29obj-$(CONFIG_SND_SOC) += samsung/ 29obj-$(CONFIG_SND_SOC) += samsung/
30obj-$(CONFIG_SND_SOC) += s6000/ 30obj-$(CONFIG_SND_SOC) += s6000/
31obj-$(CONFIG_SND_SOC) += sh/ 31obj-$(CONFIG_SND_SOC) += sh/
32obj-$(CONFIG_SND_SOC) += spear/
32obj-$(CONFIG_SND_SOC) += tegra/ 33obj-$(CONFIG_SND_SOC) += tegra/
33obj-$(CONFIG_SND_SOC) += txx9/ 34obj-$(CONFIG_SND_SOC) += txx9/
34obj-$(CONFIG_SND_SOC) += ux500/ 35obj-$(CONFIG_SND_SOC) += ux500/
diff --git a/sound/soc/atmel/sam9g20_wm8731.c b/sound/soc/atmel/sam9g20_wm8731.c
index 2d6fbd0125b9..802717eccbd0 100644
--- a/sound/soc/atmel/sam9g20_wm8731.c
+++ b/sound/soc/atmel/sam9g20_wm8731.c
@@ -38,8 +38,6 @@
38#include <linux/platform_device.h> 38#include <linux/platform_device.h>
39#include <linux/i2c.h> 39#include <linux/i2c.h>
40 40
41#include <linux/pinctrl/consumer.h>
42
43#include <linux/atmel-ssc.h> 41#include <linux/atmel-ssc.h>
44 42
45#include <sound/core.h> 43#include <sound/core.h>
@@ -203,15 +201,8 @@ static int at91sam9g20ek_audio_probe(struct platform_device *pdev)
203 struct device_node *codec_np, *cpu_np; 201 struct device_node *codec_np, *cpu_np;
204 struct clk *pllb; 202 struct clk *pllb;
205 struct snd_soc_card *card = &snd_soc_at91sam9g20ek; 203 struct snd_soc_card *card = &snd_soc_at91sam9g20ek;
206 struct pinctrl *pinctrl;
207 int ret; 204 int ret;
208 205
209 pinctrl = devm_pinctrl_get_select_default(&pdev->dev);
210 if (IS_ERR(pinctrl)) {
211 dev_err(&pdev->dev, "Failed to request pinctrl for mck\n");
212 return PTR_ERR(pinctrl);
213 }
214
215 if (!np) { 206 if (!np) {
216 if (!(machine_is_at91sam9g20ek() || 207 if (!(machine_is_at91sam9g20ek() ||
217 machine_is_at91sam9g20ek_2mmc())) 208 machine_is_at91sam9g20ek_2mmc()))
diff --git a/sound/soc/au1x/ac97c.c b/sound/soc/au1x/ac97c.c
index 44b8dcecf571..d6f7694fcad4 100644
--- a/sound/soc/au1x/ac97c.c
+++ b/sound/soc/au1x/ac97c.c
@@ -179,13 +179,12 @@ static void au1xac97c_ac97_cold_reset(struct snd_ac97 *ac97)
179} 179}
180 180
181/* AC97 controller operations */ 181/* AC97 controller operations */
182struct snd_ac97_bus_ops soc_ac97_ops = { 182static struct snd_ac97_bus_ops ac97c_bus_ops = {
183 .read = au1xac97c_ac97_read, 183 .read = au1xac97c_ac97_read,
184 .write = au1xac97c_ac97_write, 184 .write = au1xac97c_ac97_write,
185 .reset = au1xac97c_ac97_cold_reset, 185 .reset = au1xac97c_ac97_cold_reset,
186 .warm_reset = au1xac97c_ac97_warm_reset, 186 .warm_reset = au1xac97c_ac97_warm_reset,
187}; 187};
188EXPORT_SYMBOL_GPL(soc_ac97_ops); /* globals be gone! */
189 188
190static int alchemy_ac97c_startup(struct snd_pcm_substream *substream, 189static int alchemy_ac97c_startup(struct snd_pcm_substream *substream,
191 struct snd_soc_dai *dai) 190 struct snd_soc_dai *dai)
@@ -272,6 +271,10 @@ static int au1xac97c_drvprobe(struct platform_device *pdev)
272 271
273 platform_set_drvdata(pdev, ctx); 272 platform_set_drvdata(pdev, ctx);
274 273
274 ret = snd_soc_set_ac97_ops(&ac97c_bus_ops);
275 if (ret)
276 return ret;
277
275 ret = snd_soc_register_component(&pdev->dev, &au1xac97c_component, 278 ret = snd_soc_register_component(&pdev->dev, &au1xac97c_component,
276 &au1xac97c_dai_driver, 1); 279 &au1xac97c_dai_driver, 1);
277 if (ret) 280 if (ret)
@@ -338,19 +341,7 @@ static struct platform_driver au1xac97c_driver = {
338 .remove = au1xac97c_drvremove, 341 .remove = au1xac97c_drvremove,
339}; 342};
340 343
341static int __init au1xac97c_load(void) 344module_platform_driver(&au1xac97c_driver);
342{
343 ac97c_workdata = NULL;
344 return platform_driver_register(&au1xac97c_driver);
345}
346
347static void __exit au1xac97c_unload(void)
348{
349 platform_driver_unregister(&au1xac97c_driver);
350}
351
352module_init(au1xac97c_load);
353module_exit(au1xac97c_unload);
354 345
355MODULE_LICENSE("GPL"); 346MODULE_LICENSE("GPL");
356MODULE_DESCRIPTION("Au1000/1500/1100 AC97C ASoC driver"); 347MODULE_DESCRIPTION("Au1000/1500/1100 AC97C ASoC driver");
diff --git a/sound/soc/au1x/psc-ac97.c b/sound/soc/au1x/psc-ac97.c
index 8f1862aa7333..a822ab822bb7 100644
--- a/sound/soc/au1x/psc-ac97.c
+++ b/sound/soc/au1x/psc-ac97.c
@@ -201,13 +201,12 @@ static void au1xpsc_ac97_cold_reset(struct snd_ac97 *ac97)
201} 201}
202 202
203/* AC97 controller operations */ 203/* AC97 controller operations */
204struct snd_ac97_bus_ops soc_ac97_ops = { 204static struct snd_ac97_bus_ops psc_ac97_ops = {
205 .read = au1xpsc_ac97_read, 205 .read = au1xpsc_ac97_read,
206 .write = au1xpsc_ac97_write, 206 .write = au1xpsc_ac97_write,
207 .reset = au1xpsc_ac97_cold_reset, 207 .reset = au1xpsc_ac97_cold_reset,
208 .warm_reset = au1xpsc_ac97_warm_reset, 208 .warm_reset = au1xpsc_ac97_warm_reset,
209}; 209};
210EXPORT_SYMBOL_GPL(soc_ac97_ops);
211 210
212static int au1xpsc_ac97_hw_params(struct snd_pcm_substream *substream, 211static int au1xpsc_ac97_hw_params(struct snd_pcm_substream *substream,
213 struct snd_pcm_hw_params *params, 212 struct snd_pcm_hw_params *params,
@@ -383,15 +382,9 @@ static int au1xpsc_ac97_drvprobe(struct platform_device *pdev)
383 if (!iores) 382 if (!iores)
384 return -ENODEV; 383 return -ENODEV;
385 384
386 if (!devm_request_mem_region(&pdev->dev, iores->start, 385 wd->mmio = devm_ioremap_resource(&pdev->dev, iores);
387 resource_size(iores), 386 if (IS_ERR(wd->mmio))
388 pdev->name)) 387 return PTR_ERR(wd->mmio);
389 return -EBUSY;
390
391 wd->mmio = devm_ioremap(&pdev->dev, iores->start,
392 resource_size(iores));
393 if (!wd->mmio)
394 return -EBUSY;
395 388
396 dmares = platform_get_resource(pdev, IORESOURCE_DMA, 0); 389 dmares = platform_get_resource(pdev, IORESOURCE_DMA, 0);
397 if (!dmares) 390 if (!dmares)
@@ -423,6 +416,10 @@ static int au1xpsc_ac97_drvprobe(struct platform_device *pdev)
423 416
424 platform_set_drvdata(pdev, wd); 417 platform_set_drvdata(pdev, wd);
425 418
419 ret = snd_soc_set_ac97_ops(&psc_ac97_ops);
420 if (ret)
421 return ret;
422
426 ret = snd_soc_register_component(&pdev->dev, &au1xpsc_ac97_component, 423 ret = snd_soc_register_component(&pdev->dev, &au1xpsc_ac97_component,
427 &wd->dai_drv, 1); 424 &wd->dai_drv, 1);
428 if (ret) 425 if (ret)
@@ -503,19 +500,7 @@ static struct platform_driver au1xpsc_ac97_driver = {
503 .remove = au1xpsc_ac97_drvremove, 500 .remove = au1xpsc_ac97_drvremove,
504}; 501};
505 502
506static int __init au1xpsc_ac97_load(void) 503module_platform_driver(au1xpsc_ac97_driver);
507{
508 au1xpsc_ac97_workdata = NULL;
509 return platform_driver_register(&au1xpsc_ac97_driver);
510}
511
512static void __exit au1xpsc_ac97_unload(void)
513{
514 platform_driver_unregister(&au1xpsc_ac97_driver);
515}
516
517module_init(au1xpsc_ac97_load);
518module_exit(au1xpsc_ac97_unload);
519 504
520MODULE_LICENSE("GPL"); 505MODULE_LICENSE("GPL");
521MODULE_DESCRIPTION("Au12x0/Au1550 PSC AC97 ALSA ASoC audio driver"); 506MODULE_DESCRIPTION("Au12x0/Au1550 PSC AC97 ALSA ASoC audio driver");
diff --git a/sound/soc/blackfin/Kconfig b/sound/soc/blackfin/Kconfig
index 16b88f5c26e2..54f74f8cbb75 100644
--- a/sound/soc/blackfin/Kconfig
+++ b/sound/soc/blackfin/Kconfig
@@ -56,6 +56,23 @@ config SND_SOC_BFIN_EVAL_ADAV80X
56 Note: This driver assumes that the ADAV80X digital record and playback 56 Note: This driver assumes that the ADAV80X digital record and playback
57 interfaces are connected to the first SPORT port on the BF5XX board. 57 interfaces are connected to the first SPORT port on the BF5XX board.
58 58
59config SND_BF5XX_SOC_AD1836
60 tristate "SoC AD1836 Audio support for BF5xx"
61 depends on SND_BF5XX_I2S
62 select SND_BF5XX_SOC_I2S
63 select SND_SOC_AD1836
64 help
65 Say Y if you want to add support for SoC audio on BF5xx STAMP/EZKIT.
66
67config SND_BF5XX_SOC_AD193X
68 tristate "SoC AD193X Audio support for Blackfin"
69 depends on SND_BF5XX_I2S
70 select SND_BF5XX_SOC_I2S
71 select SND_SOC_AD193X
72 help
73 Say Y if you want to add support for AD193X codec on Blackfin.
74 This driver supports AD1936, AD1937, AD1938 and AD1939.
75
59config SND_BF5XX_SOC_AD73311 76config SND_BF5XX_SOC_AD73311
60 tristate "SoC AD73311 Audio support for Blackfin" 77 tristate "SoC AD73311 Audio support for Blackfin"
61 depends on SND_BF5XX_I2S 78 depends on SND_BF5XX_I2S
@@ -72,33 +89,6 @@ config SND_BFIN_AD73311_SE
72 Enter the GPIO used to control AD73311's SE pin. Acceptable 89 Enter the GPIO used to control AD73311's SE pin. Acceptable
73 values are 0 to 7 90 values are 0 to 7
74 91
75config SND_BF5XX_TDM
76 tristate "SoC I2S(TDM mode) Audio for the ADI BF5xx chip"
77 depends on (BLACKFIN && SND_SOC)
78 select SND_BF5XX_SOC_SPORT
79 help
80 Say Y or M if you want to add support for codecs attached to
81 the Blackfin SPORT (synchronous serial ports) interface in TDM
82 mode.
83 You will also need to select the audio interfaces to support below.
84
85config SND_BF5XX_SOC_AD1836
86 tristate "SoC AD1836 Audio support for BF5xx"
87 depends on SND_BF5XX_TDM
88 select SND_BF5XX_SOC_TDM
89 select SND_SOC_AD1836
90 help
91 Say Y if you want to add support for SoC audio on BF5xx STAMP/EZKIT.
92
93config SND_BF5XX_SOC_AD193X
94 tristate "SoC AD193X Audio support for Blackfin"
95 depends on SND_BF5XX_TDM
96 select SND_BF5XX_SOC_TDM
97 select SND_SOC_AD193X
98 help
99 Say Y if you want to add support for AD193X codec on Blackfin.
100 This driver supports AD1936, AD1937, AD1938 and AD1939.
101
102config SND_BF5XX_AC97 92config SND_BF5XX_AC97
103 tristate "SoC AC97 Audio for the ADI BF5xx chip" 93 tristate "SoC AC97 Audio for the ADI BF5xx chip"
104 depends on BLACKFIN 94 depends on BLACKFIN
@@ -174,9 +164,6 @@ config SND_BF5XX_SOC_I2S
174config SND_BF6XX_SOC_I2S 164config SND_BF6XX_SOC_I2S
175 tristate 165 tristate
176 166
177config SND_BF5XX_SOC_TDM
178 tristate
179
180config SND_BF5XX_SOC_AC97 167config SND_BF5XX_SOC_AC97
181 tristate 168 tristate
182 169
diff --git a/sound/soc/blackfin/Makefile b/sound/soc/blackfin/Makefile
index 6fea1f4cbee2..ad0a6e99bc5d 100644
--- a/sound/soc/blackfin/Makefile
+++ b/sound/soc/blackfin/Makefile
@@ -1,23 +1,19 @@
1# Blackfin Platform Support 1# Blackfin Platform Support
2snd-bf5xx-ac97-objs := bf5xx-ac97-pcm.o 2snd-bf5xx-ac97-objs := bf5xx-ac97-pcm.o
3snd-bf5xx-i2s-objs := bf5xx-i2s-pcm.o 3snd-bf5xx-i2s-objs := bf5xx-i2s-pcm.o
4snd-bf5xx-tdm-objs := bf5xx-tdm-pcm.o
5snd-soc-bf5xx-sport-objs := bf5xx-sport.o 4snd-soc-bf5xx-sport-objs := bf5xx-sport.o
6snd-soc-bf6xx-sport-objs := bf6xx-sport.o 5snd-soc-bf6xx-sport-objs := bf6xx-sport.o
7snd-soc-bf5xx-ac97-objs := bf5xx-ac97.o 6snd-soc-bf5xx-ac97-objs := bf5xx-ac97.o
8snd-soc-bf5xx-i2s-objs := bf5xx-i2s.o 7snd-soc-bf5xx-i2s-objs := bf5xx-i2s.o
9snd-soc-bf6xx-i2s-objs := bf6xx-i2s.o 8snd-soc-bf6xx-i2s-objs := bf6xx-i2s.o
10snd-soc-bf5xx-tdm-objs := bf5xx-tdm.o
11 9
12obj-$(CONFIG_SND_BF5XX_AC97) += snd-bf5xx-ac97.o 10obj-$(CONFIG_SND_BF5XX_AC97) += snd-bf5xx-ac97.o
13obj-$(CONFIG_SND_BF5XX_I2S) += snd-bf5xx-i2s.o 11obj-$(CONFIG_SND_BF5XX_I2S) += snd-bf5xx-i2s.o
14obj-$(CONFIG_SND_BF5XX_TDM) += snd-bf5xx-tdm.o
15obj-$(CONFIG_SND_BF5XX_SOC_SPORT) += snd-soc-bf5xx-sport.o 12obj-$(CONFIG_SND_BF5XX_SOC_SPORT) += snd-soc-bf5xx-sport.o
16obj-$(CONFIG_SND_BF6XX_SOC_SPORT) += snd-soc-bf6xx-sport.o 13obj-$(CONFIG_SND_BF6XX_SOC_SPORT) += snd-soc-bf6xx-sport.o
17obj-$(CONFIG_SND_BF5XX_SOC_AC97) += snd-soc-bf5xx-ac97.o 14obj-$(CONFIG_SND_BF5XX_SOC_AC97) += snd-soc-bf5xx-ac97.o
18obj-$(CONFIG_SND_BF5XX_SOC_I2S) += snd-soc-bf5xx-i2s.o 15obj-$(CONFIG_SND_BF5XX_SOC_I2S) += snd-soc-bf5xx-i2s.o
19obj-$(CONFIG_SND_BF6XX_SOC_I2S) += snd-soc-bf6xx-i2s.o 16obj-$(CONFIG_SND_BF6XX_SOC_I2S) += snd-soc-bf6xx-i2s.o
20obj-$(CONFIG_SND_BF5XX_SOC_TDM) += snd-soc-bf5xx-tdm.o
21 17
22# Blackfin Machine Support 18# Blackfin Machine Support
23snd-ad1836-objs := bf5xx-ad1836.o 19snd-ad1836-objs := bf5xx-ad1836.o
diff --git a/sound/soc/blackfin/bf5xx-ac97-pcm.c b/sound/soc/blackfin/bf5xx-ac97-pcm.c
index 7e2f36004a5a..53f84085bf1f 100644
--- a/sound/soc/blackfin/bf5xx-ac97-pcm.c
+++ b/sound/soc/blackfin/bf5xx-ac97-pcm.c
@@ -39,7 +39,6 @@
39 39
40#include <asm/dma.h> 40#include <asm/dma.h>
41 41
42#include "bf5xx-ac97-pcm.h"
43#include "bf5xx-ac97.h" 42#include "bf5xx-ac97.h"
44#include "bf5xx-sport.h" 43#include "bf5xx-sport.h"
45 44
diff --git a/sound/soc/blackfin/bf5xx-ac97-pcm.h b/sound/soc/blackfin/bf5xx-ac97-pcm.h
deleted file mode 100644
index d324d5826a9b..000000000000
--- a/sound/soc/blackfin/bf5xx-ac97-pcm.h
+++ /dev/null
@@ -1,26 +0,0 @@
1/*
2 * linux/sound/arm/bf5xx-ac97-pcm.h -- ALSA PCM interface for the Blackfin
3 *
4 * Copyright 2007 Analog Device Inc.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 */
10
11#ifndef _BF5XX_AC97_PCM_H
12#define _BF5XX_AC97_PCM_H
13
14struct bf5xx_pcm_dma_params {
15 char *name; /* stream identifier */
16};
17
18struct bf5xx_gpio {
19 u32 sys;
20 u32 rx;
21 u32 tx;
22 u32 clk;
23 u32 frm;
24};
25
26#endif
diff --git a/sound/soc/blackfin/bf5xx-ac97.c b/sound/soc/blackfin/bf5xx-ac97.c
index 490217325975..efb1daecd0dd 100644
--- a/sound/soc/blackfin/bf5xx-ac97.c
+++ b/sound/soc/blackfin/bf5xx-ac97.c
@@ -198,13 +198,12 @@ static void bf5xx_ac97_cold_reset(struct snd_ac97 *ac97)
198#endif 198#endif
199} 199}
200 200
201struct snd_ac97_bus_ops soc_ac97_ops = { 201static struct snd_ac97_bus_ops bf5xx_ac97_ops = {
202 .read = bf5xx_ac97_read, 202 .read = bf5xx_ac97_read,
203 .write = bf5xx_ac97_write, 203 .write = bf5xx_ac97_write,
204 .warm_reset = bf5xx_ac97_warm_reset, 204 .warm_reset = bf5xx_ac97_warm_reset,
205 .reset = bf5xx_ac97_cold_reset, 205 .reset = bf5xx_ac97_cold_reset,
206}; 206};
207EXPORT_SYMBOL_GPL(soc_ac97_ops);
208 207
209#ifdef CONFIG_PM 208#ifdef CONFIG_PM
210static int bf5xx_ac97_suspend(struct snd_soc_dai *dai) 209static int bf5xx_ac97_suspend(struct snd_soc_dai *dai)
@@ -231,9 +230,9 @@ static int bf5xx_ac97_resume(struct snd_soc_dai *dai)
231 return 0; 230 return 0;
232 231
233#if defined(CONFIG_SND_BF5XX_MULTICHAN_SUPPORT) 232#if defined(CONFIG_SND_BF5XX_MULTICHAN_SUPPORT)
234 ret = sport_set_multichannel(sport, 16, 0x3FF, 1); 233 ret = sport_set_multichannel(sport, 16, 0x3FF, 0x3FF, 1);
235#else 234#else
236 ret = sport_set_multichannel(sport, 16, 0x1F, 1); 235 ret = sport_set_multichannel(sport, 16, 0x1F, 0x1F, 1);
237#endif 236#endif
238 if (ret) { 237 if (ret) {
239 pr_err("SPORT is busy!\n"); 238 pr_err("SPORT is busy!\n");
@@ -293,13 +292,14 @@ static int asoc_bfin_ac97_probe(struct platform_device *pdev)
293 292
294#ifdef CONFIG_SND_BF5XX_HAVE_COLD_RESET 293#ifdef CONFIG_SND_BF5XX_HAVE_COLD_RESET
295 /* Request PB3 as reset pin */ 294 /* Request PB3 as reset pin */
296 if (gpio_request(CONFIG_SND_BF5XX_RESET_GPIO_NUM, "SND_AD198x RESET")) { 295 ret = devm_gpio_request_one(&pdev->dev,
297 pr_err("Failed to request GPIO_%d for reset\n", 296 CONFIG_SND_BF5XX_RESET_GPIO_NUM,
298 CONFIG_SND_BF5XX_RESET_GPIO_NUM); 297 GPIOF_OUT_INIT_HIGH, "SND_AD198x RESET") {
299 ret = -1; 298 dev_err(&pdev->dev,
299 "Failed to request GPIO_%d for reset: %d\n",
300 CONFIG_SND_BF5XX_RESET_GPIO_NUM, ret);
300 goto gpio_err; 301 goto gpio_err;
301 } 302 }
302 gpio_direction_output(CONFIG_SND_BF5XX_RESET_GPIO_NUM, 1);
303#endif 303#endif
304 304
305 sport_handle = sport_init(pdev, 2, sizeof(struct ac97_frame), 305 sport_handle = sport_init(pdev, 2, sizeof(struct ac97_frame),
@@ -311,9 +311,9 @@ static int asoc_bfin_ac97_probe(struct platform_device *pdev)
311 311
312 /*SPORT works in TDM mode to simulate AC97 transfers*/ 312 /*SPORT works in TDM mode to simulate AC97 transfers*/
313#if defined(CONFIG_SND_BF5XX_MULTICHAN_SUPPORT) 313#if defined(CONFIG_SND_BF5XX_MULTICHAN_SUPPORT)
314 ret = sport_set_multichannel(sport_handle, 16, 0x3FF, 1); 314 ret = sport_set_multichannel(sport_handle, 16, 0x3FF, 0x3FF, 1);
315#else 315#else
316 ret = sport_set_multichannel(sport_handle, 16, 0x1F, 1); 316 ret = sport_set_multichannel(sport_handle, 16, 0x1F, 0x1F, 1);
317#endif 317#endif
318 if (ret) { 318 if (ret) {
319 pr_err("SPORT is busy!\n"); 319 pr_err("SPORT is busy!\n");
@@ -335,6 +335,12 @@ static int asoc_bfin_ac97_probe(struct platform_device *pdev)
335 goto sport_config_err; 335 goto sport_config_err;
336 } 336 }
337 337
338 ret = snd_soc_set_ac97_ops(&bf5xx_ac97_ops);
339 if (ret != 0) {
340 dev_err(&pdev->dev, "Failed to set AC'97 ops: %d\n", ret);
341 goto sport_config_err;
342 }
343
338 ret = snd_soc_register_component(&pdev->dev, &bfin_ac97_component, 344 ret = snd_soc_register_component(&pdev->dev, &bfin_ac97_component,
339 &bfin_ac97_dai, 1); 345 &bfin_ac97_dai, 1);
340 if (ret) { 346 if (ret) {
@@ -349,10 +355,7 @@ static int asoc_bfin_ac97_probe(struct platform_device *pdev)
349sport_config_err: 355sport_config_err:
350 sport_done(sport_handle); 356 sport_done(sport_handle);
351sport_err: 357sport_err:
352#ifdef CONFIG_SND_BF5XX_HAVE_COLD_RESET 358 snd_soc_set_ac97_ops(NULL);
353 gpio_free(CONFIG_SND_BF5XX_RESET_GPIO_NUM);
354gpio_err:
355#endif
356 359
357 return ret; 360 return ret;
358} 361}
@@ -363,9 +366,7 @@ static int asoc_bfin_ac97_remove(struct platform_device *pdev)
363 366
364 snd_soc_unregister_component(&pdev->dev); 367 snd_soc_unregister_component(&pdev->dev);
365 sport_done(sport_handle); 368 sport_done(sport_handle);
366#ifdef CONFIG_SND_BF5XX_HAVE_COLD_RESET 369 snd_soc_set_ac97_ops(NULL);
367 gpio_free(CONFIG_SND_BF5XX_RESET_GPIO_NUM);
368#endif
369 370
370 return 0; 371 return 0;
371} 372}
diff --git a/sound/soc/blackfin/bf5xx-ad1836.c b/sound/soc/blackfin/bf5xx-ad1836.c
index d23f4b0ea54f..8fcfc4ec3a51 100644
--- a/sound/soc/blackfin/bf5xx-ad1836.c
+++ b/sound/soc/blackfin/bf5xx-ad1836.c
@@ -30,15 +30,10 @@
30 30
31#include "../codecs/ad1836.h" 31#include "../codecs/ad1836.h"
32 32
33#include "bf5xx-tdm-pcm.h"
34#include "bf5xx-tdm.h"
35
36static struct snd_soc_card bf5xx_ad1836; 33static struct snd_soc_card bf5xx_ad1836;
37 34
38static int bf5xx_ad1836_hw_params(struct snd_pcm_substream *substream, 35static int bf5xx_ad1836_init(struct snd_soc_pcm_runtime *rtd)
39 struct snd_pcm_hw_params *params)
40{ 36{
41 struct snd_soc_pcm_runtime *rtd = substream->private_data;
42 struct snd_soc_dai *cpu_dai = rtd->cpu_dai; 37 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
43 unsigned int channel_map[] = {0, 4, 1, 5, 2, 6, 3, 7}; 38 unsigned int channel_map[] = {0, 4, 1, 5, 2, 6, 3, 7};
44 int ret = 0; 39 int ret = 0;
@@ -49,13 +44,13 @@ static int bf5xx_ad1836_hw_params(struct snd_pcm_substream *substream,
49 if (ret < 0) 44 if (ret < 0)
50 return ret; 45 return ret;
51 46
47 ret = snd_soc_dai_set_tdm_slot(cpu_dai, 0xFF, 0xFF, 8, 32);
48 if (ret < 0)
49 return ret;
50
52 return 0; 51 return 0;
53} 52}
54 53
55static struct snd_soc_ops bf5xx_ad1836_ops = {
56 .hw_params = bf5xx_ad1836_hw_params,
57};
58
59#define BF5XX_AD1836_DAIFMT (SND_SOC_DAIFMT_DSP_A | SND_SOC_DAIFMT_IB_IF | \ 54#define BF5XX_AD1836_DAIFMT (SND_SOC_DAIFMT_DSP_A | SND_SOC_DAIFMT_IB_IF | \
60 SND_SOC_DAIFMT_CBM_CFM) 55 SND_SOC_DAIFMT_CBM_CFM)
61 56
@@ -63,9 +58,9 @@ static struct snd_soc_dai_link bf5xx_ad1836_dai = {
63 .name = "ad1836", 58 .name = "ad1836",
64 .stream_name = "AD1836", 59 .stream_name = "AD1836",
65 .codec_dai_name = "ad1836-hifi", 60 .codec_dai_name = "ad1836-hifi",
66 .platform_name = "bfin-tdm-pcm-audio", 61 .platform_name = "bfin-i2s-pcm-audio",
67 .ops = &bf5xx_ad1836_ops,
68 .dai_fmt = BF5XX_AD1836_DAIFMT, 62 .dai_fmt = BF5XX_AD1836_DAIFMT,
63 .init = bf5xx_ad1836_init,
69}; 64};
70 65
71static struct snd_soc_card bf5xx_ad1836 = { 66static struct snd_soc_card bf5xx_ad1836 = {
diff --git a/sound/soc/blackfin/bf5xx-ad193x.c b/sound/soc/blackfin/bf5xx-ad193x.c
index 0e55e9f2a514..603ad1f2b9b9 100644
--- a/sound/soc/blackfin/bf5xx-ad193x.c
+++ b/sound/soc/blackfin/bf5xx-ad193x.c
@@ -39,30 +39,16 @@
39 39
40#include "../codecs/ad193x.h" 40#include "../codecs/ad193x.h"
41 41
42#include "bf5xx-tdm-pcm.h"
43#include "bf5xx-tdm.h"
44
45static struct snd_soc_card bf5xx_ad193x; 42static struct snd_soc_card bf5xx_ad193x;
46 43
47static int bf5xx_ad193x_hw_params(struct snd_pcm_substream *substream, 44static int bf5xx_ad193x_link_init(struct snd_soc_pcm_runtime *rtd)
48 struct snd_pcm_hw_params *params)
49{ 45{
50 struct snd_soc_pcm_runtime *rtd = substream->private_data;
51 struct snd_soc_dai *cpu_dai = rtd->cpu_dai; 46 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
52 struct snd_soc_dai *codec_dai = rtd->codec_dai; 47 struct snd_soc_dai *codec_dai = rtd->codec_dai;
53 unsigned int clk = 0; 48 int ret;
54 unsigned int channel_map[] = {0, 1, 2, 3, 4, 5, 6, 7};
55 int ret = 0;
56
57 switch (params_rate(params)) {
58 case 48000:
59 clk = 24576000;
60 break;
61 }
62 49
63 /* set the codec system clock for DAC and ADC */ 50 /* set the codec system clock for DAC and ADC */
64 ret = snd_soc_dai_set_sysclk(codec_dai, 0, clk, 51 ret = snd_soc_dai_set_sysclk(codec_dai, 0, 24576000, SND_SOC_CLOCK_IN);
65 SND_SOC_CLOCK_IN);
66 if (ret < 0) 52 if (ret < 0)
67 return ret; 53 return ret;
68 54
@@ -71,9 +57,7 @@ static int bf5xx_ad193x_hw_params(struct snd_pcm_substream *substream,
71 if (ret < 0) 57 if (ret < 0)
72 return ret; 58 return ret;
73 59
74 /* set cpu DAI channel mapping */ 60 ret = snd_soc_dai_set_tdm_slot(cpu_dai, 0xFF, 0xFF, 8, 32);
75 ret = snd_soc_dai_set_channel_map(cpu_dai, ARRAY_SIZE(channel_map),
76 channel_map, ARRAY_SIZE(channel_map), channel_map);
77 if (ret < 0) 61 if (ret < 0)
78 return ret; 62 return ret;
79 63
@@ -83,30 +67,26 @@ static int bf5xx_ad193x_hw_params(struct snd_pcm_substream *substream,
83#define BF5XX_AD193X_DAIFMT (SND_SOC_DAIFMT_DSP_A | SND_SOC_DAIFMT_IB_IF | \ 67#define BF5XX_AD193X_DAIFMT (SND_SOC_DAIFMT_DSP_A | SND_SOC_DAIFMT_IB_IF | \
84 SND_SOC_DAIFMT_CBM_CFM) 68 SND_SOC_DAIFMT_CBM_CFM)
85 69
86static struct snd_soc_ops bf5xx_ad193x_ops = {
87 .hw_params = bf5xx_ad193x_hw_params,
88};
89
90static struct snd_soc_dai_link bf5xx_ad193x_dai[] = { 70static struct snd_soc_dai_link bf5xx_ad193x_dai[] = {
91 { 71 {
92 .name = "ad193x", 72 .name = "ad193x",
93 .stream_name = "AD193X", 73 .stream_name = "AD193X",
94 .cpu_dai_name = "bfin-tdm.0", 74 .cpu_dai_name = "bfin-i2s.0",
95 .codec_dai_name ="ad193x-hifi", 75 .codec_dai_name ="ad193x-hifi",
96 .platform_name = "bfin-tdm-pcm-audio", 76 .platform_name = "bfin-i2s-pcm-audio",
97 .codec_name = "spi0.5", 77 .codec_name = "spi0.5",
98 .ops = &bf5xx_ad193x_ops,
99 .dai_fmt = BF5XX_AD193X_DAIFMT, 78 .dai_fmt = BF5XX_AD193X_DAIFMT,
79 .init = bf5xx_ad193x_link_init,
100 }, 80 },
101 { 81 {
102 .name = "ad193x", 82 .name = "ad193x",
103 .stream_name = "AD193X", 83 .stream_name = "AD193X",
104 .cpu_dai_name = "bfin-tdm.1", 84 .cpu_dai_name = "bfin-i2s.1",
105 .codec_dai_name ="ad193x-hifi", 85 .codec_dai_name ="ad193x-hifi",
106 .platform_name = "bfin-tdm-pcm-audio", 86 .platform_name = "bfin-i2s-pcm-audio",
107 .codec_name = "spi0.5", 87 .codec_name = "spi0.5",
108 .ops = &bf5xx_ad193x_ops,
109 .dai_fmt = BF5XX_AD193X_DAIFMT, 88 .dai_fmt = BF5XX_AD193X_DAIFMT,
89 .init = bf5xx_ad193x_link_init,
110 }, 90 },
111}; 91};
112 92
diff --git a/sound/soc/blackfin/bf5xx-ad1980.c b/sound/soc/blackfin/bf5xx-ad1980.c
index b30f88bbd703..3450e8f9080d 100644
--- a/sound/soc/blackfin/bf5xx-ad1980.c
+++ b/sound/soc/blackfin/bf5xx-ad1980.c
@@ -48,7 +48,6 @@
48 48
49#include "../codecs/ad1980.h" 49#include "../codecs/ad1980.h"
50 50
51#include "bf5xx-ac97-pcm.h"
52#include "bf5xx-ac97.h" 51#include "bf5xx-ac97.h"
53 52
54static struct snd_soc_card bf5xx_board; 53static struct snd_soc_card bf5xx_board;
diff --git a/sound/soc/blackfin/bf5xx-ad73311.c b/sound/soc/blackfin/bf5xx-ad73311.c
index 61cc91d4a028..786bbdd96e7c 100644
--- a/sound/soc/blackfin/bf5xx-ad73311.c
+++ b/sound/soc/blackfin/bf5xx-ad73311.c
@@ -45,7 +45,6 @@
45 45
46#include "../codecs/ad73311.h" 46#include "../codecs/ad73311.h"
47#include "bf5xx-sport.h" 47#include "bf5xx-sport.h"
48#include "bf5xx-i2s-pcm.h"
49 48
50#if CONFIG_SND_BF5XX_SPORT_NUM == 0 49#if CONFIG_SND_BF5XX_SPORT_NUM == 0
51#define bfin_write_SPORT_TCR1 bfin_write_SPORT0_TCR1 50#define bfin_write_SPORT_TCR1 bfin_write_SPORT0_TCR1
diff --git a/sound/soc/blackfin/bf5xx-i2s-pcm.c b/sound/soc/blackfin/bf5xx-i2s-pcm.c
index 262c1de364d8..9cb4a80df98e 100644
--- a/sound/soc/blackfin/bf5xx-i2s-pcm.c
+++ b/sound/soc/blackfin/bf5xx-i2s-pcm.c
@@ -39,8 +39,8 @@
39 39
40#include <asm/dma.h> 40#include <asm/dma.h>
41 41
42#include "bf5xx-i2s-pcm.h"
43#include "bf5xx-sport.h" 42#include "bf5xx-sport.h"
43#include "bf5xx-i2s-pcm.h"
44 44
45static void bf5xx_dma_irq(void *data) 45static void bf5xx_dma_irq(void *data)
46{ 46{
@@ -50,7 +50,6 @@ static void bf5xx_dma_irq(void *data)
50 50
51static const struct snd_pcm_hardware bf5xx_pcm_hardware = { 51static const struct snd_pcm_hardware bf5xx_pcm_hardware = {
52 .info = SNDRV_PCM_INFO_INTERLEAVED | 52 .info = SNDRV_PCM_INFO_INTERLEAVED |
53 SNDRV_PCM_INFO_MMAP |
54 SNDRV_PCM_INFO_MMAP_VALID | 53 SNDRV_PCM_INFO_MMAP_VALID |
55 SNDRV_PCM_INFO_BLOCK_TRANSFER, 54 SNDRV_PCM_INFO_BLOCK_TRANSFER,
56 .formats = SNDRV_PCM_FMTBIT_S16_LE | 55 .formats = SNDRV_PCM_FMTBIT_S16_LE |
@@ -67,10 +66,16 @@ static const struct snd_pcm_hardware bf5xx_pcm_hardware = {
67static int bf5xx_pcm_hw_params(struct snd_pcm_substream *substream, 66static int bf5xx_pcm_hw_params(struct snd_pcm_substream *substream,
68 struct snd_pcm_hw_params *params) 67 struct snd_pcm_hw_params *params)
69{ 68{
70 size_t size = bf5xx_pcm_hardware.buffer_bytes_max; 69 struct snd_soc_pcm_runtime *rtd = substream->private_data;
71 snd_pcm_lib_malloc_pages(substream, size); 70 unsigned int buffer_size = params_buffer_bytes(params);
71 struct bf5xx_i2s_pcm_data *dma_data;
72 72
73 return 0; 73 dma_data = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
74
75 if (dma_data->tdm_mode)
76 buffer_size = buffer_size / params_channels(params) * 8;
77
78 return snd_pcm_lib_malloc_pages(substream, buffer_size);
74} 79}
75 80
76static int bf5xx_pcm_hw_free(struct snd_pcm_substream *substream) 81static int bf5xx_pcm_hw_free(struct snd_pcm_substream *substream)
@@ -82,9 +87,16 @@ static int bf5xx_pcm_hw_free(struct snd_pcm_substream *substream)
82 87
83static int bf5xx_pcm_prepare(struct snd_pcm_substream *substream) 88static int bf5xx_pcm_prepare(struct snd_pcm_substream *substream)
84{ 89{
90 struct snd_soc_pcm_runtime *rtd = substream->private_data;
85 struct snd_pcm_runtime *runtime = substream->runtime; 91 struct snd_pcm_runtime *runtime = substream->runtime;
86 struct sport_device *sport = runtime->private_data; 92 struct sport_device *sport = runtime->private_data;
87 int period_bytes = frames_to_bytes(runtime, runtime->period_size); 93 int period_bytes = frames_to_bytes(runtime, runtime->period_size);
94 struct bf5xx_i2s_pcm_data *dma_data;
95
96 dma_data = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
97
98 if (dma_data->tdm_mode)
99 period_bytes = period_bytes / runtime->channels * 8;
88 100
89 pr_debug("%s enter\n", __func__); 101 pr_debug("%s enter\n", __func__);
90 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { 102 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
@@ -131,10 +143,15 @@ static int bf5xx_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
131 143
132static snd_pcm_uframes_t bf5xx_pcm_pointer(struct snd_pcm_substream *substream) 144static snd_pcm_uframes_t bf5xx_pcm_pointer(struct snd_pcm_substream *substream)
133{ 145{
146 struct snd_soc_pcm_runtime *rtd = substream->private_data;
134 struct snd_pcm_runtime *runtime = substream->runtime; 147 struct snd_pcm_runtime *runtime = substream->runtime;
135 struct sport_device *sport = runtime->private_data; 148 struct sport_device *sport = runtime->private_data;
136 unsigned int diff; 149 unsigned int diff;
137 snd_pcm_uframes_t frames; 150 snd_pcm_uframes_t frames;
151 struct bf5xx_i2s_pcm_data *dma_data;
152
153 dma_data = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
154
138 pr_debug("%s enter\n", __func__); 155 pr_debug("%s enter\n", __func__);
139 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { 156 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
140 diff = sport_curr_offset_tx(sport); 157 diff = sport_curr_offset_tx(sport);
@@ -151,6 +168,8 @@ static snd_pcm_uframes_t bf5xx_pcm_pointer(struct snd_pcm_substream *substream)
151 diff = 0; 168 diff = 0;
152 169
153 frames = bytes_to_frames(substream->runtime, diff); 170 frames = bytes_to_frames(substream->runtime, diff);
171 if (dma_data->tdm_mode)
172 frames = frames * runtime->channels / 8;
154 173
155 return frames; 174 return frames;
156} 175}
@@ -162,11 +181,18 @@ static int bf5xx_pcm_open(struct snd_pcm_substream *substream)
162 struct sport_device *sport_handle = snd_soc_dai_get_drvdata(cpu_dai); 181 struct sport_device *sport_handle = snd_soc_dai_get_drvdata(cpu_dai);
163 struct snd_pcm_runtime *runtime = substream->runtime; 182 struct snd_pcm_runtime *runtime = substream->runtime;
164 struct snd_dma_buffer *buf = &substream->dma_buffer; 183 struct snd_dma_buffer *buf = &substream->dma_buffer;
184 struct bf5xx_i2s_pcm_data *dma_data;
165 int ret; 185 int ret;
166 186
187 dma_data = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
188
167 pr_debug("%s enter\n", __func__); 189 pr_debug("%s enter\n", __func__);
168 190
169 snd_soc_set_runtime_hwparams(substream, &bf5xx_pcm_hardware); 191 snd_soc_set_runtime_hwparams(substream, &bf5xx_pcm_hardware);
192 if (dma_data->tdm_mode)
193 runtime->hw.buffer_bytes_max /= 4;
194 else
195 runtime->hw.info |= SNDRV_PCM_INFO_MMAP;
170 196
171 ret = snd_pcm_hw_constraint_integer(runtime, 197 ret = snd_pcm_hw_constraint_integer(runtime,
172 SNDRV_PCM_HW_PARAM_PERIODS); 198 SNDRV_PCM_HW_PARAM_PERIODS);
@@ -202,6 +228,88 @@ static int bf5xx_pcm_mmap(struct snd_pcm_substream *substream,
202 return 0 ; 228 return 0 ;
203} 229}
204 230
231static int bf5xx_pcm_copy(struct snd_pcm_substream *substream, int channel,
232 snd_pcm_uframes_t pos, void *buf, snd_pcm_uframes_t count)
233{
234 struct snd_soc_pcm_runtime *rtd = substream->private_data;
235 struct snd_pcm_runtime *runtime = substream->runtime;
236 unsigned int sample_size = runtime->sample_bits / 8;
237 struct bf5xx_i2s_pcm_data *dma_data;
238 unsigned int i;
239 void *src, *dst;
240
241 dma_data = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
242
243 if (dma_data->tdm_mode) {
244 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
245 src = buf;
246 dst = runtime->dma_area;
247 dst += pos * sample_size * 8;
248
249 while (count--) {
250 for (i = 0; i < runtime->channels; i++) {
251 memcpy(dst + dma_data->map[i] *
252 sample_size, src, sample_size);
253 src += sample_size;
254 }
255 dst += 8 * sample_size;
256 }
257 } else {
258 src = runtime->dma_area;
259 src += pos * sample_size * 8;
260 dst = buf;
261
262 while (count--) {
263 for (i = 0; i < runtime->channels; i++) {
264 memcpy(dst, src + dma_data->map[i] *
265 sample_size, sample_size);
266 dst += sample_size;
267 }
268 src += 8 * sample_size;
269 }
270 }
271 } else {
272 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
273 src = buf;
274 dst = runtime->dma_area;
275 dst += frames_to_bytes(runtime, pos);
276 } else {
277 src = runtime->dma_area;
278 src += frames_to_bytes(runtime, pos);
279 dst = buf;
280 }
281
282 memcpy(dst, src, frames_to_bytes(runtime, count));
283 }
284
285 return 0;
286}
287
288static int bf5xx_pcm_silence(struct snd_pcm_substream *substream,
289 int channel, snd_pcm_uframes_t pos, snd_pcm_uframes_t count)
290{
291 struct snd_soc_pcm_runtime *rtd = substream->private_data;
292 struct snd_pcm_runtime *runtime = substream->runtime;
293 unsigned int sample_size = runtime->sample_bits / 8;
294 void *buf = runtime->dma_area;
295 struct bf5xx_i2s_pcm_data *dma_data;
296 unsigned int offset, size;
297
298 dma_data = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
299
300 if (dma_data->tdm_mode) {
301 offset = pos * 8 * sample_size;
302 size = count * 8 * sample_size;
303 } else {
304 offset = frames_to_bytes(runtime, pos);
305 size = frames_to_bytes(runtime, count);
306 }
307
308 snd_pcm_format_set_silence(runtime->format, buf + offset, size);
309
310 return 0;
311}
312
205static struct snd_pcm_ops bf5xx_pcm_i2s_ops = { 313static struct snd_pcm_ops bf5xx_pcm_i2s_ops = {
206 .open = bf5xx_pcm_open, 314 .open = bf5xx_pcm_open,
207 .ioctl = snd_pcm_lib_ioctl, 315 .ioctl = snd_pcm_lib_ioctl,
@@ -211,57 +319,16 @@ static struct snd_pcm_ops bf5xx_pcm_i2s_ops = {
211 .trigger = bf5xx_pcm_trigger, 319 .trigger = bf5xx_pcm_trigger,
212 .pointer = bf5xx_pcm_pointer, 320 .pointer = bf5xx_pcm_pointer,
213 .mmap = bf5xx_pcm_mmap, 321 .mmap = bf5xx_pcm_mmap,
322 .copy = bf5xx_pcm_copy,
323 .silence = bf5xx_pcm_silence,
214}; 324};
215 325
216static int bf5xx_pcm_preallocate_dma_buffer(struct snd_pcm *pcm, int stream)
217{
218 struct snd_pcm_substream *substream = pcm->streams[stream].substream;
219 struct snd_dma_buffer *buf = &substream->dma_buffer;
220 size_t size = bf5xx_pcm_hardware.buffer_bytes_max;
221
222 buf->dev.type = SNDRV_DMA_TYPE_DEV;
223 buf->dev.dev = pcm->card->dev;
224 buf->private_data = NULL;
225 buf->area = dma_alloc_coherent(pcm->card->dev, size,
226 &buf->addr, GFP_KERNEL);
227 if (!buf->area) {
228 pr_err("Failed to allocate dma memory - Please increase uncached DMA memory region\n");
229 return -ENOMEM;
230 }
231 buf->bytes = size;
232
233 pr_debug("%s, area:%p, size:0x%08lx\n", __func__,
234 buf->area, buf->bytes);
235
236 return 0;
237}
238
239static void bf5xx_pcm_free_dma_buffers(struct snd_pcm *pcm)
240{
241 struct snd_pcm_substream *substream;
242 struct snd_dma_buffer *buf;
243 int stream;
244
245 for (stream = 0; stream < 2; stream++) {
246 substream = pcm->streams[stream].substream;
247 if (!substream)
248 continue;
249
250 buf = &substream->dma_buffer;
251 if (!buf->area)
252 continue;
253 dma_free_coherent(NULL, buf->bytes, buf->area, 0);
254 buf->area = NULL;
255 }
256}
257
258static u64 bf5xx_pcm_dmamask = DMA_BIT_MASK(32); 326static u64 bf5xx_pcm_dmamask = DMA_BIT_MASK(32);
259 327
260static int bf5xx_pcm_i2s_new(struct snd_soc_pcm_runtime *rtd) 328static int bf5xx_pcm_i2s_new(struct snd_soc_pcm_runtime *rtd)
261{ 329{
262 struct snd_card *card = rtd->card->snd_card; 330 struct snd_card *card = rtd->card->snd_card;
263 struct snd_pcm *pcm = rtd->pcm; 331 size_t size = bf5xx_pcm_hardware.buffer_bytes_max;
264 int ret = 0;
265 332
266 pr_debug("%s enter\n", __func__); 333 pr_debug("%s enter\n", __func__);
267 if (!card->dev->dma_mask) 334 if (!card->dev->dma_mask)
@@ -269,27 +336,13 @@ static int bf5xx_pcm_i2s_new(struct snd_soc_pcm_runtime *rtd)
269 if (!card->dev->coherent_dma_mask) 336 if (!card->dev->coherent_dma_mask)
270 card->dev->coherent_dma_mask = DMA_BIT_MASK(32); 337 card->dev->coherent_dma_mask = DMA_BIT_MASK(32);
271 338
272 if (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream) { 339 return snd_pcm_lib_preallocate_pages_for_all(rtd->pcm,
273 ret = bf5xx_pcm_preallocate_dma_buffer(pcm, 340 SNDRV_DMA_TYPE_DEV, card->dev, size, size);
274 SNDRV_PCM_STREAM_PLAYBACK);
275 if (ret)
276 goto out;
277 }
278
279 if (pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream) {
280 ret = bf5xx_pcm_preallocate_dma_buffer(pcm,
281 SNDRV_PCM_STREAM_CAPTURE);
282 if (ret)
283 goto out;
284 }
285 out:
286 return ret;
287} 341}
288 342
289static struct snd_soc_platform_driver bf5xx_i2s_soc_platform = { 343static struct snd_soc_platform_driver bf5xx_i2s_soc_platform = {
290 .ops = &bf5xx_pcm_i2s_ops, 344 .ops = &bf5xx_pcm_i2s_ops,
291 .pcm_new = bf5xx_pcm_i2s_new, 345 .pcm_new = bf5xx_pcm_i2s_new,
292 .pcm_free = bf5xx_pcm_free_dma_buffers,
293}; 346};
294 347
295static int bfin_i2s_soc_platform_probe(struct platform_device *pdev) 348static int bfin_i2s_soc_platform_probe(struct platform_device *pdev)
diff --git a/sound/soc/blackfin/bf5xx-i2s-pcm.h b/sound/soc/blackfin/bf5xx-i2s-pcm.h
index 0c2c5a68d4ff..1f0435249f88 100644
--- a/sound/soc/blackfin/bf5xx-i2s-pcm.h
+++ b/sound/soc/blackfin/bf5xx-i2s-pcm.h
@@ -1,26 +1,17 @@
1/* 1/*
2 * linux/sound/arm/bf5xx-i2s-pcm.h -- ALSA PCM interface for the Blackfin
3 *
4 * Copyright 2007 Analog Device Inc.
5 *
6 * This program is free software; you can redistribute it and/or modify 2 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as 3 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation. 4 * published by the Free Software Foundation.
9 */ 5 */
10 6
11#ifndef _BF5XX_I2S_PCM_H 7#ifndef _BF5XX_TDM_PCM_H
12#define _BF5XX_I2S_PCM_H 8#define _BF5XX_TDM_PCM_H
13 9
14struct bf5xx_pcm_dma_params { 10#define BFIN_TDM_DAI_MAX_SLOTS 8
15 char *name; /* stream identifier */
16};
17 11
18struct bf5xx_gpio { 12struct bf5xx_i2s_pcm_data {
19 u32 sys; 13 unsigned int map[BFIN_TDM_DAI_MAX_SLOTS];
20 u32 rx; 14 bool tdm_mode;
21 u32 tx;
22 u32 clk;
23 u32 frm;
24}; 15};
25 16
26#endif 17#endif
diff --git a/sound/soc/blackfin/bf5xx-i2s.c b/sound/soc/blackfin/bf5xx-i2s.c
index dd0c2a4f83a3..9a174fc47d39 100644
--- a/sound/soc/blackfin/bf5xx-i2s.c
+++ b/sound/soc/blackfin/bf5xx-i2s.c
@@ -42,6 +42,7 @@
42#include <linux/gpio.h> 42#include <linux/gpio.h>
43 43
44#include "bf5xx-sport.h" 44#include "bf5xx-sport.h"
45#include "bf5xx-i2s-pcm.h"
45 46
46struct bf5xx_i2s_port { 47struct bf5xx_i2s_port {
47 u16 tcr1; 48 u16 tcr1;
@@ -49,6 +50,13 @@ struct bf5xx_i2s_port {
49 u16 tcr2; 50 u16 tcr2;
50 u16 rcr2; 51 u16 rcr2;
51 int configured; 52 int configured;
53
54 unsigned int slots;
55 unsigned int tx_mask;
56 unsigned int rx_mask;
57
58 struct bf5xx_i2s_pcm_data tx_dma_data;
59 struct bf5xx_i2s_pcm_data rx_dma_data;
52}; 60};
53 61
54static int bf5xx_i2s_set_dai_fmt(struct snd_soc_dai *cpu_dai, 62static int bf5xx_i2s_set_dai_fmt(struct snd_soc_dai *cpu_dai,
@@ -74,7 +82,8 @@ static int bf5xx_i2s_set_dai_fmt(struct snd_soc_dai *cpu_dai,
74 ret = -EINVAL; 82 ret = -EINVAL;
75 break; 83 break;
76 default: 84 default:
77 printk(KERN_ERR "%s: Unknown DAI format type\n", __func__); 85 dev_err(cpu_dai->dev, "%s: Unknown DAI format type\n",
86 __func__);
78 ret = -EINVAL; 87 ret = -EINVAL;
79 break; 88 break;
80 } 89 }
@@ -88,7 +97,8 @@ static int bf5xx_i2s_set_dai_fmt(struct snd_soc_dai *cpu_dai,
88 ret = -EINVAL; 97 ret = -EINVAL;
89 break; 98 break;
90 default: 99 default:
91 printk(KERN_ERR "%s: Unknown DAI master type\n", __func__); 100 dev_err(cpu_dai->dev, "%s: Unknown DAI master type\n",
101 __func__);
92 ret = -EINVAL; 102 ret = -EINVAL;
93 break; 103 break;
94 } 104 }
@@ -141,14 +151,14 @@ static int bf5xx_i2s_hw_params(struct snd_pcm_substream *substream,
141 ret = sport_config_rx(sport_handle, bf5xx_i2s->rcr1, 151 ret = sport_config_rx(sport_handle, bf5xx_i2s->rcr1,
142 bf5xx_i2s->rcr2, 0, 0); 152 bf5xx_i2s->rcr2, 0, 0);
143 if (ret) { 153 if (ret) {
144 pr_err("SPORT is busy!\n"); 154 dev_err(dai->dev, "SPORT is busy!\n");
145 return -EBUSY; 155 return -EBUSY;
146 } 156 }
147 157
148 ret = sport_config_tx(sport_handle, bf5xx_i2s->tcr1, 158 ret = sport_config_tx(sport_handle, bf5xx_i2s->tcr1,
149 bf5xx_i2s->tcr2, 0, 0); 159 bf5xx_i2s->tcr2, 0, 0);
150 if (ret) { 160 if (ret) {
151 pr_err("SPORT is busy!\n"); 161 dev_err(dai->dev, "SPORT is busy!\n");
152 return -EBUSY; 162 return -EBUSY;
153 } 163 }
154 } 164 }
@@ -162,18 +172,76 @@ static void bf5xx_i2s_shutdown(struct snd_pcm_substream *substream,
162 struct sport_device *sport_handle = snd_soc_dai_get_drvdata(dai); 172 struct sport_device *sport_handle = snd_soc_dai_get_drvdata(dai);
163 struct bf5xx_i2s_port *bf5xx_i2s = sport_handle->private_data; 173 struct bf5xx_i2s_port *bf5xx_i2s = sport_handle->private_data;
164 174
165 pr_debug("%s enter\n", __func__); 175 dev_dbg(dai->dev, "%s enter\n", __func__);
166 /* No active stream, SPORT is allowed to be configured again. */ 176 /* No active stream, SPORT is allowed to be configured again. */
167 if (!dai->active) 177 if (!dai->active)
168 bf5xx_i2s->configured = 0; 178 bf5xx_i2s->configured = 0;
169} 179}
170 180
181static int bf5xx_i2s_set_channel_map(struct snd_soc_dai *dai,
182 unsigned int tx_num, unsigned int *tx_slot,
183 unsigned int rx_num, unsigned int *rx_slot)
184{
185 struct sport_device *sport_handle = snd_soc_dai_get_drvdata(dai);
186 struct bf5xx_i2s_port *bf5xx_i2s = sport_handle->private_data;
187 unsigned int tx_mapped = 0, rx_mapped = 0;
188 unsigned int slot;
189 int i;
190
191 if ((tx_num > BFIN_TDM_DAI_MAX_SLOTS) ||
192 (rx_num > BFIN_TDM_DAI_MAX_SLOTS))
193 return -EINVAL;
194
195 for (i = 0; i < tx_num; i++) {
196 slot = tx_slot[i];
197 if ((slot < BFIN_TDM_DAI_MAX_SLOTS) &&
198 (!(tx_mapped & (1 << slot)))) {
199 bf5xx_i2s->tx_dma_data.map[i] = slot;
200 tx_mapped |= 1 << slot;
201 } else
202 return -EINVAL;
203 }
204 for (i = 0; i < rx_num; i++) {
205 slot = rx_slot[i];
206 if ((slot < BFIN_TDM_DAI_MAX_SLOTS) &&
207 (!(rx_mapped & (1 << slot)))) {
208 bf5xx_i2s->rx_dma_data.map[i] = slot;
209 rx_mapped |= 1 << slot;
210 } else
211 return -EINVAL;
212 }
213
214 return 0;
215}
216
217static int bf5xx_i2s_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
218 unsigned int rx_mask, int slots, int width)
219{
220 struct sport_device *sport_handle = snd_soc_dai_get_drvdata(dai);
221 struct bf5xx_i2s_port *bf5xx_i2s = sport_handle->private_data;
222
223 if (slots % 8 != 0 || slots > 8)
224 return -EINVAL;
225
226 if (width != 32)
227 return -EINVAL;
228
229 bf5xx_i2s->slots = slots;
230 bf5xx_i2s->tx_mask = tx_mask;
231 bf5xx_i2s->rx_mask = rx_mask;
232
233 bf5xx_i2s->tx_dma_data.tdm_mode = slots != 0;
234 bf5xx_i2s->rx_dma_data.tdm_mode = slots != 0;
235
236 return sport_set_multichannel(sport_handle, slots, tx_mask, rx_mask, 0);
237}
238
171#ifdef CONFIG_PM 239#ifdef CONFIG_PM
172static int bf5xx_i2s_suspend(struct snd_soc_dai *dai) 240static int bf5xx_i2s_suspend(struct snd_soc_dai *dai)
173{ 241{
174 struct sport_device *sport_handle = snd_soc_dai_get_drvdata(dai); 242 struct sport_device *sport_handle = snd_soc_dai_get_drvdata(dai);
175 243
176 pr_debug("%s : sport %d\n", __func__, dai->id); 244 dev_dbg(dai->dev, "%s : sport %d\n", __func__, dai->id);
177 245
178 if (dai->capture_active) 246 if (dai->capture_active)
179 sport_rx_stop(sport_handle); 247 sport_rx_stop(sport_handle);
@@ -188,23 +256,24 @@ static int bf5xx_i2s_resume(struct snd_soc_dai *dai)
188 struct bf5xx_i2s_port *bf5xx_i2s = sport_handle->private_data; 256 struct bf5xx_i2s_port *bf5xx_i2s = sport_handle->private_data;
189 int ret; 257 int ret;
190 258
191 pr_debug("%s : sport %d\n", __func__, dai->id); 259 dev_dbg(dai->dev, "%s : sport %d\n", __func__, dai->id);
192 260
193 ret = sport_config_rx(sport_handle, bf5xx_i2s->rcr1, 261 ret = sport_config_rx(sport_handle, bf5xx_i2s->rcr1,
194 bf5xx_i2s->rcr2, 0, 0); 262 bf5xx_i2s->rcr2, 0, 0);
195 if (ret) { 263 if (ret) {
196 pr_err("SPORT is busy!\n"); 264 dev_err(dai->dev, "SPORT is busy!\n");
197 return -EBUSY; 265 return -EBUSY;
198 } 266 }
199 267
200 ret = sport_config_tx(sport_handle, bf5xx_i2s->tcr1, 268 ret = sport_config_tx(sport_handle, bf5xx_i2s->tcr1,
201 bf5xx_i2s->tcr2, 0, 0); 269 bf5xx_i2s->tcr2, 0, 0);
202 if (ret) { 270 if (ret) {
203 pr_err("SPORT is busy!\n"); 271 dev_err(dai->dev, "SPORT is busy!\n");
204 return -EBUSY; 272 return -EBUSY;
205 } 273 }
206 274
207 return 0; 275 return sport_set_multichannel(sport_handle, bf5xx_i2s->slots,
276 bf5xx_i2s->tx_mask, bf5xx_i2s->rx_mask, 0);
208} 277}
209 278
210#else 279#else
@@ -212,6 +281,23 @@ static int bf5xx_i2s_resume(struct snd_soc_dai *dai)
212#define bf5xx_i2s_resume NULL 281#define bf5xx_i2s_resume NULL
213#endif 282#endif
214 283
284static int bf5xx_i2s_dai_probe(struct snd_soc_dai *dai)
285{
286 struct sport_device *sport_handle = snd_soc_dai_get_drvdata(dai);
287 struct bf5xx_i2s_port *bf5xx_i2s = sport_handle->private_data;
288 unsigned int i;
289
290 for (i = 0; i < BFIN_TDM_DAI_MAX_SLOTS; i++) {
291 bf5xx_i2s->tx_dma_data.map[i] = i;
292 bf5xx_i2s->rx_dma_data.map[i] = i;
293 }
294
295 dai->playback_dma_data = &bf5xx_i2s->tx_dma_data;
296 dai->capture_dma_data = &bf5xx_i2s->rx_dma_data;
297
298 return 0;
299}
300
215#define BF5XX_I2S_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |\ 301#define BF5XX_I2S_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |\
216 SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 | \ 302 SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 | \
217 SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 | \ 303 SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 | \
@@ -224,22 +310,25 @@ static int bf5xx_i2s_resume(struct snd_soc_dai *dai)
224 SNDRV_PCM_FMTBIT_S32_LE) 310 SNDRV_PCM_FMTBIT_S32_LE)
225 311
226static const struct snd_soc_dai_ops bf5xx_i2s_dai_ops = { 312static const struct snd_soc_dai_ops bf5xx_i2s_dai_ops = {
227 .shutdown = bf5xx_i2s_shutdown, 313 .shutdown = bf5xx_i2s_shutdown,
228 .hw_params = bf5xx_i2s_hw_params, 314 .hw_params = bf5xx_i2s_hw_params,
229 .set_fmt = bf5xx_i2s_set_dai_fmt, 315 .set_fmt = bf5xx_i2s_set_dai_fmt,
316 .set_tdm_slot = bf5xx_i2s_set_tdm_slot,
317 .set_channel_map = bf5xx_i2s_set_channel_map,
230}; 318};
231 319
232static struct snd_soc_dai_driver bf5xx_i2s_dai = { 320static struct snd_soc_dai_driver bf5xx_i2s_dai = {
321 .probe = bf5xx_i2s_dai_probe,
233 .suspend = bf5xx_i2s_suspend, 322 .suspend = bf5xx_i2s_suspend,
234 .resume = bf5xx_i2s_resume, 323 .resume = bf5xx_i2s_resume,
235 .playback = { 324 .playback = {
236 .channels_min = 1, 325 .channels_min = 2,
237 .channels_max = 2, 326 .channels_max = 8,
238 .rates = BF5XX_I2S_RATES, 327 .rates = BF5XX_I2S_RATES,
239 .formats = BF5XX_I2S_FORMATS,}, 328 .formats = BF5XX_I2S_FORMATS,},
240 .capture = { 329 .capture = {
241 .channels_min = 1, 330 .channels_min = 2,
242 .channels_max = 2, 331 .channels_max = 8,
243 .rates = BF5XX_I2S_RATES, 332 .rates = BF5XX_I2S_RATES,
244 .formats = BF5XX_I2S_FORMATS,}, 333 .formats = BF5XX_I2S_FORMATS,},
245 .ops = &bf5xx_i2s_dai_ops, 334 .ops = &bf5xx_i2s_dai_ops,
@@ -255,7 +344,7 @@ static int bf5xx_i2s_probe(struct platform_device *pdev)
255 int ret; 344 int ret;
256 345
257 /* configure SPORT for I2S */ 346 /* configure SPORT for I2S */
258 sport_handle = sport_init(pdev, 4, 2 * sizeof(u32), 347 sport_handle = sport_init(pdev, 4, 8 * sizeof(u32),
259 sizeof(struct bf5xx_i2s_port)); 348 sizeof(struct bf5xx_i2s_port));
260 if (!sport_handle) 349 if (!sport_handle)
261 return -ENODEV; 350 return -ENODEV;
@@ -264,7 +353,7 @@ static int bf5xx_i2s_probe(struct platform_device *pdev)
264 ret = snd_soc_register_component(&pdev->dev, &bf5xx_i2s_component, 353 ret = snd_soc_register_component(&pdev->dev, &bf5xx_i2s_component,
265 &bf5xx_i2s_dai, 1); 354 &bf5xx_i2s_dai, 1);
266 if (ret) { 355 if (ret) {
267 pr_err("Failed to register DAI: %d\n", ret); 356 dev_err(&pdev->dev, "Failed to register DAI: %d\n", ret);
268 sport_done(sport_handle); 357 sport_done(sport_handle);
269 return ret; 358 return ret;
270 } 359 }
@@ -276,7 +365,7 @@ static int bf5xx_i2s_remove(struct platform_device *pdev)
276{ 365{
277 struct sport_device *sport_handle = platform_get_drvdata(pdev); 366 struct sport_device *sport_handle = platform_get_drvdata(pdev);
278 367
279 pr_debug("%s enter\n", __func__); 368 dev_dbg(&pdev->dev, "%s enter\n", __func__);
280 369
281 snd_soc_unregister_component(&pdev->dev); 370 snd_soc_unregister_component(&pdev->dev);
282 sport_done(sport_handle); 371 sport_done(sport_handle);
diff --git a/sound/soc/blackfin/bf5xx-sport.c b/sound/soc/blackfin/bf5xx-sport.c
index 2fd9f2a06968..695351241db8 100644
--- a/sound/soc/blackfin/bf5xx-sport.c
+++ b/sound/soc/blackfin/bf5xx-sport.c
@@ -46,10 +46,10 @@
46/* note: multichannel is in units of 8 channels, 46/* note: multichannel is in units of 8 channels,
47 * tdm_count is # channels NOT / 8 ! */ 47 * tdm_count is # channels NOT / 8 ! */
48int sport_set_multichannel(struct sport_device *sport, 48int sport_set_multichannel(struct sport_device *sport,
49 int tdm_count, u32 mask, int packed) 49 int tdm_count, u32 tx_mask, u32 rx_mask, int packed)
50{ 50{
51 pr_debug("%s tdm_count=%d mask:0x%08x packed=%d\n", __func__, 51 pr_debug("%s tdm_count=%d tx_mask:0x%08x rx_mask:0x%08x packed=%d\n",
52 tdm_count, mask, packed); 52 __func__, tdm_count, tx_mask, rx_mask, packed);
53 53
54 if ((sport->regs->tcr1 & TSPEN) || (sport->regs->rcr1 & RSPEN)) 54 if ((sport->regs->tcr1 & TSPEN) || (sport->regs->rcr1 & RSPEN))
55 return -EBUSY; 55 return -EBUSY;
@@ -65,8 +65,8 @@ int sport_set_multichannel(struct sport_device *sport,
65 sport->regs->mcmc2 = FRAME_DELAY | MCMEN | \ 65 sport->regs->mcmc2 = FRAME_DELAY | MCMEN | \
66 (packed ? (MCDTXPE|MCDRXPE) : 0); 66 (packed ? (MCDTXPE|MCDRXPE) : 0);
67 67
68 sport->regs->mtcs0 = mask; 68 sport->regs->mtcs0 = tx_mask;
69 sport->regs->mrcs0 = mask; 69 sport->regs->mrcs0 = rx_mask;
70 sport->regs->mtcs1 = 0; 70 sport->regs->mtcs1 = 0;
71 sport->regs->mrcs1 = 0; 71 sport->regs->mrcs1 = 0;
72 sport->regs->mtcs2 = 0; 72 sport->regs->mtcs2 = 0;
diff --git a/sound/soc/blackfin/bf5xx-sport.h b/sound/soc/blackfin/bf5xx-sport.h
index 5ab60bd613ea..9fc2192feb3b 100644
--- a/sound/soc/blackfin/bf5xx-sport.h
+++ b/sound/soc/blackfin/bf5xx-sport.h
@@ -128,7 +128,7 @@ void sport_done(struct sport_device *sport);
128/* note: multichannel is in units of 8 channels, tdm_count is number of channels 128/* note: multichannel is in units of 8 channels, tdm_count is number of channels
129 * NOT / 8 ! all channels are enabled by default */ 129 * NOT / 8 ! all channels are enabled by default */
130int sport_set_multichannel(struct sport_device *sport, int tdm_count, 130int sport_set_multichannel(struct sport_device *sport, int tdm_count,
131 u32 mask, int packed); 131 u32 tx_mask, u32 rx_mask, int packed);
132 132
133int sport_config_rx(struct sport_device *sport, 133int sport_config_rx(struct sport_device *sport,
134 unsigned int rcr1, unsigned int rcr2, 134 unsigned int rcr1, unsigned int rcr2,
diff --git a/sound/soc/blackfin/bf5xx-ssm2602.c b/sound/soc/blackfin/bf5xx-ssm2602.c
index 7dbeef1099b4..9c19ccc936e2 100644
--- a/sound/soc/blackfin/bf5xx-ssm2602.c
+++ b/sound/soc/blackfin/bf5xx-ssm2602.c
@@ -40,7 +40,6 @@
40#include <linux/gpio.h> 40#include <linux/gpio.h>
41#include "../codecs/ssm2602.h" 41#include "../codecs/ssm2602.h"
42#include "bf5xx-sport.h" 42#include "bf5xx-sport.h"
43#include "bf5xx-i2s-pcm.h"
44 43
45static struct snd_soc_card bf5xx_ssm2602; 44static struct snd_soc_card bf5xx_ssm2602;
46 45
diff --git a/sound/soc/blackfin/bf5xx-tdm-pcm.c b/sound/soc/blackfin/bf5xx-tdm-pcm.c
deleted file mode 100644
index 0e6b888bb4cc..000000000000
--- a/sound/soc/blackfin/bf5xx-tdm-pcm.c
+++ /dev/null
@@ -1,345 +0,0 @@
1/*
2 * File: sound/soc/blackfin/bf5xx-tdm-pcm.c
3 * Author: Barry Song <Barry.Song@analog.com>
4 *
5 * Created: Tue June 06 2009
6 * Description: DMA driver for tdm codec
7 *
8 * Modified:
9 * Copyright 2009 Analog Devices Inc.
10 *
11 * Bugs: Enter bugs at http://blackfin.uclinux.org/
12 *
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 2 of the License, or
16 * (at your option) any later version.
17 *
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
22 *
23 * You should have received a copy of the GNU General Public License
24 * along with this program; if not, see the file COPYING, or write
25 * to the Free Software Foundation, Inc.,
26 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
27 */
28
29#include <linux/module.h>
30#include <linux/init.h>
31#include <linux/platform_device.h>
32#include <linux/dma-mapping.h>
33#include <linux/gfp.h>
34
35#include <sound/core.h>
36#include <sound/pcm.h>
37#include <sound/pcm_params.h>
38#include <sound/soc.h>
39
40#include <asm/dma.h>
41
42#include "bf5xx-tdm-pcm.h"
43#include "bf5xx-tdm.h"
44#include "bf5xx-sport.h"
45
46#define PCM_BUFFER_MAX 0x8000
47#define FRAGMENT_SIZE_MIN (4*1024)
48#define FRAGMENTS_MIN 2
49#define FRAGMENTS_MAX 32
50
51static void bf5xx_dma_irq(void *data)
52{
53 struct snd_pcm_substream *pcm = data;
54 snd_pcm_period_elapsed(pcm);
55}
56
57static const struct snd_pcm_hardware bf5xx_pcm_hardware = {
58 .info = (SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER |
59 SNDRV_PCM_INFO_RESUME),
60 .formats = SNDRV_PCM_FMTBIT_S32_LE,
61 .rates = SNDRV_PCM_RATE_48000,
62 .channels_min = 2,
63 .channels_max = 8,
64 .buffer_bytes_max = PCM_BUFFER_MAX,
65 .period_bytes_min = FRAGMENT_SIZE_MIN,
66 .period_bytes_max = PCM_BUFFER_MAX/2,
67 .periods_min = FRAGMENTS_MIN,
68 .periods_max = FRAGMENTS_MAX,
69};
70
71static int bf5xx_pcm_hw_params(struct snd_pcm_substream *substream,
72 struct snd_pcm_hw_params *params)
73{
74 size_t size = bf5xx_pcm_hardware.buffer_bytes_max;
75 snd_pcm_lib_malloc_pages(substream, size * 4);
76
77 return 0;
78}
79
80static int bf5xx_pcm_hw_free(struct snd_pcm_substream *substream)
81{
82 snd_pcm_lib_free_pages(substream);
83
84 return 0;
85}
86
87static int bf5xx_pcm_prepare(struct snd_pcm_substream *substream)
88{
89 struct snd_pcm_runtime *runtime = substream->runtime;
90 struct sport_device *sport = runtime->private_data;
91 int fragsize_bytes = frames_to_bytes(runtime, runtime->period_size);
92
93 fragsize_bytes /= runtime->channels;
94 /* inflate the fragsize to match the dma width of SPORT */
95 fragsize_bytes *= 8;
96
97 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
98 sport_set_tx_callback(sport, bf5xx_dma_irq, substream);
99 sport_config_tx_dma(sport, runtime->dma_area,
100 runtime->periods, fragsize_bytes);
101 } else {
102 sport_set_rx_callback(sport, bf5xx_dma_irq, substream);
103 sport_config_rx_dma(sport, runtime->dma_area,
104 runtime->periods, fragsize_bytes);
105 }
106
107 return 0;
108}
109
110static int bf5xx_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
111{
112 struct snd_pcm_runtime *runtime = substream->runtime;
113 struct sport_device *sport = runtime->private_data;
114 int ret = 0;
115
116 switch (cmd) {
117 case SNDRV_PCM_TRIGGER_START:
118 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
119 sport_tx_start(sport);
120 else
121 sport_rx_start(sport);
122 break;
123 case SNDRV_PCM_TRIGGER_STOP:
124 case SNDRV_PCM_TRIGGER_SUSPEND:
125 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
126 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
127 sport_tx_stop(sport);
128 else
129 sport_rx_stop(sport);
130 break;
131 default:
132 ret = -EINVAL;
133 }
134
135 return ret;
136}
137
138static snd_pcm_uframes_t bf5xx_pcm_pointer(struct snd_pcm_substream *substream)
139{
140 struct snd_pcm_runtime *runtime = substream->runtime;
141 struct sport_device *sport = runtime->private_data;
142 unsigned int diff;
143 snd_pcm_uframes_t frames;
144
145 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
146 diff = sport_curr_offset_tx(sport);
147 frames = diff / (8*4); /* 32 bytes per frame */
148 } else {
149 diff = sport_curr_offset_rx(sport);
150 frames = diff / (8*4);
151 }
152 return frames;
153}
154
155static int bf5xx_pcm_open(struct snd_pcm_substream *substream)
156{
157 struct snd_soc_pcm_runtime *rtd = substream->private_data;
158 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
159 struct sport_device *sport_handle = snd_soc_dai_get_drvdata(cpu_dai);
160 struct snd_pcm_runtime *runtime = substream->runtime;
161 struct snd_dma_buffer *buf = &substream->dma_buffer;
162
163 int ret = 0;
164
165 snd_soc_set_runtime_hwparams(substream, &bf5xx_pcm_hardware);
166
167 ret = snd_pcm_hw_constraint_integer(runtime,
168 SNDRV_PCM_HW_PARAM_PERIODS);
169 if (ret < 0)
170 goto out;
171
172 if (sport_handle != NULL) {
173 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
174 sport_handle->tx_buf = buf->area;
175 else
176 sport_handle->rx_buf = buf->area;
177
178 runtime->private_data = sport_handle;
179 } else {
180 pr_err("sport_handle is NULL\n");
181 ret = -ENODEV;
182 }
183out:
184 return ret;
185}
186
187static int bf5xx_pcm_copy(struct snd_pcm_substream *substream, int channel,
188 snd_pcm_uframes_t pos, void *buf, snd_pcm_uframes_t count)
189{
190 struct snd_pcm_runtime *runtime = substream->runtime;
191 struct sport_device *sport = runtime->private_data;
192 struct bf5xx_tdm_port *tdm_port = sport->private_data;
193 unsigned int *src;
194 unsigned int *dst;
195 int i;
196
197 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
198 src = buf;
199 dst = (unsigned int *)substream->runtime->dma_area;
200
201 dst += pos * 8;
202 while (count--) {
203 for (i = 0; i < substream->runtime->channels; i++)
204 *(dst + tdm_port->tx_map[i]) = *src++;
205 dst += 8;
206 }
207 } else {
208 src = (unsigned int *)substream->runtime->dma_area;
209 dst = buf;
210
211 src += pos * 8;
212 while (count--) {
213 for (i = 0; i < substream->runtime->channels; i++)
214 *dst++ = *(src + tdm_port->rx_map[i]);
215 src += 8;
216 }
217 }
218
219 return 0;
220}
221
222static int bf5xx_pcm_silence(struct snd_pcm_substream *substream,
223 int channel, snd_pcm_uframes_t pos, snd_pcm_uframes_t count)
224{
225 unsigned char *buf = substream->runtime->dma_area;
226 buf += pos * 8 * 4;
227 memset(buf, '\0', count * 8 * 4);
228
229 return 0;
230}
231
232
233struct snd_pcm_ops bf5xx_pcm_tdm_ops = {
234 .open = bf5xx_pcm_open,
235 .ioctl = snd_pcm_lib_ioctl,
236 .hw_params = bf5xx_pcm_hw_params,
237 .hw_free = bf5xx_pcm_hw_free,
238 .prepare = bf5xx_pcm_prepare,
239 .trigger = bf5xx_pcm_trigger,
240 .pointer = bf5xx_pcm_pointer,
241 .copy = bf5xx_pcm_copy,
242 .silence = bf5xx_pcm_silence,
243};
244
245static int bf5xx_pcm_preallocate_dma_buffer(struct snd_pcm *pcm, int stream)
246{
247 struct snd_pcm_substream *substream = pcm->streams[stream].substream;
248 struct snd_dma_buffer *buf = &substream->dma_buffer;
249 size_t size = bf5xx_pcm_hardware.buffer_bytes_max;
250
251 buf->dev.type = SNDRV_DMA_TYPE_DEV;
252 buf->dev.dev = pcm->card->dev;
253 buf->private_data = NULL;
254 buf->area = dma_alloc_coherent(pcm->card->dev, size * 4,
255 &buf->addr, GFP_KERNEL);
256 if (!buf->area) {
257 pr_err("Failed to allocate dma memory - Please increase uncached DMA memory region\n");
258 return -ENOMEM;
259 }
260 buf->bytes = size;
261
262 return 0;
263}
264
265static void bf5xx_pcm_free_dma_buffers(struct snd_pcm *pcm)
266{
267 struct snd_pcm_substream *substream;
268 struct snd_dma_buffer *buf;
269 int stream;
270
271 for (stream = 0; stream < 2; stream++) {
272 substream = pcm->streams[stream].substream;
273 if (!substream)
274 continue;
275
276 buf = &substream->dma_buffer;
277 if (!buf->area)
278 continue;
279 dma_free_coherent(NULL, buf->bytes, buf->area, 0);
280 buf->area = NULL;
281 }
282}
283
284static u64 bf5xx_pcm_dmamask = DMA_BIT_MASK(32);
285
286static int bf5xx_pcm_tdm_new(struct snd_soc_pcm_runtime *rtd)
287{
288 struct snd_card *card = rtd->card->snd_card;
289 struct snd_pcm *pcm = rtd->pcm;
290 int ret = 0;
291
292 if (!card->dev->dma_mask)
293 card->dev->dma_mask = &bf5xx_pcm_dmamask;
294 if (!card->dev->coherent_dma_mask)
295 card->dev->coherent_dma_mask = DMA_BIT_MASK(32);
296
297 if (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream) {
298 ret = bf5xx_pcm_preallocate_dma_buffer(pcm,
299 SNDRV_PCM_STREAM_PLAYBACK);
300 if (ret)
301 goto out;
302 }
303
304 if (pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream) {
305 ret = bf5xx_pcm_preallocate_dma_buffer(pcm,
306 SNDRV_PCM_STREAM_CAPTURE);
307 if (ret)
308 goto out;
309 }
310out:
311 return ret;
312}
313
314static struct snd_soc_platform_driver bf5xx_tdm_soc_platform = {
315 .ops = &bf5xx_pcm_tdm_ops,
316 .pcm_new = bf5xx_pcm_tdm_new,
317 .pcm_free = bf5xx_pcm_free_dma_buffers,
318};
319
320static int bf5xx_soc_platform_probe(struct platform_device *pdev)
321{
322 return snd_soc_register_platform(&pdev->dev, &bf5xx_tdm_soc_platform);
323}
324
325static int bf5xx_soc_platform_remove(struct platform_device *pdev)
326{
327 snd_soc_unregister_platform(&pdev->dev);
328 return 0;
329}
330
331static struct platform_driver bfin_tdm_driver = {
332 .driver = {
333 .name = "bfin-tdm-pcm-audio",
334 .owner = THIS_MODULE,
335 },
336
337 .probe = bf5xx_soc_platform_probe,
338 .remove = bf5xx_soc_platform_remove,
339};
340
341module_platform_driver(bfin_tdm_driver);
342
343MODULE_AUTHOR("Barry Song");
344MODULE_DESCRIPTION("ADI Blackfin TDM PCM DMA module");
345MODULE_LICENSE("GPL");
diff --git a/sound/soc/blackfin/bf5xx-tdm-pcm.h b/sound/soc/blackfin/bf5xx-tdm-pcm.h
deleted file mode 100644
index 7f8cc01c4477..000000000000
--- a/sound/soc/blackfin/bf5xx-tdm-pcm.h
+++ /dev/null
@@ -1,18 +0,0 @@
1/*
2 * sound/soc/blackfin/bf5xx-tdm-pcm.h -- ALSA PCM interface for the Blackfin
3 *
4 * Copyright 2009 Analog Device Inc.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 */
10
11#ifndef _BF5XX_TDM_PCM_H
12#define _BF5XX_TDM_PCM_H
13
14struct bf5xx_pcm_dma_params {
15 char *name; /* stream identifier */
16};
17
18#endif
diff --git a/sound/soc/blackfin/bf5xx-tdm.c b/sound/soc/blackfin/bf5xx-tdm.c
deleted file mode 100644
index 69e9a3e935bd..000000000000
--- a/sound/soc/blackfin/bf5xx-tdm.c
+++ /dev/null
@@ -1,328 +0,0 @@
1/*
2 * File: sound/soc/blackfin/bf5xx-tdm.c
3 * Author: Barry Song <Barry.Song@analog.com>
4 *
5 * Created: Thurs June 04 2009
6 * Description: Blackfin I2S(TDM) CPU DAI driver
7 * Even though TDM mode can be as part of I2S DAI, but there
8 * are so much difference in configuration and data flow,
9 * it's very ugly to integrate I2S and TDM into a module
10 *
11 * Modified:
12 * Copyright 2009 Analog Devices Inc.
13 *
14 * Bugs: Enter bugs at http://blackfin.uclinux.org/
15 *
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation; either version 2 of the License, or
19 * (at your option) any later version.
20 *
21 * This program is distributed in the hope that it will be useful,
22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 * GNU General Public License for more details.
25 *
26 * You should have received a copy of the GNU General Public License
27 * along with this program; if not, see the file COPYING, or write
28 * to the Free Software Foundation, Inc.,
29 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
30 */
31
32#include <linux/init.h>
33#include <linux/module.h>
34#include <linux/device.h>
35#include <sound/core.h>
36#include <sound/pcm.h>
37#include <sound/pcm_params.h>
38#include <sound/initval.h>
39#include <sound/soc.h>
40
41#include <asm/irq.h>
42#include <asm/portmux.h>
43#include <linux/mutex.h>
44#include <linux/gpio.h>
45
46#include "bf5xx-sport.h"
47#include "bf5xx-tdm.h"
48
49static int bf5xx_tdm_set_dai_fmt(struct snd_soc_dai *cpu_dai,
50 unsigned int fmt)
51{
52 int ret = 0;
53
54 /* interface format:support TDM,slave mode */
55 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
56 case SND_SOC_DAIFMT_DSP_A:
57 break;
58 default:
59 printk(KERN_ERR "%s: Unknown DAI format type\n", __func__);
60 ret = -EINVAL;
61 break;
62 }
63
64 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
65 case SND_SOC_DAIFMT_CBM_CFM:
66 break;
67 case SND_SOC_DAIFMT_CBS_CFS:
68 case SND_SOC_DAIFMT_CBM_CFS:
69 case SND_SOC_DAIFMT_CBS_CFM:
70 ret = -EINVAL;
71 break;
72 default:
73 printk(KERN_ERR "%s: Unknown DAI master type\n", __func__);
74 ret = -EINVAL;
75 break;
76 }
77
78 return ret;
79}
80
81static int bf5xx_tdm_hw_params(struct snd_pcm_substream *substream,
82 struct snd_pcm_hw_params *params,
83 struct snd_soc_dai *dai)
84{
85 struct sport_device *sport_handle = snd_soc_dai_get_drvdata(dai);
86 struct bf5xx_tdm_port *bf5xx_tdm = sport_handle->private_data;
87 int ret = 0;
88
89 bf5xx_tdm->tcr2 &= ~0x1f;
90 bf5xx_tdm->rcr2 &= ~0x1f;
91 switch (params_format(params)) {
92 case SNDRV_PCM_FORMAT_S32_LE:
93 bf5xx_tdm->tcr2 |= 31;
94 bf5xx_tdm->rcr2 |= 31;
95 sport_handle->wdsize = 4;
96 break;
97 /* at present, we only support 32bit transfer */
98 default:
99 pr_err("not supported PCM format yet\n");
100 return -EINVAL;
101 break;
102 }
103
104 if (!bf5xx_tdm->configured) {
105 /*
106 * TX and RX are not independent,they are enabled at the
107 * same time, even if only one side is running. So, we
108 * need to configure both of them at the time when the first
109 * stream is opened.
110 *
111 * CPU DAI:slave mode.
112 */
113 ret = sport_config_rx(sport_handle, bf5xx_tdm->rcr1,
114 bf5xx_tdm->rcr2, 0, 0);
115 if (ret) {
116 pr_err("SPORT is busy!\n");
117 return -EBUSY;
118 }
119
120 ret = sport_config_tx(sport_handle, bf5xx_tdm->tcr1,
121 bf5xx_tdm->tcr2, 0, 0);
122 if (ret) {
123 pr_err("SPORT is busy!\n");
124 return -EBUSY;
125 }
126
127 bf5xx_tdm->configured = 1;
128 }
129
130 return 0;
131}
132
133static void bf5xx_tdm_shutdown(struct snd_pcm_substream *substream,
134 struct snd_soc_dai *dai)
135{
136 struct sport_device *sport_handle = snd_soc_dai_get_drvdata(dai);
137 struct bf5xx_tdm_port *bf5xx_tdm = sport_handle->private_data;
138
139 /* No active stream, SPORT is allowed to be configured again. */
140 if (!dai->active)
141 bf5xx_tdm->configured = 0;
142}
143
144static int bf5xx_tdm_set_channel_map(struct snd_soc_dai *dai,
145 unsigned int tx_num, unsigned int *tx_slot,
146 unsigned int rx_num, unsigned int *rx_slot)
147{
148 struct sport_device *sport_handle = snd_soc_dai_get_drvdata(dai);
149 struct bf5xx_tdm_port *bf5xx_tdm = sport_handle->private_data;
150 int i;
151 unsigned int slot;
152 unsigned int tx_mapped = 0, rx_mapped = 0;
153
154 if ((tx_num > BFIN_TDM_DAI_MAX_SLOTS) ||
155 (rx_num > BFIN_TDM_DAI_MAX_SLOTS))
156 return -EINVAL;
157
158 for (i = 0; i < tx_num; i++) {
159 slot = tx_slot[i];
160 if ((slot < BFIN_TDM_DAI_MAX_SLOTS) &&
161 (!(tx_mapped & (1 << slot)))) {
162 bf5xx_tdm->tx_map[i] = slot;
163 tx_mapped |= 1 << slot;
164 } else
165 return -EINVAL;
166 }
167 for (i = 0; i < rx_num; i++) {
168 slot = rx_slot[i];
169 if ((slot < BFIN_TDM_DAI_MAX_SLOTS) &&
170 (!(rx_mapped & (1 << slot)))) {
171 bf5xx_tdm->rx_map[i] = slot;
172 rx_mapped |= 1 << slot;
173 } else
174 return -EINVAL;
175 }
176
177 return 0;
178}
179
180#ifdef CONFIG_PM
181static int bf5xx_tdm_suspend(struct snd_soc_dai *dai)
182{
183 struct sport_device *sport = snd_soc_dai_get_drvdata(dai);
184
185 if (dai->playback_active)
186 sport_tx_stop(sport);
187 if (dai->capture_active)
188 sport_rx_stop(sport);
189
190 /* isolate sync/clock pins from codec while sports resume */
191 peripheral_free_list(sport->pin_req);
192
193 return 0;
194}
195
196static int bf5xx_tdm_resume(struct snd_soc_dai *dai)
197{
198 int ret;
199 struct sport_device *sport = snd_soc_dai_get_drvdata(dai);
200
201 ret = sport_set_multichannel(sport, 8, 0xFF, 1);
202 if (ret) {
203 pr_err("SPORT is busy!\n");
204 ret = -EBUSY;
205 }
206
207 ret = sport_config_rx(sport, 0, 0x1F, 0, 0);
208 if (ret) {
209 pr_err("SPORT is busy!\n");
210 ret = -EBUSY;
211 }
212
213 ret = sport_config_tx(sport, 0, 0x1F, 0, 0);
214 if (ret) {
215 pr_err("SPORT is busy!\n");
216 ret = -EBUSY;
217 }
218
219 peripheral_request_list(sport->pin_req, "soc-audio");
220
221 return 0;
222}
223
224#else
225#define bf5xx_tdm_suspend NULL
226#define bf5xx_tdm_resume NULL
227#endif
228
229static const struct snd_soc_dai_ops bf5xx_tdm_dai_ops = {
230 .hw_params = bf5xx_tdm_hw_params,
231 .set_fmt = bf5xx_tdm_set_dai_fmt,
232 .shutdown = bf5xx_tdm_shutdown,
233 .set_channel_map = bf5xx_tdm_set_channel_map,
234};
235
236static struct snd_soc_dai_driver bf5xx_tdm_dai = {
237 .suspend = bf5xx_tdm_suspend,
238 .resume = bf5xx_tdm_resume,
239 .playback = {
240 .channels_min = 2,
241 .channels_max = 8,
242 .rates = SNDRV_PCM_RATE_48000,
243 .formats = SNDRV_PCM_FMTBIT_S32_LE,},
244 .capture = {
245 .channels_min = 2,
246 .channels_max = 8,
247 .rates = SNDRV_PCM_RATE_48000,
248 .formats = SNDRV_PCM_FMTBIT_S32_LE,},
249 .ops = &bf5xx_tdm_dai_ops,
250};
251
252static const struct snd_soc_component_driver bf5xx_tdm_component = {
253 .name = "bf5xx-tdm",
254};
255
256static int bfin_tdm_probe(struct platform_device *pdev)
257{
258 struct sport_device *sport_handle;
259 int ret;
260
261 /* configure SPORT for TDM */
262 sport_handle = sport_init(pdev, 4, 8 * sizeof(u32),
263 sizeof(struct bf5xx_tdm_port));
264 if (!sport_handle)
265 return -ENODEV;
266
267 /* SPORT works in TDM mode */
268 ret = sport_set_multichannel(sport_handle, 8, 0xFF, 1);
269 if (ret) {
270 pr_err("SPORT is busy!\n");
271 ret = -EBUSY;
272 goto sport_config_err;
273 }
274
275 ret = sport_config_rx(sport_handle, 0, 0x1F, 0, 0);
276 if (ret) {
277 pr_err("SPORT is busy!\n");
278 ret = -EBUSY;
279 goto sport_config_err;
280 }
281
282 ret = sport_config_tx(sport_handle, 0, 0x1F, 0, 0);
283 if (ret) {
284 pr_err("SPORT is busy!\n");
285 ret = -EBUSY;
286 goto sport_config_err;
287 }
288
289 ret = snd_soc_register_component(&pdev->dev, &bf5xx_tdm_component,
290 &bf5xx_tdm_dai, 1);
291 if (ret) {
292 pr_err("Failed to register DAI: %d\n", ret);
293 goto sport_config_err;
294 }
295
296 return 0;
297
298sport_config_err:
299 sport_done(sport_handle);
300 return ret;
301}
302
303static int bfin_tdm_remove(struct platform_device *pdev)
304{
305 struct sport_device *sport_handle = platform_get_drvdata(pdev);
306
307 snd_soc_unregister_component(&pdev->dev);
308 sport_done(sport_handle);
309
310 return 0;
311}
312
313static struct platform_driver bfin_tdm_driver = {
314 .probe = bfin_tdm_probe,
315 .remove = bfin_tdm_remove,
316 .driver = {
317 .name = "bfin-tdm",
318 .owner = THIS_MODULE,
319 },
320};
321
322module_platform_driver(bfin_tdm_driver);
323
324/* Module information */
325MODULE_AUTHOR("Barry Song");
326MODULE_DESCRIPTION("TDM driver for ADI Blackfin");
327MODULE_LICENSE("GPL");
328
diff --git a/sound/soc/blackfin/bf5xx-tdm.h b/sound/soc/blackfin/bf5xx-tdm.h
deleted file mode 100644
index e986a3ea3315..000000000000
--- a/sound/soc/blackfin/bf5xx-tdm.h
+++ /dev/null
@@ -1,23 +0,0 @@
1/*
2 * sound/soc/blackfin/bf5xx-tdm.h
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 */
8
9#ifndef _BF5XX_TDM_H
10#define _BF5XX_TDM_H
11
12#define BFIN_TDM_DAI_MAX_SLOTS 8
13struct bf5xx_tdm_port {
14 u16 tcr1;
15 u16 rcr1;
16 u16 tcr2;
17 u16 rcr2;
18 unsigned int tx_map[BFIN_TDM_DAI_MAX_SLOTS];
19 unsigned int rx_map[BFIN_TDM_DAI_MAX_SLOTS];
20 int configured;
21};
22
23#endif
diff --git a/sound/soc/cirrus/Kconfig b/sound/soc/cirrus/Kconfig
index 88143db7e753..2c20f01e1f7e 100644
--- a/sound/soc/cirrus/Kconfig
+++ b/sound/soc/cirrus/Kconfig
@@ -1,7 +1,7 @@
1config SND_EP93XX_SOC 1config SND_EP93XX_SOC
2 tristate "SoC Audio support for the Cirrus Logic EP93xx series" 2 tristate "SoC Audio support for the Cirrus Logic EP93xx series"
3 depends on ARCH_EP93XX && SND_SOC 3 depends on ARCH_EP93XX && SND_SOC
4 select SND_SOC_DMAENGINE_PCM 4 select SND_SOC_GENERIC_DMAENGINE_PCM
5 help 5 help
6 Say Y or M if you want to add support for codecs attached to 6 Say Y or M if you want to add support for codecs attached to
7 the EP93xx I2S or AC97 interfaces. 7 the EP93xx I2S or AC97 interfaces.
diff --git a/sound/soc/cirrus/ep93xx-ac97.c b/sound/soc/cirrus/ep93xx-ac97.c
index 7798fbd5e81d..ac73c607410a 100644
--- a/sound/soc/cirrus/ep93xx-ac97.c
+++ b/sound/soc/cirrus/ep93xx-ac97.c
@@ -237,13 +237,12 @@ static irqreturn_t ep93xx_ac97_interrupt(int irq, void *dev_id)
237 return IRQ_HANDLED; 237 return IRQ_HANDLED;
238} 238}
239 239
240struct snd_ac97_bus_ops soc_ac97_ops = { 240static struct snd_ac97_bus_ops ep93xx_ac97_ops = {
241 .read = ep93xx_ac97_read, 241 .read = ep93xx_ac97_read,
242 .write = ep93xx_ac97_write, 242 .write = ep93xx_ac97_write,
243 .reset = ep93xx_ac97_cold_reset, 243 .reset = ep93xx_ac97_cold_reset,
244 .warm_reset = ep93xx_ac97_warm_reset, 244 .warm_reset = ep93xx_ac97_warm_reset,
245}; 245};
246EXPORT_SYMBOL_GPL(soc_ac97_ops);
247 246
248static int ep93xx_ac97_trigger(struct snd_pcm_substream *substream, 247static int ep93xx_ac97_trigger(struct snd_pcm_substream *substream,
249 int cmd, struct snd_soc_dai *dai) 248 int cmd, struct snd_soc_dai *dai)
@@ -314,22 +313,15 @@ static int ep93xx_ac97_trigger(struct snd_pcm_substream *substream,
314 return 0; 313 return 0;
315} 314}
316 315
317static int ep93xx_ac97_startup(struct snd_pcm_substream *substream, 316static int ep93xx_ac97_dai_probe(struct snd_soc_dai *dai)
318 struct snd_soc_dai *dai)
319{ 317{
320 struct ep93xx_dma_data *dma_data; 318 dai->playback_dma_data = &ep93xx_ac97_pcm_out;
319 dai->capture_dma_data = &ep93xx_ac97_pcm_in;
321 320
322 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
323 dma_data = &ep93xx_ac97_pcm_out;
324 else
325 dma_data = &ep93xx_ac97_pcm_in;
326
327 snd_soc_dai_set_dma_data(dai, substream, dma_data);
328 return 0; 321 return 0;
329} 322}
330 323
331static const struct snd_soc_dai_ops ep93xx_ac97_dai_ops = { 324static const struct snd_soc_dai_ops ep93xx_ac97_dai_ops = {
332 .startup = ep93xx_ac97_startup,
333 .trigger = ep93xx_ac97_trigger, 325 .trigger = ep93xx_ac97_trigger,
334}; 326};
335 327
@@ -337,6 +329,7 @@ static struct snd_soc_dai_driver ep93xx_ac97_dai = {
337 .name = "ep93xx-ac97", 329 .name = "ep93xx-ac97",
338 .id = 0, 330 .id = 0,
339 .ac97_control = 1, 331 .ac97_control = 1,
332 .probe = ep93xx_ac97_dai_probe,
340 .playback = { 333 .playback = {
341 .stream_name = "AC97 Playback", 334 .stream_name = "AC97 Playback",
342 .channels_min = 2, 335 .channels_min = 2,
@@ -395,6 +388,10 @@ static int ep93xx_ac97_probe(struct platform_device *pdev)
395 ep93xx_ac97_info = info; 388 ep93xx_ac97_info = info;
396 platform_set_drvdata(pdev, info); 389 platform_set_drvdata(pdev, info);
397 390
391 ret = snd_soc_set_ac97_ops(&ep93xx_ac97_ops);
392 if (ret)
393 goto fail;
394
398 ret = snd_soc_register_component(&pdev->dev, &ep93xx_ac97_component, 395 ret = snd_soc_register_component(&pdev->dev, &ep93xx_ac97_component,
399 &ep93xx_ac97_dai, 1); 396 &ep93xx_ac97_dai, 1);
400 if (ret) 397 if (ret)
@@ -403,9 +400,8 @@ static int ep93xx_ac97_probe(struct platform_device *pdev)
403 return 0; 400 return 0;
404 401
405fail: 402fail:
406 platform_set_drvdata(pdev, NULL);
407 ep93xx_ac97_info = NULL; 403 ep93xx_ac97_info = NULL;
408 dev_set_drvdata(&pdev->dev, NULL); 404 snd_soc_set_ac97_ops(NULL);
409 return ret; 405 return ret;
410} 406}
411 407
@@ -418,9 +414,9 @@ static int ep93xx_ac97_remove(struct platform_device *pdev)
418 /* disable the AC97 controller */ 414 /* disable the AC97 controller */
419 ep93xx_ac97_write_reg(info, AC97GCR, 0); 415 ep93xx_ac97_write_reg(info, AC97GCR, 0);
420 416
421 platform_set_drvdata(pdev, NULL);
422 ep93xx_ac97_info = NULL; 417 ep93xx_ac97_info = NULL;
423 dev_set_drvdata(&pdev->dev, NULL); 418
419 snd_soc_set_ac97_ops(NULL);
424 420
425 return 0; 421 return 0;
426} 422}
diff --git a/sound/soc/cirrus/ep93xx-i2s.c b/sound/soc/cirrus/ep93xx-i2s.c
index 5c1102e9e159..17ad70bca9fe 100644
--- a/sound/soc/cirrus/ep93xx-i2s.c
+++ b/sound/soc/cirrus/ep93xx-i2s.c
@@ -60,11 +60,10 @@ struct ep93xx_i2s_info {
60 struct clk *mclk; 60 struct clk *mclk;
61 struct clk *sclk; 61 struct clk *sclk;
62 struct clk *lrclk; 62 struct clk *lrclk;
63 struct ep93xx_dma_data *dma_data;
64 void __iomem *regs; 63 void __iomem *regs;
65}; 64};
66 65
67struct ep93xx_dma_data ep93xx_i2s_dma_data[] = { 66static struct ep93xx_dma_data ep93xx_i2s_dma_data[] = {
68 [SNDRV_PCM_STREAM_PLAYBACK] = { 67 [SNDRV_PCM_STREAM_PLAYBACK] = {
69 .name = "i2s-pcm-out", 68 .name = "i2s-pcm-out",
70 .port = EP93XX_DMA_I2S1, 69 .port = EP93XX_DMA_I2S1,
@@ -139,15 +138,11 @@ static void ep93xx_i2s_disable(struct ep93xx_i2s_info *info, int stream)
139 } 138 }
140} 139}
141 140
142static int ep93xx_i2s_startup(struct snd_pcm_substream *substream, 141static int ep93xx_i2s_dai_probe(struct snd_soc_dai *dai)
143 struct snd_soc_dai *dai)
144{ 142{
145 struct snd_soc_pcm_runtime *rtd = substream->private_data; 143 dai->playback_dma_data = &ep93xx_i2s_dma_data[SNDRV_PCM_STREAM_PLAYBACK];
146 struct ep93xx_i2s_info *info = snd_soc_dai_get_drvdata(dai); 144 dai->capture_dma_data = &ep93xx_i2s_dma_data[SNDRV_PCM_STREAM_CAPTURE];
147 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
148 145
149 snd_soc_dai_set_dma_data(cpu_dai, substream,
150 &info->dma_data[substream->stream]);
151 return 0; 146 return 0;
152} 147}
153 148
@@ -338,7 +333,6 @@ static int ep93xx_i2s_resume(struct snd_soc_dai *dai)
338#endif 333#endif
339 334
340static const struct snd_soc_dai_ops ep93xx_i2s_dai_ops = { 335static const struct snd_soc_dai_ops ep93xx_i2s_dai_ops = {
341 .startup = ep93xx_i2s_startup,
342 .shutdown = ep93xx_i2s_shutdown, 336 .shutdown = ep93xx_i2s_shutdown,
343 .hw_params = ep93xx_i2s_hw_params, 337 .hw_params = ep93xx_i2s_hw_params,
344 .set_sysclk = ep93xx_i2s_set_sysclk, 338 .set_sysclk = ep93xx_i2s_set_sysclk,
@@ -349,6 +343,7 @@ static const struct snd_soc_dai_ops ep93xx_i2s_dai_ops = {
349 343
350static struct snd_soc_dai_driver ep93xx_i2s_dai = { 344static struct snd_soc_dai_driver ep93xx_i2s_dai = {
351 .symmetric_rates= 1, 345 .symmetric_rates= 1,
346 .probe = ep93xx_i2s_dai_probe,
352 .suspend = ep93xx_i2s_suspend, 347 .suspend = ep93xx_i2s_suspend,
353 .resume = ep93xx_i2s_resume, 348 .resume = ep93xx_i2s_resume,
354 .playback = { 349 .playback = {
@@ -407,7 +402,6 @@ static int ep93xx_i2s_probe(struct platform_device *pdev)
407 } 402 }
408 403
409 dev_set_drvdata(&pdev->dev, info); 404 dev_set_drvdata(&pdev->dev, info);
410 info->dma_data = ep93xx_i2s_dma_data;
411 405
412 err = snd_soc_register_component(&pdev->dev, &ep93xx_i2s_component, 406 err = snd_soc_register_component(&pdev->dev, &ep93xx_i2s_component,
413 &ep93xx_i2s_dai, 1); 407 &ep93xx_i2s_dai, 1);
diff --git a/sound/soc/cirrus/ep93xx-pcm.c b/sound/soc/cirrus/ep93xx-pcm.c
index 488032690378..0e9f56e0d4b2 100644
--- a/sound/soc/cirrus/ep93xx-pcm.c
+++ b/sound/soc/cirrus/ep93xx-pcm.c
@@ -14,20 +14,14 @@
14 14
15#include <linux/module.h> 15#include <linux/module.h>
16#include <linux/init.h> 16#include <linux/init.h>
17#include <linux/device.h> 17#include <linux/platform_device.h>
18#include <linux/slab.h>
19#include <linux/dmaengine.h> 18#include <linux/dmaengine.h>
20#include <linux/dma-mapping.h>
21 19
22#include <sound/core.h>
23#include <sound/pcm.h> 20#include <sound/pcm.h>
24#include <sound/pcm_params.h>
25#include <sound/soc.h> 21#include <sound/soc.h>
26#include <sound/dmaengine_pcm.h> 22#include <sound/dmaengine_pcm.h>
27 23
28#include <linux/platform_data/dma-ep93xx.h> 24#include <linux/platform_data/dma-ep93xx.h>
29#include <mach/hardware.h>
30#include <mach/ep93xx-regs.h>
31 25
32static const struct snd_pcm_hardware ep93xx_pcm_hardware = { 26static const struct snd_pcm_hardware ep93xx_pcm_hardware = {
33 .info = (SNDRV_PCM_INFO_MMAP | 27 .info = (SNDRV_PCM_INFO_MMAP |
@@ -63,134 +57,24 @@ static bool ep93xx_pcm_dma_filter(struct dma_chan *chan, void *filter_param)
63 return false; 57 return false;
64} 58}
65 59
66static int ep93xx_pcm_open(struct snd_pcm_substream *substream) 60static const struct snd_dmaengine_pcm_config ep93xx_dmaengine_pcm_config = {
67{ 61 .pcm_hardware = &ep93xx_pcm_hardware,
68 struct snd_soc_pcm_runtime *rtd = substream->private_data; 62 .compat_filter_fn = ep93xx_pcm_dma_filter,
69 63 .prealloc_buffer_size = 131072,
70 snd_soc_set_runtime_hwparams(substream, &ep93xx_pcm_hardware);
71
72 return snd_dmaengine_pcm_open_request_chan(substream,
73 ep93xx_pcm_dma_filter,
74 snd_soc_dai_get_dma_data(rtd->cpu_dai, substream));
75}
76
77static int ep93xx_pcm_hw_params(struct snd_pcm_substream *substream,
78 struct snd_pcm_hw_params *params)
79{
80 snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer);
81
82 return 0;
83}
84
85static int ep93xx_pcm_hw_free(struct snd_pcm_substream *substream)
86{
87 snd_pcm_set_runtime_buffer(substream, NULL);
88 return 0;
89}
90
91static int ep93xx_pcm_mmap(struct snd_pcm_substream *substream,
92 struct vm_area_struct *vma)
93{
94 struct snd_pcm_runtime *runtime = substream->runtime;
95
96 return dma_mmap_writecombine(substream->pcm->card->dev, vma,
97 runtime->dma_area,
98 runtime->dma_addr,
99 runtime->dma_bytes);
100}
101
102static struct snd_pcm_ops ep93xx_pcm_ops = {
103 .open = ep93xx_pcm_open,
104 .close = snd_dmaengine_pcm_close_release_chan,
105 .ioctl = snd_pcm_lib_ioctl,
106 .hw_params = ep93xx_pcm_hw_params,
107 .hw_free = ep93xx_pcm_hw_free,
108 .trigger = snd_dmaengine_pcm_trigger,
109 .pointer = snd_dmaengine_pcm_pointer_no_residue,
110 .mmap = ep93xx_pcm_mmap,
111};
112
113static int ep93xx_pcm_preallocate_dma_buffer(struct snd_pcm *pcm, int stream)
114{
115 struct snd_pcm_substream *substream = pcm->streams[stream].substream;
116 struct snd_dma_buffer *buf = &substream->dma_buffer;
117 size_t size = ep93xx_pcm_hardware.buffer_bytes_max;
118
119 buf->dev.type = SNDRV_DMA_TYPE_DEV;
120 buf->dev.dev = pcm->card->dev;
121 buf->private_data = NULL;
122 buf->area = dma_alloc_writecombine(pcm->card->dev, size,
123 &buf->addr, GFP_KERNEL);
124 buf->bytes = size;
125
126 return (buf->area == NULL) ? -ENOMEM : 0;
127}
128
129static void ep93xx_pcm_free_dma_buffers(struct snd_pcm *pcm)
130{
131 struct snd_pcm_substream *substream;
132 struct snd_dma_buffer *buf;
133 int stream;
134
135 for (stream = 0; stream < 2; stream++) {
136 substream = pcm->streams[stream].substream;
137 if (!substream)
138 continue;
139
140 buf = &substream->dma_buffer;
141 if (!buf->area)
142 continue;
143
144 dma_free_writecombine(pcm->card->dev, buf->bytes, buf->area,
145 buf->addr);
146 buf->area = NULL;
147 }
148}
149
150static u64 ep93xx_pcm_dmamask = DMA_BIT_MASK(32);
151
152static int ep93xx_pcm_new(struct snd_soc_pcm_runtime *rtd)
153{
154 struct snd_card *card = rtd->card->snd_card;
155 struct snd_pcm *pcm = rtd->pcm;
156 int ret = 0;
157
158 if (!card->dev->dma_mask)
159 card->dev->dma_mask = &ep93xx_pcm_dmamask;
160 if (!card->dev->coherent_dma_mask)
161 card->dev->coherent_dma_mask = DMA_BIT_MASK(32);
162
163 if (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream) {
164 ret = ep93xx_pcm_preallocate_dma_buffer(pcm,
165 SNDRV_PCM_STREAM_PLAYBACK);
166 if (ret)
167 return ret;
168 }
169
170 if (pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream) {
171 ret = ep93xx_pcm_preallocate_dma_buffer(pcm,
172 SNDRV_PCM_STREAM_CAPTURE);
173 if (ret)
174 return ret;
175 }
176
177 return 0;
178}
179
180static struct snd_soc_platform_driver ep93xx_soc_platform = {
181 .ops = &ep93xx_pcm_ops,
182 .pcm_new = &ep93xx_pcm_new,
183 .pcm_free = &ep93xx_pcm_free_dma_buffers,
184}; 64};
185 65
186static int ep93xx_soc_platform_probe(struct platform_device *pdev) 66static int ep93xx_soc_platform_probe(struct platform_device *pdev)
187{ 67{
188 return snd_soc_register_platform(&pdev->dev, &ep93xx_soc_platform); 68 return snd_dmaengine_pcm_register(&pdev->dev,
69 &ep93xx_dmaengine_pcm_config,
70 SND_DMAENGINE_PCM_FLAG_NO_RESIDUE |
71 SND_DMAENGINE_PCM_FLAG_NO_DT |
72 SND_DMAENGINE_PCM_FLAG_COMPAT);
189} 73}
190 74
191static int ep93xx_soc_platform_remove(struct platform_device *pdev) 75static int ep93xx_soc_platform_remove(struct platform_device *pdev)
192{ 76{
193 snd_soc_unregister_platform(&pdev->dev); 77 snd_dmaengine_pcm_unregister(&pdev->dev);
194 return 0; 78 return 0;
195} 79}
196 80
diff --git a/sound/soc/codecs/88pm860x-codec.c b/sound/soc/codecs/88pm860x-codec.c
index 60159c07448d..8af04343cc1a 100644
--- a/sound/soc/codecs/88pm860x-codec.c
+++ b/sound/soc/codecs/88pm860x-codec.c
@@ -120,10 +120,8 @@
120 * before DAC & PGA in DAPM power-off sequence. 120 * before DAC & PGA in DAPM power-off sequence.
121 */ 121 */
122#define PM860X_DAPM_OUTPUT(wname, wevent) \ 122#define PM860X_DAPM_OUTPUT(wname, wevent) \
123{ .id = snd_soc_dapm_pga, .name = wname, .reg = SND_SOC_NOPM, \ 123 SND_SOC_DAPM_PGA_E(wname, SND_SOC_NOPM, 0, 0, NULL, 0, wevent, \
124 .shift = 0, .invert = 0, .kcontrol_news = NULL, \ 124 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD)
125 .num_kcontrols = 0, .event = wevent, \
126 .event_flags = SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD, }
127 125
128struct pm860x_det { 126struct pm860x_det {
129 struct snd_soc_jack *hp_jack; 127 struct snd_soc_jack *hp_jack;
@@ -1444,7 +1442,7 @@ static int pm860x_codec_probe(struct platform_device *pdev)
1444 res = platform_get_resource(pdev, IORESOURCE_IRQ, i); 1442 res = platform_get_resource(pdev, IORESOURCE_IRQ, i);
1445 if (!res) { 1443 if (!res) {
1446 dev_err(&pdev->dev, "Failed to get IRQ resources\n"); 1444 dev_err(&pdev->dev, "Failed to get IRQ resources\n");
1447 goto out; 1445 return -EINVAL;
1448 } 1446 }
1449 pm860x->irq[i] = res->start + chip->irq_base; 1447 pm860x->irq[i] = res->start + chip->irq_base;
1450 strncpy(pm860x->name[i], res->name, MAX_NAME_LEN); 1448 strncpy(pm860x->name[i], res->name, MAX_NAME_LEN);
@@ -1454,19 +1452,14 @@ static int pm860x_codec_probe(struct platform_device *pdev)
1454 pm860x_dai, ARRAY_SIZE(pm860x_dai)); 1452 pm860x_dai, ARRAY_SIZE(pm860x_dai));
1455 if (ret) { 1453 if (ret) {
1456 dev_err(&pdev->dev, "Failed to register codec\n"); 1454 dev_err(&pdev->dev, "Failed to register codec\n");
1457 goto out; 1455 return -EINVAL;
1458 } 1456 }
1459 return ret; 1457 return ret;
1460
1461out:
1462 platform_set_drvdata(pdev, NULL);
1463 return -EINVAL;
1464} 1458}
1465 1459
1466static int pm860x_codec_remove(struct platform_device *pdev) 1460static int pm860x_codec_remove(struct platform_device *pdev)
1467{ 1461{
1468 snd_soc_unregister_codec(&pdev->dev); 1462 snd_soc_unregister_codec(&pdev->dev);
1469 platform_set_drvdata(pdev, NULL);
1470 return 0; 1463 return 0;
1471} 1464}
1472 1465
diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig
index 2f45f00e31b0..badb6fbacaa6 100644
--- a/sound/soc/codecs/Kconfig
+++ b/sound/soc/codecs/Kconfig
@@ -19,7 +19,7 @@ config SND_SOC_ALL_CODECS
19 select SND_SOC_AD1980 if SND_SOC_AC97_BUS 19 select SND_SOC_AD1980 if SND_SOC_AC97_BUS
20 select SND_SOC_AD73311 20 select SND_SOC_AD73311
21 select SND_SOC_ADAU1373 if I2C 21 select SND_SOC_ADAU1373 if I2C
22 select SND_SOC_ADAV80X 22 select SND_SOC_ADAV80X if SND_SOC_I2C_AND_SPI
23 select SND_SOC_ADS117X 23 select SND_SOC_ADS117X
24 select SND_SOC_AK4104 if SPI_MASTER 24 select SND_SOC_AK4104 if SPI_MASTER
25 select SND_SOC_AK4535 if I2C 25 select SND_SOC_AK4535 if I2C
@@ -40,7 +40,7 @@ config SND_SOC_ALL_CODECS
40 select SND_SOC_DA7213 if I2C 40 select SND_SOC_DA7213 if I2C
41 select SND_SOC_DA732X if I2C 41 select SND_SOC_DA732X if I2C
42 select SND_SOC_DA9055 if I2C 42 select SND_SOC_DA9055 if I2C
43 select SND_SOC_DFBMCS320 43 select SND_SOC_BT_SCO
44 select SND_SOC_ISABELLE if I2C 44 select SND_SOC_ISABELLE if I2C
45 select SND_SOC_JZ4740_CODEC 45 select SND_SOC_JZ4740_CODEC
46 select SND_SOC_LM4857 if I2C 46 select SND_SOC_LM4857 if I2C
@@ -53,13 +53,15 @@ config SND_SOC_ALL_CODECS
53 select SND_SOC_MAX9877 if I2C 53 select SND_SOC_MAX9877 if I2C
54 select SND_SOC_MC13783 if MFD_MC13XXX 54 select SND_SOC_MC13783 if MFD_MC13XXX
55 select SND_SOC_ML26124 if I2C 55 select SND_SOC_ML26124 if I2C
56 select SND_SOC_OMAP_HDMI_CODEC if OMAP4_DSS_HDMI 56 select SND_SOC_HDMI_CODEC
57 select SND_SOC_PCM3008 57 select SND_SOC_PCM3008
58 select SND_SOC_RT5631 if I2C 58 select SND_SOC_RT5631 if I2C
59 select SND_SOC_RT5640 if I2C
59 select SND_SOC_SGTL5000 if I2C 60 select SND_SOC_SGTL5000 if I2C
60 select SND_SOC_SI476X if MFD_SI476X_CORE 61 select SND_SOC_SI476X if MFD_SI476X_CORE
61 select SND_SOC_SN95031 if INTEL_SCU_IPC 62 select SND_SOC_SN95031 if INTEL_SCU_IPC
62 select SND_SOC_SPDIF 63 select SND_SOC_SPDIF
64 select SND_SOC_SSM2518 if I2C
63 select SND_SOC_SSM2602 if SND_SOC_I2C_AND_SPI 65 select SND_SOC_SSM2602 if SND_SOC_I2C_AND_SPI
64 select SND_SOC_STA32X if I2C 66 select SND_SOC_STA32X if I2C
65 select SND_SOC_STA529 if I2C 67 select SND_SOC_STA529 if I2C
@@ -263,7 +265,7 @@ config SND_SOC_DA732X
263config SND_SOC_DA9055 265config SND_SOC_DA9055
264 tristate 266 tristate
265 267
266config SND_SOC_DFBMCS320 268config SND_SOC_BT_SCO
267 tristate 269 tristate
268 270
269config SND_SOC_DMIC 271config SND_SOC_DMIC
@@ -287,7 +289,7 @@ config SND_SOC_MAX98095
287config SND_SOC_MAX9850 289config SND_SOC_MAX9850
288 tristate 290 tristate
289 291
290config SND_SOC_OMAP_HDMI_CODEC 292config SND_SOC_HDMI_CODEC
291 tristate 293 tristate
292 294
293config SND_SOC_PCM3008 295config SND_SOC_PCM3008
@@ -296,6 +298,9 @@ config SND_SOC_PCM3008
296config SND_SOC_RT5631 298config SND_SOC_RT5631
297 tristate 299 tristate
298 300
301config SND_SOC_RT5640
302 tristate
303
299#Freescale sgtl5000 codec 304#Freescale sgtl5000 codec
300config SND_SOC_SGTL5000 305config SND_SOC_SGTL5000
301 tristate 306 tristate
@@ -313,6 +318,9 @@ config SND_SOC_SN95031
313config SND_SOC_SPDIF 318config SND_SOC_SPDIF
314 tristate 319 tristate
315 320
321config SND_SOC_SSM2518
322 tristate
323
316config SND_SOC_SSM2602 324config SND_SOC_SSM2602
317 tristate 325 tristate
318 326
diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile
index b9e41c9a1f4c..70fd8066f546 100644
--- a/sound/soc/codecs/Makefile
+++ b/sound/soc/codecs/Makefile
@@ -27,7 +27,7 @@ snd-soc-da7210-objs := da7210.o
27snd-soc-da7213-objs := da7213.o 27snd-soc-da7213-objs := da7213.o
28snd-soc-da732x-objs := da732x.o 28snd-soc-da732x-objs := da732x.o
29snd-soc-da9055-objs := da9055.o 29snd-soc-da9055-objs := da9055.o
30snd-soc-dfbmcs320-objs := dfbmcs320.o 30snd-soc-bt-sco-objs := bt-sco.o
31snd-soc-dmic-objs := dmic.o 31snd-soc-dmic-objs := dmic.o
32snd-soc-isabelle-objs := isabelle.o 32snd-soc-isabelle-objs := isabelle.o
33snd-soc-jz4740-codec-objs := jz4740.o 33snd-soc-jz4740-codec-objs := jz4740.o
@@ -41,17 +41,19 @@ snd-soc-max98095-objs := max98095.o
41snd-soc-max9850-objs := max9850.o 41snd-soc-max9850-objs := max9850.o
42snd-soc-mc13783-objs := mc13783.o 42snd-soc-mc13783-objs := mc13783.o
43snd-soc-ml26124-objs := ml26124.o 43snd-soc-ml26124-objs := ml26124.o
44snd-soc-omap-hdmi-codec-objs := omap-hdmi.o 44snd-soc-hdmi-codec-objs := hdmi.o
45snd-soc-pcm3008-objs := pcm3008.o 45snd-soc-pcm3008-objs := pcm3008.o
46snd-soc-rt5631-objs := rt5631.o 46snd-soc-rt5631-objs := rt5631.o
47snd-soc-rt5640-objs := rt5640.o
47snd-soc-sgtl5000-objs := sgtl5000.o 48snd-soc-sgtl5000-objs := sgtl5000.o
48snd-soc-alc5623-objs := alc5623.o 49snd-soc-alc5623-objs := alc5623.o
49snd-soc-alc5632-objs := alc5632.o 50snd-soc-alc5632-objs := alc5632.o
50snd-soc-sigmadsp-objs := sigmadsp.o 51snd-soc-sigmadsp-objs := sigmadsp.o
51snd-soc-si476x-objs := si476x.o 52snd-soc-si476x-objs := si476x.o
52snd-soc-sn95031-objs := sn95031.o 53snd-soc-sn95031-objs := sn95031.o
53snd-soc-spdif-tx-objs := spdif_transciever.o 54snd-soc-spdif-tx-objs := spdif_transmitter.o
54snd-soc-spdif-rx-objs := spdif_receiver.o 55snd-soc-spdif-rx-objs := spdif_receiver.o
56snd-soc-ssm2518-objs := ssm2518.o
55snd-soc-ssm2602-objs := ssm2602.o 57snd-soc-ssm2602-objs := ssm2602.o
56snd-soc-sta32x-objs := sta32x.o 58snd-soc-sta32x-objs := sta32x.o
57snd-soc-sta529-objs := sta529.o 59snd-soc-sta529-objs := sta529.o
@@ -154,7 +156,7 @@ obj-$(CONFIG_SND_SOC_DA7210) += snd-soc-da7210.o
154obj-$(CONFIG_SND_SOC_DA7213) += snd-soc-da7213.o 156obj-$(CONFIG_SND_SOC_DA7213) += snd-soc-da7213.o
155obj-$(CONFIG_SND_SOC_DA732X) += snd-soc-da732x.o 157obj-$(CONFIG_SND_SOC_DA732X) += snd-soc-da732x.o
156obj-$(CONFIG_SND_SOC_DA9055) += snd-soc-da9055.o 158obj-$(CONFIG_SND_SOC_DA9055) += snd-soc-da9055.o
157obj-$(CONFIG_SND_SOC_DFBMCS320) += snd-soc-dfbmcs320.o 159obj-$(CONFIG_SND_SOC_BT_SCO) += snd-soc-bt-sco.o
158obj-$(CONFIG_SND_SOC_DMIC) += snd-soc-dmic.o 160obj-$(CONFIG_SND_SOC_DMIC) += snd-soc-dmic.o
159obj-$(CONFIG_SND_SOC_ISABELLE) += snd-soc-isabelle.o 161obj-$(CONFIG_SND_SOC_ISABELLE) += snd-soc-isabelle.o
160obj-$(CONFIG_SND_SOC_JZ4740_CODEC) += snd-soc-jz4740-codec.o 162obj-$(CONFIG_SND_SOC_JZ4740_CODEC) += snd-soc-jz4740-codec.o
@@ -168,14 +170,16 @@ obj-$(CONFIG_SND_SOC_MAX98095) += snd-soc-max98095.o
168obj-$(CONFIG_SND_SOC_MAX9850) += snd-soc-max9850.o 170obj-$(CONFIG_SND_SOC_MAX9850) += snd-soc-max9850.o
169obj-$(CONFIG_SND_SOC_MC13783) += snd-soc-mc13783.o 171obj-$(CONFIG_SND_SOC_MC13783) += snd-soc-mc13783.o
170obj-$(CONFIG_SND_SOC_ML26124) += snd-soc-ml26124.o 172obj-$(CONFIG_SND_SOC_ML26124) += snd-soc-ml26124.o
171obj-$(CONFIG_SND_SOC_OMAP_HDMI_CODEC) += snd-soc-omap-hdmi-codec.o 173obj-$(CONFIG_SND_SOC_HDMI_CODEC) += snd-soc-hdmi-codec.o
172obj-$(CONFIG_SND_SOC_PCM3008) += snd-soc-pcm3008.o 174obj-$(CONFIG_SND_SOC_PCM3008) += snd-soc-pcm3008.o
173obj-$(CONFIG_SND_SOC_RT5631) += snd-soc-rt5631.o 175obj-$(CONFIG_SND_SOC_RT5631) += snd-soc-rt5631.o
176obj-$(CONFIG_SND_SOC_RT5640) += snd-soc-rt5640.o
174obj-$(CONFIG_SND_SOC_SGTL5000) += snd-soc-sgtl5000.o 177obj-$(CONFIG_SND_SOC_SGTL5000) += snd-soc-sgtl5000.o
175obj-$(CONFIG_SND_SOC_SIGMADSP) += snd-soc-sigmadsp.o 178obj-$(CONFIG_SND_SOC_SIGMADSP) += snd-soc-sigmadsp.o
176obj-$(CONFIG_SND_SOC_SI476X) += snd-soc-si476x.o 179obj-$(CONFIG_SND_SOC_SI476X) += snd-soc-si476x.o
177obj-$(CONFIG_SND_SOC_SN95031) +=snd-soc-sn95031.o 180obj-$(CONFIG_SND_SOC_SN95031) +=snd-soc-sn95031.o
178obj-$(CONFIG_SND_SOC_SPDIF) += snd-soc-spdif-rx.o snd-soc-spdif-tx.o 181obj-$(CONFIG_SND_SOC_SPDIF) += snd-soc-spdif-rx.o snd-soc-spdif-tx.o
182obj-$(CONFIG_SND_SOC_SSM2518) += snd-soc-ssm2518.o
179obj-$(CONFIG_SND_SOC_SSM2602) += snd-soc-ssm2602.o 183obj-$(CONFIG_SND_SOC_SSM2602) += snd-soc-ssm2602.o
180obj-$(CONFIG_SND_SOC_STA32X) += snd-soc-sta32x.o 184obj-$(CONFIG_SND_SOC_STA32X) += snd-soc-sta32x.o
181obj-$(CONFIG_SND_SOC_STA529) += snd-soc-sta529.o 185obj-$(CONFIG_SND_SOC_STA529) += snd-soc-sta529.o
diff --git a/sound/soc/codecs/ab8500-codec.c b/sound/soc/codecs/ab8500-codec.c
index a153b168129b..b8ba0adacfce 100644
--- a/sound/soc/codecs/ab8500-codec.c
+++ b/sound/soc/codecs/ab8500-codec.c
@@ -1496,6 +1496,12 @@ static const char * const enum_ad_to_slot_map[] = {"AD_OUT1",
1496 "AD_OUT7", 1496 "AD_OUT7",
1497 "AD_OUT8", 1497 "AD_OUT8",
1498 "zeroes", 1498 "zeroes",
1499 "zeroes",
1500 "zeroes",
1501 "zeroes",
1502 "tristate",
1503 "tristate",
1504 "tristate",
1499 "tristate"}; 1505 "tristate"};
1500static SOC_ENUM_SINGLE_DECL(soc_enum_adslot0map, 1506static SOC_ENUM_SINGLE_DECL(soc_enum_adslot0map,
1501 AB8500_ADSLOTSEL1, AB8500_ADSLOTSELX_EVEN_SHIFT, 1507 AB8500_ADSLOTSEL1, AB8500_ADSLOTSELX_EVEN_SHIFT,
@@ -2230,7 +2236,7 @@ static int ab8500_codec_set_dai_tdm_slot(struct snd_soc_dai *dai,
2230 int slots, int slot_width) 2236 int slots, int slot_width)
2231{ 2237{
2232 struct snd_soc_codec *codec = dai->codec; 2238 struct snd_soc_codec *codec = dai->codec;
2233 unsigned int val, mask, slots_active; 2239 unsigned int val, mask, slot, slots_active;
2234 2240
2235 mask = BIT(AB8500_DIGIFCONF2_IF0WL0) | 2241 mask = BIT(AB8500_DIGIFCONF2_IF0WL0) |
2236 BIT(AB8500_DIGIFCONF2_IF0WL1); 2242 BIT(AB8500_DIGIFCONF2_IF0WL1);
@@ -2286,27 +2292,34 @@ static int ab8500_codec_set_dai_tdm_slot(struct snd_soc_dai *dai,
2286 snd_soc_update_bits(codec, AB8500_DIGIFCONF1, mask, val); 2292 snd_soc_update_bits(codec, AB8500_DIGIFCONF1, mask, val);
2287 2293
2288 /* Setup TDM DA according to active tx slots */ 2294 /* Setup TDM DA according to active tx slots */
2295
2296 if (tx_mask & ~0xff)
2297 return -EINVAL;
2298
2289 mask = AB8500_DASLOTCONFX_SLTODAX_MASK; 2299 mask = AB8500_DASLOTCONFX_SLTODAX_MASK;
2300 tx_mask = tx_mask << AB8500_DA_DATA0_OFFSET;
2290 slots_active = hweight32(tx_mask); 2301 slots_active = hweight32(tx_mask);
2302
2291 dev_dbg(dai->codec->dev, "%s: Slots, active, TX: %d\n", __func__, 2303 dev_dbg(dai->codec->dev, "%s: Slots, active, TX: %d\n", __func__,
2292 slots_active); 2304 slots_active);
2305
2293 switch (slots_active) { 2306 switch (slots_active) {
2294 case 0: 2307 case 0:
2295 break; 2308 break;
2296 case 1: 2309 case 1:
2297 /* Slot 9 -> DA_IN1 & DA_IN3 */ 2310 slot = find_first_bit((unsigned long *)&tx_mask, 32);
2298 snd_soc_update_bits(codec, AB8500_DASLOTCONF1, mask, 11); 2311 snd_soc_update_bits(codec, AB8500_DASLOTCONF1, mask, slot);
2299 snd_soc_update_bits(codec, AB8500_DASLOTCONF3, mask, 11); 2312 snd_soc_update_bits(codec, AB8500_DASLOTCONF3, mask, slot);
2300 snd_soc_update_bits(codec, AB8500_DASLOTCONF2, mask, 11); 2313 snd_soc_update_bits(codec, AB8500_DASLOTCONF2, mask, slot);
2301 snd_soc_update_bits(codec, AB8500_DASLOTCONF4, mask, 11); 2314 snd_soc_update_bits(codec, AB8500_DASLOTCONF4, mask, slot);
2302 break; 2315 break;
2303 case 2: 2316 case 2:
2304 /* Slot 9 -> DA_IN1 & DA_IN3, Slot 11 -> DA_IN2 & DA_IN4 */ 2317 slot = find_first_bit((unsigned long *)&tx_mask, 32);
2305 snd_soc_update_bits(codec, AB8500_DASLOTCONF1, mask, 9); 2318 snd_soc_update_bits(codec, AB8500_DASLOTCONF1, mask, slot);
2306 snd_soc_update_bits(codec, AB8500_DASLOTCONF3, mask, 9); 2319 snd_soc_update_bits(codec, AB8500_DASLOTCONF3, mask, slot);
2307 snd_soc_update_bits(codec, AB8500_DASLOTCONF2, mask, 11); 2320 slot = find_next_bit((unsigned long *)&tx_mask, 32, slot + 1);
2308 snd_soc_update_bits(codec, AB8500_DASLOTCONF4, mask, 11); 2321 snd_soc_update_bits(codec, AB8500_DASLOTCONF2, mask, slot);
2309 2322 snd_soc_update_bits(codec, AB8500_DASLOTCONF4, mask, slot);
2310 break; 2323 break;
2311 case 8: 2324 case 8:
2312 dev_dbg(dai->codec->dev, 2325 dev_dbg(dai->codec->dev,
@@ -2321,25 +2334,36 @@ static int ab8500_codec_set_dai_tdm_slot(struct snd_soc_dai *dai,
2321 } 2334 }
2322 2335
2323 /* Setup TDM AD according to active RX-slots */ 2336 /* Setup TDM AD according to active RX-slots */
2337
2338 if (rx_mask & ~0xff)
2339 return -EINVAL;
2340
2341 rx_mask = rx_mask << AB8500_AD_DATA0_OFFSET;
2324 slots_active = hweight32(rx_mask); 2342 slots_active = hweight32(rx_mask);
2343
2325 dev_dbg(dai->codec->dev, "%s: Slots, active, RX: %d\n", __func__, 2344 dev_dbg(dai->codec->dev, "%s: Slots, active, RX: %d\n", __func__,
2326 slots_active); 2345 slots_active);
2346
2327 switch (slots_active) { 2347 switch (slots_active) {
2328 case 0: 2348 case 0:
2329 break; 2349 break;
2330 case 1: 2350 case 1:
2331 /* AD_OUT3 -> slot 0 & 1 */ 2351 slot = find_first_bit((unsigned long *)&rx_mask, 32);
2332 snd_soc_update_bits(codec, AB8500_ADSLOTSEL1, AB8500_MASK_ALL, 2352 snd_soc_update_bits(codec, AB8500_ADSLOTSEL(slot),
2333 AB8500_ADSLOTSELX_AD_OUT3_TO_SLOT_EVEN | 2353 AB8500_MASK_SLOT(slot),
2334 AB8500_ADSLOTSELX_AD_OUT3_TO_SLOT_ODD); 2354 AB8500_ADSLOTSELX_AD_OUT_TO_SLOT(AB8500_AD_OUT3, slot));
2335 break; 2355 break;
2336 case 2: 2356 case 2:
2337 /* AD_OUT3 -> slot 0, AD_OUT2 -> slot 1 */ 2357 slot = find_first_bit((unsigned long *)&rx_mask, 32);
2338 snd_soc_update_bits(codec, 2358 snd_soc_update_bits(codec,
2339 AB8500_ADSLOTSEL1, 2359 AB8500_ADSLOTSEL(slot),
2340 AB8500_MASK_ALL, 2360 AB8500_MASK_SLOT(slot),
2341 AB8500_ADSLOTSELX_AD_OUT3_TO_SLOT_EVEN | 2361 AB8500_ADSLOTSELX_AD_OUT_TO_SLOT(AB8500_AD_OUT3, slot));
2342 AB8500_ADSLOTSELX_AD_OUT2_TO_SLOT_ODD); 2362 slot = find_next_bit((unsigned long *)&rx_mask, 32, slot + 1);
2363 snd_soc_update_bits(codec,
2364 AB8500_ADSLOTSEL(slot),
2365 AB8500_MASK_SLOT(slot),
2366 AB8500_ADSLOTSELX_AD_OUT_TO_SLOT(AB8500_AD_OUT2, slot));
2343 break; 2367 break;
2344 case 8: 2368 case 8:
2345 dev_dbg(dai->codec->dev, 2369 dev_dbg(dai->codec->dev,
@@ -2356,6 +2380,11 @@ static int ab8500_codec_set_dai_tdm_slot(struct snd_soc_dai *dai,
2356 return 0; 2380 return 0;
2357} 2381}
2358 2382
2383static const struct snd_soc_dai_ops ab8500_codec_ops = {
2384 .set_fmt = ab8500_codec_set_dai_fmt,
2385 .set_tdm_slot = ab8500_codec_set_dai_tdm_slot,
2386};
2387
2359static struct snd_soc_dai_driver ab8500_codec_dai[] = { 2388static struct snd_soc_dai_driver ab8500_codec_dai[] = {
2360 { 2389 {
2361 .name = "ab8500-codec-dai.0", 2390 .name = "ab8500-codec-dai.0",
@@ -2367,12 +2396,7 @@ static struct snd_soc_dai_driver ab8500_codec_dai[] = {
2367 .rates = AB8500_SUPPORTED_RATE, 2396 .rates = AB8500_SUPPORTED_RATE,
2368 .formats = AB8500_SUPPORTED_FMT, 2397 .formats = AB8500_SUPPORTED_FMT,
2369 }, 2398 },
2370 .ops = (struct snd_soc_dai_ops[]) { 2399 .ops = &ab8500_codec_ops,
2371 {
2372 .set_tdm_slot = ab8500_codec_set_dai_tdm_slot,
2373 .set_fmt = ab8500_codec_set_dai_fmt,
2374 }
2375 },
2376 .symmetric_rates = 1 2400 .symmetric_rates = 1
2377 }, 2401 },
2378 { 2402 {
@@ -2385,12 +2409,7 @@ static struct snd_soc_dai_driver ab8500_codec_dai[] = {
2385 .rates = AB8500_SUPPORTED_RATE, 2409 .rates = AB8500_SUPPORTED_RATE,
2386 .formats = AB8500_SUPPORTED_FMT, 2410 .formats = AB8500_SUPPORTED_FMT,
2387 }, 2411 },
2388 .ops = (struct snd_soc_dai_ops[]) { 2412 .ops = &ab8500_codec_ops,
2389 {
2390 .set_tdm_slot = ab8500_codec_set_dai_tdm_slot,
2391 .set_fmt = ab8500_codec_set_dai_fmt,
2392 }
2393 },
2394 .symmetric_rates = 1 2413 .symmetric_rates = 1
2395 } 2414 }
2396}; 2415};
diff --git a/sound/soc/codecs/ab8500-codec.h b/sound/soc/codecs/ab8500-codec.h
index 306d0bc8455f..e2e54425d25e 100644
--- a/sound/soc/codecs/ab8500-codec.h
+++ b/sound/soc/codecs/ab8500-codec.h
@@ -24,6 +24,13 @@
24#define AB8500_SUPPORTED_RATE (SNDRV_PCM_RATE_48000) 24#define AB8500_SUPPORTED_RATE (SNDRV_PCM_RATE_48000)
25#define AB8500_SUPPORTED_FMT (SNDRV_PCM_FMTBIT_S16_LE) 25#define AB8500_SUPPORTED_FMT (SNDRV_PCM_FMTBIT_S16_LE)
26 26
27/* AB8500 interface slot offset definitions */
28
29#define AB8500_AD_DATA0_OFFSET 0
30#define AB8500_DA_DATA0_OFFSET 8
31#define AB8500_AD_DATA1_OFFSET 16
32#define AB8500_DA_DATA1_OFFSET 24
33
27/* AB8500 audio bank (0x0d) register definitions */ 34/* AB8500 audio bank (0x0d) register definitions */
28 35
29#define AB8500_POWERUP 0x00 36#define AB8500_POWERUP 0x00
@@ -73,6 +80,7 @@
73#define AB8500_ADSLOTSEL14 0x2C 80#define AB8500_ADSLOTSEL14 0x2C
74#define AB8500_ADSLOTSEL15 0x2D 81#define AB8500_ADSLOTSEL15 0x2D
75#define AB8500_ADSLOTSEL16 0x2E 82#define AB8500_ADSLOTSEL16 0x2E
83#define AB8500_ADSLOTSEL(slot) (AB8500_ADSLOTSEL1 + (slot >> 1))
76#define AB8500_ADSLOTHIZCTRL1 0x2F 84#define AB8500_ADSLOTHIZCTRL1 0x2F
77#define AB8500_ADSLOTHIZCTRL2 0x30 85#define AB8500_ADSLOTHIZCTRL2 0x30
78#define AB8500_ADSLOTHIZCTRL3 0x31 86#define AB8500_ADSLOTHIZCTRL3 0x31
@@ -144,6 +152,7 @@
144#define AB8500_CACHEREGNUM (AB8500_LAST_REG + 1) 152#define AB8500_CACHEREGNUM (AB8500_LAST_REG + 1)
145 153
146#define AB8500_MASK_ALL 0xFF 154#define AB8500_MASK_ALL 0xFF
155#define AB8500_MASK_SLOT(slot) ((slot & 1) ? 0xF0 : 0x0F)
147#define AB8500_MASK_NONE 0x00 156#define AB8500_MASK_NONE 0x00
148 157
149/* AB8500_POWERUP */ 158/* AB8500_POWERUP */
@@ -347,28 +356,21 @@
347#define AB8500_DIGIFCONF4_IF1WL0 0 356#define AB8500_DIGIFCONF4_IF1WL0 0
348 357
349/* AB8500_ADSLOTSELX */ 358/* AB8500_ADSLOTSELX */
350#define AB8500_ADSLOTSELX_AD_OUT1_TO_SLOT_ODD 0x00 359#define AB8500_AD_OUT1 0x0
351#define AB8500_ADSLOTSELX_AD_OUT2_TO_SLOT_ODD 0x10 360#define AB8500_AD_OUT2 0x1
352#define AB8500_ADSLOTSELX_AD_OUT3_TO_SLOT_ODD 0x20 361#define AB8500_AD_OUT3 0x2
353#define AB8500_ADSLOTSELX_AD_OUT4_TO_SLOT_ODD 0x30 362#define AB8500_AD_OUT4 0x3
354#define AB8500_ADSLOTSELX_AD_OUT5_TO_SLOT_ODD 0x40 363#define AB8500_AD_OUT5 0x4
355#define AB8500_ADSLOTSELX_AD_OUT6_TO_SLOT_ODD 0x50 364#define AB8500_AD_OUT6 0x5
356#define AB8500_ADSLOTSELX_AD_OUT7_TO_SLOT_ODD 0x60 365#define AB8500_AD_OUT7 0x6
357#define AB8500_ADSLOTSELX_AD_OUT8_TO_SLOT_ODD 0x70 366#define AB8500_AD_OUT8 0x7
358#define AB8500_ADSLOTSELX_ZEROES_TO_SLOT_ODD 0x80 367#define AB8500_ZEROES 0x8
359#define AB8500_ADSLOTSELX_TRISTATE_TO_SLOT_ODD 0xF0 368#define AB8500_TRISTATE 0xF
360#define AB8500_ADSLOTSELX_AD_OUT1_TO_SLOT_EVEN 0x00
361#define AB8500_ADSLOTSELX_AD_OUT2_TO_SLOT_EVEN 0x01
362#define AB8500_ADSLOTSELX_AD_OUT3_TO_SLOT_EVEN 0x02
363#define AB8500_ADSLOTSELX_AD_OUT4_TO_SLOT_EVEN 0x03
364#define AB8500_ADSLOTSELX_AD_OUT5_TO_SLOT_EVEN 0x04
365#define AB8500_ADSLOTSELX_AD_OUT6_TO_SLOT_EVEN 0x05
366#define AB8500_ADSLOTSELX_AD_OUT7_TO_SLOT_EVEN 0x06
367#define AB8500_ADSLOTSELX_AD_OUT8_TO_SLOT_EVEN 0x07
368#define AB8500_ADSLOTSELX_ZEROES_TO_SLOT_EVEN 0x08
369#define AB8500_ADSLOTSELX_TRISTATE_TO_SLOT_EVEN 0x0F
370#define AB8500_ADSLOTSELX_EVEN_SHIFT 0 369#define AB8500_ADSLOTSELX_EVEN_SHIFT 0
371#define AB8500_ADSLOTSELX_ODD_SHIFT 4 370#define AB8500_ADSLOTSELX_ODD_SHIFT 4
371#define AB8500_ADSLOTSELX_AD_OUT_TO_SLOT(out, slot) \
372 ((out) << (((slot) & 1) ? \
373 AB8500_ADSLOTSELX_ODD_SHIFT : AB8500_ADSLOTSELX_EVEN_SHIFT))
372 374
373/* AB8500_ADSLOTHIZCTRL1 */ 375/* AB8500_ADSLOTHIZCTRL1 */
374/* AB8500_ADSLOTHIZCTRL2 */ 376/* AB8500_ADSLOTHIZCTRL2 */
diff --git a/sound/soc/codecs/ac97.c b/sound/soc/codecs/ac97.c
index ef2ae32ffc66..ec7351803c24 100644
--- a/sound/soc/codecs/ac97.c
+++ b/sound/soc/codecs/ac97.c
@@ -62,13 +62,13 @@ static struct snd_soc_dai_driver ac97_dai = {
62static unsigned int ac97_read(struct snd_soc_codec *codec, 62static unsigned int ac97_read(struct snd_soc_codec *codec,
63 unsigned int reg) 63 unsigned int reg)
64{ 64{
65 return soc_ac97_ops.read(codec->ac97, reg); 65 return soc_ac97_ops->read(codec->ac97, reg);
66} 66}
67 67
68static int ac97_write(struct snd_soc_codec *codec, unsigned int reg, 68static int ac97_write(struct snd_soc_codec *codec, unsigned int reg,
69 unsigned int val) 69 unsigned int val)
70{ 70{
71 soc_ac97_ops.write(codec->ac97, reg, val); 71 soc_ac97_ops->write(codec->ac97, reg, val);
72 return 0; 72 return 0;
73} 73}
74 74
@@ -79,7 +79,8 @@ static int ac97_soc_probe(struct snd_soc_codec *codec)
79 int ret; 79 int ret;
80 80
81 /* add codec as bus device for standard ac97 */ 81 /* add codec as bus device for standard ac97 */
82 ret = snd_ac97_bus(codec->card->snd_card, 0, &soc_ac97_ops, NULL, &ac97_bus); 82 ret = snd_ac97_bus(codec->card->snd_card, 0, soc_ac97_ops, NULL,
83 &ac97_bus);
83 if (ret < 0) 84 if (ret < 0)
84 return ret; 85 return ret;
85 86
diff --git a/sound/soc/codecs/ad1980.c b/sound/soc/codecs/ad1980.c
index f385342947d3..89fcf7d6e7b8 100644
--- a/sound/soc/codecs/ad1980.c
+++ b/sound/soc/codecs/ad1980.c
@@ -108,7 +108,7 @@ static unsigned int ac97_read(struct snd_soc_codec *codec,
108 case AC97_EXTENDED_STATUS: 108 case AC97_EXTENDED_STATUS:
109 case AC97_VENDOR_ID1: 109 case AC97_VENDOR_ID1:
110 case AC97_VENDOR_ID2: 110 case AC97_VENDOR_ID2:
111 return soc_ac97_ops.read(codec->ac97, reg); 111 return soc_ac97_ops->read(codec->ac97, reg);
112 default: 112 default:
113 reg = reg >> 1; 113 reg = reg >> 1;
114 114
@@ -124,7 +124,7 @@ static int ac97_write(struct snd_soc_codec *codec, unsigned int reg,
124{ 124{
125 u16 *cache = codec->reg_cache; 125 u16 *cache = codec->reg_cache;
126 126
127 soc_ac97_ops.write(codec->ac97, reg, val); 127 soc_ac97_ops->write(codec->ac97, reg, val);
128 reg = reg >> 1; 128 reg = reg >> 1;
129 if (reg < ARRAY_SIZE(ad1980_reg)) 129 if (reg < ARRAY_SIZE(ad1980_reg))
130 cache[reg] = val; 130 cache[reg] = val;
@@ -154,13 +154,13 @@ static int ad1980_reset(struct snd_soc_codec *codec, int try_warm)
154 u16 retry_cnt = 0; 154 u16 retry_cnt = 0;
155 155
156retry: 156retry:
157 if (try_warm && soc_ac97_ops.warm_reset) { 157 if (try_warm && soc_ac97_ops->warm_reset) {
158 soc_ac97_ops.warm_reset(codec->ac97); 158 soc_ac97_ops->warm_reset(codec->ac97);
159 if (ac97_read(codec, AC97_RESET) == 0x0090) 159 if (ac97_read(codec, AC97_RESET) == 0x0090)
160 return 1; 160 return 1;
161 } 161 }
162 162
163 soc_ac97_ops.reset(codec->ac97); 163 soc_ac97_ops->reset(codec->ac97);
164 /* Set bit 16slot in register 74h, then every slot will has only 16 164 /* Set bit 16slot in register 74h, then every slot will has only 16
165 * bits. This command is sent out in 20bit mode, in which case the 165 * bits. This command is sent out in 20bit mode, in which case the
166 * first nibble of data is eaten by the addr. (Tag is always 16 bit)*/ 166 * first nibble of data is eaten by the addr. (Tag is always 16 bit)*/
@@ -186,7 +186,7 @@ static int ad1980_soc_probe(struct snd_soc_codec *codec)
186 186
187 printk(KERN_INFO "AD1980 SoC Audio Codec\n"); 187 printk(KERN_INFO "AD1980 SoC Audio Codec\n");
188 188
189 ret = snd_soc_new_ac97_codec(codec, &soc_ac97_ops, 0); 189 ret = snd_soc_new_ac97_codec(codec, soc_ac97_ops, 0);
190 if (ret < 0) { 190 if (ret < 0) {
191 printk(KERN_ERR "ad1980: failed to register AC97 codec\n"); 191 printk(KERN_ERR "ad1980: failed to register AC97 codec\n");
192 return ret; 192 return ret;
diff --git a/sound/soc/codecs/adau1701.c b/sound/soc/codecs/adau1701.c
index dafdbe87edeb..d1124a5b3471 100644
--- a/sound/soc/codecs/adau1701.c
+++ b/sound/soc/codecs/adau1701.c
@@ -13,6 +13,10 @@
13#include <linux/i2c.h> 13#include <linux/i2c.h>
14#include <linux/delay.h> 14#include <linux/delay.h>
15#include <linux/slab.h> 15#include <linux/slab.h>
16#include <linux/of.h>
17#include <linux/of_gpio.h>
18#include <linux/of_device.h>
19#include <linux/regmap.h>
16#include <sound/core.h> 20#include <sound/core.h>
17#include <sound/pcm.h> 21#include <sound/pcm.h>
18#include <sound/pcm_params.h> 22#include <sound/pcm_params.h>
@@ -21,16 +25,19 @@
21#include "sigmadsp.h" 25#include "sigmadsp.h"
22#include "adau1701.h" 26#include "adau1701.h"
23 27
24#define ADAU1701_DSPCTRL 0x1c 28#define ADAU1701_DSPCTRL 0x081c
25#define ADAU1701_SEROCTL 0x1e 29#define ADAU1701_SEROCTL 0x081e
26#define ADAU1701_SERICTL 0x1f 30#define ADAU1701_SERICTL 0x081f
27 31
28#define ADAU1701_AUXNPOW 0x22 32#define ADAU1701_AUXNPOW 0x0822
33#define ADAU1701_PINCONF_0 0x0820
34#define ADAU1701_PINCONF_1 0x0821
35#define ADAU1701_AUXNPOW 0x0822
29 36
30#define ADAU1701_OSCIPOW 0x26 37#define ADAU1701_OSCIPOW 0x0826
31#define ADAU1701_DACSET 0x27 38#define ADAU1701_DACSET 0x0827
32 39
33#define ADAU1701_NUM_REGS 0x28 40#define ADAU1701_MAX_REGISTER 0x0828
34 41
35#define ADAU1701_DSPCTRL_CR (1 << 2) 42#define ADAU1701_DSPCTRL_CR (1 << 2)
36#define ADAU1701_DSPCTRL_DAM (1 << 3) 43#define ADAU1701_DSPCTRL_DAM (1 << 3)
@@ -84,10 +91,18 @@
84#define ADAU1701_OSCIPOW_OPD 0x04 91#define ADAU1701_OSCIPOW_OPD 0x04
85#define ADAU1701_DACSET_DACINIT 1 92#define ADAU1701_DACSET_DACINIT 1
86 93
94#define ADAU1707_CLKDIV_UNSET (-1UL)
95
87#define ADAU1701_FIRMWARE "adau1701.bin" 96#define ADAU1701_FIRMWARE "adau1701.bin"
88 97
89struct adau1701 { 98struct adau1701 {
99 int gpio_nreset;
100 int gpio_pll_mode[2];
90 unsigned int dai_fmt; 101 unsigned int dai_fmt;
102 unsigned int pll_clkdiv;
103 unsigned int sysclk;
104 struct regmap *regmap;
105 u8 pin_config[12];
91}; 106};
92 107
93static const struct snd_kcontrol_new adau1701_controls[] = { 108static const struct snd_kcontrol_new adau1701_controls[] = {
@@ -119,10 +134,13 @@ static const struct snd_soc_dapm_route adau1701_dapm_routes[] = {
119 { "ADC", NULL, "IN1" }, 134 { "ADC", NULL, "IN1" },
120}; 135};
121 136
122static unsigned int adau1701_register_size(struct snd_soc_codec *codec, 137static unsigned int adau1701_register_size(struct device *dev,
123 unsigned int reg) 138 unsigned int reg)
124{ 139{
125 switch (reg) { 140 switch (reg) {
141 case ADAU1701_PINCONF_0:
142 case ADAU1701_PINCONF_1:
143 return 3;
126 case ADAU1701_DSPCTRL: 144 case ADAU1701_DSPCTRL:
127 case ADAU1701_SEROCTL: 145 case ADAU1701_SEROCTL:
128 case ADAU1701_AUXNPOW: 146 case ADAU1701_AUXNPOW:
@@ -133,33 +151,42 @@ static unsigned int adau1701_register_size(struct snd_soc_codec *codec,
133 return 1; 151 return 1;
134 } 152 }
135 153
136 dev_err(codec->dev, "Unsupported register address: %d\n", reg); 154 dev_err(dev, "Unsupported register address: %d\n", reg);
137 return 0; 155 return 0;
138} 156}
139 157
140static int adau1701_write(struct snd_soc_codec *codec, unsigned int reg, 158static bool adau1701_volatile_reg(struct device *dev, unsigned int reg)
141 unsigned int value) 159{
160 switch (reg) {
161 case ADAU1701_DACSET:
162 return true;
163 default:
164 return false;
165 }
166}
167
168static int adau1701_reg_write(void *context, unsigned int reg,
169 unsigned int value)
142{ 170{
171 struct i2c_client *client = context;
143 unsigned int i; 172 unsigned int i;
144 unsigned int size; 173 unsigned int size;
145 uint8_t buf[4]; 174 uint8_t buf[5];
146 int ret; 175 int ret;
147 176
148 size = adau1701_register_size(codec, reg); 177 size = adau1701_register_size(&client->dev, reg);
149 if (size == 0) 178 if (size == 0)
150 return -EINVAL; 179 return -EINVAL;
151 180
152 snd_soc_cache_write(codec, reg, value); 181 buf[0] = reg >> 8;
153 182 buf[1] = reg & 0xff;
154 buf[0] = 0x08;
155 buf[1] = reg;
156 183
157 for (i = size + 1; i >= 2; --i) { 184 for (i = size + 1; i >= 2; --i) {
158 buf[i] = value; 185 buf[i] = value;
159 value >>= 8; 186 value >>= 8;
160 } 187 }
161 188
162 ret = i2c_master_send(to_i2c_client(codec->dev), buf, size + 2); 189 ret = i2c_master_send(client, buf, size + 2);
163 if (ret == size + 2) 190 if (ret == size + 2)
164 return 0; 191 return 0;
165 else if (ret < 0) 192 else if (ret < 0)
@@ -168,21 +195,107 @@ static int adau1701_write(struct snd_soc_codec *codec, unsigned int reg,
168 return -EIO; 195 return -EIO;
169} 196}
170 197
171static unsigned int adau1701_read(struct snd_soc_codec *codec, unsigned int reg) 198static int adau1701_reg_read(void *context, unsigned int reg,
199 unsigned int *value)
172{ 200{
173 unsigned int value; 201 int ret;
174 unsigned int ret; 202 unsigned int i;
203 unsigned int size;
204 uint8_t send_buf[2], recv_buf[3];
205 struct i2c_client *client = context;
206 struct i2c_msg msgs[2];
207
208 size = adau1701_register_size(&client->dev, reg);
209 if (size == 0)
210 return -EINVAL;
175 211
176 ret = snd_soc_cache_read(codec, reg, &value); 212 send_buf[0] = reg >> 8;
177 if (ret) 213 send_buf[1] = reg & 0xff;
214
215 msgs[0].addr = client->addr;
216 msgs[0].len = sizeof(send_buf);
217 msgs[0].buf = send_buf;
218 msgs[0].flags = 0;
219
220 msgs[1].addr = client->addr;
221 msgs[1].len = size;
222 msgs[1].buf = recv_buf;
223 msgs[1].flags = I2C_M_RD;
224
225 ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs));
226 if (ret < 0)
178 return ret; 227 return ret;
228 else if (ret != ARRAY_SIZE(msgs))
229 return -EIO;
179 230
180 return value; 231 *value = 0;
232
233 for (i = 0; i < size; i++)
234 *value |= recv_buf[i] << (i * 8);
235
236 return 0;
181} 237}
182 238
183static int adau1701_load_firmware(struct snd_soc_codec *codec) 239static int adau1701_reset(struct snd_soc_codec *codec, unsigned int clkdiv)
184{ 240{
185 return process_sigma_firmware(codec->control_data, ADAU1701_FIRMWARE); 241 struct adau1701 *adau1701 = snd_soc_codec_get_drvdata(codec);
242 struct i2c_client *client = to_i2c_client(codec->dev);
243 int ret;
244
245 if (clkdiv != ADAU1707_CLKDIV_UNSET &&
246 gpio_is_valid(adau1701->gpio_pll_mode[0]) &&
247 gpio_is_valid(adau1701->gpio_pll_mode[1])) {
248 switch (clkdiv) {
249 case 64:
250 gpio_set_value(adau1701->gpio_pll_mode[0], 0);
251 gpio_set_value(adau1701->gpio_pll_mode[1], 0);
252 break;
253 case 256:
254 gpio_set_value(adau1701->gpio_pll_mode[0], 0);
255 gpio_set_value(adau1701->gpio_pll_mode[1], 1);
256 break;
257 case 384:
258 gpio_set_value(adau1701->gpio_pll_mode[0], 1);
259 gpio_set_value(adau1701->gpio_pll_mode[1], 0);
260 break;
261 case 0: /* fallback */
262 case 512:
263 gpio_set_value(adau1701->gpio_pll_mode[0], 1);
264 gpio_set_value(adau1701->gpio_pll_mode[1], 1);
265 break;
266 }
267 }
268
269 adau1701->pll_clkdiv = clkdiv;
270
271 if (gpio_is_valid(adau1701->gpio_nreset)) {
272 gpio_set_value(adau1701->gpio_nreset, 0);
273 /* minimum reset time is 20ns */
274 udelay(1);
275 gpio_set_value(adau1701->gpio_nreset, 1);
276 /* power-up time may be as long as 85ms */
277 mdelay(85);
278 }
279
280 /*
281 * Postpone the firmware download to a point in time when we
282 * know the correct PLL setup
283 */
284 if (clkdiv != ADAU1707_CLKDIV_UNSET) {
285 ret = process_sigma_firmware(client, ADAU1701_FIRMWARE);
286 if (ret) {
287 dev_warn(codec->dev, "Failed to load firmware\n");
288 return ret;
289 }
290 }
291
292 regmap_write(adau1701->regmap, ADAU1701_DACSET, ADAU1701_DACSET_DACINIT);
293 regmap_write(adau1701->regmap, ADAU1701_DSPCTRL, ADAU1701_DSPCTRL_CR);
294
295 regcache_mark_dirty(adau1701->regmap);
296 regcache_sync(adau1701->regmap);
297
298 return 0;
186} 299}
187 300
188static int adau1701_set_capture_pcm_format(struct snd_soc_codec *codec, 301static int adau1701_set_capture_pcm_format(struct snd_soc_codec *codec,
@@ -221,7 +334,7 @@ static int adau1701_set_capture_pcm_format(struct snd_soc_codec *codec,
221 mask |= ADAU1701_SEROCTL_MSB_DEALY_MASK; 334 mask |= ADAU1701_SEROCTL_MSB_DEALY_MASK;
222 } 335 }
223 336
224 snd_soc_update_bits(codec, ADAU1701_SEROCTL, mask, val); 337 regmap_update_bits(adau1701->regmap, ADAU1701_SEROCTL, mask, val);
225 338
226 return 0; 339 return 0;
227} 340}
@@ -249,7 +362,7 @@ static int adau1701_set_playback_pcm_format(struct snd_soc_codec *codec,
249 return -EINVAL; 362 return -EINVAL;
250 } 363 }
251 364
252 snd_soc_update_bits(codec, ADAU1701_SERICTL, 365 regmap_update_bits(adau1701->regmap, ADAU1701_SERICTL,
253 ADAU1701_SERICTL_MODE_MASK, val); 366 ADAU1701_SERICTL_MODE_MASK, val);
254 367
255 return 0; 368 return 0;
@@ -259,8 +372,22 @@ static int adau1701_hw_params(struct snd_pcm_substream *substream,
259 struct snd_pcm_hw_params *params, struct snd_soc_dai *dai) 372 struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
260{ 373{
261 struct snd_soc_codec *codec = dai->codec; 374 struct snd_soc_codec *codec = dai->codec;
375 struct adau1701 *adau1701 = snd_soc_codec_get_drvdata(codec);
376 unsigned int clkdiv = adau1701->sysclk / params_rate(params);
262 snd_pcm_format_t format; 377 snd_pcm_format_t format;
263 unsigned int val; 378 unsigned int val;
379 int ret;
380
381 /*
382 * If the mclk/lrclk ratio changes, the chip needs updated PLL
383 * mode GPIO settings, and a full reset cycle, including a new
384 * firmware upload.
385 */
386 if (clkdiv != adau1701->pll_clkdiv) {
387 ret = adau1701_reset(codec, clkdiv);
388 if (ret < 0)
389 return ret;
390 }
264 391
265 switch (params_rate(params)) { 392 switch (params_rate(params)) {
266 case 192000: 393 case 192000:
@@ -276,7 +403,7 @@ static int adau1701_hw_params(struct snd_pcm_substream *substream,
276 return -EINVAL; 403 return -EINVAL;
277 } 404 }
278 405
279 snd_soc_update_bits(codec, ADAU1701_DSPCTRL, 406 regmap_update_bits(adau1701->regmap, ADAU1701_DSPCTRL,
280 ADAU1701_DSPCTRL_SR_MASK, val); 407 ADAU1701_DSPCTRL_SR_MASK, val);
281 408
282 format = params_format(params); 409 format = params_format(params);
@@ -352,8 +479,8 @@ static int adau1701_set_dai_fmt(struct snd_soc_dai *codec_dai,
352 479
353 adau1701->dai_fmt = fmt & SND_SOC_DAIFMT_FORMAT_MASK; 480 adau1701->dai_fmt = fmt & SND_SOC_DAIFMT_FORMAT_MASK;
354 481
355 snd_soc_write(codec, ADAU1701_SERICTL, serictl); 482 regmap_write(adau1701->regmap, ADAU1701_SERICTL, serictl);
356 snd_soc_update_bits(codec, ADAU1701_SEROCTL, 483 regmap_update_bits(adau1701->regmap, ADAU1701_SEROCTL,
357 ~ADAU1701_SEROCTL_WORD_LEN_MASK, seroctl); 484 ~ADAU1701_SEROCTL_WORD_LEN_MASK, seroctl);
358 485
359 return 0; 486 return 0;
@@ -363,6 +490,7 @@ static int adau1701_set_bias_level(struct snd_soc_codec *codec,
363 enum snd_soc_bias_level level) 490 enum snd_soc_bias_level level)
364{ 491{
365 unsigned int mask = ADAU1701_AUXNPOW_VBPD | ADAU1701_AUXNPOW_VRPD; 492 unsigned int mask = ADAU1701_AUXNPOW_VBPD | ADAU1701_AUXNPOW_VRPD;
493 struct adau1701 *adau1701 = snd_soc_codec_get_drvdata(codec);
366 494
367 switch (level) { 495 switch (level) {
368 case SND_SOC_BIAS_ON: 496 case SND_SOC_BIAS_ON:
@@ -371,11 +499,13 @@ static int adau1701_set_bias_level(struct snd_soc_codec *codec,
371 break; 499 break;
372 case SND_SOC_BIAS_STANDBY: 500 case SND_SOC_BIAS_STANDBY:
373 /* Enable VREF and VREF buffer */ 501 /* Enable VREF and VREF buffer */
374 snd_soc_update_bits(codec, ADAU1701_AUXNPOW, mask, 0x00); 502 regmap_update_bits(adau1701->regmap,
503 ADAU1701_AUXNPOW, mask, 0x00);
375 break; 504 break;
376 case SND_SOC_BIAS_OFF: 505 case SND_SOC_BIAS_OFF:
377 /* Disable VREF and VREF buffer */ 506 /* Disable VREF and VREF buffer */
378 snd_soc_update_bits(codec, ADAU1701_AUXNPOW, mask, mask); 507 regmap_update_bits(adau1701->regmap,
508 ADAU1701_AUXNPOW, mask, mask);
379 break; 509 break;
380 } 510 }
381 511
@@ -387,6 +517,7 @@ static int adau1701_digital_mute(struct snd_soc_dai *dai, int mute)
387{ 517{
388 struct snd_soc_codec *codec = dai->codec; 518 struct snd_soc_codec *codec = dai->codec;
389 unsigned int mask = ADAU1701_DSPCTRL_DAM; 519 unsigned int mask = ADAU1701_DSPCTRL_DAM;
520 struct adau1701 *adau1701 = snd_soc_codec_get_drvdata(codec);
390 unsigned int val; 521 unsigned int val;
391 522
392 if (mute) 523 if (mute)
@@ -394,7 +525,7 @@ static int adau1701_digital_mute(struct snd_soc_dai *dai, int mute)
394 else 525 else
395 val = mask; 526 val = mask;
396 527
397 snd_soc_update_bits(codec, ADAU1701_DSPCTRL, mask, val); 528 regmap_update_bits(adau1701->regmap, ADAU1701_DSPCTRL, mask, val);
398 529
399 return 0; 530 return 0;
400} 531}
@@ -403,6 +534,7 @@ static int adau1701_set_sysclk(struct snd_soc_codec *codec, int clk_id,
403 int source, unsigned int freq, int dir) 534 int source, unsigned int freq, int dir)
404{ 535{
405 unsigned int val; 536 unsigned int val;
537 struct adau1701 *adau1701 = snd_soc_codec_get_drvdata(codec);
406 538
407 switch (clk_id) { 539 switch (clk_id) {
408 case ADAU1701_CLK_SRC_OSC: 540 case ADAU1701_CLK_SRC_OSC:
@@ -415,7 +547,9 @@ static int adau1701_set_sysclk(struct snd_soc_codec *codec, int clk_id,
415 return -EINVAL; 547 return -EINVAL;
416 } 548 }
417 549
418 snd_soc_update_bits(codec, ADAU1701_OSCIPOW, ADAU1701_OSCIPOW_OPD, val); 550 regmap_update_bits(adau1701->regmap, ADAU1701_OSCIPOW,
551 ADAU1701_OSCIPOW_OPD, val);
552 adau1701->sysclk = freq;
419 553
420 return 0; 554 return 0;
421} 555}
@@ -452,18 +586,45 @@ static struct snd_soc_dai_driver adau1701_dai = {
452 .symmetric_rates = 1, 586 .symmetric_rates = 1,
453}; 587};
454 588
589#ifdef CONFIG_OF
590static const struct of_device_id adau1701_dt_ids[] = {
591 { .compatible = "adi,adau1701", },
592 { }
593};
594MODULE_DEVICE_TABLE(of, adau1701_dt_ids);
595#endif
596
455static int adau1701_probe(struct snd_soc_codec *codec) 597static int adau1701_probe(struct snd_soc_codec *codec)
456{ 598{
457 int ret; 599 int i, ret;
600 unsigned int val;
601 struct adau1701 *adau1701 = snd_soc_codec_get_drvdata(codec);
602
603 /*
604 * Let the pll_clkdiv variable default to something that won't happen
605 * at runtime. That way, we can postpone the firmware download from
606 * adau1701_reset() to a point in time when we know the correct PLL
607 * mode parameters.
608 */
609 adau1701->pll_clkdiv = ADAU1707_CLKDIV_UNSET;
610
611 /* initalize with pre-configured pll mode settings */
612 ret = adau1701_reset(codec, adau1701->pll_clkdiv);
613 if (ret < 0)
614 return ret;
615
616 /* set up pin config */
617 val = 0;
618 for (i = 0; i < 6; i++)
619 val |= adau1701->pin_config[i] << (i * 4);
458 620
459 codec->control_data = to_i2c_client(codec->dev); 621 regmap_write(adau1701->regmap, ADAU1701_PINCONF_0, val);
460 622
461 ret = adau1701_load_firmware(codec); 623 val = 0;
462 if (ret) 624 for (i = 0; i < 6; i++)
463 dev_warn(codec->dev, "Failed to load firmware\n"); 625 val |= adau1701->pin_config[i + 6] << (i * 4);
464 626
465 snd_soc_write(codec, ADAU1701_DACSET, ADAU1701_DACSET_DACINIT); 627 regmap_write(adau1701->regmap, ADAU1701_PINCONF_1, val);
466 snd_soc_write(codec, ADAU1701_DSPCTRL, ADAU1701_DSPCTRL_CR);
467 628
468 return 0; 629 return 0;
469} 630}
@@ -473,9 +634,6 @@ static struct snd_soc_codec_driver adau1701_codec_drv = {
473 .set_bias_level = adau1701_set_bias_level, 634 .set_bias_level = adau1701_set_bias_level,
474 .idle_bias_off = true, 635 .idle_bias_off = true,
475 636
476 .reg_cache_size = ADAU1701_NUM_REGS,
477 .reg_word_size = sizeof(u16),
478
479 .controls = adau1701_controls, 637 .controls = adau1701_controls,
480 .num_controls = ARRAY_SIZE(adau1701_controls), 638 .num_controls = ARRAY_SIZE(adau1701_controls),
481 .dapm_widgets = adau1701_dapm_widgets, 639 .dapm_widgets = adau1701_dapm_widgets,
@@ -483,22 +641,86 @@ static struct snd_soc_codec_driver adau1701_codec_drv = {
483 .dapm_routes = adau1701_dapm_routes, 641 .dapm_routes = adau1701_dapm_routes,
484 .num_dapm_routes = ARRAY_SIZE(adau1701_dapm_routes), 642 .num_dapm_routes = ARRAY_SIZE(adau1701_dapm_routes),
485 643
486 .write = adau1701_write,
487 .read = adau1701_read,
488
489 .set_sysclk = adau1701_set_sysclk, 644 .set_sysclk = adau1701_set_sysclk,
490}; 645};
491 646
647static const struct regmap_config adau1701_regmap = {
648 .reg_bits = 16,
649 .val_bits = 32,
650 .max_register = ADAU1701_MAX_REGISTER,
651 .cache_type = REGCACHE_RBTREE,
652 .volatile_reg = adau1701_volatile_reg,
653 .reg_write = adau1701_reg_write,
654 .reg_read = adau1701_reg_read,
655};
656
492static int adau1701_i2c_probe(struct i2c_client *client, 657static int adau1701_i2c_probe(struct i2c_client *client,
493 const struct i2c_device_id *id) 658 const struct i2c_device_id *id)
494{ 659{
495 struct adau1701 *adau1701; 660 struct adau1701 *adau1701;
661 struct device *dev = &client->dev;
662 int gpio_nreset = -EINVAL;
663 int gpio_pll_mode[2] = { -EINVAL, -EINVAL };
496 int ret; 664 int ret;
497 665
498 adau1701 = devm_kzalloc(&client->dev, sizeof(*adau1701), GFP_KERNEL); 666 adau1701 = devm_kzalloc(dev, sizeof(*adau1701), GFP_KERNEL);
499 if (!adau1701) 667 if (!adau1701)
500 return -ENOMEM; 668 return -ENOMEM;
501 669
670 adau1701->regmap = devm_regmap_init(dev, NULL, client,
671 &adau1701_regmap);
672 if (IS_ERR(adau1701->regmap))
673 return PTR_ERR(adau1701->regmap);
674
675 if (dev->of_node) {
676 gpio_nreset = of_get_named_gpio(dev->of_node, "reset-gpio", 0);
677 if (gpio_nreset < 0 && gpio_nreset != -ENOENT)
678 return gpio_nreset;
679
680 gpio_pll_mode[0] = of_get_named_gpio(dev->of_node,
681 "adi,pll-mode-gpios", 0);
682 if (gpio_pll_mode[0] < 0 && gpio_pll_mode[0] != -ENOENT)
683 return gpio_pll_mode[0];
684
685 gpio_pll_mode[1] = of_get_named_gpio(dev->of_node,
686 "adi,pll-mode-gpios", 1);
687 if (gpio_pll_mode[1] < 0 && gpio_pll_mode[1] != -ENOENT)
688 return gpio_pll_mode[1];
689
690 of_property_read_u32(dev->of_node, "adi,pll-clkdiv",
691 &adau1701->pll_clkdiv);
692
693 of_property_read_u8_array(dev->of_node, "adi,pin-config",
694 adau1701->pin_config,
695 ARRAY_SIZE(adau1701->pin_config));
696 }
697
698 if (gpio_is_valid(gpio_nreset)) {
699 ret = devm_gpio_request_one(dev, gpio_nreset, GPIOF_OUT_INIT_LOW,
700 "ADAU1701 Reset");
701 if (ret < 0)
702 return ret;
703 }
704
705 if (gpio_is_valid(gpio_pll_mode[0]) &&
706 gpio_is_valid(gpio_pll_mode[1])) {
707 ret = devm_gpio_request_one(dev, gpio_pll_mode[0],
708 GPIOF_OUT_INIT_LOW,
709 "ADAU1701 PLL mode 0");
710 if (ret < 0)
711 return ret;
712
713 ret = devm_gpio_request_one(dev, gpio_pll_mode[1],
714 GPIOF_OUT_INIT_LOW,
715 "ADAU1701 PLL mode 1");
716 if (ret < 0)
717 return ret;
718 }
719
720 adau1701->gpio_nreset = gpio_nreset;
721 adau1701->gpio_pll_mode[0] = gpio_pll_mode[0];
722 adau1701->gpio_pll_mode[1] = gpio_pll_mode[1];
723
502 i2c_set_clientdata(client, adau1701); 724 i2c_set_clientdata(client, adau1701);
503 ret = snd_soc_register_codec(&client->dev, &adau1701_codec_drv, 725 ret = snd_soc_register_codec(&client->dev, &adau1701_codec_drv,
504 &adau1701_dai, 1); 726 &adau1701_dai, 1);
@@ -521,6 +743,7 @@ static struct i2c_driver adau1701_i2c_driver = {
521 .driver = { 743 .driver = {
522 .name = "adau1701", 744 .name = "adau1701",
523 .owner = THIS_MODULE, 745 .owner = THIS_MODULE,
746 .of_match_table = of_match_ptr(adau1701_dt_ids),
524 }, 747 },
525 .probe = adau1701_i2c_probe, 748 .probe = adau1701_i2c_probe,
526 .remove = adau1701_i2c_remove, 749 .remove = adau1701_i2c_remove,
diff --git a/sound/soc/codecs/arizona.c b/sound/soc/codecs/arizona.c
index 389f23253831..de625813c0e6 100644
--- a/sound/soc/codecs/arizona.c
+++ b/sound/soc/codecs/arizona.c
@@ -1198,6 +1198,13 @@ const struct snd_soc_dai_ops arizona_dai_ops = {
1198}; 1198};
1199EXPORT_SYMBOL_GPL(arizona_dai_ops); 1199EXPORT_SYMBOL_GPL(arizona_dai_ops);
1200 1200
1201const struct snd_soc_dai_ops arizona_simple_dai_ops = {
1202 .startup = arizona_startup,
1203 .hw_params = arizona_hw_params_rate,
1204 .set_sysclk = arizona_dai_set_sysclk,
1205};
1206EXPORT_SYMBOL_GPL(arizona_simple_dai_ops);
1207
1201int arizona_init_dai(struct arizona_priv *priv, int id) 1208int arizona_init_dai(struct arizona_priv *priv, int id)
1202{ 1209{
1203 struct arizona_dai_priv *dai_priv = &priv->dai[id]; 1210 struct arizona_dai_priv *dai_priv = &priv->dai[id];
diff --git a/sound/soc/codecs/arizona.h b/sound/soc/codecs/arizona.h
index af39f1006427..b60b08ccc1d0 100644
--- a/sound/soc/codecs/arizona.h
+++ b/sound/soc/codecs/arizona.h
@@ -57,7 +57,7 @@
57#define ARIZONA_CLK_98MHZ 5 57#define ARIZONA_CLK_98MHZ 5
58#define ARIZONA_CLK_147MHZ 6 58#define ARIZONA_CLK_147MHZ 6
59 59
60#define ARIZONA_MAX_DAI 4 60#define ARIZONA_MAX_DAI 6
61#define ARIZONA_MAX_ADSP 4 61#define ARIZONA_MAX_ADSP 4
62 62
63struct arizona; 63struct arizona;
@@ -213,6 +213,7 @@ extern int arizona_set_sysclk(struct snd_soc_codec *codec, int clk_id,
213 int source, unsigned int freq, int dir); 213 int source, unsigned int freq, int dir);
214 214
215extern const struct snd_soc_dai_ops arizona_dai_ops; 215extern const struct snd_soc_dai_ops arizona_dai_ops;
216extern const struct snd_soc_dai_ops arizona_simple_dai_ops;
216 217
217#define ARIZONA_FLL_NAME_LEN 20 218#define ARIZONA_FLL_NAME_LEN 20
218 219
diff --git a/sound/soc/codecs/dfbmcs320.c b/sound/soc/codecs/bt-sco.c
index 4f4f7f41a7d1..a081d9fcb166 100644
--- a/sound/soc/codecs/dfbmcs320.c
+++ b/sound/soc/codecs/bt-sco.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Driver for the DFBM-CS320 bluetooth module 2 * Driver for generic Bluetooth SCO link
3 * Copyright 2011 Lars-Peter Clausen <lars@metafoo.de> 3 * Copyright 2011 Lars-Peter Clausen <lars@metafoo.de>
4 * 4 *
5 * This program is free software; you can redistribute it and/or modify it 5 * This program is free software; you can redistribute it and/or modify it
@@ -15,8 +15,8 @@
15 15
16#include <sound/soc.h> 16#include <sound/soc.h>
17 17
18static struct snd_soc_dai_driver dfbmcs320_dai = { 18static struct snd_soc_dai_driver bt_sco_dai = {
19 .name = "dfbmcs320-pcm", 19 .name = "bt-sco-pcm",
20 .playback = { 20 .playback = {
21 .channels_min = 1, 21 .channels_min = 1,
22 .channels_max = 1, 22 .channels_max = 1,
@@ -31,32 +31,41 @@ static struct snd_soc_dai_driver dfbmcs320_dai = {
31 }, 31 },
32}; 32};
33 33
34static struct snd_soc_codec_driver soc_codec_dev_dfbmcs320; 34static struct snd_soc_codec_driver soc_codec_dev_bt_sco;
35 35
36static int dfbmcs320_probe(struct platform_device *pdev) 36static int bt_sco_probe(struct platform_device *pdev)
37{ 37{
38 return snd_soc_register_codec(&pdev->dev, &soc_codec_dev_dfbmcs320, 38 return snd_soc_register_codec(&pdev->dev, &soc_codec_dev_bt_sco,
39 &dfbmcs320_dai, 1); 39 &bt_sco_dai, 1);
40} 40}
41 41
42static int dfbmcs320_remove(struct platform_device *pdev) 42static int bt_sco_remove(struct platform_device *pdev)
43{ 43{
44 snd_soc_unregister_codec(&pdev->dev); 44 snd_soc_unregister_codec(&pdev->dev);
45 45
46 return 0; 46 return 0;
47} 47}
48 48
49static struct platform_driver dfmcs320_driver = { 49static struct platform_device_id bt_sco_driver_ids[] = {
50 {
51 .name = "dfbmcs320",
52 },
53 {},
54};
55MODULE_DEVICE_TABLE(platform, bt_sco_driver_ids);
56
57static struct platform_driver bt_sco_driver = {
50 .driver = { 58 .driver = {
51 .name = "dfbmcs320", 59 .name = "bt-sco",
52 .owner = THIS_MODULE, 60 .owner = THIS_MODULE,
53 }, 61 },
54 .probe = dfbmcs320_probe, 62 .probe = bt_sco_probe,
55 .remove = dfbmcs320_remove, 63 .remove = bt_sco_remove,
64 .id_table = bt_sco_driver_ids,
56}; 65};
57 66
58module_platform_driver(dfmcs320_driver); 67module_platform_driver(bt_sco_driver);
59 68
60MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>"); 69MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
61MODULE_DESCRIPTION("ASoC DFBM-CS320 bluethooth module driver"); 70MODULE_DESCRIPTION("ASoC generic bluethooth sco link driver");
62MODULE_LICENSE("GPL"); 71MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/omap-hdmi.c b/sound/soc/codecs/hdmi.c
index 529d06444c54..2bcae2b40c92 100644
--- a/sound/soc/codecs/omap-hdmi.c
+++ b/sound/soc/codecs/hdmi.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * ALSA SoC codec driver for HDMI audio on OMAP processors. 2 * ALSA SoC codec driver for HDMI audio codecs.
3 * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/ 3 * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/
4 * Author: Ricardo Neri <ricardo.neri@ti.com> 4 * Author: Ricardo Neri <ricardo.neri@ti.com>
5 * 5 *
@@ -23,10 +23,10 @@
23 23
24#define DRV_NAME "hdmi-audio-codec" 24#define DRV_NAME "hdmi-audio-codec"
25 25
26static struct snd_soc_codec_driver omap_hdmi_codec; 26static struct snd_soc_codec_driver hdmi_codec;
27 27
28static struct snd_soc_dai_driver omap_hdmi_codec_dai = { 28static struct snd_soc_dai_driver hdmi_codec_dai = {
29 .name = "omap-hdmi-hifi", 29 .name = "hdmi-hifi",
30 .playback = { 30 .playback = {
31 .channels_min = 2, 31 .channels_min = 2,
32 .channels_max = 8, 32 .channels_max = 8,
@@ -39,31 +39,31 @@ static struct snd_soc_dai_driver omap_hdmi_codec_dai = {
39 }, 39 },
40}; 40};
41 41
42static int omap_hdmi_codec_probe(struct platform_device *pdev) 42static int hdmi_codec_probe(struct platform_device *pdev)
43{ 43{
44 return snd_soc_register_codec(&pdev->dev, &omap_hdmi_codec, 44 return snd_soc_register_codec(&pdev->dev, &hdmi_codec,
45 &omap_hdmi_codec_dai, 1); 45 &hdmi_codec_dai, 1);
46} 46}
47 47
48static int omap_hdmi_codec_remove(struct platform_device *pdev) 48static int hdmi_codec_remove(struct platform_device *pdev)
49{ 49{
50 snd_soc_unregister_codec(&pdev->dev); 50 snd_soc_unregister_codec(&pdev->dev);
51 return 0; 51 return 0;
52} 52}
53 53
54static struct platform_driver omap_hdmi_codec_driver = { 54static struct platform_driver hdmi_codec_driver = {
55 .driver = { 55 .driver = {
56 .name = DRV_NAME, 56 .name = DRV_NAME,
57 .owner = THIS_MODULE, 57 .owner = THIS_MODULE,
58 }, 58 },
59 59
60 .probe = omap_hdmi_codec_probe, 60 .probe = hdmi_codec_probe,
61 .remove = omap_hdmi_codec_remove, 61 .remove = hdmi_codec_remove,
62}; 62};
63 63
64module_platform_driver(omap_hdmi_codec_driver); 64module_platform_driver(hdmi_codec_driver);
65 65
66MODULE_AUTHOR("Ricardo Neri <ricardo.neri@ti.com>"); 66MODULE_AUTHOR("Ricardo Neri <ricardo.neri@ti.com>");
67MODULE_DESCRIPTION("ASoC OMAP HDMI codec driver"); 67MODULE_DESCRIPTION("ASoC generic HDMI codec driver");
68MODULE_LICENSE("GPL"); 68MODULE_LICENSE("GPL");
69MODULE_ALIAS("platform:" DRV_NAME); 69MODULE_ALIAS("platform:" DRV_NAME);
diff --git a/sound/soc/codecs/jz4740.c b/sound/soc/codecs/jz4740.c
index 5f607b35b68b..bcebd1a9ce31 100644
--- a/sound/soc/codecs/jz4740.c
+++ b/sound/soc/codecs/jz4740.c
@@ -384,8 +384,6 @@ static int jz4740_codec_remove(struct platform_device *pdev)
384{ 384{
385 snd_soc_unregister_codec(&pdev->dev); 385 snd_soc_unregister_codec(&pdev->dev);
386 386
387 platform_set_drvdata(pdev, NULL);
388
389 return 0; 387 return 0;
390} 388}
391 389
diff --git a/sound/soc/codecs/max98090.c b/sound/soc/codecs/max98090.c
index 8d14a76c7249..ad5313f98f28 100644
--- a/sound/soc/codecs/max98090.c
+++ b/sound/soc/codecs/max98090.c
@@ -857,6 +857,14 @@ static const struct soc_enum mic2_mux_enum =
857static const struct snd_kcontrol_new max98090_mic2_mux = 857static const struct snd_kcontrol_new max98090_mic2_mux =
858 SOC_DAPM_ENUM("MIC2 Mux", mic2_mux_enum); 858 SOC_DAPM_ENUM("MIC2 Mux", mic2_mux_enum);
859 859
860static const char *dmic_mux_text[] = { "ADC", "DMIC" };
861
862static const struct soc_enum dmic_mux_enum =
863 SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(dmic_mux_text), dmic_mux_text);
864
865static const struct snd_kcontrol_new max98090_dmic_mux =
866 SOC_DAPM_ENUM_VIRT("DMIC Mux", dmic_mux_enum);
867
860static const char *max98090_micpre_text[] = { "Off", "On" }; 868static const char *max98090_micpre_text[] = { "Off", "On" };
861 869
862static const struct soc_enum max98090_pa1en_enum = 870static const struct soc_enum max98090_pa1en_enum =
@@ -1144,6 +1152,9 @@ static const struct snd_soc_dapm_widget max98090_dapm_widgets[] = {
1144 SND_SOC_DAPM_MUX("MIC2 Mux", SND_SOC_NOPM, 1152 SND_SOC_DAPM_MUX("MIC2 Mux", SND_SOC_NOPM,
1145 0, 0, &max98090_mic2_mux), 1153 0, 0, &max98090_mic2_mux),
1146 1154
1155 SND_SOC_DAPM_VIRT_MUX("DMIC Mux", SND_SOC_NOPM,
1156 0, 0, &max98090_dmic_mux),
1157
1147 SND_SOC_DAPM_PGA_E("MIC1 Input", M98090_REG_MIC1_INPUT_LEVEL, 1158 SND_SOC_DAPM_PGA_E("MIC1 Input", M98090_REG_MIC1_INPUT_LEVEL,
1148 M98090_MIC_PA1EN_SHIFT, 0, NULL, 0, max98090_micinput_event, 1159 M98090_MIC_PA1EN_SHIFT, 0, NULL, 0, max98090_micinput_event,
1149 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), 1160 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
@@ -1336,11 +1347,14 @@ static const struct snd_soc_dapm_route max98090_dapm_routes[] = {
1336 {"ADCL", NULL, "SHDN"}, 1347 {"ADCL", NULL, "SHDN"},
1337 {"ADCR", NULL, "SHDN"}, 1348 {"ADCR", NULL, "SHDN"},
1338 1349
1339 {"LBENL Mux", "Normal", "ADCL"}, 1350 {"DMIC Mux", "ADC", "ADCL"},
1340 {"LBENL Mux", "Normal", "DMICL"}, 1351 {"DMIC Mux", "ADC", "ADCR"},
1352 {"DMIC Mux", "DMIC", "DMICL"},
1353 {"DMIC Mux", "DMIC", "DMICR"},
1354
1355 {"LBENL Mux", "Normal", "DMIC Mux"},
1341 {"LBENL Mux", "Loopback", "LTENL Mux"}, 1356 {"LBENL Mux", "Loopback", "LTENL Mux"},
1342 {"LBENR Mux", "Normal", "ADCR"}, 1357 {"LBENR Mux", "Normal", "DMIC Mux"},
1343 {"LBENR Mux", "Normal", "DMICR"},
1344 {"LBENR Mux", "Loopback", "LTENR Mux"}, 1358 {"LBENR Mux", "Loopback", "LTENR Mux"},
1345 1359
1346 {"AIFOUTL", NULL, "LBENL Mux"}, 1360 {"AIFOUTL", NULL, "LBENL Mux"},
@@ -2336,6 +2350,7 @@ static int max98090_i2c_remove(struct i2c_client *client)
2336 return 0; 2350 return 0;
2337} 2351}
2338 2352
2353#ifdef CONFIG_PM_RUNTIME
2339static int max98090_runtime_resume(struct device *dev) 2354static int max98090_runtime_resume(struct device *dev)
2340{ 2355{
2341 struct max98090_priv *max98090 = dev_get_drvdata(dev); 2356 struct max98090_priv *max98090 = dev_get_drvdata(dev);
@@ -2355,6 +2370,7 @@ static int max98090_runtime_suspend(struct device *dev)
2355 2370
2356 return 0; 2371 return 0;
2357} 2372}
2373#endif
2358 2374
2359static const struct dev_pm_ops max98090_pm = { 2375static const struct dev_pm_ops max98090_pm = {
2360 SET_RUNTIME_PM_OPS(max98090_runtime_suspend, 2376 SET_RUNTIME_PM_OPS(max98090_runtime_suspend,
diff --git a/sound/soc/codecs/rt5640.c b/sound/soc/codecs/rt5640.c
new file mode 100644
index 000000000000..ce585e37e38a
--- /dev/null
+++ b/sound/soc/codecs/rt5640.c
@@ -0,0 +1,2128 @@
1/*
2 * rt5640.c -- RT5640 ALSA SoC audio codec driver
3 *
4 * Copyright 2011 Realtek Semiconductor Corp.
5 * Author: Johnny Hsu <johnnyhsu@realtek.com>
6 * Copyright (c) 2013, NVIDIA CORPORATION. All rights reserved.
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 */
12
13#include <linux/module.h>
14#include <linux/moduleparam.h>
15#include <linux/init.h>
16#include <linux/delay.h>
17#include <linux/pm.h>
18#include <linux/gpio.h>
19#include <linux/i2c.h>
20#include <linux/regmap.h>
21#include <linux/of_gpio.h>
22#include <linux/platform_device.h>
23#include <linux/spi/spi.h>
24#include <sound/core.h>
25#include <sound/pcm.h>
26#include <sound/pcm_params.h>
27#include <sound/soc.h>
28#include <sound/soc-dapm.h>
29#include <sound/initval.h>
30#include <sound/tlv.h>
31
32#include "rt5640.h"
33
34#define RT5640_DEVICE_ID 0x6231
35
36#define RT5640_PR_RANGE_BASE (0xff + 1)
37#define RT5640_PR_SPACING 0x100
38
39#define RT5640_PR_BASE (RT5640_PR_RANGE_BASE + (0 * RT5640_PR_SPACING))
40
41static const struct regmap_range_cfg rt5640_ranges[] = {
42 { .name = "PR", .range_min = RT5640_PR_BASE,
43 .range_max = RT5640_PR_BASE + 0xb4,
44 .selector_reg = RT5640_PRIV_INDEX,
45 .selector_mask = 0xff,
46 .selector_shift = 0x0,
47 .window_start = RT5640_PRIV_DATA,
48 .window_len = 0x1, },
49};
50
51static struct reg_default init_list[] = {
52 {RT5640_PR_BASE + 0x3d, 0x3600},
53 {RT5640_PR_BASE + 0x1c, 0x0D21},
54 {RT5640_PR_BASE + 0x1b, 0x0000},
55 {RT5640_PR_BASE + 0x12, 0x0aa8},
56 {RT5640_PR_BASE + 0x14, 0x0aaa},
57 {RT5640_PR_BASE + 0x20, 0x6110},
58 {RT5640_PR_BASE + 0x21, 0xe0e0},
59 {RT5640_PR_BASE + 0x23, 0x1804},
60};
61#define RT5640_INIT_REG_LEN ARRAY_SIZE(init_list)
62
63static const struct reg_default rt5640_reg[RT5640_VENDOR_ID2 + 1] = {
64 { 0x00, 0x000e },
65 { 0x01, 0xc8c8 },
66 { 0x02, 0xc8c8 },
67 { 0x03, 0xc8c8 },
68 { 0x04, 0x8000 },
69 { 0x0d, 0x0000 },
70 { 0x0e, 0x0000 },
71 { 0x0f, 0x0808 },
72 { 0x19, 0xafaf },
73 { 0x1a, 0xafaf },
74 { 0x1b, 0x0000 },
75 { 0x1c, 0x2f2f },
76 { 0x1d, 0x2f2f },
77 { 0x1e, 0x0000 },
78 { 0x27, 0x7060 },
79 { 0x28, 0x7070 },
80 { 0x29, 0x8080 },
81 { 0x2a, 0x5454 },
82 { 0x2b, 0x5454 },
83 { 0x2c, 0xaa00 },
84 { 0x2d, 0x0000 },
85 { 0x2e, 0xa000 },
86 { 0x2f, 0x0000 },
87 { 0x3b, 0x0000 },
88 { 0x3c, 0x007f },
89 { 0x3d, 0x0000 },
90 { 0x3e, 0x007f },
91 { 0x45, 0xe000 },
92 { 0x46, 0x003e },
93 { 0x47, 0x003e },
94 { 0x48, 0xf800 },
95 { 0x49, 0x3800 },
96 { 0x4a, 0x0004 },
97 { 0x4c, 0xfc00 },
98 { 0x4d, 0x0000 },
99 { 0x4f, 0x01ff },
100 { 0x50, 0x0000 },
101 { 0x51, 0x0000 },
102 { 0x52, 0x01ff },
103 { 0x53, 0xf000 },
104 { 0x61, 0x0000 },
105 { 0x62, 0x0000 },
106 { 0x63, 0x00c0 },
107 { 0x64, 0x0000 },
108 { 0x65, 0x0000 },
109 { 0x66, 0x0000 },
110 { 0x6a, 0x0000 },
111 { 0x6c, 0x0000 },
112 { 0x70, 0x8000 },
113 { 0x71, 0x8000 },
114 { 0x72, 0x8000 },
115 { 0x73, 0x1114 },
116 { 0x74, 0x0c00 },
117 { 0x75, 0x1d00 },
118 { 0x80, 0x0000 },
119 { 0x81, 0x0000 },
120 { 0x82, 0x0000 },
121 { 0x83, 0x0000 },
122 { 0x84, 0x0000 },
123 { 0x85, 0x0008 },
124 { 0x89, 0x0000 },
125 { 0x8a, 0x0000 },
126 { 0x8b, 0x0600 },
127 { 0x8c, 0x0228 },
128 { 0x8d, 0xa000 },
129 { 0x8e, 0x0004 },
130 { 0x8f, 0x1100 },
131 { 0x90, 0x0646 },
132 { 0x91, 0x0c00 },
133 { 0x92, 0x0000 },
134 { 0x93, 0x3000 },
135 { 0xb0, 0x2080 },
136 { 0xb1, 0x0000 },
137 { 0xb4, 0x2206 },
138 { 0xb5, 0x1f00 },
139 { 0xb6, 0x0000 },
140 { 0xb8, 0x034b },
141 { 0xb9, 0x0066 },
142 { 0xba, 0x000b },
143 { 0xbb, 0x0000 },
144 { 0xbc, 0x0000 },
145 { 0xbd, 0x0000 },
146 { 0xbe, 0x0000 },
147 { 0xbf, 0x0000 },
148 { 0xc0, 0x0400 },
149 { 0xc2, 0x0000 },
150 { 0xc4, 0x0000 },
151 { 0xc5, 0x0000 },
152 { 0xc6, 0x2000 },
153 { 0xc8, 0x0000 },
154 { 0xc9, 0x0000 },
155 { 0xca, 0x0000 },
156 { 0xcb, 0x0000 },
157 { 0xcc, 0x0000 },
158 { 0xcf, 0x0013 },
159 { 0xd0, 0x0680 },
160 { 0xd1, 0x1c17 },
161 { 0xd2, 0x8c00 },
162 { 0xd3, 0xaa20 },
163 { 0xd6, 0x0400 },
164 { 0xd9, 0x0809 },
165 { 0xfe, 0x10ec },
166 { 0xff, 0x6231 },
167};
168
169static int rt5640_reset(struct snd_soc_codec *codec)
170{
171 return snd_soc_write(codec, RT5640_RESET, 0);
172}
173
174static bool rt5640_volatile_register(struct device *dev, unsigned int reg)
175{
176 int i;
177
178 for (i = 0; i < ARRAY_SIZE(rt5640_ranges); i++)
179 if ((reg >= rt5640_ranges[i].window_start &&
180 reg <= rt5640_ranges[i].window_start +
181 rt5640_ranges[i].window_len) ||
182 (reg >= rt5640_ranges[i].range_min &&
183 reg <= rt5640_ranges[i].range_max))
184 return true;
185
186 switch (reg) {
187 case RT5640_RESET:
188 case RT5640_ASRC_5:
189 case RT5640_EQ_CTRL1:
190 case RT5640_DRC_AGC_1:
191 case RT5640_ANC_CTRL1:
192 case RT5640_IRQ_CTRL2:
193 case RT5640_INT_IRQ_ST:
194 case RT5640_DSP_CTRL2:
195 case RT5640_DSP_CTRL3:
196 case RT5640_PRIV_INDEX:
197 case RT5640_PRIV_DATA:
198 case RT5640_PGM_REG_ARR1:
199 case RT5640_PGM_REG_ARR3:
200 case RT5640_VENDOR_ID:
201 case RT5640_VENDOR_ID1:
202 case RT5640_VENDOR_ID2:
203 return true;
204 default:
205 return false;
206 }
207}
208
209static bool rt5640_readable_register(struct device *dev, unsigned int reg)
210{
211 int i;
212
213 for (i = 0; i < ARRAY_SIZE(rt5640_ranges); i++)
214 if ((reg >= rt5640_ranges[i].window_start &&
215 reg <= rt5640_ranges[i].window_start +
216 rt5640_ranges[i].window_len) ||
217 (reg >= rt5640_ranges[i].range_min &&
218 reg <= rt5640_ranges[i].range_max))
219 return true;
220
221 switch (reg) {
222 case RT5640_RESET:
223 case RT5640_SPK_VOL:
224 case RT5640_HP_VOL:
225 case RT5640_OUTPUT:
226 case RT5640_MONO_OUT:
227 case RT5640_IN1_IN2:
228 case RT5640_IN3_IN4:
229 case RT5640_INL_INR_VOL:
230 case RT5640_DAC1_DIG_VOL:
231 case RT5640_DAC2_DIG_VOL:
232 case RT5640_DAC2_CTRL:
233 case RT5640_ADC_DIG_VOL:
234 case RT5640_ADC_DATA:
235 case RT5640_ADC_BST_VOL:
236 case RT5640_STO_ADC_MIXER:
237 case RT5640_MONO_ADC_MIXER:
238 case RT5640_AD_DA_MIXER:
239 case RT5640_STO_DAC_MIXER:
240 case RT5640_MONO_DAC_MIXER:
241 case RT5640_DIG_MIXER:
242 case RT5640_DSP_PATH1:
243 case RT5640_DSP_PATH2:
244 case RT5640_DIG_INF_DATA:
245 case RT5640_REC_L1_MIXER:
246 case RT5640_REC_L2_MIXER:
247 case RT5640_REC_R1_MIXER:
248 case RT5640_REC_R2_MIXER:
249 case RT5640_HPO_MIXER:
250 case RT5640_SPK_L_MIXER:
251 case RT5640_SPK_R_MIXER:
252 case RT5640_SPO_L_MIXER:
253 case RT5640_SPO_R_MIXER:
254 case RT5640_SPO_CLSD_RATIO:
255 case RT5640_MONO_MIXER:
256 case RT5640_OUT_L1_MIXER:
257 case RT5640_OUT_L2_MIXER:
258 case RT5640_OUT_L3_MIXER:
259 case RT5640_OUT_R1_MIXER:
260 case RT5640_OUT_R2_MIXER:
261 case RT5640_OUT_R3_MIXER:
262 case RT5640_LOUT_MIXER:
263 case RT5640_PWR_DIG1:
264 case RT5640_PWR_DIG2:
265 case RT5640_PWR_ANLG1:
266 case RT5640_PWR_ANLG2:
267 case RT5640_PWR_MIXER:
268 case RT5640_PWR_VOL:
269 case RT5640_PRIV_INDEX:
270 case RT5640_PRIV_DATA:
271 case RT5640_I2S1_SDP:
272 case RT5640_I2S2_SDP:
273 case RT5640_ADDA_CLK1:
274 case RT5640_ADDA_CLK2:
275 case RT5640_DMIC:
276 case RT5640_GLB_CLK:
277 case RT5640_PLL_CTRL1:
278 case RT5640_PLL_CTRL2:
279 case RT5640_ASRC_1:
280 case RT5640_ASRC_2:
281 case RT5640_ASRC_3:
282 case RT5640_ASRC_4:
283 case RT5640_ASRC_5:
284 case RT5640_HP_OVCD:
285 case RT5640_CLS_D_OVCD:
286 case RT5640_CLS_D_OUT:
287 case RT5640_DEPOP_M1:
288 case RT5640_DEPOP_M2:
289 case RT5640_DEPOP_M3:
290 case RT5640_CHARGE_PUMP:
291 case RT5640_PV_DET_SPK_G:
292 case RT5640_MICBIAS:
293 case RT5640_EQ_CTRL1:
294 case RT5640_EQ_CTRL2:
295 case RT5640_WIND_FILTER:
296 case RT5640_DRC_AGC_1:
297 case RT5640_DRC_AGC_2:
298 case RT5640_DRC_AGC_3:
299 case RT5640_SVOL_ZC:
300 case RT5640_ANC_CTRL1:
301 case RT5640_ANC_CTRL2:
302 case RT5640_ANC_CTRL3:
303 case RT5640_JD_CTRL:
304 case RT5640_ANC_JD:
305 case RT5640_IRQ_CTRL1:
306 case RT5640_IRQ_CTRL2:
307 case RT5640_INT_IRQ_ST:
308 case RT5640_GPIO_CTRL1:
309 case RT5640_GPIO_CTRL2:
310 case RT5640_GPIO_CTRL3:
311 case RT5640_DSP_CTRL1:
312 case RT5640_DSP_CTRL2:
313 case RT5640_DSP_CTRL3:
314 case RT5640_DSP_CTRL4:
315 case RT5640_PGM_REG_ARR1:
316 case RT5640_PGM_REG_ARR2:
317 case RT5640_PGM_REG_ARR3:
318 case RT5640_PGM_REG_ARR4:
319 case RT5640_PGM_REG_ARR5:
320 case RT5640_SCB_FUNC:
321 case RT5640_SCB_CTRL:
322 case RT5640_BASE_BACK:
323 case RT5640_MP3_PLUS1:
324 case RT5640_MP3_PLUS2:
325 case RT5640_3D_HP:
326 case RT5640_ADJ_HPF:
327 case RT5640_HP_CALIB_AMP_DET:
328 case RT5640_HP_CALIB2:
329 case RT5640_SV_ZCD1:
330 case RT5640_SV_ZCD2:
331 case RT5640_DUMMY1:
332 case RT5640_DUMMY2:
333 case RT5640_DUMMY3:
334 case RT5640_VENDOR_ID:
335 case RT5640_VENDOR_ID1:
336 case RT5640_VENDOR_ID2:
337 return true;
338 default:
339 return false;
340 }
341}
342
343static const DECLARE_TLV_DB_SCALE(out_vol_tlv, -4650, 150, 0);
344static const DECLARE_TLV_DB_SCALE(dac_vol_tlv, -65625, 375, 0);
345static const DECLARE_TLV_DB_SCALE(in_vol_tlv, -3450, 150, 0);
346static const DECLARE_TLV_DB_SCALE(adc_vol_tlv, -17625, 375, 0);
347static const DECLARE_TLV_DB_SCALE(adc_bst_tlv, 0, 1200, 0);
348
349/* {0, +20, +24, +30, +35, +40, +44, +50, +52} dB */
350static unsigned int bst_tlv[] = {
351 TLV_DB_RANGE_HEAD(7),
352 0, 0, TLV_DB_SCALE_ITEM(0, 0, 0),
353 1, 1, TLV_DB_SCALE_ITEM(2000, 0, 0),
354 2, 2, TLV_DB_SCALE_ITEM(2400, 0, 0),
355 3, 5, TLV_DB_SCALE_ITEM(3000, 500, 0),
356 6, 6, TLV_DB_SCALE_ITEM(4400, 0, 0),
357 7, 7, TLV_DB_SCALE_ITEM(5000, 0, 0),
358 8, 8, TLV_DB_SCALE_ITEM(5200, 0, 0),
359};
360
361/* Interface data select */
362static const char * const rt5640_data_select[] = {
363 "Normal", "left copy to right", "right copy to left", "Swap"};
364
365static const SOC_ENUM_SINGLE_DECL(rt5640_if1_dac_enum, RT5640_DIG_INF_DATA,
366 RT5640_IF1_DAC_SEL_SFT, rt5640_data_select);
367
368static const SOC_ENUM_SINGLE_DECL(rt5640_if1_adc_enum, RT5640_DIG_INF_DATA,
369 RT5640_IF1_ADC_SEL_SFT, rt5640_data_select);
370
371static const SOC_ENUM_SINGLE_DECL(rt5640_if2_dac_enum, RT5640_DIG_INF_DATA,
372 RT5640_IF2_DAC_SEL_SFT, rt5640_data_select);
373
374static const SOC_ENUM_SINGLE_DECL(rt5640_if2_adc_enum, RT5640_DIG_INF_DATA,
375 RT5640_IF2_ADC_SEL_SFT, rt5640_data_select);
376
377/* Class D speaker gain ratio */
378static const char * const rt5640_clsd_spk_ratio[] = {"1.66x", "1.83x", "1.94x",
379 "2x", "2.11x", "2.22x", "2.33x", "2.44x", "2.55x", "2.66x", "2.77x"};
380
381static const SOC_ENUM_SINGLE_DECL(
382 rt5640_clsd_spk_ratio_enum, RT5640_CLS_D_OUT,
383 RT5640_CLSD_RATIO_SFT, rt5640_clsd_spk_ratio);
384
385static const struct snd_kcontrol_new rt5640_snd_controls[] = {
386 /* Speaker Output Volume */
387 SOC_DOUBLE("Speaker Playback Switch", RT5640_SPK_VOL,
388 RT5640_L_MUTE_SFT, RT5640_R_MUTE_SFT, 1, 1),
389 SOC_DOUBLE("Speaker Channel Switch", RT5640_SPK_VOL,
390 RT5640_VOL_L_SFT, RT5640_VOL_R_SFT, 1, 1),
391 SOC_DOUBLE_TLV("Speaker Playback Volume", RT5640_SPK_VOL,
392 RT5640_L_VOL_SFT, RT5640_R_VOL_SFT, 39, 1, out_vol_tlv),
393 /* Headphone Output Volume */
394 SOC_DOUBLE("HP Playback Switch", RT5640_HP_VOL,
395 RT5640_L_MUTE_SFT, RT5640_R_MUTE_SFT, 1, 1),
396 SOC_DOUBLE("HP Channel Switch", RT5640_HP_VOL,
397 RT5640_VOL_L_SFT, RT5640_VOL_R_SFT, 1, 1),
398 SOC_DOUBLE_TLV("HP Playback Volume", RT5640_HP_VOL,
399 RT5640_L_VOL_SFT, RT5640_R_VOL_SFT, 39, 1, out_vol_tlv),
400 /* OUTPUT Control */
401 SOC_DOUBLE("OUT Playback Switch", RT5640_OUTPUT,
402 RT5640_L_MUTE_SFT, RT5640_R_MUTE_SFT, 1, 1),
403 SOC_DOUBLE("OUT Channel Switch", RT5640_OUTPUT,
404 RT5640_VOL_L_SFT, RT5640_VOL_R_SFT, 1, 1),
405 SOC_DOUBLE_TLV("OUT Playback Volume", RT5640_OUTPUT,
406 RT5640_L_VOL_SFT, RT5640_R_VOL_SFT, 39, 1, out_vol_tlv),
407 /* MONO Output Control */
408 SOC_SINGLE("Mono Playback Switch", RT5640_MONO_OUT,
409 RT5640_L_MUTE_SFT, 1, 1),
410 /* DAC Digital Volume */
411 SOC_DOUBLE("DAC2 Playback Switch", RT5640_DAC2_CTRL,
412 RT5640_M_DAC_L2_VOL_SFT, RT5640_M_DAC_R2_VOL_SFT, 1, 1),
413 SOC_DOUBLE_TLV("DAC1 Playback Volume", RT5640_DAC1_DIG_VOL,
414 RT5640_L_VOL_SFT, RT5640_R_VOL_SFT,
415 175, 0, dac_vol_tlv),
416 SOC_DOUBLE_TLV("Mono DAC Playback Volume", RT5640_DAC2_DIG_VOL,
417 RT5640_L_VOL_SFT, RT5640_R_VOL_SFT,
418 175, 0, dac_vol_tlv),
419 /* IN1/IN2 Control */
420 SOC_SINGLE_TLV("IN1 Boost", RT5640_IN1_IN2,
421 RT5640_BST_SFT1, 8, 0, bst_tlv),
422 SOC_SINGLE_TLV("IN2 Boost", RT5640_IN3_IN4,
423 RT5640_BST_SFT2, 8, 0, bst_tlv),
424 /* INL/INR Volume Control */
425 SOC_DOUBLE_TLV("IN Capture Volume", RT5640_INL_INR_VOL,
426 RT5640_INL_VOL_SFT, RT5640_INR_VOL_SFT,
427 31, 1, in_vol_tlv),
428 /* ADC Digital Volume Control */
429 SOC_DOUBLE("ADC Capture Switch", RT5640_ADC_DIG_VOL,
430 RT5640_L_MUTE_SFT, RT5640_R_MUTE_SFT, 1, 1),
431 SOC_DOUBLE_TLV("ADC Capture Volume", RT5640_ADC_DIG_VOL,
432 RT5640_L_VOL_SFT, RT5640_R_VOL_SFT,
433 127, 0, adc_vol_tlv),
434 SOC_DOUBLE_TLV("Mono ADC Capture Volume", RT5640_ADC_DATA,
435 RT5640_L_VOL_SFT, RT5640_R_VOL_SFT,
436 127, 0, adc_vol_tlv),
437 /* ADC Boost Volume Control */
438 SOC_DOUBLE_TLV("ADC Boost Gain", RT5640_ADC_BST_VOL,
439 RT5640_ADC_L_BST_SFT, RT5640_ADC_R_BST_SFT,
440 3, 0, adc_bst_tlv),
441 /* Class D speaker gain ratio */
442 SOC_ENUM("Class D SPK Ratio Control", rt5640_clsd_spk_ratio_enum),
443
444 SOC_ENUM("ADC IF1 Data Switch", rt5640_if1_adc_enum),
445 SOC_ENUM("DAC IF1 Data Switch", rt5640_if1_dac_enum),
446 SOC_ENUM("ADC IF2 Data Switch", rt5640_if2_adc_enum),
447 SOC_ENUM("DAC IF2 Data Switch", rt5640_if2_dac_enum),
448};
449
450/**
451 * set_dmic_clk - Set parameter of dmic.
452 *
453 * @w: DAPM widget.
454 * @kcontrol: The kcontrol of this widget.
455 * @event: Event id.
456 *
457 * Choose dmic clock between 1MHz and 3MHz.
458 * It is better for clock to approximate 3MHz.
459 */
460static int set_dmic_clk(struct snd_soc_dapm_widget *w,
461 struct snd_kcontrol *kcontrol, int event)
462{
463 struct snd_soc_codec *codec = w->codec;
464 struct rt5640_priv *rt5640 = snd_soc_codec_get_drvdata(codec);
465 int div[] = {2, 3, 4, 6, 8, 12};
466 int idx = -EINVAL, i;
467 int rate, red, bound, temp;
468
469 rate = rt5640->sysclk;
470 red = 3000000 * 12;
471 for (i = 0; i < ARRAY_SIZE(div); i++) {
472 bound = div[i] * 3000000;
473 if (rate > bound)
474 continue;
475 temp = bound - rate;
476 if (temp < red) {
477 red = temp;
478 idx = i;
479 }
480 }
481 if (idx < 0)
482 dev_err(codec->dev, "Failed to set DMIC clock\n");
483 else
484 snd_soc_update_bits(codec, RT5640_DMIC, RT5640_DMIC_CLK_MASK,
485 idx << RT5640_DMIC_CLK_SFT);
486 return idx;
487}
488
489static int check_sysclk1_source(struct snd_soc_dapm_widget *source,
490 struct snd_soc_dapm_widget *sink)
491{
492 unsigned int val;
493
494 val = snd_soc_read(source->codec, RT5640_GLB_CLK);
495 val &= RT5640_SCLK_SRC_MASK;
496 if (val == RT5640_SCLK_SRC_PLL1 || val == RT5640_SCLK_SRC_PLL1T)
497 return 1;
498 else
499 return 0;
500}
501
502/* Digital Mixer */
503static const struct snd_kcontrol_new rt5640_sto_adc_l_mix[] = {
504 SOC_DAPM_SINGLE("ADC1 Switch", RT5640_STO_ADC_MIXER,
505 RT5640_M_ADC_L1_SFT, 1, 1),
506 SOC_DAPM_SINGLE("ADC2 Switch", RT5640_STO_ADC_MIXER,
507 RT5640_M_ADC_L2_SFT, 1, 1),
508};
509
510static const struct snd_kcontrol_new rt5640_sto_adc_r_mix[] = {
511 SOC_DAPM_SINGLE("ADC1 Switch", RT5640_STO_ADC_MIXER,
512 RT5640_M_ADC_R1_SFT, 1, 1),
513 SOC_DAPM_SINGLE("ADC2 Switch", RT5640_STO_ADC_MIXER,
514 RT5640_M_ADC_R2_SFT, 1, 1),
515};
516
517static const struct snd_kcontrol_new rt5640_mono_adc_l_mix[] = {
518 SOC_DAPM_SINGLE("ADC1 Switch", RT5640_MONO_ADC_MIXER,
519 RT5640_M_MONO_ADC_L1_SFT, 1, 1),
520 SOC_DAPM_SINGLE("ADC2 Switch", RT5640_MONO_ADC_MIXER,
521 RT5640_M_MONO_ADC_L2_SFT, 1, 1),
522};
523
524static const struct snd_kcontrol_new rt5640_mono_adc_r_mix[] = {
525 SOC_DAPM_SINGLE("ADC1 Switch", RT5640_MONO_ADC_MIXER,
526 RT5640_M_MONO_ADC_R1_SFT, 1, 1),
527 SOC_DAPM_SINGLE("ADC2 Switch", RT5640_MONO_ADC_MIXER,
528 RT5640_M_MONO_ADC_R2_SFT, 1, 1),
529};
530
531static const struct snd_kcontrol_new rt5640_dac_l_mix[] = {
532 SOC_DAPM_SINGLE("Stereo ADC Switch", RT5640_AD_DA_MIXER,
533 RT5640_M_ADCMIX_L_SFT, 1, 1),
534 SOC_DAPM_SINGLE("INF1 Switch", RT5640_AD_DA_MIXER,
535 RT5640_M_IF1_DAC_L_SFT, 1, 1),
536};
537
538static const struct snd_kcontrol_new rt5640_dac_r_mix[] = {
539 SOC_DAPM_SINGLE("Stereo ADC Switch", RT5640_AD_DA_MIXER,
540 RT5640_M_ADCMIX_R_SFT, 1, 1),
541 SOC_DAPM_SINGLE("INF1 Switch", RT5640_AD_DA_MIXER,
542 RT5640_M_IF1_DAC_R_SFT, 1, 1),
543};
544
545static const struct snd_kcontrol_new rt5640_sto_dac_l_mix[] = {
546 SOC_DAPM_SINGLE("DAC L1 Switch", RT5640_STO_DAC_MIXER,
547 RT5640_M_DAC_L1_SFT, 1, 1),
548 SOC_DAPM_SINGLE("DAC L2 Switch", RT5640_STO_DAC_MIXER,
549 RT5640_M_DAC_L2_SFT, 1, 1),
550 SOC_DAPM_SINGLE("ANC Switch", RT5640_STO_DAC_MIXER,
551 RT5640_M_ANC_DAC_L_SFT, 1, 1),
552};
553
554static const struct snd_kcontrol_new rt5640_sto_dac_r_mix[] = {
555 SOC_DAPM_SINGLE("DAC R1 Switch", RT5640_STO_DAC_MIXER,
556 RT5640_M_DAC_R1_SFT, 1, 1),
557 SOC_DAPM_SINGLE("DAC R2 Switch", RT5640_STO_DAC_MIXER,
558 RT5640_M_DAC_R2_SFT, 1, 1),
559 SOC_DAPM_SINGLE("ANC Switch", RT5640_STO_DAC_MIXER,
560 RT5640_M_ANC_DAC_R_SFT, 1, 1),
561};
562
563static const struct snd_kcontrol_new rt5640_mono_dac_l_mix[] = {
564 SOC_DAPM_SINGLE("DAC L1 Switch", RT5640_MONO_DAC_MIXER,
565 RT5640_M_DAC_L1_MONO_L_SFT, 1, 1),
566 SOC_DAPM_SINGLE("DAC L2 Switch", RT5640_MONO_DAC_MIXER,
567 RT5640_M_DAC_L2_MONO_L_SFT, 1, 1),
568 SOC_DAPM_SINGLE("DAC R2 Switch", RT5640_MONO_DAC_MIXER,
569 RT5640_M_DAC_R2_MONO_L_SFT, 1, 1),
570};
571
572static const struct snd_kcontrol_new rt5640_mono_dac_r_mix[] = {
573 SOC_DAPM_SINGLE("DAC R1 Switch", RT5640_MONO_DAC_MIXER,
574 RT5640_M_DAC_R1_MONO_R_SFT, 1, 1),
575 SOC_DAPM_SINGLE("DAC R2 Switch", RT5640_MONO_DAC_MIXER,
576 RT5640_M_DAC_R2_MONO_R_SFT, 1, 1),
577 SOC_DAPM_SINGLE("DAC L2 Switch", RT5640_MONO_DAC_MIXER,
578 RT5640_M_DAC_L2_MONO_R_SFT, 1, 1),
579};
580
581static const struct snd_kcontrol_new rt5640_dig_l_mix[] = {
582 SOC_DAPM_SINGLE("DAC L1 Switch", RT5640_DIG_MIXER,
583 RT5640_M_STO_L_DAC_L_SFT, 1, 1),
584 SOC_DAPM_SINGLE("DAC L2 Switch", RT5640_DIG_MIXER,
585 RT5640_M_DAC_L2_DAC_L_SFT, 1, 1),
586};
587
588static const struct snd_kcontrol_new rt5640_dig_r_mix[] = {
589 SOC_DAPM_SINGLE("DAC R1 Switch", RT5640_DIG_MIXER,
590 RT5640_M_STO_R_DAC_R_SFT, 1, 1),
591 SOC_DAPM_SINGLE("DAC R2 Switch", RT5640_DIG_MIXER,
592 RT5640_M_DAC_R2_DAC_R_SFT, 1, 1),
593};
594
595/* Analog Input Mixer */
596static const struct snd_kcontrol_new rt5640_rec_l_mix[] = {
597 SOC_DAPM_SINGLE("HPOL Switch", RT5640_REC_L2_MIXER,
598 RT5640_M_HP_L_RM_L_SFT, 1, 1),
599 SOC_DAPM_SINGLE("INL Switch", RT5640_REC_L2_MIXER,
600 RT5640_M_IN_L_RM_L_SFT, 1, 1),
601 SOC_DAPM_SINGLE("BST2 Switch", RT5640_REC_L2_MIXER,
602 RT5640_M_BST4_RM_L_SFT, 1, 1),
603 SOC_DAPM_SINGLE("BST1 Switch", RT5640_REC_L2_MIXER,
604 RT5640_M_BST1_RM_L_SFT, 1, 1),
605 SOC_DAPM_SINGLE("OUT MIXL Switch", RT5640_REC_L2_MIXER,
606 RT5640_M_OM_L_RM_L_SFT, 1, 1),
607};
608
609static const struct snd_kcontrol_new rt5640_rec_r_mix[] = {
610 SOC_DAPM_SINGLE("HPOR Switch", RT5640_REC_R2_MIXER,
611 RT5640_M_HP_R_RM_R_SFT, 1, 1),
612 SOC_DAPM_SINGLE("INR Switch", RT5640_REC_R2_MIXER,
613 RT5640_M_IN_R_RM_R_SFT, 1, 1),
614 SOC_DAPM_SINGLE("BST2 Switch", RT5640_REC_R2_MIXER,
615 RT5640_M_BST4_RM_R_SFT, 1, 1),
616 SOC_DAPM_SINGLE("BST1 Switch", RT5640_REC_R2_MIXER,
617 RT5640_M_BST1_RM_R_SFT, 1, 1),
618 SOC_DAPM_SINGLE("OUT MIXR Switch", RT5640_REC_R2_MIXER,
619 RT5640_M_OM_R_RM_R_SFT, 1, 1),
620};
621
622/* Analog Output Mixer */
623static const struct snd_kcontrol_new rt5640_spk_l_mix[] = {
624 SOC_DAPM_SINGLE("REC MIXL Switch", RT5640_SPK_L_MIXER,
625 RT5640_M_RM_L_SM_L_SFT, 1, 1),
626 SOC_DAPM_SINGLE("INL Switch", RT5640_SPK_L_MIXER,
627 RT5640_M_IN_L_SM_L_SFT, 1, 1),
628 SOC_DAPM_SINGLE("DAC L1 Switch", RT5640_SPK_L_MIXER,
629 RT5640_M_DAC_L1_SM_L_SFT, 1, 1),
630 SOC_DAPM_SINGLE("DAC L2 Switch", RT5640_SPK_L_MIXER,
631 RT5640_M_DAC_L2_SM_L_SFT, 1, 1),
632 SOC_DAPM_SINGLE("OUT MIXL Switch", RT5640_SPK_L_MIXER,
633 RT5640_M_OM_L_SM_L_SFT, 1, 1),
634};
635
636static const struct snd_kcontrol_new rt5640_spk_r_mix[] = {
637 SOC_DAPM_SINGLE("REC MIXR Switch", RT5640_SPK_R_MIXER,
638 RT5640_M_RM_R_SM_R_SFT, 1, 1),
639 SOC_DAPM_SINGLE("INR Switch", RT5640_SPK_R_MIXER,
640 RT5640_M_IN_R_SM_R_SFT, 1, 1),
641 SOC_DAPM_SINGLE("DAC R1 Switch", RT5640_SPK_R_MIXER,
642 RT5640_M_DAC_R1_SM_R_SFT, 1, 1),
643 SOC_DAPM_SINGLE("DAC R2 Switch", RT5640_SPK_R_MIXER,
644 RT5640_M_DAC_R2_SM_R_SFT, 1, 1),
645 SOC_DAPM_SINGLE("OUT MIXR Switch", RT5640_SPK_R_MIXER,
646 RT5640_M_OM_R_SM_R_SFT, 1, 1),
647};
648
649static const struct snd_kcontrol_new rt5640_out_l_mix[] = {
650 SOC_DAPM_SINGLE("SPK MIXL Switch", RT5640_OUT_L3_MIXER,
651 RT5640_M_SM_L_OM_L_SFT, 1, 1),
652 SOC_DAPM_SINGLE("BST1 Switch", RT5640_OUT_L3_MIXER,
653 RT5640_M_BST1_OM_L_SFT, 1, 1),
654 SOC_DAPM_SINGLE("INL Switch", RT5640_OUT_L3_MIXER,
655 RT5640_M_IN_L_OM_L_SFT, 1, 1),
656 SOC_DAPM_SINGLE("REC MIXL Switch", RT5640_OUT_L3_MIXER,
657 RT5640_M_RM_L_OM_L_SFT, 1, 1),
658 SOC_DAPM_SINGLE("DAC R2 Switch", RT5640_OUT_L3_MIXER,
659 RT5640_M_DAC_R2_OM_L_SFT, 1, 1),
660 SOC_DAPM_SINGLE("DAC L2 Switch", RT5640_OUT_L3_MIXER,
661 RT5640_M_DAC_L2_OM_L_SFT, 1, 1),
662 SOC_DAPM_SINGLE("DAC L1 Switch", RT5640_OUT_L3_MIXER,
663 RT5640_M_DAC_L1_OM_L_SFT, 1, 1),
664};
665
666static const struct snd_kcontrol_new rt5640_out_r_mix[] = {
667 SOC_DAPM_SINGLE("SPK MIXR Switch", RT5640_OUT_R3_MIXER,
668 RT5640_M_SM_L_OM_R_SFT, 1, 1),
669 SOC_DAPM_SINGLE("BST2 Switch", RT5640_OUT_R3_MIXER,
670 RT5640_M_BST4_OM_R_SFT, 1, 1),
671 SOC_DAPM_SINGLE("BST1 Switch", RT5640_OUT_R3_MIXER,
672 RT5640_M_BST1_OM_R_SFT, 1, 1),
673 SOC_DAPM_SINGLE("INR Switch", RT5640_OUT_R3_MIXER,
674 RT5640_M_IN_R_OM_R_SFT, 1, 1),
675 SOC_DAPM_SINGLE("REC MIXR Switch", RT5640_OUT_R3_MIXER,
676 RT5640_M_RM_R_OM_R_SFT, 1, 1),
677 SOC_DAPM_SINGLE("DAC L2 Switch", RT5640_OUT_R3_MIXER,
678 RT5640_M_DAC_L2_OM_R_SFT, 1, 1),
679 SOC_DAPM_SINGLE("DAC R2 Switch", RT5640_OUT_R3_MIXER,
680 RT5640_M_DAC_R2_OM_R_SFT, 1, 1),
681 SOC_DAPM_SINGLE("DAC R1 Switch", RT5640_OUT_R3_MIXER,
682 RT5640_M_DAC_R1_OM_R_SFT, 1, 1),
683};
684
685static const struct snd_kcontrol_new rt5640_spo_l_mix[] = {
686 SOC_DAPM_SINGLE("DAC R1 Switch", RT5640_SPO_L_MIXER,
687 RT5640_M_DAC_R1_SPM_L_SFT, 1, 1),
688 SOC_DAPM_SINGLE("DAC L1 Switch", RT5640_SPO_L_MIXER,
689 RT5640_M_DAC_L1_SPM_L_SFT, 1, 1),
690 SOC_DAPM_SINGLE("SPKVOL R Switch", RT5640_SPO_L_MIXER,
691 RT5640_M_SV_R_SPM_L_SFT, 1, 1),
692 SOC_DAPM_SINGLE("SPKVOL L Switch", RT5640_SPO_L_MIXER,
693 RT5640_M_SV_L_SPM_L_SFT, 1, 1),
694 SOC_DAPM_SINGLE("BST1 Switch", RT5640_SPO_L_MIXER,
695 RT5640_M_BST1_SPM_L_SFT, 1, 1),
696};
697
698static const struct snd_kcontrol_new rt5640_spo_r_mix[] = {
699 SOC_DAPM_SINGLE("DAC R1 Switch", RT5640_SPO_R_MIXER,
700 RT5640_M_DAC_R1_SPM_R_SFT, 1, 1),
701 SOC_DAPM_SINGLE("SPKVOL R Switch", RT5640_SPO_R_MIXER,
702 RT5640_M_SV_R_SPM_R_SFT, 1, 1),
703 SOC_DAPM_SINGLE("BST1 Switch", RT5640_SPO_R_MIXER,
704 RT5640_M_BST1_SPM_R_SFT, 1, 1),
705};
706
707static const struct snd_kcontrol_new rt5640_hpo_mix[] = {
708 SOC_DAPM_SINGLE("HPO MIX DAC2 Switch", RT5640_HPO_MIXER,
709 RT5640_M_DAC2_HM_SFT, 1, 1),
710 SOC_DAPM_SINGLE("HPO MIX DAC1 Switch", RT5640_HPO_MIXER,
711 RT5640_M_DAC1_HM_SFT, 1, 1),
712 SOC_DAPM_SINGLE("HPO MIX HPVOL Switch", RT5640_HPO_MIXER,
713 RT5640_M_HPVOL_HM_SFT, 1, 1),
714};
715
716static const struct snd_kcontrol_new rt5640_lout_mix[] = {
717 SOC_DAPM_SINGLE("DAC L1 Switch", RT5640_LOUT_MIXER,
718 RT5640_M_DAC_L1_LM_SFT, 1, 1),
719 SOC_DAPM_SINGLE("DAC R1 Switch", RT5640_LOUT_MIXER,
720 RT5640_M_DAC_R1_LM_SFT, 1, 1),
721 SOC_DAPM_SINGLE("OUTVOL L Switch", RT5640_LOUT_MIXER,
722 RT5640_M_OV_L_LM_SFT, 1, 1),
723 SOC_DAPM_SINGLE("OUTVOL R Switch", RT5640_LOUT_MIXER,
724 RT5640_M_OV_R_LM_SFT, 1, 1),
725};
726
727static const struct snd_kcontrol_new rt5640_mono_mix[] = {
728 SOC_DAPM_SINGLE("DAC R2 Switch", RT5640_MONO_MIXER,
729 RT5640_M_DAC_R2_MM_SFT, 1, 1),
730 SOC_DAPM_SINGLE("DAC L2 Switch", RT5640_MONO_MIXER,
731 RT5640_M_DAC_L2_MM_SFT, 1, 1),
732 SOC_DAPM_SINGLE("OUTVOL R Switch", RT5640_MONO_MIXER,
733 RT5640_M_OV_R_MM_SFT, 1, 1),
734 SOC_DAPM_SINGLE("OUTVOL L Switch", RT5640_MONO_MIXER,
735 RT5640_M_OV_L_MM_SFT, 1, 1),
736 SOC_DAPM_SINGLE("BST1 Switch", RT5640_MONO_MIXER,
737 RT5640_M_BST1_MM_SFT, 1, 1),
738};
739
740/* INL/R source */
741static const char * const rt5640_inl_src[] = {
742 "IN2P", "MONOP"
743};
744
745static const SOC_ENUM_SINGLE_DECL(
746 rt5640_inl_enum, RT5640_INL_INR_VOL,
747 RT5640_INL_SEL_SFT, rt5640_inl_src);
748
749static const struct snd_kcontrol_new rt5640_inl_mux =
750 SOC_DAPM_ENUM("INL source", rt5640_inl_enum);
751
752static const char * const rt5640_inr_src[] = {
753 "IN2N", "MONON"
754};
755
756static const SOC_ENUM_SINGLE_DECL(
757 rt5640_inr_enum, RT5640_INL_INR_VOL,
758 RT5640_INR_SEL_SFT, rt5640_inr_src);
759
760static const struct snd_kcontrol_new rt5640_inr_mux =
761 SOC_DAPM_ENUM("INR source", rt5640_inr_enum);
762
763/* Stereo ADC source */
764static const char * const rt5640_stereo_adc1_src[] = {
765 "DIG MIX", "ADC"
766};
767
768static const SOC_ENUM_SINGLE_DECL(
769 rt5640_stereo_adc1_enum, RT5640_STO_ADC_MIXER,
770 RT5640_ADC_1_SRC_SFT, rt5640_stereo_adc1_src);
771
772static const struct snd_kcontrol_new rt5640_sto_adc_1_mux =
773 SOC_DAPM_ENUM("Stereo ADC1 Mux", rt5640_stereo_adc1_enum);
774
775static const char * const rt5640_stereo_adc2_src[] = {
776 "DMIC1", "DMIC2", "DIG MIX"
777};
778
779static const SOC_ENUM_SINGLE_DECL(
780 rt5640_stereo_adc2_enum, RT5640_STO_ADC_MIXER,
781 RT5640_ADC_2_SRC_SFT, rt5640_stereo_adc2_src);
782
783static const struct snd_kcontrol_new rt5640_sto_adc_2_mux =
784 SOC_DAPM_ENUM("Stereo ADC2 Mux", rt5640_stereo_adc2_enum);
785
786/* Mono ADC source */
787static const char * const rt5640_mono_adc_l1_src[] = {
788 "Mono DAC MIXL", "ADCL"
789};
790
791static const SOC_ENUM_SINGLE_DECL(
792 rt5640_mono_adc_l1_enum, RT5640_MONO_ADC_MIXER,
793 RT5640_MONO_ADC_L1_SRC_SFT, rt5640_mono_adc_l1_src);
794
795static const struct snd_kcontrol_new rt5640_mono_adc_l1_mux =
796 SOC_DAPM_ENUM("Mono ADC1 left source", rt5640_mono_adc_l1_enum);
797
798static const char * const rt5640_mono_adc_l2_src[] = {
799 "DMIC L1", "DMIC L2", "Mono DAC MIXL"
800};
801
802static const SOC_ENUM_SINGLE_DECL(
803 rt5640_mono_adc_l2_enum, RT5640_MONO_ADC_MIXER,
804 RT5640_MONO_ADC_L2_SRC_SFT, rt5640_mono_adc_l2_src);
805
806static const struct snd_kcontrol_new rt5640_mono_adc_l2_mux =
807 SOC_DAPM_ENUM("Mono ADC2 left source", rt5640_mono_adc_l2_enum);
808
809static const char * const rt5640_mono_adc_r1_src[] = {
810 "Mono DAC MIXR", "ADCR"
811};
812
813static const SOC_ENUM_SINGLE_DECL(
814 rt5640_mono_adc_r1_enum, RT5640_MONO_ADC_MIXER,
815 RT5640_MONO_ADC_R1_SRC_SFT, rt5640_mono_adc_r1_src);
816
817static const struct snd_kcontrol_new rt5640_mono_adc_r1_mux =
818 SOC_DAPM_ENUM("Mono ADC1 right source", rt5640_mono_adc_r1_enum);
819
820static const char * const rt5640_mono_adc_r2_src[] = {
821 "DMIC R1", "DMIC R2", "Mono DAC MIXR"
822};
823
824static const SOC_ENUM_SINGLE_DECL(
825 rt5640_mono_adc_r2_enum, RT5640_MONO_ADC_MIXER,
826 RT5640_MONO_ADC_R2_SRC_SFT, rt5640_mono_adc_r2_src);
827
828static const struct snd_kcontrol_new rt5640_mono_adc_r2_mux =
829 SOC_DAPM_ENUM("Mono ADC2 right source", rt5640_mono_adc_r2_enum);
830
831/* DAC2 channel source */
832static const char * const rt5640_dac_l2_src[] = {
833 "IF2", "Base L/R"
834};
835
836static int rt5640_dac_l2_values[] = {
837 0,
838 3,
839};
840
841static const SOC_VALUE_ENUM_SINGLE_DECL(
842 rt5640_dac_l2_enum, RT5640_DSP_PATH2, RT5640_DAC_L2_SEL_SFT,
843 0x3, rt5640_dac_l2_src, rt5640_dac_l2_values);
844
845static const struct snd_kcontrol_new rt5640_dac_l2_mux =
846 SOC_DAPM_VALUE_ENUM("DAC2 left channel source", rt5640_dac_l2_enum);
847
848static const char * const rt5640_dac_r2_src[] = {
849 "IF2",
850};
851
852static int rt5640_dac_r2_values[] = {
853 0,
854};
855
856static const SOC_VALUE_ENUM_SINGLE_DECL(
857 rt5640_dac_r2_enum, RT5640_DSP_PATH2, RT5640_DAC_R2_SEL_SFT,
858 0x3, rt5640_dac_r2_src, rt5640_dac_r2_values);
859
860static const struct snd_kcontrol_new rt5640_dac_r2_mux =
861 SOC_DAPM_ENUM("DAC2 right channel source", rt5640_dac_r2_enum);
862
863/* digital interface and iis interface map */
864static const char * const rt5640_dai_iis_map[] = {
865 "1:1|2:2", "1:2|2:1", "1:1|2:1", "1:2|2:2"
866};
867
868static int rt5640_dai_iis_map_values[] = {
869 0,
870 5,
871 6,
872 7,
873};
874
875static const SOC_VALUE_ENUM_SINGLE_DECL(
876 rt5640_dai_iis_map_enum, RT5640_I2S1_SDP, RT5640_I2S_IF_SFT,
877 0x7, rt5640_dai_iis_map, rt5640_dai_iis_map_values);
878
879static const struct snd_kcontrol_new rt5640_dai_mux =
880 SOC_DAPM_VALUE_ENUM("DAI select", rt5640_dai_iis_map_enum);
881
882/* SDI select */
883static const char * const rt5640_sdi_sel[] = {
884 "IF1", "IF2"
885};
886
887static const SOC_ENUM_SINGLE_DECL(
888 rt5640_sdi_sel_enum, RT5640_I2S2_SDP,
889 RT5640_I2S2_SDI_SFT, rt5640_sdi_sel);
890
891static const struct snd_kcontrol_new rt5640_sdi_mux =
892 SOC_DAPM_ENUM("SDI select", rt5640_sdi_sel_enum);
893
894static int spk_event(struct snd_soc_dapm_widget *w,
895 struct snd_kcontrol *kcontrol, int event)
896{
897 struct snd_soc_codec *codec = w->codec;
898 struct rt5640_priv *rt5640 = snd_soc_codec_get_drvdata(codec);
899
900 switch (event) {
901 case SND_SOC_DAPM_POST_PMU:
902 regmap_update_bits(rt5640->regmap, RT5640_PWR_DIG1,
903 0x0001, 0x0001);
904 regmap_update_bits(rt5640->regmap, RT5640_PR_BASE + 0x1c,
905 0xf000, 0xf000);
906 break;
907
908 case SND_SOC_DAPM_PRE_PMD:
909 regmap_update_bits(rt5640->regmap, RT5640_PR_BASE + 0x1c,
910 0xf000, 0x0000);
911 regmap_update_bits(rt5640->regmap, RT5640_PWR_DIG1,
912 0x0001, 0x0000);
913 break;
914
915 default:
916 return 0;
917 }
918 return 0;
919}
920
921static int rt5640_set_dmic1_event(struct snd_soc_dapm_widget *w,
922 struct snd_kcontrol *kcontrol, int event)
923{
924 struct snd_soc_codec *codec = w->codec;
925
926 switch (event) {
927 case SND_SOC_DAPM_PRE_PMU:
928 snd_soc_update_bits(codec, RT5640_GPIO_CTRL1,
929 RT5640_GP2_PIN_MASK | RT5640_GP3_PIN_MASK,
930 RT5640_GP2_PIN_DMIC1_SCL | RT5640_GP3_PIN_DMIC1_SDA);
931 snd_soc_update_bits(codec, RT5640_DMIC,
932 RT5640_DMIC_1L_LH_MASK | RT5640_DMIC_1R_LH_MASK |
933 RT5640_DMIC_1_DP_MASK,
934 RT5640_DMIC_1L_LH_FALLING | RT5640_DMIC_1R_LH_RISING |
935 RT5640_DMIC_1_DP_IN1P);
936 break;
937
938 default:
939 return 0;
940 }
941
942 return 0;
943}
944
945static int rt5640_set_dmic2_event(struct snd_soc_dapm_widget *w,
946 struct snd_kcontrol *kcontrol, int event)
947{
948 struct snd_soc_codec *codec = w->codec;
949
950 switch (event) {
951 case SND_SOC_DAPM_PRE_PMU:
952 snd_soc_update_bits(codec, RT5640_GPIO_CTRL1,
953 RT5640_GP2_PIN_MASK | RT5640_GP4_PIN_MASK,
954 RT5640_GP2_PIN_DMIC1_SCL | RT5640_GP4_PIN_DMIC2_SDA);
955 snd_soc_update_bits(codec, RT5640_DMIC,
956 RT5640_DMIC_2L_LH_MASK | RT5640_DMIC_2R_LH_MASK |
957 RT5640_DMIC_2_DP_MASK,
958 RT5640_DMIC_2L_LH_FALLING | RT5640_DMIC_2R_LH_RISING |
959 RT5640_DMIC_2_DP_IN1N);
960 break;
961
962 default:
963 return 0;
964 }
965
966 return 0;
967}
968
969static const struct snd_soc_dapm_widget rt5640_dapm_widgets[] = {
970 SND_SOC_DAPM_SUPPLY("PLL1", RT5640_PWR_ANLG2,
971 RT5640_PWR_PLL_BIT, 0, NULL, 0),
972 /* Input Side */
973 /* micbias */
974 SND_SOC_DAPM_SUPPLY("LDO2", RT5640_PWR_ANLG1,
975 RT5640_PWR_LDO2_BIT, 0, NULL, 0),
976 SND_SOC_DAPM_SUPPLY("MICBIAS1", RT5640_PWR_ANLG2,
977 RT5640_PWR_MB1_BIT, 0, NULL, 0),
978 /* Input Lines */
979 SND_SOC_DAPM_INPUT("DMIC1"),
980 SND_SOC_DAPM_INPUT("DMIC2"),
981 SND_SOC_DAPM_INPUT("IN1P"),
982 SND_SOC_DAPM_INPUT("IN1N"),
983 SND_SOC_DAPM_INPUT("IN2P"),
984 SND_SOC_DAPM_INPUT("IN2N"),
985 SND_SOC_DAPM_PGA("DMIC L1", SND_SOC_NOPM, 0, 0, NULL, 0),
986 SND_SOC_DAPM_PGA("DMIC R1", SND_SOC_NOPM, 0, 0, NULL, 0),
987 SND_SOC_DAPM_PGA("DMIC L2", SND_SOC_NOPM, 0, 0, NULL, 0),
988 SND_SOC_DAPM_PGA("DMIC R2", SND_SOC_NOPM, 0, 0, NULL, 0),
989
990 SND_SOC_DAPM_SUPPLY("DMIC CLK", SND_SOC_NOPM, 0, 0,
991 set_dmic_clk, SND_SOC_DAPM_PRE_PMU),
992 SND_SOC_DAPM_SUPPLY("DMIC1 Power", RT5640_DMIC,
993 RT5640_DMIC_1_EN_SFT, 0, rt5640_set_dmic1_event,
994 SND_SOC_DAPM_PRE_PMU),
995 SND_SOC_DAPM_SUPPLY("DMIC2 Power", RT5640_DMIC,
996 RT5640_DMIC_2_EN_SFT, 0, rt5640_set_dmic2_event,
997 SND_SOC_DAPM_PRE_PMU),
998 /* Boost */
999 SND_SOC_DAPM_PGA("BST1", RT5640_PWR_ANLG2,
1000 RT5640_PWR_BST1_BIT, 0, NULL, 0),
1001 SND_SOC_DAPM_PGA("BST2", RT5640_PWR_ANLG2,
1002 RT5640_PWR_BST4_BIT, 0, NULL, 0),
1003 /* Input Volume */
1004 SND_SOC_DAPM_PGA("INL VOL", RT5640_PWR_VOL,
1005 RT5640_PWR_IN_L_BIT, 0, NULL, 0),
1006 SND_SOC_DAPM_PGA("INR VOL", RT5640_PWR_VOL,
1007 RT5640_PWR_IN_R_BIT, 0, NULL, 0),
1008 /* IN Mux */
1009 SND_SOC_DAPM_MUX("INL Mux", SND_SOC_NOPM, 0, 0, &rt5640_inl_mux),
1010 SND_SOC_DAPM_MUX("INR Mux", SND_SOC_NOPM, 0, 0, &rt5640_inr_mux),
1011 /* REC Mixer */
1012 SND_SOC_DAPM_MIXER("RECMIXL", RT5640_PWR_MIXER, RT5640_PWR_RM_L_BIT, 0,
1013 rt5640_rec_l_mix, ARRAY_SIZE(rt5640_rec_l_mix)),
1014 SND_SOC_DAPM_MIXER("RECMIXR", RT5640_PWR_MIXER, RT5640_PWR_RM_R_BIT, 0,
1015 rt5640_rec_r_mix, ARRAY_SIZE(rt5640_rec_r_mix)),
1016 /* ADCs */
1017 SND_SOC_DAPM_ADC("ADC L", NULL, RT5640_PWR_DIG1,
1018 RT5640_PWR_ADC_L_BIT, 0),
1019 SND_SOC_DAPM_ADC("ADC R", NULL, RT5640_PWR_DIG1,
1020 RT5640_PWR_ADC_R_BIT, 0),
1021 /* ADC Mux */
1022 SND_SOC_DAPM_MUX("Stereo ADC L2 Mux", SND_SOC_NOPM, 0, 0,
1023 &rt5640_sto_adc_2_mux),
1024 SND_SOC_DAPM_MUX("Stereo ADC R2 Mux", SND_SOC_NOPM, 0, 0,
1025 &rt5640_sto_adc_2_mux),
1026 SND_SOC_DAPM_MUX("Stereo ADC L1 Mux", SND_SOC_NOPM, 0, 0,
1027 &rt5640_sto_adc_1_mux),
1028 SND_SOC_DAPM_MUX("Stereo ADC R1 Mux", SND_SOC_NOPM, 0, 0,
1029 &rt5640_sto_adc_1_mux),
1030 SND_SOC_DAPM_MUX("Mono ADC L2 Mux", SND_SOC_NOPM, 0, 0,
1031 &rt5640_mono_adc_l2_mux),
1032 SND_SOC_DAPM_MUX("Mono ADC L1 Mux", SND_SOC_NOPM, 0, 0,
1033 &rt5640_mono_adc_l1_mux),
1034 SND_SOC_DAPM_MUX("Mono ADC R1 Mux", SND_SOC_NOPM, 0, 0,
1035 &rt5640_mono_adc_r1_mux),
1036 SND_SOC_DAPM_MUX("Mono ADC R2 Mux", SND_SOC_NOPM, 0, 0,
1037 &rt5640_mono_adc_r2_mux),
1038 /* ADC Mixer */
1039 SND_SOC_DAPM_SUPPLY("Stereo Filter", RT5640_PWR_DIG2,
1040 RT5640_PWR_ADC_SF_BIT, 0, NULL, 0),
1041 SND_SOC_DAPM_MIXER("Stereo ADC MIXL", SND_SOC_NOPM, 0, 0,
1042 rt5640_sto_adc_l_mix, ARRAY_SIZE(rt5640_sto_adc_l_mix)),
1043 SND_SOC_DAPM_MIXER("Stereo ADC MIXR", SND_SOC_NOPM, 0, 0,
1044 rt5640_sto_adc_r_mix, ARRAY_SIZE(rt5640_sto_adc_r_mix)),
1045 SND_SOC_DAPM_SUPPLY("Mono Left Filter", RT5640_PWR_DIG2,
1046 RT5640_PWR_ADC_MF_L_BIT, 0, NULL, 0),
1047 SND_SOC_DAPM_MIXER("Mono ADC MIXL", SND_SOC_NOPM, 0, 0,
1048 rt5640_mono_adc_l_mix, ARRAY_SIZE(rt5640_mono_adc_l_mix)),
1049 SND_SOC_DAPM_SUPPLY("Mono Right Filter", RT5640_PWR_DIG2,
1050 RT5640_PWR_ADC_MF_R_BIT, 0, NULL, 0),
1051 SND_SOC_DAPM_MIXER("Mono ADC MIXR", SND_SOC_NOPM, 0, 0,
1052 rt5640_mono_adc_r_mix, ARRAY_SIZE(rt5640_mono_adc_r_mix)),
1053
1054 /* Digital Interface */
1055 SND_SOC_DAPM_SUPPLY("I2S1", RT5640_PWR_DIG1,
1056 RT5640_PWR_I2S1_BIT, 0, NULL, 0),
1057 SND_SOC_DAPM_PGA("IF1 DAC", SND_SOC_NOPM, 0, 0, NULL, 0),
1058 SND_SOC_DAPM_PGA("IF1 DAC L", SND_SOC_NOPM, 0, 0, NULL, 0),
1059 SND_SOC_DAPM_PGA("IF1 DAC R", SND_SOC_NOPM, 0, 0, NULL, 0),
1060 SND_SOC_DAPM_PGA("IF1 ADC", SND_SOC_NOPM, 0, 0, NULL, 0),
1061 SND_SOC_DAPM_PGA("IF1 ADC L", SND_SOC_NOPM, 0, 0, NULL, 0),
1062 SND_SOC_DAPM_PGA("IF1 ADC R", SND_SOC_NOPM, 0, 0, NULL, 0),
1063 SND_SOC_DAPM_SUPPLY("I2S2", RT5640_PWR_DIG1,
1064 RT5640_PWR_I2S2_BIT, 0, NULL, 0),
1065 SND_SOC_DAPM_PGA("IF2 DAC", SND_SOC_NOPM, 0, 0, NULL, 0),
1066 SND_SOC_DAPM_PGA("IF2 DAC L", SND_SOC_NOPM, 0, 0, NULL, 0),
1067 SND_SOC_DAPM_PGA("IF2 DAC R", SND_SOC_NOPM, 0, 0, NULL, 0),
1068 SND_SOC_DAPM_PGA("IF2 ADC", SND_SOC_NOPM, 0, 0, NULL, 0),
1069 SND_SOC_DAPM_PGA("IF2 ADC L", SND_SOC_NOPM, 0, 0, NULL, 0),
1070 SND_SOC_DAPM_PGA("IF2 ADC R", SND_SOC_NOPM, 0, 0, NULL, 0),
1071 /* Digital Interface Select */
1072 SND_SOC_DAPM_MUX("DAI1 RX Mux", SND_SOC_NOPM, 0, 0, &rt5640_dai_mux),
1073 SND_SOC_DAPM_MUX("DAI1 TX Mux", SND_SOC_NOPM, 0, 0, &rt5640_dai_mux),
1074 SND_SOC_DAPM_MUX("DAI1 IF1 Mux", SND_SOC_NOPM, 0, 0, &rt5640_dai_mux),
1075 SND_SOC_DAPM_MUX("DAI1 IF2 Mux", SND_SOC_NOPM, 0, 0, &rt5640_dai_mux),
1076 SND_SOC_DAPM_MUX("SDI1 TX Mux", SND_SOC_NOPM, 0, 0, &rt5640_sdi_mux),
1077 SND_SOC_DAPM_MUX("DAI2 RX Mux", SND_SOC_NOPM, 0, 0, &rt5640_dai_mux),
1078 SND_SOC_DAPM_MUX("DAI2 TX Mux", SND_SOC_NOPM, 0, 0, &rt5640_dai_mux),
1079 SND_SOC_DAPM_MUX("DAI2 IF1 Mux", SND_SOC_NOPM, 0, 0, &rt5640_dai_mux),
1080 SND_SOC_DAPM_MUX("DAI2 IF2 Mux", SND_SOC_NOPM, 0, 0, &rt5640_dai_mux),
1081 SND_SOC_DAPM_MUX("SDI2 TX Mux", SND_SOC_NOPM, 0, 0, &rt5640_sdi_mux),
1082 /* Audio Interface */
1083 SND_SOC_DAPM_AIF_IN("AIF1RX", "AIF1 Playback", 0, SND_SOC_NOPM, 0, 0),
1084 SND_SOC_DAPM_AIF_OUT("AIF1TX", "AIF1 Capture", 0, SND_SOC_NOPM, 0, 0),
1085 SND_SOC_DAPM_AIF_IN("AIF2RX", "AIF2 Playback", 0, SND_SOC_NOPM, 0, 0),
1086 SND_SOC_DAPM_AIF_OUT("AIF2TX", "AIF2 Capture", 0, SND_SOC_NOPM, 0, 0),
1087 /* Audio DSP */
1088 SND_SOC_DAPM_PGA("Audio DSP", SND_SOC_NOPM, 0, 0, NULL, 0),
1089 /* ANC */
1090 SND_SOC_DAPM_PGA("ANC", SND_SOC_NOPM, 0, 0, NULL, 0),
1091 /* Output Side */
1092 /* DAC mixer before sound effect */
1093 SND_SOC_DAPM_MIXER("DAC MIXL", SND_SOC_NOPM, 0, 0,
1094 rt5640_dac_l_mix, ARRAY_SIZE(rt5640_dac_l_mix)),
1095 SND_SOC_DAPM_MIXER("DAC MIXR", SND_SOC_NOPM, 0, 0,
1096 rt5640_dac_r_mix, ARRAY_SIZE(rt5640_dac_r_mix)),
1097 /* DAC2 channel Mux */
1098 SND_SOC_DAPM_MUX("DAC L2 Mux", SND_SOC_NOPM, 0, 0,
1099 &rt5640_dac_l2_mux),
1100 SND_SOC_DAPM_MUX("DAC R2 Mux", SND_SOC_NOPM, 0, 0,
1101 &rt5640_dac_r2_mux),
1102 /* DAC Mixer */
1103 SND_SOC_DAPM_MIXER("Stereo DAC MIXL", SND_SOC_NOPM, 0, 0,
1104 rt5640_sto_dac_l_mix, ARRAY_SIZE(rt5640_sto_dac_l_mix)),
1105 SND_SOC_DAPM_MIXER("Stereo DAC MIXR", SND_SOC_NOPM, 0, 0,
1106 rt5640_sto_dac_r_mix, ARRAY_SIZE(rt5640_sto_dac_r_mix)),
1107 SND_SOC_DAPM_MIXER("Mono DAC MIXL", SND_SOC_NOPM, 0, 0,
1108 rt5640_mono_dac_l_mix, ARRAY_SIZE(rt5640_mono_dac_l_mix)),
1109 SND_SOC_DAPM_MIXER("Mono DAC MIXR", SND_SOC_NOPM, 0, 0,
1110 rt5640_mono_dac_r_mix, ARRAY_SIZE(rt5640_mono_dac_r_mix)),
1111 SND_SOC_DAPM_MIXER("DIG MIXL", SND_SOC_NOPM, 0, 0,
1112 rt5640_dig_l_mix, ARRAY_SIZE(rt5640_dig_l_mix)),
1113 SND_SOC_DAPM_MIXER("DIG MIXR", SND_SOC_NOPM, 0, 0,
1114 rt5640_dig_r_mix, ARRAY_SIZE(rt5640_dig_r_mix)),
1115 /* DACs */
1116 SND_SOC_DAPM_DAC("DAC L1", NULL, RT5640_PWR_DIG1,
1117 RT5640_PWR_DAC_L1_BIT, 0),
1118 SND_SOC_DAPM_DAC("DAC L2", NULL, RT5640_PWR_DIG1,
1119 RT5640_PWR_DAC_L2_BIT, 0),
1120 SND_SOC_DAPM_DAC("DAC R1", NULL, RT5640_PWR_DIG1,
1121 RT5640_PWR_DAC_R1_BIT, 0),
1122 SND_SOC_DAPM_DAC("DAC R2", NULL, RT5640_PWR_DIG1,
1123 RT5640_PWR_DAC_R2_BIT, 0),
1124 /* SPK/OUT Mixer */
1125 SND_SOC_DAPM_MIXER("SPK MIXL", RT5640_PWR_MIXER, RT5640_PWR_SM_L_BIT,
1126 0, rt5640_spk_l_mix, ARRAY_SIZE(rt5640_spk_l_mix)),
1127 SND_SOC_DAPM_MIXER("SPK MIXR", RT5640_PWR_MIXER, RT5640_PWR_SM_R_BIT,
1128 0, rt5640_spk_r_mix, ARRAY_SIZE(rt5640_spk_r_mix)),
1129 SND_SOC_DAPM_MIXER("OUT MIXL", RT5640_PWR_MIXER, RT5640_PWR_OM_L_BIT,
1130 0, rt5640_out_l_mix, ARRAY_SIZE(rt5640_out_l_mix)),
1131 SND_SOC_DAPM_MIXER("OUT MIXR", RT5640_PWR_MIXER, RT5640_PWR_OM_R_BIT,
1132 0, rt5640_out_r_mix, ARRAY_SIZE(rt5640_out_r_mix)),
1133 /* Ouput Volume */
1134 SND_SOC_DAPM_PGA("SPKVOL L", RT5640_PWR_VOL,
1135 RT5640_PWR_SV_L_BIT, 0, NULL, 0),
1136 SND_SOC_DAPM_PGA("SPKVOL R", RT5640_PWR_VOL,
1137 RT5640_PWR_SV_R_BIT, 0, NULL, 0),
1138 SND_SOC_DAPM_PGA("OUTVOL L", RT5640_PWR_VOL,
1139 RT5640_PWR_OV_L_BIT, 0, NULL, 0),
1140 SND_SOC_DAPM_PGA("OUTVOL R", RT5640_PWR_VOL,
1141 RT5640_PWR_OV_R_BIT, 0, NULL, 0),
1142 SND_SOC_DAPM_PGA("HPOVOL L", RT5640_PWR_VOL,
1143 RT5640_PWR_HV_L_BIT, 0, NULL, 0),
1144 SND_SOC_DAPM_PGA("HPOVOL R", RT5640_PWR_VOL,
1145 RT5640_PWR_HV_R_BIT, 0, NULL, 0),
1146 /* SPO/HPO/LOUT/Mono Mixer */
1147 SND_SOC_DAPM_MIXER("SPOL MIX", SND_SOC_NOPM, 0,
1148 0, rt5640_spo_l_mix, ARRAY_SIZE(rt5640_spo_l_mix)),
1149 SND_SOC_DAPM_MIXER("SPOR MIX", SND_SOC_NOPM, 0,
1150 0, rt5640_spo_r_mix, ARRAY_SIZE(rt5640_spo_r_mix)),
1151 SND_SOC_DAPM_MIXER("HPO MIX L", SND_SOC_NOPM, 0, 0,
1152 rt5640_hpo_mix, ARRAY_SIZE(rt5640_hpo_mix)),
1153 SND_SOC_DAPM_MIXER("HPO MIX R", SND_SOC_NOPM, 0, 0,
1154 rt5640_hpo_mix, ARRAY_SIZE(rt5640_hpo_mix)),
1155 SND_SOC_DAPM_MIXER("LOUT MIX", RT5640_PWR_ANLG1, RT5640_PWR_LM_BIT, 0,
1156 rt5640_lout_mix, ARRAY_SIZE(rt5640_lout_mix)),
1157 SND_SOC_DAPM_MIXER("Mono MIX", RT5640_PWR_ANLG1, RT5640_PWR_MM_BIT, 0,
1158 rt5640_mono_mix, ARRAY_SIZE(rt5640_mono_mix)),
1159 SND_SOC_DAPM_SUPPLY("Improve MONO Amp Drv", RT5640_PWR_ANLG1,
1160 RT5640_PWR_MA_BIT, 0, NULL, 0),
1161 SND_SOC_DAPM_SUPPLY("Improve HP Amp Drv", RT5640_PWR_ANLG1,
1162 SND_SOC_NOPM, 0, NULL, 0),
1163 SND_SOC_DAPM_PGA("HP L Amp", RT5640_PWR_ANLG1,
1164 RT5640_PWR_HP_L_BIT, 0, NULL, 0),
1165 SND_SOC_DAPM_PGA("HP R Amp", RT5640_PWR_ANLG1,
1166 RT5640_PWR_HP_R_BIT, 0, NULL, 0),
1167 SND_SOC_DAPM_SUPPLY("Improve SPK Amp Drv", RT5640_PWR_DIG1,
1168 SND_SOC_NOPM, 0, spk_event,
1169 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
1170 /* Output Lines */
1171 SND_SOC_DAPM_OUTPUT("SPOLP"),
1172 SND_SOC_DAPM_OUTPUT("SPOLN"),
1173 SND_SOC_DAPM_OUTPUT("SPORP"),
1174 SND_SOC_DAPM_OUTPUT("SPORN"),
1175 SND_SOC_DAPM_OUTPUT("HPOL"),
1176 SND_SOC_DAPM_OUTPUT("HPOR"),
1177 SND_SOC_DAPM_OUTPUT("LOUTL"),
1178 SND_SOC_DAPM_OUTPUT("LOUTR"),
1179 SND_SOC_DAPM_OUTPUT("MONOP"),
1180 SND_SOC_DAPM_OUTPUT("MONON"),
1181};
1182
1183static const struct snd_soc_dapm_route rt5640_dapm_routes[] = {
1184 {"IN1P", NULL, "LDO2"},
1185 {"IN2P", NULL, "LDO2"},
1186
1187 {"DMIC L1", NULL, "DMIC1"},
1188 {"DMIC R1", NULL, "DMIC1"},
1189 {"DMIC L2", NULL, "DMIC2"},
1190 {"DMIC R2", NULL, "DMIC2"},
1191
1192 {"BST1", NULL, "IN1P"},
1193 {"BST1", NULL, "IN1N"},
1194 {"BST2", NULL, "IN2P"},
1195 {"BST2", NULL, "IN2N"},
1196
1197 {"INL VOL", NULL, "IN2P"},
1198 {"INR VOL", NULL, "IN2N"},
1199
1200 {"RECMIXL", "HPOL Switch", "HPOL"},
1201 {"RECMIXL", "INL Switch", "INL VOL"},
1202 {"RECMIXL", "BST2 Switch", "BST2"},
1203 {"RECMIXL", "BST1 Switch", "BST1"},
1204 {"RECMIXL", "OUT MIXL Switch", "OUT MIXL"},
1205
1206 {"RECMIXR", "HPOR Switch", "HPOR"},
1207 {"RECMIXR", "INR Switch", "INR VOL"},
1208 {"RECMIXR", "BST2 Switch", "BST2"},
1209 {"RECMIXR", "BST1 Switch", "BST1"},
1210 {"RECMIXR", "OUT MIXR Switch", "OUT MIXR"},
1211
1212 {"ADC L", NULL, "RECMIXL"},
1213 {"ADC R", NULL, "RECMIXR"},
1214
1215 {"DMIC L1", NULL, "DMIC CLK"},
1216 {"DMIC L1", NULL, "DMIC1 Power"},
1217 {"DMIC R1", NULL, "DMIC CLK"},
1218 {"DMIC R1", NULL, "DMIC1 Power"},
1219 {"DMIC L2", NULL, "DMIC CLK"},
1220 {"DMIC L2", NULL, "DMIC2 Power"},
1221 {"DMIC R2", NULL, "DMIC CLK"},
1222 {"DMIC R2", NULL, "DMIC2 Power"},
1223
1224 {"Stereo ADC L2 Mux", "DMIC1", "DMIC L1"},
1225 {"Stereo ADC L2 Mux", "DMIC2", "DMIC L2"},
1226 {"Stereo ADC L2 Mux", "DIG MIX", "DIG MIXL"},
1227 {"Stereo ADC L1 Mux", "ADC", "ADC L"},
1228 {"Stereo ADC L1 Mux", "DIG MIX", "DIG MIXL"},
1229
1230 {"Stereo ADC R1 Mux", "ADC", "ADC R"},
1231 {"Stereo ADC R1 Mux", "DIG MIX", "DIG MIXR"},
1232 {"Stereo ADC R2 Mux", "DMIC1", "DMIC R1"},
1233 {"Stereo ADC R2 Mux", "DMIC2", "DMIC R2"},
1234 {"Stereo ADC R2 Mux", "DIG MIX", "DIG MIXR"},
1235
1236 {"Mono ADC L2 Mux", "DMIC L1", "DMIC L1"},
1237 {"Mono ADC L2 Mux", "DMIC L2", "DMIC L2"},
1238 {"Mono ADC L2 Mux", "Mono DAC MIXL", "Mono DAC MIXL"},
1239 {"Mono ADC L1 Mux", "Mono DAC MIXL", "Mono DAC MIXL"},
1240 {"Mono ADC L1 Mux", "ADCL", "ADC L"},
1241
1242 {"Mono ADC R1 Mux", "Mono DAC MIXR", "Mono DAC MIXR"},
1243 {"Mono ADC R1 Mux", "ADCR", "ADC R"},
1244 {"Mono ADC R2 Mux", "DMIC R1", "DMIC R1"},
1245 {"Mono ADC R2 Mux", "DMIC R2", "DMIC R2"},
1246 {"Mono ADC R2 Mux", "Mono DAC MIXR", "Mono DAC MIXR"},
1247
1248 {"Stereo ADC MIXL", "ADC1 Switch", "Stereo ADC L1 Mux"},
1249 {"Stereo ADC MIXL", "ADC2 Switch", "Stereo ADC L2 Mux"},
1250 {"Stereo ADC MIXL", NULL, "Stereo Filter"},
1251 {"Stereo Filter", NULL, "PLL1", check_sysclk1_source},
1252
1253 {"Stereo ADC MIXR", "ADC1 Switch", "Stereo ADC R1 Mux"},
1254 {"Stereo ADC MIXR", "ADC2 Switch", "Stereo ADC R2 Mux"},
1255 {"Stereo ADC MIXR", NULL, "Stereo Filter"},
1256 {"Stereo Filter", NULL, "PLL1", check_sysclk1_source},
1257
1258 {"Mono ADC MIXL", "ADC1 Switch", "Mono ADC L1 Mux"},
1259 {"Mono ADC MIXL", "ADC2 Switch", "Mono ADC L2 Mux"},
1260 {"Mono ADC MIXL", NULL, "Mono Left Filter"},
1261 {"Mono Left Filter", NULL, "PLL1", check_sysclk1_source},
1262
1263 {"Mono ADC MIXR", "ADC1 Switch", "Mono ADC R1 Mux"},
1264 {"Mono ADC MIXR", "ADC2 Switch", "Mono ADC R2 Mux"},
1265 {"Mono ADC MIXR", NULL, "Mono Right Filter"},
1266 {"Mono Right Filter", NULL, "PLL1", check_sysclk1_source},
1267
1268 {"IF2 ADC L", NULL, "Mono ADC MIXL"},
1269 {"IF2 ADC R", NULL, "Mono ADC MIXR"},
1270 {"IF1 ADC L", NULL, "Stereo ADC MIXL"},
1271 {"IF1 ADC R", NULL, "Stereo ADC MIXR"},
1272
1273 {"IF1 ADC", NULL, "I2S1"},
1274 {"IF1 ADC", NULL, "IF1 ADC L"},
1275 {"IF1 ADC", NULL, "IF1 ADC R"},
1276 {"IF2 ADC", NULL, "I2S2"},
1277 {"IF2 ADC", NULL, "IF2 ADC L"},
1278 {"IF2 ADC", NULL, "IF2 ADC R"},
1279
1280 {"DAI1 TX Mux", "1:1|2:2", "IF1 ADC"},
1281 {"DAI1 TX Mux", "1:2|2:1", "IF2 ADC"},
1282 {"DAI1 IF1 Mux", "1:1|2:1", "IF1 ADC"},
1283 {"DAI1 IF2 Mux", "1:1|2:1", "IF2 ADC"},
1284 {"SDI1 TX Mux", "IF1", "DAI1 IF1 Mux"},
1285 {"SDI1 TX Mux", "IF2", "DAI1 IF2 Mux"},
1286
1287 {"DAI2 TX Mux", "1:2|2:1", "IF1 ADC"},
1288 {"DAI2 TX Mux", "1:1|2:2", "IF2 ADC"},
1289 {"DAI2 IF1 Mux", "1:2|2:2", "IF1 ADC"},
1290 {"DAI2 IF2 Mux", "1:2|2:2", "IF2 ADC"},
1291 {"SDI2 TX Mux", "IF1", "DAI2 IF1 Mux"},
1292 {"SDI2 TX Mux", "IF2", "DAI2 IF2 Mux"},
1293
1294 {"AIF1TX", NULL, "DAI1 TX Mux"},
1295 {"AIF1TX", NULL, "SDI1 TX Mux"},
1296 {"AIF2TX", NULL, "DAI2 TX Mux"},
1297 {"AIF2TX", NULL, "SDI2 TX Mux"},
1298
1299 {"DAI1 RX Mux", "1:1|2:2", "AIF1RX"},
1300 {"DAI1 RX Mux", "1:1|2:1", "AIF1RX"},
1301 {"DAI1 RX Mux", "1:2|2:1", "AIF2RX"},
1302 {"DAI1 RX Mux", "1:2|2:2", "AIF2RX"},
1303
1304 {"DAI2 RX Mux", "1:2|2:1", "AIF1RX"},
1305 {"DAI2 RX Mux", "1:1|2:1", "AIF1RX"},
1306 {"DAI2 RX Mux", "1:1|2:2", "AIF2RX"},
1307 {"DAI2 RX Mux", "1:2|2:2", "AIF2RX"},
1308
1309 {"IF1 DAC", NULL, "I2S1"},
1310 {"IF1 DAC", NULL, "DAI1 RX Mux"},
1311 {"IF2 DAC", NULL, "I2S2"},
1312 {"IF2 DAC", NULL, "DAI2 RX Mux"},
1313
1314 {"IF1 DAC L", NULL, "IF1 DAC"},
1315 {"IF1 DAC R", NULL, "IF1 DAC"},
1316 {"IF2 DAC L", NULL, "IF2 DAC"},
1317 {"IF2 DAC R", NULL, "IF2 DAC"},
1318
1319 {"DAC MIXL", "Stereo ADC Switch", "Stereo ADC MIXL"},
1320 {"DAC MIXL", "INF1 Switch", "IF1 DAC L"},
1321 {"DAC MIXR", "Stereo ADC Switch", "Stereo ADC MIXR"},
1322 {"DAC MIXR", "INF1 Switch", "IF1 DAC R"},
1323
1324 {"ANC", NULL, "Stereo ADC MIXL"},
1325 {"ANC", NULL, "Stereo ADC MIXR"},
1326
1327 {"Audio DSP", NULL, "DAC MIXL"},
1328 {"Audio DSP", NULL, "DAC MIXR"},
1329
1330 {"DAC L2 Mux", "IF2", "IF2 DAC L"},
1331 {"DAC L2 Mux", "Base L/R", "Audio DSP"},
1332
1333 {"DAC R2 Mux", "IF2", "IF2 DAC R"},
1334
1335 {"Stereo DAC MIXL", "DAC L1 Switch", "DAC MIXL"},
1336 {"Stereo DAC MIXL", "DAC L2 Switch", "DAC L2 Mux"},
1337 {"Stereo DAC MIXL", "ANC Switch", "ANC"},
1338 {"Stereo DAC MIXR", "DAC R1 Switch", "DAC MIXR"},
1339 {"Stereo DAC MIXR", "DAC R2 Switch", "DAC R2 Mux"},
1340 {"Stereo DAC MIXR", "ANC Switch", "ANC"},
1341
1342 {"Mono DAC MIXL", "DAC L1 Switch", "DAC MIXL"},
1343 {"Mono DAC MIXL", "DAC L2 Switch", "DAC L2 Mux"},
1344 {"Mono DAC MIXL", "DAC R2 Switch", "DAC R2 Mux"},
1345 {"Mono DAC MIXR", "DAC R1 Switch", "DAC MIXR"},
1346 {"Mono DAC MIXR", "DAC R2 Switch", "DAC R2 Mux"},
1347 {"Mono DAC MIXR", "DAC L2 Switch", "DAC L2 Mux"},
1348
1349 {"DIG MIXL", "DAC L1 Switch", "DAC MIXL"},
1350 {"DIG MIXL", "DAC L2 Switch", "DAC L2 Mux"},
1351 {"DIG MIXR", "DAC R1 Switch", "DAC MIXR"},
1352 {"DIG MIXR", "DAC R2 Switch", "DAC R2 Mux"},
1353
1354 {"DAC L1", NULL, "Stereo DAC MIXL"},
1355 {"DAC L1", NULL, "PLL1", check_sysclk1_source},
1356 {"DAC R1", NULL, "Stereo DAC MIXR"},
1357 {"DAC R1", NULL, "PLL1", check_sysclk1_source},
1358 {"DAC L2", NULL, "Mono DAC MIXL"},
1359 {"DAC L2", NULL, "PLL1", check_sysclk1_source},
1360 {"DAC R2", NULL, "Mono DAC MIXR"},
1361 {"DAC R2", NULL, "PLL1", check_sysclk1_source},
1362
1363 {"SPK MIXL", "REC MIXL Switch", "RECMIXL"},
1364 {"SPK MIXL", "INL Switch", "INL VOL"},
1365 {"SPK MIXL", "DAC L1 Switch", "DAC L1"},
1366 {"SPK MIXL", "DAC L2 Switch", "DAC L2"},
1367 {"SPK MIXL", "OUT MIXL Switch", "OUT MIXL"},
1368 {"SPK MIXR", "REC MIXR Switch", "RECMIXR"},
1369 {"SPK MIXR", "INR Switch", "INR VOL"},
1370 {"SPK MIXR", "DAC R1 Switch", "DAC R1"},
1371 {"SPK MIXR", "DAC R2 Switch", "DAC R2"},
1372 {"SPK MIXR", "OUT MIXR Switch", "OUT MIXR"},
1373
1374 {"OUT MIXL", "SPK MIXL Switch", "SPK MIXL"},
1375 {"OUT MIXL", "BST1 Switch", "BST1"},
1376 {"OUT MIXL", "INL Switch", "INL VOL"},
1377 {"OUT MIXL", "REC MIXL Switch", "RECMIXL"},
1378 {"OUT MIXL", "DAC R2 Switch", "DAC R2"},
1379 {"OUT MIXL", "DAC L2 Switch", "DAC L2"},
1380 {"OUT MIXL", "DAC L1 Switch", "DAC L1"},
1381
1382 {"OUT MIXR", "SPK MIXR Switch", "SPK MIXR"},
1383 {"OUT MIXR", "BST2 Switch", "BST2"},
1384 {"OUT MIXR", "BST1 Switch", "BST1"},
1385 {"OUT MIXR", "INR Switch", "INR VOL"},
1386 {"OUT MIXR", "REC MIXR Switch", "RECMIXR"},
1387 {"OUT MIXR", "DAC L2 Switch", "DAC L2"},
1388 {"OUT MIXR", "DAC R2 Switch", "DAC R2"},
1389 {"OUT MIXR", "DAC R1 Switch", "DAC R1"},
1390
1391 {"SPKVOL L", NULL, "SPK MIXL"},
1392 {"SPKVOL R", NULL, "SPK MIXR"},
1393 {"HPOVOL L", NULL, "OUT MIXL"},
1394 {"HPOVOL R", NULL, "OUT MIXR"},
1395 {"OUTVOL L", NULL, "OUT MIXL"},
1396 {"OUTVOL R", NULL, "OUT MIXR"},
1397
1398 {"SPOL MIX", "DAC R1 Switch", "DAC R1"},
1399 {"SPOL MIX", "DAC L1 Switch", "DAC L1"},
1400 {"SPOL MIX", "SPKVOL R Switch", "SPKVOL R"},
1401 {"SPOL MIX", "SPKVOL L Switch", "SPKVOL L"},
1402 {"SPOL MIX", "BST1 Switch", "BST1"},
1403 {"SPOR MIX", "DAC R1 Switch", "DAC R1"},
1404 {"SPOR MIX", "SPKVOL R Switch", "SPKVOL R"},
1405 {"SPOR MIX", "BST1 Switch", "BST1"},
1406
1407 {"HPO MIX L", "HPO MIX DAC2 Switch", "DAC L2"},
1408 {"HPO MIX L", "HPO MIX DAC1 Switch", "DAC L1"},
1409 {"HPO MIX L", "HPO MIX HPVOL Switch", "HPOVOL L"},
1410 {"HPO MIX R", "HPO MIX DAC2 Switch", "DAC R2"},
1411 {"HPO MIX R", "HPO MIX DAC1 Switch", "DAC R1"},
1412 {"HPO MIX R", "HPO MIX HPVOL Switch", "HPOVOL R"},
1413
1414 {"LOUT MIX", "DAC L1 Switch", "DAC L1"},
1415 {"LOUT MIX", "DAC R1 Switch", "DAC R1"},
1416 {"LOUT MIX", "OUTVOL L Switch", "OUTVOL L"},
1417 {"LOUT MIX", "OUTVOL R Switch", "OUTVOL R"},
1418
1419 {"Mono MIX", "DAC R2 Switch", "DAC R2"},
1420 {"Mono MIX", "DAC L2 Switch", "DAC L2"},
1421 {"Mono MIX", "OUTVOL R Switch", "OUTVOL R"},
1422 {"Mono MIX", "OUTVOL L Switch", "OUTVOL L"},
1423 {"Mono MIX", "BST1 Switch", "BST1"},
1424
1425 {"HP L Amp", NULL, "HPO MIX L"},
1426 {"HP R Amp", NULL, "HPO MIX R"},
1427
1428 {"SPOLP", NULL, "SPOL MIX"},
1429 {"SPOLN", NULL, "SPOL MIX"},
1430 {"SPORP", NULL, "SPOR MIX"},
1431 {"SPORN", NULL, "SPOR MIX"},
1432
1433 {"SPOLP", NULL, "Improve SPK Amp Drv"},
1434 {"SPOLN", NULL, "Improve SPK Amp Drv"},
1435 {"SPORP", NULL, "Improve SPK Amp Drv"},
1436 {"SPORN", NULL, "Improve SPK Amp Drv"},
1437
1438 {"HPOL", NULL, "Improve HP Amp Drv"},
1439 {"HPOR", NULL, "Improve HP Amp Drv"},
1440
1441 {"HPOL", NULL, "HP L Amp"},
1442 {"HPOR", NULL, "HP R Amp"},
1443 {"LOUTL", NULL, "LOUT MIX"},
1444 {"LOUTR", NULL, "LOUT MIX"},
1445 {"MONOP", NULL, "Mono MIX"},
1446 {"MONON", NULL, "Mono MIX"},
1447 {"MONOP", NULL, "Improve MONO Amp Drv"},
1448};
1449
1450static int get_sdp_info(struct snd_soc_codec *codec, int dai_id)
1451{
1452 int ret = 0, val;
1453
1454 if (codec == NULL)
1455 return -EINVAL;
1456
1457 val = snd_soc_read(codec, RT5640_I2S1_SDP);
1458 val = (val & RT5640_I2S_IF_MASK) >> RT5640_I2S_IF_SFT;
1459 switch (dai_id) {
1460 case RT5640_AIF1:
1461 switch (val) {
1462 case RT5640_IF_123:
1463 case RT5640_IF_132:
1464 ret |= RT5640_U_IF1;
1465 break;
1466 case RT5640_IF_113:
1467 ret |= RT5640_U_IF1;
1468 case RT5640_IF_312:
1469 case RT5640_IF_213:
1470 ret |= RT5640_U_IF2;
1471 break;
1472 }
1473 break;
1474
1475 case RT5640_AIF2:
1476 switch (val) {
1477 case RT5640_IF_231:
1478 case RT5640_IF_213:
1479 ret |= RT5640_U_IF1;
1480 break;
1481 case RT5640_IF_223:
1482 ret |= RT5640_U_IF1;
1483 case RT5640_IF_123:
1484 case RT5640_IF_321:
1485 ret |= RT5640_U_IF2;
1486 break;
1487 }
1488 break;
1489
1490 default:
1491 ret = -EINVAL;
1492 break;
1493 }
1494
1495 return ret;
1496}
1497
1498static int get_clk_info(int sclk, int rate)
1499{
1500 int i, pd[] = {1, 2, 3, 4, 6, 8, 12, 16};
1501
1502 if (sclk <= 0 || rate <= 0)
1503 return -EINVAL;
1504
1505 rate = rate << 8;
1506 for (i = 0; i < ARRAY_SIZE(pd); i++)
1507 if (sclk == rate * pd[i])
1508 return i;
1509
1510 return -EINVAL;
1511}
1512
1513static int rt5640_hw_params(struct snd_pcm_substream *substream,
1514 struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
1515{
1516 struct snd_soc_pcm_runtime *rtd = substream->private_data;
1517 struct snd_soc_codec *codec = rtd->codec;
1518 struct rt5640_priv *rt5640 = snd_soc_codec_get_drvdata(codec);
1519 unsigned int val_len = 0, val_clk, mask_clk, dai_sel;
1520 int pre_div, bclk_ms, frame_size;
1521
1522 rt5640->lrck[dai->id] = params_rate(params);
1523 pre_div = get_clk_info(rt5640->sysclk, rt5640->lrck[dai->id]);
1524 if (pre_div < 0) {
1525 dev_err(codec->dev, "Unsupported clock setting\n");
1526 return -EINVAL;
1527 }
1528 frame_size = snd_soc_params_to_frame_size(params);
1529 if (frame_size < 0) {
1530 dev_err(codec->dev, "Unsupported frame size: %d\n", frame_size);
1531 return frame_size;
1532 }
1533 if (frame_size > 32)
1534 bclk_ms = 1;
1535 else
1536 bclk_ms = 0;
1537 rt5640->bclk[dai->id] = rt5640->lrck[dai->id] * (32 << bclk_ms);
1538
1539 dev_dbg(dai->dev, "bclk is %dHz and lrck is %dHz\n",
1540 rt5640->bclk[dai->id], rt5640->lrck[dai->id]);
1541 dev_dbg(dai->dev, "bclk_ms is %d and pre_div is %d for iis %d\n",
1542 bclk_ms, pre_div, dai->id);
1543
1544 switch (params_format(params)) {
1545 case SNDRV_PCM_FORMAT_S16_LE:
1546 break;
1547 case SNDRV_PCM_FORMAT_S20_3LE:
1548 val_len |= RT5640_I2S_DL_20;
1549 break;
1550 case SNDRV_PCM_FORMAT_S24_LE:
1551 val_len |= RT5640_I2S_DL_24;
1552 break;
1553 case SNDRV_PCM_FORMAT_S8:
1554 val_len |= RT5640_I2S_DL_8;
1555 break;
1556 default:
1557 return -EINVAL;
1558 }
1559
1560 dai_sel = get_sdp_info(codec, dai->id);
1561 if (dai_sel < 0) {
1562 dev_err(codec->dev, "Failed to get sdp info: %d\n", dai_sel);
1563 return -EINVAL;
1564 }
1565 if (dai_sel & RT5640_U_IF1) {
1566 mask_clk = RT5640_I2S_BCLK_MS1_MASK | RT5640_I2S_PD1_MASK;
1567 val_clk = bclk_ms << RT5640_I2S_BCLK_MS1_SFT |
1568 pre_div << RT5640_I2S_PD1_SFT;
1569 snd_soc_update_bits(codec, RT5640_I2S1_SDP,
1570 RT5640_I2S_DL_MASK, val_len);
1571 snd_soc_update_bits(codec, RT5640_ADDA_CLK1, mask_clk, val_clk);
1572 }
1573 if (dai_sel & RT5640_U_IF2) {
1574 mask_clk = RT5640_I2S_BCLK_MS2_MASK | RT5640_I2S_PD2_MASK;
1575 val_clk = bclk_ms << RT5640_I2S_BCLK_MS2_SFT |
1576 pre_div << RT5640_I2S_PD2_SFT;
1577 snd_soc_update_bits(codec, RT5640_I2S2_SDP,
1578 RT5640_I2S_DL_MASK, val_len);
1579 snd_soc_update_bits(codec, RT5640_ADDA_CLK1, mask_clk, val_clk);
1580 }
1581
1582 return 0;
1583}
1584
1585static int rt5640_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
1586{
1587 struct snd_soc_codec *codec = dai->codec;
1588 struct rt5640_priv *rt5640 = snd_soc_codec_get_drvdata(codec);
1589 unsigned int reg_val = 0, dai_sel;
1590
1591 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
1592 case SND_SOC_DAIFMT_CBM_CFM:
1593 rt5640->master[dai->id] = 1;
1594 break;
1595 case SND_SOC_DAIFMT_CBS_CFS:
1596 reg_val |= RT5640_I2S_MS_S;
1597 rt5640->master[dai->id] = 0;
1598 break;
1599 default:
1600 return -EINVAL;
1601 }
1602
1603 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
1604 case SND_SOC_DAIFMT_NB_NF:
1605 break;
1606 case SND_SOC_DAIFMT_IB_NF:
1607 reg_val |= RT5640_I2S_BP_INV;
1608 break;
1609 default:
1610 return -EINVAL;
1611 }
1612
1613 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
1614 case SND_SOC_DAIFMT_I2S:
1615 break;
1616 case SND_SOC_DAIFMT_LEFT_J:
1617 reg_val |= RT5640_I2S_DF_LEFT;
1618 break;
1619 case SND_SOC_DAIFMT_DSP_A:
1620 reg_val |= RT5640_I2S_DF_PCM_A;
1621 break;
1622 case SND_SOC_DAIFMT_DSP_B:
1623 reg_val |= RT5640_I2S_DF_PCM_B;
1624 break;
1625 default:
1626 return -EINVAL;
1627 }
1628
1629 dai_sel = get_sdp_info(codec, dai->id);
1630 if (dai_sel < 0) {
1631 dev_err(codec->dev, "Failed to get sdp info: %d\n", dai_sel);
1632 return -EINVAL;
1633 }
1634 if (dai_sel & RT5640_U_IF1) {
1635 snd_soc_update_bits(codec, RT5640_I2S1_SDP,
1636 RT5640_I2S_MS_MASK | RT5640_I2S_BP_MASK |
1637 RT5640_I2S_DF_MASK, reg_val);
1638 }
1639 if (dai_sel & RT5640_U_IF2) {
1640 snd_soc_update_bits(codec, RT5640_I2S2_SDP,
1641 RT5640_I2S_MS_MASK | RT5640_I2S_BP_MASK |
1642 RT5640_I2S_DF_MASK, reg_val);
1643 }
1644
1645 return 0;
1646}
1647
1648static int rt5640_set_dai_sysclk(struct snd_soc_dai *dai,
1649 int clk_id, unsigned int freq, int dir)
1650{
1651 struct snd_soc_codec *codec = dai->codec;
1652 struct rt5640_priv *rt5640 = snd_soc_codec_get_drvdata(codec);
1653 unsigned int reg_val = 0;
1654
1655 if (freq == rt5640->sysclk && clk_id == rt5640->sysclk_src)
1656 return 0;
1657
1658 switch (clk_id) {
1659 case RT5640_SCLK_S_MCLK:
1660 reg_val |= RT5640_SCLK_SRC_MCLK;
1661 break;
1662 case RT5640_SCLK_S_PLL1:
1663 reg_val |= RT5640_SCLK_SRC_PLL1;
1664 break;
1665 case RT5640_SCLK_S_PLL1_TK:
1666 reg_val |= RT5640_SCLK_SRC_PLL1T;
1667 break;
1668 case RT5640_SCLK_S_RCCLK:
1669 reg_val |= RT5640_SCLK_SRC_RCCLK;
1670 break;
1671 default:
1672 dev_err(codec->dev, "Invalid clock id (%d)\n", clk_id);
1673 return -EINVAL;
1674 }
1675 snd_soc_update_bits(codec, RT5640_GLB_CLK,
1676 RT5640_SCLK_SRC_MASK, reg_val);
1677 rt5640->sysclk = freq;
1678 rt5640->sysclk_src = clk_id;
1679
1680 dev_dbg(dai->dev, "Sysclk is %dHz and clock id is %d\n", freq, clk_id);
1681 return 0;
1682}
1683
1684/**
1685 * rt5640_pll_calc - Calculate PLL M/N/K code.
1686 * @freq_in: external clock provided to codec.
1687 * @freq_out: target clock which codec works on.
1688 * @pll_code: Pointer to structure with M, N, K and bypass flag.
1689 *
1690 * Calculate M/N/K code to configure PLL for codec. And K is assigned to 2
1691 * which make calculation more efficiently.
1692 *
1693 * Returns 0 for success or negative error code.
1694 */
1695static int rt5640_pll_calc(const unsigned int freq_in,
1696 const unsigned int freq_out, struct rt5640_pll_code *pll_code)
1697{
1698 int max_n = RT5640_PLL_N_MAX, max_m = RT5640_PLL_M_MAX;
1699 int n = 0, m = 0, red, n_t, m_t, in_t, out_t;
1700 int red_t = abs(freq_out - freq_in);
1701 bool bypass = false;
1702
1703 if (RT5640_PLL_INP_MAX < freq_in || RT5640_PLL_INP_MIN > freq_in)
1704 return -EINVAL;
1705
1706 for (n_t = 0; n_t <= max_n; n_t++) {
1707 in_t = (freq_in >> 1) + (freq_in >> 2) * n_t;
1708 if (in_t < 0)
1709 continue;
1710 if (in_t == freq_out) {
1711 bypass = true;
1712 n = n_t;
1713 goto code_find;
1714 }
1715 for (m_t = 0; m_t <= max_m; m_t++) {
1716 out_t = in_t / (m_t + 2);
1717 red = abs(out_t - freq_out);
1718 if (red < red_t) {
1719 n = n_t;
1720 m = m_t;
1721 if (red == 0)
1722 goto code_find;
1723 red_t = red;
1724 }
1725 }
1726 }
1727 pr_debug("Only get approximation about PLL\n");
1728
1729code_find:
1730 pll_code->m_bp = bypass;
1731 pll_code->m_code = m;
1732 pll_code->n_code = n;
1733 pll_code->k_code = 2;
1734 return 0;
1735}
1736
1737static int rt5640_set_dai_pll(struct snd_soc_dai *dai, int pll_id, int source,
1738 unsigned int freq_in, unsigned int freq_out)
1739{
1740 struct snd_soc_codec *codec = dai->codec;
1741 struct rt5640_priv *rt5640 = snd_soc_codec_get_drvdata(codec);
1742 struct rt5640_pll_code *pll_code = &rt5640->pll_code;
1743 int ret, dai_sel;
1744
1745 if (source == rt5640->pll_src && freq_in == rt5640->pll_in &&
1746 freq_out == rt5640->pll_out)
1747 return 0;
1748
1749 if (!freq_in || !freq_out) {
1750 dev_dbg(codec->dev, "PLL disabled\n");
1751
1752 rt5640->pll_in = 0;
1753 rt5640->pll_out = 0;
1754 snd_soc_update_bits(codec, RT5640_GLB_CLK,
1755 RT5640_SCLK_SRC_MASK, RT5640_SCLK_SRC_MCLK);
1756 return 0;
1757 }
1758
1759 switch (source) {
1760 case RT5640_PLL1_S_MCLK:
1761 snd_soc_update_bits(codec, RT5640_GLB_CLK,
1762 RT5640_PLL1_SRC_MASK, RT5640_PLL1_SRC_MCLK);
1763 break;
1764 case RT5640_PLL1_S_BCLK1:
1765 case RT5640_PLL1_S_BCLK2:
1766 dai_sel = get_sdp_info(codec, dai->id);
1767 if (dai_sel < 0) {
1768 dev_err(codec->dev,
1769 "Failed to get sdp info: %d\n", dai_sel);
1770 return -EINVAL;
1771 }
1772 if (dai_sel & RT5640_U_IF1) {
1773 snd_soc_update_bits(codec, RT5640_GLB_CLK,
1774 RT5640_PLL1_SRC_MASK, RT5640_PLL1_SRC_BCLK1);
1775 }
1776 if (dai_sel & RT5640_U_IF2) {
1777 snd_soc_update_bits(codec, RT5640_GLB_CLK,
1778 RT5640_PLL1_SRC_MASK, RT5640_PLL1_SRC_BCLK2);
1779 }
1780 break;
1781 default:
1782 dev_err(codec->dev, "Unknown PLL source %d\n", source);
1783 return -EINVAL;
1784 }
1785
1786 ret = rt5640_pll_calc(freq_in, freq_out, pll_code);
1787 if (ret < 0) {
1788 dev_err(codec->dev, "Unsupport input clock %d\n", freq_in);
1789 return ret;
1790 }
1791
1792 dev_dbg(codec->dev, "bypass=%d m=%d n=%d k=2\n", pll_code->m_bp,
1793 (pll_code->m_bp ? 0 : pll_code->m_code), pll_code->n_code);
1794
1795 snd_soc_write(codec, RT5640_PLL_CTRL1,
1796 pll_code->n_code << RT5640_PLL_N_SFT | pll_code->k_code);
1797 snd_soc_write(codec, RT5640_PLL_CTRL2,
1798 (pll_code->m_bp ? 0 : pll_code->m_code) << RT5640_PLL_M_SFT |
1799 pll_code->m_bp << RT5640_PLL_M_BP_SFT);
1800
1801 rt5640->pll_in = freq_in;
1802 rt5640->pll_out = freq_out;
1803 rt5640->pll_src = source;
1804
1805 return 0;
1806}
1807
1808static int rt5640_set_bias_level(struct snd_soc_codec *codec,
1809 enum snd_soc_bias_level level)
1810{
1811 struct rt5640_priv *rt5640 = snd_soc_codec_get_drvdata(codec);
1812 switch (level) {
1813 case SND_SOC_BIAS_STANDBY:
1814 if (SND_SOC_BIAS_OFF == codec->dapm.bias_level) {
1815 regcache_cache_only(rt5640->regmap, false);
1816 snd_soc_update_bits(codec, RT5640_PWR_ANLG1,
1817 RT5640_PWR_VREF1 | RT5640_PWR_MB |
1818 RT5640_PWR_BG | RT5640_PWR_VREF2,
1819 RT5640_PWR_VREF1 | RT5640_PWR_MB |
1820 RT5640_PWR_BG | RT5640_PWR_VREF2);
1821 mdelay(10);
1822 snd_soc_update_bits(codec, RT5640_PWR_ANLG1,
1823 RT5640_PWR_FV1 | RT5640_PWR_FV2,
1824 RT5640_PWR_FV1 | RT5640_PWR_FV2);
1825 regcache_sync(rt5640->regmap);
1826 snd_soc_update_bits(codec, RT5640_DUMMY1,
1827 0x0301, 0x0301);
1828 snd_soc_update_bits(codec, RT5640_DEPOP_M1,
1829 0x001d, 0x0019);
1830 snd_soc_update_bits(codec, RT5640_DEPOP_M2,
1831 0x2000, 0x2000);
1832 snd_soc_update_bits(codec, RT5640_MICBIAS,
1833 0x0030, 0x0030);
1834 }
1835 break;
1836
1837 case SND_SOC_BIAS_OFF:
1838 snd_soc_write(codec, RT5640_DEPOP_M1, 0x0004);
1839 snd_soc_write(codec, RT5640_DEPOP_M2, 0x1100);
1840 snd_soc_update_bits(codec, RT5640_DUMMY1, 0x1, 0);
1841 snd_soc_write(codec, RT5640_PWR_DIG1, 0x0000);
1842 snd_soc_write(codec, RT5640_PWR_DIG2, 0x0000);
1843 snd_soc_write(codec, RT5640_PWR_VOL, 0x0000);
1844 snd_soc_write(codec, RT5640_PWR_MIXER, 0x0000);
1845 snd_soc_write(codec, RT5640_PWR_ANLG1, 0x0000);
1846 snd_soc_write(codec, RT5640_PWR_ANLG2, 0x0000);
1847 break;
1848
1849 default:
1850 break;
1851 }
1852 codec->dapm.bias_level = level;
1853
1854 return 0;
1855}
1856
1857static int rt5640_probe(struct snd_soc_codec *codec)
1858{
1859 struct rt5640_priv *rt5640 = snd_soc_codec_get_drvdata(codec);
1860 int ret;
1861
1862 rt5640->codec = codec;
1863 codec->control_data = rt5640->regmap;
1864
1865 ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_REGMAP);
1866 if (ret != 0) {
1867 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
1868 return ret;
1869 }
1870
1871 codec->dapm.idle_bias_off = 1;
1872 rt5640_set_bias_level(codec, SND_SOC_BIAS_OFF);
1873
1874 snd_soc_update_bits(codec, RT5640_DUMMY1, 0x0301, 0x0301);
1875 snd_soc_update_bits(codec, RT5640_DEPOP_M1, 0x001d, 0x0019);
1876 snd_soc_update_bits(codec, RT5640_DEPOP_M2, 0x2000, 0x2000);
1877 snd_soc_update_bits(codec, RT5640_MICBIAS, 0x0030, 0x0030);
1878 snd_soc_update_bits(codec, RT5640_DSP_PATH2, 0xfc00, 0x0c00);
1879
1880 return 0;
1881}
1882
1883static int rt5640_remove(struct snd_soc_codec *codec)
1884{
1885 rt5640_reset(codec);
1886
1887 return 0;
1888}
1889
1890#ifdef CONFIG_PM
1891static int rt5640_suspend(struct snd_soc_codec *codec)
1892{
1893 struct rt5640_priv *rt5640 = snd_soc_codec_get_drvdata(codec);
1894
1895 rt5640_set_bias_level(codec, SND_SOC_BIAS_OFF);
1896 rt5640_reset(codec);
1897 regcache_cache_only(rt5640->regmap, true);
1898 regcache_mark_dirty(rt5640->regmap);
1899
1900 return 0;
1901}
1902
1903static int rt5640_resume(struct snd_soc_codec *codec)
1904{
1905 rt5640_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1906
1907 return 0;
1908}
1909#else
1910#define rt5640_suspend NULL
1911#define rt5640_resume NULL
1912#endif
1913
1914#define RT5640_STEREO_RATES SNDRV_PCM_RATE_8000_96000
1915#define RT5640_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \
1916 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S8)
1917
1918static const struct snd_soc_dai_ops rt5640_aif_dai_ops = {
1919 .hw_params = rt5640_hw_params,
1920 .set_fmt = rt5640_set_dai_fmt,
1921 .set_sysclk = rt5640_set_dai_sysclk,
1922 .set_pll = rt5640_set_dai_pll,
1923};
1924
1925static struct snd_soc_dai_driver rt5640_dai[] = {
1926 {
1927 .name = "rt5640-aif1",
1928 .id = RT5640_AIF1,
1929 .playback = {
1930 .stream_name = "AIF1 Playback",
1931 .channels_min = 1,
1932 .channels_max = 2,
1933 .rates = RT5640_STEREO_RATES,
1934 .formats = RT5640_FORMATS,
1935 },
1936 .capture = {
1937 .stream_name = "AIF1 Capture",
1938 .channels_min = 1,
1939 .channels_max = 2,
1940 .rates = RT5640_STEREO_RATES,
1941 .formats = RT5640_FORMATS,
1942 },
1943 .ops = &rt5640_aif_dai_ops,
1944 },
1945 {
1946 .name = "rt5640-aif2",
1947 .id = RT5640_AIF2,
1948 .playback = {
1949 .stream_name = "AIF2 Playback",
1950 .channels_min = 1,
1951 .channels_max = 2,
1952 .rates = RT5640_STEREO_RATES,
1953 .formats = RT5640_FORMATS,
1954 },
1955 .capture = {
1956 .stream_name = "AIF2 Capture",
1957 .channels_min = 1,
1958 .channels_max = 2,
1959 .rates = RT5640_STEREO_RATES,
1960 .formats = RT5640_FORMATS,
1961 },
1962 .ops = &rt5640_aif_dai_ops,
1963 },
1964};
1965
1966static struct snd_soc_codec_driver soc_codec_dev_rt5640 = {
1967 .probe = rt5640_probe,
1968 .remove = rt5640_remove,
1969 .suspend = rt5640_suspend,
1970 .resume = rt5640_resume,
1971 .set_bias_level = rt5640_set_bias_level,
1972 .controls = rt5640_snd_controls,
1973 .num_controls = ARRAY_SIZE(rt5640_snd_controls),
1974 .dapm_widgets = rt5640_dapm_widgets,
1975 .num_dapm_widgets = ARRAY_SIZE(rt5640_dapm_widgets),
1976 .dapm_routes = rt5640_dapm_routes,
1977 .num_dapm_routes = ARRAY_SIZE(rt5640_dapm_routes),
1978};
1979
1980static const struct regmap_config rt5640_regmap = {
1981 .reg_bits = 8,
1982 .val_bits = 16,
1983
1984 .max_register = RT5640_VENDOR_ID2 + 1 + (ARRAY_SIZE(rt5640_ranges) *
1985 RT5640_PR_SPACING),
1986 .volatile_reg = rt5640_volatile_register,
1987 .readable_reg = rt5640_readable_register,
1988
1989 .cache_type = REGCACHE_RBTREE,
1990 .reg_defaults = rt5640_reg,
1991 .num_reg_defaults = ARRAY_SIZE(rt5640_reg),
1992 .ranges = rt5640_ranges,
1993 .num_ranges = ARRAY_SIZE(rt5640_ranges),
1994};
1995
1996static const struct i2c_device_id rt5640_i2c_id[] = {
1997 { "rt5640", 0 },
1998 { }
1999};
2000MODULE_DEVICE_TABLE(i2c, rt5640_i2c_id);
2001
2002static int rt5640_parse_dt(struct rt5640_priv *rt5640, struct device_node *np)
2003{
2004 rt5640->pdata.in1_diff = of_property_read_bool(np,
2005 "realtek,in1-differential");
2006 rt5640->pdata.in2_diff = of_property_read_bool(np,
2007 "realtek,in2-differential");
2008
2009 rt5640->pdata.ldo1_en = of_get_named_gpio(np,
2010 "realtek,ldo1-en-gpios", 0);
2011 /*
2012 * LDO1_EN is optional (it may be statically tied on the board).
2013 * -ENOENT means that the property doesn't exist, i.e. there is no
2014 * GPIO, so is not an error. Any other error code means the property
2015 * exists, but could not be parsed.
2016 */
2017 if (!gpio_is_valid(rt5640->pdata.ldo1_en) &&
2018 (rt5640->pdata.ldo1_en != -ENOENT))
2019 return rt5640->pdata.ldo1_en;
2020
2021 return 0;
2022}
2023
2024static int rt5640_i2c_probe(struct i2c_client *i2c,
2025 const struct i2c_device_id *id)
2026{
2027 struct rt5640_platform_data *pdata = dev_get_platdata(&i2c->dev);
2028 struct rt5640_priv *rt5640;
2029 int ret;
2030 unsigned int val;
2031
2032 rt5640 = devm_kzalloc(&i2c->dev,
2033 sizeof(struct rt5640_priv),
2034 GFP_KERNEL);
2035 if (NULL == rt5640)
2036 return -ENOMEM;
2037 i2c_set_clientdata(i2c, rt5640);
2038
2039 if (pdata) {
2040 rt5640->pdata = *pdata;
2041 /*
2042 * Translate zero'd out (default) pdata value to an invalid
2043 * GPIO ID. This makes the pdata and DT paths consistent in
2044 * terms of the value left in this field when no GPIO is
2045 * specified, but means we can't actually use GPIO 0.
2046 */
2047 if (!rt5640->pdata.ldo1_en)
2048 rt5640->pdata.ldo1_en = -EINVAL;
2049 } else if (i2c->dev.of_node) {
2050 ret = rt5640_parse_dt(rt5640, i2c->dev.of_node);
2051 if (ret)
2052 return ret;
2053 } else
2054 rt5640->pdata.ldo1_en = -EINVAL;
2055
2056 rt5640->regmap = devm_regmap_init_i2c(i2c, &rt5640_regmap);
2057 if (IS_ERR(rt5640->regmap)) {
2058 ret = PTR_ERR(rt5640->regmap);
2059 dev_err(&i2c->dev, "Failed to allocate register map: %d\n",
2060 ret);
2061 return ret;
2062 }
2063
2064 if (gpio_is_valid(rt5640->pdata.ldo1_en)) {
2065 ret = devm_gpio_request_one(&i2c->dev, rt5640->pdata.ldo1_en,
2066 GPIOF_OUT_INIT_HIGH,
2067 "RT5640 LDO1_EN");
2068 if (ret < 0) {
2069 dev_err(&i2c->dev, "Failed to request LDO1_EN %d: %d\n",
2070 rt5640->pdata.ldo1_en, ret);
2071 return ret;
2072 }
2073 msleep(400);
2074 }
2075
2076 regmap_read(rt5640->regmap, RT5640_VENDOR_ID2, &val);
2077 if ((val != RT5640_DEVICE_ID)) {
2078 dev_err(&i2c->dev,
2079 "Device with ID register %x is not rt5640/39\n", val);
2080 return -ENODEV;
2081 }
2082
2083 regmap_write(rt5640->regmap, RT5640_RESET, 0);
2084
2085 ret = regmap_register_patch(rt5640->regmap, init_list,
2086 ARRAY_SIZE(init_list));
2087 if (ret != 0)
2088 dev_warn(&i2c->dev, "Failed to apply regmap patch: %d\n", ret);
2089
2090 if (rt5640->pdata.in1_diff)
2091 regmap_update_bits(rt5640->regmap, RT5640_IN1_IN2,
2092 RT5640_IN_DF1, RT5640_IN_DF1);
2093
2094 if (rt5640->pdata.in2_diff)
2095 regmap_update_bits(rt5640->regmap, RT5640_IN3_IN4,
2096 RT5640_IN_DF2, RT5640_IN_DF2);
2097
2098 ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_rt5640,
2099 rt5640_dai, ARRAY_SIZE(rt5640_dai));
2100 if (ret < 0)
2101 goto err;
2102
2103 return 0;
2104err:
2105 return ret;
2106}
2107
2108static int rt5640_i2c_remove(struct i2c_client *i2c)
2109{
2110 snd_soc_unregister_codec(&i2c->dev);
2111
2112 return 0;
2113}
2114
2115static struct i2c_driver rt5640_i2c_driver = {
2116 .driver = {
2117 .name = "rt5640",
2118 .owner = THIS_MODULE,
2119 },
2120 .probe = rt5640_i2c_probe,
2121 .remove = rt5640_i2c_remove,
2122 .id_table = rt5640_i2c_id,
2123};
2124module_i2c_driver(rt5640_i2c_driver);
2125
2126MODULE_DESCRIPTION("ASoC RT5640 driver");
2127MODULE_AUTHOR("Johnny Hsu <johnnyhsu@realtek.com>");
2128MODULE_LICENSE("GPL v2");
diff --git a/sound/soc/codecs/rt5640.h b/sound/soc/codecs/rt5640.h
new file mode 100644
index 000000000000..c48286d7118f
--- /dev/null
+++ b/sound/soc/codecs/rt5640.h
@@ -0,0 +1,2092 @@
1/*
2 * rt5640.h -- RT5640 ALSA SoC audio driver
3 *
4 * Copyright 2011 Realtek Microelectronics
5 * Author: Johnny Hsu <johnnyhsu@realtek.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11
12#ifndef _RT5640_H
13#define _RT5640_H
14
15#include <sound/rt5640.h>
16
17/* Info */
18#define RT5640_RESET 0x00
19#define RT5640_VENDOR_ID 0xfd
20#define RT5640_VENDOR_ID1 0xfe
21#define RT5640_VENDOR_ID2 0xff
22/* I/O - Output */
23#define RT5640_SPK_VOL 0x01
24#define RT5640_HP_VOL 0x02
25#define RT5640_OUTPUT 0x03
26#define RT5640_MONO_OUT 0x04
27/* I/O - Input */
28#define RT5640_IN1_IN2 0x0d
29#define RT5640_IN3_IN4 0x0e
30#define RT5640_INL_INR_VOL 0x0f
31/* I/O - ADC/DAC/DMIC */
32#define RT5640_DAC1_DIG_VOL 0x19
33#define RT5640_DAC2_DIG_VOL 0x1a
34#define RT5640_DAC2_CTRL 0x1b
35#define RT5640_ADC_DIG_VOL 0x1c
36#define RT5640_ADC_DATA 0x1d
37#define RT5640_ADC_BST_VOL 0x1e
38/* Mixer - D-D */
39#define RT5640_STO_ADC_MIXER 0x27
40#define RT5640_MONO_ADC_MIXER 0x28
41#define RT5640_AD_DA_MIXER 0x29
42#define RT5640_STO_DAC_MIXER 0x2a
43#define RT5640_MONO_DAC_MIXER 0x2b
44#define RT5640_DIG_MIXER 0x2c
45#define RT5640_DSP_PATH1 0x2d
46#define RT5640_DSP_PATH2 0x2e
47#define RT5640_DIG_INF_DATA 0x2f
48/* Mixer - ADC */
49#define RT5640_REC_L1_MIXER 0x3b
50#define RT5640_REC_L2_MIXER 0x3c
51#define RT5640_REC_R1_MIXER 0x3d
52#define RT5640_REC_R2_MIXER 0x3e
53/* Mixer - DAC */
54#define RT5640_HPO_MIXER 0x45
55#define RT5640_SPK_L_MIXER 0x46
56#define RT5640_SPK_R_MIXER 0x47
57#define RT5640_SPO_L_MIXER 0x48
58#define RT5640_SPO_R_MIXER 0x49
59#define RT5640_SPO_CLSD_RATIO 0x4a
60#define RT5640_MONO_MIXER 0x4c
61#define RT5640_OUT_L1_MIXER 0x4d
62#define RT5640_OUT_L2_MIXER 0x4e
63#define RT5640_OUT_L3_MIXER 0x4f
64#define RT5640_OUT_R1_MIXER 0x50
65#define RT5640_OUT_R2_MIXER 0x51
66#define RT5640_OUT_R3_MIXER 0x52
67#define RT5640_LOUT_MIXER 0x53
68/* Power */
69#define RT5640_PWR_DIG1 0x61
70#define RT5640_PWR_DIG2 0x62
71#define RT5640_PWR_ANLG1 0x63
72#define RT5640_PWR_ANLG2 0x64
73#define RT5640_PWR_MIXER 0x65
74#define RT5640_PWR_VOL 0x66
75/* Private Register Control */
76#define RT5640_PRIV_INDEX 0x6a
77#define RT5640_PRIV_DATA 0x6c
78/* Format - ADC/DAC */
79#define RT5640_I2S1_SDP 0x70
80#define RT5640_I2S2_SDP 0x71
81#define RT5640_ADDA_CLK1 0x73
82#define RT5640_ADDA_CLK2 0x74
83#define RT5640_DMIC 0x75
84/* Function - Analog */
85#define RT5640_GLB_CLK 0x80
86#define RT5640_PLL_CTRL1 0x81
87#define RT5640_PLL_CTRL2 0x82
88#define RT5640_ASRC_1 0x83
89#define RT5640_ASRC_2 0x84
90#define RT5640_ASRC_3 0x85
91#define RT5640_ASRC_4 0x89
92#define RT5640_ASRC_5 0x8a
93#define RT5640_HP_OVCD 0x8b
94#define RT5640_CLS_D_OVCD 0x8c
95#define RT5640_CLS_D_OUT 0x8d
96#define RT5640_DEPOP_M1 0x8e
97#define RT5640_DEPOP_M2 0x8f
98#define RT5640_DEPOP_M3 0x90
99#define RT5640_CHARGE_PUMP 0x91
100#define RT5640_PV_DET_SPK_G 0x92
101#define RT5640_MICBIAS 0x93
102/* Function - Digital */
103#define RT5640_EQ_CTRL1 0xb0
104#define RT5640_EQ_CTRL2 0xb1
105#define RT5640_WIND_FILTER 0xb2
106#define RT5640_DRC_AGC_1 0xb4
107#define RT5640_DRC_AGC_2 0xb5
108#define RT5640_DRC_AGC_3 0xb6
109#define RT5640_SVOL_ZC 0xb7
110#define RT5640_ANC_CTRL1 0xb8
111#define RT5640_ANC_CTRL2 0xb9
112#define RT5640_ANC_CTRL3 0xba
113#define RT5640_JD_CTRL 0xbb
114#define RT5640_ANC_JD 0xbc
115#define RT5640_IRQ_CTRL1 0xbd
116#define RT5640_IRQ_CTRL2 0xbe
117#define RT5640_INT_IRQ_ST 0xbf
118#define RT5640_GPIO_CTRL1 0xc0
119#define RT5640_GPIO_CTRL2 0xc1
120#define RT5640_GPIO_CTRL3 0xc2
121#define RT5640_DSP_CTRL1 0xc4
122#define RT5640_DSP_CTRL2 0xc5
123#define RT5640_DSP_CTRL3 0xc6
124#define RT5640_DSP_CTRL4 0xc7
125#define RT5640_PGM_REG_ARR1 0xc8
126#define RT5640_PGM_REG_ARR2 0xc9
127#define RT5640_PGM_REG_ARR3 0xca
128#define RT5640_PGM_REG_ARR4 0xcb
129#define RT5640_PGM_REG_ARR5 0xcc
130#define RT5640_SCB_FUNC 0xcd
131#define RT5640_SCB_CTRL 0xce
132#define RT5640_BASE_BACK 0xcf
133#define RT5640_MP3_PLUS1 0xd0
134#define RT5640_MP3_PLUS2 0xd1
135#define RT5640_3D_HP 0xd2
136#define RT5640_ADJ_HPF 0xd3
137#define RT5640_HP_CALIB_AMP_DET 0xd6
138#define RT5640_HP_CALIB2 0xd7
139#define RT5640_SV_ZCD1 0xd9
140#define RT5640_SV_ZCD2 0xda
141/* Dummy Register */
142#define RT5640_DUMMY1 0xfa
143#define RT5640_DUMMY2 0xfb
144#define RT5640_DUMMY3 0xfc
145
146
147/* Index of Codec Private Register definition */
148#define RT5640_3D_SPK 0x63
149#define RT5640_WND_1 0x6c
150#define RT5640_WND_2 0x6d
151#define RT5640_WND_3 0x6e
152#define RT5640_WND_4 0x6f
153#define RT5640_WND_5 0x70
154#define RT5640_WND_8 0x73
155#define RT5640_DIP_SPK_INF 0x75
156#define RT5640_EQ_BW_LOP 0xa0
157#define RT5640_EQ_GN_LOP 0xa1
158#define RT5640_EQ_FC_BP1 0xa2
159#define RT5640_EQ_BW_BP1 0xa3
160#define RT5640_EQ_GN_BP1 0xa4
161#define RT5640_EQ_FC_BP2 0xa5
162#define RT5640_EQ_BW_BP2 0xa6
163#define RT5640_EQ_GN_BP2 0xa7
164#define RT5640_EQ_FC_BP3 0xa8
165#define RT5640_EQ_BW_BP3 0xa9
166#define RT5640_EQ_GN_BP3 0xaa
167#define RT5640_EQ_FC_BP4 0xab
168#define RT5640_EQ_BW_BP4 0xac
169#define RT5640_EQ_GN_BP4 0xad
170#define RT5640_EQ_FC_HIP1 0xae
171#define RT5640_EQ_GN_HIP1 0xaf
172#define RT5640_EQ_FC_HIP2 0xb0
173#define RT5640_EQ_BW_HIP2 0xb1
174#define RT5640_EQ_GN_HIP2 0xb2
175#define RT5640_EQ_PRE_VOL 0xb3
176#define RT5640_EQ_PST_VOL 0xb4
177
178/* global definition */
179#define RT5640_L_MUTE (0x1 << 15)
180#define RT5640_L_MUTE_SFT 15
181#define RT5640_VOL_L_MUTE (0x1 << 14)
182#define RT5640_VOL_L_SFT 14
183#define RT5640_R_MUTE (0x1 << 7)
184#define RT5640_R_MUTE_SFT 7
185#define RT5640_VOL_R_MUTE (0x1 << 6)
186#define RT5640_VOL_R_SFT 6
187#define RT5640_L_VOL_MASK (0x3f << 8)
188#define RT5640_L_VOL_SFT 8
189#define RT5640_R_VOL_MASK (0x3f)
190#define RT5640_R_VOL_SFT 0
191
192/* IN1 and IN2 Control (0x0d) */
193/* IN3 and IN4 Control (0x0e) */
194#define RT5640_BST_SFT1 12
195#define RT5640_BST_SFT2 8
196#define RT5640_IN_DF1 (0x1 << 7)
197#define RT5640_IN_SFT1 7
198#define RT5640_IN_DF2 (0x1 << 6)
199#define RT5640_IN_SFT2 6
200
201/* INL and INR Volume Control (0x0f) */
202#define RT5640_INL_SEL_MASK (0x1 << 15)
203#define RT5640_INL_SEL_SFT 15
204#define RT5640_INL_SEL_IN4P (0x0 << 15)
205#define RT5640_INL_SEL_MONOP (0x1 << 15)
206#define RT5640_INL_VOL_MASK (0x1f << 8)
207#define RT5640_INL_VOL_SFT 8
208#define RT5640_INR_SEL_MASK (0x1 << 7)
209#define RT5640_INR_SEL_SFT 7
210#define RT5640_INR_SEL_IN4N (0x0 << 7)
211#define RT5640_INR_SEL_MONON (0x1 << 7)
212#define RT5640_INR_VOL_MASK (0x1f)
213#define RT5640_INR_VOL_SFT 0
214
215/* DAC1 Digital Volume (0x19) */
216#define RT5640_DAC_L1_VOL_MASK (0xff << 8)
217#define RT5640_DAC_L1_VOL_SFT 8
218#define RT5640_DAC_R1_VOL_MASK (0xff)
219#define RT5640_DAC_R1_VOL_SFT 0
220
221/* DAC2 Digital Volume (0x1a) */
222#define RT5640_DAC_L2_VOL_MASK (0xff << 8)
223#define RT5640_DAC_L2_VOL_SFT 8
224#define RT5640_DAC_R2_VOL_MASK (0xff)
225#define RT5640_DAC_R2_VOL_SFT 0
226
227/* DAC2 Control (0x1b) */
228#define RT5640_M_DAC_L2_VOL (0x1 << 13)
229#define RT5640_M_DAC_L2_VOL_SFT 13
230#define RT5640_M_DAC_R2_VOL (0x1 << 12)
231#define RT5640_M_DAC_R2_VOL_SFT 12
232
233/* ADC Digital Volume Control (0x1c) */
234#define RT5640_ADC_L_VOL_MASK (0x7f << 8)
235#define RT5640_ADC_L_VOL_SFT 8
236#define RT5640_ADC_R_VOL_MASK (0x7f)
237#define RT5640_ADC_R_VOL_SFT 0
238
239/* Mono ADC Digital Volume Control (0x1d) */
240#define RT5640_MONO_ADC_L_VOL_MASK (0x7f << 8)
241#define RT5640_MONO_ADC_L_VOL_SFT 8
242#define RT5640_MONO_ADC_R_VOL_MASK (0x7f)
243#define RT5640_MONO_ADC_R_VOL_SFT 0
244
245/* ADC Boost Volume Control (0x1e) */
246#define RT5640_ADC_L_BST_MASK (0x3 << 14)
247#define RT5640_ADC_L_BST_SFT 14
248#define RT5640_ADC_R_BST_MASK (0x3 << 12)
249#define RT5640_ADC_R_BST_SFT 12
250#define RT5640_ADC_COMP_MASK (0x3 << 10)
251#define RT5640_ADC_COMP_SFT 10
252
253/* Stereo ADC Mixer Control (0x27) */
254#define RT5640_M_ADC_L1 (0x1 << 14)
255#define RT5640_M_ADC_L1_SFT 14
256#define RT5640_M_ADC_L2 (0x1 << 13)
257#define RT5640_M_ADC_L2_SFT 13
258#define RT5640_ADC_1_SRC_MASK (0x1 << 12)
259#define RT5640_ADC_1_SRC_SFT 12
260#define RT5640_ADC_1_SRC_ADC (0x1 << 12)
261#define RT5640_ADC_1_SRC_DACMIX (0x0 << 12)
262#define RT5640_ADC_2_SRC_MASK (0x3 << 10)
263#define RT5640_ADC_2_SRC_SFT 10
264#define RT5640_ADC_2_SRC_DMIC1 (0x0 << 10)
265#define RT5640_ADC_2_SRC_DMIC2 (0x1 << 10)
266#define RT5640_ADC_2_SRC_DACMIX (0x2 << 10)
267#define RT5640_M_ADC_R1 (0x1 << 6)
268#define RT5640_M_ADC_R1_SFT 6
269#define RT5640_M_ADC_R2 (0x1 << 5)
270#define RT5640_M_ADC_R2_SFT 5
271
272/* Mono ADC Mixer Control (0x28) */
273#define RT5640_M_MONO_ADC_L1 (0x1 << 14)
274#define RT5640_M_MONO_ADC_L1_SFT 14
275#define RT5640_M_MONO_ADC_L2 (0x1 << 13)
276#define RT5640_M_MONO_ADC_L2_SFT 13
277#define RT5640_MONO_ADC_L1_SRC_MASK (0x1 << 12)
278#define RT5640_MONO_ADC_L1_SRC_SFT 12
279#define RT5640_MONO_ADC_L1_SRC_DACMIXL (0x0 << 12)
280#define RT5640_MONO_ADC_L1_SRC_ADCL (0x1 << 12)
281#define RT5640_MONO_ADC_L2_SRC_MASK (0x3 << 10)
282#define RT5640_MONO_ADC_L2_SRC_SFT 10
283#define RT5640_MONO_ADC_L2_SRC_DMIC_L1 (0x0 << 10)
284#define RT5640_MONO_ADC_L2_SRC_DMIC_L2 (0x1 << 10)
285#define RT5640_MONO_ADC_L2_SRC_DACMIXL (0x2 << 10)
286#define RT5640_M_MONO_ADC_R1 (0x1 << 6)
287#define RT5640_M_MONO_ADC_R1_SFT 6
288#define RT5640_M_MONO_ADC_R2 (0x1 << 5)
289#define RT5640_M_MONO_ADC_R2_SFT 5
290#define RT5640_MONO_ADC_R1_SRC_MASK (0x1 << 4)
291#define RT5640_MONO_ADC_R1_SRC_SFT 4
292#define RT5640_MONO_ADC_R1_SRC_ADCR (0x1 << 4)
293#define RT5640_MONO_ADC_R1_SRC_DACMIXR (0x0 << 4)
294#define RT5640_MONO_ADC_R2_SRC_MASK (0x3 << 2)
295#define RT5640_MONO_ADC_R2_SRC_SFT 2
296#define RT5640_MONO_ADC_R2_SRC_DMIC_R1 (0x0 << 2)
297#define RT5640_MONO_ADC_R2_SRC_DMIC_R2 (0x1 << 2)
298#define RT5640_MONO_ADC_R2_SRC_DACMIXR (0x2 << 2)
299
300/* ADC Mixer to DAC Mixer Control (0x29) */
301#define RT5640_M_ADCMIX_L (0x1 << 15)
302#define RT5640_M_ADCMIX_L_SFT 15
303#define RT5640_M_IF1_DAC_L (0x1 << 14)
304#define RT5640_M_IF1_DAC_L_SFT 14
305#define RT5640_M_ADCMIX_R (0x1 << 7)
306#define RT5640_M_ADCMIX_R_SFT 7
307#define RT5640_M_IF1_DAC_R (0x1 << 6)
308#define RT5640_M_IF1_DAC_R_SFT 6
309
310/* Stereo DAC Mixer Control (0x2a) */
311#define RT5640_M_DAC_L1 (0x1 << 14)
312#define RT5640_M_DAC_L1_SFT 14
313#define RT5640_DAC_L1_STO_L_VOL_MASK (0x1 << 13)
314#define RT5640_DAC_L1_STO_L_VOL_SFT 13
315#define RT5640_M_DAC_L2 (0x1 << 12)
316#define RT5640_M_DAC_L2_SFT 12
317#define RT5640_DAC_L2_STO_L_VOL_MASK (0x1 << 11)
318#define RT5640_DAC_L2_STO_L_VOL_SFT 11
319#define RT5640_M_ANC_DAC_L (0x1 << 10)
320#define RT5640_M_ANC_DAC_L_SFT 10
321#define RT5640_M_DAC_R1 (0x1 << 6)
322#define RT5640_M_DAC_R1_SFT 6
323#define RT5640_DAC_R1_STO_R_VOL_MASK (0x1 << 5)
324#define RT5640_DAC_R1_STO_R_VOL_SFT 5
325#define RT5640_M_DAC_R2 (0x1 << 4)
326#define RT5640_M_DAC_R2_SFT 4
327#define RT5640_DAC_R2_STO_R_VOL_MASK (0x1 << 3)
328#define RT5640_DAC_R2_STO_R_VOL_SFT 3
329#define RT5640_M_ANC_DAC_R (0x1 << 2)
330#define RT5640_M_ANC_DAC_R_SFT 2
331
332/* Mono DAC Mixer Control (0x2b) */
333#define RT5640_M_DAC_L1_MONO_L (0x1 << 14)
334#define RT5640_M_DAC_L1_MONO_L_SFT 14
335#define RT5640_DAC_L1_MONO_L_VOL_MASK (0x1 << 13)
336#define RT5640_DAC_L1_MONO_L_VOL_SFT 13
337#define RT5640_M_DAC_L2_MONO_L (0x1 << 12)
338#define RT5640_M_DAC_L2_MONO_L_SFT 12
339#define RT5640_DAC_L2_MONO_L_VOL_MASK (0x1 << 11)
340#define RT5640_DAC_L2_MONO_L_VOL_SFT 11
341#define RT5640_M_DAC_R2_MONO_L (0x1 << 10)
342#define RT5640_M_DAC_R2_MONO_L_SFT 10
343#define RT5640_DAC_R2_MONO_L_VOL_MASK (0x1 << 9)
344#define RT5640_DAC_R2_MONO_L_VOL_SFT 9
345#define RT5640_M_DAC_R1_MONO_R (0x1 << 6)
346#define RT5640_M_DAC_R1_MONO_R_SFT 6
347#define RT5640_DAC_R1_MONO_R_VOL_MASK (0x1 << 5)
348#define RT5640_DAC_R1_MONO_R_VOL_SFT 5
349#define RT5640_M_DAC_R2_MONO_R (0x1 << 4)
350#define RT5640_M_DAC_R2_MONO_R_SFT 4
351#define RT5640_DAC_R2_MONO_R_VOL_MASK (0x1 << 3)
352#define RT5640_DAC_R2_MONO_R_VOL_SFT 3
353#define RT5640_M_DAC_L2_MONO_R (0x1 << 2)
354#define RT5640_M_DAC_L2_MONO_R_SFT 2
355#define RT5640_DAC_L2_MONO_R_VOL_MASK (0x1 << 1)
356#define RT5640_DAC_L2_MONO_R_VOL_SFT 1
357
358/* Digital Mixer Control (0x2c) */
359#define RT5640_M_STO_L_DAC_L (0x1 << 15)
360#define RT5640_M_STO_L_DAC_L_SFT 15
361#define RT5640_STO_L_DAC_L_VOL_MASK (0x1 << 14)
362#define RT5640_STO_L_DAC_L_VOL_SFT 14
363#define RT5640_M_DAC_L2_DAC_L (0x1 << 13)
364#define RT5640_M_DAC_L2_DAC_L_SFT 13
365#define RT5640_DAC_L2_DAC_L_VOL_MASK (0x1 << 12)
366#define RT5640_DAC_L2_DAC_L_VOL_SFT 12
367#define RT5640_M_STO_R_DAC_R (0x1 << 11)
368#define RT5640_M_STO_R_DAC_R_SFT 11
369#define RT5640_STO_R_DAC_R_VOL_MASK (0x1 << 10)
370#define RT5640_STO_R_DAC_R_VOL_SFT 10
371#define RT5640_M_DAC_R2_DAC_R (0x1 << 9)
372#define RT5640_M_DAC_R2_DAC_R_SFT 9
373#define RT5640_DAC_R2_DAC_R_VOL_MASK (0x1 << 8)
374#define RT5640_DAC_R2_DAC_R_VOL_SFT 8
375
376/* DSP Path Control 1 (0x2d) */
377#define RT5640_RXDP_SRC_MASK (0x1 << 15)
378#define RT5640_RXDP_SRC_SFT 15
379#define RT5640_RXDP_SRC_NOR (0x0 << 15)
380#define RT5640_RXDP_SRC_DIV3 (0x1 << 15)
381#define RT5640_TXDP_SRC_MASK (0x1 << 14)
382#define RT5640_TXDP_SRC_SFT 14
383#define RT5640_TXDP_SRC_NOR (0x0 << 14)
384#define RT5640_TXDP_SRC_DIV3 (0x1 << 14)
385
386/* DSP Path Control 2 (0x2e) */
387#define RT5640_DAC_L2_SEL_MASK (0x3 << 14)
388#define RT5640_DAC_L2_SEL_SFT 14
389#define RT5640_DAC_L2_SEL_IF2 (0x0 << 14)
390#define RT5640_DAC_L2_SEL_IF3 (0x1 << 14)
391#define RT5640_DAC_L2_SEL_TXDC (0x2 << 14)
392#define RT5640_DAC_L2_SEL_BASS (0x3 << 14)
393#define RT5640_DAC_R2_SEL_MASK (0x3 << 12)
394#define RT5640_DAC_R2_SEL_SFT 12
395#define RT5640_DAC_R2_SEL_IF2 (0x0 << 12)
396#define RT5640_DAC_R2_SEL_IF3 (0x1 << 12)
397#define RT5640_DAC_R2_SEL_TXDC (0x2 << 12)
398#define RT5640_IF2_ADC_L_SEL_MASK (0x1 << 11)
399#define RT5640_IF2_ADC_L_SEL_SFT 11
400#define RT5640_IF2_ADC_L_SEL_TXDP (0x0 << 11)
401#define RT5640_IF2_ADC_L_SEL_PASS (0x1 << 11)
402#define RT5640_IF2_ADC_R_SEL_MASK (0x1 << 10)
403#define RT5640_IF2_ADC_R_SEL_SFT 10
404#define RT5640_IF2_ADC_R_SEL_TXDP (0x0 << 10)
405#define RT5640_IF2_ADC_R_SEL_PASS (0x1 << 10)
406#define RT5640_RXDC_SEL_MASK (0x3 << 8)
407#define RT5640_RXDC_SEL_SFT 8
408#define RT5640_RXDC_SEL_NOR (0x0 << 8)
409#define RT5640_RXDC_SEL_L2R (0x1 << 8)
410#define RT5640_RXDC_SEL_R2L (0x2 << 8)
411#define RT5640_RXDC_SEL_SWAP (0x3 << 8)
412#define RT5640_RXDP_SEL_MASK (0x3 << 6)
413#define RT5640_RXDP_SEL_SFT 6
414#define RT5640_RXDP_SEL_NOR (0x0 << 6)
415#define RT5640_RXDP_SEL_L2R (0x1 << 6)
416#define RT5640_RXDP_SEL_R2L (0x2 << 6)
417#define RT5640_RXDP_SEL_SWAP (0x3 << 6)
418#define RT5640_TXDC_SEL_MASK (0x3 << 4)
419#define RT5640_TXDC_SEL_SFT 4
420#define RT5640_TXDC_SEL_NOR (0x0 << 4)
421#define RT5640_TXDC_SEL_L2R (0x1 << 4)
422#define RT5640_TXDC_SEL_R2L (0x2 << 4)
423#define RT5640_TXDC_SEL_SWAP (0x3 << 4)
424#define RT5640_TXDP_SEL_MASK (0x3 << 2)
425#define RT5640_TXDP_SEL_SFT 2
426#define RT5640_TXDP_SEL_NOR (0x0 << 2)
427#define RT5640_TXDP_SEL_L2R (0x1 << 2)
428#define RT5640_TXDP_SEL_R2L (0x2 << 2)
429#define RT5640_TRXDP_SEL_SWAP (0x3 << 2)
430
431/* Digital Interface Data Control (0x2f) */
432#define RT5640_IF1_DAC_SEL_MASK (0x3 << 14)
433#define RT5640_IF1_DAC_SEL_SFT 14
434#define RT5640_IF1_DAC_SEL_NOR (0x0 << 14)
435#define RT5640_IF1_DAC_SEL_L2R (0x1 << 14)
436#define RT5640_IF1_DAC_SEL_R2L (0x2 << 14)
437#define RT5640_IF1_DAC_SEL_SWAP (0x3 << 14)
438#define RT5640_IF1_ADC_SEL_MASK (0x3 << 12)
439#define RT5640_IF1_ADC_SEL_SFT 12
440#define RT5640_IF1_ADC_SEL_NOR (0x0 << 12)
441#define RT5640_IF1_ADC_SEL_L2R (0x1 << 12)
442#define RT5640_IF1_ADC_SEL_R2L (0x2 << 12)
443#define RT5640_IF1_ADC_SEL_SWAP (0x3 << 12)
444#define RT5640_IF2_DAC_SEL_MASK (0x3 << 10)
445#define RT5640_IF2_DAC_SEL_SFT 10
446#define RT5640_IF2_DAC_SEL_NOR (0x0 << 10)
447#define RT5640_IF2_DAC_SEL_L2R (0x1 << 10)
448#define RT5640_IF2_DAC_SEL_R2L (0x2 << 10)
449#define RT5640_IF2_DAC_SEL_SWAP (0x3 << 10)
450#define RT5640_IF2_ADC_SEL_MASK (0x3 << 8)
451#define RT5640_IF2_ADC_SEL_SFT 8
452#define RT5640_IF2_ADC_SEL_NOR (0x0 << 8)
453#define RT5640_IF2_ADC_SEL_L2R (0x1 << 8)
454#define RT5640_IF2_ADC_SEL_R2L (0x2 << 8)
455#define RT5640_IF2_ADC_SEL_SWAP (0x3 << 8)
456#define RT5640_IF3_DAC_SEL_MASK (0x3 << 6)
457#define RT5640_IF3_DAC_SEL_SFT 6
458#define RT5640_IF3_DAC_SEL_NOR (0x0 << 6)
459#define RT5640_IF3_DAC_SEL_L2R (0x1 << 6)
460#define RT5640_IF3_DAC_SEL_R2L (0x2 << 6)
461#define RT5640_IF3_DAC_SEL_SWAP (0x3 << 6)
462#define RT5640_IF3_ADC_SEL_MASK (0x3 << 4)
463#define RT5640_IF3_ADC_SEL_SFT 4
464#define RT5640_IF3_ADC_SEL_NOR (0x0 << 4)
465#define RT5640_IF3_ADC_SEL_L2R (0x1 << 4)
466#define RT5640_IF3_ADC_SEL_R2L (0x2 << 4)
467#define RT5640_IF3_ADC_SEL_SWAP (0x3 << 4)
468
469/* REC Left Mixer Control 1 (0x3b) */
470#define RT5640_G_HP_L_RM_L_MASK (0x7 << 13)
471#define RT5640_G_HP_L_RM_L_SFT 13
472#define RT5640_G_IN_L_RM_L_MASK (0x7 << 10)
473#define RT5640_G_IN_L_RM_L_SFT 10
474#define RT5640_G_BST4_RM_L_MASK (0x7 << 7)
475#define RT5640_G_BST4_RM_L_SFT 7
476#define RT5640_G_BST3_RM_L_MASK (0x7 << 4)
477#define RT5640_G_BST3_RM_L_SFT 4
478#define RT5640_G_BST2_RM_L_MASK (0x7 << 1)
479#define RT5640_G_BST2_RM_L_SFT 1
480
481/* REC Left Mixer Control 2 (0x3c) */
482#define RT5640_G_BST1_RM_L_MASK (0x7 << 13)
483#define RT5640_G_BST1_RM_L_SFT 13
484#define RT5640_G_OM_L_RM_L_MASK (0x7 << 10)
485#define RT5640_G_OM_L_RM_L_SFT 10
486#define RT5640_M_HP_L_RM_L (0x1 << 6)
487#define RT5640_M_HP_L_RM_L_SFT 6
488#define RT5640_M_IN_L_RM_L (0x1 << 5)
489#define RT5640_M_IN_L_RM_L_SFT 5
490#define RT5640_M_BST4_RM_L (0x1 << 4)
491#define RT5640_M_BST4_RM_L_SFT 4
492#define RT5640_M_BST3_RM_L (0x1 << 3)
493#define RT5640_M_BST3_RM_L_SFT 3
494#define RT5640_M_BST2_RM_L (0x1 << 2)
495#define RT5640_M_BST2_RM_L_SFT 2
496#define RT5640_M_BST1_RM_L (0x1 << 1)
497#define RT5640_M_BST1_RM_L_SFT 1
498#define RT5640_M_OM_L_RM_L (0x1)
499#define RT5640_M_OM_L_RM_L_SFT 0
500
501/* REC Right Mixer Control 1 (0x3d) */
502#define RT5640_G_HP_R_RM_R_MASK (0x7 << 13)
503#define RT5640_G_HP_R_RM_R_SFT 13
504#define RT5640_G_IN_R_RM_R_MASK (0x7 << 10)
505#define RT5640_G_IN_R_RM_R_SFT 10
506#define RT5640_G_BST4_RM_R_MASK (0x7 << 7)
507#define RT5640_G_BST4_RM_R_SFT 7
508#define RT5640_G_BST3_RM_R_MASK (0x7 << 4)
509#define RT5640_G_BST3_RM_R_SFT 4
510#define RT5640_G_BST2_RM_R_MASK (0x7 << 1)
511#define RT5640_G_BST2_RM_R_SFT 1
512
513/* REC Right Mixer Control 2 (0x3e) */
514#define RT5640_G_BST1_RM_R_MASK (0x7 << 13)
515#define RT5640_G_BST1_RM_R_SFT 13
516#define RT5640_G_OM_R_RM_R_MASK (0x7 << 10)
517#define RT5640_G_OM_R_RM_R_SFT 10
518#define RT5640_M_HP_R_RM_R (0x1 << 6)
519#define RT5640_M_HP_R_RM_R_SFT 6
520#define RT5640_M_IN_R_RM_R (0x1 << 5)
521#define RT5640_M_IN_R_RM_R_SFT 5
522#define RT5640_M_BST4_RM_R (0x1 << 4)
523#define RT5640_M_BST4_RM_R_SFT 4
524#define RT5640_M_BST3_RM_R (0x1 << 3)
525#define RT5640_M_BST3_RM_R_SFT 3
526#define RT5640_M_BST2_RM_R (0x1 << 2)
527#define RT5640_M_BST2_RM_R_SFT 2
528#define RT5640_M_BST1_RM_R (0x1 << 1)
529#define RT5640_M_BST1_RM_R_SFT 1
530#define RT5640_M_OM_R_RM_R (0x1)
531#define RT5640_M_OM_R_RM_R_SFT 0
532
533/* HPMIX Control (0x45) */
534#define RT5640_M_DAC2_HM (0x1 << 15)
535#define RT5640_M_DAC2_HM_SFT 15
536#define RT5640_M_DAC1_HM (0x1 << 14)
537#define RT5640_M_DAC1_HM_SFT 14
538#define RT5640_M_HPVOL_HM (0x1 << 13)
539#define RT5640_M_HPVOL_HM_SFT 13
540#define RT5640_G_HPOMIX_MASK (0x1 << 12)
541#define RT5640_G_HPOMIX_SFT 12
542
543/* SPK Left Mixer Control (0x46) */
544#define RT5640_G_RM_L_SM_L_MASK (0x3 << 14)
545#define RT5640_G_RM_L_SM_L_SFT 14
546#define RT5640_G_IN_L_SM_L_MASK (0x3 << 12)
547#define RT5640_G_IN_L_SM_L_SFT 12
548#define RT5640_G_DAC_L1_SM_L_MASK (0x3 << 10)
549#define RT5640_G_DAC_L1_SM_L_SFT 10
550#define RT5640_G_DAC_L2_SM_L_MASK (0x3 << 8)
551#define RT5640_G_DAC_L2_SM_L_SFT 8
552#define RT5640_G_OM_L_SM_L_MASK (0x3 << 6)
553#define RT5640_G_OM_L_SM_L_SFT 6
554#define RT5640_M_RM_L_SM_L (0x1 << 5)
555#define RT5640_M_RM_L_SM_L_SFT 5
556#define RT5640_M_IN_L_SM_L (0x1 << 4)
557#define RT5640_M_IN_L_SM_L_SFT 4
558#define RT5640_M_DAC_L1_SM_L (0x1 << 3)
559#define RT5640_M_DAC_L1_SM_L_SFT 3
560#define RT5640_M_DAC_L2_SM_L (0x1 << 2)
561#define RT5640_M_DAC_L2_SM_L_SFT 2
562#define RT5640_M_OM_L_SM_L (0x1 << 1)
563#define RT5640_M_OM_L_SM_L_SFT 1
564
565/* SPK Right Mixer Control (0x47) */
566#define RT5640_G_RM_R_SM_R_MASK (0x3 << 14)
567#define RT5640_G_RM_R_SM_R_SFT 14
568#define RT5640_G_IN_R_SM_R_MASK (0x3 << 12)
569#define RT5640_G_IN_R_SM_R_SFT 12
570#define RT5640_G_DAC_R1_SM_R_MASK (0x3 << 10)
571#define RT5640_G_DAC_R1_SM_R_SFT 10
572#define RT5640_G_DAC_R2_SM_R_MASK (0x3 << 8)
573#define RT5640_G_DAC_R2_SM_R_SFT 8
574#define RT5640_G_OM_R_SM_R_MASK (0x3 << 6)
575#define RT5640_G_OM_R_SM_R_SFT 6
576#define RT5640_M_RM_R_SM_R (0x1 << 5)
577#define RT5640_M_RM_R_SM_R_SFT 5
578#define RT5640_M_IN_R_SM_R (0x1 << 4)
579#define RT5640_M_IN_R_SM_R_SFT 4
580#define RT5640_M_DAC_R1_SM_R (0x1 << 3)
581#define RT5640_M_DAC_R1_SM_R_SFT 3
582#define RT5640_M_DAC_R2_SM_R (0x1 << 2)
583#define RT5640_M_DAC_R2_SM_R_SFT 2
584#define RT5640_M_OM_R_SM_R (0x1 << 1)
585#define RT5640_M_OM_R_SM_R_SFT 1
586
587/* SPOLMIX Control (0x48) */
588#define RT5640_M_DAC_R1_SPM_L (0x1 << 15)
589#define RT5640_M_DAC_R1_SPM_L_SFT 15
590#define RT5640_M_DAC_L1_SPM_L (0x1 << 14)
591#define RT5640_M_DAC_L1_SPM_L_SFT 14
592#define RT5640_M_SV_R_SPM_L (0x1 << 13)
593#define RT5640_M_SV_R_SPM_L_SFT 13
594#define RT5640_M_SV_L_SPM_L (0x1 << 12)
595#define RT5640_M_SV_L_SPM_L_SFT 12
596#define RT5640_M_BST1_SPM_L (0x1 << 11)
597#define RT5640_M_BST1_SPM_L_SFT 11
598
599/* SPORMIX Control (0x49) */
600#define RT5640_M_DAC_R1_SPM_R (0x1 << 13)
601#define RT5640_M_DAC_R1_SPM_R_SFT 13
602#define RT5640_M_SV_R_SPM_R (0x1 << 12)
603#define RT5640_M_SV_R_SPM_R_SFT 12
604#define RT5640_M_BST1_SPM_R (0x1 << 11)
605#define RT5640_M_BST1_SPM_R_SFT 11
606
607/* SPOLMIX / SPORMIX Ratio Control (0x4a) */
608#define RT5640_SPO_CLSD_RATIO_MASK (0x7)
609#define RT5640_SPO_CLSD_RATIO_SFT 0
610
611/* Mono Output Mixer Control (0x4c) */
612#define RT5640_M_DAC_R2_MM (0x1 << 15)
613#define RT5640_M_DAC_R2_MM_SFT 15
614#define RT5640_M_DAC_L2_MM (0x1 << 14)
615#define RT5640_M_DAC_L2_MM_SFT 14
616#define RT5640_M_OV_R_MM (0x1 << 13)
617#define RT5640_M_OV_R_MM_SFT 13
618#define RT5640_M_OV_L_MM (0x1 << 12)
619#define RT5640_M_OV_L_MM_SFT 12
620#define RT5640_M_BST1_MM (0x1 << 11)
621#define RT5640_M_BST1_MM_SFT 11
622#define RT5640_G_MONOMIX_MASK (0x1 << 10)
623#define RT5640_G_MONOMIX_SFT 10
624
625/* Output Left Mixer Control 1 (0x4d) */
626#define RT5640_G_BST3_OM_L_MASK (0x7 << 13)
627#define RT5640_G_BST3_OM_L_SFT 13
628#define RT5640_G_BST2_OM_L_MASK (0x7 << 10)
629#define RT5640_G_BST2_OM_L_SFT 10
630#define RT5640_G_BST1_OM_L_MASK (0x7 << 7)
631#define RT5640_G_BST1_OM_L_SFT 7
632#define RT5640_G_IN_L_OM_L_MASK (0x7 << 4)
633#define RT5640_G_IN_L_OM_L_SFT 4
634#define RT5640_G_RM_L_OM_L_MASK (0x7 << 1)
635#define RT5640_G_RM_L_OM_L_SFT 1
636
637/* Output Left Mixer Control 2 (0x4e) */
638#define RT5640_G_DAC_R2_OM_L_MASK (0x7 << 13)
639#define RT5640_G_DAC_R2_OM_L_SFT 13
640#define RT5640_G_DAC_L2_OM_L_MASK (0x7 << 10)
641#define RT5640_G_DAC_L2_OM_L_SFT 10
642#define RT5640_G_DAC_L1_OM_L_MASK (0x7 << 7)
643#define RT5640_G_DAC_L1_OM_L_SFT 7
644
645/* Output Left Mixer Control 3 (0x4f) */
646#define RT5640_M_SM_L_OM_L (0x1 << 8)
647#define RT5640_M_SM_L_OM_L_SFT 8
648#define RT5640_M_BST3_OM_L (0x1 << 7)
649#define RT5640_M_BST3_OM_L_SFT 7
650#define RT5640_M_BST2_OM_L (0x1 << 6)
651#define RT5640_M_BST2_OM_L_SFT 6
652#define RT5640_M_BST1_OM_L (0x1 << 5)
653#define RT5640_M_BST1_OM_L_SFT 5
654#define RT5640_M_IN_L_OM_L (0x1 << 4)
655#define RT5640_M_IN_L_OM_L_SFT 4
656#define RT5640_M_RM_L_OM_L (0x1 << 3)
657#define RT5640_M_RM_L_OM_L_SFT 3
658#define RT5640_M_DAC_R2_OM_L (0x1 << 2)
659#define RT5640_M_DAC_R2_OM_L_SFT 2
660#define RT5640_M_DAC_L2_OM_L (0x1 << 1)
661#define RT5640_M_DAC_L2_OM_L_SFT 1
662#define RT5640_M_DAC_L1_OM_L (0x1)
663#define RT5640_M_DAC_L1_OM_L_SFT 0
664
665/* Output Right Mixer Control 1 (0x50) */
666#define RT5640_G_BST4_OM_R_MASK (0x7 << 13)
667#define RT5640_G_BST4_OM_R_SFT 13
668#define RT5640_G_BST2_OM_R_MASK (0x7 << 10)
669#define RT5640_G_BST2_OM_R_SFT 10
670#define RT5640_G_BST1_OM_R_MASK (0x7 << 7)
671#define RT5640_G_BST1_OM_R_SFT 7
672#define RT5640_G_IN_R_OM_R_MASK (0x7 << 4)
673#define RT5640_G_IN_R_OM_R_SFT 4
674#define RT5640_G_RM_R_OM_R_MASK (0x7 << 1)
675#define RT5640_G_RM_R_OM_R_SFT 1
676
677/* Output Right Mixer Control 2 (0x51) */
678#define RT5640_G_DAC_L2_OM_R_MASK (0x7 << 13)
679#define RT5640_G_DAC_L2_OM_R_SFT 13
680#define RT5640_G_DAC_R2_OM_R_MASK (0x7 << 10)
681#define RT5640_G_DAC_R2_OM_R_SFT 10
682#define RT5640_G_DAC_R1_OM_R_MASK (0x7 << 7)
683#define RT5640_G_DAC_R1_OM_R_SFT 7
684
685/* Output Right Mixer Control 3 (0x52) */
686#define RT5640_M_SM_L_OM_R (0x1 << 8)
687#define RT5640_M_SM_L_OM_R_SFT 8
688#define RT5640_M_BST4_OM_R (0x1 << 7)
689#define RT5640_M_BST4_OM_R_SFT 7
690#define RT5640_M_BST2_OM_R (0x1 << 6)
691#define RT5640_M_BST2_OM_R_SFT 6
692#define RT5640_M_BST1_OM_R (0x1 << 5)
693#define RT5640_M_BST1_OM_R_SFT 5
694#define RT5640_M_IN_R_OM_R (0x1 << 4)
695#define RT5640_M_IN_R_OM_R_SFT 4
696#define RT5640_M_RM_R_OM_R (0x1 << 3)
697#define RT5640_M_RM_R_OM_R_SFT 3
698#define RT5640_M_DAC_L2_OM_R (0x1 << 2)
699#define RT5640_M_DAC_L2_OM_R_SFT 2
700#define RT5640_M_DAC_R2_OM_R (0x1 << 1)
701#define RT5640_M_DAC_R2_OM_R_SFT 1
702#define RT5640_M_DAC_R1_OM_R (0x1)
703#define RT5640_M_DAC_R1_OM_R_SFT 0
704
705/* LOUT Mixer Control (0x53) */
706#define RT5640_M_DAC_L1_LM (0x1 << 15)
707#define RT5640_M_DAC_L1_LM_SFT 15
708#define RT5640_M_DAC_R1_LM (0x1 << 14)
709#define RT5640_M_DAC_R1_LM_SFT 14
710#define RT5640_M_OV_L_LM (0x1 << 13)
711#define RT5640_M_OV_L_LM_SFT 13
712#define RT5640_M_OV_R_LM (0x1 << 12)
713#define RT5640_M_OV_R_LM_SFT 12
714#define RT5640_G_LOUTMIX_MASK (0x1 << 11)
715#define RT5640_G_LOUTMIX_SFT 11
716
717/* Power Management for Digital 1 (0x61) */
718#define RT5640_PWR_I2S1 (0x1 << 15)
719#define RT5640_PWR_I2S1_BIT 15
720#define RT5640_PWR_I2S2 (0x1 << 14)
721#define RT5640_PWR_I2S2_BIT 14
722#define RT5640_PWR_DAC_L1 (0x1 << 12)
723#define RT5640_PWR_DAC_L1_BIT 12
724#define RT5640_PWR_DAC_R1 (0x1 << 11)
725#define RT5640_PWR_DAC_R1_BIT 11
726#define RT5640_PWR_DAC_L2 (0x1 << 7)
727#define RT5640_PWR_DAC_L2_BIT 7
728#define RT5640_PWR_DAC_R2 (0x1 << 6)
729#define RT5640_PWR_DAC_R2_BIT 6
730#define RT5640_PWR_ADC_L (0x1 << 2)
731#define RT5640_PWR_ADC_L_BIT 2
732#define RT5640_PWR_ADC_R (0x1 << 1)
733#define RT5640_PWR_ADC_R_BIT 1
734#define RT5640_PWR_CLS_D (0x1)
735#define RT5640_PWR_CLS_D_BIT 0
736
737/* Power Management for Digital 2 (0x62) */
738#define RT5640_PWR_ADC_SF (0x1 << 15)
739#define RT5640_PWR_ADC_SF_BIT 15
740#define RT5640_PWR_ADC_MF_L (0x1 << 14)
741#define RT5640_PWR_ADC_MF_L_BIT 14
742#define RT5640_PWR_ADC_MF_R (0x1 << 13)
743#define RT5640_PWR_ADC_MF_R_BIT 13
744#define RT5640_PWR_I2S_DSP (0x1 << 12)
745#define RT5640_PWR_I2S_DSP_BIT 12
746
747/* Power Management for Analog 1 (0x63) */
748#define RT5640_PWR_VREF1 (0x1 << 15)
749#define RT5640_PWR_VREF1_BIT 15
750#define RT5640_PWR_FV1 (0x1 << 14)
751#define RT5640_PWR_FV1_BIT 14
752#define RT5640_PWR_MB (0x1 << 13)
753#define RT5640_PWR_MB_BIT 13
754#define RT5640_PWR_LM (0x1 << 12)
755#define RT5640_PWR_LM_BIT 12
756#define RT5640_PWR_BG (0x1 << 11)
757#define RT5640_PWR_BG_BIT 11
758#define RT5640_PWR_MM (0x1 << 10)
759#define RT5640_PWR_MM_BIT 10
760#define RT5640_PWR_MA (0x1 << 8)
761#define RT5640_PWR_MA_BIT 8
762#define RT5640_PWR_HP_L (0x1 << 7)
763#define RT5640_PWR_HP_L_BIT 7
764#define RT5640_PWR_HP_R (0x1 << 6)
765#define RT5640_PWR_HP_R_BIT 6
766#define RT5640_PWR_HA (0x1 << 5)
767#define RT5640_PWR_HA_BIT 5
768#define RT5640_PWR_VREF2 (0x1 << 4)
769#define RT5640_PWR_VREF2_BIT 4
770#define RT5640_PWR_FV2 (0x1 << 3)
771#define RT5640_PWR_FV2_BIT 3
772#define RT5640_PWR_LDO2 (0x1 << 2)
773#define RT5640_PWR_LDO2_BIT 2
774
775/* Power Management for Analog 2 (0x64) */
776#define RT5640_PWR_BST1 (0x1 << 15)
777#define RT5640_PWR_BST1_BIT 15
778#define RT5640_PWR_BST2 (0x1 << 14)
779#define RT5640_PWR_BST2_BIT 14
780#define RT5640_PWR_BST3 (0x1 << 13)
781#define RT5640_PWR_BST3_BIT 13
782#define RT5640_PWR_BST4 (0x1 << 12)
783#define RT5640_PWR_BST4_BIT 12
784#define RT5640_PWR_MB1 (0x1 << 11)
785#define RT5640_PWR_MB1_BIT 11
786#define RT5640_PWR_PLL (0x1 << 9)
787#define RT5640_PWR_PLL_BIT 9
788
789/* Power Management for Mixer (0x65) */
790#define RT5640_PWR_OM_L (0x1 << 15)
791#define RT5640_PWR_OM_L_BIT 15
792#define RT5640_PWR_OM_R (0x1 << 14)
793#define RT5640_PWR_OM_R_BIT 14
794#define RT5640_PWR_SM_L (0x1 << 13)
795#define RT5640_PWR_SM_L_BIT 13
796#define RT5640_PWR_SM_R (0x1 << 12)
797#define RT5640_PWR_SM_R_BIT 12
798#define RT5640_PWR_RM_L (0x1 << 11)
799#define RT5640_PWR_RM_L_BIT 11
800#define RT5640_PWR_RM_R (0x1 << 10)
801#define RT5640_PWR_RM_R_BIT 10
802
803/* Power Management for Volume (0x66) */
804#define RT5640_PWR_SV_L (0x1 << 15)
805#define RT5640_PWR_SV_L_BIT 15
806#define RT5640_PWR_SV_R (0x1 << 14)
807#define RT5640_PWR_SV_R_BIT 14
808#define RT5640_PWR_OV_L (0x1 << 13)
809#define RT5640_PWR_OV_L_BIT 13
810#define RT5640_PWR_OV_R (0x1 << 12)
811#define RT5640_PWR_OV_R_BIT 12
812#define RT5640_PWR_HV_L (0x1 << 11)
813#define RT5640_PWR_HV_L_BIT 11
814#define RT5640_PWR_HV_R (0x1 << 10)
815#define RT5640_PWR_HV_R_BIT 10
816#define RT5640_PWR_IN_L (0x1 << 9)
817#define RT5640_PWR_IN_L_BIT 9
818#define RT5640_PWR_IN_R (0x1 << 8)
819#define RT5640_PWR_IN_R_BIT 8
820
821/* I2S1/2/3 Audio Serial Data Port Control (0x70 0x71 0x72) */
822#define RT5640_I2S_MS_MASK (0x1 << 15)
823#define RT5640_I2S_MS_SFT 15
824#define RT5640_I2S_MS_M (0x0 << 15)
825#define RT5640_I2S_MS_S (0x1 << 15)
826#define RT5640_I2S_IF_MASK (0x7 << 12)
827#define RT5640_I2S_IF_SFT 12
828#define RT5640_I2S_O_CP_MASK (0x3 << 10)
829#define RT5640_I2S_O_CP_SFT 10
830#define RT5640_I2S_O_CP_OFF (0x0 << 10)
831#define RT5640_I2S_O_CP_U_LAW (0x1 << 10)
832#define RT5640_I2S_O_CP_A_LAW (0x2 << 10)
833#define RT5640_I2S_I_CP_MASK (0x3 << 8)
834#define RT5640_I2S_I_CP_SFT 8
835#define RT5640_I2S_I_CP_OFF (0x0 << 8)
836#define RT5640_I2S_I_CP_U_LAW (0x1 << 8)
837#define RT5640_I2S_I_CP_A_LAW (0x2 << 8)
838#define RT5640_I2S_BP_MASK (0x1 << 7)
839#define RT5640_I2S_BP_SFT 7
840#define RT5640_I2S_BP_NOR (0x0 << 7)
841#define RT5640_I2S_BP_INV (0x1 << 7)
842#define RT5640_I2S_DL_MASK (0x3 << 2)
843#define RT5640_I2S_DL_SFT 2
844#define RT5640_I2S_DL_16 (0x0 << 2)
845#define RT5640_I2S_DL_20 (0x1 << 2)
846#define RT5640_I2S_DL_24 (0x2 << 2)
847#define RT5640_I2S_DL_8 (0x3 << 2)
848#define RT5640_I2S_DF_MASK (0x3)
849#define RT5640_I2S_DF_SFT 0
850#define RT5640_I2S_DF_I2S (0x0)
851#define RT5640_I2S_DF_LEFT (0x1)
852#define RT5640_I2S_DF_PCM_A (0x2)
853#define RT5640_I2S_DF_PCM_B (0x3)
854
855/* I2S2 Audio Serial Data Port Control (0x71) */
856#define RT5640_I2S2_SDI_MASK (0x1 << 6)
857#define RT5640_I2S2_SDI_SFT 6
858#define RT5640_I2S2_SDI_I2S1 (0x0 << 6)
859#define RT5640_I2S2_SDI_I2S2 (0x1 << 6)
860
861/* ADC/DAC Clock Control 1 (0x73) */
862#define RT5640_I2S_BCLK_MS1_MASK (0x1 << 15)
863#define RT5640_I2S_BCLK_MS1_SFT 15
864#define RT5640_I2S_BCLK_MS1_32 (0x0 << 15)
865#define RT5640_I2S_BCLK_MS1_64 (0x1 << 15)
866#define RT5640_I2S_PD1_MASK (0x7 << 12)
867#define RT5640_I2S_PD1_SFT 12
868#define RT5640_I2S_PD1_1 (0x0 << 12)
869#define RT5640_I2S_PD1_2 (0x1 << 12)
870#define RT5640_I2S_PD1_3 (0x2 << 12)
871#define RT5640_I2S_PD1_4 (0x3 << 12)
872#define RT5640_I2S_PD1_6 (0x4 << 12)
873#define RT5640_I2S_PD1_8 (0x5 << 12)
874#define RT5640_I2S_PD1_12 (0x6 << 12)
875#define RT5640_I2S_PD1_16 (0x7 << 12)
876#define RT5640_I2S_BCLK_MS2_MASK (0x1 << 11)
877#define RT5640_I2S_BCLK_MS2_SFT 11
878#define RT5640_I2S_BCLK_MS2_32 (0x0 << 11)
879#define RT5640_I2S_BCLK_MS2_64 (0x1 << 11)
880#define RT5640_I2S_PD2_MASK (0x7 << 8)
881#define RT5640_I2S_PD2_SFT 8
882#define RT5640_I2S_PD2_1 (0x0 << 8)
883#define RT5640_I2S_PD2_2 (0x1 << 8)
884#define RT5640_I2S_PD2_3 (0x2 << 8)
885#define RT5640_I2S_PD2_4 (0x3 << 8)
886#define RT5640_I2S_PD2_6 (0x4 << 8)
887#define RT5640_I2S_PD2_8 (0x5 << 8)
888#define RT5640_I2S_PD2_12 (0x6 << 8)
889#define RT5640_I2S_PD2_16 (0x7 << 8)
890#define RT5640_I2S_BCLK_MS3_MASK (0x1 << 7)
891#define RT5640_I2S_BCLK_MS3_SFT 7
892#define RT5640_I2S_BCLK_MS3_32 (0x0 << 7)
893#define RT5640_I2S_BCLK_MS3_64 (0x1 << 7)
894#define RT5640_I2S_PD3_MASK (0x7 << 4)
895#define RT5640_I2S_PD3_SFT 4
896#define RT5640_I2S_PD3_1 (0x0 << 4)
897#define RT5640_I2S_PD3_2 (0x1 << 4)
898#define RT5640_I2S_PD3_3 (0x2 << 4)
899#define RT5640_I2S_PD3_4 (0x3 << 4)
900#define RT5640_I2S_PD3_6 (0x4 << 4)
901#define RT5640_I2S_PD3_8 (0x5 << 4)
902#define RT5640_I2S_PD3_12 (0x6 << 4)
903#define RT5640_I2S_PD3_16 (0x7 << 4)
904#define RT5640_DAC_OSR_MASK (0x3 << 2)
905#define RT5640_DAC_OSR_SFT 2
906#define RT5640_DAC_OSR_128 (0x0 << 2)
907#define RT5640_DAC_OSR_64 (0x1 << 2)
908#define RT5640_DAC_OSR_32 (0x2 << 2)
909#define RT5640_DAC_OSR_16 (0x3 << 2)
910#define RT5640_ADC_OSR_MASK (0x3)
911#define RT5640_ADC_OSR_SFT 0
912#define RT5640_ADC_OSR_128 (0x0)
913#define RT5640_ADC_OSR_64 (0x1)
914#define RT5640_ADC_OSR_32 (0x2)
915#define RT5640_ADC_OSR_16 (0x3)
916
917/* ADC/DAC Clock Control 2 (0x74) */
918#define RT5640_DAC_L_OSR_MASK (0x3 << 14)
919#define RT5640_DAC_L_OSR_SFT 14
920#define RT5640_DAC_L_OSR_128 (0x0 << 14)
921#define RT5640_DAC_L_OSR_64 (0x1 << 14)
922#define RT5640_DAC_L_OSR_32 (0x2 << 14)
923#define RT5640_DAC_L_OSR_16 (0x3 << 14)
924#define RT5640_ADC_R_OSR_MASK (0x3 << 12)
925#define RT5640_ADC_R_OSR_SFT 12
926#define RT5640_ADC_R_OSR_128 (0x0 << 12)
927#define RT5640_ADC_R_OSR_64 (0x1 << 12)
928#define RT5640_ADC_R_OSR_32 (0x2 << 12)
929#define RT5640_ADC_R_OSR_16 (0x3 << 12)
930#define RT5640_DAHPF_EN (0x1 << 11)
931#define RT5640_DAHPF_EN_SFT 11
932#define RT5640_ADHPF_EN (0x1 << 10)
933#define RT5640_ADHPF_EN_SFT 10
934
935/* Digital Microphone Control (0x75) */
936#define RT5640_DMIC_1_EN_MASK (0x1 << 15)
937#define RT5640_DMIC_1_EN_SFT 15
938#define RT5640_DMIC_1_DIS (0x0 << 15)
939#define RT5640_DMIC_1_EN (0x1 << 15)
940#define RT5640_DMIC_2_EN_MASK (0x1 << 14)
941#define RT5640_DMIC_2_EN_SFT 14
942#define RT5640_DMIC_2_DIS (0x0 << 14)
943#define RT5640_DMIC_2_EN (0x1 << 14)
944#define RT5640_DMIC_1L_LH_MASK (0x1 << 13)
945#define RT5640_DMIC_1L_LH_SFT 13
946#define RT5640_DMIC_1L_LH_FALLING (0x0 << 13)
947#define RT5640_DMIC_1L_LH_RISING (0x1 << 13)
948#define RT5640_DMIC_1R_LH_MASK (0x1 << 12)
949#define RT5640_DMIC_1R_LH_SFT 12
950#define RT5640_DMIC_1R_LH_FALLING (0x0 << 12)
951#define RT5640_DMIC_1R_LH_RISING (0x1 << 12)
952#define RT5640_DMIC_1_DP_MASK (0x1 << 11)
953#define RT5640_DMIC_1_DP_SFT 11
954#define RT5640_DMIC_1_DP_GPIO3 (0x0 << 11)
955#define RT5640_DMIC_1_DP_IN1P (0x1 << 11)
956#define RT5640_DMIC_2_DP_MASK (0x1 << 10)
957#define RT5640_DMIC_2_DP_SFT 10
958#define RT5640_DMIC_2_DP_GPIO4 (0x0 << 10)
959#define RT5640_DMIC_2_DP_IN1N (0x1 << 10)
960#define RT5640_DMIC_2L_LH_MASK (0x1 << 9)
961#define RT5640_DMIC_2L_LH_SFT 9
962#define RT5640_DMIC_2L_LH_FALLING (0x0 << 9)
963#define RT5640_DMIC_2L_LH_RISING (0x1 << 9)
964#define RT5640_DMIC_2R_LH_MASK (0x1 << 8)
965#define RT5640_DMIC_2R_LH_SFT 8
966#define RT5640_DMIC_2R_LH_FALLING (0x0 << 8)
967#define RT5640_DMIC_2R_LH_RISING (0x1 << 8)
968#define RT5640_DMIC_CLK_MASK (0x7 << 5)
969#define RT5640_DMIC_CLK_SFT 5
970
971/* Global Clock Control (0x80) */
972#define RT5640_SCLK_SRC_MASK (0x3 << 14)
973#define RT5640_SCLK_SRC_SFT 14
974#define RT5640_SCLK_SRC_MCLK (0x0 << 14)
975#define RT5640_SCLK_SRC_PLL1 (0x1 << 14)
976#define RT5640_SCLK_SRC_PLL1T (0x2 << 14)
977#define RT5640_SCLK_SRC_RCCLK (0x3 << 14) /* 15MHz */
978#define RT5640_PLL1_SRC_MASK (0x3 << 12)
979#define RT5640_PLL1_SRC_SFT 12
980#define RT5640_PLL1_SRC_MCLK (0x0 << 12)
981#define RT5640_PLL1_SRC_BCLK1 (0x1 << 12)
982#define RT5640_PLL1_SRC_BCLK2 (0x2 << 12)
983#define RT5640_PLL1_SRC_BCLK3 (0x3 << 12)
984#define RT5640_PLL1_PD_MASK (0x1 << 3)
985#define RT5640_PLL1_PD_SFT 3
986#define RT5640_PLL1_PD_1 (0x0 << 3)
987#define RT5640_PLL1_PD_2 (0x1 << 3)
988
989#define RT5640_PLL_INP_MAX 40000000
990#define RT5640_PLL_INP_MIN 256000
991/* PLL M/N/K Code Control 1 (0x81) */
992#define RT5640_PLL_N_MAX 0x1ff
993#define RT5640_PLL_N_MASK (RT5640_PLL_N_MAX << 7)
994#define RT5640_PLL_N_SFT 7
995#define RT5640_PLL_K_MAX 0x1f
996#define RT5640_PLL_K_MASK (RT5640_PLL_K_MAX)
997#define RT5640_PLL_K_SFT 0
998
999/* PLL M/N/K Code Control 2 (0x82) */
1000#define RT5640_PLL_M_MAX 0xf
1001#define RT5640_PLL_M_MASK (RT5640_PLL_M_MAX << 12)
1002#define RT5640_PLL_M_SFT 12
1003#define RT5640_PLL_M_BP (0x1 << 11)
1004#define RT5640_PLL_M_BP_SFT 11
1005
1006/* ASRC Control 1 (0x83) */
1007#define RT5640_STO_T_MASK (0x1 << 15)
1008#define RT5640_STO_T_SFT 15
1009#define RT5640_STO_T_SCLK (0x0 << 15)
1010#define RT5640_STO_T_LRCK1 (0x1 << 15)
1011#define RT5640_M1_T_MASK (0x1 << 14)
1012#define RT5640_M1_T_SFT 14
1013#define RT5640_M1_T_I2S2 (0x0 << 14)
1014#define RT5640_M1_T_I2S2_D3 (0x1 << 14)
1015#define RT5640_I2S2_F_MASK (0x1 << 12)
1016#define RT5640_I2S2_F_SFT 12
1017#define RT5640_I2S2_F_I2S2_D2 (0x0 << 12)
1018#define RT5640_I2S2_F_I2S1_TCLK (0x1 << 12)
1019#define RT5640_DMIC_1_M_MASK (0x1 << 9)
1020#define RT5640_DMIC_1_M_SFT 9
1021#define RT5640_DMIC_1_M_NOR (0x0 << 9)
1022#define RT5640_DMIC_1_M_ASYN (0x1 << 9)
1023#define RT5640_DMIC_2_M_MASK (0x1 << 8)
1024#define RT5640_DMIC_2_M_SFT 8
1025#define RT5640_DMIC_2_M_NOR (0x0 << 8)
1026#define RT5640_DMIC_2_M_ASYN (0x1 << 8)
1027
1028/* ASRC Control 2 (0x84) */
1029#define RT5640_MDA_L_M_MASK (0x1 << 15)
1030#define RT5640_MDA_L_M_SFT 15
1031#define RT5640_MDA_L_M_NOR (0x0 << 15)
1032#define RT5640_MDA_L_M_ASYN (0x1 << 15)
1033#define RT5640_MDA_R_M_MASK (0x1 << 14)
1034#define RT5640_MDA_R_M_SFT 14
1035#define RT5640_MDA_R_M_NOR (0x0 << 14)
1036#define RT5640_MDA_R_M_ASYN (0x1 << 14)
1037#define RT5640_MAD_L_M_MASK (0x1 << 13)
1038#define RT5640_MAD_L_M_SFT 13
1039#define RT5640_MAD_L_M_NOR (0x0 << 13)
1040#define RT5640_MAD_L_M_ASYN (0x1 << 13)
1041#define RT5640_MAD_R_M_MASK (0x1 << 12)
1042#define RT5640_MAD_R_M_SFT 12
1043#define RT5640_MAD_R_M_NOR (0x0 << 12)
1044#define RT5640_MAD_R_M_ASYN (0x1 << 12)
1045#define RT5640_ADC_M_MASK (0x1 << 11)
1046#define RT5640_ADC_M_SFT 11
1047#define RT5640_ADC_M_NOR (0x0 << 11)
1048#define RT5640_ADC_M_ASYN (0x1 << 11)
1049#define RT5640_STO_DAC_M_MASK (0x1 << 5)
1050#define RT5640_STO_DAC_M_SFT 5
1051#define RT5640_STO_DAC_M_NOR (0x0 << 5)
1052#define RT5640_STO_DAC_M_ASYN (0x1 << 5)
1053#define RT5640_I2S1_R_D_MASK (0x1 << 4)
1054#define RT5640_I2S1_R_D_SFT 4
1055#define RT5640_I2S1_R_D_DIS (0x0 << 4)
1056#define RT5640_I2S1_R_D_EN (0x1 << 4)
1057#define RT5640_I2S2_R_D_MASK (0x1 << 3)
1058#define RT5640_I2S2_R_D_SFT 3
1059#define RT5640_I2S2_R_D_DIS (0x0 << 3)
1060#define RT5640_I2S2_R_D_EN (0x1 << 3)
1061#define RT5640_PRE_SCLK_MASK (0x3)
1062#define RT5640_PRE_SCLK_SFT 0
1063#define RT5640_PRE_SCLK_512 (0x0)
1064#define RT5640_PRE_SCLK_1024 (0x1)
1065#define RT5640_PRE_SCLK_2048 (0x2)
1066
1067/* ASRC Control 3 (0x85) */
1068#define RT5640_I2S1_RATE_MASK (0xf << 12)
1069#define RT5640_I2S1_RATE_SFT 12
1070#define RT5640_I2S2_RATE_MASK (0xf << 8)
1071#define RT5640_I2S2_RATE_SFT 8
1072
1073/* ASRC Control 4 (0x89) */
1074#define RT5640_I2S1_PD_MASK (0x7 << 12)
1075#define RT5640_I2S1_PD_SFT 12
1076#define RT5640_I2S2_PD_MASK (0x7 << 8)
1077#define RT5640_I2S2_PD_SFT 8
1078
1079/* HPOUT Over Current Detection (0x8b) */
1080#define RT5640_HP_OVCD_MASK (0x1 << 10)
1081#define RT5640_HP_OVCD_SFT 10
1082#define RT5640_HP_OVCD_DIS (0x0 << 10)
1083#define RT5640_HP_OVCD_EN (0x1 << 10)
1084#define RT5640_HP_OC_TH_MASK (0x3 << 8)
1085#define RT5640_HP_OC_TH_SFT 8
1086#define RT5640_HP_OC_TH_90 (0x0 << 8)
1087#define RT5640_HP_OC_TH_105 (0x1 << 8)
1088#define RT5640_HP_OC_TH_120 (0x2 << 8)
1089#define RT5640_HP_OC_TH_135 (0x3 << 8)
1090
1091/* Class D Over Current Control (0x8c) */
1092#define RT5640_CLSD_OC_MASK (0x1 << 9)
1093#define RT5640_CLSD_OC_SFT 9
1094#define RT5640_CLSD_OC_PU (0x0 << 9)
1095#define RT5640_CLSD_OC_PD (0x1 << 9)
1096#define RT5640_AUTO_PD_MASK (0x1 << 8)
1097#define RT5640_AUTO_PD_SFT 8
1098#define RT5640_AUTO_PD_DIS (0x0 << 8)
1099#define RT5640_AUTO_PD_EN (0x1 << 8)
1100#define RT5640_CLSD_OC_TH_MASK (0x3f)
1101#define RT5640_CLSD_OC_TH_SFT 0
1102
1103/* Class D Output Control (0x8d) */
1104#define RT5640_CLSD_RATIO_MASK (0xf << 12)
1105#define RT5640_CLSD_RATIO_SFT 12
1106#define RT5640_CLSD_OM_MASK (0x1 << 11)
1107#define RT5640_CLSD_OM_SFT 11
1108#define RT5640_CLSD_OM_MONO (0x0 << 11)
1109#define RT5640_CLSD_OM_STO (0x1 << 11)
1110#define RT5640_CLSD_SCH_MASK (0x1 << 10)
1111#define RT5640_CLSD_SCH_SFT 10
1112#define RT5640_CLSD_SCH_L (0x0 << 10)
1113#define RT5640_CLSD_SCH_S (0x1 << 10)
1114
1115/* Depop Mode Control 1 (0x8e) */
1116#define RT5640_SMT_TRIG_MASK (0x1 << 15)
1117#define RT5640_SMT_TRIG_SFT 15
1118#define RT5640_SMT_TRIG_DIS (0x0 << 15)
1119#define RT5640_SMT_TRIG_EN (0x1 << 15)
1120#define RT5640_HP_L_SMT_MASK (0x1 << 9)
1121#define RT5640_HP_L_SMT_SFT 9
1122#define RT5640_HP_L_SMT_DIS (0x0 << 9)
1123#define RT5640_HP_L_SMT_EN (0x1 << 9)
1124#define RT5640_HP_R_SMT_MASK (0x1 << 8)
1125#define RT5640_HP_R_SMT_SFT 8
1126#define RT5640_HP_R_SMT_DIS (0x0 << 8)
1127#define RT5640_HP_R_SMT_EN (0x1 << 8)
1128#define RT5640_HP_CD_PD_MASK (0x1 << 7)
1129#define RT5640_HP_CD_PD_SFT 7
1130#define RT5640_HP_CD_PD_DIS (0x0 << 7)
1131#define RT5640_HP_CD_PD_EN (0x1 << 7)
1132#define RT5640_RSTN_MASK (0x1 << 6)
1133#define RT5640_RSTN_SFT 6
1134#define RT5640_RSTN_DIS (0x0 << 6)
1135#define RT5640_RSTN_EN (0x1 << 6)
1136#define RT5640_RSTP_MASK (0x1 << 5)
1137#define RT5640_RSTP_SFT 5
1138#define RT5640_RSTP_DIS (0x0 << 5)
1139#define RT5640_RSTP_EN (0x1 << 5)
1140#define RT5640_HP_CO_MASK (0x1 << 4)
1141#define RT5640_HP_CO_SFT 4
1142#define RT5640_HP_CO_DIS (0x0 << 4)
1143#define RT5640_HP_CO_EN (0x1 << 4)
1144#define RT5640_HP_CP_MASK (0x1 << 3)
1145#define RT5640_HP_CP_SFT 3
1146#define RT5640_HP_CP_PD (0x0 << 3)
1147#define RT5640_HP_CP_PU (0x1 << 3)
1148#define RT5640_HP_SG_MASK (0x1 << 2)
1149#define RT5640_HP_SG_SFT 2
1150#define RT5640_HP_SG_DIS (0x0 << 2)
1151#define RT5640_HP_SG_EN (0x1 << 2)
1152#define RT5640_HP_DP_MASK (0x1 << 1)
1153#define RT5640_HP_DP_SFT 1
1154#define RT5640_HP_DP_PD (0x0 << 1)
1155#define RT5640_HP_DP_PU (0x1 << 1)
1156#define RT5640_HP_CB_MASK (0x1)
1157#define RT5640_HP_CB_SFT 0
1158#define RT5640_HP_CB_PD (0x0)
1159#define RT5640_HP_CB_PU (0x1)
1160
1161/* Depop Mode Control 2 (0x8f) */
1162#define RT5640_DEPOP_MASK (0x1 << 13)
1163#define RT5640_DEPOP_SFT 13
1164#define RT5640_DEPOP_AUTO (0x0 << 13)
1165#define RT5640_DEPOP_MAN (0x1 << 13)
1166#define RT5640_RAMP_MASK (0x1 << 12)
1167#define RT5640_RAMP_SFT 12
1168#define RT5640_RAMP_DIS (0x0 << 12)
1169#define RT5640_RAMP_EN (0x1 << 12)
1170#define RT5640_BPS_MASK (0x1 << 11)
1171#define RT5640_BPS_SFT 11
1172#define RT5640_BPS_DIS (0x0 << 11)
1173#define RT5640_BPS_EN (0x1 << 11)
1174#define RT5640_FAST_UPDN_MASK (0x1 << 10)
1175#define RT5640_FAST_UPDN_SFT 10
1176#define RT5640_FAST_UPDN_DIS (0x0 << 10)
1177#define RT5640_FAST_UPDN_EN (0x1 << 10)
1178#define RT5640_MRES_MASK (0x3 << 8)
1179#define RT5640_MRES_SFT 8
1180#define RT5640_MRES_15MO (0x0 << 8)
1181#define RT5640_MRES_25MO (0x1 << 8)
1182#define RT5640_MRES_35MO (0x2 << 8)
1183#define RT5640_MRES_45MO (0x3 << 8)
1184#define RT5640_VLO_MASK (0x1 << 7)
1185#define RT5640_VLO_SFT 7
1186#define RT5640_VLO_3V (0x0 << 7)
1187#define RT5640_VLO_32V (0x1 << 7)
1188#define RT5640_DIG_DP_MASK (0x1 << 6)
1189#define RT5640_DIG_DP_SFT 6
1190#define RT5640_DIG_DP_DIS (0x0 << 6)
1191#define RT5640_DIG_DP_EN (0x1 << 6)
1192#define RT5640_DP_TH_MASK (0x3 << 4)
1193#define RT5640_DP_TH_SFT 4
1194
1195/* Depop Mode Control 3 (0x90) */
1196#define RT5640_CP_SYS_MASK (0x7 << 12)
1197#define RT5640_CP_SYS_SFT 12
1198#define RT5640_CP_FQ1_MASK (0x7 << 8)
1199#define RT5640_CP_FQ1_SFT 8
1200#define RT5640_CP_FQ2_MASK (0x7 << 4)
1201#define RT5640_CP_FQ2_SFT 4
1202#define RT5640_CP_FQ3_MASK (0x7)
1203#define RT5640_CP_FQ3_SFT 0
1204
1205/* HPOUT charge pump (0x91) */
1206#define RT5640_OSW_L_MASK (0x1 << 11)
1207#define RT5640_OSW_L_SFT 11
1208#define RT5640_OSW_L_DIS (0x0 << 11)
1209#define RT5640_OSW_L_EN (0x1 << 11)
1210#define RT5640_OSW_R_MASK (0x1 << 10)
1211#define RT5640_OSW_R_SFT 10
1212#define RT5640_OSW_R_DIS (0x0 << 10)
1213#define RT5640_OSW_R_EN (0x1 << 10)
1214#define RT5640_PM_HP_MASK (0x3 << 8)
1215#define RT5640_PM_HP_SFT 8
1216#define RT5640_PM_HP_LV (0x0 << 8)
1217#define RT5640_PM_HP_MV (0x1 << 8)
1218#define RT5640_PM_HP_HV (0x2 << 8)
1219#define RT5640_IB_HP_MASK (0x3 << 6)
1220#define RT5640_IB_HP_SFT 6
1221#define RT5640_IB_HP_125IL (0x0 << 6)
1222#define RT5640_IB_HP_25IL (0x1 << 6)
1223#define RT5640_IB_HP_5IL (0x2 << 6)
1224#define RT5640_IB_HP_1IL (0x3 << 6)
1225
1226/* PV detection and SPK gain control (0x92) */
1227#define RT5640_PVDD_DET_MASK (0x1 << 15)
1228#define RT5640_PVDD_DET_SFT 15
1229#define RT5640_PVDD_DET_DIS (0x0 << 15)
1230#define RT5640_PVDD_DET_EN (0x1 << 15)
1231#define RT5640_SPK_AG_MASK (0x1 << 14)
1232#define RT5640_SPK_AG_SFT 14
1233#define RT5640_SPK_AG_DIS (0x0 << 14)
1234#define RT5640_SPK_AG_EN (0x1 << 14)
1235
1236/* Micbias Control (0x93) */
1237#define RT5640_MIC1_BS_MASK (0x1 << 15)
1238#define RT5640_MIC1_BS_SFT 15
1239#define RT5640_MIC1_BS_9AV (0x0 << 15)
1240#define RT5640_MIC1_BS_75AV (0x1 << 15)
1241#define RT5640_MIC2_BS_MASK (0x1 << 14)
1242#define RT5640_MIC2_BS_SFT 14
1243#define RT5640_MIC2_BS_9AV (0x0 << 14)
1244#define RT5640_MIC2_BS_75AV (0x1 << 14)
1245#define RT5640_MIC1_CLK_MASK (0x1 << 13)
1246#define RT5640_MIC1_CLK_SFT 13
1247#define RT5640_MIC1_CLK_DIS (0x0 << 13)
1248#define RT5640_MIC1_CLK_EN (0x1 << 13)
1249#define RT5640_MIC2_CLK_MASK (0x1 << 12)
1250#define RT5640_MIC2_CLK_SFT 12
1251#define RT5640_MIC2_CLK_DIS (0x0 << 12)
1252#define RT5640_MIC2_CLK_EN (0x1 << 12)
1253#define RT5640_MIC1_OVCD_MASK (0x1 << 11)
1254#define RT5640_MIC1_OVCD_SFT 11
1255#define RT5640_MIC1_OVCD_DIS (0x0 << 11)
1256#define RT5640_MIC1_OVCD_EN (0x1 << 11)
1257#define RT5640_MIC1_OVTH_MASK (0x3 << 9)
1258#define RT5640_MIC1_OVTH_SFT 9
1259#define RT5640_MIC1_OVTH_600UA (0x0 << 9)
1260#define RT5640_MIC1_OVTH_1500UA (0x1 << 9)
1261#define RT5640_MIC1_OVTH_2000UA (0x2 << 9)
1262#define RT5640_MIC2_OVCD_MASK (0x1 << 8)
1263#define RT5640_MIC2_OVCD_SFT 8
1264#define RT5640_MIC2_OVCD_DIS (0x0 << 8)
1265#define RT5640_MIC2_OVCD_EN (0x1 << 8)
1266#define RT5640_MIC2_OVTH_MASK (0x3 << 6)
1267#define RT5640_MIC2_OVTH_SFT 6
1268#define RT5640_MIC2_OVTH_600UA (0x0 << 6)
1269#define RT5640_MIC2_OVTH_1500UA (0x1 << 6)
1270#define RT5640_MIC2_OVTH_2000UA (0x2 << 6)
1271#define RT5640_PWR_MB_MASK (0x1 << 5)
1272#define RT5640_PWR_MB_SFT 5
1273#define RT5640_PWR_MB_PD (0x0 << 5)
1274#define RT5640_PWR_MB_PU (0x1 << 5)
1275#define RT5640_PWR_CLK25M_MASK (0x1 << 4)
1276#define RT5640_PWR_CLK25M_SFT 4
1277#define RT5640_PWR_CLK25M_PD (0x0 << 4)
1278#define RT5640_PWR_CLK25M_PU (0x1 << 4)
1279
1280/* EQ Control 1 (0xb0) */
1281#define RT5640_EQ_SRC_MASK (0x1 << 15)
1282#define RT5640_EQ_SRC_SFT 15
1283#define RT5640_EQ_SRC_DAC (0x0 << 15)
1284#define RT5640_EQ_SRC_ADC (0x1 << 15)
1285#define RT5640_EQ_UPD (0x1 << 14)
1286#define RT5640_EQ_UPD_BIT 14
1287#define RT5640_EQ_CD_MASK (0x1 << 13)
1288#define RT5640_EQ_CD_SFT 13
1289#define RT5640_EQ_CD_DIS (0x0 << 13)
1290#define RT5640_EQ_CD_EN (0x1 << 13)
1291#define RT5640_EQ_DITH_MASK (0x3 << 8)
1292#define RT5640_EQ_DITH_SFT 8
1293#define RT5640_EQ_DITH_NOR (0x0 << 8)
1294#define RT5640_EQ_DITH_LSB (0x1 << 8)
1295#define RT5640_EQ_DITH_LSB_1 (0x2 << 8)
1296#define RT5640_EQ_DITH_LSB_2 (0x3 << 8)
1297
1298/* EQ Control 2 (0xb1) */
1299#define RT5640_EQ_HPF1_M_MASK (0x1 << 8)
1300#define RT5640_EQ_HPF1_M_SFT 8
1301#define RT5640_EQ_HPF1_M_HI (0x0 << 8)
1302#define RT5640_EQ_HPF1_M_1ST (0x1 << 8)
1303#define RT5640_EQ_LPF1_M_MASK (0x1 << 7)
1304#define RT5640_EQ_LPF1_M_SFT 7
1305#define RT5640_EQ_LPF1_M_LO (0x0 << 7)
1306#define RT5640_EQ_LPF1_M_1ST (0x1 << 7)
1307#define RT5640_EQ_HPF2_MASK (0x1 << 6)
1308#define RT5640_EQ_HPF2_SFT 6
1309#define RT5640_EQ_HPF2_DIS (0x0 << 6)
1310#define RT5640_EQ_HPF2_EN (0x1 << 6)
1311#define RT5640_EQ_HPF1_MASK (0x1 << 5)
1312#define RT5640_EQ_HPF1_SFT 5
1313#define RT5640_EQ_HPF1_DIS (0x0 << 5)
1314#define RT5640_EQ_HPF1_EN (0x1 << 5)
1315#define RT5640_EQ_BPF4_MASK (0x1 << 4)
1316#define RT5640_EQ_BPF4_SFT 4
1317#define RT5640_EQ_BPF4_DIS (0x0 << 4)
1318#define RT5640_EQ_BPF4_EN (0x1 << 4)
1319#define RT5640_EQ_BPF3_MASK (0x1 << 3)
1320#define RT5640_EQ_BPF3_SFT 3
1321#define RT5640_EQ_BPF3_DIS (0x0 << 3)
1322#define RT5640_EQ_BPF3_EN (0x1 << 3)
1323#define RT5640_EQ_BPF2_MASK (0x1 << 2)
1324#define RT5640_EQ_BPF2_SFT 2
1325#define RT5640_EQ_BPF2_DIS (0x0 << 2)
1326#define RT5640_EQ_BPF2_EN (0x1 << 2)
1327#define RT5640_EQ_BPF1_MASK (0x1 << 1)
1328#define RT5640_EQ_BPF1_SFT 1
1329#define RT5640_EQ_BPF1_DIS (0x0 << 1)
1330#define RT5640_EQ_BPF1_EN (0x1 << 1)
1331#define RT5640_EQ_LPF_MASK (0x1)
1332#define RT5640_EQ_LPF_SFT 0
1333#define RT5640_EQ_LPF_DIS (0x0)
1334#define RT5640_EQ_LPF_EN (0x1)
1335
1336/* Memory Test (0xb2) */
1337#define RT5640_MT_MASK (0x1 << 15)
1338#define RT5640_MT_SFT 15
1339#define RT5640_MT_DIS (0x0 << 15)
1340#define RT5640_MT_EN (0x1 << 15)
1341
1342/* DRC/AGC Control 1 (0xb4) */
1343#define RT5640_DRC_AGC_P_MASK (0x1 << 15)
1344#define RT5640_DRC_AGC_P_SFT 15
1345#define RT5640_DRC_AGC_P_DAC (0x0 << 15)
1346#define RT5640_DRC_AGC_P_ADC (0x1 << 15)
1347#define RT5640_DRC_AGC_MASK (0x1 << 14)
1348#define RT5640_DRC_AGC_SFT 14
1349#define RT5640_DRC_AGC_DIS (0x0 << 14)
1350#define RT5640_DRC_AGC_EN (0x1 << 14)
1351#define RT5640_DRC_AGC_UPD (0x1 << 13)
1352#define RT5640_DRC_AGC_UPD_BIT 13
1353#define RT5640_DRC_AGC_AR_MASK (0x1f << 8)
1354#define RT5640_DRC_AGC_AR_SFT 8
1355#define RT5640_DRC_AGC_R_MASK (0x7 << 5)
1356#define RT5640_DRC_AGC_R_SFT 5
1357#define RT5640_DRC_AGC_R_48K (0x1 << 5)
1358#define RT5640_DRC_AGC_R_96K (0x2 << 5)
1359#define RT5640_DRC_AGC_R_192K (0x3 << 5)
1360#define RT5640_DRC_AGC_R_441K (0x5 << 5)
1361#define RT5640_DRC_AGC_R_882K (0x6 << 5)
1362#define RT5640_DRC_AGC_R_1764K (0x7 << 5)
1363#define RT5640_DRC_AGC_RC_MASK (0x1f)
1364#define RT5640_DRC_AGC_RC_SFT 0
1365
1366/* DRC/AGC Control 2 (0xb5) */
1367#define RT5640_DRC_AGC_POB_MASK (0x3f << 8)
1368#define RT5640_DRC_AGC_POB_SFT 8
1369#define RT5640_DRC_AGC_CP_MASK (0x1 << 7)
1370#define RT5640_DRC_AGC_CP_SFT 7
1371#define RT5640_DRC_AGC_CP_DIS (0x0 << 7)
1372#define RT5640_DRC_AGC_CP_EN (0x1 << 7)
1373#define RT5640_DRC_AGC_CPR_MASK (0x3 << 5)
1374#define RT5640_DRC_AGC_CPR_SFT 5
1375#define RT5640_DRC_AGC_CPR_1_1 (0x0 << 5)
1376#define RT5640_DRC_AGC_CPR_1_2 (0x1 << 5)
1377#define RT5640_DRC_AGC_CPR_1_3 (0x2 << 5)
1378#define RT5640_DRC_AGC_CPR_1_4 (0x3 << 5)
1379#define RT5640_DRC_AGC_PRB_MASK (0x1f)
1380#define RT5640_DRC_AGC_PRB_SFT 0
1381
1382/* DRC/AGC Control 3 (0xb6) */
1383#define RT5640_DRC_AGC_NGB_MASK (0xf << 12)
1384#define RT5640_DRC_AGC_NGB_SFT 12
1385#define RT5640_DRC_AGC_TAR_MASK (0x1f << 7)
1386#define RT5640_DRC_AGC_TAR_SFT 7
1387#define RT5640_DRC_AGC_NG_MASK (0x1 << 6)
1388#define RT5640_DRC_AGC_NG_SFT 6
1389#define RT5640_DRC_AGC_NG_DIS (0x0 << 6)
1390#define RT5640_DRC_AGC_NG_EN (0x1 << 6)
1391#define RT5640_DRC_AGC_NGH_MASK (0x1 << 5)
1392#define RT5640_DRC_AGC_NGH_SFT 5
1393#define RT5640_DRC_AGC_NGH_DIS (0x0 << 5)
1394#define RT5640_DRC_AGC_NGH_EN (0x1 << 5)
1395#define RT5640_DRC_AGC_NGT_MASK (0x1f)
1396#define RT5640_DRC_AGC_NGT_SFT 0
1397
1398/* ANC Control 1 (0xb8) */
1399#define RT5640_ANC_M_MASK (0x1 << 15)
1400#define RT5640_ANC_M_SFT 15
1401#define RT5640_ANC_M_NOR (0x0 << 15)
1402#define RT5640_ANC_M_REV (0x1 << 15)
1403#define RT5640_ANC_MASK (0x1 << 14)
1404#define RT5640_ANC_SFT 14
1405#define RT5640_ANC_DIS (0x0 << 14)
1406#define RT5640_ANC_EN (0x1 << 14)
1407#define RT5640_ANC_MD_MASK (0x3 << 12)
1408#define RT5640_ANC_MD_SFT 12
1409#define RT5640_ANC_MD_DIS (0x0 << 12)
1410#define RT5640_ANC_MD_67MS (0x1 << 12)
1411#define RT5640_ANC_MD_267MS (0x2 << 12)
1412#define RT5640_ANC_MD_1067MS (0x3 << 12)
1413#define RT5640_ANC_SN_MASK (0x1 << 11)
1414#define RT5640_ANC_SN_SFT 11
1415#define RT5640_ANC_SN_DIS (0x0 << 11)
1416#define RT5640_ANC_SN_EN (0x1 << 11)
1417#define RT5640_ANC_CLK_MASK (0x1 << 10)
1418#define RT5640_ANC_CLK_SFT 10
1419#define RT5640_ANC_CLK_ANC (0x0 << 10)
1420#define RT5640_ANC_CLK_REG (0x1 << 10)
1421#define RT5640_ANC_ZCD_MASK (0x3 << 8)
1422#define RT5640_ANC_ZCD_SFT 8
1423#define RT5640_ANC_ZCD_DIS (0x0 << 8)
1424#define RT5640_ANC_ZCD_T1 (0x1 << 8)
1425#define RT5640_ANC_ZCD_T2 (0x2 << 8)
1426#define RT5640_ANC_ZCD_WT (0x3 << 8)
1427#define RT5640_ANC_CS_MASK (0x1 << 7)
1428#define RT5640_ANC_CS_SFT 7
1429#define RT5640_ANC_CS_DIS (0x0 << 7)
1430#define RT5640_ANC_CS_EN (0x1 << 7)
1431#define RT5640_ANC_SW_MASK (0x1 << 6)
1432#define RT5640_ANC_SW_SFT 6
1433#define RT5640_ANC_SW_NOR (0x0 << 6)
1434#define RT5640_ANC_SW_AUTO (0x1 << 6)
1435#define RT5640_ANC_CO_L_MASK (0x3f)
1436#define RT5640_ANC_CO_L_SFT 0
1437
1438/* ANC Control 2 (0xb6) */
1439#define RT5640_ANC_FG_R_MASK (0xf << 12)
1440#define RT5640_ANC_FG_R_SFT 12
1441#define RT5640_ANC_FG_L_MASK (0xf << 8)
1442#define RT5640_ANC_FG_L_SFT 8
1443#define RT5640_ANC_CG_R_MASK (0xf << 4)
1444#define RT5640_ANC_CG_R_SFT 4
1445#define RT5640_ANC_CG_L_MASK (0xf)
1446#define RT5640_ANC_CG_L_SFT 0
1447
1448/* ANC Control 3 (0xb6) */
1449#define RT5640_ANC_CD_MASK (0x1 << 6)
1450#define RT5640_ANC_CD_SFT 6
1451#define RT5640_ANC_CD_BOTH (0x0 << 6)
1452#define RT5640_ANC_CD_IND (0x1 << 6)
1453#define RT5640_ANC_CO_R_MASK (0x3f)
1454#define RT5640_ANC_CO_R_SFT 0
1455
1456/* Jack Detect Control (0xbb) */
1457#define RT5640_JD_MASK (0x7 << 13)
1458#define RT5640_JD_SFT 13
1459#define RT5640_JD_DIS (0x0 << 13)
1460#define RT5640_JD_GPIO1 (0x1 << 13)
1461#define RT5640_JD_JD1_IN4P (0x2 << 13)
1462#define RT5640_JD_JD2_IN4N (0x3 << 13)
1463#define RT5640_JD_GPIO2 (0x4 << 13)
1464#define RT5640_JD_GPIO3 (0x5 << 13)
1465#define RT5640_JD_GPIO4 (0x6 << 13)
1466#define RT5640_JD_HP_MASK (0x1 << 11)
1467#define RT5640_JD_HP_SFT 11
1468#define RT5640_JD_HP_DIS (0x0 << 11)
1469#define RT5640_JD_HP_EN (0x1 << 11)
1470#define RT5640_JD_HP_TRG_MASK (0x1 << 10)
1471#define RT5640_JD_HP_TRG_SFT 10
1472#define RT5640_JD_HP_TRG_LO (0x0 << 10)
1473#define RT5640_JD_HP_TRG_HI (0x1 << 10)
1474#define RT5640_JD_SPL_MASK (0x1 << 9)
1475#define RT5640_JD_SPL_SFT 9
1476#define RT5640_JD_SPL_DIS (0x0 << 9)
1477#define RT5640_JD_SPL_EN (0x1 << 9)
1478#define RT5640_JD_SPL_TRG_MASK (0x1 << 8)
1479#define RT5640_JD_SPL_TRG_SFT 8
1480#define RT5640_JD_SPL_TRG_LO (0x0 << 8)
1481#define RT5640_JD_SPL_TRG_HI (0x1 << 8)
1482#define RT5640_JD_SPR_MASK (0x1 << 7)
1483#define RT5640_JD_SPR_SFT 7
1484#define RT5640_JD_SPR_DIS (0x0 << 7)
1485#define RT5640_JD_SPR_EN (0x1 << 7)
1486#define RT5640_JD_SPR_TRG_MASK (0x1 << 6)
1487#define RT5640_JD_SPR_TRG_SFT 6
1488#define RT5640_JD_SPR_TRG_LO (0x0 << 6)
1489#define RT5640_JD_SPR_TRG_HI (0x1 << 6)
1490#define RT5640_JD_MO_MASK (0x1 << 5)
1491#define RT5640_JD_MO_SFT 5
1492#define RT5640_JD_MO_DIS (0x0 << 5)
1493#define RT5640_JD_MO_EN (0x1 << 5)
1494#define RT5640_JD_MO_TRG_MASK (0x1 << 4)
1495#define RT5640_JD_MO_TRG_SFT 4
1496#define RT5640_JD_MO_TRG_LO (0x0 << 4)
1497#define RT5640_JD_MO_TRG_HI (0x1 << 4)
1498#define RT5640_JD_LO_MASK (0x1 << 3)
1499#define RT5640_JD_LO_SFT 3
1500#define RT5640_JD_LO_DIS (0x0 << 3)
1501#define RT5640_JD_LO_EN (0x1 << 3)
1502#define RT5640_JD_LO_TRG_MASK (0x1 << 2)
1503#define RT5640_JD_LO_TRG_SFT 2
1504#define RT5640_JD_LO_TRG_LO (0x0 << 2)
1505#define RT5640_JD_LO_TRG_HI (0x1 << 2)
1506#define RT5640_JD1_IN4P_MASK (0x1 << 1)
1507#define RT5640_JD1_IN4P_SFT 1
1508#define RT5640_JD1_IN4P_DIS (0x0 << 1)
1509#define RT5640_JD1_IN4P_EN (0x1 << 1)
1510#define RT5640_JD2_IN4N_MASK (0x1)
1511#define RT5640_JD2_IN4N_SFT 0
1512#define RT5640_JD2_IN4N_DIS (0x0)
1513#define RT5640_JD2_IN4N_EN (0x1)
1514
1515/* Jack detect for ANC (0xbc) */
1516#define RT5640_ANC_DET_MASK (0x3 << 4)
1517#define RT5640_ANC_DET_SFT 4
1518#define RT5640_ANC_DET_DIS (0x0 << 4)
1519#define RT5640_ANC_DET_MB1 (0x1 << 4)
1520#define RT5640_ANC_DET_MB2 (0x2 << 4)
1521#define RT5640_ANC_DET_JD (0x3 << 4)
1522#define RT5640_AD_TRG_MASK (0x1 << 3)
1523#define RT5640_AD_TRG_SFT 3
1524#define RT5640_AD_TRG_LO (0x0 << 3)
1525#define RT5640_AD_TRG_HI (0x1 << 3)
1526#define RT5640_ANCM_DET_MASK (0x3 << 4)
1527#define RT5640_ANCM_DET_SFT 4
1528#define RT5640_ANCM_DET_DIS (0x0 << 4)
1529#define RT5640_ANCM_DET_MB1 (0x1 << 4)
1530#define RT5640_ANCM_DET_MB2 (0x2 << 4)
1531#define RT5640_ANCM_DET_JD (0x3 << 4)
1532#define RT5640_AMD_TRG_MASK (0x1 << 3)
1533#define RT5640_AMD_TRG_SFT 3
1534#define RT5640_AMD_TRG_LO (0x0 << 3)
1535#define RT5640_AMD_TRG_HI (0x1 << 3)
1536
1537/* IRQ Control 1 (0xbd) */
1538#define RT5640_IRQ_JD_MASK (0x1 << 15)
1539#define RT5640_IRQ_JD_SFT 15
1540#define RT5640_IRQ_JD_BP (0x0 << 15)
1541#define RT5640_IRQ_JD_NOR (0x1 << 15)
1542#define RT5640_IRQ_OT_MASK (0x1 << 14)
1543#define RT5640_IRQ_OT_SFT 14
1544#define RT5640_IRQ_OT_BP (0x0 << 14)
1545#define RT5640_IRQ_OT_NOR (0x1 << 14)
1546#define RT5640_JD_STKY_MASK (0x1 << 13)
1547#define RT5640_JD_STKY_SFT 13
1548#define RT5640_JD_STKY_DIS (0x0 << 13)
1549#define RT5640_JD_STKY_EN (0x1 << 13)
1550#define RT5640_OT_STKY_MASK (0x1 << 12)
1551#define RT5640_OT_STKY_SFT 12
1552#define RT5640_OT_STKY_DIS (0x0 << 12)
1553#define RT5640_OT_STKY_EN (0x1 << 12)
1554#define RT5640_JD_P_MASK (0x1 << 11)
1555#define RT5640_JD_P_SFT 11
1556#define RT5640_JD_P_NOR (0x0 << 11)
1557#define RT5640_JD_P_INV (0x1 << 11)
1558#define RT5640_OT_P_MASK (0x1 << 10)
1559#define RT5640_OT_P_SFT 10
1560#define RT5640_OT_P_NOR (0x0 << 10)
1561#define RT5640_OT_P_INV (0x1 << 10)
1562
1563/* IRQ Control 2 (0xbe) */
1564#define RT5640_IRQ_MB1_OC_MASK (0x1 << 15)
1565#define RT5640_IRQ_MB1_OC_SFT 15
1566#define RT5640_IRQ_MB1_OC_BP (0x0 << 15)
1567#define RT5640_IRQ_MB1_OC_NOR (0x1 << 15)
1568#define RT5640_IRQ_MB2_OC_MASK (0x1 << 14)
1569#define RT5640_IRQ_MB2_OC_SFT 14
1570#define RT5640_IRQ_MB2_OC_BP (0x0 << 14)
1571#define RT5640_IRQ_MB2_OC_NOR (0x1 << 14)
1572#define RT5640_MB1_OC_STKY_MASK (0x1 << 11)
1573#define RT5640_MB1_OC_STKY_SFT 11
1574#define RT5640_MB1_OC_STKY_DIS (0x0 << 11)
1575#define RT5640_MB1_OC_STKY_EN (0x1 << 11)
1576#define RT5640_MB2_OC_STKY_MASK (0x1 << 10)
1577#define RT5640_MB2_OC_STKY_SFT 10
1578#define RT5640_MB2_OC_STKY_DIS (0x0 << 10)
1579#define RT5640_MB2_OC_STKY_EN (0x1 << 10)
1580#define RT5640_MB1_OC_P_MASK (0x1 << 7)
1581#define RT5640_MB1_OC_P_SFT 7
1582#define RT5640_MB1_OC_P_NOR (0x0 << 7)
1583#define RT5640_MB1_OC_P_INV (0x1 << 7)
1584#define RT5640_MB2_OC_P_MASK (0x1 << 6)
1585#define RT5640_MB2_OC_P_SFT 6
1586#define RT5640_MB2_OC_P_NOR (0x0 << 6)
1587#define RT5640_MB2_OC_P_INV (0x1 << 6)
1588#define RT5640_MB1_OC_CLR (0x1 << 3)
1589#define RT5640_MB1_OC_CLR_SFT 3
1590#define RT5640_MB2_OC_CLR (0x1 << 2)
1591#define RT5640_MB2_OC_CLR_SFT 2
1592
1593/* GPIO Control 1 (0xc0) */
1594#define RT5640_GP1_PIN_MASK (0x1 << 15)
1595#define RT5640_GP1_PIN_SFT 15
1596#define RT5640_GP1_PIN_GPIO1 (0x0 << 15)
1597#define RT5640_GP1_PIN_IRQ (0x1 << 15)
1598#define RT5640_GP2_PIN_MASK (0x1 << 14)
1599#define RT5640_GP2_PIN_SFT 14
1600#define RT5640_GP2_PIN_GPIO2 (0x0 << 14)
1601#define RT5640_GP2_PIN_DMIC1_SCL (0x1 << 14)
1602#define RT5640_GP3_PIN_MASK (0x3 << 12)
1603#define RT5640_GP3_PIN_SFT 12
1604#define RT5640_GP3_PIN_GPIO3 (0x0 << 12)
1605#define RT5640_GP3_PIN_DMIC1_SDA (0x1 << 12)
1606#define RT5640_GP3_PIN_IRQ (0x2 << 12)
1607#define RT5640_GP4_PIN_MASK (0x1 << 11)
1608#define RT5640_GP4_PIN_SFT 11
1609#define RT5640_GP4_PIN_GPIO4 (0x0 << 11)
1610#define RT5640_GP4_PIN_DMIC2_SDA (0x1 << 11)
1611#define RT5640_DP_SIG_MASK (0x1 << 10)
1612#define RT5640_DP_SIG_SFT 10
1613#define RT5640_DP_SIG_TEST (0x0 << 10)
1614#define RT5640_DP_SIG_AP (0x1 << 10)
1615#define RT5640_GPIO_M_MASK (0x1 << 9)
1616#define RT5640_GPIO_M_SFT 9
1617#define RT5640_GPIO_M_FLT (0x0 << 9)
1618#define RT5640_GPIO_M_PH (0x1 << 9)
1619
1620/* GPIO Control 3 (0xc2) */
1621#define RT5640_GP4_PF_MASK (0x1 << 11)
1622#define RT5640_GP4_PF_SFT 11
1623#define RT5640_GP4_PF_IN (0x0 << 11)
1624#define RT5640_GP4_PF_OUT (0x1 << 11)
1625#define RT5640_GP4_OUT_MASK (0x1 << 10)
1626#define RT5640_GP4_OUT_SFT 10
1627#define RT5640_GP4_OUT_LO (0x0 << 10)
1628#define RT5640_GP4_OUT_HI (0x1 << 10)
1629#define RT5640_GP4_P_MASK (0x1 << 9)
1630#define RT5640_GP4_P_SFT 9
1631#define RT5640_GP4_P_NOR (0x0 << 9)
1632#define RT5640_GP4_P_INV (0x1 << 9)
1633#define RT5640_GP3_PF_MASK (0x1 << 8)
1634#define RT5640_GP3_PF_SFT 8
1635#define RT5640_GP3_PF_IN (0x0 << 8)
1636#define RT5640_GP3_PF_OUT (0x1 << 8)
1637#define RT5640_GP3_OUT_MASK (0x1 << 7)
1638#define RT5640_GP3_OUT_SFT 7
1639#define RT5640_GP3_OUT_LO (0x0 << 7)
1640#define RT5640_GP3_OUT_HI (0x1 << 7)
1641#define RT5640_GP3_P_MASK (0x1 << 6)
1642#define RT5640_GP3_P_SFT 6
1643#define RT5640_GP3_P_NOR (0x0 << 6)
1644#define RT5640_GP3_P_INV (0x1 << 6)
1645#define RT5640_GP2_PF_MASK (0x1 << 5)
1646#define RT5640_GP2_PF_SFT 5
1647#define RT5640_GP2_PF_IN (0x0 << 5)
1648#define RT5640_GP2_PF_OUT (0x1 << 5)
1649#define RT5640_GP2_OUT_MASK (0x1 << 4)
1650#define RT5640_GP2_OUT_SFT 4
1651#define RT5640_GP2_OUT_LO (0x0 << 4)
1652#define RT5640_GP2_OUT_HI (0x1 << 4)
1653#define RT5640_GP2_P_MASK (0x1 << 3)
1654#define RT5640_GP2_P_SFT 3
1655#define RT5640_GP2_P_NOR (0x0 << 3)
1656#define RT5640_GP2_P_INV (0x1 << 3)
1657#define RT5640_GP1_PF_MASK (0x1 << 2)
1658#define RT5640_GP1_PF_SFT 2
1659#define RT5640_GP1_PF_IN (0x0 << 2)
1660#define RT5640_GP1_PF_OUT (0x1 << 2)
1661#define RT5640_GP1_OUT_MASK (0x1 << 1)
1662#define RT5640_GP1_OUT_SFT 1
1663#define RT5640_GP1_OUT_LO (0x0 << 1)
1664#define RT5640_GP1_OUT_HI (0x1 << 1)
1665#define RT5640_GP1_P_MASK (0x1)
1666#define RT5640_GP1_P_SFT 0
1667#define RT5640_GP1_P_NOR (0x0)
1668#define RT5640_GP1_P_INV (0x1)
1669
1670/* FM34-500 Register Control 1 (0xc4) */
1671#define RT5640_DSP_ADD_SFT 0
1672
1673/* FM34-500 Register Control 2 (0xc5) */
1674#define RT5640_DSP_DAT_SFT 0
1675
1676/* FM34-500 Register Control 3 (0xc6) */
1677#define RT5640_DSP_BUSY_MASK (0x1 << 15)
1678#define RT5640_DSP_BUSY_BIT 15
1679#define RT5640_DSP_DS_MASK (0x1 << 14)
1680#define RT5640_DSP_DS_SFT 14
1681#define RT5640_DSP_DS_FM3010 (0x1 << 14)
1682#define RT5640_DSP_DS_TEMP (0x1 << 14)
1683#define RT5640_DSP_CLK_MASK (0x3 << 12)
1684#define RT5640_DSP_CLK_SFT 12
1685#define RT5640_DSP_CLK_384K (0x0 << 12)
1686#define RT5640_DSP_CLK_192K (0x1 << 12)
1687#define RT5640_DSP_CLK_96K (0x2 << 12)
1688#define RT5640_DSP_CLK_64K (0x3 << 12)
1689#define RT5640_DSP_PD_PIN_MASK (0x1 << 11)
1690#define RT5640_DSP_PD_PIN_SFT 11
1691#define RT5640_DSP_PD_PIN_LO (0x0 << 11)
1692#define RT5640_DSP_PD_PIN_HI (0x1 << 11)
1693#define RT5640_DSP_RST_PIN_MASK (0x1 << 10)
1694#define RT5640_DSP_RST_PIN_SFT 10
1695#define RT5640_DSP_RST_PIN_LO (0x0 << 10)
1696#define RT5640_DSP_RST_PIN_HI (0x1 << 10)
1697#define RT5640_DSP_R_EN (0x1 << 9)
1698#define RT5640_DSP_R_EN_BIT 9
1699#define RT5640_DSP_W_EN (0x1 << 8)
1700#define RT5640_DSP_W_EN_BIT 8
1701#define RT5640_DSP_CMD_MASK (0xff)
1702#define RT5640_DSP_CMD_SFT 0
1703#define RT5640_DSP_CMD_MW (0x3B) /* Memory Write */
1704#define RT5640_DSP_CMD_MR (0x37) /* Memory Read */
1705#define RT5640_DSP_CMD_RR (0x60) /* Register Read */
1706#define RT5640_DSP_CMD_RW (0x68) /* Register Write */
1707
1708/* Programmable Register Array Control 1 (0xc8) */
1709#define RT5640_REG_SEQ_MASK (0xf << 12)
1710#define RT5640_REG_SEQ_SFT 12
1711#define RT5640_SEQ1_ST_MASK (0x1 << 11) /*RO*/
1712#define RT5640_SEQ1_ST_SFT 11
1713#define RT5640_SEQ1_ST_RUN (0x0 << 11)
1714#define RT5640_SEQ1_ST_FIN (0x1 << 11)
1715#define RT5640_SEQ2_ST_MASK (0x1 << 10) /*RO*/
1716#define RT5640_SEQ2_ST_SFT 10
1717#define RT5640_SEQ2_ST_RUN (0x0 << 10)
1718#define RT5640_SEQ2_ST_FIN (0x1 << 10)
1719#define RT5640_REG_LV_MASK (0x1 << 9)
1720#define RT5640_REG_LV_SFT 9
1721#define RT5640_REG_LV_MX (0x0 << 9)
1722#define RT5640_REG_LV_PR (0x1 << 9)
1723#define RT5640_SEQ_2_PT_MASK (0x1 << 8)
1724#define RT5640_SEQ_2_PT_BIT 8
1725#define RT5640_REG_IDX_MASK (0xff)
1726#define RT5640_REG_IDX_SFT 0
1727
1728/* Programmable Register Array Control 2 (0xc9) */
1729#define RT5640_REG_DAT_MASK (0xffff)
1730#define RT5640_REG_DAT_SFT 0
1731
1732/* Programmable Register Array Control 3 (0xca) */
1733#define RT5640_SEQ_DLY_MASK (0xff << 8)
1734#define RT5640_SEQ_DLY_SFT 8
1735#define RT5640_PROG_MASK (0x1 << 7)
1736#define RT5640_PROG_SFT 7
1737#define RT5640_PROG_DIS (0x0 << 7)
1738#define RT5640_PROG_EN (0x1 << 7)
1739#define RT5640_SEQ1_PT_RUN (0x1 << 6)
1740#define RT5640_SEQ1_PT_RUN_BIT 6
1741#define RT5640_SEQ2_PT_RUN (0x1 << 5)
1742#define RT5640_SEQ2_PT_RUN_BIT 5
1743
1744/* Programmable Register Array Control 4 (0xcb) */
1745#define RT5640_SEQ1_START_MASK (0xf << 8)
1746#define RT5640_SEQ1_START_SFT 8
1747#define RT5640_SEQ1_END_MASK (0xf)
1748#define RT5640_SEQ1_END_SFT 0
1749
1750/* Programmable Register Array Control 5 (0xcc) */
1751#define RT5640_SEQ2_START_MASK (0xf << 8)
1752#define RT5640_SEQ2_START_SFT 8
1753#define RT5640_SEQ2_END_MASK (0xf)
1754#define RT5640_SEQ2_END_SFT 0
1755
1756/* Scramble Function (0xcd) */
1757#define RT5640_SCB_KEY_MASK (0xff)
1758#define RT5640_SCB_KEY_SFT 0
1759
1760/* Scramble Control (0xce) */
1761#define RT5640_SCB_SWAP_MASK (0x1 << 15)
1762#define RT5640_SCB_SWAP_SFT 15
1763#define RT5640_SCB_SWAP_DIS (0x0 << 15)
1764#define RT5640_SCB_SWAP_EN (0x1 << 15)
1765#define RT5640_SCB_MASK (0x1 << 14)
1766#define RT5640_SCB_SFT 14
1767#define RT5640_SCB_DIS (0x0 << 14)
1768#define RT5640_SCB_EN (0x1 << 14)
1769
1770/* Baseback Control (0xcf) */
1771#define RT5640_BB_MASK (0x1 << 15)
1772#define RT5640_BB_SFT 15
1773#define RT5640_BB_DIS (0x0 << 15)
1774#define RT5640_BB_EN (0x1 << 15)
1775#define RT5640_BB_CT_MASK (0x7 << 12)
1776#define RT5640_BB_CT_SFT 12
1777#define RT5640_BB_CT_A (0x0 << 12)
1778#define RT5640_BB_CT_B (0x1 << 12)
1779#define RT5640_BB_CT_C (0x2 << 12)
1780#define RT5640_BB_CT_D (0x3 << 12)
1781#define RT5640_M_BB_L_MASK (0x1 << 9)
1782#define RT5640_M_BB_L_SFT 9
1783#define RT5640_M_BB_R_MASK (0x1 << 8)
1784#define RT5640_M_BB_R_SFT 8
1785#define RT5640_M_BB_HPF_L_MASK (0x1 << 7)
1786#define RT5640_M_BB_HPF_L_SFT 7
1787#define RT5640_M_BB_HPF_R_MASK (0x1 << 6)
1788#define RT5640_M_BB_HPF_R_SFT 6
1789#define RT5640_G_BB_BST_MASK (0x3f)
1790#define RT5640_G_BB_BST_SFT 0
1791
1792/* MP3 Plus Control 1 (0xd0) */
1793#define RT5640_M_MP3_L_MASK (0x1 << 15)
1794#define RT5640_M_MP3_L_SFT 15
1795#define RT5640_M_MP3_R_MASK (0x1 << 14)
1796#define RT5640_M_MP3_R_SFT 14
1797#define RT5640_M_MP3_MASK (0x1 << 13)
1798#define RT5640_M_MP3_SFT 13
1799#define RT5640_M_MP3_DIS (0x0 << 13)
1800#define RT5640_M_MP3_EN (0x1 << 13)
1801#define RT5640_EG_MP3_MASK (0x1f << 8)
1802#define RT5640_EG_MP3_SFT 8
1803#define RT5640_MP3_HLP_MASK (0x1 << 7)
1804#define RT5640_MP3_HLP_SFT 7
1805#define RT5640_MP3_HLP_DIS (0x0 << 7)
1806#define RT5640_MP3_HLP_EN (0x1 << 7)
1807#define RT5640_M_MP3_ORG_L_MASK (0x1 << 6)
1808#define RT5640_M_MP3_ORG_L_SFT 6
1809#define RT5640_M_MP3_ORG_R_MASK (0x1 << 5)
1810#define RT5640_M_MP3_ORG_R_SFT 5
1811
1812/* MP3 Plus Control 2 (0xd1) */
1813#define RT5640_MP3_WT_MASK (0x1 << 13)
1814#define RT5640_MP3_WT_SFT 13
1815#define RT5640_MP3_WT_1_4 (0x0 << 13)
1816#define RT5640_MP3_WT_1_2 (0x1 << 13)
1817#define RT5640_OG_MP3_MASK (0x1f << 8)
1818#define RT5640_OG_MP3_SFT 8
1819#define RT5640_HG_MP3_MASK (0x3f)
1820#define RT5640_HG_MP3_SFT 0
1821
1822/* 3D HP Control 1 (0xd2) */
1823#define RT5640_3D_CF_MASK (0x1 << 15)
1824#define RT5640_3D_CF_SFT 15
1825#define RT5640_3D_CF_DIS (0x0 << 15)
1826#define RT5640_3D_CF_EN (0x1 << 15)
1827#define RT5640_3D_HP_MASK (0x1 << 14)
1828#define RT5640_3D_HP_SFT 14
1829#define RT5640_3D_HP_DIS (0x0 << 14)
1830#define RT5640_3D_HP_EN (0x1 << 14)
1831#define RT5640_3D_BT_MASK (0x1 << 13)
1832#define RT5640_3D_BT_SFT 13
1833#define RT5640_3D_BT_DIS (0x0 << 13)
1834#define RT5640_3D_BT_EN (0x1 << 13)
1835#define RT5640_3D_1F_MIX_MASK (0x3 << 11)
1836#define RT5640_3D_1F_MIX_SFT 11
1837#define RT5640_3D_HP_M_MASK (0x1 << 10)
1838#define RT5640_3D_HP_M_SFT 10
1839#define RT5640_3D_HP_M_SUR (0x0 << 10)
1840#define RT5640_3D_HP_M_FRO (0x1 << 10)
1841#define RT5640_M_3D_HRTF_MASK (0x1 << 9)
1842#define RT5640_M_3D_HRTF_SFT 9
1843#define RT5640_M_3D_D2H_MASK (0x1 << 8)
1844#define RT5640_M_3D_D2H_SFT 8
1845#define RT5640_M_3D_D2R_MASK (0x1 << 7)
1846#define RT5640_M_3D_D2R_SFT 7
1847#define RT5640_M_3D_REVB_MASK (0x1 << 6)
1848#define RT5640_M_3D_REVB_SFT 6
1849
1850/* Adjustable high pass filter control 1 (0xd3) */
1851#define RT5640_2ND_HPF_MASK (0x1 << 15)
1852#define RT5640_2ND_HPF_SFT 15
1853#define RT5640_2ND_HPF_DIS (0x0 << 15)
1854#define RT5640_2ND_HPF_EN (0x1 << 15)
1855#define RT5640_HPF_CF_L_MASK (0x7 << 12)
1856#define RT5640_HPF_CF_L_SFT 12
1857#define RT5640_1ST_HPF_MASK (0x1 << 11)
1858#define RT5640_1ST_HPF_SFT 11
1859#define RT5640_1ST_HPF_DIS (0x0 << 11)
1860#define RT5640_1ST_HPF_EN (0x1 << 11)
1861#define RT5640_HPF_CF_R_MASK (0x7 << 8)
1862#define RT5640_HPF_CF_R_SFT 8
1863#define RT5640_ZD_T_MASK (0x3 << 6)
1864#define RT5640_ZD_T_SFT 6
1865#define RT5640_ZD_F_MASK (0x3 << 4)
1866#define RT5640_ZD_F_SFT 4
1867#define RT5640_ZD_F_IM (0x0 << 4)
1868#define RT5640_ZD_F_ZC_IM (0x1 << 4)
1869#define RT5640_ZD_F_ZC_IOD (0x2 << 4)
1870#define RT5640_ZD_F_UN (0x3 << 4)
1871
1872/* HP calibration control and Amp detection (0xd6) */
1873#define RT5640_SI_DAC_MASK (0x1 << 11)
1874#define RT5640_SI_DAC_SFT 11
1875#define RT5640_SI_DAC_AUTO (0x0 << 11)
1876#define RT5640_SI_DAC_TEST (0x1 << 11)
1877#define RT5640_DC_CAL_M_MASK (0x1 << 10)
1878#define RT5640_DC_CAL_M_SFT 10
1879#define RT5640_DC_CAL_M_CAL (0x0 << 10)
1880#define RT5640_DC_CAL_M_NOR (0x1 << 10)
1881#define RT5640_DC_CAL_MASK (0x1 << 9)
1882#define RT5640_DC_CAL_SFT 9
1883#define RT5640_DC_CAL_DIS (0x0 << 9)
1884#define RT5640_DC_CAL_EN (0x1 << 9)
1885#define RT5640_HPD_RCV_MASK (0x7 << 6)
1886#define RT5640_HPD_RCV_SFT 6
1887#define RT5640_HPD_PS_MASK (0x1 << 5)
1888#define RT5640_HPD_PS_SFT 5
1889#define RT5640_HPD_PS_DIS (0x0 << 5)
1890#define RT5640_HPD_PS_EN (0x1 << 5)
1891#define RT5640_CAL_M_MASK (0x1 << 4)
1892#define RT5640_CAL_M_SFT 4
1893#define RT5640_CAL_M_DEP (0x0 << 4)
1894#define RT5640_CAL_M_CAL (0x1 << 4)
1895#define RT5640_CAL_MASK (0x1 << 3)
1896#define RT5640_CAL_SFT 3
1897#define RT5640_CAL_DIS (0x0 << 3)
1898#define RT5640_CAL_EN (0x1 << 3)
1899#define RT5640_CAL_TEST_MASK (0x1 << 2)
1900#define RT5640_CAL_TEST_SFT 2
1901#define RT5640_CAL_TEST_DIS (0x0 << 2)
1902#define RT5640_CAL_TEST_EN (0x1 << 2)
1903#define RT5640_CAL_P_MASK (0x3)
1904#define RT5640_CAL_P_SFT 0
1905#define RT5640_CAL_P_NONE (0x0)
1906#define RT5640_CAL_P_CAL (0x1)
1907#define RT5640_CAL_P_DAC_CAL (0x2)
1908
1909/* Soft volume and zero cross control 1 (0xd9) */
1910#define RT5640_SV_MASK (0x1 << 15)
1911#define RT5640_SV_SFT 15
1912#define RT5640_SV_DIS (0x0 << 15)
1913#define RT5640_SV_EN (0x1 << 15)
1914#define RT5640_SPO_SV_MASK (0x1 << 14)
1915#define RT5640_SPO_SV_SFT 14
1916#define RT5640_SPO_SV_DIS (0x0 << 14)
1917#define RT5640_SPO_SV_EN (0x1 << 14)
1918#define RT5640_OUT_SV_MASK (0x1 << 13)
1919#define RT5640_OUT_SV_SFT 13
1920#define RT5640_OUT_SV_DIS (0x0 << 13)
1921#define RT5640_OUT_SV_EN (0x1 << 13)
1922#define RT5640_HP_SV_MASK (0x1 << 12)
1923#define RT5640_HP_SV_SFT 12
1924#define RT5640_HP_SV_DIS (0x0 << 12)
1925#define RT5640_HP_SV_EN (0x1 << 12)
1926#define RT5640_ZCD_DIG_MASK (0x1 << 11)
1927#define RT5640_ZCD_DIG_SFT 11
1928#define RT5640_ZCD_DIG_DIS (0x0 << 11)
1929#define RT5640_ZCD_DIG_EN (0x1 << 11)
1930#define RT5640_ZCD_MASK (0x1 << 10)
1931#define RT5640_ZCD_SFT 10
1932#define RT5640_ZCD_PD (0x0 << 10)
1933#define RT5640_ZCD_PU (0x1 << 10)
1934#define RT5640_M_ZCD_MASK (0x3f << 4)
1935#define RT5640_M_ZCD_SFT 4
1936#define RT5640_M_ZCD_RM_L (0x1 << 9)
1937#define RT5640_M_ZCD_RM_R (0x1 << 8)
1938#define RT5640_M_ZCD_SM_L (0x1 << 7)
1939#define RT5640_M_ZCD_SM_R (0x1 << 6)
1940#define RT5640_M_ZCD_OM_L (0x1 << 5)
1941#define RT5640_M_ZCD_OM_R (0x1 << 4)
1942#define RT5640_SV_DLY_MASK (0xf)
1943#define RT5640_SV_DLY_SFT 0
1944
1945/* Soft volume and zero cross control 2 (0xda) */
1946#define RT5640_ZCD_HP_MASK (0x1 << 15)
1947#define RT5640_ZCD_HP_SFT 15
1948#define RT5640_ZCD_HP_DIS (0x0 << 15)
1949#define RT5640_ZCD_HP_EN (0x1 << 15)
1950
1951
1952/* Codec Private Register definition */
1953/* 3D Speaker Control (0x63) */
1954#define RT5640_3D_SPK_MASK (0x1 << 15)
1955#define RT5640_3D_SPK_SFT 15
1956#define RT5640_3D_SPK_DIS (0x0 << 15)
1957#define RT5640_3D_SPK_EN (0x1 << 15)
1958#define RT5640_3D_SPK_M_MASK (0x3 << 13)
1959#define RT5640_3D_SPK_M_SFT 13
1960#define RT5640_3D_SPK_CG_MASK (0x1f << 8)
1961#define RT5640_3D_SPK_CG_SFT 8
1962#define RT5640_3D_SPK_SG_MASK (0x1f)
1963#define RT5640_3D_SPK_SG_SFT 0
1964
1965/* Wind Noise Detection Control 1 (0x6c) */
1966#define RT5640_WND_MASK (0x1 << 15)
1967#define RT5640_WND_SFT 15
1968#define RT5640_WND_DIS (0x0 << 15)
1969#define RT5640_WND_EN (0x1 << 15)
1970
1971/* Wind Noise Detection Control 2 (0x6d) */
1972#define RT5640_WND_FC_NW_MASK (0x3f << 10)
1973#define RT5640_WND_FC_NW_SFT 10
1974#define RT5640_WND_FC_WK_MASK (0x3f << 4)
1975#define RT5640_WND_FC_WK_SFT 4
1976
1977/* Wind Noise Detection Control 3 (0x6e) */
1978#define RT5640_HPF_FC_MASK (0x3f << 6)
1979#define RT5640_HPF_FC_SFT 6
1980#define RT5640_WND_FC_ST_MASK (0x3f)
1981#define RT5640_WND_FC_ST_SFT 0
1982
1983/* Wind Noise Detection Control 4 (0x6f) */
1984#define RT5640_WND_TH_LO_MASK (0x3ff)
1985#define RT5640_WND_TH_LO_SFT 0
1986
1987/* Wind Noise Detection Control 5 (0x70) */
1988#define RT5640_WND_TH_HI_MASK (0x3ff)
1989#define RT5640_WND_TH_HI_SFT 0
1990
1991/* Wind Noise Detection Control 8 (0x73) */
1992#define RT5640_WND_WIND_MASK (0x1 << 13) /* Read-Only */
1993#define RT5640_WND_WIND_SFT 13
1994#define RT5640_WND_STRONG_MASK (0x1 << 12) /* Read-Only */
1995#define RT5640_WND_STRONG_SFT 12
1996enum {
1997 RT5640_NO_WIND,
1998 RT5640_BREEZE,
1999 RT5640_STORM,
2000};
2001
2002/* Dipole Speaker Interface (0x75) */
2003#define RT5640_DP_ATT_MASK (0x3 << 14)
2004#define RT5640_DP_ATT_SFT 14
2005#define RT5640_DP_SPK_MASK (0x1 << 10)
2006#define RT5640_DP_SPK_SFT 10
2007#define RT5640_DP_SPK_DIS (0x0 << 10)
2008#define RT5640_DP_SPK_EN (0x1 << 10)
2009
2010/* EQ Pre Volume Control (0xb3) */
2011#define RT5640_EQ_PRE_VOL_MASK (0xffff)
2012#define RT5640_EQ_PRE_VOL_SFT 0
2013
2014/* EQ Post Volume Control (0xb4) */
2015#define RT5640_EQ_PST_VOL_MASK (0xffff)
2016#define RT5640_EQ_PST_VOL_SFT 0
2017
2018#define RT5640_NO_JACK BIT(0)
2019#define RT5640_HEADSET_DET BIT(1)
2020#define RT5640_HEADPHO_DET BIT(2)
2021
2022/* System Clock Source */
2023#define RT5640_SCLK_S_MCLK 0
2024#define RT5640_SCLK_S_PLL1 1
2025#define RT5640_SCLK_S_PLL1_TK 2
2026#define RT5640_SCLK_S_RCCLK 3
2027
2028/* PLL1 Source */
2029#define RT5640_PLL1_S_MCLK 0
2030#define RT5640_PLL1_S_BCLK1 1
2031#define RT5640_PLL1_S_BCLK2 2
2032#define RT5640_PLL1_S_BCLK3 3
2033
2034
2035enum {
2036 RT5640_AIF1,
2037 RT5640_AIF2,
2038 RT5640_AIF3,
2039 RT5640_AIFS,
2040};
2041
2042enum {
2043 RT5640_U_IF1 = 0x1,
2044 RT5640_U_IF2 = 0x2,
2045 RT5640_U_IF3 = 0x4,
2046};
2047
2048enum {
2049 RT5640_IF_123,
2050 RT5640_IF_132,
2051 RT5640_IF_312,
2052 RT5640_IF_321,
2053 RT5640_IF_231,
2054 RT5640_IF_213,
2055 RT5640_IF_113,
2056 RT5640_IF_223,
2057 RT5640_IF_ALL,
2058};
2059
2060enum {
2061 RT5640_DMIC_DIS,
2062 RT5640_DMIC1,
2063 RT5640_DMIC2,
2064};
2065
2066struct rt5640_pll_code {
2067 bool m_bp; /* Indicates bypass m code or not. */
2068 int m_code;
2069 int n_code;
2070 int k_code;
2071};
2072
2073struct rt5640_priv {
2074 struct snd_soc_codec *codec;
2075 struct rt5640_platform_data pdata;
2076 struct regmap *regmap;
2077
2078 int sysclk;
2079 int sysclk_src;
2080 int lrck[RT5640_AIFS];
2081 int bclk[RT5640_AIFS];
2082 int master[RT5640_AIFS];
2083
2084 struct rt5640_pll_code pll_code;
2085 int pll_src;
2086 int pll_in;
2087 int pll_out;
2088
2089 int dmic_en;
2090};
2091
2092#endif
diff --git a/sound/soc/codecs/sgtl5000.c b/sound/soc/codecs/sgtl5000.c
index 92bbfec9b107..d441559dc92c 100644
--- a/sound/soc/codecs/sgtl5000.c
+++ b/sound/soc/codecs/sgtl5000.c
@@ -16,6 +16,7 @@
16#include <linux/pm.h> 16#include <linux/pm.h>
17#include <linux/i2c.h> 17#include <linux/i2c.h>
18#include <linux/clk.h> 18#include <linux/clk.h>
19#include <linux/regmap.h>
19#include <linux/regulator/driver.h> 20#include <linux/regulator/driver.h>
20#include <linux/regulator/machine.h> 21#include <linux/regulator/machine.h>
21#include <linux/regulator/consumer.h> 22#include <linux/regulator/consumer.h>
@@ -34,30 +35,30 @@
34#define SGTL5000_MAX_REG_OFFSET 0x013A 35#define SGTL5000_MAX_REG_OFFSET 0x013A
35 36
36/* default value of sgtl5000 registers */ 37/* default value of sgtl5000 registers */
37static const u16 sgtl5000_regs[SGTL5000_MAX_REG_OFFSET] = { 38static const struct reg_default sgtl5000_reg_defaults[] = {
38 [SGTL5000_CHIP_CLK_CTRL] = 0x0008, 39 { SGTL5000_CHIP_CLK_CTRL, 0x0008 },
39 [SGTL5000_CHIP_I2S_CTRL] = 0x0010, 40 { SGTL5000_CHIP_I2S_CTRL, 0x0010 },
40 [SGTL5000_CHIP_SSS_CTRL] = 0x0008, 41 { SGTL5000_CHIP_SSS_CTRL, 0x0008 },
41 [SGTL5000_CHIP_DAC_VOL] = 0x3c3c, 42 { SGTL5000_CHIP_DAC_VOL, 0x3c3c },
42 [SGTL5000_CHIP_PAD_STRENGTH] = 0x015f, 43 { SGTL5000_CHIP_PAD_STRENGTH, 0x015f },
43 [SGTL5000_CHIP_ANA_HP_CTRL] = 0x1818, 44 { SGTL5000_CHIP_ANA_HP_CTRL, 0x1818 },
44 [SGTL5000_CHIP_ANA_CTRL] = 0x0111, 45 { SGTL5000_CHIP_ANA_CTRL, 0x0111 },
45 [SGTL5000_CHIP_LINE_OUT_VOL] = 0x0404, 46 { SGTL5000_CHIP_LINE_OUT_VOL, 0x0404 },
46 [SGTL5000_CHIP_ANA_POWER] = 0x7060, 47 { SGTL5000_CHIP_ANA_POWER, 0x7060 },
47 [SGTL5000_CHIP_PLL_CTRL] = 0x5000, 48 { SGTL5000_CHIP_PLL_CTRL, 0x5000 },
48 [SGTL5000_DAP_BASS_ENHANCE] = 0x0040, 49 { SGTL5000_DAP_BASS_ENHANCE, 0x0040 },
49 [SGTL5000_DAP_BASS_ENHANCE_CTRL] = 0x051f, 50 { SGTL5000_DAP_BASS_ENHANCE_CTRL, 0x051f },
50 [SGTL5000_DAP_SURROUND] = 0x0040, 51 { SGTL5000_DAP_SURROUND, 0x0040 },
51 [SGTL5000_DAP_EQ_BASS_BAND0] = 0x002f, 52 { SGTL5000_DAP_EQ_BASS_BAND0, 0x002f },
52 [SGTL5000_DAP_EQ_BASS_BAND1] = 0x002f, 53 { SGTL5000_DAP_EQ_BASS_BAND1, 0x002f },
53 [SGTL5000_DAP_EQ_BASS_BAND2] = 0x002f, 54 { SGTL5000_DAP_EQ_BASS_BAND2, 0x002f },
54 [SGTL5000_DAP_EQ_BASS_BAND3] = 0x002f, 55 { SGTL5000_DAP_EQ_BASS_BAND3, 0x002f },
55 [SGTL5000_DAP_EQ_BASS_BAND4] = 0x002f, 56 { SGTL5000_DAP_EQ_BASS_BAND4, 0x002f },
56 [SGTL5000_DAP_MAIN_CHAN] = 0x8000, 57 { SGTL5000_DAP_MAIN_CHAN, 0x8000 },
57 [SGTL5000_DAP_AVC_CTRL] = 0x0510, 58 { SGTL5000_DAP_AVC_CTRL, 0x0510 },
58 [SGTL5000_DAP_AVC_THRESHOLD] = 0x1473, 59 { SGTL5000_DAP_AVC_THRESHOLD, 0x1473 },
59 [SGTL5000_DAP_AVC_ATTACK] = 0x0028, 60 { SGTL5000_DAP_AVC_ATTACK, 0x0028 },
60 [SGTL5000_DAP_AVC_DECAY] = 0x0050, 61 { SGTL5000_DAP_AVC_DECAY, 0x0050 },
61}; 62};
62 63
63/* regulator supplies for sgtl5000, VDDD is an optional external supply */ 64/* regulator supplies for sgtl5000, VDDD is an optional external supply */
@@ -112,6 +113,8 @@ struct sgtl5000_priv {
112 int fmt; /* i2s data format */ 113 int fmt; /* i2s data format */
113 struct regulator_bulk_data supplies[SGTL5000_SUPPLY_NUM]; 114 struct regulator_bulk_data supplies[SGTL5000_SUPPLY_NUM];
114 struct ldo_regulator *ldo; 115 struct ldo_regulator *ldo;
116 struct regmap *regmap;
117 struct clk *mclk;
115}; 118};
116 119
117/* 120/*
@@ -151,12 +154,12 @@ static int power_vag_event(struct snd_soc_dapm_widget *w,
151 struct snd_kcontrol *kcontrol, int event) 154 struct snd_kcontrol *kcontrol, int event)
152{ 155{
153 switch (event) { 156 switch (event) {
154 case SND_SOC_DAPM_PRE_PMU: 157 case SND_SOC_DAPM_POST_PMU:
155 snd_soc_update_bits(w->codec, SGTL5000_CHIP_ANA_POWER, 158 snd_soc_update_bits(w->codec, SGTL5000_CHIP_ANA_POWER,
156 SGTL5000_VAG_POWERUP, SGTL5000_VAG_POWERUP); 159 SGTL5000_VAG_POWERUP, SGTL5000_VAG_POWERUP);
157 break; 160 break;
158 161
159 case SND_SOC_DAPM_POST_PMD: 162 case SND_SOC_DAPM_PRE_PMD:
160 snd_soc_update_bits(w->codec, SGTL5000_CHIP_ANA_POWER, 163 snd_soc_update_bits(w->codec, SGTL5000_CHIP_ANA_POWER,
161 SGTL5000_VAG_POWERUP, 0); 164 SGTL5000_VAG_POWERUP, 0);
162 msleep(400); 165 msleep(400);
@@ -217,12 +220,11 @@ static const struct snd_soc_dapm_widget sgtl5000_dapm_widgets[] = {
217 0, SGTL5000_CHIP_DIG_POWER, 220 0, SGTL5000_CHIP_DIG_POWER,
218 1, 0), 221 1, 0),
219 222
220 SND_SOC_DAPM_SUPPLY("VAG_POWER", SGTL5000_CHIP_ANA_POWER, 7, 0,
221 power_vag_event,
222 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
223
224 SND_SOC_DAPM_ADC("ADC", "Capture", SGTL5000_CHIP_ANA_POWER, 1, 0), 223 SND_SOC_DAPM_ADC("ADC", "Capture", SGTL5000_CHIP_ANA_POWER, 1, 0),
225 SND_SOC_DAPM_DAC("DAC", "Playback", SGTL5000_CHIP_ANA_POWER, 3, 0), 224 SND_SOC_DAPM_DAC("DAC", "Playback", SGTL5000_CHIP_ANA_POWER, 3, 0),
225
226 SND_SOC_DAPM_PRE("VAG_POWER_PRE", power_vag_event),
227 SND_SOC_DAPM_POST("VAG_POWER_POST", power_vag_event),
226}; 228};
227 229
228/* routes for sgtl5000 */ 230/* routes for sgtl5000 */
@@ -230,16 +232,13 @@ static const struct snd_soc_dapm_route sgtl5000_dapm_routes[] = {
230 {"Capture Mux", "LINE_IN", "LINE_IN"}, /* line_in --> adc_mux */ 232 {"Capture Mux", "LINE_IN", "LINE_IN"}, /* line_in --> adc_mux */
231 {"Capture Mux", "MIC_IN", "MIC_IN"}, /* mic_in --> adc_mux */ 233 {"Capture Mux", "MIC_IN", "MIC_IN"}, /* mic_in --> adc_mux */
232 234
233 {"ADC", NULL, "VAG_POWER"},
234 {"ADC", NULL, "Capture Mux"}, /* adc_mux --> adc */ 235 {"ADC", NULL, "Capture Mux"}, /* adc_mux --> adc */
235 {"AIFOUT", NULL, "ADC"}, /* adc --> i2s_out */ 236 {"AIFOUT", NULL, "ADC"}, /* adc --> i2s_out */
236 237
237 {"DAC", NULL, "VAG_POWER"},
238 {"DAC", NULL, "AIFIN"}, /* i2s-->dac,skip audio mux */ 238 {"DAC", NULL, "AIFIN"}, /* i2s-->dac,skip audio mux */
239 {"Headphone Mux", "DAC", "DAC"}, /* dac --> hp_mux */ 239 {"Headphone Mux", "DAC", "DAC"}, /* dac --> hp_mux */
240 {"LO", NULL, "DAC"}, /* dac --> line_out */ 240 {"LO", NULL, "DAC"}, /* dac --> line_out */
241 241
242 {"LINE_IN", NULL, "VAG_POWER"},
243 {"Headphone Mux", "LINE_IN", "LINE_IN"},/* line_in --> hp_mux */ 242 {"Headphone Mux", "LINE_IN", "LINE_IN"},/* line_in --> hp_mux */
244 {"HP", NULL, "Headphone Mux"}, /* hp_mux --> hp */ 243 {"HP", NULL, "Headphone Mux"}, /* hp_mux --> hp */
245 244
@@ -909,10 +908,25 @@ static int sgtl5000_set_bias_level(struct snd_soc_codec *codec,
909 if (ret) 908 if (ret)
910 return ret; 909 return ret;
911 udelay(10); 910 udelay(10);
911
912 regcache_cache_only(sgtl5000->regmap, false);
913
914 ret = regcache_sync(sgtl5000->regmap);
915 if (ret != 0) {
916 dev_err(codec->dev,
917 "Failed to restore cache: %d\n", ret);
918
919 regcache_cache_only(sgtl5000->regmap, true);
920 regulator_bulk_disable(ARRAY_SIZE(sgtl5000->supplies),
921 sgtl5000->supplies);
922
923 return ret;
924 }
912 } 925 }
913 926
914 break; 927 break;
915 case SND_SOC_BIAS_OFF: 928 case SND_SOC_BIAS_OFF:
929 regcache_cache_only(sgtl5000->regmap, true);
916 regulator_bulk_disable(ARRAY_SIZE(sgtl5000->supplies), 930 regulator_bulk_disable(ARRAY_SIZE(sgtl5000->supplies),
917 sgtl5000->supplies); 931 sgtl5000->supplies);
918 break; 932 break;
@@ -958,17 +972,76 @@ static struct snd_soc_dai_driver sgtl5000_dai = {
958 .symmetric_rates = 1, 972 .symmetric_rates = 1,
959}; 973};
960 974
961static int sgtl5000_volatile_register(struct snd_soc_codec *codec, 975static bool sgtl5000_volatile(struct device *dev, unsigned int reg)
962 unsigned int reg)
963{ 976{
964 switch (reg) { 977 switch (reg) {
965 case SGTL5000_CHIP_ID: 978 case SGTL5000_CHIP_ID:
966 case SGTL5000_CHIP_ADCDAC_CTRL: 979 case SGTL5000_CHIP_ADCDAC_CTRL:
967 case SGTL5000_CHIP_ANA_STATUS: 980 case SGTL5000_CHIP_ANA_STATUS:
968 return 1; 981 return true;
969 } 982 }
970 983
971 return 0; 984 return false;
985}
986
987static bool sgtl5000_readable(struct device *dev, unsigned int reg)
988{
989 switch (reg) {
990 case SGTL5000_CHIP_ID:
991 case SGTL5000_CHIP_DIG_POWER:
992 case SGTL5000_CHIP_CLK_CTRL:
993 case SGTL5000_CHIP_I2S_CTRL:
994 case SGTL5000_CHIP_SSS_CTRL:
995 case SGTL5000_CHIP_ADCDAC_CTRL:
996 case SGTL5000_CHIP_DAC_VOL:
997 case SGTL5000_CHIP_PAD_STRENGTH:
998 case SGTL5000_CHIP_ANA_ADC_CTRL:
999 case SGTL5000_CHIP_ANA_HP_CTRL:
1000 case SGTL5000_CHIP_ANA_CTRL:
1001 case SGTL5000_CHIP_LINREG_CTRL:
1002 case SGTL5000_CHIP_REF_CTRL:
1003 case SGTL5000_CHIP_MIC_CTRL:
1004 case SGTL5000_CHIP_LINE_OUT_CTRL:
1005 case SGTL5000_CHIP_LINE_OUT_VOL:
1006 case SGTL5000_CHIP_ANA_POWER:
1007 case SGTL5000_CHIP_PLL_CTRL:
1008 case SGTL5000_CHIP_CLK_TOP_CTRL:
1009 case SGTL5000_CHIP_ANA_STATUS:
1010 case SGTL5000_CHIP_SHORT_CTRL:
1011 case SGTL5000_CHIP_ANA_TEST2:
1012 case SGTL5000_DAP_CTRL:
1013 case SGTL5000_DAP_PEQ:
1014 case SGTL5000_DAP_BASS_ENHANCE:
1015 case SGTL5000_DAP_BASS_ENHANCE_CTRL:
1016 case SGTL5000_DAP_AUDIO_EQ:
1017 case SGTL5000_DAP_SURROUND:
1018 case SGTL5000_DAP_FLT_COEF_ACCESS:
1019 case SGTL5000_DAP_COEF_WR_B0_MSB:
1020 case SGTL5000_DAP_COEF_WR_B0_LSB:
1021 case SGTL5000_DAP_EQ_BASS_BAND0:
1022 case SGTL5000_DAP_EQ_BASS_BAND1:
1023 case SGTL5000_DAP_EQ_BASS_BAND2:
1024 case SGTL5000_DAP_EQ_BASS_BAND3:
1025 case SGTL5000_DAP_EQ_BASS_BAND4:
1026 case SGTL5000_DAP_MAIN_CHAN:
1027 case SGTL5000_DAP_MIX_CHAN:
1028 case SGTL5000_DAP_AVC_CTRL:
1029 case SGTL5000_DAP_AVC_THRESHOLD:
1030 case SGTL5000_DAP_AVC_ATTACK:
1031 case SGTL5000_DAP_AVC_DECAY:
1032 case SGTL5000_DAP_COEF_WR_B1_MSB:
1033 case SGTL5000_DAP_COEF_WR_B1_LSB:
1034 case SGTL5000_DAP_COEF_WR_B2_MSB:
1035 case SGTL5000_DAP_COEF_WR_B2_LSB:
1036 case SGTL5000_DAP_COEF_WR_A1_MSB:
1037 case SGTL5000_DAP_COEF_WR_A1_LSB:
1038 case SGTL5000_DAP_COEF_WR_A2_MSB:
1039 case SGTL5000_DAP_COEF_WR_A2_LSB:
1040 return true;
1041
1042 default:
1043 return false;
1044 }
972} 1045}
973 1046
974#ifdef CONFIG_SUSPEND 1047#ifdef CONFIG_SUSPEND
@@ -1214,7 +1287,7 @@ static int sgtl5000_replace_vddd_with_ldo(struct snd_soc_codec *codec)
1214 1287
1215static int sgtl5000_enable_regulators(struct snd_soc_codec *codec) 1288static int sgtl5000_enable_regulators(struct snd_soc_codec *codec)
1216{ 1289{
1217 u16 reg; 1290 int reg;
1218 int ret; 1291 int ret;
1219 int rev; 1292 int rev;
1220 int i; 1293 int i;
@@ -1242,23 +1315,17 @@ static int sgtl5000_enable_regulators(struct snd_soc_codec *codec)
1242 /* wait for all power rails bring up */ 1315 /* wait for all power rails bring up */
1243 udelay(10); 1316 udelay(10);
1244 1317
1245 /* read chip information */
1246 reg = snd_soc_read(codec, SGTL5000_CHIP_ID);
1247 if (((reg & SGTL5000_PARTID_MASK) >> SGTL5000_PARTID_SHIFT) !=
1248 SGTL5000_PARTID_PART_ID) {
1249 dev_err(codec->dev,
1250 "Device with ID register %x is not a sgtl5000\n", reg);
1251 ret = -ENODEV;
1252 goto err_regulator_disable;
1253 }
1254
1255 rev = (reg & SGTL5000_REVID_MASK) >> SGTL5000_REVID_SHIFT;
1256 dev_info(codec->dev, "sgtl5000 revision 0x%x\n", rev);
1257
1258 /* 1318 /*
1259 * workaround for revision 0x11 and later, 1319 * workaround for revision 0x11 and later,
1260 * roll back to use internal LDO 1320 * roll back to use internal LDO
1261 */ 1321 */
1322
1323 ret = regmap_read(sgtl5000->regmap, SGTL5000_CHIP_ID, &reg);
1324 if (ret)
1325 goto err_regulator_disable;
1326
1327 rev = (reg & SGTL5000_REVID_MASK) >> SGTL5000_REVID_SHIFT;
1328
1262 if (external_vddd && rev >= 0x11) { 1329 if (external_vddd && rev >= 0x11) {
1263 /* disable all regulator first */ 1330 /* disable all regulator first */
1264 regulator_bulk_disable(ARRAY_SIZE(sgtl5000->supplies), 1331 regulator_bulk_disable(ARRAY_SIZE(sgtl5000->supplies),
@@ -1300,7 +1367,8 @@ static int sgtl5000_probe(struct snd_soc_codec *codec)
1300 struct sgtl5000_priv *sgtl5000 = snd_soc_codec_get_drvdata(codec); 1367 struct sgtl5000_priv *sgtl5000 = snd_soc_codec_get_drvdata(codec);
1301 1368
1302 /* setup i2c data ops */ 1369 /* setup i2c data ops */
1303 ret = snd_soc_codec_set_cache_io(codec, 16, 16, SND_SOC_I2C); 1370 codec->control_data = sgtl5000->regmap;
1371 ret = snd_soc_codec_set_cache_io(codec, 16, 16, SND_SOC_REGMAP);
1304 if (ret < 0) { 1372 if (ret < 0) {
1305 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); 1373 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
1306 return ret; 1374 return ret;
@@ -1391,11 +1459,6 @@ static struct snd_soc_codec_driver sgtl5000_driver = {
1391 .suspend = sgtl5000_suspend, 1459 .suspend = sgtl5000_suspend,
1392 .resume = sgtl5000_resume, 1460 .resume = sgtl5000_resume,
1393 .set_bias_level = sgtl5000_set_bias_level, 1461 .set_bias_level = sgtl5000_set_bias_level,
1394 .reg_cache_size = ARRAY_SIZE(sgtl5000_regs),
1395 .reg_word_size = sizeof(u16),
1396 .reg_cache_step = 2,
1397 .reg_cache_default = sgtl5000_regs,
1398 .volatile_register = sgtl5000_volatile_register,
1399 .controls = sgtl5000_snd_controls, 1462 .controls = sgtl5000_snd_controls,
1400 .num_controls = ARRAY_SIZE(sgtl5000_snd_controls), 1463 .num_controls = ARRAY_SIZE(sgtl5000_snd_controls),
1401 .dapm_widgets = sgtl5000_dapm_widgets, 1464 .dapm_widgets = sgtl5000_dapm_widgets,
@@ -1404,28 +1467,114 @@ static struct snd_soc_codec_driver sgtl5000_driver = {
1404 .num_dapm_routes = ARRAY_SIZE(sgtl5000_dapm_routes), 1467 .num_dapm_routes = ARRAY_SIZE(sgtl5000_dapm_routes),
1405}; 1468};
1406 1469
1470static const struct regmap_config sgtl5000_regmap = {
1471 .reg_bits = 16,
1472 .val_bits = 16,
1473
1474 .max_register = SGTL5000_MAX_REG_OFFSET,
1475 .volatile_reg = sgtl5000_volatile,
1476 .readable_reg = sgtl5000_readable,
1477
1478 .cache_type = REGCACHE_RBTREE,
1479 .reg_defaults = sgtl5000_reg_defaults,
1480 .num_reg_defaults = ARRAY_SIZE(sgtl5000_reg_defaults),
1481};
1482
1483/*
1484 * Write all the default values from sgtl5000_reg_defaults[] array into the
1485 * sgtl5000 registers, to make sure we always start with the sane registers
1486 * values as stated in the datasheet.
1487 *
1488 * Since sgtl5000 does not have a reset line, nor a reset command in software,
1489 * we follow this approach to guarantee we always start from the default values
1490 * and avoid problems like, not being able to probe after an audio playback
1491 * followed by a system reset or a 'reboot' command in Linux
1492 */
1493static int sgtl5000_fill_defaults(struct sgtl5000_priv *sgtl5000)
1494{
1495 int i, ret, val, index;
1496
1497 for (i = 0; i < ARRAY_SIZE(sgtl5000_reg_defaults); i++) {
1498 val = sgtl5000_reg_defaults[i].def;
1499 index = sgtl5000_reg_defaults[i].reg;
1500 ret = regmap_write(sgtl5000->regmap, index, val);
1501 if (ret)
1502 return ret;
1503 }
1504
1505 return 0;
1506}
1507
1407static int sgtl5000_i2c_probe(struct i2c_client *client, 1508static int sgtl5000_i2c_probe(struct i2c_client *client,
1408 const struct i2c_device_id *id) 1509 const struct i2c_device_id *id)
1409{ 1510{
1410 struct sgtl5000_priv *sgtl5000; 1511 struct sgtl5000_priv *sgtl5000;
1411 int ret; 1512 int ret, reg, rev;
1412 1513
1413 sgtl5000 = devm_kzalloc(&client->dev, sizeof(struct sgtl5000_priv), 1514 sgtl5000 = devm_kzalloc(&client->dev, sizeof(struct sgtl5000_priv),
1414 GFP_KERNEL); 1515 GFP_KERNEL);
1415 if (!sgtl5000) 1516 if (!sgtl5000)
1416 return -ENOMEM; 1517 return -ENOMEM;
1417 1518
1519 sgtl5000->regmap = devm_regmap_init_i2c(client, &sgtl5000_regmap);
1520 if (IS_ERR(sgtl5000->regmap)) {
1521 ret = PTR_ERR(sgtl5000->regmap);
1522 dev_err(&client->dev, "Failed to allocate regmap: %d\n", ret);
1523 return ret;
1524 }
1525
1526 sgtl5000->mclk = devm_clk_get(&client->dev, NULL);
1527 if (IS_ERR(sgtl5000->mclk)) {
1528 ret = PTR_ERR(sgtl5000->mclk);
1529 dev_err(&client->dev, "Failed to get mclock: %d\n", ret);
1530 return ret;
1531 }
1532
1533 ret = clk_prepare_enable(sgtl5000->mclk);
1534 if (ret)
1535 return ret;
1536
1537 /* read chip information */
1538 ret = regmap_read(sgtl5000->regmap, SGTL5000_CHIP_ID, &reg);
1539 if (ret)
1540 goto disable_clk;
1541
1542 if (((reg & SGTL5000_PARTID_MASK) >> SGTL5000_PARTID_SHIFT) !=
1543 SGTL5000_PARTID_PART_ID) {
1544 dev_err(&client->dev,
1545 "Device with ID register %x is not a sgtl5000\n", reg);
1546 ret = -ENODEV;
1547 goto disable_clk;
1548 }
1549
1550 rev = (reg & SGTL5000_REVID_MASK) >> SGTL5000_REVID_SHIFT;
1551 dev_info(&client->dev, "sgtl5000 revision 0x%x\n", rev);
1552
1418 i2c_set_clientdata(client, sgtl5000); 1553 i2c_set_clientdata(client, sgtl5000);
1419 1554
1555 /* Ensure sgtl5000 will start with sane register values */
1556 ret = sgtl5000_fill_defaults(sgtl5000);
1557 if (ret)
1558 goto disable_clk;
1559
1420 ret = snd_soc_register_codec(&client->dev, 1560 ret = snd_soc_register_codec(&client->dev,
1421 &sgtl5000_driver, &sgtl5000_dai, 1); 1561 &sgtl5000_driver, &sgtl5000_dai, 1);
1562 if (ret)
1563 goto disable_clk;
1564
1565 return 0;
1566
1567disable_clk:
1568 clk_disable_unprepare(sgtl5000->mclk);
1422 return ret; 1569 return ret;
1423} 1570}
1424 1571
1425static int sgtl5000_i2c_remove(struct i2c_client *client) 1572static int sgtl5000_i2c_remove(struct i2c_client *client)
1426{ 1573{
1427 snd_soc_unregister_codec(&client->dev); 1574 struct sgtl5000_priv *sgtl5000 = i2c_get_clientdata(client);
1428 1575
1576 snd_soc_unregister_codec(&client->dev);
1577 clk_disable_unprepare(sgtl5000->mclk);
1429 return 0; 1578 return 0;
1430} 1579}
1431 1580
diff --git a/sound/soc/codecs/sgtl5000.h b/sound/soc/codecs/sgtl5000.h
index 8a9f43534b79..4b69229a9818 100644
--- a/sound/soc/codecs/sgtl5000.h
+++ b/sound/soc/codecs/sgtl5000.h
@@ -12,7 +12,7 @@
12#define _SGTL5000_H 12#define _SGTL5000_H
13 13
14/* 14/*
15 * Register values. 15 * Registers addresses
16 */ 16 */
17#define SGTL5000_CHIP_ID 0x0000 17#define SGTL5000_CHIP_ID 0x0000
18#define SGTL5000_CHIP_DIG_POWER 0x0002 18#define SGTL5000_CHIP_DIG_POWER 0x0002
diff --git a/sound/soc/codecs/sn95031.c b/sound/soc/codecs/sn95031.c
index d1ae869d3181..dba26e63844e 100644
--- a/sound/soc/codecs/sn95031.c
+++ b/sound/soc/codecs/sn95031.c
@@ -883,7 +883,7 @@ static int sn95031_codec_remove(struct snd_soc_codec *codec)
883 return 0; 883 return 0;
884} 884}
885 885
886struct snd_soc_codec_driver sn95031_codec = { 886static struct snd_soc_codec_driver sn95031_codec = {
887 .probe = sn95031_codec_probe, 887 .probe = sn95031_codec_probe,
888 .remove = sn95031_codec_remove, 888 .remove = sn95031_codec_remove,
889 .read = sn95031_read, 889 .read = sn95031_read,
diff --git a/sound/soc/codecs/spdif_receiver.c b/sound/soc/codecs/spdif_receiver.c
index dd8d856053fc..e9d7881ed2c8 100644
--- a/sound/soc/codecs/spdif_receiver.c
+++ b/sound/soc/codecs/spdif_receiver.c
@@ -21,6 +21,7 @@
21#include <sound/soc.h> 21#include <sound/soc.h>
22#include <sound/pcm.h> 22#include <sound/pcm.h>
23#include <sound/initval.h> 23#include <sound/initval.h>
24#include <linux/of.h>
24 25
25#define STUB_RATES SNDRV_PCM_RATE_8000_192000 26#define STUB_RATES SNDRV_PCM_RATE_8000_192000
26#define STUB_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | \ 27#define STUB_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | \
@@ -51,12 +52,21 @@ static int spdif_dir_remove(struct platform_device *pdev)
51 return 0; 52 return 0;
52} 53}
53 54
55#ifdef CONFIG_OF
56static const struct of_device_id spdif_dir_dt_ids[] = {
57 { .compatible = "linux,spdif-dir", },
58 { }
59};
60MODULE_DEVICE_TABLE(of, spdif_dir_dt_ids);
61#endif
62
54static struct platform_driver spdif_dir_driver = { 63static struct platform_driver spdif_dir_driver = {
55 .probe = spdif_dir_probe, 64 .probe = spdif_dir_probe,
56 .remove = spdif_dir_remove, 65 .remove = spdif_dir_remove,
57 .driver = { 66 .driver = {
58 .name = "spdif-dir", 67 .name = "spdif-dir",
59 .owner = THIS_MODULE, 68 .owner = THIS_MODULE,
69 .of_match_table = of_match_ptr(spdif_dir_dt_ids),
60 }, 70 },
61}; 71};
62 72
diff --git a/sound/soc/codecs/spdif_transciever.c b/sound/soc/codecs/spdif_transmitter.c
index 112a49d66e39..18280499fd55 100644
--- a/sound/soc/codecs/spdif_transciever.c
+++ b/sound/soc/codecs/spdif_transmitter.c
@@ -20,6 +20,7 @@
20#include <sound/soc.h> 20#include <sound/soc.h>
21#include <sound/pcm.h> 21#include <sound/pcm.h>
22#include <sound/initval.h> 22#include <sound/initval.h>
23#include <linux/of.h>
23 24
24#define DRV_NAME "spdif-dit" 25#define DRV_NAME "spdif-dit"
25 26
@@ -52,12 +53,21 @@ static int spdif_dit_remove(struct platform_device *pdev)
52 return 0; 53 return 0;
53} 54}
54 55
56#ifdef CONFIG_OF
57static const struct of_device_id spdif_dit_dt_ids[] = {
58 { .compatible = "linux,spdif-dit", },
59 { }
60};
61MODULE_DEVICE_TABLE(of, spdif_dit_dt_ids);
62#endif
63
55static struct platform_driver spdif_dit_driver = { 64static struct platform_driver spdif_dit_driver = {
56 .probe = spdif_dit_probe, 65 .probe = spdif_dit_probe,
57 .remove = spdif_dit_remove, 66 .remove = spdif_dit_remove,
58 .driver = { 67 .driver = {
59 .name = DRV_NAME, 68 .name = DRV_NAME,
60 .owner = THIS_MODULE, 69 .owner = THIS_MODULE,
70 .of_match_table = of_match_ptr(spdif_dit_dt_ids),
61 }, 71 },
62}; 72};
63 73
diff --git a/sound/soc/codecs/ssm2518.c b/sound/soc/codecs/ssm2518.c
new file mode 100644
index 000000000000..95aed552139a
--- /dev/null
+++ b/sound/soc/codecs/ssm2518.c
@@ -0,0 +1,856 @@
1/*
2 * SSM2518 amplifier audio driver
3 *
4 * Copyright 2013 Analog Devices Inc.
5 * Author: Lars-Peter Clausen <lars@metafoo.de>
6 *
7 * Licensed under the GPL-2.
8 */
9
10#include <linux/module.h>
11#include <linux/init.h>
12#include <linux/i2c.h>
13#include <linux/regmap.h>
14#include <linux/slab.h>
15#include <linux/gpio.h>
16#include <linux/of_gpio.h>
17#include <linux/platform_data/ssm2518.h>
18#include <sound/core.h>
19#include <sound/pcm.h>
20#include <sound/pcm_params.h>
21#include <sound/soc.h>
22#include <sound/initval.h>
23#include <sound/tlv.h>
24
25#include "ssm2518.h"
26
27#define SSM2518_REG_POWER1 0x00
28#define SSM2518_REG_CLOCK 0x01
29#define SSM2518_REG_SAI_CTRL1 0x02
30#define SSM2518_REG_SAI_CTRL2 0x03
31#define SSM2518_REG_CHAN_MAP 0x04
32#define SSM2518_REG_LEFT_VOL 0x05
33#define SSM2518_REG_RIGHT_VOL 0x06
34#define SSM2518_REG_MUTE_CTRL 0x07
35#define SSM2518_REG_FAULT_CTRL 0x08
36#define SSM2518_REG_POWER2 0x09
37#define SSM2518_REG_DRC_1 0x0a
38#define SSM2518_REG_DRC_2 0x0b
39#define SSM2518_REG_DRC_3 0x0c
40#define SSM2518_REG_DRC_4 0x0d
41#define SSM2518_REG_DRC_5 0x0e
42#define SSM2518_REG_DRC_6 0x0f
43#define SSM2518_REG_DRC_7 0x10
44#define SSM2518_REG_DRC_8 0x11
45#define SSM2518_REG_DRC_9 0x12
46
47#define SSM2518_POWER1_RESET BIT(7)
48#define SSM2518_POWER1_NO_BCLK BIT(5)
49#define SSM2518_POWER1_MCS_MASK (0xf << 1)
50#define SSM2518_POWER1_MCS_64FS (0x0 << 1)
51#define SSM2518_POWER1_MCS_128FS (0x1 << 1)
52#define SSM2518_POWER1_MCS_256FS (0x2 << 1)
53#define SSM2518_POWER1_MCS_384FS (0x3 << 1)
54#define SSM2518_POWER1_MCS_512FS (0x4 << 1)
55#define SSM2518_POWER1_MCS_768FS (0x5 << 1)
56#define SSM2518_POWER1_MCS_100FS (0x6 << 1)
57#define SSM2518_POWER1_MCS_200FS (0x7 << 1)
58#define SSM2518_POWER1_MCS_400FS (0x8 << 1)
59#define SSM2518_POWER1_SPWDN BIT(0)
60
61#define SSM2518_CLOCK_ASR BIT(0)
62
63#define SSM2518_SAI_CTRL1_FMT_MASK (0x3 << 5)
64#define SSM2518_SAI_CTRL1_FMT_I2S (0x0 << 5)
65#define SSM2518_SAI_CTRL1_FMT_LJ (0x1 << 5)
66#define SSM2518_SAI_CTRL1_FMT_RJ_24BIT (0x2 << 5)
67#define SSM2518_SAI_CTRL1_FMT_RJ_16BIT (0x3 << 5)
68
69#define SSM2518_SAI_CTRL1_SAI_MASK (0x7 << 2)
70#define SSM2518_SAI_CTRL1_SAI_I2S (0x0 << 2)
71#define SSM2518_SAI_CTRL1_SAI_TDM_2 (0x1 << 2)
72#define SSM2518_SAI_CTRL1_SAI_TDM_4 (0x2 << 2)
73#define SSM2518_SAI_CTRL1_SAI_TDM_8 (0x3 << 2)
74#define SSM2518_SAI_CTRL1_SAI_TDM_16 (0x4 << 2)
75#define SSM2518_SAI_CTRL1_SAI_MONO (0x5 << 2)
76
77#define SSM2518_SAI_CTRL1_FS_MASK (0x3)
78#define SSM2518_SAI_CTRL1_FS_8000_12000 (0x0)
79#define SSM2518_SAI_CTRL1_FS_16000_24000 (0x1)
80#define SSM2518_SAI_CTRL1_FS_32000_48000 (0x2)
81#define SSM2518_SAI_CTRL1_FS_64000_96000 (0x3)
82
83#define SSM2518_SAI_CTRL2_BCLK_INTERAL BIT(7)
84#define SSM2518_SAI_CTRL2_LRCLK_PULSE BIT(6)
85#define SSM2518_SAI_CTRL2_LRCLK_INVERT BIT(5)
86#define SSM2518_SAI_CTRL2_MSB BIT(4)
87#define SSM2518_SAI_CTRL2_SLOT_WIDTH_MASK (0x3 << 2)
88#define SSM2518_SAI_CTRL2_SLOT_WIDTH_32 (0x0 << 2)
89#define SSM2518_SAI_CTRL2_SLOT_WIDTH_24 (0x1 << 2)
90#define SSM2518_SAI_CTRL2_SLOT_WIDTH_16 (0x2 << 2)
91#define SSM2518_SAI_CTRL2_BCLK_INVERT BIT(1)
92
93#define SSM2518_CHAN_MAP_RIGHT_SLOT_OFFSET 4
94#define SSM2518_CHAN_MAP_RIGHT_SLOT_MASK 0xf0
95#define SSM2518_CHAN_MAP_LEFT_SLOT_OFFSET 0
96#define SSM2518_CHAN_MAP_LEFT_SLOT_MASK 0x0f
97
98#define SSM2518_MUTE_CTRL_ANA_GAIN BIT(5)
99#define SSM2518_MUTE_CTRL_MUTE_MASTER BIT(0)
100
101#define SSM2518_POWER2_APWDN BIT(0)
102
103#define SSM2518_DAC_MUTE BIT(6)
104#define SSM2518_DAC_FS_MASK 0x07
105#define SSM2518_DAC_FS_8000 0x00
106#define SSM2518_DAC_FS_16000 0x01
107#define SSM2518_DAC_FS_32000 0x02
108#define SSM2518_DAC_FS_64000 0x03
109#define SSM2518_DAC_FS_128000 0x04
110
111struct ssm2518 {
112 struct regmap *regmap;
113 bool right_j;
114
115 unsigned int sysclk;
116 const struct snd_pcm_hw_constraint_list *constraints;
117
118 int enable_gpio;
119};
120
121static const struct reg_default ssm2518_reg_defaults[] = {
122 { 0x00, 0x05 },
123 { 0x01, 0x00 },
124 { 0x02, 0x02 },
125 { 0x03, 0x00 },
126 { 0x04, 0x10 },
127 { 0x05, 0x40 },
128 { 0x06, 0x40 },
129 { 0x07, 0x81 },
130 { 0x08, 0x0c },
131 { 0x09, 0x99 },
132 { 0x0a, 0x7c },
133 { 0x0b, 0x5b },
134 { 0x0c, 0x57 },
135 { 0x0d, 0x89 },
136 { 0x0e, 0x8c },
137 { 0x0f, 0x77 },
138 { 0x10, 0x26 },
139 { 0x11, 0x1c },
140 { 0x12, 0x97 },
141};
142
143static const DECLARE_TLV_DB_MINMAX_MUTE(ssm2518_vol_tlv, -7125, 2400);
144static const DECLARE_TLV_DB_SCALE(ssm2518_compressor_tlv, -3400, 200, 0);
145static const DECLARE_TLV_DB_SCALE(ssm2518_expander_tlv, -8100, 300, 0);
146static const DECLARE_TLV_DB_SCALE(ssm2518_noise_gate_tlv, -9600, 300, 0);
147static const DECLARE_TLV_DB_SCALE(ssm2518_post_drc_tlv, -2400, 300, 0);
148
149static const DECLARE_TLV_DB_RANGE(ssm2518_limiter_tlv,
150 0, 7, TLV_DB_SCALE_ITEM(-2200, 200, 0),
151 7, 15, TLV_DB_SCALE_ITEM(-800, 100, 0),
152);
153
154static const char * const ssm2518_drc_peak_detector_attack_time_text[] = {
155 "0 ms", "0.1 ms", "0.19 ms", "0.37 ms", "0.75 ms", "1.5 ms", "3 ms",
156 "6 ms", "12 ms", "24 ms", "48 ms", "96 ms", "192 ms", "384 ms",
157 "768 ms", "1536 ms",
158};
159
160static const char * const ssm2518_drc_peak_detector_release_time_text[] = {
161 "0 ms", "1.5 ms", "3 ms", "6 ms", "12 ms", "24 ms", "48 ms", "96 ms",
162 "192 ms", "384 ms", "768 ms", "1536 ms", "3072 ms", "6144 ms",
163 "12288 ms", "24576 ms"
164};
165
166static const char * const ssm2518_drc_hold_time_text[] = {
167 "0 ms", "0.67 ms", "1.33 ms", "2.67 ms", "5.33 ms", "10.66 ms",
168 "21.32 ms", "42.64 ms", "85.28 ms", "170.56 ms", "341.12 ms",
169 "682.24 ms", "1364 ms",
170};
171
172static const SOC_ENUM_SINGLE_DECL(ssm2518_drc_peak_detector_attack_time_enum,
173 SSM2518_REG_DRC_2, 4, ssm2518_drc_peak_detector_attack_time_text);
174static const SOC_ENUM_SINGLE_DECL(ssm2518_drc_peak_detector_release_time_enum,
175 SSM2518_REG_DRC_2, 0, ssm2518_drc_peak_detector_release_time_text);
176static const SOC_ENUM_SINGLE_DECL(ssm2518_drc_attack_time_enum,
177 SSM2518_REG_DRC_6, 4, ssm2518_drc_peak_detector_attack_time_text);
178static const SOC_ENUM_SINGLE_DECL(ssm2518_drc_decay_time_enum,
179 SSM2518_REG_DRC_6, 0, ssm2518_drc_peak_detector_release_time_text);
180static const SOC_ENUM_SINGLE_DECL(ssm2518_drc_hold_time_enum,
181 SSM2518_REG_DRC_7, 4, ssm2518_drc_hold_time_text);
182static const SOC_ENUM_SINGLE_DECL(ssm2518_drc_noise_gate_hold_time_enum,
183 SSM2518_REG_DRC_7, 0, ssm2518_drc_hold_time_text);
184static const SOC_ENUM_SINGLE_DECL(ssm2518_drc_rms_averaging_time_enum,
185 SSM2518_REG_DRC_9, 0, ssm2518_drc_peak_detector_release_time_text);
186
187static const struct snd_kcontrol_new ssm2518_snd_controls[] = {
188 SOC_SINGLE("Playback De-emphasis Switch", SSM2518_REG_MUTE_CTRL,
189 4, 1, 0),
190 SOC_DOUBLE_R_TLV("Master Playback Volume", SSM2518_REG_LEFT_VOL,
191 SSM2518_REG_RIGHT_VOL, 0, 0xff, 1, ssm2518_vol_tlv),
192 SOC_DOUBLE("Master Playback Switch", SSM2518_REG_MUTE_CTRL, 2, 1, 1, 1),
193
194 SOC_SINGLE("Amp Low Power Mode Switch", SSM2518_REG_POWER2, 4, 1, 0),
195 SOC_SINGLE("DAC Low Power Mode Switch", SSM2518_REG_POWER2, 3, 1, 0),
196
197 SOC_SINGLE("DRC Limiter Switch", SSM2518_REG_DRC_1, 5, 1, 0),
198 SOC_SINGLE("DRC Compressor Switch", SSM2518_REG_DRC_1, 4, 1, 0),
199 SOC_SINGLE("DRC Expander Switch", SSM2518_REG_DRC_1, 3, 1, 0),
200 SOC_SINGLE("DRC Noise Gate Switch", SSM2518_REG_DRC_1, 2, 1, 0),
201 SOC_DOUBLE("DRC Switch", SSM2518_REG_DRC_1, 0, 1, 1, 0),
202
203 SOC_SINGLE_TLV("DRC Limiter Threshold Volume",
204 SSM2518_REG_DRC_3, 4, 15, 1, ssm2518_limiter_tlv),
205 SOC_SINGLE_TLV("DRC Compressor Lower Threshold Volume",
206 SSM2518_REG_DRC_3, 0, 15, 1, ssm2518_compressor_tlv),
207 SOC_SINGLE_TLV("DRC Expander Upper Threshold Volume", SSM2518_REG_DRC_4,
208 4, 15, 1, ssm2518_expander_tlv),
209 SOC_SINGLE_TLV("DRC Noise Gate Threshold Volume",
210 SSM2518_REG_DRC_4, 0, 15, 1, ssm2518_noise_gate_tlv),
211 SOC_SINGLE_TLV("DRC Upper Output Threshold Volume",
212 SSM2518_REG_DRC_5, 4, 15, 1, ssm2518_limiter_tlv),
213 SOC_SINGLE_TLV("DRC Lower Output Threshold Volume",
214 SSM2518_REG_DRC_5, 0, 15, 1, ssm2518_noise_gate_tlv),
215 SOC_SINGLE_TLV("DRC Post Volume", SSM2518_REG_DRC_8,
216 2, 15, 1, ssm2518_post_drc_tlv),
217
218 SOC_ENUM("DRC Peak Detector Attack Time",
219 ssm2518_drc_peak_detector_attack_time_enum),
220 SOC_ENUM("DRC Peak Detector Release Time",
221 ssm2518_drc_peak_detector_release_time_enum),
222 SOC_ENUM("DRC Attack Time", ssm2518_drc_attack_time_enum),
223 SOC_ENUM("DRC Decay Time", ssm2518_drc_decay_time_enum),
224 SOC_ENUM("DRC Hold Time", ssm2518_drc_hold_time_enum),
225 SOC_ENUM("DRC Noise Gate Hold Time",
226 ssm2518_drc_noise_gate_hold_time_enum),
227 SOC_ENUM("DRC RMS Averaging Time", ssm2518_drc_rms_averaging_time_enum),
228};
229
230static const struct snd_soc_dapm_widget ssm2518_dapm_widgets[] = {
231 SND_SOC_DAPM_DAC("DACL", "HiFi Playback", SSM2518_REG_POWER2, 1, 1),
232 SND_SOC_DAPM_DAC("DACR", "HiFi Playback", SSM2518_REG_POWER2, 2, 1),
233
234 SND_SOC_DAPM_OUTPUT("OUTL"),
235 SND_SOC_DAPM_OUTPUT("OUTR"),
236};
237
238static const struct snd_soc_dapm_route ssm2518_routes[] = {
239 { "OUTL", NULL, "DACL" },
240 { "OUTR", NULL, "DACR" },
241};
242
243struct ssm2518_mcs_lut {
244 unsigned int rate;
245 const unsigned int *sysclks;
246};
247
248static const unsigned int ssm2518_sysclks_2048000[] = {
249 2048000, 4096000, 8192000, 12288000, 16384000, 24576000,
250 3200000, 6400000, 12800000, 0
251};
252
253static const unsigned int ssm2518_sysclks_2822000[] = {
254 2822000, 5644800, 11289600, 16934400, 22579200, 33868800,
255 4410000, 8820000, 17640000, 0
256};
257
258static const unsigned int ssm2518_sysclks_3072000[] = {
259 3072000, 6144000, 12288000, 16384000, 24576000, 38864000,
260 4800000, 9600000, 19200000, 0
261};
262
263static const struct ssm2518_mcs_lut ssm2518_mcs_lut[] = {
264 { 8000, ssm2518_sysclks_2048000, },
265 { 11025, ssm2518_sysclks_2822000, },
266 { 12000, ssm2518_sysclks_3072000, },
267 { 16000, ssm2518_sysclks_2048000, },
268 { 24000, ssm2518_sysclks_3072000, },
269 { 22050, ssm2518_sysclks_2822000, },
270 { 32000, ssm2518_sysclks_2048000, },
271 { 44100, ssm2518_sysclks_2822000, },
272 { 48000, ssm2518_sysclks_3072000, },
273 { 96000, ssm2518_sysclks_3072000, },
274};
275
276static const unsigned int ssm2518_rates_2048000[] = {
277 8000, 16000, 32000,
278};
279
280static const struct snd_pcm_hw_constraint_list ssm2518_constraints_2048000 = {
281 .list = ssm2518_rates_2048000,
282 .count = ARRAY_SIZE(ssm2518_rates_2048000),
283};
284
285static const unsigned int ssm2518_rates_2822000[] = {
286 11025, 22050, 44100,
287};
288
289static const struct snd_pcm_hw_constraint_list ssm2518_constraints_2822000 = {
290 .list = ssm2518_rates_2822000,
291 .count = ARRAY_SIZE(ssm2518_rates_2822000),
292};
293
294static const unsigned int ssm2518_rates_3072000[] = {
295 12000, 24000, 48000, 96000,
296};
297
298static const struct snd_pcm_hw_constraint_list ssm2518_constraints_3072000 = {
299 .list = ssm2518_rates_3072000,
300 .count = ARRAY_SIZE(ssm2518_rates_3072000),
301};
302
303static const unsigned int ssm2518_rates_12288000[] = {
304 8000, 12000, 16000, 24000, 32000, 48000, 96000,
305};
306
307static const struct snd_pcm_hw_constraint_list ssm2518_constraints_12288000 = {
308 .list = ssm2518_rates_12288000,
309 .count = ARRAY_SIZE(ssm2518_rates_12288000),
310};
311
312static unsigned int ssm2518_lookup_mcs(struct ssm2518 *ssm2518,
313 unsigned int rate)
314{
315 const unsigned int *sysclks = NULL;
316 int i;
317
318 for (i = 0; i < ARRAY_SIZE(ssm2518_mcs_lut); i++) {
319 if (ssm2518_mcs_lut[i].rate == rate) {
320 sysclks = ssm2518_mcs_lut[i].sysclks;
321 break;
322 }
323 }
324
325 if (!sysclks)
326 return -EINVAL;
327
328 for (i = 0; sysclks[i]; i++) {
329 if (sysclks[i] == ssm2518->sysclk)
330 return i;
331 }
332
333 return -EINVAL;
334}
335
336static int ssm2518_hw_params(struct snd_pcm_substream *substream,
337 struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
338{
339 struct snd_soc_codec *codec = dai->codec;
340 struct ssm2518 *ssm2518 = snd_soc_codec_get_drvdata(codec);
341 unsigned int rate = params_rate(params);
342 unsigned int ctrl1, ctrl1_mask;
343 int mcs;
344 int ret;
345
346 mcs = ssm2518_lookup_mcs(ssm2518, rate);
347 if (mcs < 0)
348 return mcs;
349
350 ctrl1_mask = SSM2518_SAI_CTRL1_FS_MASK;
351
352 if (rate >= 8000 && rate <= 12000)
353 ctrl1 = SSM2518_SAI_CTRL1_FS_8000_12000;
354 else if (rate >= 16000 && rate <= 24000)
355 ctrl1 = SSM2518_SAI_CTRL1_FS_16000_24000;
356 else if (rate >= 32000 && rate <= 48000)
357 ctrl1 = SSM2518_SAI_CTRL1_FS_32000_48000;
358 else if (rate >= 64000 && rate <= 96000)
359 ctrl1 = SSM2518_SAI_CTRL1_FS_64000_96000;
360 else
361 return -EINVAL;
362
363 if (ssm2518->right_j) {
364 switch (params_format(params)) {
365 case SNDRV_PCM_FORMAT_S16_LE:
366 ctrl1 |= SSM2518_SAI_CTRL1_FMT_RJ_16BIT;
367 break;
368 case SNDRV_PCM_FORMAT_S24_LE:
369 ctrl1 |= SSM2518_SAI_CTRL1_FMT_RJ_24BIT;
370 break;
371 default:
372 return -EINVAL;
373 }
374 ctrl1_mask |= SSM2518_SAI_CTRL1_FMT_MASK;
375 }
376
377 /* Disable auto samplerate detection */
378 ret = regmap_update_bits(ssm2518->regmap, SSM2518_REG_CLOCK,
379 SSM2518_CLOCK_ASR, SSM2518_CLOCK_ASR);
380 if (ret < 0)
381 return ret;
382
383 ret = regmap_update_bits(ssm2518->regmap, SSM2518_REG_SAI_CTRL1,
384 ctrl1_mask, ctrl1);
385 if (ret < 0)
386 return ret;
387
388 return regmap_update_bits(ssm2518->regmap, SSM2518_REG_POWER1,
389 SSM2518_POWER1_MCS_MASK, mcs << 1);
390}
391
392static int ssm2518_mute(struct snd_soc_dai *dai, int mute)
393{
394 struct ssm2518 *ssm2518 = snd_soc_codec_get_drvdata(dai->codec);
395 unsigned int val;
396
397 if (mute)
398 val = SSM2518_MUTE_CTRL_MUTE_MASTER;
399 else
400 val = 0;
401
402 return regmap_update_bits(ssm2518->regmap, SSM2518_REG_MUTE_CTRL,
403 SSM2518_MUTE_CTRL_MUTE_MASTER, val);
404}
405
406static int ssm2518_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
407{
408 struct ssm2518 *ssm2518 = snd_soc_codec_get_drvdata(dai->codec);
409 unsigned int ctrl1 = 0, ctrl2 = 0;
410 bool invert_fclk;
411 int ret;
412
413 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
414 case SND_SOC_DAIFMT_CBS_CFS:
415 break;
416 default:
417 return -EINVAL;
418 }
419
420 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
421 case SND_SOC_DAIFMT_NB_NF:
422 invert_fclk = false;
423 break;
424 case SND_SOC_DAIFMT_IB_NF:
425 ctrl2 |= SSM2518_SAI_CTRL2_BCLK_INVERT;
426 invert_fclk = false;
427 break;
428 case SND_SOC_DAIFMT_NB_IF:
429 invert_fclk = true;
430 break;
431 case SND_SOC_DAIFMT_IB_IF:
432 ctrl2 |= SSM2518_SAI_CTRL2_BCLK_INVERT;
433 invert_fclk = true;
434 break;
435 default:
436 return -EINVAL;
437 }
438
439 ssm2518->right_j = false;
440 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
441 case SND_SOC_DAIFMT_I2S:
442 ctrl1 |= SSM2518_SAI_CTRL1_FMT_I2S;
443 break;
444 case SND_SOC_DAIFMT_LEFT_J:
445 ctrl1 |= SSM2518_SAI_CTRL1_FMT_LJ;
446 invert_fclk = !invert_fclk;
447 break;
448 case SND_SOC_DAIFMT_RIGHT_J:
449 ctrl1 |= SSM2518_SAI_CTRL1_FMT_RJ_24BIT;
450 ssm2518->right_j = true;
451 invert_fclk = !invert_fclk;
452 break;
453 case SND_SOC_DAIFMT_DSP_A:
454 ctrl2 |= SSM2518_SAI_CTRL2_LRCLK_PULSE;
455 ctrl1 |= SSM2518_SAI_CTRL1_FMT_I2S;
456 invert_fclk = false;
457 break;
458 case SND_SOC_DAIFMT_DSP_B:
459 ctrl2 |= SSM2518_SAI_CTRL2_LRCLK_PULSE;
460 ctrl1 |= SSM2518_SAI_CTRL1_FMT_LJ;
461 invert_fclk = false;
462 break;
463 default:
464 return -EINVAL;
465 }
466
467 if (invert_fclk)
468 ctrl2 |= SSM2518_SAI_CTRL2_LRCLK_INVERT;
469
470 ret = regmap_write(ssm2518->regmap, SSM2518_REG_SAI_CTRL1, ctrl1);
471 if (ret)
472 return ret;
473
474 return regmap_write(ssm2518->regmap, SSM2518_REG_SAI_CTRL2, ctrl2);
475}
476
477static int ssm2518_set_power(struct ssm2518 *ssm2518, bool enable)
478{
479 int ret = 0;
480
481 if (!enable) {
482 ret = regmap_update_bits(ssm2518->regmap, SSM2518_REG_POWER1,
483 SSM2518_POWER1_SPWDN, SSM2518_POWER1_SPWDN);
484 regcache_mark_dirty(ssm2518->regmap);
485 }
486
487 if (gpio_is_valid(ssm2518->enable_gpio))
488 gpio_set_value(ssm2518->enable_gpio, enable);
489
490 regcache_cache_only(ssm2518->regmap, !enable);
491
492 if (enable) {
493 ret = regmap_update_bits(ssm2518->regmap, SSM2518_REG_POWER1,
494 SSM2518_POWER1_SPWDN | SSM2518_POWER1_RESET, 0x00);
495 regcache_sync(ssm2518->regmap);
496 }
497
498 return ret;
499}
500
501static int ssm2518_set_bias_level(struct snd_soc_codec *codec,
502 enum snd_soc_bias_level level)
503{
504 struct ssm2518 *ssm2518 = snd_soc_codec_get_drvdata(codec);
505 int ret = 0;
506
507 switch (level) {
508 case SND_SOC_BIAS_ON:
509 break;
510 case SND_SOC_BIAS_PREPARE:
511 break;
512 case SND_SOC_BIAS_STANDBY:
513 if (codec->dapm.bias_level == SND_SOC_BIAS_OFF)
514 ret = ssm2518_set_power(ssm2518, true);
515 break;
516 case SND_SOC_BIAS_OFF:
517 ret = ssm2518_set_power(ssm2518, false);
518 break;
519 }
520
521 if (ret)
522 return ret;
523
524 codec->dapm.bias_level = level;
525
526 return 0;
527}
528
529static int ssm2518_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
530 unsigned int rx_mask, int slots, int width)
531{
532 struct ssm2518 *ssm2518 = snd_soc_codec_get_drvdata(dai->codec);
533 unsigned int ctrl1, ctrl2;
534 int left_slot, right_slot;
535 int ret;
536
537 if (slots == 0)
538 return regmap_update_bits(ssm2518->regmap,
539 SSM2518_REG_SAI_CTRL1, SSM2518_SAI_CTRL1_SAI_MASK,
540 SSM2518_SAI_CTRL1_SAI_I2S);
541
542 if (tx_mask == 0 || rx_mask != 0)
543 return -EINVAL;
544
545 if (slots == 1) {
546 if (tx_mask != 1)
547 return -EINVAL;
548 left_slot = 0;
549 right_slot = 0;
550 } else {
551 /* We assume the left channel < right channel */
552 left_slot = ffs(tx_mask);
553 tx_mask &= ~(1 << tx_mask);
554 if (tx_mask == 0) {
555 right_slot = left_slot;
556 } else {
557 right_slot = ffs(tx_mask);
558 tx_mask &= ~(1 << tx_mask);
559 }
560 }
561
562 if (tx_mask != 0 || left_slot >= slots || right_slot >= slots)
563 return -EINVAL;
564
565 switch (width) {
566 case 16:
567 ctrl2 = SSM2518_SAI_CTRL2_SLOT_WIDTH_16;
568 break;
569 case 24:
570 ctrl2 = SSM2518_SAI_CTRL2_SLOT_WIDTH_24;
571 break;
572 case 32:
573 ctrl2 = SSM2518_SAI_CTRL2_SLOT_WIDTH_32;
574 break;
575 default:
576 return -EINVAL;
577 }
578
579 switch (slots) {
580 case 1:
581 ctrl1 = SSM2518_SAI_CTRL1_SAI_MONO;
582 break;
583 case 2:
584 ctrl1 = SSM2518_SAI_CTRL1_SAI_TDM_2;
585 break;
586 case 4:
587 ctrl1 = SSM2518_SAI_CTRL1_SAI_TDM_4;
588 break;
589 case 8:
590 ctrl1 = SSM2518_SAI_CTRL1_SAI_TDM_8;
591 break;
592 case 16:
593 ctrl1 = SSM2518_SAI_CTRL1_SAI_TDM_16;
594 break;
595 default:
596 return -EINVAL;
597 }
598
599 ret = regmap_write(ssm2518->regmap, SSM2518_REG_CHAN_MAP,
600 (left_slot << SSM2518_CHAN_MAP_LEFT_SLOT_OFFSET) |
601 (right_slot << SSM2518_CHAN_MAP_RIGHT_SLOT_OFFSET));
602 if (ret)
603 return ret;
604
605 ret = regmap_update_bits(ssm2518->regmap, SSM2518_REG_SAI_CTRL1,
606 SSM2518_SAI_CTRL1_SAI_MASK, ctrl1);
607 if (ret)
608 return ret;
609
610 return regmap_update_bits(ssm2518->regmap, SSM2518_REG_SAI_CTRL2,
611 SSM2518_SAI_CTRL2_SLOT_WIDTH_MASK, ctrl2);
612}
613
614static int ssm2518_startup(struct snd_pcm_substream *substream,
615 struct snd_soc_dai *dai)
616{
617 struct ssm2518 *ssm2518 = snd_soc_codec_get_drvdata(dai->codec);
618
619 if (ssm2518->constraints)
620 snd_pcm_hw_constraint_list(substream->runtime, 0,
621 SNDRV_PCM_HW_PARAM_RATE, ssm2518->constraints);
622
623 return 0;
624}
625
626#define SSM2518_FORMATS (SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_S16_LE | \
627 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32)
628
629static const struct snd_soc_dai_ops ssm2518_dai_ops = {
630 .startup = ssm2518_startup,
631 .hw_params = ssm2518_hw_params,
632 .digital_mute = ssm2518_mute,
633 .set_fmt = ssm2518_set_dai_fmt,
634 .set_tdm_slot = ssm2518_set_tdm_slot,
635};
636
637static struct snd_soc_dai_driver ssm2518_dai = {
638 .name = "ssm2518-hifi",
639 .playback = {
640 .stream_name = "Playback",
641 .channels_min = 2,
642 .channels_max = 2,
643 .rates = SNDRV_PCM_RATE_8000_96000,
644 .formats = SSM2518_FORMATS,
645 },
646 .ops = &ssm2518_dai_ops,
647};
648
649static int ssm2518_probe(struct snd_soc_codec *codec)
650{
651 struct ssm2518 *ssm2518 = snd_soc_codec_get_drvdata(codec);
652 int ret;
653
654 codec->control_data = ssm2518->regmap;
655 ret = snd_soc_codec_set_cache_io(codec, 0, 0, SND_SOC_REGMAP);
656 if (ret < 0) {
657 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
658 return ret;
659 }
660
661 return ssm2518_set_bias_level(codec, SND_SOC_BIAS_OFF);
662}
663
664static int ssm2518_remove(struct snd_soc_codec *codec)
665{
666 ssm2518_set_bias_level(codec, SND_SOC_BIAS_OFF);
667 return 0;
668}
669
670static int ssm2518_set_sysclk(struct snd_soc_codec *codec, int clk_id,
671 int source, unsigned int freq, int dir)
672{
673 struct ssm2518 *ssm2518 = snd_soc_codec_get_drvdata(codec);
674 unsigned int val;
675
676 if (clk_id != SSM2518_SYSCLK)
677 return -EINVAL;
678
679 switch (source) {
680 case SSM2518_SYSCLK_SRC_MCLK:
681 val = 0;
682 break;
683 case SSM2518_SYSCLK_SRC_BCLK:
684 /* In this case the bitclock is used as the system clock, and
685 * the bitclock signal needs to be connected to the MCLK pin and
686 * the BCLK pin is left unconnected */
687 val = SSM2518_POWER1_NO_BCLK;
688 break;
689 default:
690 return -EINVAL;
691 }
692
693 switch (freq) {
694 case 0:
695 ssm2518->constraints = NULL;
696 break;
697 case 2048000:
698 case 4096000:
699 case 8192000:
700 case 3200000:
701 case 6400000:
702 case 12800000:
703 ssm2518->constraints = &ssm2518_constraints_2048000;
704 break;
705 case 2822000:
706 case 5644800:
707 case 11289600:
708 case 16934400:
709 case 22579200:
710 case 33868800:
711 case 4410000:
712 case 8820000:
713 case 17640000:
714 ssm2518->constraints = &ssm2518_constraints_2822000;
715 break;
716 case 3072000:
717 case 6144000:
718 case 38864000:
719 case 4800000:
720 case 9600000:
721 case 19200000:
722 ssm2518->constraints = &ssm2518_constraints_3072000;
723 break;
724 case 12288000:
725 case 16384000:
726 case 24576000:
727 ssm2518->constraints = &ssm2518_constraints_12288000;
728 break;
729 default:
730 return -EINVAL;
731 }
732
733 ssm2518->sysclk = freq;
734
735 return regmap_update_bits(ssm2518->regmap, SSM2518_REG_POWER1,
736 SSM2518_POWER1_NO_BCLK, val);
737}
738
739static struct snd_soc_codec_driver ssm2518_codec_driver = {
740 .probe = ssm2518_probe,
741 .remove = ssm2518_remove,
742 .set_bias_level = ssm2518_set_bias_level,
743 .set_sysclk = ssm2518_set_sysclk,
744 .idle_bias_off = true,
745
746 .controls = ssm2518_snd_controls,
747 .num_controls = ARRAY_SIZE(ssm2518_snd_controls),
748 .dapm_widgets = ssm2518_dapm_widgets,
749 .num_dapm_widgets = ARRAY_SIZE(ssm2518_dapm_widgets),
750 .dapm_routes = ssm2518_routes,
751 .num_dapm_routes = ARRAY_SIZE(ssm2518_routes),
752};
753
754static bool ssm2518_register_volatile(struct device *dev, unsigned int reg)
755{
756 return false;
757}
758
759static const struct regmap_config ssm2518_regmap_config = {
760 .val_bits = 8,
761 .reg_bits = 8,
762
763 .max_register = SSM2518_REG_DRC_9,
764 .volatile_reg = ssm2518_register_volatile,
765
766 .cache_type = REGCACHE_RBTREE,
767 .reg_defaults = ssm2518_reg_defaults,
768 .num_reg_defaults = ARRAY_SIZE(ssm2518_reg_defaults),
769};
770
771static int ssm2518_i2c_probe(struct i2c_client *i2c,
772 const struct i2c_device_id *id)
773{
774 struct ssm2518_platform_data *pdata = i2c->dev.platform_data;
775 struct ssm2518 *ssm2518;
776 int ret;
777
778 ssm2518 = devm_kzalloc(&i2c->dev, sizeof(*ssm2518), GFP_KERNEL);
779 if (ssm2518 == NULL)
780 return -ENOMEM;
781
782 if (pdata) {
783 ssm2518->enable_gpio = pdata->enable_gpio;
784 } else if (i2c->dev.of_node) {
785 ssm2518->enable_gpio = of_get_gpio(i2c->dev.of_node, 0);
786 if (ssm2518->enable_gpio < 0 && ssm2518->enable_gpio != -ENOENT)
787 return ssm2518->enable_gpio;
788 } else {
789 ssm2518->enable_gpio = -1;
790 }
791
792 if (gpio_is_valid(ssm2518->enable_gpio)) {
793 ret = devm_gpio_request_one(&i2c->dev, ssm2518->enable_gpio,
794 GPIOF_OUT_INIT_HIGH, "SSM2518 nSD");
795 if (ret)
796 return ret;
797 }
798
799 i2c_set_clientdata(i2c, ssm2518);
800
801 ssm2518->regmap = devm_regmap_init_i2c(i2c, &ssm2518_regmap_config);
802 if (IS_ERR(ssm2518->regmap))
803 return PTR_ERR(ssm2518->regmap);
804
805 /*
806 * The reset bit is obviously volatile, but we need to be able to cache
807 * the other bits in the register, so we can't just mark the whole
808 * register as volatile. Since this is the only place where we'll ever
809 * touch the reset bit just bypass the cache for this operation.
810 */
811 regcache_cache_bypass(ssm2518->regmap, true);
812 ret = regmap_write(ssm2518->regmap, SSM2518_REG_POWER1,
813 SSM2518_POWER1_RESET);
814 regcache_cache_bypass(ssm2518->regmap, false);
815 if (ret)
816 return ret;
817
818 ret = regmap_update_bits(ssm2518->regmap, SSM2518_REG_POWER2,
819 SSM2518_POWER2_APWDN, 0x00);
820 if (ret)
821 return ret;
822
823 ret = ssm2518_set_power(ssm2518, false);
824 if (ret)
825 return ret;
826
827 return snd_soc_register_codec(&i2c->dev, &ssm2518_codec_driver,
828 &ssm2518_dai, 1);
829}
830
831static int ssm2518_i2c_remove(struct i2c_client *client)
832{
833 snd_soc_unregister_codec(&client->dev);
834 return 0;
835}
836
837static const struct i2c_device_id ssm2518_i2c_ids[] = {
838 { "ssm2518", 0 },
839 { }
840};
841MODULE_DEVICE_TABLE(i2c, ssm2518_i2c_ids);
842
843static struct i2c_driver ssm2518_driver = {
844 .driver = {
845 .name = "ssm2518",
846 .owner = THIS_MODULE,
847 },
848 .probe = ssm2518_i2c_probe,
849 .remove = ssm2518_i2c_remove,
850 .id_table = ssm2518_i2c_ids,
851};
852module_i2c_driver(ssm2518_driver);
853
854MODULE_DESCRIPTION("ASoC SSM2518 driver");
855MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
856MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/ssm2518.h b/sound/soc/codecs/ssm2518.h
new file mode 100644
index 000000000000..62511d80518e
--- /dev/null
+++ b/sound/soc/codecs/ssm2518.h
@@ -0,0 +1,20 @@
1/*
2 * SSM2518 amplifier audio driver
3 *
4 * Copyright 2013 Analog Devices Inc.
5 * Author: Lars-Peter Clausen <lars@metafoo.de>
6 *
7 * Licensed under the GPL-2.
8 */
9
10#ifndef __SND_SOC_CODECS_SSM2518_H__
11#define __SND_SOC_CODECS_SSM2518_H__
12
13#define SSM2518_SYSCLK 0
14
15enum ssm2518_sysclk_src {
16 SSM2518_SYSCLK_SRC_MCLK = 0,
17 SSM2518_SYSCLK_SRC_BCLK = 1,
18};
19
20#endif
diff --git a/sound/soc/codecs/stac9766.c b/sound/soc/codecs/stac9766.c
index 2eda85ba79ac..a5455c1aea42 100644
--- a/sound/soc/codecs/stac9766.c
+++ b/sound/soc/codecs/stac9766.c
@@ -28,8 +28,6 @@
28 28
29#include "stac9766.h" 29#include "stac9766.h"
30 30
31#define STAC9766_VERSION "0.10"
32
33/* 31/*
34 * STAC9766 register cache 32 * STAC9766 register cache
35 */ 33 */
@@ -145,14 +143,14 @@ static int stac9766_ac97_write(struct snd_soc_codec *codec, unsigned int reg,
145 143
146 if (reg > AC97_STAC_PAGE0) { 144 if (reg > AC97_STAC_PAGE0) {
147 stac9766_ac97_write(codec, AC97_INT_PAGING, 0); 145 stac9766_ac97_write(codec, AC97_INT_PAGING, 0);
148 soc_ac97_ops.write(codec->ac97, reg, val); 146 soc_ac97_ops->write(codec->ac97, reg, val);
149 stac9766_ac97_write(codec, AC97_INT_PAGING, 1); 147 stac9766_ac97_write(codec, AC97_INT_PAGING, 1);
150 return 0; 148 return 0;
151 } 149 }
152 if (reg / 2 >= ARRAY_SIZE(stac9766_reg)) 150 if (reg / 2 >= ARRAY_SIZE(stac9766_reg))
153 return -EIO; 151 return -EIO;
154 152
155 soc_ac97_ops.write(codec->ac97, reg, val); 153 soc_ac97_ops->write(codec->ac97, reg, val);
156 cache[reg / 2] = val; 154 cache[reg / 2] = val;
157 return 0; 155 return 0;
158} 156}
@@ -164,7 +162,7 @@ static unsigned int stac9766_ac97_read(struct snd_soc_codec *codec,
164 162
165 if (reg > AC97_STAC_PAGE0) { 163 if (reg > AC97_STAC_PAGE0) {
166 stac9766_ac97_write(codec, AC97_INT_PAGING, 0); 164 stac9766_ac97_write(codec, AC97_INT_PAGING, 0);
167 val = soc_ac97_ops.read(codec->ac97, reg - AC97_STAC_PAGE0); 165 val = soc_ac97_ops->read(codec->ac97, reg - AC97_STAC_PAGE0);
168 stac9766_ac97_write(codec, AC97_INT_PAGING, 1); 166 stac9766_ac97_write(codec, AC97_INT_PAGING, 1);
169 return val; 167 return val;
170 } 168 }
@@ -175,7 +173,7 @@ static unsigned int stac9766_ac97_read(struct snd_soc_codec *codec,
175 reg == AC97_INT_PAGING || reg == AC97_VENDOR_ID1 || 173 reg == AC97_INT_PAGING || reg == AC97_VENDOR_ID1 ||
176 reg == AC97_VENDOR_ID2) { 174 reg == AC97_VENDOR_ID2) {
177 175
178 val = soc_ac97_ops.read(codec->ac97, reg); 176 val = soc_ac97_ops->read(codec->ac97, reg);
179 return val; 177 return val;
180 } 178 }
181 return cache[reg / 2]; 179 return cache[reg / 2];
@@ -242,15 +240,15 @@ static int stac9766_set_bias_level(struct snd_soc_codec *codec,
242 240
243static int stac9766_reset(struct snd_soc_codec *codec, int try_warm) 241static int stac9766_reset(struct snd_soc_codec *codec, int try_warm)
244{ 242{
245 if (try_warm && soc_ac97_ops.warm_reset) { 243 if (try_warm && soc_ac97_ops->warm_reset) {
246 soc_ac97_ops.warm_reset(codec->ac97); 244 soc_ac97_ops->warm_reset(codec->ac97);
247 if (stac9766_ac97_read(codec, 0) == stac9766_reg[0]) 245 if (stac9766_ac97_read(codec, 0) == stac9766_reg[0])
248 return 1; 246 return 1;
249 } 247 }
250 248
251 soc_ac97_ops.reset(codec->ac97); 249 soc_ac97_ops->reset(codec->ac97);
252 if (soc_ac97_ops.warm_reset) 250 if (soc_ac97_ops->warm_reset)
253 soc_ac97_ops.warm_reset(codec->ac97); 251 soc_ac97_ops->warm_reset(codec->ac97);
254 if (stac9766_ac97_read(codec, 0) != stac9766_reg[0]) 252 if (stac9766_ac97_read(codec, 0) != stac9766_reg[0])
255 return -EIO; 253 return -EIO;
256 return 0; 254 return 0;
@@ -274,7 +272,7 @@ reset:
274 return -EIO; 272 return -EIO;
275 } 273 }
276 codec->ac97->bus->ops->warm_reset(codec->ac97); 274 codec->ac97->bus->ops->warm_reset(codec->ac97);
277 id = soc_ac97_ops.read(codec->ac97, AC97_VENDOR_ID2); 275 id = soc_ac97_ops->read(codec->ac97, AC97_VENDOR_ID2);
278 if (id != 0x4c13) { 276 if (id != 0x4c13) {
279 stac9766_reset(codec, 0); 277 stac9766_reset(codec, 0);
280 reset++; 278 reset++;
@@ -338,9 +336,7 @@ static int stac9766_codec_probe(struct snd_soc_codec *codec)
338{ 336{
339 int ret = 0; 337 int ret = 0;
340 338
341 printk(KERN_INFO "STAC9766 SoC Audio Codec %s\n", STAC9766_VERSION); 339 ret = snd_soc_new_ac97_codec(codec, soc_ac97_ops, 0);
342
343 ret = snd_soc_new_ac97_codec(codec, &soc_ac97_ops, 0);
344 if (ret < 0) 340 if (ret < 0)
345 goto codec_err; 341 goto codec_err;
346 342
diff --git a/sound/soc/codecs/tas5086.c b/sound/soc/codecs/tas5086.c
index d447c4aa1d5e..6d31d88f7204 100644
--- a/sound/soc/codecs/tas5086.c
+++ b/sound/soc/codecs/tas5086.c
@@ -83,6 +83,14 @@
83#define TAS5086_SPLIT_CAP_CHARGE 0x1a /* Split cap charge period register */ 83#define TAS5086_SPLIT_CAP_CHARGE 0x1a /* Split cap charge period register */
84#define TAS5086_OSC_TRIM 0x1b /* Oscillator trim register */ 84#define TAS5086_OSC_TRIM 0x1b /* Oscillator trim register */
85#define TAS5086_BKNDERR 0x1c 85#define TAS5086_BKNDERR 0x1c
86#define TAS5086_INPUT_MUX 0x20
87#define TAS5086_PWM_OUTPUT_MUX 0x25
88
89#define TAS5086_MAX_REGISTER TAS5086_PWM_OUTPUT_MUX
90
91#define TAS5086_PWM_START_MIDZ_FOR_START_1 (1 << 7)
92#define TAS5086_PWM_START_MIDZ_FOR_START_2 (1 << 6)
93#define TAS5086_PWM_START_CHANNEL_MASK (0x3f)
86 94
87/* 95/*
88 * Default TAS5086 power-up configuration 96 * Default TAS5086 power-up configuration
@@ -119,9 +127,30 @@ static const struct reg_default tas5086_reg_defaults[] = {
119 { 0x1c, 0x05 }, 127 { 0x1c, 0x05 },
120}; 128};
121 129
130static int tas5086_register_size(struct device *dev, unsigned int reg)
131{
132 switch (reg) {
133 case TAS5086_CLOCK_CONTROL ... TAS5086_BKNDERR:
134 return 1;
135 case TAS5086_INPUT_MUX:
136 case TAS5086_PWM_OUTPUT_MUX:
137 return 4;
138 }
139
140 dev_err(dev, "Unsupported register address: %d\n", reg);
141 return 0;
142}
143
122static bool tas5086_accessible_reg(struct device *dev, unsigned int reg) 144static bool tas5086_accessible_reg(struct device *dev, unsigned int reg)
123{ 145{
124 return !((reg == 0x0f) || (reg >= 0x11 && reg <= 0x17)); 146 switch (reg) {
147 case 0x0f:
148 case 0x11 ... 0x17:
149 case 0x1d ... 0x1f:
150 return false;
151 default:
152 return true;
153 }
125} 154}
126 155
127static bool tas5086_volatile_reg(struct device *dev, unsigned int reg) 156static bool tas5086_volatile_reg(struct device *dev, unsigned int reg)
@@ -140,6 +169,76 @@ static bool tas5086_writeable_reg(struct device *dev, unsigned int reg)
140 return tas5086_accessible_reg(dev, reg) && (reg != TAS5086_DEV_ID); 169 return tas5086_accessible_reg(dev, reg) && (reg != TAS5086_DEV_ID);
141} 170}
142 171
172static int tas5086_reg_write(void *context, unsigned int reg,
173 unsigned int value)
174{
175 struct i2c_client *client = context;
176 unsigned int i, size;
177 uint8_t buf[5];
178 int ret;
179
180 size = tas5086_register_size(&client->dev, reg);
181 if (size == 0)
182 return -EINVAL;
183
184 buf[0] = reg;
185
186 for (i = size; i >= 1; --i) {
187 buf[i] = value;
188 value >>= 8;
189 }
190
191 ret = i2c_master_send(client, buf, size + 1);
192 if (ret == size + 1)
193 return 0;
194 else if (ret < 0)
195 return ret;
196 else
197 return -EIO;
198}
199
200static int tas5086_reg_read(void *context, unsigned int reg,
201 unsigned int *value)
202{
203 struct i2c_client *client = context;
204 uint8_t send_buf, recv_buf[4];
205 struct i2c_msg msgs[2];
206 unsigned int size;
207 unsigned int i;
208 int ret;
209
210 size = tas5086_register_size(&client->dev, reg);
211 if (size == 0)
212 return -EINVAL;
213
214 send_buf = reg;
215
216 msgs[0].addr = client->addr;
217 msgs[0].len = sizeof(send_buf);
218 msgs[0].buf = &send_buf;
219 msgs[0].flags = 0;
220
221 msgs[1].addr = client->addr;
222 msgs[1].len = size;
223 msgs[1].buf = recv_buf;
224 msgs[1].flags = I2C_M_RD;
225
226 ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs));
227 if (ret < 0)
228 return ret;
229 else if (ret != ARRAY_SIZE(msgs))
230 return -EIO;
231
232 *value = 0;
233
234 for (i = 0; i < size; i++) {
235 *value <<= 8;
236 *value |= recv_buf[i];
237 }
238
239 return 0;
240}
241
143struct tas5086_private { 242struct tas5086_private {
144 struct regmap *regmap; 243 struct regmap *regmap;
145 unsigned int mclk, sclk; 244 unsigned int mclk, sclk;
@@ -376,6 +475,202 @@ static const struct snd_kcontrol_new tas5086_controls[] = {
376 tas5086_get_deemph, tas5086_put_deemph), 475 tas5086_get_deemph, tas5086_put_deemph),
377}; 476};
378 477
478/* Input mux controls */
479static const char *tas5086_dapm_sdin_texts[] =
480{
481 "SDIN1-L", "SDIN1-R", "SDIN2-L", "SDIN2-R",
482 "SDIN3-L", "SDIN3-R", "Ground (0)", "nc"
483};
484
485static const struct soc_enum tas5086_dapm_input_mux_enum[] = {
486 SOC_ENUM_SINGLE(TAS5086_INPUT_MUX, 20, 8, tas5086_dapm_sdin_texts),
487 SOC_ENUM_SINGLE(TAS5086_INPUT_MUX, 16, 8, tas5086_dapm_sdin_texts),
488 SOC_ENUM_SINGLE(TAS5086_INPUT_MUX, 12, 8, tas5086_dapm_sdin_texts),
489 SOC_ENUM_SINGLE(TAS5086_INPUT_MUX, 8, 8, tas5086_dapm_sdin_texts),
490 SOC_ENUM_SINGLE(TAS5086_INPUT_MUX, 4, 8, tas5086_dapm_sdin_texts),
491 SOC_ENUM_SINGLE(TAS5086_INPUT_MUX, 0, 8, tas5086_dapm_sdin_texts),
492};
493
494static const struct snd_kcontrol_new tas5086_dapm_input_mux_controls[] = {
495 SOC_DAPM_ENUM("Channel 1 input", tas5086_dapm_input_mux_enum[0]),
496 SOC_DAPM_ENUM("Channel 2 input", tas5086_dapm_input_mux_enum[1]),
497 SOC_DAPM_ENUM("Channel 3 input", tas5086_dapm_input_mux_enum[2]),
498 SOC_DAPM_ENUM("Channel 4 input", tas5086_dapm_input_mux_enum[3]),
499 SOC_DAPM_ENUM("Channel 5 input", tas5086_dapm_input_mux_enum[4]),
500 SOC_DAPM_ENUM("Channel 6 input", tas5086_dapm_input_mux_enum[5]),
501};
502
503/* Output mux controls */
504static const char *tas5086_dapm_channel_texts[] =
505 { "Channel 1 Mux", "Channel 2 Mux", "Channel 3 Mux",
506 "Channel 4 Mux", "Channel 5 Mux", "Channel 6 Mux" };
507
508static const struct soc_enum tas5086_dapm_output_mux_enum[] = {
509 SOC_ENUM_SINGLE(TAS5086_PWM_OUTPUT_MUX, 20, 6, tas5086_dapm_channel_texts),
510 SOC_ENUM_SINGLE(TAS5086_PWM_OUTPUT_MUX, 16, 6, tas5086_dapm_channel_texts),
511 SOC_ENUM_SINGLE(TAS5086_PWM_OUTPUT_MUX, 12, 6, tas5086_dapm_channel_texts),
512 SOC_ENUM_SINGLE(TAS5086_PWM_OUTPUT_MUX, 8, 6, tas5086_dapm_channel_texts),
513 SOC_ENUM_SINGLE(TAS5086_PWM_OUTPUT_MUX, 4, 6, tas5086_dapm_channel_texts),
514 SOC_ENUM_SINGLE(TAS5086_PWM_OUTPUT_MUX, 0, 6, tas5086_dapm_channel_texts),
515};
516
517static const struct snd_kcontrol_new tas5086_dapm_output_mux_controls[] = {
518 SOC_DAPM_ENUM("PWM1 Output", tas5086_dapm_output_mux_enum[0]),
519 SOC_DAPM_ENUM("PWM2 Output", tas5086_dapm_output_mux_enum[1]),
520 SOC_DAPM_ENUM("PWM3 Output", tas5086_dapm_output_mux_enum[2]),
521 SOC_DAPM_ENUM("PWM4 Output", tas5086_dapm_output_mux_enum[3]),
522 SOC_DAPM_ENUM("PWM5 Output", tas5086_dapm_output_mux_enum[4]),
523 SOC_DAPM_ENUM("PWM6 Output", tas5086_dapm_output_mux_enum[5]),
524};
525
526static const struct snd_soc_dapm_widget tas5086_dapm_widgets[] = {
527 SND_SOC_DAPM_INPUT("SDIN1-L"),
528 SND_SOC_DAPM_INPUT("SDIN1-R"),
529 SND_SOC_DAPM_INPUT("SDIN2-L"),
530 SND_SOC_DAPM_INPUT("SDIN2-R"),
531 SND_SOC_DAPM_INPUT("SDIN3-L"),
532 SND_SOC_DAPM_INPUT("SDIN3-R"),
533 SND_SOC_DAPM_INPUT("SDIN4-L"),
534 SND_SOC_DAPM_INPUT("SDIN4-R"),
535
536 SND_SOC_DAPM_OUTPUT("PWM1"),
537 SND_SOC_DAPM_OUTPUT("PWM2"),
538 SND_SOC_DAPM_OUTPUT("PWM3"),
539 SND_SOC_DAPM_OUTPUT("PWM4"),
540 SND_SOC_DAPM_OUTPUT("PWM5"),
541 SND_SOC_DAPM_OUTPUT("PWM6"),
542
543 SND_SOC_DAPM_MUX("Channel 1 Mux", SND_SOC_NOPM, 0, 0,
544 &tas5086_dapm_input_mux_controls[0]),
545 SND_SOC_DAPM_MUX("Channel 2 Mux", SND_SOC_NOPM, 0, 0,
546 &tas5086_dapm_input_mux_controls[1]),
547 SND_SOC_DAPM_MUX("Channel 3 Mux", SND_SOC_NOPM, 0, 0,
548 &tas5086_dapm_input_mux_controls[2]),
549 SND_SOC_DAPM_MUX("Channel 4 Mux", SND_SOC_NOPM, 0, 0,
550 &tas5086_dapm_input_mux_controls[3]),
551 SND_SOC_DAPM_MUX("Channel 5 Mux", SND_SOC_NOPM, 0, 0,
552 &tas5086_dapm_input_mux_controls[4]),
553 SND_SOC_DAPM_MUX("Channel 6 Mux", SND_SOC_NOPM, 0, 0,
554 &tas5086_dapm_input_mux_controls[5]),
555
556 SND_SOC_DAPM_MUX("PWM1 Mux", SND_SOC_NOPM, 0, 0,
557 &tas5086_dapm_output_mux_controls[0]),
558 SND_SOC_DAPM_MUX("PWM2 Mux", SND_SOC_NOPM, 0, 0,
559 &tas5086_dapm_output_mux_controls[1]),
560 SND_SOC_DAPM_MUX("PWM3 Mux", SND_SOC_NOPM, 0, 0,
561 &tas5086_dapm_output_mux_controls[2]),
562 SND_SOC_DAPM_MUX("PWM4 Mux", SND_SOC_NOPM, 0, 0,
563 &tas5086_dapm_output_mux_controls[3]),
564 SND_SOC_DAPM_MUX("PWM5 Mux", SND_SOC_NOPM, 0, 0,
565 &tas5086_dapm_output_mux_controls[4]),
566 SND_SOC_DAPM_MUX("PWM6 Mux", SND_SOC_NOPM, 0, 0,
567 &tas5086_dapm_output_mux_controls[5]),
568};
569
570static const struct snd_soc_dapm_route tas5086_dapm_routes[] = {
571 /* SDIN inputs -> channel muxes */
572 { "Channel 1 Mux", "SDIN1-L", "SDIN1-L" },
573 { "Channel 1 Mux", "SDIN1-R", "SDIN1-R" },
574 { "Channel 1 Mux", "SDIN2-L", "SDIN2-L" },
575 { "Channel 1 Mux", "SDIN2-R", "SDIN2-R" },
576 { "Channel 1 Mux", "SDIN3-L", "SDIN3-L" },
577 { "Channel 1 Mux", "SDIN3-R", "SDIN3-R" },
578
579 { "Channel 2 Mux", "SDIN1-L", "SDIN1-L" },
580 { "Channel 2 Mux", "SDIN1-R", "SDIN1-R" },
581 { "Channel 2 Mux", "SDIN2-L", "SDIN2-L" },
582 { "Channel 2 Mux", "SDIN2-R", "SDIN2-R" },
583 { "Channel 2 Mux", "SDIN3-L", "SDIN3-L" },
584 { "Channel 2 Mux", "SDIN3-R", "SDIN3-R" },
585
586 { "Channel 2 Mux", "SDIN1-L", "SDIN1-L" },
587 { "Channel 2 Mux", "SDIN1-R", "SDIN1-R" },
588 { "Channel 2 Mux", "SDIN2-L", "SDIN2-L" },
589 { "Channel 2 Mux", "SDIN2-R", "SDIN2-R" },
590 { "Channel 2 Mux", "SDIN3-L", "SDIN3-L" },
591 { "Channel 2 Mux", "SDIN3-R", "SDIN3-R" },
592
593 { "Channel 3 Mux", "SDIN1-L", "SDIN1-L" },
594 { "Channel 3 Mux", "SDIN1-R", "SDIN1-R" },
595 { "Channel 3 Mux", "SDIN2-L", "SDIN2-L" },
596 { "Channel 3 Mux", "SDIN2-R", "SDIN2-R" },
597 { "Channel 3 Mux", "SDIN3-L", "SDIN3-L" },
598 { "Channel 3 Mux", "SDIN3-R", "SDIN3-R" },
599
600 { "Channel 4 Mux", "SDIN1-L", "SDIN1-L" },
601 { "Channel 4 Mux", "SDIN1-R", "SDIN1-R" },
602 { "Channel 4 Mux", "SDIN2-L", "SDIN2-L" },
603 { "Channel 4 Mux", "SDIN2-R", "SDIN2-R" },
604 { "Channel 4 Mux", "SDIN3-L", "SDIN3-L" },
605 { "Channel 4 Mux", "SDIN3-R", "SDIN3-R" },
606
607 { "Channel 5 Mux", "SDIN1-L", "SDIN1-L" },
608 { "Channel 5 Mux", "SDIN1-R", "SDIN1-R" },
609 { "Channel 5 Mux", "SDIN2-L", "SDIN2-L" },
610 { "Channel 5 Mux", "SDIN2-R", "SDIN2-R" },
611 { "Channel 5 Mux", "SDIN3-L", "SDIN3-L" },
612 { "Channel 5 Mux", "SDIN3-R", "SDIN3-R" },
613
614 { "Channel 6 Mux", "SDIN1-L", "SDIN1-L" },
615 { "Channel 6 Mux", "SDIN1-R", "SDIN1-R" },
616 { "Channel 6 Mux", "SDIN2-L", "SDIN2-L" },
617 { "Channel 6 Mux", "SDIN2-R", "SDIN2-R" },
618 { "Channel 6 Mux", "SDIN3-L", "SDIN3-L" },
619 { "Channel 6 Mux", "SDIN3-R", "SDIN3-R" },
620
621 /* Channel muxes -> PWM muxes */
622 { "PWM1 Mux", "Channel 1 Mux", "Channel 1 Mux" },
623 { "PWM2 Mux", "Channel 1 Mux", "Channel 1 Mux" },
624 { "PWM3 Mux", "Channel 1 Mux", "Channel 1 Mux" },
625 { "PWM4 Mux", "Channel 1 Mux", "Channel 1 Mux" },
626 { "PWM5 Mux", "Channel 1 Mux", "Channel 1 Mux" },
627 { "PWM6 Mux", "Channel 1 Mux", "Channel 1 Mux" },
628
629 { "PWM1 Mux", "Channel 2 Mux", "Channel 2 Mux" },
630 { "PWM2 Mux", "Channel 2 Mux", "Channel 2 Mux" },
631 { "PWM3 Mux", "Channel 2 Mux", "Channel 2 Mux" },
632 { "PWM4 Mux", "Channel 2 Mux", "Channel 2 Mux" },
633 { "PWM5 Mux", "Channel 2 Mux", "Channel 2 Mux" },
634 { "PWM6 Mux", "Channel 2 Mux", "Channel 2 Mux" },
635
636 { "PWM1 Mux", "Channel 3 Mux", "Channel 3 Mux" },
637 { "PWM2 Mux", "Channel 3 Mux", "Channel 3 Mux" },
638 { "PWM3 Mux", "Channel 3 Mux", "Channel 3 Mux" },
639 { "PWM4 Mux", "Channel 3 Mux", "Channel 3 Mux" },
640 { "PWM5 Mux", "Channel 3 Mux", "Channel 3 Mux" },
641 { "PWM6 Mux", "Channel 3 Mux", "Channel 3 Mux" },
642
643 { "PWM1 Mux", "Channel 4 Mux", "Channel 4 Mux" },
644 { "PWM2 Mux", "Channel 4 Mux", "Channel 4 Mux" },
645 { "PWM3 Mux", "Channel 4 Mux", "Channel 4 Mux" },
646 { "PWM4 Mux", "Channel 4 Mux", "Channel 4 Mux" },
647 { "PWM5 Mux", "Channel 4 Mux", "Channel 4 Mux" },
648 { "PWM6 Mux", "Channel 4 Mux", "Channel 4 Mux" },
649
650 { "PWM1 Mux", "Channel 5 Mux", "Channel 5 Mux" },
651 { "PWM2 Mux", "Channel 5 Mux", "Channel 5 Mux" },
652 { "PWM3 Mux", "Channel 5 Mux", "Channel 5 Mux" },
653 { "PWM4 Mux", "Channel 5 Mux", "Channel 5 Mux" },
654 { "PWM5 Mux", "Channel 5 Mux", "Channel 5 Mux" },
655 { "PWM6 Mux", "Channel 5 Mux", "Channel 5 Mux" },
656
657 { "PWM1 Mux", "Channel 6 Mux", "Channel 6 Mux" },
658 { "PWM2 Mux", "Channel 6 Mux", "Channel 6 Mux" },
659 { "PWM3 Mux", "Channel 6 Mux", "Channel 6 Mux" },
660 { "PWM4 Mux", "Channel 6 Mux", "Channel 6 Mux" },
661 { "PWM5 Mux", "Channel 6 Mux", "Channel 6 Mux" },
662 { "PWM6 Mux", "Channel 6 Mux", "Channel 6 Mux" },
663
664 /* The PWM muxes are directly connected to the PWM outputs */
665 { "PWM1", NULL, "PWM1 Mux" },
666 { "PWM2", NULL, "PWM2 Mux" },
667 { "PWM3", NULL, "PWM3 Mux" },
668 { "PWM4", NULL, "PWM4 Mux" },
669 { "PWM5", NULL, "PWM5 Mux" },
670 { "PWM6", NULL, "PWM6 Mux" },
671
672};
673
379static const struct snd_soc_dai_ops tas5086_dai_ops = { 674static const struct snd_soc_dai_ops tas5086_dai_ops = {
380 .hw_params = tas5086_hw_params, 675 .hw_params = tas5086_hw_params,
381 .set_sysclk = tas5086_set_dai_sysclk, 676 .set_sysclk = tas5086_set_dai_sysclk,
@@ -426,13 +721,34 @@ static int tas5086_probe(struct snd_soc_codec *codec)
426{ 721{
427 struct tas5086_private *priv = snd_soc_codec_get_drvdata(codec); 722 struct tas5086_private *priv = snd_soc_codec_get_drvdata(codec);
428 int charge_period = 1300000; /* hardware default is 1300 ms */ 723 int charge_period = 1300000; /* hardware default is 1300 ms */
724 u8 pwm_start_mid_z = 0;
429 int i, ret; 725 int i, ret;
430 726
431 if (of_match_device(of_match_ptr(tas5086_dt_ids), codec->dev)) { 727 if (of_match_device(of_match_ptr(tas5086_dt_ids), codec->dev)) {
432 struct device_node *of_node = codec->dev->of_node; 728 struct device_node *of_node = codec->dev->of_node;
433 of_property_read_u32(of_node, "ti,charge-period", &charge_period); 729 of_property_read_u32(of_node, "ti,charge-period", &charge_period);
730
731 for (i = 0; i < 6; i++) {
732 char name[25];
733
734 snprintf(name, sizeof(name),
735 "ti,mid-z-channel-%d", i + 1);
736
737 if (of_get_property(of_node, name, NULL) != NULL)
738 pwm_start_mid_z |= 1 << i;
739 }
434 } 740 }
435 741
742 /*
743 * If any of the channels is configured to start in Mid-Z mode,
744 * configure 'part 1' of the PWM starts to use Mid-Z, and tell
745 * all configured mid-z channels to start start under 'part 1'.
746 */
747 if (pwm_start_mid_z)
748 regmap_write(priv->regmap, TAS5086_PWM_START,
749 TAS5086_PWM_START_MIDZ_FOR_START_1 |
750 pwm_start_mid_z);
751
436 /* lookup and set split-capacitor charge period */ 752 /* lookup and set split-capacitor charge period */
437 if (charge_period == 0) { 753 if (charge_period == 0) {
438 regmap_write(priv->regmap, TAS5086_SPLIT_CAP_CHARGE, 0); 754 regmap_write(priv->regmap, TAS5086_SPLIT_CAP_CHARGE, 0);
@@ -490,6 +806,10 @@ static struct snd_soc_codec_driver soc_codec_dev_tas5086 = {
490 .resume = tas5086_soc_resume, 806 .resume = tas5086_soc_resume,
491 .controls = tas5086_controls, 807 .controls = tas5086_controls,
492 .num_controls = ARRAY_SIZE(tas5086_controls), 808 .num_controls = ARRAY_SIZE(tas5086_controls),
809 .dapm_widgets = tas5086_dapm_widgets,
810 .num_dapm_widgets = ARRAY_SIZE(tas5086_dapm_widgets),
811 .dapm_routes = tas5086_dapm_routes,
812 .num_dapm_routes = ARRAY_SIZE(tas5086_dapm_routes),
493}; 813};
494 814
495static const struct i2c_device_id tas5086_i2c_id[] = { 815static const struct i2c_device_id tas5086_i2c_id[] = {
@@ -500,14 +820,16 @@ MODULE_DEVICE_TABLE(i2c, tas5086_i2c_id);
500 820
501static const struct regmap_config tas5086_regmap = { 821static const struct regmap_config tas5086_regmap = {
502 .reg_bits = 8, 822 .reg_bits = 8,
503 .val_bits = 8, 823 .val_bits = 32,
504 .max_register = ARRAY_SIZE(tas5086_reg_defaults), 824 .max_register = TAS5086_MAX_REGISTER,
505 .reg_defaults = tas5086_reg_defaults, 825 .reg_defaults = tas5086_reg_defaults,
506 .num_reg_defaults = ARRAY_SIZE(tas5086_reg_defaults), 826 .num_reg_defaults = ARRAY_SIZE(tas5086_reg_defaults),
507 .cache_type = REGCACHE_RBTREE, 827 .cache_type = REGCACHE_RBTREE,
508 .volatile_reg = tas5086_volatile_reg, 828 .volatile_reg = tas5086_volatile_reg,
509 .writeable_reg = tas5086_writeable_reg, 829 .writeable_reg = tas5086_writeable_reg,
510 .readable_reg = tas5086_accessible_reg, 830 .readable_reg = tas5086_accessible_reg,
831 .reg_read = tas5086_reg_read,
832 .reg_write = tas5086_reg_write,
511}; 833};
512 834
513static int tas5086_i2c_probe(struct i2c_client *i2c, 835static int tas5086_i2c_probe(struct i2c_client *i2c,
@@ -522,7 +844,7 @@ static int tas5086_i2c_probe(struct i2c_client *i2c,
522 if (!priv) 844 if (!priv)
523 return -ENOMEM; 845 return -ENOMEM;
524 846
525 priv->regmap = devm_regmap_init_i2c(i2c, &tas5086_regmap); 847 priv->regmap = devm_regmap_init(dev, NULL, i2c, &tas5086_regmap);
526 if (IS_ERR(priv->regmap)) { 848 if (IS_ERR(priv->regmap)) {
527 ret = PTR_ERR(priv->regmap); 849 ret = PTR_ERR(priv->regmap);
528 dev_err(&i2c->dev, "Failed to create regmap: %d\n", ret); 850 dev_err(&i2c->dev, "Failed to create regmap: %d\n", ret);
diff --git a/sound/soc/codecs/tlv320aic3x.c b/sound/soc/codecs/tlv320aic3x.c
index 1514bf845e4b..e5b926883131 100644
--- a/sound/soc/codecs/tlv320aic3x.c
+++ b/sound/soc/codecs/tlv320aic3x.c
@@ -128,10 +128,8 @@ static const u8 aic3x_reg[AIC3X_CACHEREGNUM] = {
128}; 128};
129 129
130#define SOC_DAPM_SINGLE_AIC3X(xname, reg, shift, mask, invert) \ 130#define SOC_DAPM_SINGLE_AIC3X(xname, reg, shift, mask, invert) \
131{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \ 131 SOC_SINGLE_EXT(xname, reg, shift, mask, invert, \
132 .info = snd_soc_info_volsw, \ 132 snd_soc_dapm_get_volsw, snd_soc_dapm_put_volsw_aic3x)
133 .get = snd_soc_dapm_get_volsw, .put = snd_soc_dapm_put_volsw_aic3x, \
134 .private_value = SOC_SINGLE_VALUE(reg, shift, mask, invert) }
135 133
136/* 134/*
137 * All input lines are connected when !0xf and disconnected with 0xf bit field, 135 * All input lines are connected when !0xf and disconnected with 0xf bit field,
diff --git a/sound/soc/codecs/twl6040.c b/sound/soc/codecs/twl6040.c
index 9b9a6e587610..44621ddc332d 100644
--- a/sound/soc/codecs/twl6040.c
+++ b/sound/soc/codecs/twl6040.c
@@ -38,6 +38,14 @@
38 38
39#include "twl6040.h" 39#include "twl6040.h"
40 40
41enum twl6040_dai_id {
42 TWL6040_DAI_LEGACY = 0,
43 TWL6040_DAI_UL,
44 TWL6040_DAI_DL1,
45 TWL6040_DAI_DL2,
46 TWL6040_DAI_VIB,
47};
48
41#define TWL6040_RATES SNDRV_PCM_RATE_8000_96000 49#define TWL6040_RATES SNDRV_PCM_RATE_8000_96000
42#define TWL6040_FORMATS (SNDRV_PCM_FMTBIT_S32_LE) 50#define TWL6040_FORMATS (SNDRV_PCM_FMTBIT_S32_LE)
43 51
@@ -67,6 +75,8 @@ struct twl6040_data {
67 int pll_power_mode; 75 int pll_power_mode;
68 int hs_power_mode; 76 int hs_power_mode;
69 int hs_power_mode_locked; 77 int hs_power_mode_locked;
78 bool dl1_unmuted;
79 bool dl2_unmuted;
70 unsigned int clk_in; 80 unsigned int clk_in;
71 unsigned int sysclk; 81 unsigned int sysclk;
72 struct twl6040_jack_data hs_jack; 82 struct twl6040_jack_data hs_jack;
@@ -220,6 +230,25 @@ static int twl6040_read_reg_volatile(struct snd_soc_codec *codec,
220 return value; 230 return value;
221} 231}
222 232
233static bool twl6040_is_path_unmuted(struct snd_soc_codec *codec,
234 unsigned int reg)
235{
236 struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec);
237
238 switch (reg) {
239 case TWL6040_REG_HSLCTL:
240 case TWL6040_REG_HSRCTL:
241 case TWL6040_REG_EARCTL:
242 /* DL1 path */
243 return priv->dl1_unmuted;
244 case TWL6040_REG_HFLCTL:
245 case TWL6040_REG_HFRCTL:
246 return priv->dl2_unmuted;
247 default:
248 return 1;
249 };
250}
251
223/* 252/*
224 * write to the twl6040 register space 253 * write to the twl6040 register space
225 */ 254 */
@@ -232,7 +261,8 @@ static int twl6040_write(struct snd_soc_codec *codec,
232 return -EIO; 261 return -EIO;
233 262
234 twl6040_write_reg_cache(codec, reg, value); 263 twl6040_write_reg_cache(codec, reg, value);
235 if (likely(reg < TWL6040_REG_SW_SHADOW)) 264 if (likely(reg < TWL6040_REG_SW_SHADOW) &&
265 twl6040_is_path_unmuted(codec, reg))
236 return twl6040_reg_write(twl6040, reg, value); 266 return twl6040_reg_write(twl6040, reg, value);
237 else 267 else
238 return 0; 268 return 0;
@@ -1026,16 +1056,84 @@ static int twl6040_set_dai_sysclk(struct snd_soc_dai *codec_dai,
1026 return 0; 1056 return 0;
1027} 1057}
1028 1058
1059static void twl6040_mute_path(struct snd_soc_codec *codec, enum twl6040_dai_id id,
1060 int mute)
1061{
1062 struct twl6040 *twl6040 = codec->control_data;
1063 struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec);
1064 int hslctl, hsrctl, earctl;
1065 int hflctl, hfrctl;
1066
1067 switch (id) {
1068 case TWL6040_DAI_DL1:
1069 hslctl = twl6040_read_reg_cache(codec, TWL6040_REG_HSLCTL);
1070 hsrctl = twl6040_read_reg_cache(codec, TWL6040_REG_HSRCTL);
1071 earctl = twl6040_read_reg_cache(codec, TWL6040_REG_EARCTL);
1072
1073 if (mute) {
1074 /* Power down drivers and DACs */
1075 earctl &= ~0x01;
1076 hslctl &= ~(TWL6040_HSDRVENA | TWL6040_HSDACENA);
1077 hsrctl &= ~(TWL6040_HSDRVENA | TWL6040_HSDACENA);
1078
1079 }
1080
1081 twl6040_reg_write(twl6040, TWL6040_REG_EARCTL, earctl);
1082 twl6040_reg_write(twl6040, TWL6040_REG_HSLCTL, hslctl);
1083 twl6040_reg_write(twl6040, TWL6040_REG_HSRCTL, hsrctl);
1084 priv->dl1_unmuted = !mute;
1085 break;
1086 case TWL6040_DAI_DL2:
1087 hflctl = twl6040_read_reg_cache(codec, TWL6040_REG_HFLCTL);
1088 hfrctl = twl6040_read_reg_cache(codec, TWL6040_REG_HFRCTL);
1089
1090 if (mute) {
1091 /* Power down drivers and DACs */
1092 hflctl &= ~(TWL6040_HFDACENA | TWL6040_HFPGAENA |
1093 TWL6040_HFDRVENA);
1094 hfrctl &= ~(TWL6040_HFDACENA | TWL6040_HFPGAENA |
1095 TWL6040_HFDRVENA);
1096 }
1097
1098 twl6040_reg_write(twl6040, TWL6040_REG_HFLCTL, hflctl);
1099 twl6040_reg_write(twl6040, TWL6040_REG_HFRCTL, hfrctl);
1100 priv->dl2_unmuted = !mute;
1101 break;
1102 default:
1103 break;
1104 };
1105}
1106
1107static int twl6040_digital_mute(struct snd_soc_dai *dai, int mute)
1108{
1109 switch (dai->id) {
1110 case TWL6040_DAI_LEGACY:
1111 twl6040_mute_path(dai->codec, TWL6040_DAI_DL1, mute);
1112 twl6040_mute_path(dai->codec, TWL6040_DAI_DL2, mute);
1113 break;
1114 case TWL6040_DAI_DL1:
1115 case TWL6040_DAI_DL2:
1116 twl6040_mute_path(dai->codec, dai->id, mute);
1117 break;
1118 default:
1119 break;
1120 }
1121
1122 return 0;
1123}
1124
1029static const struct snd_soc_dai_ops twl6040_dai_ops = { 1125static const struct snd_soc_dai_ops twl6040_dai_ops = {
1030 .startup = twl6040_startup, 1126 .startup = twl6040_startup,
1031 .hw_params = twl6040_hw_params, 1127 .hw_params = twl6040_hw_params,
1032 .prepare = twl6040_prepare, 1128 .prepare = twl6040_prepare,
1033 .set_sysclk = twl6040_set_dai_sysclk, 1129 .set_sysclk = twl6040_set_dai_sysclk,
1130 .digital_mute = twl6040_digital_mute,
1034}; 1131};
1035 1132
1036static struct snd_soc_dai_driver twl6040_dai[] = { 1133static struct snd_soc_dai_driver twl6040_dai[] = {
1037{ 1134{
1038 .name = "twl6040-legacy", 1135 .name = "twl6040-legacy",
1136 .id = TWL6040_DAI_LEGACY,
1039 .playback = { 1137 .playback = {
1040 .stream_name = "Legacy Playback", 1138 .stream_name = "Legacy Playback",
1041 .channels_min = 1, 1139 .channels_min = 1,
@@ -1054,6 +1152,7 @@ static struct snd_soc_dai_driver twl6040_dai[] = {
1054}, 1152},
1055{ 1153{
1056 .name = "twl6040-ul", 1154 .name = "twl6040-ul",
1155 .id = TWL6040_DAI_UL,
1057 .capture = { 1156 .capture = {
1058 .stream_name = "Capture", 1157 .stream_name = "Capture",
1059 .channels_min = 1, 1158 .channels_min = 1,
@@ -1065,6 +1164,7 @@ static struct snd_soc_dai_driver twl6040_dai[] = {
1065}, 1164},
1066{ 1165{
1067 .name = "twl6040-dl1", 1166 .name = "twl6040-dl1",
1167 .id = TWL6040_DAI_DL1,
1068 .playback = { 1168 .playback = {
1069 .stream_name = "Headset Playback", 1169 .stream_name = "Headset Playback",
1070 .channels_min = 1, 1170 .channels_min = 1,
@@ -1076,6 +1176,7 @@ static struct snd_soc_dai_driver twl6040_dai[] = {
1076}, 1176},
1077{ 1177{
1078 .name = "twl6040-dl2", 1178 .name = "twl6040-dl2",
1179 .id = TWL6040_DAI_DL2,
1079 .playback = { 1180 .playback = {
1080 .stream_name = "Handsfree Playback", 1181 .stream_name = "Handsfree Playback",
1081 .channels_min = 1, 1182 .channels_min = 1,
@@ -1087,6 +1188,7 @@ static struct snd_soc_dai_driver twl6040_dai[] = {
1087}, 1188},
1088{ 1189{
1089 .name = "twl6040-vib", 1190 .name = "twl6040-vib",
1191 .id = TWL6040_DAI_VIB,
1090 .playback = { 1192 .playback = {
1091 .stream_name = "Vibra Playback", 1193 .stream_name = "Vibra Playback",
1092 .channels_min = 1, 1194 .channels_min = 1,
@@ -1143,7 +1245,7 @@ static int twl6040_probe(struct snd_soc_codec *codec)
1143 1245
1144 mutex_init(&priv->mutex); 1246 mutex_init(&priv->mutex);
1145 1247
1146 ret = devm_request_threaded_irq(codec->dev, priv->plug_irq, NULL, 1248 ret = request_threaded_irq(priv->plug_irq, NULL,
1147 twl6040_audio_handler, IRQF_NO_SUSPEND, 1249 twl6040_audio_handler, IRQF_NO_SUSPEND,
1148 "twl6040_irq_plug", codec); 1250 "twl6040_irq_plug", codec);
1149 if (ret) { 1251 if (ret) {
@@ -1159,6 +1261,9 @@ static int twl6040_probe(struct snd_soc_codec *codec)
1159 1261
1160static int twl6040_remove(struct snd_soc_codec *codec) 1262static int twl6040_remove(struct snd_soc_codec *codec)
1161{ 1263{
1264 struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec);
1265
1266 free_irq(priv->plug_irq, codec);
1162 twl6040_set_bias_level(codec, SND_SOC_BIAS_OFF); 1267 twl6040_set_bias_level(codec, SND_SOC_BIAS_OFF);
1163 1268
1164 return 0; 1269 return 0;
diff --git a/sound/soc/codecs/wm0010.c b/sound/soc/codecs/wm0010.c
index 370af0cbcc9a..f5e835662cdc 100644
--- a/sound/soc/codecs/wm0010.c
+++ b/sound/soc/codecs/wm0010.c
@@ -14,6 +14,7 @@
14 14
15#include <linux/module.h> 15#include <linux/module.h>
16#include <linux/moduleparam.h> 16#include <linux/moduleparam.h>
17#include <linux/interrupt.h>
17#include <linux/irqreturn.h> 18#include <linux/irqreturn.h>
18#include <linux/init.h> 19#include <linux/init.h>
19#include <linux/spi/spi.h> 20#include <linux/spi/spi.h>
@@ -972,6 +973,13 @@ static int wm0010_spi_probe(struct spi_device *spi)
972 } 973 }
973 wm0010->irq = irq; 974 wm0010->irq = irq;
974 975
976 ret = irq_set_irq_wake(irq, 1);
977 if (ret) {
978 dev_err(wm0010->dev, "Failed to set IRQ %d as wake source: %d\n",
979 irq, ret);
980 return ret;
981 }
982
975 if (spi->max_speed_hz) 983 if (spi->max_speed_hz)
976 wm0010->board_max_spi_speed = spi->max_speed_hz; 984 wm0010->board_max_spi_speed = spi->max_speed_hz;
977 else 985 else
@@ -995,6 +1003,8 @@ static int wm0010_spi_remove(struct spi_device *spi)
995 gpio_set_value_cansleep(wm0010->gpio_reset, 1003 gpio_set_value_cansleep(wm0010->gpio_reset,
996 wm0010->gpio_reset_value); 1004 wm0010->gpio_reset_value);
997 1005
1006 irq_set_irq_wake(wm0010->irq, 0);
1007
998 if (wm0010->irq) 1008 if (wm0010->irq)
999 free_irq(wm0010->irq, wm0010); 1009 free_irq(wm0010->irq, wm0010);
1000 1010
diff --git a/sound/soc/codecs/wm5102.c b/sound/soc/codecs/wm5102.c
index 100fdadda56a..282fd232cdf7 100644
--- a/sound/soc/codecs/wm5102.c
+++ b/sound/soc/codecs/wm5102.c
@@ -814,7 +814,20 @@ SOC_DOUBLE_R_TLV("SPKDAT1 Digital Volume", ARIZONA_DAC_DIGITAL_VOLUME_5L,
814 814
815SOC_VALUE_ENUM("HPOUT1 OSR", wm5102_hpout_osr[0]), 815SOC_VALUE_ENUM("HPOUT1 OSR", wm5102_hpout_osr[0]),
816SOC_VALUE_ENUM("HPOUT2 OSR", wm5102_hpout_osr[1]), 816SOC_VALUE_ENUM("HPOUT2 OSR", wm5102_hpout_osr[1]),
817SOC_VALUE_ENUM("HPOUT3 OSR", wm5102_hpout_osr[2]), 817SOC_VALUE_ENUM("EPOUT OSR", wm5102_hpout_osr[2]),
818
819SOC_DOUBLE("HPOUT1 DRE Switch", ARIZONA_DRE_ENABLE,
820 ARIZONA_DRE1L_ENA_SHIFT, ARIZONA_DRE1R_ENA_SHIFT, 1, 0),
821SOC_DOUBLE("HPOUT2 DRE Switch", ARIZONA_DRE_ENABLE,
822 ARIZONA_DRE2L_ENA_SHIFT, ARIZONA_DRE2R_ENA_SHIFT, 1, 0),
823SOC_SINGLE("EPOUT DRE Switch", ARIZONA_DRE_ENABLE,
824 ARIZONA_DRE3L_ENA_SHIFT, 1, 0),
825
826SOC_SINGLE("DRE Threshold", ARIZONA_DRE_CONTROL_2,
827 ARIZONA_DRE_T_LOW_SHIFT, 63, 0),
828
829SOC_SINGLE("DRE Low Level ABS", ARIZONA_DRE_CONTROL_3,
830 ARIZONA_DRE_LOW_LEVEL_ABS_SHIFT, 15, 0),
818 831
819SOC_ENUM("Output Ramp Up", arizona_out_vi_ramp), 832SOC_ENUM("Output Ramp Up", arizona_out_vi_ramp),
820SOC_ENUM("Output Ramp Down", arizona_out_vd_ramp), 833SOC_ENUM("Output Ramp Down", arizona_out_vd_ramp),
@@ -852,6 +865,15 @@ ARIZONA_MIXER_CONTROLS("AIF2TX2", ARIZONA_AIF2TX2MIX_INPUT_1_SOURCE),
852 865
853ARIZONA_MIXER_CONTROLS("AIF3TX1", ARIZONA_AIF3TX1MIX_INPUT_1_SOURCE), 866ARIZONA_MIXER_CONTROLS("AIF3TX1", ARIZONA_AIF3TX1MIX_INPUT_1_SOURCE),
854ARIZONA_MIXER_CONTROLS("AIF3TX2", ARIZONA_AIF3TX2MIX_INPUT_1_SOURCE), 867ARIZONA_MIXER_CONTROLS("AIF3TX2", ARIZONA_AIF3TX2MIX_INPUT_1_SOURCE),
868
869ARIZONA_MIXER_CONTROLS("SLIMTX1", ARIZONA_SLIMTX1MIX_INPUT_1_SOURCE),
870ARIZONA_MIXER_CONTROLS("SLIMTX2", ARIZONA_SLIMTX2MIX_INPUT_1_SOURCE),
871ARIZONA_MIXER_CONTROLS("SLIMTX3", ARIZONA_SLIMTX3MIX_INPUT_1_SOURCE),
872ARIZONA_MIXER_CONTROLS("SLIMTX4", ARIZONA_SLIMTX4MIX_INPUT_1_SOURCE),
873ARIZONA_MIXER_CONTROLS("SLIMTX5", ARIZONA_SLIMTX5MIX_INPUT_1_SOURCE),
874ARIZONA_MIXER_CONTROLS("SLIMTX6", ARIZONA_SLIMTX6MIX_INPUT_1_SOURCE),
875ARIZONA_MIXER_CONTROLS("SLIMTX7", ARIZONA_SLIMTX7MIX_INPUT_1_SOURCE),
876ARIZONA_MIXER_CONTROLS("SLIMTX8", ARIZONA_SLIMTX8MIX_INPUT_1_SOURCE),
855}; 877};
856 878
857ARIZONA_MIXER_ENUMS(EQ1, ARIZONA_EQ1MIX_INPUT_1_SOURCE); 879ARIZONA_MIXER_ENUMS(EQ1, ARIZONA_EQ1MIX_INPUT_1_SOURCE);
@@ -898,6 +920,15 @@ ARIZONA_MIXER_ENUMS(AIF2TX2, ARIZONA_AIF2TX2MIX_INPUT_1_SOURCE);
898ARIZONA_MIXER_ENUMS(AIF3TX1, ARIZONA_AIF3TX1MIX_INPUT_1_SOURCE); 920ARIZONA_MIXER_ENUMS(AIF3TX1, ARIZONA_AIF3TX1MIX_INPUT_1_SOURCE);
899ARIZONA_MIXER_ENUMS(AIF3TX2, ARIZONA_AIF3TX2MIX_INPUT_1_SOURCE); 921ARIZONA_MIXER_ENUMS(AIF3TX2, ARIZONA_AIF3TX2MIX_INPUT_1_SOURCE);
900 922
923ARIZONA_MIXER_ENUMS(SLIMTX1, ARIZONA_SLIMTX1MIX_INPUT_1_SOURCE);
924ARIZONA_MIXER_ENUMS(SLIMTX2, ARIZONA_SLIMTX2MIX_INPUT_1_SOURCE);
925ARIZONA_MIXER_ENUMS(SLIMTX3, ARIZONA_SLIMTX3MIX_INPUT_1_SOURCE);
926ARIZONA_MIXER_ENUMS(SLIMTX4, ARIZONA_SLIMTX4MIX_INPUT_1_SOURCE);
927ARIZONA_MIXER_ENUMS(SLIMTX5, ARIZONA_SLIMTX5MIX_INPUT_1_SOURCE);
928ARIZONA_MIXER_ENUMS(SLIMTX6, ARIZONA_SLIMTX6MIX_INPUT_1_SOURCE);
929ARIZONA_MIXER_ENUMS(SLIMTX7, ARIZONA_SLIMTX7MIX_INPUT_1_SOURCE);
930ARIZONA_MIXER_ENUMS(SLIMTX8, ARIZONA_SLIMTX8MIX_INPUT_1_SOURCE);
931
901ARIZONA_MUX_ENUMS(ASRC1L, ARIZONA_ASRC1LMIX_INPUT_1_SOURCE); 932ARIZONA_MUX_ENUMS(ASRC1L, ARIZONA_ASRC1LMIX_INPUT_1_SOURCE);
902ARIZONA_MUX_ENUMS(ASRC1R, ARIZONA_ASRC1RMIX_INPUT_1_SOURCE); 933ARIZONA_MUX_ENUMS(ASRC1R, ARIZONA_ASRC1RMIX_INPUT_1_SOURCE);
903ARIZONA_MUX_ENUMS(ASRC2L, ARIZONA_ASRC2LMIX_INPUT_1_SOURCE); 934ARIZONA_MUX_ENUMS(ASRC2L, ARIZONA_ASRC2LMIX_INPUT_1_SOURCE);
@@ -1117,6 +1148,56 @@ SND_SOC_DAPM_AIF_IN("AIF3RX1", NULL, 0,
1117SND_SOC_DAPM_AIF_IN("AIF3RX2", NULL, 0, 1148SND_SOC_DAPM_AIF_IN("AIF3RX2", NULL, 0,
1118 ARIZONA_AIF3_RX_ENABLES, ARIZONA_AIF3RX2_ENA_SHIFT, 0), 1149 ARIZONA_AIF3_RX_ENABLES, ARIZONA_AIF3RX2_ENA_SHIFT, 0),
1119 1150
1151SND_SOC_DAPM_AIF_OUT("SLIMTX1", NULL, 0,
1152 ARIZONA_SLIMBUS_TX_CHANNEL_ENABLE,
1153 ARIZONA_SLIMTX1_ENA_SHIFT, 0),
1154SND_SOC_DAPM_AIF_OUT("SLIMTX2", NULL, 0,
1155 ARIZONA_SLIMBUS_TX_CHANNEL_ENABLE,
1156 ARIZONA_SLIMTX2_ENA_SHIFT, 0),
1157SND_SOC_DAPM_AIF_OUT("SLIMTX3", NULL, 0,
1158 ARIZONA_SLIMBUS_TX_CHANNEL_ENABLE,
1159 ARIZONA_SLIMTX3_ENA_SHIFT, 0),
1160SND_SOC_DAPM_AIF_OUT("SLIMTX4", NULL, 0,
1161 ARIZONA_SLIMBUS_TX_CHANNEL_ENABLE,
1162 ARIZONA_SLIMTX4_ENA_SHIFT, 0),
1163SND_SOC_DAPM_AIF_OUT("SLIMTX5", NULL, 0,
1164 ARIZONA_SLIMBUS_TX_CHANNEL_ENABLE,
1165 ARIZONA_SLIMTX5_ENA_SHIFT, 0),
1166SND_SOC_DAPM_AIF_OUT("SLIMTX6", NULL, 0,
1167 ARIZONA_SLIMBUS_TX_CHANNEL_ENABLE,
1168 ARIZONA_SLIMTX6_ENA_SHIFT, 0),
1169SND_SOC_DAPM_AIF_OUT("SLIMTX7", NULL, 0,
1170 ARIZONA_SLIMBUS_TX_CHANNEL_ENABLE,
1171 ARIZONA_SLIMTX7_ENA_SHIFT, 0),
1172SND_SOC_DAPM_AIF_OUT("SLIMTX8", NULL, 0,
1173 ARIZONA_SLIMBUS_TX_CHANNEL_ENABLE,
1174 ARIZONA_SLIMTX8_ENA_SHIFT, 0),
1175
1176SND_SOC_DAPM_AIF_IN("SLIMRX1", NULL, 0,
1177 ARIZONA_SLIMBUS_RX_CHANNEL_ENABLE,
1178 ARIZONA_SLIMRX1_ENA_SHIFT, 0),
1179SND_SOC_DAPM_AIF_IN("SLIMRX2", NULL, 0,
1180 ARIZONA_SLIMBUS_RX_CHANNEL_ENABLE,
1181 ARIZONA_SLIMRX2_ENA_SHIFT, 0),
1182SND_SOC_DAPM_AIF_IN("SLIMRX3", NULL, 0,
1183 ARIZONA_SLIMBUS_RX_CHANNEL_ENABLE,
1184 ARIZONA_SLIMRX3_ENA_SHIFT, 0),
1185SND_SOC_DAPM_AIF_IN("SLIMRX4", NULL, 0,
1186 ARIZONA_SLIMBUS_RX_CHANNEL_ENABLE,
1187 ARIZONA_SLIMRX4_ENA_SHIFT, 0),
1188SND_SOC_DAPM_AIF_IN("SLIMRX5", NULL, 0,
1189 ARIZONA_SLIMBUS_RX_CHANNEL_ENABLE,
1190 ARIZONA_SLIMRX5_ENA_SHIFT, 0),
1191SND_SOC_DAPM_AIF_IN("SLIMRX6", NULL, 0,
1192 ARIZONA_SLIMBUS_RX_CHANNEL_ENABLE,
1193 ARIZONA_SLIMRX6_ENA_SHIFT, 0),
1194SND_SOC_DAPM_AIF_IN("SLIMRX7", NULL, 0,
1195 ARIZONA_SLIMBUS_RX_CHANNEL_ENABLE,
1196 ARIZONA_SLIMRX7_ENA_SHIFT, 0),
1197SND_SOC_DAPM_AIF_IN("SLIMRX8", NULL, 0,
1198 ARIZONA_SLIMBUS_RX_CHANNEL_ENABLE,
1199 ARIZONA_SLIMRX8_ENA_SHIFT, 0),
1200
1120ARIZONA_DSP_WIDGETS(DSP1, "DSP1"), 1201ARIZONA_DSP_WIDGETS(DSP1, "DSP1"),
1121 1202
1122SND_SOC_DAPM_VALUE_MUX("AEC Loopback", ARIZONA_DAC_AEC_CONTROL_1, 1203SND_SOC_DAPM_VALUE_MUX("AEC Loopback", ARIZONA_DAC_AEC_CONTROL_1,
@@ -1189,6 +1270,15 @@ ARIZONA_MIXER_WIDGETS(AIF2TX2, "AIF2TX2"),
1189ARIZONA_MIXER_WIDGETS(AIF3TX1, "AIF3TX1"), 1270ARIZONA_MIXER_WIDGETS(AIF3TX1, "AIF3TX1"),
1190ARIZONA_MIXER_WIDGETS(AIF3TX2, "AIF3TX2"), 1271ARIZONA_MIXER_WIDGETS(AIF3TX2, "AIF3TX2"),
1191 1272
1273ARIZONA_MIXER_WIDGETS(SLIMTX1, "SLIMTX1"),
1274ARIZONA_MIXER_WIDGETS(SLIMTX2, "SLIMTX2"),
1275ARIZONA_MIXER_WIDGETS(SLIMTX3, "SLIMTX3"),
1276ARIZONA_MIXER_WIDGETS(SLIMTX4, "SLIMTX4"),
1277ARIZONA_MIXER_WIDGETS(SLIMTX5, "SLIMTX5"),
1278ARIZONA_MIXER_WIDGETS(SLIMTX6, "SLIMTX6"),
1279ARIZONA_MIXER_WIDGETS(SLIMTX7, "SLIMTX7"),
1280ARIZONA_MIXER_WIDGETS(SLIMTX8, "SLIMTX8"),
1281
1192ARIZONA_MUX_WIDGETS(ASRC1L, "ASRC1L"), 1282ARIZONA_MUX_WIDGETS(ASRC1L, "ASRC1L"),
1193ARIZONA_MUX_WIDGETS(ASRC1R, "ASRC1R"), 1283ARIZONA_MUX_WIDGETS(ASRC1R, "ASRC1R"),
1194ARIZONA_MUX_WIDGETS(ASRC2L, "ASRC2L"), 1284ARIZONA_MUX_WIDGETS(ASRC2L, "ASRC2L"),
@@ -1249,6 +1339,14 @@ SND_SOC_DAPM_OUTPUT("MICSUPP"),
1249 { name, "AIF2RX2", "AIF2RX2" }, \ 1339 { name, "AIF2RX2", "AIF2RX2" }, \
1250 { name, "AIF3RX1", "AIF3RX1" }, \ 1340 { name, "AIF3RX1", "AIF3RX1" }, \
1251 { name, "AIF3RX2", "AIF3RX2" }, \ 1341 { name, "AIF3RX2", "AIF3RX2" }, \
1342 { name, "SLIMRX1", "SLIMRX1" }, \
1343 { name, "SLIMRX2", "SLIMRX2" }, \
1344 { name, "SLIMRX3", "SLIMRX3" }, \
1345 { name, "SLIMRX4", "SLIMRX4" }, \
1346 { name, "SLIMRX5", "SLIMRX5" }, \
1347 { name, "SLIMRX6", "SLIMRX6" }, \
1348 { name, "SLIMRX7", "SLIMRX7" }, \
1349 { name, "SLIMRX8", "SLIMRX8" }, \
1252 { name, "EQ1", "EQ1" }, \ 1350 { name, "EQ1", "EQ1" }, \
1253 { name, "EQ2", "EQ2" }, \ 1351 { name, "EQ2", "EQ2" }, \
1254 { name, "EQ3", "EQ3" }, \ 1352 { name, "EQ3", "EQ3" }, \
@@ -1304,10 +1402,21 @@ static const struct snd_soc_dapm_route wm5102_dapm_routes[] = {
1304 { "OUT5L", NULL, "SYSCLK" }, 1402 { "OUT5L", NULL, "SYSCLK" },
1305 { "OUT5R", NULL, "SYSCLK" }, 1403 { "OUT5R", NULL, "SYSCLK" },
1306 1404
1405 { "IN1L", NULL, "SYSCLK" },
1406 { "IN1R", NULL, "SYSCLK" },
1407 { "IN2L", NULL, "SYSCLK" },
1408 { "IN2R", NULL, "SYSCLK" },
1409 { "IN3L", NULL, "SYSCLK" },
1410 { "IN3R", NULL, "SYSCLK" },
1411
1307 { "MICBIAS1", NULL, "MICVDD" }, 1412 { "MICBIAS1", NULL, "MICVDD" },
1308 { "MICBIAS2", NULL, "MICVDD" }, 1413 { "MICBIAS2", NULL, "MICVDD" },
1309 { "MICBIAS3", NULL, "MICVDD" }, 1414 { "MICBIAS3", NULL, "MICVDD" },
1310 1415
1416 { "Noise Generator", NULL, "SYSCLK" },
1417 { "Tone Generator 1", NULL, "SYSCLK" },
1418 { "Tone Generator 2", NULL, "SYSCLK" },
1419
1311 { "Noise Generator", NULL, "NOISE" }, 1420 { "Noise Generator", NULL, "NOISE" },
1312 { "Tone Generator 1", NULL, "TONE" }, 1421 { "Tone Generator 1", NULL, "TONE" },
1313 { "Tone Generator 2", NULL, "TONE" }, 1422 { "Tone Generator 2", NULL, "TONE" },
@@ -1345,13 +1454,41 @@ static const struct snd_soc_dapm_route wm5102_dapm_routes[] = {
1345 { "AIF3RX1", NULL, "AIF3 Playback" }, 1454 { "AIF3RX1", NULL, "AIF3 Playback" },
1346 { "AIF3RX2", NULL, "AIF3 Playback" }, 1455 { "AIF3RX2", NULL, "AIF3 Playback" },
1347 1456
1457 { "Slim1 Capture", NULL, "SLIMTX1" },
1458 { "Slim1 Capture", NULL, "SLIMTX2" },
1459 { "Slim1 Capture", NULL, "SLIMTX3" },
1460 { "Slim1 Capture", NULL, "SLIMTX4" },
1461
1462 { "SLIMRX1", NULL, "Slim1 Playback" },
1463 { "SLIMRX2", NULL, "Slim1 Playback" },
1464 { "SLIMRX3", NULL, "Slim1 Playback" },
1465 { "SLIMRX4", NULL, "Slim1 Playback" },
1466
1467 { "Slim2 Capture", NULL, "SLIMTX5" },
1468 { "Slim2 Capture", NULL, "SLIMTX6" },
1469
1470 { "SLIMRX5", NULL, "Slim2 Playback" },
1471 { "SLIMRX6", NULL, "Slim2 Playback" },
1472
1473 { "Slim3 Capture", NULL, "SLIMTX7" },
1474 { "Slim3 Capture", NULL, "SLIMTX8" },
1475
1476 { "SLIMRX7", NULL, "Slim3 Playback" },
1477 { "SLIMRX8", NULL, "Slim3 Playback" },
1478
1348 { "AIF1 Playback", NULL, "SYSCLK" }, 1479 { "AIF1 Playback", NULL, "SYSCLK" },
1349 { "AIF2 Playback", NULL, "SYSCLK" }, 1480 { "AIF2 Playback", NULL, "SYSCLK" },
1350 { "AIF3 Playback", NULL, "SYSCLK" }, 1481 { "AIF3 Playback", NULL, "SYSCLK" },
1482 { "Slim1 Playback", NULL, "SYSCLK" },
1483 { "Slim2 Playback", NULL, "SYSCLK" },
1484 { "Slim3 Playback", NULL, "SYSCLK" },
1351 1485
1352 { "AIF1 Capture", NULL, "SYSCLK" }, 1486 { "AIF1 Capture", NULL, "SYSCLK" },
1353 { "AIF2 Capture", NULL, "SYSCLK" }, 1487 { "AIF2 Capture", NULL, "SYSCLK" },
1354 { "AIF3 Capture", NULL, "SYSCLK" }, 1488 { "AIF3 Capture", NULL, "SYSCLK" },
1489 { "Slim1 Capture", NULL, "SYSCLK" },
1490 { "Slim2 Capture", NULL, "SYSCLK" },
1491 { "Slim3 Capture", NULL, "SYSCLK" },
1355 1492
1356 { "IN1L PGA", NULL, "IN1L" }, 1493 { "IN1L PGA", NULL, "IN1L" },
1357 { "IN1R PGA", NULL, "IN1R" }, 1494 { "IN1R PGA", NULL, "IN1R" },
@@ -1408,6 +1545,15 @@ static const struct snd_soc_dapm_route wm5102_dapm_routes[] = {
1408 ARIZONA_MIXER_ROUTES("AIF3TX1", "AIF3TX1"), 1545 ARIZONA_MIXER_ROUTES("AIF3TX1", "AIF3TX1"),
1409 ARIZONA_MIXER_ROUTES("AIF3TX2", "AIF3TX2"), 1546 ARIZONA_MIXER_ROUTES("AIF3TX2", "AIF3TX2"),
1410 1547
1548 ARIZONA_MIXER_ROUTES("SLIMTX1", "SLIMTX1"),
1549 ARIZONA_MIXER_ROUTES("SLIMTX2", "SLIMTX2"),
1550 ARIZONA_MIXER_ROUTES("SLIMTX3", "SLIMTX3"),
1551 ARIZONA_MIXER_ROUTES("SLIMTX4", "SLIMTX4"),
1552 ARIZONA_MIXER_ROUTES("SLIMTX5", "SLIMTX5"),
1553 ARIZONA_MIXER_ROUTES("SLIMTX6", "SLIMTX6"),
1554 ARIZONA_MIXER_ROUTES("SLIMTX7", "SLIMTX7"),
1555 ARIZONA_MIXER_ROUTES("SLIMTX8", "SLIMTX8"),
1556
1411 ARIZONA_MIXER_ROUTES("EQ1", "EQ1"), 1557 ARIZONA_MIXER_ROUTES("EQ1", "EQ1"),
1412 ARIZONA_MIXER_ROUTES("EQ2", "EQ2"), 1558 ARIZONA_MIXER_ROUTES("EQ2", "EQ2"),
1413 ARIZONA_MIXER_ROUTES("EQ3", "EQ3"), 1559 ARIZONA_MIXER_ROUTES("EQ3", "EQ3"),
@@ -1560,6 +1706,63 @@ static struct snd_soc_dai_driver wm5102_dai[] = {
1560 .ops = &arizona_dai_ops, 1706 .ops = &arizona_dai_ops,
1561 .symmetric_rates = 1, 1707 .symmetric_rates = 1,
1562 }, 1708 },
1709 {
1710 .name = "wm5102-slim1",
1711 .id = 4,
1712 .playback = {
1713 .stream_name = "Slim1 Playback",
1714 .channels_min = 1,
1715 .channels_max = 4,
1716 .rates = WM5102_RATES,
1717 .formats = WM5102_FORMATS,
1718 },
1719 .capture = {
1720 .stream_name = "Slim1 Capture",
1721 .channels_min = 1,
1722 .channels_max = 4,
1723 .rates = WM5102_RATES,
1724 .formats = WM5102_FORMATS,
1725 },
1726 .ops = &arizona_simple_dai_ops,
1727 },
1728 {
1729 .name = "wm5102-slim2",
1730 .id = 5,
1731 .playback = {
1732 .stream_name = "Slim2 Playback",
1733 .channels_min = 1,
1734 .channels_max = 2,
1735 .rates = WM5102_RATES,
1736 .formats = WM5102_FORMATS,
1737 },
1738 .capture = {
1739 .stream_name = "Slim2 Capture",
1740 .channels_min = 1,
1741 .channels_max = 2,
1742 .rates = WM5102_RATES,
1743 .formats = WM5102_FORMATS,
1744 },
1745 .ops = &arizona_simple_dai_ops,
1746 },
1747 {
1748 .name = "wm5102-slim3",
1749 .id = 6,
1750 .playback = {
1751 .stream_name = "Slim3 Playback",
1752 .channels_min = 1,
1753 .channels_max = 2,
1754 .rates = WM5102_RATES,
1755 .formats = WM5102_FORMATS,
1756 },
1757 .capture = {
1758 .stream_name = "Slim3 Capture",
1759 .channels_min = 1,
1760 .channels_max = 2,
1761 .rates = WM5102_RATES,
1762 .formats = WM5102_FORMATS,
1763 },
1764 .ops = &arizona_simple_dai_ops,
1765 },
1563}; 1766};
1564 1767
1565static int wm5102_codec_probe(struct snd_soc_codec *codec) 1768static int wm5102_codec_probe(struct snd_soc_codec *codec)
diff --git a/sound/soc/codecs/wm5110.c b/sound/soc/codecs/wm5110.c
index 88ad7db52dde..2e7cb4ba161a 100644
--- a/sound/soc/codecs/wm5110.c
+++ b/sound/soc/codecs/wm5110.c
@@ -309,6 +309,15 @@ ARIZONA_MIXER_CONTROLS("AIF2TX2", ARIZONA_AIF2TX2MIX_INPUT_1_SOURCE),
309 309
310ARIZONA_MIXER_CONTROLS("AIF3TX1", ARIZONA_AIF3TX1MIX_INPUT_1_SOURCE), 310ARIZONA_MIXER_CONTROLS("AIF3TX1", ARIZONA_AIF3TX1MIX_INPUT_1_SOURCE),
311ARIZONA_MIXER_CONTROLS("AIF3TX2", ARIZONA_AIF3TX2MIX_INPUT_1_SOURCE), 311ARIZONA_MIXER_CONTROLS("AIF3TX2", ARIZONA_AIF3TX2MIX_INPUT_1_SOURCE),
312
313ARIZONA_MIXER_CONTROLS("SLIMTX1", ARIZONA_SLIMTX1MIX_INPUT_1_SOURCE),
314ARIZONA_MIXER_CONTROLS("SLIMTX2", ARIZONA_SLIMTX2MIX_INPUT_1_SOURCE),
315ARIZONA_MIXER_CONTROLS("SLIMTX3", ARIZONA_SLIMTX3MIX_INPUT_1_SOURCE),
316ARIZONA_MIXER_CONTROLS("SLIMTX4", ARIZONA_SLIMTX4MIX_INPUT_1_SOURCE),
317ARIZONA_MIXER_CONTROLS("SLIMTX5", ARIZONA_SLIMTX5MIX_INPUT_1_SOURCE),
318ARIZONA_MIXER_CONTROLS("SLIMTX6", ARIZONA_SLIMTX6MIX_INPUT_1_SOURCE),
319ARIZONA_MIXER_CONTROLS("SLIMTX7", ARIZONA_SLIMTX7MIX_INPUT_1_SOURCE),
320ARIZONA_MIXER_CONTROLS("SLIMTX8", ARIZONA_SLIMTX8MIX_INPUT_1_SOURCE),
312}; 321};
313 322
314ARIZONA_MIXER_ENUMS(EQ1, ARIZONA_EQ1MIX_INPUT_1_SOURCE); 323ARIZONA_MIXER_ENUMS(EQ1, ARIZONA_EQ1MIX_INPUT_1_SOURCE);
@@ -360,6 +369,15 @@ ARIZONA_MIXER_ENUMS(AIF2TX2, ARIZONA_AIF2TX2MIX_INPUT_1_SOURCE);
360ARIZONA_MIXER_ENUMS(AIF3TX1, ARIZONA_AIF3TX1MIX_INPUT_1_SOURCE); 369ARIZONA_MIXER_ENUMS(AIF3TX1, ARIZONA_AIF3TX1MIX_INPUT_1_SOURCE);
361ARIZONA_MIXER_ENUMS(AIF3TX2, ARIZONA_AIF3TX2MIX_INPUT_1_SOURCE); 370ARIZONA_MIXER_ENUMS(AIF3TX2, ARIZONA_AIF3TX2MIX_INPUT_1_SOURCE);
362 371
372ARIZONA_MIXER_ENUMS(SLIMTX1, ARIZONA_SLIMTX1MIX_INPUT_1_SOURCE);
373ARIZONA_MIXER_ENUMS(SLIMTX2, ARIZONA_SLIMTX2MIX_INPUT_1_SOURCE);
374ARIZONA_MIXER_ENUMS(SLIMTX3, ARIZONA_SLIMTX3MIX_INPUT_1_SOURCE);
375ARIZONA_MIXER_ENUMS(SLIMTX4, ARIZONA_SLIMTX4MIX_INPUT_1_SOURCE);
376ARIZONA_MIXER_ENUMS(SLIMTX5, ARIZONA_SLIMTX5MIX_INPUT_1_SOURCE);
377ARIZONA_MIXER_ENUMS(SLIMTX6, ARIZONA_SLIMTX6MIX_INPUT_1_SOURCE);
378ARIZONA_MIXER_ENUMS(SLIMTX7, ARIZONA_SLIMTX7MIX_INPUT_1_SOURCE);
379ARIZONA_MIXER_ENUMS(SLIMTX8, ARIZONA_SLIMTX8MIX_INPUT_1_SOURCE);
380
363ARIZONA_MUX_ENUMS(ASRC1L, ARIZONA_ASRC1LMIX_INPUT_1_SOURCE); 381ARIZONA_MUX_ENUMS(ASRC1L, ARIZONA_ASRC1LMIX_INPUT_1_SOURCE);
364ARIZONA_MUX_ENUMS(ASRC1R, ARIZONA_ASRC1RMIX_INPUT_1_SOURCE); 382ARIZONA_MUX_ENUMS(ASRC1R, ARIZONA_ASRC1RMIX_INPUT_1_SOURCE);
365ARIZONA_MUX_ENUMS(ASRC2L, ARIZONA_ASRC2LMIX_INPUT_1_SOURCE); 383ARIZONA_MUX_ENUMS(ASRC2L, ARIZONA_ASRC2LMIX_INPUT_1_SOURCE);
@@ -550,6 +568,56 @@ SND_SOC_DAPM_AIF_IN("AIF2RX1", NULL, 0,
550SND_SOC_DAPM_AIF_IN("AIF2RX2", NULL, 0, 568SND_SOC_DAPM_AIF_IN("AIF2RX2", NULL, 0,
551 ARIZONA_AIF2_RX_ENABLES, ARIZONA_AIF2RX2_ENA_SHIFT, 0), 569 ARIZONA_AIF2_RX_ENABLES, ARIZONA_AIF2RX2_ENA_SHIFT, 0),
552 570
571SND_SOC_DAPM_AIF_IN("SLIMRX1", NULL, 0,
572 ARIZONA_SLIMBUS_RX_CHANNEL_ENABLE,
573 ARIZONA_SLIMRX1_ENA_SHIFT, 0),
574SND_SOC_DAPM_AIF_IN("SLIMRX2", NULL, 0,
575 ARIZONA_SLIMBUS_RX_CHANNEL_ENABLE,
576 ARIZONA_SLIMRX2_ENA_SHIFT, 0),
577SND_SOC_DAPM_AIF_IN("SLIMRX3", NULL, 0,
578 ARIZONA_SLIMBUS_RX_CHANNEL_ENABLE,
579 ARIZONA_SLIMRX3_ENA_SHIFT, 0),
580SND_SOC_DAPM_AIF_IN("SLIMRX4", NULL, 0,
581 ARIZONA_SLIMBUS_RX_CHANNEL_ENABLE,
582 ARIZONA_SLIMRX4_ENA_SHIFT, 0),
583SND_SOC_DAPM_AIF_IN("SLIMRX5", NULL, 0,
584 ARIZONA_SLIMBUS_RX_CHANNEL_ENABLE,
585 ARIZONA_SLIMRX5_ENA_SHIFT, 0),
586SND_SOC_DAPM_AIF_IN("SLIMRX6", NULL, 0,
587 ARIZONA_SLIMBUS_RX_CHANNEL_ENABLE,
588 ARIZONA_SLIMRX6_ENA_SHIFT, 0),
589SND_SOC_DAPM_AIF_IN("SLIMRX7", NULL, 0,
590 ARIZONA_SLIMBUS_RX_CHANNEL_ENABLE,
591 ARIZONA_SLIMRX7_ENA_SHIFT, 0),
592SND_SOC_DAPM_AIF_IN("SLIMRX8", NULL, 0,
593 ARIZONA_SLIMBUS_RX_CHANNEL_ENABLE,
594 ARIZONA_SLIMRX8_ENA_SHIFT, 0),
595
596SND_SOC_DAPM_AIF_OUT("SLIMTX1", NULL, 0,
597 ARIZONA_SLIMBUS_TX_CHANNEL_ENABLE,
598 ARIZONA_SLIMTX1_ENA_SHIFT, 0),
599SND_SOC_DAPM_AIF_OUT("SLIMTX2", NULL, 0,
600 ARIZONA_SLIMBUS_TX_CHANNEL_ENABLE,
601 ARIZONA_SLIMTX2_ENA_SHIFT, 0),
602SND_SOC_DAPM_AIF_OUT("SLIMTX3", NULL, 0,
603 ARIZONA_SLIMBUS_TX_CHANNEL_ENABLE,
604 ARIZONA_SLIMTX3_ENA_SHIFT, 0),
605SND_SOC_DAPM_AIF_OUT("SLIMTX4", NULL, 0,
606 ARIZONA_SLIMBUS_TX_CHANNEL_ENABLE,
607 ARIZONA_SLIMTX4_ENA_SHIFT, 0),
608SND_SOC_DAPM_AIF_OUT("SLIMTX5", NULL, 0,
609 ARIZONA_SLIMBUS_TX_CHANNEL_ENABLE,
610 ARIZONA_SLIMTX5_ENA_SHIFT, 0),
611SND_SOC_DAPM_AIF_OUT("SLIMTX6", NULL, 0,
612 ARIZONA_SLIMBUS_TX_CHANNEL_ENABLE,
613 ARIZONA_SLIMTX6_ENA_SHIFT, 0),
614SND_SOC_DAPM_AIF_OUT("SLIMTX7", NULL, 0,
615 ARIZONA_SLIMBUS_TX_CHANNEL_ENABLE,
616 ARIZONA_SLIMTX7_ENA_SHIFT, 0),
617SND_SOC_DAPM_AIF_OUT("SLIMTX8", NULL, 0,
618 ARIZONA_SLIMBUS_TX_CHANNEL_ENABLE,
619 ARIZONA_SLIMTX8_ENA_SHIFT, 0),
620
553SND_SOC_DAPM_AIF_OUT("AIF3TX1", NULL, 0, 621SND_SOC_DAPM_AIF_OUT("AIF3TX1", NULL, 0,
554 ARIZONA_AIF3_TX_ENABLES, ARIZONA_AIF3TX1_ENA_SHIFT, 0), 622 ARIZONA_AIF3_TX_ENABLES, ARIZONA_AIF3TX1_ENA_SHIFT, 0),
555SND_SOC_DAPM_AIF_OUT("AIF3TX2", NULL, 0, 623SND_SOC_DAPM_AIF_OUT("AIF3TX2", NULL, 0,
@@ -640,6 +708,15 @@ ARIZONA_MIXER_WIDGETS(AIF2TX2, "AIF2TX2"),
640ARIZONA_MIXER_WIDGETS(AIF3TX1, "AIF3TX1"), 708ARIZONA_MIXER_WIDGETS(AIF3TX1, "AIF3TX1"),
641ARIZONA_MIXER_WIDGETS(AIF3TX2, "AIF3TX2"), 709ARIZONA_MIXER_WIDGETS(AIF3TX2, "AIF3TX2"),
642 710
711ARIZONA_MIXER_WIDGETS(SLIMTX1, "SLIMTX1"),
712ARIZONA_MIXER_WIDGETS(SLIMTX2, "SLIMTX2"),
713ARIZONA_MIXER_WIDGETS(SLIMTX3, "SLIMTX3"),
714ARIZONA_MIXER_WIDGETS(SLIMTX4, "SLIMTX4"),
715ARIZONA_MIXER_WIDGETS(SLIMTX5, "SLIMTX5"),
716ARIZONA_MIXER_WIDGETS(SLIMTX6, "SLIMTX6"),
717ARIZONA_MIXER_WIDGETS(SLIMTX7, "SLIMTX7"),
718ARIZONA_MIXER_WIDGETS(SLIMTX8, "SLIMTX8"),
719
643ARIZONA_MUX_WIDGETS(ASRC1L, "ASRC1L"), 720ARIZONA_MUX_WIDGETS(ASRC1L, "ASRC1L"),
644ARIZONA_MUX_WIDGETS(ASRC1R, "ASRC1R"), 721ARIZONA_MUX_WIDGETS(ASRC1R, "ASRC1R"),
645ARIZONA_MUX_WIDGETS(ASRC2L, "ASRC2L"), 722ARIZONA_MUX_WIDGETS(ASRC2L, "ASRC2L"),
@@ -690,6 +767,14 @@ SND_SOC_DAPM_OUTPUT("MICSUPP"),
690 { name, "AIF2RX2", "AIF2RX2" }, \ 767 { name, "AIF2RX2", "AIF2RX2" }, \
691 { name, "AIF3RX1", "AIF3RX1" }, \ 768 { name, "AIF3RX1", "AIF3RX1" }, \
692 { name, "AIF3RX2", "AIF3RX2" }, \ 769 { name, "AIF3RX2", "AIF3RX2" }, \
770 { name, "SLIMRX1", "SLIMRX1" }, \
771 { name, "SLIMRX2", "SLIMRX2" }, \
772 { name, "SLIMRX3", "SLIMRX3" }, \
773 { name, "SLIMRX4", "SLIMRX4" }, \
774 { name, "SLIMRX5", "SLIMRX5" }, \
775 { name, "SLIMRX6", "SLIMRX6" }, \
776 { name, "SLIMRX7", "SLIMRX7" }, \
777 { name, "SLIMRX8", "SLIMRX8" }, \
693 { name, "EQ1", "EQ1" }, \ 778 { name, "EQ1", "EQ1" }, \
694 { name, "EQ2", "EQ2" }, \ 779 { name, "EQ2", "EQ2" }, \
695 { name, "EQ3", "EQ3" }, \ 780 { name, "EQ3", "EQ3" }, \
@@ -736,10 +821,23 @@ static const struct snd_soc_dapm_route wm5110_dapm_routes[] = {
736 { "OUT6L", NULL, "SYSCLK" }, 821 { "OUT6L", NULL, "SYSCLK" },
737 { "OUT6R", NULL, "SYSCLK" }, 822 { "OUT6R", NULL, "SYSCLK" },
738 823
824 { "IN1L", NULL, "SYSCLK" },
825 { "IN1R", NULL, "SYSCLK" },
826 { "IN2L", NULL, "SYSCLK" },
827 { "IN2R", NULL, "SYSCLK" },
828 { "IN3L", NULL, "SYSCLK" },
829 { "IN3R", NULL, "SYSCLK" },
830 { "IN4L", NULL, "SYSCLK" },
831 { "IN4R", NULL, "SYSCLK" },
832
739 { "MICBIAS1", NULL, "MICVDD" }, 833 { "MICBIAS1", NULL, "MICVDD" },
740 { "MICBIAS2", NULL, "MICVDD" }, 834 { "MICBIAS2", NULL, "MICVDD" },
741 { "MICBIAS3", NULL, "MICVDD" }, 835 { "MICBIAS3", NULL, "MICVDD" },
742 836
837 { "Noise Generator", NULL, "SYSCLK" },
838 { "Tone Generator 1", NULL, "SYSCLK" },
839 { "Tone Generator 2", NULL, "SYSCLK" },
840
743 { "Noise Generator", NULL, "NOISE" }, 841 { "Noise Generator", NULL, "NOISE" },
744 { "Tone Generator 1", NULL, "TONE" }, 842 { "Tone Generator 1", NULL, "TONE" },
745 { "Tone Generator 2", NULL, "TONE" }, 843 { "Tone Generator 2", NULL, "TONE" },
@@ -777,13 +875,41 @@ static const struct snd_soc_dapm_route wm5110_dapm_routes[] = {
777 { "AIF3RX1", NULL, "AIF3 Playback" }, 875 { "AIF3RX1", NULL, "AIF3 Playback" },
778 { "AIF3RX2", NULL, "AIF3 Playback" }, 876 { "AIF3RX2", NULL, "AIF3 Playback" },
779 877
878 { "Slim1 Capture", NULL, "SLIMTX1" },
879 { "Slim1 Capture", NULL, "SLIMTX2" },
880 { "Slim1 Capture", NULL, "SLIMTX3" },
881 { "Slim1 Capture", NULL, "SLIMTX4" },
882
883 { "SLIMRX1", NULL, "Slim1 Playback" },
884 { "SLIMRX2", NULL, "Slim1 Playback" },
885 { "SLIMRX3", NULL, "Slim1 Playback" },
886 { "SLIMRX4", NULL, "Slim1 Playback" },
887
888 { "Slim2 Capture", NULL, "SLIMTX5" },
889 { "Slim2 Capture", NULL, "SLIMTX6" },
890
891 { "SLIMRX5", NULL, "Slim2 Playback" },
892 { "SLIMRX6", NULL, "Slim2 Playback" },
893
894 { "Slim3 Capture", NULL, "SLIMTX7" },
895 { "Slim3 Capture", NULL, "SLIMTX8" },
896
897 { "SLIMRX7", NULL, "Slim3 Playback" },
898 { "SLIMRX8", NULL, "Slim3 Playback" },
899
780 { "AIF1 Playback", NULL, "SYSCLK" }, 900 { "AIF1 Playback", NULL, "SYSCLK" },
781 { "AIF2 Playback", NULL, "SYSCLK" }, 901 { "AIF2 Playback", NULL, "SYSCLK" },
782 { "AIF3 Playback", NULL, "SYSCLK" }, 902 { "AIF3 Playback", NULL, "SYSCLK" },
903 { "Slim1 Playback", NULL, "SYSCLK" },
904 { "Slim2 Playback", NULL, "SYSCLK" },
905 { "Slim3 Playback", NULL, "SYSCLK" },
783 906
784 { "AIF1 Capture", NULL, "SYSCLK" }, 907 { "AIF1 Capture", NULL, "SYSCLK" },
785 { "AIF2 Capture", NULL, "SYSCLK" }, 908 { "AIF2 Capture", NULL, "SYSCLK" },
786 { "AIF3 Capture", NULL, "SYSCLK" }, 909 { "AIF3 Capture", NULL, "SYSCLK" },
910 { "Slim1 Capture", NULL, "SYSCLK" },
911 { "Slim2 Capture", NULL, "SYSCLK" },
912 { "Slim3 Capture", NULL, "SYSCLK" },
787 913
788 { "IN1L PGA", NULL, "IN1L" }, 914 { "IN1L PGA", NULL, "IN1L" },
789 { "IN1R PGA", NULL, "IN1R" }, 915 { "IN1R PGA", NULL, "IN1R" },
@@ -829,6 +955,15 @@ static const struct snd_soc_dapm_route wm5110_dapm_routes[] = {
829 ARIZONA_MIXER_ROUTES("AIF3TX1", "AIF3TX1"), 955 ARIZONA_MIXER_ROUTES("AIF3TX1", "AIF3TX1"),
830 ARIZONA_MIXER_ROUTES("AIF3TX2", "AIF3TX2"), 956 ARIZONA_MIXER_ROUTES("AIF3TX2", "AIF3TX2"),
831 957
958 ARIZONA_MIXER_ROUTES("SLIMTX1", "SLIMTX1"),
959 ARIZONA_MIXER_ROUTES("SLIMTX2", "SLIMTX2"),
960 ARIZONA_MIXER_ROUTES("SLIMTX3", "SLIMTX3"),
961 ARIZONA_MIXER_ROUTES("SLIMTX4", "SLIMTX4"),
962 ARIZONA_MIXER_ROUTES("SLIMTX5", "SLIMTX5"),
963 ARIZONA_MIXER_ROUTES("SLIMTX6", "SLIMTX6"),
964 ARIZONA_MIXER_ROUTES("SLIMTX7", "SLIMTX7"),
965 ARIZONA_MIXER_ROUTES("SLIMTX8", "SLIMTX8"),
966
832 ARIZONA_MIXER_ROUTES("EQ1", "EQ1"), 967 ARIZONA_MIXER_ROUTES("EQ1", "EQ1"),
833 ARIZONA_MIXER_ROUTES("EQ2", "EQ2"), 968 ARIZONA_MIXER_ROUTES("EQ2", "EQ2"),
834 ARIZONA_MIXER_ROUTES("EQ3", "EQ3"), 969 ARIZONA_MIXER_ROUTES("EQ3", "EQ3"),
@@ -963,6 +1098,63 @@ static struct snd_soc_dai_driver wm5110_dai[] = {
963 .ops = &arizona_dai_ops, 1098 .ops = &arizona_dai_ops,
964 .symmetric_rates = 1, 1099 .symmetric_rates = 1,
965 }, 1100 },
1101 {
1102 .name = "wm5110-slim1",
1103 .id = 4,
1104 .playback = {
1105 .stream_name = "Slim1 Playback",
1106 .channels_min = 1,
1107 .channels_max = 4,
1108 .rates = WM5110_RATES,
1109 .formats = WM5110_FORMATS,
1110 },
1111 .capture = {
1112 .stream_name = "Slim1 Capture",
1113 .channels_min = 1,
1114 .channels_max = 4,
1115 .rates = WM5110_RATES,
1116 .formats = WM5110_FORMATS,
1117 },
1118 .ops = &arizona_simple_dai_ops,
1119 },
1120 {
1121 .name = "wm5110-slim2",
1122 .id = 5,
1123 .playback = {
1124 .stream_name = "Slim2 Playback",
1125 .channels_min = 1,
1126 .channels_max = 2,
1127 .rates = WM5110_RATES,
1128 .formats = WM5110_FORMATS,
1129 },
1130 .capture = {
1131 .stream_name = "Slim2 Capture",
1132 .channels_min = 1,
1133 .channels_max = 2,
1134 .rates = WM5110_RATES,
1135 .formats = WM5110_FORMATS,
1136 },
1137 .ops = &arizona_simple_dai_ops,
1138 },
1139 {
1140 .name = "wm5110-slim3",
1141 .id = 6,
1142 .playback = {
1143 .stream_name = "Slim3 Playback",
1144 .channels_min = 1,
1145 .channels_max = 2,
1146 .rates = WM5110_RATES,
1147 .formats = WM5110_FORMATS,
1148 },
1149 .capture = {
1150 .stream_name = "Slim3 Capture",
1151 .channels_min = 1,
1152 .channels_max = 2,
1153 .rates = WM5110_RATES,
1154 .formats = WM5110_FORMATS,
1155 },
1156 .ops = &arizona_simple_dai_ops,
1157 },
966}; 1158};
967 1159
968static int wm5110_codec_probe(struct snd_soc_codec *codec) 1160static int wm5110_codec_probe(struct snd_soc_codec *codec)
diff --git a/sound/soc/codecs/wm8400.c b/sound/soc/codecs/wm8400.c
index af6d227e67be..d2a092850283 100644
--- a/sound/soc/codecs/wm8400.c
+++ b/sound/soc/codecs/wm8400.c
@@ -143,13 +143,8 @@ static int wm8400_outpga_put_volsw_vu(struct snd_kcontrol *kcontrol,
143} 143}
144 144
145#define WM8400_OUTPGA_SINGLE_R_TLV(xname, reg, shift, max, invert, tlv_array) \ 145#define WM8400_OUTPGA_SINGLE_R_TLV(xname, reg, shift, max, invert, tlv_array) \
146{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \ 146 SOC_SINGLE_EXT_TLV(xname, reg, shift, max, invert, \
147 .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ |\ 147 snd_soc_get_volsw, wm8400_outpga_put_volsw_vu, tlv_array)
148 SNDRV_CTL_ELEM_ACCESS_READWRITE,\
149 .tlv.p = (tlv_array), \
150 .info = snd_soc_info_volsw, \
151 .get = snd_soc_get_volsw, .put = wm8400_outpga_put_volsw_vu, \
152 .private_value = SOC_SINGLE_VALUE(reg, shift, max, invert) }
153 148
154 149
155static const char *wm8400_digital_sidetone[] = 150static const char *wm8400_digital_sidetone[] =
diff --git a/sound/soc/codecs/wm8903.c b/sound/soc/codecs/wm8903.c
index 9d88437cdcd1..fa24cedee687 100644
--- a/sound/soc/codecs/wm8903.c
+++ b/sound/soc/codecs/wm8903.c
@@ -403,10 +403,8 @@ static int wm8903_class_w_put(struct snd_kcontrol *kcontrol,
403} 403}
404 404
405#define SOC_DAPM_SINGLE_W(xname, reg, shift, max, invert) \ 405#define SOC_DAPM_SINGLE_W(xname, reg, shift, max, invert) \
406{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \ 406 SOC_SINGLE_EXT(xname, reg, shift, max, invert, \
407 .info = snd_soc_info_volsw, \ 407 snd_soc_dapm_get_volsw, wm8903_class_w_put)
408 .get = snd_soc_dapm_get_volsw, .put = wm8903_class_w_put, \
409 .private_value = SOC_SINGLE_VALUE(reg, shift, max, invert) }
410 408
411 409
412static int wm8903_deemph[] = { 0, 32000, 44100, 48000 }; 410static int wm8903_deemph[] = { 0, 32000, 44100, 48000 };
diff --git a/sound/soc/codecs/wm8904.c b/sound/soc/codecs/wm8904.c
index 3ff195c541db..4c9fb142cb2d 100644
--- a/sound/soc/codecs/wm8904.c
+++ b/sound/soc/codecs/wm8904.c
@@ -603,13 +603,8 @@ SOC_DOUBLE_R("Capture Switch", WM8904_ANALOGUE_LEFT_INPUT_0,
603 603
604SOC_SINGLE("High Pass Filter Switch", WM8904_ADC_DIGITAL_0, 4, 1, 0), 604SOC_SINGLE("High Pass Filter Switch", WM8904_ADC_DIGITAL_0, 4, 1, 0),
605SOC_ENUM("High Pass Filter Mode", hpf_mode), 605SOC_ENUM("High Pass Filter Mode", hpf_mode),
606 606SOC_SINGLE_EXT("ADC 128x OSR Switch", WM8904_ANALOGUE_ADC_0, 0, 1, 0,
607{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 607 snd_soc_get_volsw, wm8904_adc_osr_put),
608 .name = "ADC 128x OSR Switch",
609 .info = snd_soc_info_volsw, .get = snd_soc_get_volsw,
610 .put = wm8904_adc_osr_put,
611 .private_value = SOC_SINGLE_VALUE(WM8904_ANALOGUE_ADC_0, 0, 1, 0),
612},
613}; 608};
614 609
615static const char *drc_path_text[] = { 610static const char *drc_path_text[] = {
diff --git a/sound/soc/codecs/wm8962.c b/sound/soc/codecs/wm8962.c
index e9710280e5e1..b1dc7d426438 100644
--- a/sound/soc/codecs/wm8962.c
+++ b/sound/soc/codecs/wm8962.c
@@ -51,6 +51,7 @@ static const char *wm8962_supply_names[WM8962_NUM_SUPPLIES] = {
51 51
52/* codec private data */ 52/* codec private data */
53struct wm8962_priv { 53struct wm8962_priv {
54 struct wm8962_pdata pdata;
54 struct regmap *regmap; 55 struct regmap *regmap;
55 struct snd_soc_codec *codec; 56 struct snd_soc_codec *codec;
56 57
@@ -1600,7 +1601,6 @@ static int wm8962_put_hp_sw(struct snd_kcontrol *kcontrol,
1600 struct snd_ctl_elem_value *ucontrol) 1601 struct snd_ctl_elem_value *ucontrol)
1601{ 1602{
1602 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); 1603 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
1603 u16 *reg_cache = codec->reg_cache;
1604 int ret; 1604 int ret;
1605 1605
1606 /* Apply the update (if any) */ 1606 /* Apply the update (if any) */
@@ -1609,16 +1609,19 @@ static int wm8962_put_hp_sw(struct snd_kcontrol *kcontrol,
1609 return 0; 1609 return 0;
1610 1610
1611 /* If the left PGA is enabled hit that VU bit... */ 1611 /* If the left PGA is enabled hit that VU bit... */
1612 if (snd_soc_read(codec, WM8962_PWR_MGMT_2) & WM8962_HPOUTL_PGA_ENA) 1612 ret = snd_soc_read(codec, WM8962_PWR_MGMT_2);
1613 return snd_soc_write(codec, WM8962_HPOUTL_VOLUME, 1613 if (ret & WM8962_HPOUTL_PGA_ENA) {
1614 reg_cache[WM8962_HPOUTL_VOLUME]); 1614 snd_soc_write(codec, WM8962_HPOUTL_VOLUME,
1615 snd_soc_read(codec, WM8962_HPOUTL_VOLUME));
1616 return 1;
1617 }
1615 1618
1616 /* ...otherwise the right. The VU is stereo. */ 1619 /* ...otherwise the right. The VU is stereo. */
1617 if (snd_soc_read(codec, WM8962_PWR_MGMT_2) & WM8962_HPOUTR_PGA_ENA) 1620 if (ret & WM8962_HPOUTR_PGA_ENA)
1618 return snd_soc_write(codec, WM8962_HPOUTR_VOLUME, 1621 snd_soc_write(codec, WM8962_HPOUTR_VOLUME,
1619 reg_cache[WM8962_HPOUTR_VOLUME]); 1622 snd_soc_read(codec, WM8962_HPOUTR_VOLUME));
1620 1623
1621 return 0; 1624 return 1;
1622} 1625}
1623 1626
1624/* The VU bits for the speakers are in a different register to the mute 1627/* The VU bits for the speakers are in a different register to the mute
@@ -2345,12 +2348,13 @@ static const struct snd_soc_dapm_route wm8962_spk_stereo_intercon[] = {
2345 2348
2346static int wm8962_add_widgets(struct snd_soc_codec *codec) 2349static int wm8962_add_widgets(struct snd_soc_codec *codec)
2347{ 2350{
2348 struct wm8962_pdata *pdata = dev_get_platdata(codec->dev); 2351 struct wm8962_priv *wm8962 = snd_soc_codec_get_drvdata(codec);
2352 struct wm8962_pdata *pdata = &wm8962->pdata;
2349 struct snd_soc_dapm_context *dapm = &codec->dapm; 2353 struct snd_soc_dapm_context *dapm = &codec->dapm;
2350 2354
2351 snd_soc_add_codec_controls(codec, wm8962_snd_controls, 2355 snd_soc_add_codec_controls(codec, wm8962_snd_controls,
2352 ARRAY_SIZE(wm8962_snd_controls)); 2356 ARRAY_SIZE(wm8962_snd_controls));
2353 if (pdata && pdata->spk_mono) 2357 if (pdata->spk_mono)
2354 snd_soc_add_codec_controls(codec, wm8962_spk_mono_controls, 2358 snd_soc_add_codec_controls(codec, wm8962_spk_mono_controls,
2355 ARRAY_SIZE(wm8962_spk_mono_controls)); 2359 ARRAY_SIZE(wm8962_spk_mono_controls));
2356 else 2360 else
@@ -2360,7 +2364,7 @@ static int wm8962_add_widgets(struct snd_soc_codec *codec)
2360 2364
2361 snd_soc_dapm_new_controls(dapm, wm8962_dapm_widgets, 2365 snd_soc_dapm_new_controls(dapm, wm8962_dapm_widgets,
2362 ARRAY_SIZE(wm8962_dapm_widgets)); 2366 ARRAY_SIZE(wm8962_dapm_widgets));
2363 if (pdata && pdata->spk_mono) 2367 if (pdata->spk_mono)
2364 snd_soc_dapm_new_controls(dapm, wm8962_dapm_spk_mono_widgets, 2368 snd_soc_dapm_new_controls(dapm, wm8962_dapm_spk_mono_widgets,
2365 ARRAY_SIZE(wm8962_dapm_spk_mono_widgets)); 2369 ARRAY_SIZE(wm8962_dapm_spk_mono_widgets));
2366 else 2370 else
@@ -2369,7 +2373,7 @@ static int wm8962_add_widgets(struct snd_soc_codec *codec)
2369 2373
2370 snd_soc_dapm_add_routes(dapm, wm8962_intercon, 2374 snd_soc_dapm_add_routes(dapm, wm8962_intercon,
2371 ARRAY_SIZE(wm8962_intercon)); 2375 ARRAY_SIZE(wm8962_intercon));
2372 if (pdata && pdata->spk_mono) 2376 if (pdata->spk_mono)
2373 snd_soc_dapm_add_routes(dapm, wm8962_spk_mono_intercon, 2377 snd_soc_dapm_add_routes(dapm, wm8962_spk_mono_intercon,
2374 ARRAY_SIZE(wm8962_spk_mono_intercon)); 2378 ARRAY_SIZE(wm8962_spk_mono_intercon));
2375 else 2379 else
@@ -3333,14 +3337,14 @@ static struct gpio_chip wm8962_template_chip = {
3333static void wm8962_init_gpio(struct snd_soc_codec *codec) 3337static void wm8962_init_gpio(struct snd_soc_codec *codec)
3334{ 3338{
3335 struct wm8962_priv *wm8962 = snd_soc_codec_get_drvdata(codec); 3339 struct wm8962_priv *wm8962 = snd_soc_codec_get_drvdata(codec);
3336 struct wm8962_pdata *pdata = dev_get_platdata(codec->dev); 3340 struct wm8962_pdata *pdata = &wm8962->pdata;
3337 int ret; 3341 int ret;
3338 3342
3339 wm8962->gpio_chip = wm8962_template_chip; 3343 wm8962->gpio_chip = wm8962_template_chip;
3340 wm8962->gpio_chip.ngpio = WM8962_MAX_GPIO; 3344 wm8962->gpio_chip.ngpio = WM8962_MAX_GPIO;
3341 wm8962->gpio_chip.dev = codec->dev; 3345 wm8962->gpio_chip.dev = codec->dev;
3342 3346
3343 if (pdata && pdata->gpio_base) 3347 if (pdata->gpio_base)
3344 wm8962->gpio_chip.base = pdata->gpio_base; 3348 wm8962->gpio_chip.base = pdata->gpio_base;
3345 else 3349 else
3346 wm8962->gpio_chip.base = -1; 3350 wm8962->gpio_chip.base = -1;
@@ -3374,7 +3378,6 @@ static int wm8962_probe(struct snd_soc_codec *codec)
3374 int ret; 3378 int ret;
3375 struct wm8962_priv *wm8962 = snd_soc_codec_get_drvdata(codec); 3379 struct wm8962_priv *wm8962 = snd_soc_codec_get_drvdata(codec);
3376 struct wm8962_pdata *pdata = dev_get_platdata(codec->dev); 3380 struct wm8962_pdata *pdata = dev_get_platdata(codec->dev);
3377 u16 *reg_cache = codec->reg_cache;
3378 int i, trigger, irq_pol; 3381 int i, trigger, irq_pol;
3379 bool dmicclk, dmicdat; 3382 bool dmicclk, dmicdat;
3380 3383
@@ -3421,30 +3424,29 @@ static int wm8962_probe(struct snd_soc_codec *codec)
3421 WM8962_OSC_ENA | WM8962_PLL2_ENA | WM8962_PLL3_ENA, 3424 WM8962_OSC_ENA | WM8962_PLL2_ENA | WM8962_PLL3_ENA,
3422 0); 3425 0);
3423 3426
3424 if (pdata) { 3427 /* Apply static configuration for GPIOs */
3425 /* Apply static configuration for GPIOs */ 3428 for (i = 0; i < ARRAY_SIZE(pdata->gpio_init); i++)
3426 for (i = 0; i < ARRAY_SIZE(pdata->gpio_init); i++) 3429 if (pdata->gpio_init[i]) {
3427 if (pdata->gpio_init[i]) { 3430 wm8962_set_gpio_mode(codec, i + 1);
3428 wm8962_set_gpio_mode(codec, i + 1); 3431 snd_soc_write(codec, 0x200 + i,
3429 snd_soc_write(codec, 0x200 + i, 3432 pdata->gpio_init[i] & 0xffff);
3430 pdata->gpio_init[i] & 0xffff); 3433 }
3431 }
3432 3434
3433 /* Put the speakers into mono mode? */
3434 if (pdata->spk_mono)
3435 reg_cache[WM8962_CLASS_D_CONTROL_2]
3436 |= WM8962_SPK_MONO;
3437 3435
3438 /* Micbias setup, detection enable and detection 3436 /* Put the speakers into mono mode? */
3439 * threasholds. */ 3437 if (pdata->spk_mono)
3440 if (pdata->mic_cfg) 3438 snd_soc_update_bits(codec, WM8962_CLASS_D_CONTROL_2,
3441 snd_soc_update_bits(codec, WM8962_ADDITIONAL_CONTROL_4, 3439 WM8962_SPK_MONO_MASK, WM8962_SPK_MONO);
3442 WM8962_MICDET_ENA | 3440
3443 WM8962_MICDET_THR_MASK | 3441 /* Micbias setup, detection enable and detection
3444 WM8962_MICSHORT_THR_MASK | 3442 * threasholds. */
3445 WM8962_MICBIAS_LVL, 3443 if (pdata->mic_cfg)
3446 pdata->mic_cfg); 3444 snd_soc_update_bits(codec, WM8962_ADDITIONAL_CONTROL_4,
3447 } 3445 WM8962_MICDET_ENA |
3446 WM8962_MICDET_THR_MASK |
3447 WM8962_MICSHORT_THR_MASK |
3448 WM8962_MICBIAS_LVL,
3449 pdata->mic_cfg);
3448 3450
3449 /* Latch volume update bits */ 3451 /* Latch volume update bits */
3450 snd_soc_update_bits(codec, WM8962_LEFT_INPUT_VOLUME, 3452 snd_soc_update_bits(codec, WM8962_LEFT_INPUT_VOLUME,
@@ -3506,7 +3508,7 @@ static int wm8962_probe(struct snd_soc_codec *codec)
3506 wm8962_init_gpio(codec); 3508 wm8962_init_gpio(codec);
3507 3509
3508 if (wm8962->irq) { 3510 if (wm8962->irq) {
3509 if (pdata && pdata->irq_active_low) { 3511 if (pdata->irq_active_low) {
3510 trigger = IRQF_TRIGGER_LOW; 3512 trigger = IRQF_TRIGGER_LOW;
3511 irq_pol = WM8962_IRQ_POL; 3513 irq_pol = WM8962_IRQ_POL;
3512 } else { 3514 } else {
@@ -3584,6 +3586,34 @@ static const struct regmap_config wm8962_regmap = {
3584 .cache_type = REGCACHE_RBTREE, 3586 .cache_type = REGCACHE_RBTREE,
3585}; 3587};
3586 3588
3589static int wm8962_set_pdata_from_of(struct i2c_client *i2c,
3590 struct wm8962_pdata *pdata)
3591{
3592 const struct device_node *np = i2c->dev.of_node;
3593 u32 val32;
3594 int i;
3595
3596 if (of_property_read_bool(np, "spk-mono"))
3597 pdata->spk_mono = true;
3598
3599 if (of_property_read_u32(np, "mic-cfg", &val32) >= 0)
3600 pdata->mic_cfg = val32;
3601
3602 if (of_property_read_u32_array(np, "gpio-cfg", pdata->gpio_init,
3603 ARRAY_SIZE(pdata->gpio_init)) >= 0)
3604 for (i = 0; i < ARRAY_SIZE(pdata->gpio_init); i++) {
3605 /*
3606 * The range of GPIO register value is [0x0, 0xffff]
3607 * While the default value of each register is 0x0
3608 * Any other value will be regarded as default value
3609 */
3610 if (pdata->gpio_init[i] > 0xffff)
3611 pdata->gpio_init[i] = 0x0;
3612 }
3613
3614 return 0;
3615}
3616
3587static int wm8962_i2c_probe(struct i2c_client *i2c, 3617static int wm8962_i2c_probe(struct i2c_client *i2c,
3588 const struct i2c_device_id *id) 3618 const struct i2c_device_id *id)
3589{ 3619{
@@ -3603,6 +3633,15 @@ static int wm8962_i2c_probe(struct i2c_client *i2c,
3603 init_completion(&wm8962->fll_lock); 3633 init_completion(&wm8962->fll_lock);
3604 wm8962->irq = i2c->irq; 3634 wm8962->irq = i2c->irq;
3605 3635
3636 /* If platform data was supplied, update the default data in priv */
3637 if (pdata) {
3638 memcpy(&wm8962->pdata, pdata, sizeof(struct wm8962_pdata));
3639 } else if (i2c->dev.of_node) {
3640 ret = wm8962_set_pdata_from_of(i2c, &wm8962->pdata);
3641 if (ret != 0)
3642 return ret;
3643 }
3644
3606 for (i = 0; i < ARRAY_SIZE(wm8962->supplies); i++) 3645 for (i = 0; i < ARRAY_SIZE(wm8962->supplies); i++)
3607 wm8962->supplies[i].supply = wm8962_supply_names[i]; 3646 wm8962->supplies[i].supply = wm8962_supply_names[i];
3608 3647
@@ -3666,7 +3705,7 @@ static int wm8962_i2c_probe(struct i2c_client *i2c,
3666 goto err_enable; 3705 goto err_enable;
3667 } 3706 }
3668 3707
3669 if (pdata && pdata->in4_dc_measure) { 3708 if (wm8962->pdata.in4_dc_measure) {
3670 ret = regmap_register_patch(wm8962->regmap, 3709 ret = regmap_register_patch(wm8962->regmap,
3671 wm8962_dc_measure, 3710 wm8962_dc_measure,
3672 ARRAY_SIZE(wm8962_dc_measure)); 3711 ARRAY_SIZE(wm8962_dc_measure));
@@ -3719,8 +3758,34 @@ static int wm8962_runtime_resume(struct device *dev)
3719 3758
3720 wm8962_reset(wm8962); 3759 wm8962_reset(wm8962);
3721 3760
3761 /* SYSCLK defaults to on; make sure it is off so we can safely
3762 * write to registers if the device is declocked.
3763 */
3764 regmap_update_bits(wm8962->regmap, WM8962_CLOCKING2,
3765 WM8962_SYSCLK_ENA, 0);
3766
3767 /* Ensure we have soft control over all registers */
3768 regmap_update_bits(wm8962->regmap, WM8962_CLOCKING2,
3769 WM8962_CLKREG_OVD, WM8962_CLKREG_OVD);
3770
3771 /* Ensure that the oscillator and PLLs are disabled */
3772 regmap_update_bits(wm8962->regmap, WM8962_PLL2,
3773 WM8962_OSC_ENA | WM8962_PLL2_ENA | WM8962_PLL3_ENA,
3774 0);
3775
3722 regcache_sync(wm8962->regmap); 3776 regcache_sync(wm8962->regmap);
3723 3777
3778 regmap_update_bits(wm8962->regmap, WM8962_ANTI_POP,
3779 WM8962_STARTUP_BIAS_ENA | WM8962_VMID_BUF_ENA,
3780 WM8962_STARTUP_BIAS_ENA | WM8962_VMID_BUF_ENA);
3781
3782 /* Bias enable at 2*5k (fast start-up) */
3783 regmap_update_bits(wm8962->regmap, WM8962_PWR_MGMT_1,
3784 WM8962_BIAS_ENA | WM8962_VMID_SEL_MASK,
3785 WM8962_BIAS_ENA | 0x180);
3786
3787 msleep(5);
3788
3724 return 0; 3789 return 0;
3725} 3790}
3726 3791
diff --git a/sound/soc/codecs/wm8990.c b/sound/soc/codecs/wm8990.c
index 837978e16e9d..253c88bb7a4c 100644
--- a/sound/soc/codecs/wm8990.c
+++ b/sound/soc/codecs/wm8990.c
@@ -151,14 +151,9 @@ static int wm899x_outpga_put_volsw_vu(struct snd_kcontrol *kcontrol,
151} 151}
152 152
153#define SOC_WM899X_OUTPGA_SINGLE_R_TLV(xname, reg, shift, max, invert,\ 153#define SOC_WM899X_OUTPGA_SINGLE_R_TLV(xname, reg, shift, max, invert,\
154 tlv_array) {\ 154 tlv_array) \
155 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \ 155 SOC_SINGLE_EXT_TLV(xname, reg, shift, max, invert, \
156 .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ |\ 156 snd_soc_get_volsw, wm899x_outpga_put_volsw_vu, tlv_array)
157 SNDRV_CTL_ELEM_ACCESS_READWRITE,\
158 .tlv.p = (tlv_array), \
159 .info = snd_soc_info_volsw, \
160 .get = snd_soc_get_volsw, .put = wm899x_outpga_put_volsw_vu, \
161 .private_value = SOC_SINGLE_VALUE(reg, shift, max, invert) }
162 157
163 158
164static const char *wm8990_digital_sidetone[] = 159static const char *wm8990_digital_sidetone[] =
diff --git a/sound/soc/codecs/wm8991.h b/sound/soc/codecs/wm8991.h
index 8a942efd18a5..07707d8d7e20 100644
--- a/sound/soc/codecs/wm8991.h
+++ b/sound/soc/codecs/wm8991.h
@@ -822,12 +822,7 @@
822 822
823#define SOC_WM899X_OUTPGA_SINGLE_R_TLV(xname, reg, shift, max, invert,\ 823#define SOC_WM899X_OUTPGA_SINGLE_R_TLV(xname, reg, shift, max, invert,\
824 tlv_array) \ 824 tlv_array) \
825{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \ 825 SOC_SINGLE_EXT_TLV(xname, reg, shift, max, invert, \
826 .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ |\ 826 snd_soc_get_volsw, wm899x_outpga_put_volsw_vu, tlv_array)
827 SNDRV_CTL_ELEM_ACCESS_READWRITE,\
828 .tlv.p = (tlv_array), \
829 .info = snd_soc_info_volsw, \
830 .get = snd_soc_get_volsw, .put = wm899x_outpga_put_volsw_vu, \
831 .private_value = SOC_SINGLE_VALUE(reg, shift, max, invert) }
832 827
833#endif /* _WM8991_H */ 828#endif /* _WM8991_H */
diff --git a/sound/soc/codecs/wm8994.c b/sound/soc/codecs/wm8994.c
index 29e95f93d482..1d4b1ec66e36 100644
--- a/sound/soc/codecs/wm8994.c
+++ b/sound/soc/codecs/wm8994.c
@@ -16,6 +16,7 @@
16#include <linux/init.h> 16#include <linux/init.h>
17#include <linux/delay.h> 17#include <linux/delay.h>
18#include <linux/pm.h> 18#include <linux/pm.h>
19#include <linux/gcd.h>
19#include <linux/i2c.h> 20#include <linux/i2c.h>
20#include <linux/platform_device.h> 21#include <linux/platform_device.h>
21#include <linux/pm_runtime.h> 22#include <linux/pm_runtime.h>
@@ -289,10 +290,8 @@ static const DECLARE_TLV_DB_SCALE(ng_tlv, -10200, 600, 0);
289static const DECLARE_TLV_DB_SCALE(mixin_boost_tlv, 0, 900, 0); 290static const DECLARE_TLV_DB_SCALE(mixin_boost_tlv, 0, 900, 0);
290 291
291#define WM8994_DRC_SWITCH(xname, reg, shift) \ 292#define WM8994_DRC_SWITCH(xname, reg, shift) \
292{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \ 293 SOC_SINGLE_EXT(xname, reg, shift, 1, 0, \
293 .info = snd_soc_info_volsw, .get = snd_soc_get_volsw,\ 294 snd_soc_get_volsw, wm8994_put_drc_sw)
294 .put = wm8994_put_drc_sw, \
295 .private_value = SOC_SINGLE_VALUE(reg, shift, 1, 0) }
296 295
297static int wm8994_put_drc_sw(struct snd_kcontrol *kcontrol, 296static int wm8994_put_drc_sw(struct snd_kcontrol *kcontrol,
298 struct snd_ctl_elem_value *ucontrol) 297 struct snd_ctl_elem_value *ucontrol)
@@ -1432,10 +1431,8 @@ SOC_DAPM_SINGLE("AIF1.1 Switch", WM8994_DAC2_RIGHT_MIXER_ROUTING,
1432}; 1431};
1433 1432
1434#define WM8994_CLASS_W_SWITCH(xname, reg, shift, max, invert) \ 1433#define WM8994_CLASS_W_SWITCH(xname, reg, shift, max, invert) \
1435{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \ 1434 SOC_SINGLE_EXT(xname, reg, shift, max, invert, \
1436 .info = snd_soc_info_volsw, \ 1435 snd_soc_get_volsw, wm8994_put_class_w)
1437 .get = snd_soc_dapm_get_volsw, .put = wm8994_put_class_w, \
1438 .private_value = SOC_SINGLE_VALUE(reg, shift, max, invert) }
1439 1436
1440static int wm8994_put_class_w(struct snd_kcontrol *kcontrol, 1437static int wm8994_put_class_w(struct snd_kcontrol *kcontrol,
1441 struct snd_ctl_elem_value *ucontrol) 1438 struct snd_ctl_elem_value *ucontrol)
@@ -1498,6 +1495,24 @@ static const char *aif1dac_text[] = {
1498 "AIF1DACDAT", "AIF3DACDAT", 1495 "AIF1DACDAT", "AIF3DACDAT",
1499}; 1496};
1500 1497
1498static const char *loopback_text[] = {
1499 "None", "ADCDAT",
1500};
1501
1502static const struct soc_enum aif1_loopback_enum =
1503 SOC_ENUM_SINGLE(WM8994_AIF1_CONTROL_2, WM8994_AIF1_LOOPBACK_SHIFT, 2,
1504 loopback_text);
1505
1506static const struct snd_kcontrol_new aif1_loopback =
1507 SOC_DAPM_ENUM("AIF1 Loopback", aif1_loopback_enum);
1508
1509static const struct soc_enum aif2_loopback_enum =
1510 SOC_ENUM_SINGLE(WM8994_AIF2_CONTROL_2, WM8994_AIF2_LOOPBACK_SHIFT, 2,
1511 loopback_text);
1512
1513static const struct snd_kcontrol_new aif2_loopback =
1514 SOC_DAPM_ENUM("AIF2 Loopback", aif2_loopback_enum);
1515
1501static const struct soc_enum aif1dac_enum = 1516static const struct soc_enum aif1dac_enum =
1502 SOC_ENUM_SINGLE(WM8994_POWER_MANAGEMENT_6, 0, 2, aif1dac_text); 1517 SOC_ENUM_SINGLE(WM8994_POWER_MANAGEMENT_6, 0, 2, aif1dac_text);
1503 1518
@@ -1744,6 +1759,9 @@ SND_SOC_DAPM_ADC("DMIC1R", NULL, WM8994_POWER_MANAGEMENT_4, 2, 0),
1744SND_SOC_DAPM_ADC("ADCL", NULL, SND_SOC_NOPM, 1, 0), 1759SND_SOC_DAPM_ADC("ADCL", NULL, SND_SOC_NOPM, 1, 0),
1745SND_SOC_DAPM_ADC("ADCR", NULL, SND_SOC_NOPM, 0, 0), 1760SND_SOC_DAPM_ADC("ADCR", NULL, SND_SOC_NOPM, 0, 0),
1746 1761
1762SND_SOC_DAPM_MUX("AIF1 Loopback", SND_SOC_NOPM, 0, 0, &aif1_loopback),
1763SND_SOC_DAPM_MUX("AIF2 Loopback", SND_SOC_NOPM, 0, 0, &aif2_loopback),
1764
1747SND_SOC_DAPM_POST("Debug log", post_ev), 1765SND_SOC_DAPM_POST("Debug log", post_ev),
1748}; 1766};
1749 1767
@@ -1875,9 +1893,9 @@ static const struct snd_soc_dapm_route intercon[] = {
1875 { "AIF1DAC2L", NULL, "AIF1DAC Mux" }, 1893 { "AIF1DAC2L", NULL, "AIF1DAC Mux" },
1876 { "AIF1DAC2R", NULL, "AIF1DAC Mux" }, 1894 { "AIF1DAC2R", NULL, "AIF1DAC Mux" },
1877 1895
1878 { "AIF1DAC Mux", "AIF1DACDAT", "AIF1DACDAT" }, 1896 { "AIF1DAC Mux", "AIF1DACDAT", "AIF1 Loopback" },
1879 { "AIF1DAC Mux", "AIF3DACDAT", "AIF3DACDAT" }, 1897 { "AIF1DAC Mux", "AIF3DACDAT", "AIF3DACDAT" },
1880 { "AIF2DAC Mux", "AIF2DACDAT", "AIF2DACDAT" }, 1898 { "AIF2DAC Mux", "AIF2DACDAT", "AIF2 Loopback" },
1881 { "AIF2DAC Mux", "AIF3DACDAT", "AIF3DACDAT" }, 1899 { "AIF2DAC Mux", "AIF3DACDAT", "AIF3DACDAT" },
1882 { "AIF2ADC Mux", "AIF2ADCDAT", "AIF2ADCL" }, 1900 { "AIF2ADC Mux", "AIF2ADCDAT", "AIF2ADCL" },
1883 { "AIF2ADC Mux", "AIF2ADCDAT", "AIF2ADCR" }, 1901 { "AIF2ADC Mux", "AIF2ADCDAT", "AIF2ADCR" },
@@ -1928,6 +1946,12 @@ static const struct snd_soc_dapm_route intercon[] = {
1928 { "AIF3ADCDAT", "AIF2DACDAT", "AIF2DACL" }, 1946 { "AIF3ADCDAT", "AIF2DACDAT", "AIF2DACL" },
1929 { "AIF3ADCDAT", "AIF2DACDAT", "AIF2DACR" }, 1947 { "AIF3ADCDAT", "AIF2DACDAT", "AIF2DACR" },
1930 1948
1949 /* Loopback */
1950 { "AIF1 Loopback", "ADCDAT", "AIF1ADCDAT" },
1951 { "AIF1 Loopback", "None", "AIF1DACDAT" },
1952 { "AIF2 Loopback", "ADCDAT", "AIF2ADCDAT" },
1953 { "AIF2 Loopback", "None", "AIF2DACDAT" },
1954
1931 /* Sidetone */ 1955 /* Sidetone */
1932 { "Left Sidetone", "ADC/DMIC1", "ADCL Mux" }, 1956 { "Left Sidetone", "ADC/DMIC1", "ADCL Mux" },
1933 { "Left Sidetone", "DMIC2", "DMIC2L" }, 1957 { "Left Sidetone", "DMIC2", "DMIC2L" },
@@ -2010,15 +2034,16 @@ struct fll_div {
2010 u16 outdiv; 2034 u16 outdiv;
2011 u16 n; 2035 u16 n;
2012 u16 k; 2036 u16 k;
2037 u16 lambda;
2013 u16 clk_ref_div; 2038 u16 clk_ref_div;
2014 u16 fll_fratio; 2039 u16 fll_fratio;
2015}; 2040};
2016 2041
2017static int wm8994_get_fll_config(struct fll_div *fll, 2042static int wm8994_get_fll_config(struct wm8994 *control, struct fll_div *fll,
2018 int freq_in, int freq_out) 2043 int freq_in, int freq_out)
2019{ 2044{
2020 u64 Kpart; 2045 u64 Kpart;
2021 unsigned int K, Ndiv, Nmod; 2046 unsigned int K, Ndiv, Nmod, gcd_fll;
2022 2047
2023 pr_debug("FLL input=%dHz, output=%dHz\n", freq_in, freq_out); 2048 pr_debug("FLL input=%dHz, output=%dHz\n", freq_in, freq_out);
2024 2049
@@ -2067,20 +2092,32 @@ static int wm8994_get_fll_config(struct fll_div *fll,
2067 Nmod = freq_out % freq_in; 2092 Nmod = freq_out % freq_in;
2068 pr_debug("Nmod=%d\n", Nmod); 2093 pr_debug("Nmod=%d\n", Nmod);
2069 2094
2070 /* Calculate fractional part - scale up so we can round. */ 2095 switch (control->type) {
2071 Kpart = FIXED_FLL_SIZE * (long long)Nmod; 2096 case WM8994:
2097 /* Calculate fractional part - scale up so we can round. */
2098 Kpart = FIXED_FLL_SIZE * (long long)Nmod;
2099
2100 do_div(Kpart, freq_in);
2101
2102 K = Kpart & 0xFFFFFFFF;
2072 2103
2073 do_div(Kpart, freq_in); 2104 if ((K % 10) >= 5)
2105 K += 5;
2074 2106
2075 K = Kpart & 0xFFFFFFFF; 2107 /* Move down to proper range now rounding is done */
2108 fll->k = K / 10;
2109 fll->lambda = 0;
2076 2110
2077 if ((K % 10) >= 5) 2111 pr_debug("N=%x K=%x\n", fll->n, fll->k);
2078 K += 5; 2112 break;
2079 2113
2080 /* Move down to proper range now rounding is done */ 2114 default:
2081 fll->k = K / 10; 2115 gcd_fll = gcd(freq_out, freq_in);
2082 2116
2083 pr_debug("N=%x K=%x\n", fll->n, fll->k); 2117 fll->k = (freq_out - (freq_in * fll->n)) / gcd_fll;
2118 fll->lambda = freq_in / gcd_fll;
2119
2120 }
2084 2121
2085 return 0; 2122 return 0;
2086} 2123}
@@ -2144,9 +2181,9 @@ static int _wm8994_set_fll(struct snd_soc_codec *codec, int id, int src,
2144 * analysis bugs spewing warnings. 2181 * analysis bugs spewing warnings.
2145 */ 2182 */
2146 if (freq_out) 2183 if (freq_out)
2147 ret = wm8994_get_fll_config(&fll, freq_in, freq_out); 2184 ret = wm8994_get_fll_config(control, &fll, freq_in, freq_out);
2148 else 2185 else
2149 ret = wm8994_get_fll_config(&fll, wm8994->fll[id].in, 2186 ret = wm8994_get_fll_config(control, &fll, wm8994->fll[id].in,
2150 wm8994->fll[id].out); 2187 wm8994->fll[id].out);
2151 if (ret < 0) 2188 if (ret < 0)
2152 return ret; 2189 return ret;
@@ -2191,6 +2228,17 @@ static int _wm8994_set_fll(struct snd_soc_codec *codec, int id, int src,
2191 WM8994_FLL1_N_MASK, 2228 WM8994_FLL1_N_MASK,
2192 fll.n << WM8994_FLL1_N_SHIFT); 2229 fll.n << WM8994_FLL1_N_SHIFT);
2193 2230
2231 if (fll.lambda) {
2232 snd_soc_update_bits(codec, WM8958_FLL1_EFS_1 + reg_offset,
2233 WM8958_FLL1_LAMBDA_MASK,
2234 fll.lambda);
2235 snd_soc_update_bits(codec, WM8958_FLL1_EFS_2 + reg_offset,
2236 WM8958_FLL1_EFS_ENA, WM8958_FLL1_EFS_ENA);
2237 } else {
2238 snd_soc_update_bits(codec, WM8958_FLL1_EFS_2 + reg_offset,
2239 WM8958_FLL1_EFS_ENA, 0);
2240 }
2241
2194 snd_soc_update_bits(codec, WM8994_FLL1_CONTROL_5 + reg_offset, 2242 snd_soc_update_bits(codec, WM8994_FLL1_CONTROL_5 + reg_offset,
2195 WM8994_FLL1_FRC_NCO | WM8958_FLL1_BYP | 2243 WM8994_FLL1_FRC_NCO | WM8958_FLL1_BYP |
2196 WM8994_FLL1_REFCLK_DIV_MASK | 2244 WM8994_FLL1_REFCLK_DIV_MASK |
@@ -2555,17 +2603,24 @@ static int wm8994_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
2555 struct wm8994 *control = wm8994->wm8994; 2603 struct wm8994 *control = wm8994->wm8994;
2556 int ms_reg; 2604 int ms_reg;
2557 int aif1_reg; 2605 int aif1_reg;
2606 int dac_reg;
2607 int adc_reg;
2558 int ms = 0; 2608 int ms = 0;
2559 int aif1 = 0; 2609 int aif1 = 0;
2610 int lrclk = 0;
2560 2611
2561 switch (dai->id) { 2612 switch (dai->id) {
2562 case 1: 2613 case 1:
2563 ms_reg = WM8994_AIF1_MASTER_SLAVE; 2614 ms_reg = WM8994_AIF1_MASTER_SLAVE;
2564 aif1_reg = WM8994_AIF1_CONTROL_1; 2615 aif1_reg = WM8994_AIF1_CONTROL_1;
2616 dac_reg = WM8994_AIF1DAC_LRCLK;
2617 adc_reg = WM8994_AIF1ADC_LRCLK;
2565 break; 2618 break;
2566 case 2: 2619 case 2:
2567 ms_reg = WM8994_AIF2_MASTER_SLAVE; 2620 ms_reg = WM8994_AIF2_MASTER_SLAVE;
2568 aif1_reg = WM8994_AIF2_CONTROL_1; 2621 aif1_reg = WM8994_AIF2_CONTROL_1;
2622 dac_reg = WM8994_AIF1DAC_LRCLK;
2623 adc_reg = WM8994_AIF1ADC_LRCLK;
2569 break; 2624 break;
2570 default: 2625 default:
2571 return -EINVAL; 2626 return -EINVAL;
@@ -2584,6 +2639,7 @@ static int wm8994_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
2584 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { 2639 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
2585 case SND_SOC_DAIFMT_DSP_B: 2640 case SND_SOC_DAIFMT_DSP_B:
2586 aif1 |= WM8994_AIF1_LRCLK_INV; 2641 aif1 |= WM8994_AIF1_LRCLK_INV;
2642 lrclk |= WM8958_AIF1_LRCLK_INV;
2587 case SND_SOC_DAIFMT_DSP_A: 2643 case SND_SOC_DAIFMT_DSP_A:
2588 aif1 |= 0x18; 2644 aif1 |= 0x18;
2589 break; 2645 break;
@@ -2622,12 +2678,14 @@ static int wm8994_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
2622 break; 2678 break;
2623 case SND_SOC_DAIFMT_IB_IF: 2679 case SND_SOC_DAIFMT_IB_IF:
2624 aif1 |= WM8994_AIF1_BCLK_INV | WM8994_AIF1_LRCLK_INV; 2680 aif1 |= WM8994_AIF1_BCLK_INV | WM8994_AIF1_LRCLK_INV;
2681 lrclk |= WM8958_AIF1_LRCLK_INV;
2625 break; 2682 break;
2626 case SND_SOC_DAIFMT_IB_NF: 2683 case SND_SOC_DAIFMT_IB_NF:
2627 aif1 |= WM8994_AIF1_BCLK_INV; 2684 aif1 |= WM8994_AIF1_BCLK_INV;
2628 break; 2685 break;
2629 case SND_SOC_DAIFMT_NB_IF: 2686 case SND_SOC_DAIFMT_NB_IF:
2630 aif1 |= WM8994_AIF1_LRCLK_INV; 2687 aif1 |= WM8994_AIF1_LRCLK_INV;
2688 lrclk |= WM8958_AIF1_LRCLK_INV;
2631 break; 2689 break;
2632 default: 2690 default:
2633 return -EINVAL; 2691 return -EINVAL;
@@ -2658,6 +2716,10 @@ static int wm8994_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
2658 aif1); 2716 aif1);
2659 snd_soc_update_bits(codec, ms_reg, WM8994_AIF1_MSTR, 2717 snd_soc_update_bits(codec, ms_reg, WM8994_AIF1_MSTR,
2660 ms); 2718 ms);
2719 snd_soc_update_bits(codec, dac_reg,
2720 WM8958_AIF1_LRCLK_INV, lrclk);
2721 snd_soc_update_bits(codec, adc_reg,
2722 WM8958_AIF1_LRCLK_INV, lrclk);
2661 2723
2662 return 0; 2724 return 0;
2663} 2725}
@@ -3096,24 +3158,7 @@ static int wm8994_codec_suspend(struct snd_soc_codec *codec)
3096static int wm8994_codec_resume(struct snd_soc_codec *codec) 3158static int wm8994_codec_resume(struct snd_soc_codec *codec)
3097{ 3159{
3098 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); 3160 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
3099 struct wm8994 *control = wm8994->wm8994;
3100 int i, ret; 3161 int i, ret;
3101 unsigned int val, mask;
3102
3103 if (control->revision < 4) {
3104 /* force a HW read */
3105 ret = regmap_read(control->regmap,
3106 WM8994_POWER_MANAGEMENT_5, &val);
3107
3108 /* modify the cache only */
3109 codec->cache_only = 1;
3110 mask = WM8994_DAC1R_ENA | WM8994_DAC1L_ENA |
3111 WM8994_DAC2R_ENA | WM8994_DAC2L_ENA;
3112 val &= mask;
3113 snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_5,
3114 mask, val);
3115 codec->cache_only = 0;
3116 }
3117 3162
3118 for (i = 0; i < ARRAY_SIZE(wm8994->fll); i++) { 3163 for (i = 0; i < ARRAY_SIZE(wm8994->fll); i++) {
3119 if (!wm8994->fll_suspend[i].out) 3164 if (!wm8994->fll_suspend[i].out)
@@ -3495,6 +3540,31 @@ static void wm8958_button_det(struct snd_soc_codec *codec, u16 status)
3495 wm8994->btn_mask); 3540 wm8994->btn_mask);
3496} 3541}
3497 3542
3543static void wm8958_open_circuit_work(struct work_struct *work)
3544{
3545 struct wm8994_priv *wm8994 = container_of(work,
3546 struct wm8994_priv,
3547 open_circuit_work.work);
3548 struct device *dev = wm8994->wm8994->dev;
3549
3550 wm1811_micd_stop(wm8994->hubs.codec);
3551
3552 mutex_lock(&wm8994->accdet_lock);
3553
3554 dev_dbg(dev, "Reporting open circuit\n");
3555
3556 wm8994->jack_mic = false;
3557 wm8994->mic_detecting = true;
3558
3559 wm8958_micd_set_rate(wm8994->hubs.codec);
3560
3561 snd_soc_jack_report(wm8994->micdet[0].jack, 0,
3562 wm8994->btn_mask |
3563 SND_JACK_HEADSET);
3564
3565 mutex_unlock(&wm8994->accdet_lock);
3566}
3567
3498static void wm8958_mic_id(void *data, u16 status) 3568static void wm8958_mic_id(void *data, u16 status)
3499{ 3569{
3500 struct snd_soc_codec *codec = data; 3570 struct snd_soc_codec *codec = data;
@@ -3504,16 +3574,9 @@ static void wm8958_mic_id(void *data, u16 status)
3504 if (!(status & WM8958_MICD_STS)) { 3574 if (!(status & WM8958_MICD_STS)) {
3505 /* If nothing present then clear our statuses */ 3575 /* If nothing present then clear our statuses */
3506 dev_dbg(codec->dev, "Detected open circuit\n"); 3576 dev_dbg(codec->dev, "Detected open circuit\n");
3507 wm8994->jack_mic = false;
3508 wm8994->mic_detecting = true;
3509
3510 wm1811_micd_stop(codec);
3511
3512 wm8958_micd_set_rate(codec);
3513 3577
3514 snd_soc_jack_report(wm8994->micdet[0].jack, 0, 3578 schedule_delayed_work(&wm8994->open_circuit_work,
3515 wm8994->btn_mask | 3579 msecs_to_jiffies(2500));
3516 SND_JACK_HEADSET);
3517 return; 3580 return;
3518 } 3581 }
3519 3582
@@ -3598,6 +3661,8 @@ static irqreturn_t wm1811_jackdet_irq(int irq, void *data)
3598 3661
3599 pm_runtime_get_sync(codec->dev); 3662 pm_runtime_get_sync(codec->dev);
3600 3663
3664 cancel_delayed_work_sync(&wm8994->mic_complete_work);
3665
3601 mutex_lock(&wm8994->accdet_lock); 3666 mutex_lock(&wm8994->accdet_lock);
3602 3667
3603 reg = snd_soc_read(codec, WM1811_JACKDET_CTRL); 3668 reg = snd_soc_read(codec, WM1811_JACKDET_CTRL);
@@ -3780,11 +3845,33 @@ int wm8958_mic_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack,
3780} 3845}
3781EXPORT_SYMBOL_GPL(wm8958_mic_detect); 3846EXPORT_SYMBOL_GPL(wm8958_mic_detect);
3782 3847
3848static void wm8958_mic_work(struct work_struct *work)
3849{
3850 struct wm8994_priv *wm8994 = container_of(work,
3851 struct wm8994_priv,
3852 mic_complete_work.work);
3853 struct snd_soc_codec *codec = wm8994->hubs.codec;
3854
3855 dev_crit(codec->dev, "MIC WORK %x\n", wm8994->mic_status);
3856
3857 pm_runtime_get_sync(codec->dev);
3858
3859 mutex_lock(&wm8994->accdet_lock);
3860
3861 wm8994->mic_id_cb(wm8994->mic_id_cb_data, wm8994->mic_status);
3862
3863 mutex_unlock(&wm8994->accdet_lock);
3864
3865 pm_runtime_put(codec->dev);
3866
3867 dev_crit(codec->dev, "MIC WORK %x DONE\n", wm8994->mic_status);
3868}
3869
3783static irqreturn_t wm8958_mic_irq(int irq, void *data) 3870static irqreturn_t wm8958_mic_irq(int irq, void *data)
3784{ 3871{
3785 struct wm8994_priv *wm8994 = data; 3872 struct wm8994_priv *wm8994 = data;
3786 struct snd_soc_codec *codec = wm8994->hubs.codec; 3873 struct snd_soc_codec *codec = wm8994->hubs.codec;
3787 int reg, count, ret; 3874 int reg, count, ret, id_delay;
3788 3875
3789 /* 3876 /*
3790 * Jack detection may have detected a removal simulataneously 3877 * Jack detection may have detected a removal simulataneously
@@ -3794,6 +3881,9 @@ static irqreturn_t wm8958_mic_irq(int irq, void *data)
3794 if (!(snd_soc_read(codec, WM8958_MIC_DETECT_1) & WM8958_MICD_ENA)) 3881 if (!(snd_soc_read(codec, WM8958_MIC_DETECT_1) & WM8958_MICD_ENA))
3795 return IRQ_HANDLED; 3882 return IRQ_HANDLED;
3796 3883
3884 cancel_delayed_work_sync(&wm8994->mic_complete_work);
3885 cancel_delayed_work_sync(&wm8994->open_circuit_work);
3886
3797 pm_runtime_get_sync(codec->dev); 3887 pm_runtime_get_sync(codec->dev);
3798 3888
3799 /* We may occasionally read a detection without an impedence 3889 /* We may occasionally read a detection without an impedence
@@ -3846,8 +3936,12 @@ static irqreturn_t wm8958_mic_irq(int irq, void *data)
3846 goto out; 3936 goto out;
3847 } 3937 }
3848 3938
3939 wm8994->mic_status = reg;
3940 id_delay = wm8994->wm8994->pdata.mic_id_delay;
3941
3849 if (wm8994->mic_detecting) 3942 if (wm8994->mic_detecting)
3850 wm8994->mic_id_cb(wm8994->mic_id_cb_data, reg); 3943 schedule_delayed_work(&wm8994->mic_complete_work,
3944 msecs_to_jiffies(id_delay));
3851 else 3945 else
3852 wm8958_button_det(codec, reg); 3946 wm8958_button_det(codec, reg);
3853 3947
@@ -3899,6 +3993,8 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec)
3899 mutex_init(&wm8994->accdet_lock); 3993 mutex_init(&wm8994->accdet_lock);
3900 INIT_DELAYED_WORK(&wm8994->jackdet_bootstrap, 3994 INIT_DELAYED_WORK(&wm8994->jackdet_bootstrap,
3901 wm1811_jackdet_bootstrap); 3995 wm1811_jackdet_bootstrap);
3996 INIT_DELAYED_WORK(&wm8994->open_circuit_work,
3997 wm8958_open_circuit_work);
3902 3998
3903 switch (control->type) { 3999 switch (control->type) {
3904 case WM8994: 4000 case WM8994:
@@ -3911,6 +4007,8 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec)
3911 break; 4007 break;
3912 } 4008 }
3913 4009
4010 INIT_DELAYED_WORK(&wm8994->mic_complete_work, wm8958_mic_work);
4011
3914 for (i = 0; i < ARRAY_SIZE(wm8994->fll_locked); i++) 4012 for (i = 0; i < ARRAY_SIZE(wm8994->fll_locked); i++)
3915 init_completion(&wm8994->fll_locked[i]); 4013 init_completion(&wm8994->fll_locked[i]);
3916 4014
diff --git a/sound/soc/codecs/wm8994.h b/sound/soc/codecs/wm8994.h
index 55ddf4d57d9b..6536f8d45ac6 100644
--- a/sound/soc/codecs/wm8994.h
+++ b/sound/soc/codecs/wm8994.h
@@ -134,6 +134,9 @@ struct wm8994_priv {
134 struct mutex accdet_lock; 134 struct mutex accdet_lock;
135 struct wm8994_micdet micdet[2]; 135 struct wm8994_micdet micdet[2];
136 struct delayed_work mic_work; 136 struct delayed_work mic_work;
137 struct delayed_work open_circuit_work;
138 struct delayed_work mic_complete_work;
139 u16 mic_status;
137 bool mic_detecting; 140 bool mic_detecting;
138 bool jack_mic; 141 bool jack_mic;
139 int btn_mask; 142 int btn_mask;
diff --git a/sound/soc/codecs/wm8995.h b/sound/soc/codecs/wm8995.h
index 5642121c4977..508ad27fe2bb 100644
--- a/sound/soc/codecs/wm8995.h
+++ b/sound/soc/codecs/wm8995.h
@@ -4237,11 +4237,8 @@
4237#define WM8995_SPK2_MUTE_SEQ1_WIDTH 8 /* SPK2_MUTE_SEQ1 - [7:0] */ 4237#define WM8995_SPK2_MUTE_SEQ1_WIDTH 8 /* SPK2_MUTE_SEQ1 - [7:0] */
4238 4238
4239#define WM8995_CLASS_W_SWITCH(xname, reg, shift, max, invert) \ 4239#define WM8995_CLASS_W_SWITCH(xname, reg, shift, max, invert) \
4240{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \ 4240 SOC_SINGLE_EXT(xname, reg, shift, max, invert, \
4241 .info = snd_soc_info_volsw, \ 4241 snd_soc_dapm_get_volsw, wm8995_put_class_w)
4242 .get = snd_soc_dapm_get_volsw, .put = wm8995_put_class_w, \
4243 .private_value = SOC_SINGLE_VALUE(reg, shift, max, invert) \
4244}
4245 4242
4246struct wm8995_reg_access { 4243struct wm8995_reg_access {
4247 u16 read; 4244 u16 read;
diff --git a/sound/soc/codecs/wm9705.c b/sound/soc/codecs/wm9705.c
index 05b1f346695b..70ce6793c5bd 100644
--- a/sound/soc/codecs/wm9705.c
+++ b/sound/soc/codecs/wm9705.c
@@ -209,7 +209,7 @@ static unsigned int ac97_read(struct snd_soc_codec *codec, unsigned int reg)
209 case AC97_RESET: 209 case AC97_RESET:
210 case AC97_VENDOR_ID1: 210 case AC97_VENDOR_ID1:
211 case AC97_VENDOR_ID2: 211 case AC97_VENDOR_ID2:
212 return soc_ac97_ops.read(codec->ac97, reg); 212 return soc_ac97_ops->read(codec->ac97, reg);
213 default: 213 default:
214 reg = reg >> 1; 214 reg = reg >> 1;
215 215
@@ -225,7 +225,7 @@ static int ac97_write(struct snd_soc_codec *codec, unsigned int reg,
225{ 225{
226 u16 *cache = codec->reg_cache; 226 u16 *cache = codec->reg_cache;
227 227
228 soc_ac97_ops.write(codec->ac97, reg, val); 228 soc_ac97_ops->write(codec->ac97, reg, val);
229 reg = reg >> 1; 229 reg = reg >> 1;
230 if (reg < (ARRAY_SIZE(wm9705_reg))) 230 if (reg < (ARRAY_SIZE(wm9705_reg)))
231 cache[reg] = val; 231 cache[reg] = val;
@@ -294,8 +294,8 @@ static struct snd_soc_dai_driver wm9705_dai[] = {
294 294
295static int wm9705_reset(struct snd_soc_codec *codec) 295static int wm9705_reset(struct snd_soc_codec *codec)
296{ 296{
297 if (soc_ac97_ops.reset) { 297 if (soc_ac97_ops->reset) {
298 soc_ac97_ops.reset(codec->ac97); 298 soc_ac97_ops->reset(codec->ac97);
299 if (ac97_read(codec, 0) == wm9705_reg[0]) 299 if (ac97_read(codec, 0) == wm9705_reg[0])
300 return 0; /* Success */ 300 return 0; /* Success */
301 } 301 }
@@ -306,7 +306,7 @@ static int wm9705_reset(struct snd_soc_codec *codec)
306#ifdef CONFIG_PM 306#ifdef CONFIG_PM
307static int wm9705_soc_suspend(struct snd_soc_codec *codec) 307static int wm9705_soc_suspend(struct snd_soc_codec *codec)
308{ 308{
309 soc_ac97_ops.write(codec->ac97, AC97_POWERDOWN, 0xffff); 309 soc_ac97_ops->write(codec->ac97, AC97_POWERDOWN, 0xffff);
310 310
311 return 0; 311 return 0;
312} 312}
@@ -323,7 +323,7 @@ static int wm9705_soc_resume(struct snd_soc_codec *codec)
323 } 323 }
324 324
325 for (i = 2; i < ARRAY_SIZE(wm9705_reg) << 1; i += 2) { 325 for (i = 2; i < ARRAY_SIZE(wm9705_reg) << 1; i += 2) {
326 soc_ac97_ops.write(codec->ac97, i, cache[i>>1]); 326 soc_ac97_ops->write(codec->ac97, i, cache[i>>1]);
327 } 327 }
328 328
329 return 0; 329 return 0;
@@ -337,9 +337,7 @@ static int wm9705_soc_probe(struct snd_soc_codec *codec)
337{ 337{
338 int ret = 0; 338 int ret = 0;
339 339
340 printk(KERN_INFO "WM9705 SoC Audio Codec\n"); 340 ret = snd_soc_new_ac97_codec(codec, soc_ac97_ops, 0);
341
342 ret = snd_soc_new_ac97_codec(codec, &soc_ac97_ops, 0);
343 if (ret < 0) { 341 if (ret < 0) {
344 printk(KERN_ERR "wm9705: failed to register AC97 codec\n"); 342 printk(KERN_ERR "wm9705: failed to register AC97 codec\n");
345 return ret; 343 return ret;
diff --git a/sound/soc/codecs/wm9712.c b/sound/soc/codecs/wm9712.c
index 8e9a6a3eeb1a..c5eb746087b4 100644
--- a/sound/soc/codecs/wm9712.c
+++ b/sound/soc/codecs/wm9712.c
@@ -455,7 +455,7 @@ static unsigned int ac97_read(struct snd_soc_codec *codec,
455 if (reg == AC97_RESET || reg == AC97_GPIO_STATUS || 455 if (reg == AC97_RESET || reg == AC97_GPIO_STATUS ||
456 reg == AC97_VENDOR_ID1 || reg == AC97_VENDOR_ID2 || 456 reg == AC97_VENDOR_ID1 || reg == AC97_VENDOR_ID2 ||
457 reg == AC97_REC_GAIN) 457 reg == AC97_REC_GAIN)
458 return soc_ac97_ops.read(codec->ac97, reg); 458 return soc_ac97_ops->read(codec->ac97, reg);
459 else { 459 else {
460 reg = reg >> 1; 460 reg = reg >> 1;
461 461
@@ -472,7 +472,7 @@ static int ac97_write(struct snd_soc_codec *codec, unsigned int reg,
472 u16 *cache = codec->reg_cache; 472 u16 *cache = codec->reg_cache;
473 473
474 if (reg < 0x7c) 474 if (reg < 0x7c)
475 soc_ac97_ops.write(codec->ac97, reg, val); 475 soc_ac97_ops->write(codec->ac97, reg, val);
476 reg = reg >> 1; 476 reg = reg >> 1;
477 if (reg < (ARRAY_SIZE(wm9712_reg))) 477 if (reg < (ARRAY_SIZE(wm9712_reg)))
478 cache[reg] = val; 478 cache[reg] = val;
@@ -581,15 +581,15 @@ static int wm9712_set_bias_level(struct snd_soc_codec *codec,
581 581
582static int wm9712_reset(struct snd_soc_codec *codec, int try_warm) 582static int wm9712_reset(struct snd_soc_codec *codec, int try_warm)
583{ 583{
584 if (try_warm && soc_ac97_ops.warm_reset) { 584 if (try_warm && soc_ac97_ops->warm_reset) {
585 soc_ac97_ops.warm_reset(codec->ac97); 585 soc_ac97_ops->warm_reset(codec->ac97);
586 if (ac97_read(codec, 0) == wm9712_reg[0]) 586 if (ac97_read(codec, 0) == wm9712_reg[0])
587 return 1; 587 return 1;
588 } 588 }
589 589
590 soc_ac97_ops.reset(codec->ac97); 590 soc_ac97_ops->reset(codec->ac97);
591 if (soc_ac97_ops.warm_reset) 591 if (soc_ac97_ops->warm_reset)
592 soc_ac97_ops.warm_reset(codec->ac97); 592 soc_ac97_ops->warm_reset(codec->ac97);
593 if (ac97_read(codec, 0) != wm9712_reg[0]) 593 if (ac97_read(codec, 0) != wm9712_reg[0])
594 goto err; 594 goto err;
595 return 0; 595 return 0;
@@ -624,7 +624,7 @@ static int wm9712_soc_resume(struct snd_soc_codec *codec)
624 if (i == AC97_INT_PAGING || i == AC97_POWERDOWN || 624 if (i == AC97_INT_PAGING || i == AC97_POWERDOWN ||
625 (i > 0x58 && i != 0x5c)) 625 (i > 0x58 && i != 0x5c))
626 continue; 626 continue;
627 soc_ac97_ops.write(codec->ac97, i, cache[i>>1]); 627 soc_ac97_ops->write(codec->ac97, i, cache[i>>1]);
628 } 628 }
629 } 629 }
630 630
@@ -635,7 +635,7 @@ static int wm9712_soc_probe(struct snd_soc_codec *codec)
635{ 635{
636 int ret = 0; 636 int ret = 0;
637 637
638 ret = snd_soc_new_ac97_codec(codec, &soc_ac97_ops, 0); 638 ret = snd_soc_new_ac97_codec(codec, soc_ac97_ops, 0);
639 if (ret < 0) { 639 if (ret < 0) {
640 printk(KERN_ERR "wm9712: failed to register AC97 codec\n"); 640 printk(KERN_ERR "wm9712: failed to register AC97 codec\n");
641 return ret; 641 return ret;
diff --git a/sound/soc/codecs/wm9713.c b/sound/soc/codecs/wm9713.c
index f7afa68d8c7f..a53e175c015a 100644
--- a/sound/soc/codecs/wm9713.c
+++ b/sound/soc/codecs/wm9713.c
@@ -652,7 +652,7 @@ static unsigned int ac97_read(struct snd_soc_codec *codec,
652 if (reg == AC97_RESET || reg == AC97_GPIO_STATUS || 652 if (reg == AC97_RESET || reg == AC97_GPIO_STATUS ||
653 reg == AC97_VENDOR_ID1 || reg == AC97_VENDOR_ID2 || 653 reg == AC97_VENDOR_ID1 || reg == AC97_VENDOR_ID2 ||
654 reg == AC97_CD) 654 reg == AC97_CD)
655 return soc_ac97_ops.read(codec->ac97, reg); 655 return soc_ac97_ops->read(codec->ac97, reg);
656 else { 656 else {
657 reg = reg >> 1; 657 reg = reg >> 1;
658 658
@@ -668,7 +668,7 @@ static int ac97_write(struct snd_soc_codec *codec, unsigned int reg,
668{ 668{
669 u16 *cache = codec->reg_cache; 669 u16 *cache = codec->reg_cache;
670 if (reg < 0x7c) 670 if (reg < 0x7c)
671 soc_ac97_ops.write(codec->ac97, reg, val); 671 soc_ac97_ops->write(codec->ac97, reg, val);
672 reg = reg >> 1; 672 reg = reg >> 1;
673 if (reg < (ARRAY_SIZE(wm9713_reg))) 673 if (reg < (ARRAY_SIZE(wm9713_reg)))
674 cache[reg] = val; 674 cache[reg] = val;
@@ -1095,15 +1095,15 @@ static struct snd_soc_dai_driver wm9713_dai[] = {
1095 1095
1096int wm9713_reset(struct snd_soc_codec *codec, int try_warm) 1096int wm9713_reset(struct snd_soc_codec *codec, int try_warm)
1097{ 1097{
1098 if (try_warm && soc_ac97_ops.warm_reset) { 1098 if (try_warm && soc_ac97_ops->warm_reset) {
1099 soc_ac97_ops.warm_reset(codec->ac97); 1099 soc_ac97_ops->warm_reset(codec->ac97);
1100 if (ac97_read(codec, 0) == wm9713_reg[0]) 1100 if (ac97_read(codec, 0) == wm9713_reg[0])
1101 return 1; 1101 return 1;
1102 } 1102 }
1103 1103
1104 soc_ac97_ops.reset(codec->ac97); 1104 soc_ac97_ops->reset(codec->ac97);
1105 if (soc_ac97_ops.warm_reset) 1105 if (soc_ac97_ops->warm_reset)
1106 soc_ac97_ops.warm_reset(codec->ac97); 1106 soc_ac97_ops->warm_reset(codec->ac97);
1107 if (ac97_read(codec, 0) != wm9713_reg[0]) 1107 if (ac97_read(codec, 0) != wm9713_reg[0])
1108 return -EIO; 1108 return -EIO;
1109 return 0; 1109 return 0;
@@ -1180,7 +1180,7 @@ static int wm9713_soc_resume(struct snd_soc_codec *codec)
1180 if (i == AC97_POWERDOWN || i == AC97_EXTENDED_MID || 1180 if (i == AC97_POWERDOWN || i == AC97_EXTENDED_MID ||
1181 i == AC97_EXTENDED_MSTATUS || i > 0x66) 1181 i == AC97_EXTENDED_MSTATUS || i > 0x66)
1182 continue; 1182 continue;
1183 soc_ac97_ops.write(codec->ac97, i, cache[i>>1]); 1183 soc_ac97_ops->write(codec->ac97, i, cache[i>>1]);
1184 } 1184 }
1185 } 1185 }
1186 1186
@@ -1197,7 +1197,7 @@ static int wm9713_soc_probe(struct snd_soc_codec *codec)
1197 return -ENOMEM; 1197 return -ENOMEM;
1198 snd_soc_codec_set_drvdata(codec, wm9713); 1198 snd_soc_codec_set_drvdata(codec, wm9713);
1199 1199
1200 ret = snd_soc_new_ac97_codec(codec, &soc_ac97_ops, 0); 1200 ret = snd_soc_new_ac97_codec(codec, soc_ac97_ops, 0);
1201 if (ret < 0) 1201 if (ret < 0)
1202 goto codec_err; 1202 goto codec_err;
1203 1203
diff --git a/sound/soc/codecs/wm_adsp.c b/sound/soc/codecs/wm_adsp.c
index 3470b649c0b2..05252ac936a3 100644
--- a/sound/soc/codecs/wm_adsp.c
+++ b/sound/soc/codecs/wm_adsp.c
@@ -21,6 +21,7 @@
21#include <linux/regmap.h> 21#include <linux/regmap.h>
22#include <linux/regulator/consumer.h> 22#include <linux/regulator/consumer.h>
23#include <linux/slab.h> 23#include <linux/slab.h>
24#include <linux/workqueue.h>
24#include <sound/core.h> 25#include <sound/core.h>
25#include <sound/pcm.h> 26#include <sound/pcm.h>
26#include <sound/pcm_params.h> 27#include <sound/pcm_params.h>
@@ -215,6 +216,36 @@ static struct {
215 [WM_ADSP_FW_RX_ANC] = { .file = "rx-anc" }, 216 [WM_ADSP_FW_RX_ANC] = { .file = "rx-anc" },
216}; 217};
217 218
219struct wm_coeff_ctl_ops {
220 int (*xget)(struct snd_kcontrol *kcontrol,
221 struct snd_ctl_elem_value *ucontrol);
222 int (*xput)(struct snd_kcontrol *kcontrol,
223 struct snd_ctl_elem_value *ucontrol);
224 int (*xinfo)(struct snd_kcontrol *kcontrol,
225 struct snd_ctl_elem_info *uinfo);
226};
227
228struct wm_coeff {
229 struct device *dev;
230 struct list_head ctl_list;
231 struct regmap *regmap;
232};
233
234struct wm_coeff_ctl {
235 const char *name;
236 struct snd_card *card;
237 struct wm_adsp_alg_region region;
238 struct wm_coeff_ctl_ops ops;
239 struct wm_adsp *adsp;
240 void *private;
241 unsigned int enabled:1;
242 struct list_head list;
243 void *cache;
244 size_t len;
245 unsigned int set:1;
246 struct snd_kcontrol *kcontrol;
247};
248
218static int wm_adsp_fw_get(struct snd_kcontrol *kcontrol, 249static int wm_adsp_fw_get(struct snd_kcontrol *kcontrol,
219 struct snd_ctl_elem_value *ucontrol) 250 struct snd_ctl_elem_value *ucontrol)
220{ 251{
@@ -279,7 +310,7 @@ static const struct soc_enum wm_adsp2_rate_enum[] = {
279 ARIZONA_DSP1_RATE_SHIFT, 0xf, 310 ARIZONA_DSP1_RATE_SHIFT, 0xf,
280 ARIZONA_RATE_ENUM_SIZE, 311 ARIZONA_RATE_ENUM_SIZE,
281 arizona_rate_text, arizona_rate_val), 312 arizona_rate_text, arizona_rate_val),
282 SOC_VALUE_ENUM_SINGLE(ARIZONA_DSP3_CONTROL_1, 313 SOC_VALUE_ENUM_SINGLE(ARIZONA_DSP4_CONTROL_1,
283 ARIZONA_DSP1_RATE_SHIFT, 0xf, 314 ARIZONA_DSP1_RATE_SHIFT, 0xf,
284 ARIZONA_RATE_ENUM_SIZE, 315 ARIZONA_RATE_ENUM_SIZE,
285 arizona_rate_text, arizona_rate_val), 316 arizona_rate_text, arizona_rate_val),
@@ -334,6 +365,181 @@ static unsigned int wm_adsp_region_to_reg(struct wm_adsp_region const *region,
334 } 365 }
335} 366}
336 367
368static int wm_coeff_info(struct snd_kcontrol *kcontrol,
369 struct snd_ctl_elem_info *uinfo)
370{
371 struct wm_coeff_ctl *ctl = (struct wm_coeff_ctl *)kcontrol->private_value;
372
373 uinfo->type = SNDRV_CTL_ELEM_TYPE_BYTES;
374 uinfo->count = ctl->len;
375 return 0;
376}
377
378static int wm_coeff_write_control(struct snd_kcontrol *kcontrol,
379 const void *buf, size_t len)
380{
381 struct wm_coeff *wm_coeff= snd_kcontrol_chip(kcontrol);
382 struct wm_coeff_ctl *ctl = (struct wm_coeff_ctl *)kcontrol->private_value;
383 struct wm_adsp_alg_region *region = &ctl->region;
384 const struct wm_adsp_region *mem;
385 struct wm_adsp *adsp = ctl->adsp;
386 void *scratch;
387 int ret;
388 unsigned int reg;
389
390 mem = wm_adsp_find_region(adsp, region->type);
391 if (!mem) {
392 adsp_err(adsp, "No base for region %x\n",
393 region->type);
394 return -EINVAL;
395 }
396
397 reg = ctl->region.base;
398 reg = wm_adsp_region_to_reg(mem, reg);
399
400 scratch = kmemdup(buf, ctl->len, GFP_KERNEL | GFP_DMA);
401 if (!scratch)
402 return -ENOMEM;
403
404 ret = regmap_raw_write(wm_coeff->regmap, reg, scratch,
405 ctl->len);
406 if (ret) {
407 adsp_err(adsp, "Failed to write %zu bytes to %x\n",
408 ctl->len, reg);
409 kfree(scratch);
410 return ret;
411 }
412
413 kfree(scratch);
414
415 return 0;
416}
417
418static int wm_coeff_put(struct snd_kcontrol *kcontrol,
419 struct snd_ctl_elem_value *ucontrol)
420{
421 struct wm_coeff_ctl *ctl = (struct wm_coeff_ctl *)kcontrol->private_value;
422 char *p = ucontrol->value.bytes.data;
423
424 memcpy(ctl->cache, p, ctl->len);
425
426 if (!ctl->enabled) {
427 ctl->set = 1;
428 return 0;
429 }
430
431 return wm_coeff_write_control(kcontrol, p, ctl->len);
432}
433
434static int wm_coeff_read_control(struct snd_kcontrol *kcontrol,
435 void *buf, size_t len)
436{
437 struct wm_coeff *wm_coeff= snd_kcontrol_chip(kcontrol);
438 struct wm_coeff_ctl *ctl = (struct wm_coeff_ctl *)kcontrol->private_value;
439 struct wm_adsp_alg_region *region = &ctl->region;
440 const struct wm_adsp_region *mem;
441 struct wm_adsp *adsp = ctl->adsp;
442 void *scratch;
443 int ret;
444 unsigned int reg;
445
446 mem = wm_adsp_find_region(adsp, region->type);
447 if (!mem) {
448 adsp_err(adsp, "No base for region %x\n",
449 region->type);
450 return -EINVAL;
451 }
452
453 reg = ctl->region.base;
454 reg = wm_adsp_region_to_reg(mem, reg);
455
456 scratch = kmalloc(ctl->len, GFP_KERNEL | GFP_DMA);
457 if (!scratch)
458 return -ENOMEM;
459
460 ret = regmap_raw_read(wm_coeff->regmap, reg, scratch, ctl->len);
461 if (ret) {
462 adsp_err(adsp, "Failed to read %zu bytes from %x\n",
463 ctl->len, reg);
464 kfree(scratch);
465 return ret;
466 }
467
468 memcpy(buf, scratch, ctl->len);
469 kfree(scratch);
470
471 return 0;
472}
473
474static int wm_coeff_get(struct snd_kcontrol *kcontrol,
475 struct snd_ctl_elem_value *ucontrol)
476{
477 struct wm_coeff_ctl *ctl = (struct wm_coeff_ctl *)kcontrol->private_value;
478 char *p = ucontrol->value.bytes.data;
479
480 memcpy(p, ctl->cache, ctl->len);
481 return 0;
482}
483
484static int wm_coeff_add_kcontrol(struct wm_coeff *wm_coeff,
485 struct wm_coeff_ctl *ctl,
486 const struct snd_kcontrol_new *kctl)
487{
488 int ret;
489 struct snd_kcontrol *kcontrol;
490
491 kcontrol = snd_ctl_new1(kctl, wm_coeff);
492 ret = snd_ctl_add(ctl->card, kcontrol);
493 if (ret < 0) {
494 dev_err(wm_coeff->dev, "Failed to add %s: %d\n",
495 kctl->name, ret);
496 return ret;
497 }
498 ctl->kcontrol = kcontrol;
499 return 0;
500}
501
502struct wmfw_ctl_work {
503 struct wm_coeff *wm_coeff;
504 struct wm_coeff_ctl *ctl;
505 struct work_struct work;
506};
507
508static int wmfw_add_ctl(struct wm_coeff *wm_coeff,
509 struct wm_coeff_ctl *ctl)
510{
511 struct snd_kcontrol_new *kcontrol;
512 int ret;
513
514 if (!wm_coeff || !ctl || !ctl->name || !ctl->card)
515 return -EINVAL;
516
517 kcontrol = kzalloc(sizeof(*kcontrol), GFP_KERNEL);
518 if (!kcontrol)
519 return -ENOMEM;
520 kcontrol->iface = SNDRV_CTL_ELEM_IFACE_MIXER;
521
522 kcontrol->name = ctl->name;
523 kcontrol->info = wm_coeff_info;
524 kcontrol->get = wm_coeff_get;
525 kcontrol->put = wm_coeff_put;
526 kcontrol->private_value = (unsigned long)ctl;
527
528 ret = wm_coeff_add_kcontrol(wm_coeff,
529 ctl, kcontrol);
530 if (ret < 0)
531 goto err_kcontrol;
532
533 kfree(kcontrol);
534
535 list_add(&ctl->list, &wm_coeff->ctl_list);
536 return 0;
537
538err_kcontrol:
539 kfree(kcontrol);
540 return ret;
541}
542
337static int wm_adsp_load(struct wm_adsp *dsp) 543static int wm_adsp_load(struct wm_adsp *dsp)
338{ 544{
339 LIST_HEAD(buf_list); 545 LIST_HEAD(buf_list);
@@ -547,7 +753,157 @@ out:
547 return ret; 753 return ret;
548} 754}
549 755
550static int wm_adsp_setup_algs(struct wm_adsp *dsp) 756static int wm_coeff_init_control_caches(struct wm_coeff *wm_coeff)
757{
758 struct wm_coeff_ctl *ctl;
759 int ret;
760
761 list_for_each_entry(ctl, &wm_coeff->ctl_list,
762 list) {
763 if (!ctl->enabled || ctl->set)
764 continue;
765 ret = wm_coeff_read_control(ctl->kcontrol,
766 ctl->cache,
767 ctl->len);
768 if (ret < 0)
769 return ret;
770 }
771
772 return 0;
773}
774
775static int wm_coeff_sync_controls(struct wm_coeff *wm_coeff)
776{
777 struct wm_coeff_ctl *ctl;
778 int ret;
779
780 list_for_each_entry(ctl, &wm_coeff->ctl_list,
781 list) {
782 if (!ctl->enabled)
783 continue;
784 if (ctl->set) {
785 ret = wm_coeff_write_control(ctl->kcontrol,
786 ctl->cache,
787 ctl->len);
788 if (ret < 0)
789 return ret;
790 }
791 }
792
793 return 0;
794}
795
796static void wm_adsp_ctl_work(struct work_struct *work)
797{
798 struct wmfw_ctl_work *ctl_work = container_of(work,
799 struct wmfw_ctl_work,
800 work);
801
802 wmfw_add_ctl(ctl_work->wm_coeff, ctl_work->ctl);
803 kfree(ctl_work);
804}
805
806static int wm_adsp_create_control(struct snd_soc_codec *codec,
807 const struct wm_adsp_alg_region *region)
808
809{
810 struct wm_adsp *dsp = snd_soc_codec_get_drvdata(codec);
811 struct wm_coeff_ctl *ctl;
812 struct wmfw_ctl_work *ctl_work;
813 char *name;
814 char *region_name;
815 int ret;
816
817 name = kmalloc(PAGE_SIZE, GFP_KERNEL);
818 if (!name)
819 return -ENOMEM;
820
821 switch (region->type) {
822 case WMFW_ADSP1_PM:
823 region_name = "PM";
824 break;
825 case WMFW_ADSP1_DM:
826 region_name = "DM";
827 break;
828 case WMFW_ADSP2_XM:
829 region_name = "XM";
830 break;
831 case WMFW_ADSP2_YM:
832 region_name = "YM";
833 break;
834 case WMFW_ADSP1_ZM:
835 region_name = "ZM";
836 break;
837 default:
838 ret = -EINVAL;
839 goto err_name;
840 }
841
842 snprintf(name, PAGE_SIZE, "DSP%d %s %x",
843 dsp->num, region_name, region->alg);
844
845 list_for_each_entry(ctl, &dsp->wm_coeff->ctl_list,
846 list) {
847 if (!strcmp(ctl->name, name)) {
848 if (!ctl->enabled)
849 ctl->enabled = 1;
850 goto found;
851 }
852 }
853
854 ctl = kzalloc(sizeof(*ctl), GFP_KERNEL);
855 if (!ctl) {
856 ret = -ENOMEM;
857 goto err_name;
858 }
859 ctl->region = *region;
860 ctl->name = kmemdup(name, strlen(name) + 1, GFP_KERNEL);
861 if (!ctl->name) {
862 ret = -ENOMEM;
863 goto err_ctl;
864 }
865 ctl->enabled = 1;
866 ctl->set = 0;
867 ctl->ops.xget = wm_coeff_get;
868 ctl->ops.xput = wm_coeff_put;
869 ctl->card = codec->card->snd_card;
870 ctl->adsp = dsp;
871
872 ctl->len = region->len;
873 ctl->cache = kzalloc(ctl->len, GFP_KERNEL);
874 if (!ctl->cache) {
875 ret = -ENOMEM;
876 goto err_ctl_name;
877 }
878
879 ctl_work = kzalloc(sizeof(*ctl_work), GFP_KERNEL);
880 if (!ctl_work) {
881 ret = -ENOMEM;
882 goto err_ctl_cache;
883 }
884
885 ctl_work->wm_coeff = dsp->wm_coeff;
886 ctl_work->ctl = ctl;
887 INIT_WORK(&ctl_work->work, wm_adsp_ctl_work);
888 schedule_work(&ctl_work->work);
889
890found:
891 kfree(name);
892
893 return 0;
894
895err_ctl_cache:
896 kfree(ctl->cache);
897err_ctl_name:
898 kfree(ctl->name);
899err_ctl:
900 kfree(ctl);
901err_name:
902 kfree(name);
903 return ret;
904}
905
906static int wm_adsp_setup_algs(struct wm_adsp *dsp, struct snd_soc_codec *codec)
551{ 907{
552 struct regmap *regmap = dsp->regmap; 908 struct regmap *regmap = dsp->regmap;
553 struct wmfw_adsp1_id_hdr adsp1_id; 909 struct wmfw_adsp1_id_hdr adsp1_id;
@@ -730,7 +1086,16 @@ static int wm_adsp_setup_algs(struct wm_adsp *dsp)
730 region->type = WMFW_ADSP1_DM; 1086 region->type = WMFW_ADSP1_DM;
731 region->alg = be32_to_cpu(adsp1_alg[i].alg.id); 1087 region->alg = be32_to_cpu(adsp1_alg[i].alg.id);
732 region->base = be32_to_cpu(adsp1_alg[i].dm); 1088 region->base = be32_to_cpu(adsp1_alg[i].dm);
1089 region->len = 0;
733 list_add_tail(&region->list, &dsp->alg_regions); 1090 list_add_tail(&region->list, &dsp->alg_regions);
1091 if (i + 1 < algs) {
1092 region->len = be32_to_cpu(adsp1_alg[i + 1].dm);
1093 region->len -= be32_to_cpu(adsp1_alg[i].dm);
1094 wm_adsp_create_control(codec, region);
1095 } else {
1096 adsp_warn(dsp, "Missing length info for region DM with ID %x\n",
1097 be32_to_cpu(adsp1_alg[i].alg.id));
1098 }
734 1099
735 region = kzalloc(sizeof(*region), GFP_KERNEL); 1100 region = kzalloc(sizeof(*region), GFP_KERNEL);
736 if (!region) 1101 if (!region)
@@ -738,7 +1103,16 @@ static int wm_adsp_setup_algs(struct wm_adsp *dsp)
738 region->type = WMFW_ADSP1_ZM; 1103 region->type = WMFW_ADSP1_ZM;
739 region->alg = be32_to_cpu(adsp1_alg[i].alg.id); 1104 region->alg = be32_to_cpu(adsp1_alg[i].alg.id);
740 region->base = be32_to_cpu(adsp1_alg[i].zm); 1105 region->base = be32_to_cpu(adsp1_alg[i].zm);
1106 region->len = 0;
741 list_add_tail(&region->list, &dsp->alg_regions); 1107 list_add_tail(&region->list, &dsp->alg_regions);
1108 if (i + 1 < algs) {
1109 region->len = be32_to_cpu(adsp1_alg[i + 1].zm);
1110 region->len -= be32_to_cpu(adsp1_alg[i].zm);
1111 wm_adsp_create_control(codec, region);
1112 } else {
1113 adsp_warn(dsp, "Missing length info for region ZM with ID %x\n",
1114 be32_to_cpu(adsp1_alg[i].alg.id));
1115 }
742 break; 1116 break;
743 1117
744 case WMFW_ADSP2: 1118 case WMFW_ADSP2:
@@ -758,7 +1132,16 @@ static int wm_adsp_setup_algs(struct wm_adsp *dsp)
758 region->type = WMFW_ADSP2_XM; 1132 region->type = WMFW_ADSP2_XM;
759 region->alg = be32_to_cpu(adsp2_alg[i].alg.id); 1133 region->alg = be32_to_cpu(adsp2_alg[i].alg.id);
760 region->base = be32_to_cpu(adsp2_alg[i].xm); 1134 region->base = be32_to_cpu(adsp2_alg[i].xm);
1135 region->len = 0;
761 list_add_tail(&region->list, &dsp->alg_regions); 1136 list_add_tail(&region->list, &dsp->alg_regions);
1137 if (i + 1 < algs) {
1138 region->len = be32_to_cpu(adsp2_alg[i + 1].xm);
1139 region->len -= be32_to_cpu(adsp2_alg[i].xm);
1140 wm_adsp_create_control(codec, region);
1141 } else {
1142 adsp_warn(dsp, "Missing length info for region XM with ID %x\n",
1143 be32_to_cpu(adsp2_alg[i].alg.id));
1144 }
762 1145
763 region = kzalloc(sizeof(*region), GFP_KERNEL); 1146 region = kzalloc(sizeof(*region), GFP_KERNEL);
764 if (!region) 1147 if (!region)
@@ -766,7 +1149,16 @@ static int wm_adsp_setup_algs(struct wm_adsp *dsp)
766 region->type = WMFW_ADSP2_YM; 1149 region->type = WMFW_ADSP2_YM;
767 region->alg = be32_to_cpu(adsp2_alg[i].alg.id); 1150 region->alg = be32_to_cpu(adsp2_alg[i].alg.id);
768 region->base = be32_to_cpu(adsp2_alg[i].ym); 1151 region->base = be32_to_cpu(adsp2_alg[i].ym);
1152 region->len = 0;
769 list_add_tail(&region->list, &dsp->alg_regions); 1153 list_add_tail(&region->list, &dsp->alg_regions);
1154 if (i + 1 < algs) {
1155 region->len = be32_to_cpu(adsp2_alg[i + 1].ym);
1156 region->len -= be32_to_cpu(adsp2_alg[i].ym);
1157 wm_adsp_create_control(codec, region);
1158 } else {
1159 adsp_warn(dsp, "Missing length info for region YM with ID %x\n",
1160 be32_to_cpu(adsp2_alg[i].alg.id));
1161 }
770 1162
771 region = kzalloc(sizeof(*region), GFP_KERNEL); 1163 region = kzalloc(sizeof(*region), GFP_KERNEL);
772 if (!region) 1164 if (!region)
@@ -774,7 +1166,16 @@ static int wm_adsp_setup_algs(struct wm_adsp *dsp)
774 region->type = WMFW_ADSP2_ZM; 1166 region->type = WMFW_ADSP2_ZM;
775 region->alg = be32_to_cpu(adsp2_alg[i].alg.id); 1167 region->alg = be32_to_cpu(adsp2_alg[i].alg.id);
776 region->base = be32_to_cpu(adsp2_alg[i].zm); 1168 region->base = be32_to_cpu(adsp2_alg[i].zm);
1169 region->len = 0;
777 list_add_tail(&region->list, &dsp->alg_regions); 1170 list_add_tail(&region->list, &dsp->alg_regions);
1171 if (i + 1 < algs) {
1172 region->len = be32_to_cpu(adsp2_alg[i + 1].zm);
1173 region->len -= be32_to_cpu(adsp2_alg[i].zm);
1174 wm_adsp_create_control(codec, region);
1175 } else {
1176 adsp_warn(dsp, "Missing length info for region ZM with ID %x\n",
1177 be32_to_cpu(adsp2_alg[i].alg.id));
1178 }
778 break; 1179 break;
779 } 1180 }
780 } 1181 }
@@ -986,6 +1387,7 @@ int wm_adsp1_event(struct snd_soc_dapm_widget *w,
986 struct snd_soc_codec *codec = w->codec; 1387 struct snd_soc_codec *codec = w->codec;
987 struct wm_adsp *dsps = snd_soc_codec_get_drvdata(codec); 1388 struct wm_adsp *dsps = snd_soc_codec_get_drvdata(codec);
988 struct wm_adsp *dsp = &dsps[w->shift]; 1389 struct wm_adsp *dsp = &dsps[w->shift];
1390 struct wm_coeff_ctl *ctl;
989 int ret; 1391 int ret;
990 int val; 1392 int val;
991 1393
@@ -1023,7 +1425,7 @@ int wm_adsp1_event(struct snd_soc_dapm_widget *w,
1023 if (ret != 0) 1425 if (ret != 0)
1024 goto err; 1426 goto err;
1025 1427
1026 ret = wm_adsp_setup_algs(dsp); 1428 ret = wm_adsp_setup_algs(dsp, codec);
1027 if (ret != 0) 1429 if (ret != 0)
1028 goto err; 1430 goto err;
1029 1431
@@ -1031,6 +1433,16 @@ int wm_adsp1_event(struct snd_soc_dapm_widget *w,
1031 if (ret != 0) 1433 if (ret != 0)
1032 goto err; 1434 goto err;
1033 1435
1436 /* Initialize caches for enabled and unset controls */
1437 ret = wm_coeff_init_control_caches(dsp->wm_coeff);
1438 if (ret != 0)
1439 goto err;
1440
1441 /* Sync set controls */
1442 ret = wm_coeff_sync_controls(dsp->wm_coeff);
1443 if (ret != 0)
1444 goto err;
1445
1034 /* Start the core running */ 1446 /* Start the core running */
1035 regmap_update_bits(dsp->regmap, dsp->base + ADSP1_CONTROL_30, 1447 regmap_update_bits(dsp->regmap, dsp->base + ADSP1_CONTROL_30,
1036 ADSP1_CORE_ENA | ADSP1_START, 1448 ADSP1_CORE_ENA | ADSP1_START,
@@ -1047,6 +1459,11 @@ int wm_adsp1_event(struct snd_soc_dapm_widget *w,
1047 1459
1048 regmap_update_bits(dsp->regmap, dsp->base + ADSP1_CONTROL_30, 1460 regmap_update_bits(dsp->regmap, dsp->base + ADSP1_CONTROL_30,
1049 ADSP1_SYS_ENA, 0); 1461 ADSP1_SYS_ENA, 0);
1462
1463 list_for_each_entry(ctl, &dsp->wm_coeff->ctl_list,
1464 list) {
1465 ctl->enabled = 0;
1466 }
1050 break; 1467 break;
1051 1468
1052 default: 1469 default:
@@ -1099,6 +1516,7 @@ int wm_adsp2_event(struct snd_soc_dapm_widget *w,
1099 struct wm_adsp *dsps = snd_soc_codec_get_drvdata(codec); 1516 struct wm_adsp *dsps = snd_soc_codec_get_drvdata(codec);
1100 struct wm_adsp *dsp = &dsps[w->shift]; 1517 struct wm_adsp *dsp = &dsps[w->shift];
1101 struct wm_adsp_alg_region *alg_region; 1518 struct wm_adsp_alg_region *alg_region;
1519 struct wm_coeff_ctl *ctl;
1102 unsigned int val; 1520 unsigned int val;
1103 int ret; 1521 int ret;
1104 1522
@@ -1164,7 +1582,7 @@ int wm_adsp2_event(struct snd_soc_dapm_widget *w,
1164 if (ret != 0) 1582 if (ret != 0)
1165 goto err; 1583 goto err;
1166 1584
1167 ret = wm_adsp_setup_algs(dsp); 1585 ret = wm_adsp_setup_algs(dsp, codec);
1168 if (ret != 0) 1586 if (ret != 0)
1169 goto err; 1587 goto err;
1170 1588
@@ -1172,6 +1590,16 @@ int wm_adsp2_event(struct snd_soc_dapm_widget *w,
1172 if (ret != 0) 1590 if (ret != 0)
1173 goto err; 1591 goto err;
1174 1592
1593 /* Initialize caches for enabled and unset controls */
1594 ret = wm_coeff_init_control_caches(dsp->wm_coeff);
1595 if (ret != 0)
1596 goto err;
1597
1598 /* Sync set controls */
1599 ret = wm_coeff_sync_controls(dsp->wm_coeff);
1600 if (ret != 0)
1601 goto err;
1602
1175 ret = regmap_update_bits(dsp->regmap, 1603 ret = regmap_update_bits(dsp->regmap,
1176 dsp->base + ADSP2_CONTROL, 1604 dsp->base + ADSP2_CONTROL,
1177 ADSP2_CORE_ENA | ADSP2_START, 1605 ADSP2_CORE_ENA | ADSP2_START,
@@ -1209,6 +1637,11 @@ int wm_adsp2_event(struct snd_soc_dapm_widget *w,
1209 ret); 1637 ret);
1210 } 1638 }
1211 1639
1640 list_for_each_entry(ctl, &dsp->wm_coeff->ctl_list,
1641 list) {
1642 ctl->enabled = 0;
1643 }
1644
1212 while (!list_empty(&dsp->alg_regions)) { 1645 while (!list_empty(&dsp->alg_regions)) {
1213 alg_region = list_first_entry(&dsp->alg_regions, 1646 alg_region = list_first_entry(&dsp->alg_regions,
1214 struct wm_adsp_alg_region, 1647 struct wm_adsp_alg_region,
@@ -1247,36 +1680,48 @@ int wm_adsp2_init(struct wm_adsp *adsp, bool dvfs)
1247 1680
1248 INIT_LIST_HEAD(&adsp->alg_regions); 1681 INIT_LIST_HEAD(&adsp->alg_regions);
1249 1682
1683 adsp->wm_coeff = kzalloc(sizeof(*adsp->wm_coeff),
1684 GFP_KERNEL);
1685 if (!adsp->wm_coeff)
1686 return -ENOMEM;
1687 adsp->wm_coeff->regmap = adsp->regmap;
1688 adsp->wm_coeff->dev = adsp->dev;
1689 INIT_LIST_HEAD(&adsp->wm_coeff->ctl_list);
1690
1250 if (dvfs) { 1691 if (dvfs) {
1251 adsp->dvfs = devm_regulator_get(adsp->dev, "DCVDD"); 1692 adsp->dvfs = devm_regulator_get(adsp->dev, "DCVDD");
1252 if (IS_ERR(adsp->dvfs)) { 1693 if (IS_ERR(adsp->dvfs)) {
1253 ret = PTR_ERR(adsp->dvfs); 1694 ret = PTR_ERR(adsp->dvfs);
1254 dev_err(adsp->dev, "Failed to get DCVDD: %d\n", ret); 1695 dev_err(adsp->dev, "Failed to get DCVDD: %d\n", ret);
1255 return ret; 1696 goto out_coeff;
1256 } 1697 }
1257 1698
1258 ret = regulator_enable(adsp->dvfs); 1699 ret = regulator_enable(adsp->dvfs);
1259 if (ret != 0) { 1700 if (ret != 0) {
1260 dev_err(adsp->dev, "Failed to enable DCVDD: %d\n", 1701 dev_err(adsp->dev, "Failed to enable DCVDD: %d\n",
1261 ret); 1702 ret);
1262 return ret; 1703 goto out_coeff;
1263 } 1704 }
1264 1705
1265 ret = regulator_set_voltage(adsp->dvfs, 1200000, 1800000); 1706 ret = regulator_set_voltage(adsp->dvfs, 1200000, 1800000);
1266 if (ret != 0) { 1707 if (ret != 0) {
1267 dev_err(adsp->dev, "Failed to initialise DVFS: %d\n", 1708 dev_err(adsp->dev, "Failed to initialise DVFS: %d\n",
1268 ret); 1709 ret);
1269 return ret; 1710 goto out_coeff;
1270 } 1711 }
1271 1712
1272 ret = regulator_disable(adsp->dvfs); 1713 ret = regulator_disable(adsp->dvfs);
1273 if (ret != 0) { 1714 if (ret != 0) {
1274 dev_err(adsp->dev, "Failed to disable DCVDD: %d\n", 1715 dev_err(adsp->dev, "Failed to disable DCVDD: %d\n",
1275 ret); 1716 ret);
1276 return ret; 1717 goto out_coeff;
1277 } 1718 }
1278 } 1719 }
1279 1720
1280 return 0; 1721 return 0;
1722
1723out_coeff:
1724 kfree(adsp->wm_coeff);
1725 return ret;
1281} 1726}
1282EXPORT_SYMBOL_GPL(wm_adsp2_init); 1727EXPORT_SYMBOL_GPL(wm_adsp2_init);
diff --git a/sound/soc/codecs/wm_adsp.h b/sound/soc/codecs/wm_adsp.h
index fea514627526..9f922c82536c 100644
--- a/sound/soc/codecs/wm_adsp.h
+++ b/sound/soc/codecs/wm_adsp.h
@@ -30,6 +30,7 @@ struct wm_adsp_alg_region {
30 unsigned int alg; 30 unsigned int alg;
31 int type; 31 int type;
32 unsigned int base; 32 unsigned int base;
33 size_t len;
33}; 34};
34 35
35struct wm_adsp { 36struct wm_adsp {
@@ -55,17 +56,17 @@ struct wm_adsp {
55 bool running; 56 bool running;
56 57
57 struct regulator *dvfs; 58 struct regulator *dvfs;
59
60 struct wm_coeff *wm_coeff;
58}; 61};
59 62
60#define WM_ADSP1(wname, num) \ 63#define WM_ADSP1(wname, num) \
61 { .id = snd_soc_dapm_pga, .name = wname, .reg = SND_SOC_NOPM, \ 64 SND_SOC_DAPM_PGA_E(wname, SND_SOC_NOPM, num, 0, NULL, 0, \
62 .shift = num, .event = wm_adsp1_event, \ 65 wm_adsp1_event, SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD)
63 .event_flags = SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD }
64 66
65#define WM_ADSP2(wname, num) \ 67#define WM_ADSP2(wname, num) \
66{ .id = snd_soc_dapm_pga, .name = wname, .reg = SND_SOC_NOPM, \ 68 SND_SOC_DAPM_PGA_E(wname, SND_SOC_NOPM, num, 0, NULL, 0, \
67 .shift = num, .event = wm_adsp2_event, \ 69 wm_adsp2_event, SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD)
68 .event_flags = SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD }
69 70
70extern const struct snd_kcontrol_new wm_adsp1_fw_controls[]; 71extern const struct snd_kcontrol_new wm_adsp1_fw_controls[];
71extern const struct snd_kcontrol_new wm_adsp2_fw_controls[]; 72extern const struct snd_kcontrol_new wm_adsp2_fw_controls[];
diff --git a/sound/soc/codecs/wm_hubs.c b/sound/soc/codecs/wm_hubs.c
index f5d81b948759..2d9e099415a5 100644
--- a/sound/soc/codecs/wm_hubs.c
+++ b/sound/soc/codecs/wm_hubs.c
@@ -693,10 +693,8 @@ void wm_hubs_update_class_w(struct snd_soc_codec *codec)
693EXPORT_SYMBOL_GPL(wm_hubs_update_class_w); 693EXPORT_SYMBOL_GPL(wm_hubs_update_class_w);
694 694
695#define WM_HUBS_SINGLE_W(xname, reg, shift, max, invert) \ 695#define WM_HUBS_SINGLE_W(xname, reg, shift, max, invert) \
696{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \ 696 SOC_SINGLE_EXT(xname, reg, shift, max, invert, \
697 .info = snd_soc_info_volsw, \ 697 snd_soc_dapm_get_volsw, class_w_put_volsw)
698 .get = snd_soc_dapm_get_volsw, .put = class_w_put_volsw, \
699 .private_value = SOC_SINGLE_VALUE(reg, shift, max, invert) }
700 698
701static int class_w_put_volsw(struct snd_kcontrol *kcontrol, 699static int class_w_put_volsw(struct snd_kcontrol *kcontrol,
702 struct snd_ctl_elem_value *ucontrol) 700 struct snd_ctl_elem_value *ucontrol)
diff --git a/sound/soc/davinci/Kconfig b/sound/soc/davinci/Kconfig
index 9e11a14d1b45..c82f89c9475b 100644
--- a/sound/soc/davinci/Kconfig
+++ b/sound/soc/davinci/Kconfig
@@ -54,16 +54,6 @@ config SND_DM6467_SOC_EVM
54 help 54 help
55 Say Y if you want to add support for SoC audio on TI 55 Say Y if you want to add support for SoC audio on TI
56 56
57config SND_DAVINCI_SOC_SFFSDR
58 tristate "SoC Audio support for SFFSDR"
59 depends on SND_DAVINCI_SOC && MACH_SFFSDR
60 select SND_DAVINCI_SOC_I2S
61 select SND_SOC_PCM3008
62 select SFFSDR_FPGA
63 help
64 Say Y if you want to add support for SoC audio on
65 Lyrtech SFFSDR board.
66
67config SND_DA830_SOC_EVM 57config SND_DA830_SOC_EVM
68 tristate "SoC Audio support for DA830/OMAP-L137 EVM" 58 tristate "SoC Audio support for DA830/OMAP-L137 EVM"
69 depends on SND_DAVINCI_SOC && MACH_DAVINCI_DA830_EVM 59 depends on SND_DAVINCI_SOC && MACH_DAVINCI_DA830_EVM
diff --git a/sound/soc/davinci/Makefile b/sound/soc/davinci/Makefile
index a93679d618cd..a396ab6d6d5e 100644
--- a/sound/soc/davinci/Makefile
+++ b/sound/soc/davinci/Makefile
@@ -11,10 +11,8 @@ obj-$(CONFIG_SND_DAVINCI_SOC_VCIF) += snd-soc-davinci-vcif.o
11 11
12# DAVINCI Machine Support 12# DAVINCI Machine Support
13snd-soc-evm-objs := davinci-evm.o 13snd-soc-evm-objs := davinci-evm.o
14snd-soc-sffsdr-objs := davinci-sffsdr.o
15 14
16obj-$(CONFIG_SND_DAVINCI_SOC_EVM) += snd-soc-evm.o 15obj-$(CONFIG_SND_DAVINCI_SOC_EVM) += snd-soc-evm.o
17obj-$(CONFIG_SND_DM6467_SOC_EVM) += snd-soc-evm.o 16obj-$(CONFIG_SND_DM6467_SOC_EVM) += snd-soc-evm.o
18obj-$(CONFIG_SND_DA830_SOC_EVM) += snd-soc-evm.o 17obj-$(CONFIG_SND_DA830_SOC_EVM) += snd-soc-evm.o
19obj-$(CONFIG_SND_DA850_SOC_EVM) += snd-soc-evm.o 18obj-$(CONFIG_SND_DA850_SOC_EVM) += snd-soc-evm.o
20obj-$(CONFIG_SND_DAVINCI_SOC_SFFSDR) += snd-soc-sffsdr.o
diff --git a/sound/soc/davinci/davinci-mcasp.c b/sound/soc/davinci/davinci-mcasp.c
index 81490febac6d..32ddb7fe5034 100644
--- a/sound/soc/davinci/davinci-mcasp.c
+++ b/sound/soc/davinci/davinci-mcasp.c
@@ -1024,7 +1024,7 @@ static struct snd_platform_data *davinci_mcasp_set_pdata_from_of(
1024 struct device_node *np = pdev->dev.of_node; 1024 struct device_node *np = pdev->dev.of_node;
1025 struct snd_platform_data *pdata = NULL; 1025 struct snd_platform_data *pdata = NULL;
1026 const struct of_device_id *match = 1026 const struct of_device_id *match =
1027 of_match_device(of_match_ptr(mcasp_dt_ids), &pdev->dev); 1027 of_match_device(mcasp_dt_ids, &pdev->dev);
1028 1028
1029 const u32 *of_serial_dir32; 1029 const u32 *of_serial_dir32;
1030 u8 *of_serial_dir; 1030 u8 *of_serial_dir;
@@ -1257,7 +1257,7 @@ static struct platform_driver davinci_mcasp_driver = {
1257 .driver = { 1257 .driver = {
1258 .name = "davinci-mcasp", 1258 .name = "davinci-mcasp",
1259 .owner = THIS_MODULE, 1259 .owner = THIS_MODULE,
1260 .of_match_table = of_match_ptr(mcasp_dt_ids), 1260 .of_match_table = mcasp_dt_ids,
1261 }, 1261 },
1262}; 1262};
1263 1263
diff --git a/sound/soc/davinci/davinci-sffsdr.c b/sound/soc/davinci/davinci-sffsdr.c
deleted file mode 100644
index 5be65aae7e0e..000000000000
--- a/sound/soc/davinci/davinci-sffsdr.c
+++ /dev/null
@@ -1,181 +0,0 @@
1/*
2 * ASoC driver for Lyrtech SFFSDR board.
3 *
4 * Author: Hugo Villeneuve
5 * Copyright (C) 2008 Lyrtech inc
6 *
7 * Based on ASoC driver for TI DAVINCI EVM platform, original copyright follow:
8 * Copyright: (C) 2007 MontaVista Software, Inc., <source@mvista.com>
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation.
13 */
14
15#include <linux/module.h>
16#include <linux/moduleparam.h>
17#include <linux/timer.h>
18#include <linux/interrupt.h>
19#include <linux/platform_device.h>
20#include <linux/gpio.h>
21#include <sound/core.h>
22#include <sound/pcm.h>
23#include <sound/soc.h>
24
25#include <asm/dma.h>
26#include <asm/mach-types.h>
27#ifdef CONFIG_SFFSDR_FPGA
28#include <asm/plat-sffsdr/sffsdr-fpga.h>
29#endif
30
31#include <mach/edma.h>
32
33#include "../codecs/pcm3008.h"
34#include "davinci-pcm.h"
35#include "davinci-i2s.h"
36
37/*
38 * CLKX and CLKR are the inputs for the Sample Rate Generator.
39 * FSX and FSR are outputs, driven by the sample Rate Generator.
40 */
41#define AUDIO_FORMAT (SND_SOC_DAIFMT_DSP_B | \
42 SND_SOC_DAIFMT_CBM_CFS | \
43 SND_SOC_DAIFMT_IB_NF)
44
45static int sffsdr_hw_params(struct snd_pcm_substream *substream,
46 struct snd_pcm_hw_params *params)
47{
48 struct snd_soc_pcm_runtime *rtd = substream->private_data;
49 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
50 int fs;
51 int ret = 0;
52
53 /* Fsref can be 32000, 44100 or 48000. */
54 fs = params_rate(params);
55
56#ifndef CONFIG_SFFSDR_FPGA
57 /* Without the FPGA module, the Fs is fixed at 44100 Hz */
58 if (fs != 44100) {
59 pr_debug("warning: only 44.1 kHz is supported without SFFSDR FPGA module\n");
60 return -EINVAL;
61 }
62#endif
63
64 /* set cpu DAI configuration */
65 ret = snd_soc_dai_set_fmt(cpu_dai, AUDIO_FORMAT);
66 if (ret < 0)
67 return ret;
68
69 pr_debug("sffsdr_hw_params: rate = %d Hz\n", fs);
70
71#ifndef CONFIG_SFFSDR_FPGA
72 return 0;
73#else
74 return sffsdr_fpga_set_codec_fs(fs);
75#endif
76}
77
78static struct snd_soc_ops sffsdr_ops = {
79 .hw_params = sffsdr_hw_params,
80};
81
82/* davinci-sffsdr digital audio interface glue - connects codec <--> CPU */
83static struct snd_soc_dai_link sffsdr_dai = {
84 .name = "PCM3008", /* Codec name */
85 .stream_name = "PCM3008 HiFi",
86 .cpu_dai_name = "davinci-mcbsp",
87 .codec_dai_name = "pcm3008-hifi",
88 .codec_name = "pcm3008-codec",
89 .platform_name = "davinci-mcbsp",
90 .ops = &sffsdr_ops,
91};
92
93/* davinci-sffsdr audio machine driver */
94static struct snd_soc_card snd_soc_sffsdr = {
95 .name = "DaVinci SFFSDR",
96 .owner = THIS_MODULE,
97 .dai_link = &sffsdr_dai,
98 .num_links = 1,
99};
100
101/* sffsdr audio private data */
102static struct pcm3008_setup_data sffsdr_pcm3008_setup = {
103 .dem0_pin = GPIO(45),
104 .dem1_pin = GPIO(46),
105 .pdad_pin = GPIO(47),
106 .pdda_pin = GPIO(38),
107};
108
109struct platform_device pcm3008_codec = {
110 .name = "pcm3008-codec",
111 .id = 0,
112 .dev = {
113 .platform_data = &sffsdr_pcm3008_setup,
114 },
115};
116
117static struct resource sffsdr_snd_resources[] = {
118 {
119 .start = DAVINCI_MCBSP_BASE,
120 .end = DAVINCI_MCBSP_BASE + SZ_8K - 1,
121 .flags = IORESOURCE_MEM,
122 },
123};
124
125static struct evm_snd_platform_data sffsdr_snd_data = {
126 .tx_dma_ch = DAVINCI_DMA_MCBSP_TX,
127 .rx_dma_ch = DAVINCI_DMA_MCBSP_RX,
128};
129
130static struct platform_device *sffsdr_snd_device;
131
132static int __init sffsdr_init(void)
133{
134 int ret;
135
136 if (!machine_is_sffsdr())
137 return -EINVAL;
138
139 platform_device_register(&pcm3008_codec);
140
141 sffsdr_snd_device = platform_device_alloc("soc-audio", 0);
142 if (!sffsdr_snd_device) {
143 printk(KERN_ERR "platform device allocation failed\n");
144 return -ENOMEM;
145 }
146
147 platform_set_drvdata(sffsdr_snd_device, &snd_soc_sffsdr);
148 platform_device_add_data(sffsdr_snd_device, &sffsdr_snd_data,
149 sizeof(sffsdr_snd_data));
150
151 ret = platform_device_add_resources(sffsdr_snd_device,
152 sffsdr_snd_resources,
153 ARRAY_SIZE(sffsdr_snd_resources));
154 if (ret) {
155 printk(KERN_ERR "platform device add resources failed\n");
156 goto error;
157 }
158
159 ret = platform_device_add(sffsdr_snd_device);
160 if (ret)
161 goto error;
162
163 return ret;
164
165error:
166 platform_device_put(sffsdr_snd_device);
167 return ret;
168}
169
170static void __exit sffsdr_exit(void)
171{
172 platform_device_unregister(sffsdr_snd_device);
173 platform_device_unregister(&pcm3008_codec);
174}
175
176module_init(sffsdr_init);
177module_exit(sffsdr_exit);
178
179MODULE_AUTHOR("Hugo Villeneuve");
180MODULE_DESCRIPTION("Lyrtech SFFSDR ASoC driver");
181MODULE_LICENSE("GPL");
diff --git a/sound/soc/dwc/designware_i2s.c b/sound/soc/dwc/designware_i2s.c
index 593a3ea12d4c..70eb37a5dd16 100644
--- a/sound/soc/dwc/designware_i2s.c
+++ b/sound/soc/dwc/designware_i2s.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * ALSA SoC Synopsys I2S Audio Layer 2 * ALSA SoC Synopsys I2S Audio Layer
3 * 3 *
4 * sound/soc/spear/designware_i2s.c 4 * sound/soc/dwc/designware_i2s.c
5 * 5 *
6 * Copyright (C) 2010 ST Microelectronics 6 * Copyright (C) 2010 ST Microelectronics
7 * Rajeev Kumar <rajeev-dlh.kumar@st.com> 7 * Rajeev Kumar <rajeev-dlh.kumar@st.com>
@@ -396,7 +396,7 @@ static int dw_i2s_probe(struct platform_device *pdev)
396 } 396 }
397 397
398 if (cap & DWC_I2S_PLAY) { 398 if (cap & DWC_I2S_PLAY) {
399 dev_dbg(&pdev->dev, " SPEAr: play supported\n"); 399 dev_dbg(&pdev->dev, " designware: play supported\n");
400 dw_i2s_dai->playback.channels_min = MIN_CHANNEL_NUM; 400 dw_i2s_dai->playback.channels_min = MIN_CHANNEL_NUM;
401 dw_i2s_dai->playback.channels_max = pdata->channel; 401 dw_i2s_dai->playback.channels_max = pdata->channel;
402 dw_i2s_dai->playback.formats = pdata->snd_fmts; 402 dw_i2s_dai->playback.formats = pdata->snd_fmts;
@@ -404,7 +404,7 @@ static int dw_i2s_probe(struct platform_device *pdev)
404 } 404 }
405 405
406 if (cap & DWC_I2S_RECORD) { 406 if (cap & DWC_I2S_RECORD) {
407 dev_dbg(&pdev->dev, "SPEAr: record supported\n"); 407 dev_dbg(&pdev->dev, "designware: record supported\n");
408 dw_i2s_dai->capture.channels_min = MIN_CHANNEL_NUM; 408 dw_i2s_dai->capture.channels_min = MIN_CHANNEL_NUM;
409 dw_i2s_dai->capture.channels_max = pdata->channel; 409 dw_i2s_dai->capture.channels_max = pdata->channel;
410 dw_i2s_dai->capture.formats = pdata->snd_fmts; 410 dw_i2s_dai->capture.formats = pdata->snd_fmts;
diff --git a/sound/soc/fsl/Kconfig b/sound/soc/fsl/Kconfig
index 3843a18d4e56..aa438546c912 100644
--- a/sound/soc/fsl/Kconfig
+++ b/sound/soc/fsl/Kconfig
@@ -108,18 +108,13 @@ if SND_IMX_SOC
108config SND_SOC_IMX_SSI 108config SND_SOC_IMX_SSI
109 tristate 109 tristate
110 110
111config SND_SOC_IMX_PCM
112 tristate
113
114config SND_SOC_IMX_PCM_FIQ 111config SND_SOC_IMX_PCM_FIQ
115 bool 112 bool
116 select FIQ 113 select FIQ
117 select SND_SOC_IMX_PCM
118 114
119config SND_SOC_IMX_PCM_DMA 115config SND_SOC_IMX_PCM_DMA
120 bool 116 bool
121 select SND_SOC_GENERIC_DMAENGINE_PCM 117 select SND_SOC_GENERIC_DMAENGINE_PCM
122 select SND_SOC_IMX_PCM
123 118
124config SND_SOC_IMX_AUDMUX 119config SND_SOC_IMX_AUDMUX
125 tristate 120 tristate
@@ -173,6 +168,18 @@ config SND_SOC_EUKREA_TLV320
173 Enable I2S based access to the TLV320AIC23B codec attached 168 Enable I2S based access to the TLV320AIC23B codec attached
174 to the SSI interface 169 to the SSI interface
175 170
171config SND_SOC_IMX_WM8962
172 tristate "SoC Audio support for i.MX boards with wm8962"
173 depends on OF && I2C
174 select SND_SOC_WM8962
175 select SND_SOC_IMX_PCM_DMA
176 select SND_SOC_IMX_AUDMUX
177 select SND_SOC_FSL_SSI
178 select SND_SOC_FSL_UTILS
179 help
180 Say Y if you want to add support for SoC audio on an i.MX board with
181 a wm8962 codec.
182
176config SND_SOC_IMX_SGTL5000 183config SND_SOC_IMX_SGTL5000
177 tristate "SoC Audio support for i.MX boards with sgtl5000" 184 tristate "SoC Audio support for i.MX boards with sgtl5000"
178 depends on OF && I2C 185 depends on OF && I2C
diff --git a/sound/soc/fsl/Makefile b/sound/soc/fsl/Makefile
index afd34794db53..d4b4aa8b5649 100644
--- a/sound/soc/fsl/Makefile
+++ b/sound/soc/fsl/Makefile
@@ -30,18 +30,11 @@ obj-$(CONFIG_SND_MPC52xx_SOC_EFIKA) += efika-audio-fabric.o
30# i.MX Platform Support 30# i.MX Platform Support
31snd-soc-imx-ssi-objs := imx-ssi.o 31snd-soc-imx-ssi-objs := imx-ssi.o
32snd-soc-imx-audmux-objs := imx-audmux.o 32snd-soc-imx-audmux-objs := imx-audmux.o
33snd-soc-imx-pcm-objs := imx-pcm.o
34ifneq ($(CONFIG_SND_SOC_IMX_PCM_FIQ),)
35 snd-soc-imx-pcm-objs += imx-pcm-fiq.o
36endif
37ifneq ($(CONFIG_SND_SOC_IMX_PCM_DMA),)
38 snd-soc-imx-pcm-objs += imx-pcm-dma.o
39endif
40
41obj-$(CONFIG_SND_SOC_IMX_SSI) += snd-soc-imx-ssi.o 33obj-$(CONFIG_SND_SOC_IMX_SSI) += snd-soc-imx-ssi.o
42obj-$(CONFIG_SND_SOC_IMX_AUDMUX) += snd-soc-imx-audmux.o 34obj-$(CONFIG_SND_SOC_IMX_AUDMUX) += snd-soc-imx-audmux.o
43 35
44obj-$(CONFIG_SND_SOC_IMX_PCM) += snd-soc-imx-pcm.o 36obj-$(CONFIG_SND_SOC_IMX_PCM_FIQ) += imx-pcm-fiq.o
37obj-$(CONFIG_SND_SOC_IMX_PCM_DMA) += imx-pcm-dma.o
45 38
46# i.MX Machine Support 39# i.MX Machine Support
47snd-soc-eukrea-tlv320-objs := eukrea-tlv320.o 40snd-soc-eukrea-tlv320-objs := eukrea-tlv320.o
@@ -49,6 +42,7 @@ snd-soc-phycore-ac97-objs := phycore-ac97.o
49snd-soc-mx27vis-aic32x4-objs := mx27vis-aic32x4.o 42snd-soc-mx27vis-aic32x4-objs := mx27vis-aic32x4.o
50snd-soc-wm1133-ev1-objs := wm1133-ev1.o 43snd-soc-wm1133-ev1-objs := wm1133-ev1.o
51snd-soc-imx-sgtl5000-objs := imx-sgtl5000.o 44snd-soc-imx-sgtl5000-objs := imx-sgtl5000.o
45snd-soc-imx-wm8962-objs := imx-wm8962.o
52snd-soc-imx-mc13783-objs := imx-mc13783.o 46snd-soc-imx-mc13783-objs := imx-mc13783.o
53 47
54obj-$(CONFIG_SND_SOC_EUKREA_TLV320) += snd-soc-eukrea-tlv320.o 48obj-$(CONFIG_SND_SOC_EUKREA_TLV320) += snd-soc-eukrea-tlv320.o
@@ -56,4 +50,5 @@ obj-$(CONFIG_SND_SOC_PHYCORE_AC97) += snd-soc-phycore-ac97.o
56obj-$(CONFIG_SND_SOC_MX27VIS_AIC32X4) += snd-soc-mx27vis-aic32x4.o 50obj-$(CONFIG_SND_SOC_MX27VIS_AIC32X4) += snd-soc-mx27vis-aic32x4.o
57obj-$(CONFIG_SND_MXC_SOC_WM1133_EV1) += snd-soc-wm1133-ev1.o 51obj-$(CONFIG_SND_MXC_SOC_WM1133_EV1) += snd-soc-wm1133-ev1.o
58obj-$(CONFIG_SND_SOC_IMX_SGTL5000) += snd-soc-imx-sgtl5000.o 52obj-$(CONFIG_SND_SOC_IMX_SGTL5000) += snd-soc-imx-sgtl5000.o
53obj-$(CONFIG_SND_SOC_IMX_WM8962) += snd-soc-imx-wm8962.o
59obj-$(CONFIG_SND_SOC_IMX_MC13783) += snd-soc-imx-mc13783.o 54obj-$(CONFIG_SND_SOC_IMX_MC13783) += snd-soc-imx-mc13783.o
diff --git a/sound/soc/fsl/eukrea-tlv320.c b/sound/soc/fsl/eukrea-tlv320.c
index 75ffdf0e2aad..9a4a0ca2c1de 100644
--- a/sound/soc/fsl/eukrea-tlv320.c
+++ b/sound/soc/fsl/eukrea-tlv320.c
@@ -80,7 +80,7 @@ static struct snd_soc_dai_link eukrea_tlv320_dai = {
80 .name = "tlv320aic23", 80 .name = "tlv320aic23",
81 .stream_name = "TLV320AIC23", 81 .stream_name = "TLV320AIC23",
82 .codec_dai_name = "tlv320aic23-hifi", 82 .codec_dai_name = "tlv320aic23-hifi",
83 .platform_name = "imx-fiq-pcm-audio.0", 83 .platform_name = "imx-ssi.0",
84 .codec_name = "tlv320aic23-codec.0-001a", 84 .codec_name = "tlv320aic23-codec.0-001a",
85 .cpu_dai_name = "imx-ssi.0", 85 .cpu_dai_name = "imx-ssi.0",
86 .ops = &eukrea_tlv320_snd_ops, 86 .ops = &eukrea_tlv320_snd_ops,
diff --git a/sound/soc/fsl/fsl_ssi.c b/sound/soc/fsl/fsl_ssi.c
index 0f0bed6def9e..2f2d837df07f 100644
--- a/sound/soc/fsl/fsl_ssi.c
+++ b/sound/soc/fsl/fsl_ssi.c
@@ -122,7 +122,6 @@ struct fsl_ssi_private {
122 bool new_binding; 122 bool new_binding;
123 bool ssi_on_imx; 123 bool ssi_on_imx;
124 struct clk *clk; 124 struct clk *clk;
125 struct platform_device *imx_pcm_pdev;
126 struct snd_dmaengine_dai_dma_data dma_params_tx; 125 struct snd_dmaengine_dai_dma_data dma_params_tx;
127 struct snd_dmaengine_dai_dma_data dma_params_rx; 126 struct snd_dmaengine_dai_dma_data dma_params_rx;
128 struct imx_dma_data filter_data_tx; 127 struct imx_dma_data filter_data_tx;
@@ -809,13 +808,9 @@ static int fsl_ssi_probe(struct platform_device *pdev)
809 } 808 }
810 809
811 if (ssi_private->ssi_on_imx) { 810 if (ssi_private->ssi_on_imx) {
812 ssi_private->imx_pcm_pdev = 811 ret = imx_pcm_dma_init(pdev);
813 platform_device_register_simple("imx-pcm-audio", 812 if (ret)
814 -1, NULL, 0);
815 if (IS_ERR(ssi_private->imx_pcm_pdev)) {
816 ret = PTR_ERR(ssi_private->imx_pcm_pdev);
817 goto error_dev; 813 goto error_dev;
818 }
819 } 814 }
820 815
821 /* 816 /*
@@ -854,7 +849,7 @@ done:
854 849
855error_dai: 850error_dai:
856 if (ssi_private->ssi_on_imx) 851 if (ssi_private->ssi_on_imx)
857 platform_device_unregister(ssi_private->imx_pcm_pdev); 852 imx_pcm_dma_exit(pdev);
858 snd_soc_unregister_component(&pdev->dev); 853 snd_soc_unregister_component(&pdev->dev);
859 854
860error_dev: 855error_dev:
@@ -889,7 +884,7 @@ static int fsl_ssi_remove(struct platform_device *pdev)
889 if (!ssi_private->new_binding) 884 if (!ssi_private->new_binding)
890 platform_device_unregister(ssi_private->pdev); 885 platform_device_unregister(ssi_private->pdev);
891 if (ssi_private->ssi_on_imx) { 886 if (ssi_private->ssi_on_imx) {
892 platform_device_unregister(ssi_private->imx_pcm_pdev); 887 imx_pcm_dma_exit(pdev);
893 clk_disable_unprepare(ssi_private->clk); 888 clk_disable_unprepare(ssi_private->clk);
894 clk_put(ssi_private->clk); 889 clk_put(ssi_private->clk);
895 } 890 }
diff --git a/sound/soc/fsl/imx-audmux.c b/sound/soc/fsl/imx-audmux.c
index 47f046a8fdab..e260f1f899db 100644
--- a/sound/soc/fsl/imx-audmux.c
+++ b/sound/soc/fsl/imx-audmux.c
@@ -26,7 +26,6 @@
26#include <linux/of_device.h> 26#include <linux/of_device.h>
27#include <linux/platform_device.h> 27#include <linux/platform_device.h>
28#include <linux/slab.h> 28#include <linux/slab.h>
29#include <linux/pinctrl/consumer.h>
30 29
31#include "imx-audmux.h" 30#include "imx-audmux.h"
32 31
@@ -247,7 +246,6 @@ EXPORT_SYMBOL_GPL(imx_audmux_v2_configure_port);
247static int imx_audmux_probe(struct platform_device *pdev) 246static int imx_audmux_probe(struct platform_device *pdev)
248{ 247{
249 struct resource *res; 248 struct resource *res;
250 struct pinctrl *pinctrl;
251 const struct of_device_id *of_id = 249 const struct of_device_id *of_id =
252 of_match_device(imx_audmux_dt_ids, &pdev->dev); 250 of_match_device(imx_audmux_dt_ids, &pdev->dev);
253 251
@@ -256,12 +254,6 @@ static int imx_audmux_probe(struct platform_device *pdev)
256 if (IS_ERR(audmux_base)) 254 if (IS_ERR(audmux_base))
257 return PTR_ERR(audmux_base); 255 return PTR_ERR(audmux_base);
258 256
259 pinctrl = devm_pinctrl_get_select_default(&pdev->dev);
260 if (IS_ERR(pinctrl)) {
261 dev_err(&pdev->dev, "setup pinctrl failed!");
262 return PTR_ERR(pinctrl);
263 }
264
265 audmux_clk = devm_clk_get(&pdev->dev, "audmux"); 257 audmux_clk = devm_clk_get(&pdev->dev, "audmux");
266 if (IS_ERR(audmux_clk)) { 258 if (IS_ERR(audmux_clk)) {
267 dev_dbg(&pdev->dev, "cannot get clock: %ld\n", 259 dev_dbg(&pdev->dev, "cannot get clock: %ld\n",
diff --git a/sound/soc/fsl/imx-mc13783.c b/sound/soc/fsl/imx-mc13783.c
index 4ae30f21fdb5..9df173c091a6 100644
--- a/sound/soc/fsl/imx-mc13783.c
+++ b/sound/soc/fsl/imx-mc13783.c
@@ -64,7 +64,7 @@ static struct snd_soc_dai_link imx_mc13783_dai_mc13783[] = {
64 .codec_dai_name = "mc13783-hifi", 64 .codec_dai_name = "mc13783-hifi",
65 .codec_name = "mc13783-codec", 65 .codec_name = "mc13783-codec",
66 .cpu_dai_name = "imx-ssi.0", 66 .cpu_dai_name = "imx-ssi.0",
67 .platform_name = "imx-pcm-audio.0", 67 .platform_name = "imx-ssi.0",
68 .ops = &imx_mc13783_hifi_ops, 68 .ops = &imx_mc13783_hifi_ops,
69 .symmetric_rates = 1, 69 .symmetric_rates = 1,
70 .dai_fmt = FMT_SSI, 70 .dai_fmt = FMT_SSI,
diff --git a/sound/soc/fsl/imx-pcm-dma.c b/sound/soc/fsl/imx-pcm-dma.c
index c246fb514930..fde4d2ea68c8 100644
--- a/sound/soc/fsl/imx-pcm-dma.c
+++ b/sound/soc/fsl/imx-pcm-dma.c
@@ -67,8 +67,10 @@ int imx_pcm_dma_init(struct platform_device *pdev)
67 SND_DMAENGINE_PCM_FLAG_NO_DT | 67 SND_DMAENGINE_PCM_FLAG_NO_DT |
68 SND_DMAENGINE_PCM_FLAG_COMPAT); 68 SND_DMAENGINE_PCM_FLAG_COMPAT);
69} 69}
70EXPORT_SYMBOL_GPL(imx_pcm_dma_init);
70 71
71void imx_pcm_dma_exit(struct platform_device *pdev) 72void imx_pcm_dma_exit(struct platform_device *pdev)
72{ 73{
73 snd_dmaengine_pcm_unregister(&pdev->dev); 74 snd_dmaengine_pcm_unregister(&pdev->dev);
74} 75}
76EXPORT_SYMBOL_GPL(imx_pcm_dma_exit);
diff --git a/sound/soc/fsl/imx-pcm-fiq.c b/sound/soc/fsl/imx-pcm-fiq.c
index 670b96b0ce2f..310d90290320 100644
--- a/sound/soc/fsl/imx-pcm-fiq.c
+++ b/sound/soc/fsl/imx-pcm-fiq.c
@@ -225,6 +225,22 @@ static int snd_imx_close(struct snd_pcm_substream *substream)
225 return 0; 225 return 0;
226} 226}
227 227
228static int snd_imx_pcm_mmap(struct snd_pcm_substream *substream,
229 struct vm_area_struct *vma)
230{
231 struct snd_pcm_runtime *runtime = substream->runtime;
232 int ret;
233
234 ret = dma_mmap_writecombine(substream->pcm->card->dev, vma,
235 runtime->dma_area, runtime->dma_addr, runtime->dma_bytes);
236
237 pr_debug("%s: ret: %d %p 0x%08x 0x%08x\n", __func__, ret,
238 runtime->dma_area,
239 runtime->dma_addr,
240 runtime->dma_bytes);
241 return ret;
242}
243
228static struct snd_pcm_ops imx_pcm_ops = { 244static struct snd_pcm_ops imx_pcm_ops = {
229 .open = snd_imx_open, 245 .open = snd_imx_open,
230 .close = snd_imx_close, 246 .close = snd_imx_close,
@@ -236,6 +252,54 @@ static struct snd_pcm_ops imx_pcm_ops = {
236 .mmap = snd_imx_pcm_mmap, 252 .mmap = snd_imx_pcm_mmap,
237}; 253};
238 254
255static int imx_pcm_preallocate_dma_buffer(struct snd_pcm *pcm, int stream)
256{
257 struct snd_pcm_substream *substream = pcm->streams[stream].substream;
258 struct snd_dma_buffer *buf = &substream->dma_buffer;
259 size_t size = IMX_SSI_DMABUF_SIZE;
260
261 buf->dev.type = SNDRV_DMA_TYPE_DEV;
262 buf->dev.dev = pcm->card->dev;
263 buf->private_data = NULL;
264 buf->area = dma_alloc_writecombine(pcm->card->dev, size,
265 &buf->addr, GFP_KERNEL);
266 if (!buf->area)
267 return -ENOMEM;
268 buf->bytes = size;
269
270 return 0;
271}
272
273static u64 imx_pcm_dmamask = DMA_BIT_MASK(32);
274
275static int imx_pcm_new(struct snd_soc_pcm_runtime *rtd)
276{
277 struct snd_card *card = rtd->card->snd_card;
278 struct snd_pcm *pcm = rtd->pcm;
279 int ret = 0;
280
281 if (!card->dev->dma_mask)
282 card->dev->dma_mask = &imx_pcm_dmamask;
283 if (!card->dev->coherent_dma_mask)
284 card->dev->coherent_dma_mask = DMA_BIT_MASK(32);
285 if (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream) {
286 ret = imx_pcm_preallocate_dma_buffer(pcm,
287 SNDRV_PCM_STREAM_PLAYBACK);
288 if (ret)
289 goto out;
290 }
291
292 if (pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream) {
293 ret = imx_pcm_preallocate_dma_buffer(pcm,
294 SNDRV_PCM_STREAM_CAPTURE);
295 if (ret)
296 goto out;
297 }
298
299out:
300 return ret;
301}
302
239static int ssi_irq = 0; 303static int ssi_irq = 0;
240 304
241static int imx_pcm_fiq_new(struct snd_soc_pcm_runtime *rtd) 305static int imx_pcm_fiq_new(struct snd_soc_pcm_runtime *rtd)
@@ -268,6 +332,27 @@ static int imx_pcm_fiq_new(struct snd_soc_pcm_runtime *rtd)
268 return 0; 332 return 0;
269} 333}
270 334
335static void imx_pcm_free(struct snd_pcm *pcm)
336{
337 struct snd_pcm_substream *substream;
338 struct snd_dma_buffer *buf;
339 int stream;
340
341 for (stream = 0; stream < 2; stream++) {
342 substream = pcm->streams[stream].substream;
343 if (!substream)
344 continue;
345
346 buf = &substream->dma_buffer;
347 if (!buf->area)
348 continue;
349
350 dma_free_writecombine(pcm->card->dev, buf->bytes,
351 buf->area, buf->addr);
352 buf->area = NULL;
353 }
354}
355
271static void imx_pcm_fiq_free(struct snd_pcm *pcm) 356static void imx_pcm_fiq_free(struct snd_pcm *pcm)
272{ 357{
273 mxc_set_irq_fiq(ssi_irq, 0); 358 mxc_set_irq_fiq(ssi_irq, 0);
@@ -314,3 +399,10 @@ failed_register:
314 399
315 return ret; 400 return ret;
316} 401}
402EXPORT_SYMBOL_GPL(imx_pcm_fiq_init);
403
404void imx_pcm_fiq_exit(struct platform_device *pdev)
405{
406 snd_soc_unregister_platform(&pdev->dev);
407}
408EXPORT_SYMBOL_GPL(imx_pcm_fiq_exit);
diff --git a/sound/soc/fsl/imx-pcm.c b/sound/soc/fsl/imx-pcm.c
deleted file mode 100644
index c49896442d8e..000000000000
--- a/sound/soc/fsl/imx-pcm.c
+++ /dev/null
@@ -1,145 +0,0 @@
1/*
2 * Copyright 2009 Sascha Hauer <s.hauer@pengutronix.de>
3 *
4 * This code is based on code copyrighted by Freescale,
5 * Liam Girdwood, Javier Martin and probably others.
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2 of the License, or (at your
10 * option) any later version.
11 */
12
13#include <linux/dma-mapping.h>
14#include <linux/module.h>
15#include <sound/pcm.h>
16#include <sound/soc.h>
17#include "imx-pcm.h"
18
19int snd_imx_pcm_mmap(struct snd_pcm_substream *substream,
20 struct vm_area_struct *vma)
21{
22 struct snd_pcm_runtime *runtime = substream->runtime;
23 int ret;
24
25 ret = dma_mmap_writecombine(substream->pcm->card->dev, vma,
26 runtime->dma_area, runtime->dma_addr, runtime->dma_bytes);
27
28 pr_debug("%s: ret: %d %p 0x%08x 0x%08x\n", __func__, ret,
29 runtime->dma_area,
30 runtime->dma_addr,
31 runtime->dma_bytes);
32 return ret;
33}
34EXPORT_SYMBOL_GPL(snd_imx_pcm_mmap);
35
36static int imx_pcm_preallocate_dma_buffer(struct snd_pcm *pcm, int stream)
37{
38 struct snd_pcm_substream *substream = pcm->streams[stream].substream;
39 struct snd_dma_buffer *buf = &substream->dma_buffer;
40 size_t size = IMX_SSI_DMABUF_SIZE;
41
42 buf->dev.type = SNDRV_DMA_TYPE_DEV;
43 buf->dev.dev = pcm->card->dev;
44 buf->private_data = NULL;
45 buf->area = dma_alloc_writecombine(pcm->card->dev, size,
46 &buf->addr, GFP_KERNEL);
47 if (!buf->area)
48 return -ENOMEM;
49 buf->bytes = size;
50
51 return 0;
52}
53
54static u64 imx_pcm_dmamask = DMA_BIT_MASK(32);
55
56int imx_pcm_new(struct snd_soc_pcm_runtime *rtd)
57{
58 struct snd_card *card = rtd->card->snd_card;
59 struct snd_pcm *pcm = rtd->pcm;
60 int ret = 0;
61
62 if (!card->dev->dma_mask)
63 card->dev->dma_mask = &imx_pcm_dmamask;
64 if (!card->dev->coherent_dma_mask)
65 card->dev->coherent_dma_mask = DMA_BIT_MASK(32);
66 if (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream) {
67 ret = imx_pcm_preallocate_dma_buffer(pcm,
68 SNDRV_PCM_STREAM_PLAYBACK);
69 if (ret)
70 goto out;
71 }
72
73 if (pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream) {
74 ret = imx_pcm_preallocate_dma_buffer(pcm,
75 SNDRV_PCM_STREAM_CAPTURE);
76 if (ret)
77 goto out;
78 }
79
80out:
81 return ret;
82}
83EXPORT_SYMBOL_GPL(imx_pcm_new);
84
85void imx_pcm_free(struct snd_pcm *pcm)
86{
87 struct snd_pcm_substream *substream;
88 struct snd_dma_buffer *buf;
89 int stream;
90
91 for (stream = 0; stream < 2; stream++) {
92 substream = pcm->streams[stream].substream;
93 if (!substream)
94 continue;
95
96 buf = &substream->dma_buffer;
97 if (!buf->area)
98 continue;
99
100 dma_free_writecombine(pcm->card->dev, buf->bytes,
101 buf->area, buf->addr);
102 buf->area = NULL;
103 }
104}
105EXPORT_SYMBOL_GPL(imx_pcm_free);
106
107static int imx_pcm_probe(struct platform_device *pdev)
108{
109 if (strcmp(pdev->id_entry->name, "imx-fiq-pcm-audio") == 0)
110 return imx_pcm_fiq_init(pdev);
111
112 return imx_pcm_dma_init(pdev);
113}
114
115static int imx_pcm_remove(struct platform_device *pdev)
116{
117 if (strcmp(pdev->id_entry->name, "imx-fiq-pcm-audio") == 0)
118 snd_soc_unregister_platform(&pdev->dev);
119 else
120 imx_pcm_dma_exit(pdev);
121
122 return 0;
123}
124
125static struct platform_device_id imx_pcm_devtype[] = {
126 { .name = "imx-pcm-audio", },
127 { .name = "imx-fiq-pcm-audio", },
128 { /* sentinel */ }
129};
130MODULE_DEVICE_TABLE(platform, imx_pcm_devtype);
131
132static struct platform_driver imx_pcm_driver = {
133 .driver = {
134 .name = "imx-pcm",
135 .owner = THIS_MODULE,
136 },
137 .id_table = imx_pcm_devtype,
138 .probe = imx_pcm_probe,
139 .remove = imx_pcm_remove,
140};
141module_platform_driver(imx_pcm_driver);
142
143MODULE_DESCRIPTION("Freescale i.MX PCM driver");
144MODULE_AUTHOR("Sascha Hauer <s.hauer@pengutronix.de>");
145MODULE_LICENSE("GPL");
diff --git a/sound/soc/fsl/imx-pcm.h b/sound/soc/fsl/imx-pcm.h
index b7fa0d75c687..67f656c7c320 100644
--- a/sound/soc/fsl/imx-pcm.h
+++ b/sound/soc/fsl/imx-pcm.h
@@ -32,11 +32,6 @@ imx_pcm_dma_params_init_data(struct imx_dma_data *dma_data,
32 dma_data->peripheral_type = IMX_DMATYPE_SSI; 32 dma_data->peripheral_type = IMX_DMATYPE_SSI;
33} 33}
34 34
35int snd_imx_pcm_mmap(struct snd_pcm_substream *substream,
36 struct vm_area_struct *vma);
37int imx_pcm_new(struct snd_soc_pcm_runtime *rtd);
38void imx_pcm_free(struct snd_pcm *pcm);
39
40#ifdef CONFIG_SND_SOC_IMX_PCM_DMA 35#ifdef CONFIG_SND_SOC_IMX_PCM_DMA
41int imx_pcm_dma_init(struct platform_device *pdev); 36int imx_pcm_dma_init(struct platform_device *pdev);
42void imx_pcm_dma_exit(struct platform_device *pdev); 37void imx_pcm_dma_exit(struct platform_device *pdev);
@@ -53,11 +48,16 @@ static inline void imx_pcm_dma_exit(struct platform_device *pdev)
53 48
54#ifdef CONFIG_SND_SOC_IMX_PCM_FIQ 49#ifdef CONFIG_SND_SOC_IMX_PCM_FIQ
55int imx_pcm_fiq_init(struct platform_device *pdev); 50int imx_pcm_fiq_init(struct platform_device *pdev);
51void imx_pcm_fiq_exit(struct platform_device *pdev);
56#else 52#else
57static inline int imx_pcm_fiq_init(struct platform_device *pdev) 53static inline int imx_pcm_fiq_init(struct platform_device *pdev)
58{ 54{
59 return -ENODEV; 55 return -ENODEV;
60} 56}
57
58static inline void imx_pcm_fiq_exit(struct platform_device *pdev)
59{
60}
61#endif 61#endif
62 62
63#endif /* _IMX_PCM_H */ 63#endif /* _IMX_PCM_H */
diff --git a/sound/soc/fsl/imx-sgtl5000.c b/sound/soc/fsl/imx-sgtl5000.c
index 9584e78858df..7a8bc1220b2e 100644
--- a/sound/soc/fsl/imx-sgtl5000.c
+++ b/sound/soc/fsl/imx-sgtl5000.c
@@ -128,28 +128,18 @@ static int imx_sgtl5000_probe(struct platform_device *pdev)
128 goto fail; 128 goto fail;
129 } 129 }
130 130
131 data->codec_clk = clk_get(&codec_dev->dev, NULL); 131 data->codec_clk = devm_clk_get(&codec_dev->dev, NULL);
132 if (IS_ERR(data->codec_clk)) { 132 if (IS_ERR(data->codec_clk))
133 /* assuming clock enabled by default */ 133 goto fail;
134 data->codec_clk = NULL; 134
135 ret = of_property_read_u32(codec_np, "clock-frequency", 135 data->clk_frequency = clk_get_rate(data->codec_clk);
136 &data->clk_frequency);
137 if (ret) {
138 dev_err(&codec_dev->dev,
139 "clock-frequency missing or invalid\n");
140 goto fail;
141 }
142 } else {
143 data->clk_frequency = clk_get_rate(data->codec_clk);
144 clk_prepare_enable(data->codec_clk);
145 }
146 136
147 data->dai.name = "HiFi"; 137 data->dai.name = "HiFi";
148 data->dai.stream_name = "HiFi"; 138 data->dai.stream_name = "HiFi";
149 data->dai.codec_dai_name = "sgtl5000"; 139 data->dai.codec_dai_name = "sgtl5000";
150 data->dai.codec_of_node = codec_np; 140 data->dai.codec_of_node = codec_np;
151 data->dai.cpu_of_node = ssi_np; 141 data->dai.cpu_of_node = ssi_np;
152 data->dai.platform_name = "imx-pcm-audio"; 142 data->dai.platform_of_node = ssi_np;
153 data->dai.init = &imx_sgtl5000_dai_init; 143 data->dai.init = &imx_sgtl5000_dai_init;
154 data->dai.dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | 144 data->dai.dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
155 SND_SOC_DAIFMT_CBM_CFM; 145 SND_SOC_DAIFMT_CBM_CFM;
@@ -157,10 +147,10 @@ static int imx_sgtl5000_probe(struct platform_device *pdev)
157 data->card.dev = &pdev->dev; 147 data->card.dev = &pdev->dev;
158 ret = snd_soc_of_parse_card_name(&data->card, "model"); 148 ret = snd_soc_of_parse_card_name(&data->card, "model");
159 if (ret) 149 if (ret)
160 goto clk_fail; 150 goto fail;
161 ret = snd_soc_of_parse_audio_routing(&data->card, "audio-routing"); 151 ret = snd_soc_of_parse_audio_routing(&data->card, "audio-routing");
162 if (ret) 152 if (ret)
163 goto clk_fail; 153 goto fail;
164 data->card.num_links = 1; 154 data->card.num_links = 1;
165 data->card.owner = THIS_MODULE; 155 data->card.owner = THIS_MODULE;
166 data->card.dai_link = &data->dai; 156 data->card.dai_link = &data->dai;
@@ -170,12 +160,15 @@ static int imx_sgtl5000_probe(struct platform_device *pdev)
170 ret = snd_soc_register_card(&data->card); 160 ret = snd_soc_register_card(&data->card);
171 if (ret) { 161 if (ret) {
172 dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n", ret); 162 dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n", ret);
173 goto clk_fail; 163 goto fail;
174 } 164 }
175 165
176 platform_set_drvdata(pdev, data); 166 platform_set_drvdata(pdev, data);
177clk_fail: 167 of_node_put(ssi_np);
178 clk_put(data->codec_clk); 168 of_node_put(codec_np);
169
170 return 0;
171
179fail: 172fail:
180 if (ssi_np) 173 if (ssi_np)
181 of_node_put(ssi_np); 174 of_node_put(ssi_np);
@@ -189,10 +182,6 @@ static int imx_sgtl5000_remove(struct platform_device *pdev)
189{ 182{
190 struct imx_sgtl5000_data *data = platform_get_drvdata(pdev); 183 struct imx_sgtl5000_data *data = platform_get_drvdata(pdev);
191 184
192 if (data->codec_clk) {
193 clk_disable_unprepare(data->codec_clk);
194 clk_put(data->codec_clk);
195 }
196 snd_soc_unregister_card(&data->card); 185 snd_soc_unregister_card(&data->card);
197 186
198 return 0; 187 return 0;
diff --git a/sound/soc/fsl/imx-ssi.c b/sound/soc/fsl/imx-ssi.c
index c6fa03e2114a..51be3772cba9 100644
--- a/sound/soc/fsl/imx-ssi.c
+++ b/sound/soc/fsl/imx-ssi.c
@@ -501,13 +501,12 @@ static void imx_ssi_ac97_warm_reset(struct snd_ac97 *ac97)
501 imx_ssi_ac97_read(ac97, 0); 501 imx_ssi_ac97_read(ac97, 0);
502} 502}
503 503
504struct snd_ac97_bus_ops soc_ac97_ops = { 504static struct snd_ac97_bus_ops imx_ssi_ac97_ops = {
505 .read = imx_ssi_ac97_read, 505 .read = imx_ssi_ac97_read,
506 .write = imx_ssi_ac97_write, 506 .write = imx_ssi_ac97_write,
507 .reset = imx_ssi_ac97_reset, 507 .reset = imx_ssi_ac97_reset,
508 .warm_reset = imx_ssi_ac97_warm_reset 508 .warm_reset = imx_ssi_ac97_warm_reset
509}; 509};
510EXPORT_SYMBOL_GPL(soc_ac97_ops);
511 510
512static int imx_ssi_probe(struct platform_device *pdev) 511static int imx_ssi_probe(struct platform_device *pdev)
513{ 512{
@@ -583,6 +582,12 @@ static int imx_ssi_probe(struct platform_device *pdev)
583 582
584 platform_set_drvdata(pdev, ssi); 583 platform_set_drvdata(pdev, ssi);
585 584
585 ret = snd_soc_set_ac97_ops(&imx_ssi_ac97_ops);
586 if (ret != 0) {
587 dev_err(&pdev->dev, "Failed to set AC'97 ops: %d\n", ret);
588 goto failed_register;
589 }
590
586 ret = snd_soc_register_component(&pdev->dev, &imx_component, 591 ret = snd_soc_register_component(&pdev->dev, &imx_component,
587 dai, 1); 592 dai, 1);
588 if (ret) { 593 if (ret) {
@@ -590,46 +595,25 @@ static int imx_ssi_probe(struct platform_device *pdev)
590 goto failed_register; 595 goto failed_register;
591 } 596 }
592 597
593 ssi->soc_platform_pdev_fiq = platform_device_alloc("imx-fiq-pcm-audio", pdev->id); 598 ret = imx_pcm_fiq_init(pdev);
594 if (!ssi->soc_platform_pdev_fiq) { 599 if (ret)
595 ret = -ENOMEM; 600 goto failed_pcm_fiq;
596 goto failed_pdev_fiq_alloc;
597 }
598 601
599 platform_set_drvdata(ssi->soc_platform_pdev_fiq, ssi); 602 ret = imx_pcm_dma_init(pdev);
600 ret = platform_device_add(ssi->soc_platform_pdev_fiq); 603 if (ret)
601 if (ret) { 604 goto failed_pcm_dma;
602 dev_err(&pdev->dev, "failed to add platform device\n");
603 goto failed_pdev_fiq_add;
604 }
605
606 ssi->soc_platform_pdev = platform_device_alloc("imx-pcm-audio", pdev->id);
607 if (!ssi->soc_platform_pdev) {
608 ret = -ENOMEM;
609 goto failed_pdev_alloc;
610 }
611
612 platform_set_drvdata(ssi->soc_platform_pdev, ssi);
613 ret = platform_device_add(ssi->soc_platform_pdev);
614 if (ret) {
615 dev_err(&pdev->dev, "failed to add platform device\n");
616 goto failed_pdev_add;
617 }
618 605
619 return 0; 606 return 0;
620 607
621failed_pdev_add: 608failed_pcm_dma:
622 platform_device_put(ssi->soc_platform_pdev); 609 imx_pcm_fiq_exit(pdev);
623failed_pdev_alloc: 610failed_pcm_fiq:
624 platform_device_del(ssi->soc_platform_pdev_fiq);
625failed_pdev_fiq_add:
626 platform_device_put(ssi->soc_platform_pdev_fiq);
627failed_pdev_fiq_alloc:
628 snd_soc_unregister_component(&pdev->dev); 611 snd_soc_unregister_component(&pdev->dev);
629failed_register: 612failed_register:
630 release_mem_region(res->start, resource_size(res)); 613 release_mem_region(res->start, resource_size(res));
631 clk_disable_unprepare(ssi->clk); 614 clk_disable_unprepare(ssi->clk);
632failed_clk: 615failed_clk:
616 snd_soc_set_ac97_ops(NULL);
633 617
634 return ret; 618 return ret;
635} 619}
@@ -639,8 +623,8 @@ static int imx_ssi_remove(struct platform_device *pdev)
639 struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 623 struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
640 struct imx_ssi *ssi = platform_get_drvdata(pdev); 624 struct imx_ssi *ssi = platform_get_drvdata(pdev);
641 625
642 platform_device_unregister(ssi->soc_platform_pdev); 626 imx_pcm_dma_exit(pdev);
643 platform_device_unregister(ssi->soc_platform_pdev_fiq); 627 imx_pcm_fiq_exit(pdev);
644 628
645 snd_soc_unregister_component(&pdev->dev); 629 snd_soc_unregister_component(&pdev->dev);
646 630
@@ -649,6 +633,7 @@ static int imx_ssi_remove(struct platform_device *pdev)
649 633
650 release_mem_region(res->start, resource_size(res)); 634 release_mem_region(res->start, resource_size(res));
651 clk_disable_unprepare(ssi->clk); 635 clk_disable_unprepare(ssi->clk);
636 snd_soc_set_ac97_ops(NULL);
652 637
653 return 0; 638 return 0;
654} 639}
diff --git a/sound/soc/fsl/imx-ssi.h b/sound/soc/fsl/imx-ssi.h
index bb6b3dbb13fd..d5003cefca8d 100644
--- a/sound/soc/fsl/imx-ssi.h
+++ b/sound/soc/fsl/imx-ssi.h
@@ -211,9 +211,6 @@ struct imx_ssi {
211 struct imx_dma_data filter_data_rx; 211 struct imx_dma_data filter_data_rx;
212 212
213 int enabled; 213 int enabled;
214
215 struct platform_device *soc_platform_pdev;
216 struct platform_device *soc_platform_pdev_fiq;
217}; 214};
218 215
219#endif /* _IMX_SSI_H */ 216#endif /* _IMX_SSI_H */
diff --git a/sound/soc/fsl/imx-wm8962.c b/sound/soc/fsl/imx-wm8962.c
new file mode 100644
index 000000000000..52a36a90f4f4
--- /dev/null
+++ b/sound/soc/fsl/imx-wm8962.c
@@ -0,0 +1,323 @@
1/*
2 * Copyright 2013 Freescale Semiconductor, Inc.
3 *
4 * Based on imx-sgtl5000.c
5 * Copyright 2012 Freescale Semiconductor, Inc.
6 * Copyright 2012 Linaro Ltd.
7 *
8 * The code contained herein is licensed under the GNU General Public
9 * License. You may obtain a copy of the GNU General Public License
10 * Version 2 or later at the following locations:
11 *
12 * http://www.opensource.org/licenses/gpl-license.html
13 * http://www.gnu.org/copyleft/gpl.html
14 */
15
16#include <linux/module.h>
17#include <linux/of_platform.h>
18#include <linux/of_i2c.h>
19#include <linux/slab.h>
20#include <linux/clk.h>
21#include <sound/soc.h>
22#include <sound/pcm_params.h>
23#include <sound/soc-dapm.h>
24#include <linux/pinctrl/consumer.h>
25
26#include "../codecs/wm8962.h"
27#include "imx-audmux.h"
28
29#define DAI_NAME_SIZE 32
30
31struct imx_wm8962_data {
32 struct snd_soc_dai_link dai;
33 struct snd_soc_card card;
34 char codec_dai_name[DAI_NAME_SIZE];
35 char platform_name[DAI_NAME_SIZE];
36 struct clk *codec_clk;
37 unsigned int clk_frequency;
38};
39
40struct imx_priv {
41 struct platform_device *pdev;
42};
43static struct imx_priv card_priv;
44
45static const struct snd_soc_dapm_widget imx_wm8962_dapm_widgets[] = {
46 SND_SOC_DAPM_HP("Headphone Jack", NULL),
47 SND_SOC_DAPM_SPK("Ext Spk", NULL),
48 SND_SOC_DAPM_MIC("AMIC", NULL),
49 SND_SOC_DAPM_MIC("DMIC", NULL),
50};
51
52static int sample_rate = 44100;
53static snd_pcm_format_t sample_format = SNDRV_PCM_FORMAT_S16_LE;
54
55static int imx_hifi_hw_params(struct snd_pcm_substream *substream,
56 struct snd_pcm_hw_params *params)
57{
58 sample_rate = params_rate(params);
59 sample_format = params_format(params);
60
61 return 0;
62}
63
64static struct snd_soc_ops imx_hifi_ops = {
65 .hw_params = imx_hifi_hw_params,
66};
67
68static int imx_wm8962_set_bias_level(struct snd_soc_card *card,
69 struct snd_soc_dapm_context *dapm,
70 enum snd_soc_bias_level level)
71{
72 struct snd_soc_dai *codec_dai = card->rtd[0].codec_dai;
73 struct imx_priv *priv = &card_priv;
74 struct imx_wm8962_data *data = platform_get_drvdata(priv->pdev);
75 struct device *dev = &priv->pdev->dev;
76 unsigned int pll_out;
77 int ret;
78
79 if (dapm->dev != codec_dai->dev)
80 return 0;
81
82 switch (level) {
83 case SND_SOC_BIAS_PREPARE:
84 if (dapm->bias_level == SND_SOC_BIAS_STANDBY) {
85 if (sample_format == SNDRV_PCM_FORMAT_S24_LE)
86 pll_out = sample_rate * 384;
87 else
88 pll_out = sample_rate * 256;
89
90 ret = snd_soc_dai_set_pll(codec_dai, WM8962_FLL,
91 WM8962_FLL_MCLK, data->clk_frequency,
92 pll_out);
93 if (ret < 0) {
94 dev_err(dev, "failed to start FLL: %d\n", ret);
95 return ret;
96 }
97
98 ret = snd_soc_dai_set_sysclk(codec_dai,
99 WM8962_SYSCLK_FLL, pll_out,
100 SND_SOC_CLOCK_IN);
101 if (ret < 0) {
102 dev_err(dev, "failed to set SYSCLK: %d\n", ret);
103 return ret;
104 }
105 }
106 break;
107
108 case SND_SOC_BIAS_STANDBY:
109 if (dapm->bias_level == SND_SOC_BIAS_PREPARE) {
110 ret = snd_soc_dai_set_sysclk(codec_dai,
111 WM8962_SYSCLK_MCLK, data->clk_frequency,
112 SND_SOC_CLOCK_IN);
113 if (ret < 0) {
114 dev_err(dev,
115 "failed to switch away from FLL: %d\n",
116 ret);
117 return ret;
118 }
119
120 ret = snd_soc_dai_set_pll(codec_dai, WM8962_FLL,
121 0, 0, 0);
122 if (ret < 0) {
123 dev_err(dev, "failed to stop FLL: %d\n", ret);
124 return ret;
125 }
126 }
127 break;
128
129 default:
130 break;
131 }
132
133 dapm->bias_level = level;
134
135 return 0;
136}
137
138static int imx_wm8962_late_probe(struct snd_soc_card *card)
139{
140 struct snd_soc_dai *codec_dai = card->rtd[0].codec_dai;
141 struct imx_priv *priv = &card_priv;
142 struct imx_wm8962_data *data = platform_get_drvdata(priv->pdev);
143 struct device *dev = &priv->pdev->dev;
144 int ret;
145
146 ret = snd_soc_dai_set_sysclk(codec_dai, WM8962_SYSCLK_MCLK,
147 data->clk_frequency, SND_SOC_CLOCK_IN);
148 if (ret < 0)
149 dev_err(dev, "failed to set sysclk in %s\n", __func__);
150
151 return ret;
152}
153
154static int imx_wm8962_probe(struct platform_device *pdev)
155{
156 struct device_node *np = pdev->dev.of_node;
157 struct device_node *ssi_np, *codec_np;
158 struct platform_device *ssi_pdev;
159 struct imx_priv *priv = &card_priv;
160 struct i2c_client *codec_dev;
161 struct imx_wm8962_data *data;
162 int int_port, ext_port;
163 int ret;
164
165 priv->pdev = pdev;
166
167 ret = of_property_read_u32(np, "mux-int-port", &int_port);
168 if (ret) {
169 dev_err(&pdev->dev, "mux-int-port missing or invalid\n");
170 return ret;
171 }
172 ret = of_property_read_u32(np, "mux-ext-port", &ext_port);
173 if (ret) {
174 dev_err(&pdev->dev, "mux-ext-port missing or invalid\n");
175 return ret;
176 }
177
178 /*
179 * The port numbering in the hardware manual starts at 1, while
180 * the audmux API expects it starts at 0.
181 */
182 int_port--;
183 ext_port--;
184 ret = imx_audmux_v2_configure_port(int_port,
185 IMX_AUDMUX_V2_PTCR_SYN |
186 IMX_AUDMUX_V2_PTCR_TFSEL(ext_port) |
187 IMX_AUDMUX_V2_PTCR_TCSEL(ext_port) |
188 IMX_AUDMUX_V2_PTCR_TFSDIR |
189 IMX_AUDMUX_V2_PTCR_TCLKDIR,
190 IMX_AUDMUX_V2_PDCR_RXDSEL(ext_port));
191 if (ret) {
192 dev_err(&pdev->dev, "audmux internal port setup failed\n");
193 return ret;
194 }
195 imx_audmux_v2_configure_port(ext_port,
196 IMX_AUDMUX_V2_PTCR_SYN,
197 IMX_AUDMUX_V2_PDCR_RXDSEL(int_port));
198 if (ret) {
199 dev_err(&pdev->dev, "audmux external port setup failed\n");
200 return ret;
201 }
202
203 ssi_np = of_parse_phandle(pdev->dev.of_node, "ssi-controller", 0);
204 codec_np = of_parse_phandle(pdev->dev.of_node, "audio-codec", 0);
205 if (!ssi_np || !codec_np) {
206 dev_err(&pdev->dev, "phandle missing or invalid\n");
207 ret = -EINVAL;
208 goto fail;
209 }
210
211 ssi_pdev = of_find_device_by_node(ssi_np);
212 if (!ssi_pdev) {
213 dev_err(&pdev->dev, "failed to find SSI platform device\n");
214 ret = -EINVAL;
215 goto fail;
216 }
217 codec_dev = of_find_i2c_device_by_node(codec_np);
218 if (!codec_dev || !codec_dev->driver) {
219 dev_err(&pdev->dev, "failed to find codec platform device\n");
220 return -EINVAL;
221 }
222
223 data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
224 if (!data) {
225 ret = -ENOMEM;
226 goto fail;
227 }
228
229 data->codec_clk = devm_clk_get(&codec_dev->dev, NULL);
230 if (IS_ERR(data->codec_clk)) {
231 ret = PTR_ERR(data->codec_clk);
232 dev_err(&codec_dev->dev, "failed to get codec clk: %d\n", ret);
233 goto fail;
234 }
235
236 data->clk_frequency = clk_get_rate(data->codec_clk);
237 ret = clk_prepare_enable(data->codec_clk);
238 if (ret) {
239 dev_err(&codec_dev->dev, "failed to enable codec clk: %d\n", ret);
240 goto fail;
241 }
242
243 data->dai.name = "HiFi";
244 data->dai.stream_name = "HiFi";
245 data->dai.codec_dai_name = "wm8962";
246 data->dai.codec_of_node = codec_np;
247 data->dai.cpu_dai_name = dev_name(&ssi_pdev->dev);
248 data->dai.platform_of_node = ssi_np;
249 data->dai.ops = &imx_hifi_ops;
250 data->dai.dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
251 SND_SOC_DAIFMT_CBM_CFM;
252
253 data->card.dev = &pdev->dev;
254 ret = snd_soc_of_parse_card_name(&data->card, "model");
255 if (ret)
256 goto clk_fail;
257 ret = snd_soc_of_parse_audio_routing(&data->card, "audio-routing");
258 if (ret)
259 goto clk_fail;
260 data->card.num_links = 1;
261 data->card.dai_link = &data->dai;
262 data->card.dapm_widgets = imx_wm8962_dapm_widgets;
263 data->card.num_dapm_widgets = ARRAY_SIZE(imx_wm8962_dapm_widgets);
264
265 data->card.late_probe = imx_wm8962_late_probe;
266 data->card.set_bias_level = imx_wm8962_set_bias_level;
267
268 ret = snd_soc_register_card(&data->card);
269 if (ret) {
270 dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n", ret);
271 goto clk_fail;
272 }
273
274 platform_set_drvdata(pdev, data);
275 of_node_put(ssi_np);
276 of_node_put(codec_np);
277
278 return 0;
279
280clk_fail:
281 if (!IS_ERR(data->codec_clk))
282 clk_disable_unprepare(data->codec_clk);
283fail:
284 if (ssi_np)
285 of_node_put(ssi_np);
286 if (codec_np)
287 of_node_put(codec_np);
288
289 return ret;
290}
291
292static int imx_wm8962_remove(struct platform_device *pdev)
293{
294 struct imx_wm8962_data *data = platform_get_drvdata(pdev);
295
296 if (!IS_ERR(data->codec_clk))
297 clk_disable_unprepare(data->codec_clk);
298 snd_soc_unregister_card(&data->card);
299
300 return 0;
301}
302
303static const struct of_device_id imx_wm8962_dt_ids[] = {
304 { .compatible = "fsl,imx-audio-wm8962", },
305 { /* sentinel */ }
306};
307MODULE_DEVICE_TABLE(of, imx_wm8962_dt_ids);
308
309static struct platform_driver imx_wm8962_driver = {
310 .driver = {
311 .name = "imx-wm8962",
312 .owner = THIS_MODULE,
313 .of_match_table = imx_wm8962_dt_ids,
314 },
315 .probe = imx_wm8962_probe,
316 .remove = imx_wm8962_remove,
317};
318module_platform_driver(imx_wm8962_driver);
319
320MODULE_AUTHOR("Freescale Semiconductor, Inc.");
321MODULE_DESCRIPTION("Freescale i.MX WM8962 ASoC machine driver");
322MODULE_LICENSE("GPL v2");
323MODULE_ALIAS("platform:imx-wm8962");
diff --git a/sound/soc/fsl/mpc5200_psc_ac97.c b/sound/soc/fsl/mpc5200_psc_ac97.c
index 4141b35ef0bb..3ef7a0c92efa 100644
--- a/sound/soc/fsl/mpc5200_psc_ac97.c
+++ b/sound/soc/fsl/mpc5200_psc_ac97.c
@@ -131,13 +131,12 @@ static void psc_ac97_cold_reset(struct snd_ac97 *ac97)
131 psc_ac97_warm_reset(ac97); 131 psc_ac97_warm_reset(ac97);
132} 132}
133 133
134struct snd_ac97_bus_ops soc_ac97_ops = { 134static struct snd_ac97_bus_ops psc_ac97_ops = {
135 .read = psc_ac97_read, 135 .read = psc_ac97_read,
136 .write = psc_ac97_write, 136 .write = psc_ac97_write,
137 .reset = psc_ac97_cold_reset, 137 .reset = psc_ac97_cold_reset,
138 .warm_reset = psc_ac97_warm_reset, 138 .warm_reset = psc_ac97_warm_reset,
139}; 139};
140EXPORT_SYMBOL_GPL(soc_ac97_ops);
141 140
142static int psc_ac97_hw_analog_params(struct snd_pcm_substream *substream, 141static int psc_ac97_hw_analog_params(struct snd_pcm_substream *substream,
143 struct snd_pcm_hw_params *params, 142 struct snd_pcm_hw_params *params,
@@ -290,6 +289,12 @@ static int psc_ac97_of_probe(struct platform_device *op)
290 if (rc != 0) 289 if (rc != 0)
291 return rc; 290 return rc;
292 291
292 rc = snd_soc_set_ac97_ops(&psc_ac97_ops);
293 if (rc != 0) {
294 dev_err(&op->dev, "Failed to set AC'97 ops: %d\n", ret);
295 return rc;
296 }
297
293 rc = snd_soc_register_component(&op->dev, &psc_ac97_component, 298 rc = snd_soc_register_component(&op->dev, &psc_ac97_component,
294 psc_ac97_dai, ARRAY_SIZE(psc_ac97_dai)); 299 psc_ac97_dai, ARRAY_SIZE(psc_ac97_dai));
295 if (rc != 0) { 300 if (rc != 0) {
@@ -318,6 +323,7 @@ static int psc_ac97_of_remove(struct platform_device *op)
318{ 323{
319 mpc5200_audio_dma_destroy(op); 324 mpc5200_audio_dma_destroy(op);
320 snd_soc_unregister_component(&op->dev); 325 snd_soc_unregister_component(&op->dev);
326 snd_soc_set_ac97_ops(NULL);
321 return 0; 327 return 0;
322} 328}
323 329
diff --git a/sound/soc/fsl/mx27vis-aic32x4.c b/sound/soc/fsl/mx27vis-aic32x4.c
index 3d1074179057..f4c3bda5e69e 100644
--- a/sound/soc/fsl/mx27vis-aic32x4.c
+++ b/sound/soc/fsl/mx27vis-aic32x4.c
@@ -161,7 +161,7 @@ static struct snd_soc_dai_link mx27vis_aic32x4_dai = {
161 .name = "tlv320aic32x4", 161 .name = "tlv320aic32x4",
162 .stream_name = "TLV320AIC32X4", 162 .stream_name = "TLV320AIC32X4",
163 .codec_dai_name = "tlv320aic32x4-hifi", 163 .codec_dai_name = "tlv320aic32x4-hifi",
164 .platform_name = "imx-pcm-audio.0", 164 .platform_name = "imx-ssi.0",
165 .codec_name = "tlv320aic32x4.0-0018", 165 .codec_name = "tlv320aic32x4.0-0018",
166 .cpu_dai_name = "imx-ssi.0", 166 .cpu_dai_name = "imx-ssi.0",
167 .ops = &mx27vis_aic32x4_snd_ops, 167 .ops = &mx27vis_aic32x4_snd_ops,
diff --git a/sound/soc/fsl/phycore-ac97.c b/sound/soc/fsl/phycore-ac97.c
index f8da6dd115ed..ae403c29688f 100644
--- a/sound/soc/fsl/phycore-ac97.c
+++ b/sound/soc/fsl/phycore-ac97.c
@@ -33,7 +33,7 @@ static struct snd_soc_dai_link imx_phycore_dai_ac97[] = {
33 .codec_dai_name = "wm9712-hifi", 33 .codec_dai_name = "wm9712-hifi",
34 .codec_name = "wm9712-codec", 34 .codec_name = "wm9712-codec",
35 .cpu_dai_name = "imx-ssi.0", 35 .cpu_dai_name = "imx-ssi.0",
36 .platform_name = "imx-fiq-pcm-audio.0", 36 .platform_name = "imx-ssi.0",
37 .ops = &imx_phycore_hifi_ops, 37 .ops = &imx_phycore_hifi_ops,
38 }, 38 },
39}; 39};
diff --git a/sound/soc/fsl/wm1133-ev1.c b/sound/soc/fsl/wm1133-ev1.c
index fe54a69073e5..fce63252bdbb 100644
--- a/sound/soc/fsl/wm1133-ev1.c
+++ b/sound/soc/fsl/wm1133-ev1.c
@@ -245,7 +245,7 @@ static struct snd_soc_dai_link wm1133_ev1_dai = {
245 .stream_name = "Audio", 245 .stream_name = "Audio",
246 .cpu_dai_name = "imx-ssi.0", 246 .cpu_dai_name = "imx-ssi.0",
247 .codec_dai_name = "wm8350-hifi", 247 .codec_dai_name = "wm8350-hifi",
248 .platform_name = "imx-fiq-pcm-audio.0", 248 .platform_name = "imx-ssi.0",
249 .codec_name = "wm8350-codec.0-0x1a", 249 .codec_name = "wm8350-codec.0-0x1a",
250 .init = wm1133_ev1_init, 250 .init = wm1133_ev1_init,
251 .ops = &wm1133_ev1_ops, 251 .ops = &wm1133_ev1_ops,
diff --git a/sound/soc/jz4740/jz4740-i2s.c b/sound/soc/jz4740/jz4740-i2s.c
index 9a126441c5f3..4c849a49c72a 100644
--- a/sound/soc/jz4740/jz4740-i2s.c
+++ b/sound/soc/jz4740/jz4740-i2s.c
@@ -118,7 +118,7 @@ static int jz4740_i2s_startup(struct snd_pcm_substream *substream,
118 ctrl |= JZ_AIC_CTRL_FLUSH; 118 ctrl |= JZ_AIC_CTRL_FLUSH;
119 jz4740_i2s_write(i2s, JZ_REG_AIC_CTRL, ctrl); 119 jz4740_i2s_write(i2s, JZ_REG_AIC_CTRL, ctrl);
120 120
121 clk_enable(i2s->clk_i2s); 121 clk_prepare_enable(i2s->clk_i2s);
122 122
123 conf = jz4740_i2s_read(i2s, JZ_REG_AIC_CONF); 123 conf = jz4740_i2s_read(i2s, JZ_REG_AIC_CONF);
124 conf |= JZ_AIC_CONF_ENABLE; 124 conf |= JZ_AIC_CONF_ENABLE;
@@ -140,7 +140,7 @@ static void jz4740_i2s_shutdown(struct snd_pcm_substream *substream,
140 conf &= ~JZ_AIC_CONF_ENABLE; 140 conf &= ~JZ_AIC_CONF_ENABLE;
141 jz4740_i2s_write(i2s, JZ_REG_AIC_CONF, conf); 141 jz4740_i2s_write(i2s, JZ_REG_AIC_CONF, conf);
142 142
143 clk_disable(i2s->clk_i2s); 143 clk_disable_unprepare(i2s->clk_i2s);
144} 144}
145 145
146static int jz4740_i2s_trigger(struct snd_pcm_substream *substream, int cmd, 146static int jz4740_i2s_trigger(struct snd_pcm_substream *substream, int cmd,
@@ -314,10 +314,10 @@ static int jz4740_i2s_suspend(struct snd_soc_dai *dai)
314 conf &= ~JZ_AIC_CONF_ENABLE; 314 conf &= ~JZ_AIC_CONF_ENABLE;
315 jz4740_i2s_write(i2s, JZ_REG_AIC_CONF, conf); 315 jz4740_i2s_write(i2s, JZ_REG_AIC_CONF, conf);
316 316
317 clk_disable(i2s->clk_i2s); 317 clk_disable_unprepare(i2s->clk_i2s);
318 } 318 }
319 319
320 clk_disable(i2s->clk_aic); 320 clk_disable_unprepare(i2s->clk_aic);
321 321
322 return 0; 322 return 0;
323} 323}
@@ -327,10 +327,10 @@ static int jz4740_i2s_resume(struct snd_soc_dai *dai)
327 struct jz4740_i2s *i2s = snd_soc_dai_get_drvdata(dai); 327 struct jz4740_i2s *i2s = snd_soc_dai_get_drvdata(dai);
328 uint32_t conf; 328 uint32_t conf;
329 329
330 clk_enable(i2s->clk_aic); 330 clk_prepare_enable(i2s->clk_aic);
331 331
332 if (dai->active) { 332 if (dai->active) {
333 clk_enable(i2s->clk_i2s); 333 clk_prepare_enable(i2s->clk_i2s);
334 334
335 conf = jz4740_i2s_read(i2s, JZ_REG_AIC_CONF); 335 conf = jz4740_i2s_read(i2s, JZ_REG_AIC_CONF);
336 conf |= JZ_AIC_CONF_ENABLE; 336 conf |= JZ_AIC_CONF_ENABLE;
@@ -368,7 +368,7 @@ static int jz4740_i2s_dai_probe(struct snd_soc_dai *dai)
368 struct jz4740_i2s *i2s = snd_soc_dai_get_drvdata(dai); 368 struct jz4740_i2s *i2s = snd_soc_dai_get_drvdata(dai);
369 uint32_t conf; 369 uint32_t conf;
370 370
371 clk_enable(i2s->clk_aic); 371 clk_prepare_enable(i2s->clk_aic);
372 372
373 jz4740_i2c_init_pcm_config(i2s); 373 jz4740_i2c_init_pcm_config(i2s);
374 374
@@ -388,7 +388,7 @@ static int jz4740_i2s_dai_remove(struct snd_soc_dai *dai)
388{ 388{
389 struct jz4740_i2s *i2s = snd_soc_dai_get_drvdata(dai); 389 struct jz4740_i2s *i2s = snd_soc_dai_get_drvdata(dai);
390 390
391 clk_disable(i2s->clk_aic); 391 clk_disable_unprepare(i2s->clk_aic);
392 return 0; 392 return 0;
393} 393}
394 394
@@ -509,7 +509,6 @@ static int jz4740_i2s_dev_remove(struct platform_device *pdev)
509 iounmap(i2s->base); 509 iounmap(i2s->base);
510 release_mem_region(i2s->mem->start, resource_size(i2s->mem)); 510 release_mem_region(i2s->mem->start, resource_size(i2s->mem));
511 511
512 platform_set_drvdata(pdev, NULL);
513 kfree(i2s); 512 kfree(i2s);
514 513
515 return 0; 514 return 0;
diff --git a/sound/soc/kirkwood/kirkwood-dma.c b/sound/soc/kirkwood/kirkwood-dma.c
index d3d4bdca1cc6..a9f14530c3db 100644
--- a/sound/soc/kirkwood/kirkwood-dma.c
+++ b/sound/soc/kirkwood/kirkwood-dma.c
@@ -289,7 +289,7 @@ static snd_pcm_uframes_t kirkwood_dma_pointer(struct snd_pcm_substream
289 return count; 289 return count;
290} 290}
291 291
292struct snd_pcm_ops kirkwood_dma_ops = { 292static struct snd_pcm_ops kirkwood_dma_ops = {
293 .open = kirkwood_dma_open, 293 .open = kirkwood_dma_open,
294 .close = kirkwood_dma_close, 294 .close = kirkwood_dma_close,
295 .ioctl = snd_pcm_lib_ioctl, 295 .ioctl = snd_pcm_lib_ioctl,
diff --git a/sound/soc/mid-x86/mfld_machine.c b/sound/soc/mid-x86/mfld_machine.c
index 4139116c33b5..ee363845759e 100644
--- a/sound/soc/mid-x86/mfld_machine.c
+++ b/sound/soc/mid-x86/mfld_machine.c
@@ -371,7 +371,7 @@ static int snd_mfld_mc_probe(struct platform_device *pdev)
371 371
372 /* audio interrupt base of SRAM location where 372 /* audio interrupt base of SRAM location where
373 * interrupts are stored by System FW */ 373 * interrupts are stored by System FW */
374 mc_drv_ctx = kzalloc(sizeof(*mc_drv_ctx), GFP_ATOMIC); 374 mc_drv_ctx = devm_kzalloc(&pdev->dev, sizeof(*mc_drv_ctx), GFP_ATOMIC);
375 if (!mc_drv_ctx) { 375 if (!mc_drv_ctx) {
376 pr_err("allocation failed\n"); 376 pr_err("allocation failed\n");
377 return -ENOMEM; 377 return -ENOMEM;
@@ -381,51 +381,39 @@ static int snd_mfld_mc_probe(struct platform_device *pdev)
381 pdev, IORESOURCE_MEM, "IRQ_BASE"); 381 pdev, IORESOURCE_MEM, "IRQ_BASE");
382 if (!irq_mem) { 382 if (!irq_mem) {
383 pr_err("no mem resource given\n"); 383 pr_err("no mem resource given\n");
384 ret_val = -ENODEV; 384 return -ENODEV;
385 goto unalloc;
386 } 385 }
387 mc_drv_ctx->int_base = ioremap_nocache(irq_mem->start, 386 mc_drv_ctx->int_base = devm_ioremap_nocache(&pdev->dev, irq_mem->start,
388 resource_size(irq_mem)); 387 resource_size(irq_mem));
389 if (!mc_drv_ctx->int_base) { 388 if (!mc_drv_ctx->int_base) {
390 pr_err("Mapping of cache failed\n"); 389 pr_err("Mapping of cache failed\n");
391 ret_val = -ENOMEM; 390 return -ENOMEM;
392 goto unalloc;
393 } 391 }
394 /* register for interrupt */ 392 /* register for interrupt */
395 ret_val = request_threaded_irq(irq, snd_mfld_jack_intr_handler, 393 ret_val = devm_request_threaded_irq(&pdev->dev, irq,
394 snd_mfld_jack_intr_handler,
396 snd_mfld_jack_detection, 395 snd_mfld_jack_detection,
397 IRQF_SHARED, pdev->dev.driver->name, mc_drv_ctx); 396 IRQF_SHARED, pdev->dev.driver->name, mc_drv_ctx);
398 if (ret_val) { 397 if (ret_val) {
399 pr_err("cannot register IRQ\n"); 398 pr_err("cannot register IRQ\n");
400 goto unalloc; 399 return ret_val;
401 } 400 }
402 /* register the soc card */ 401 /* register the soc card */
403 snd_soc_card_mfld.dev = &pdev->dev; 402 snd_soc_card_mfld.dev = &pdev->dev;
404 ret_val = snd_soc_register_card(&snd_soc_card_mfld); 403 ret_val = snd_soc_register_card(&snd_soc_card_mfld);
405 if (ret_val) { 404 if (ret_val) {
406 pr_debug("snd_soc_register_card failed %d\n", ret_val); 405 pr_debug("snd_soc_register_card failed %d\n", ret_val);
407 goto freeirq; 406 return ret_val;
408 } 407 }
409 platform_set_drvdata(pdev, mc_drv_ctx); 408 platform_set_drvdata(pdev, mc_drv_ctx);
410 pr_debug("successfully exited probe\n"); 409 pr_debug("successfully exited probe\n");
411 return ret_val; 410 return 0;
412
413freeirq:
414 free_irq(irq, mc_drv_ctx);
415unalloc:
416 kfree(mc_drv_ctx);
417 return ret_val;
418} 411}
419 412
420static int snd_mfld_mc_remove(struct platform_device *pdev) 413static int snd_mfld_mc_remove(struct platform_device *pdev)
421{ 414{
422 struct mfld_mc_private *mc_drv_ctx = platform_get_drvdata(pdev);
423
424 pr_debug("snd_mfld_mc_remove called\n"); 415 pr_debug("snd_mfld_mc_remove called\n");
425 free_irq(platform_get_irq(pdev, 0), mc_drv_ctx);
426 snd_soc_unregister_card(&snd_soc_card_mfld); 416 snd_soc_unregister_card(&snd_soc_card_mfld);
427 kfree(mc_drv_ctx);
428 platform_set_drvdata(pdev, NULL);
429 return 0; 417 return 0;
430} 418}
431 419
diff --git a/sound/soc/mxs/mxs-pcm.c b/sound/soc/mxs/mxs-pcm.c
index b41fffc056fb..b16abbbf7764 100644
--- a/sound/soc/mxs/mxs-pcm.c
+++ b/sound/soc/mxs/mxs-pcm.c
@@ -49,24 +49,8 @@ static const struct snd_pcm_hardware snd_mxs_hardware = {
49 .fifo_size = 32, 49 .fifo_size = 32,
50}; 50};
51 51
52static bool filter(struct dma_chan *chan, void *param)
53{
54 struct mxs_pcm_dma_params *dma_params = param;
55
56 if (!mxs_dma_is_apbx(chan))
57 return false;
58
59 if (chan->chan_id != dma_params->chan_num)
60 return false;
61
62 chan->private = &dma_params->dma_data;
63
64 return true;
65}
66
67static const struct snd_dmaengine_pcm_config mxs_dmaengine_pcm_config = { 52static const struct snd_dmaengine_pcm_config mxs_dmaengine_pcm_config = {
68 .pcm_hardware = &snd_mxs_hardware, 53 .pcm_hardware = &snd_mxs_hardware,
69 .compat_filter_fn = filter,
70 .prealloc_buffer_size = 64 * 1024, 54 .prealloc_buffer_size = 64 * 1024,
71}; 55};
72 56
@@ -74,8 +58,6 @@ int mxs_pcm_platform_register(struct device *dev)
74{ 58{
75 return snd_dmaengine_pcm_register(dev, &mxs_dmaengine_pcm_config, 59 return snd_dmaengine_pcm_register(dev, &mxs_dmaengine_pcm_config,
76 SND_DMAENGINE_PCM_FLAG_NO_RESIDUE | 60 SND_DMAENGINE_PCM_FLAG_NO_RESIDUE |
77 SND_DMAENGINE_PCM_FLAG_NO_DT |
78 SND_DMAENGINE_PCM_FLAG_COMPAT |
79 SND_DMAENGINE_PCM_FLAG_HALF_DUPLEX); 61 SND_DMAENGINE_PCM_FLAG_HALF_DUPLEX);
80} 62}
81EXPORT_SYMBOL_GPL(mxs_pcm_platform_register); 63EXPORT_SYMBOL_GPL(mxs_pcm_platform_register);
diff --git a/sound/soc/mxs/mxs-pcm.h b/sound/soc/mxs/mxs-pcm.h
index 3aa918f9ed3e..bc685b67cac7 100644
--- a/sound/soc/mxs/mxs-pcm.h
+++ b/sound/soc/mxs/mxs-pcm.h
@@ -19,13 +19,6 @@
19#ifndef _MXS_PCM_H 19#ifndef _MXS_PCM_H
20#define _MXS_PCM_H 20#define _MXS_PCM_H
21 21
22#include <linux/fsl/mxs-dma.h>
23
24struct mxs_pcm_dma_params {
25 struct mxs_dma_data dma_data;
26 int chan_num;
27};
28
29int mxs_pcm_platform_register(struct device *dev); 22int mxs_pcm_platform_register(struct device *dev);
30void mxs_pcm_platform_unregister(struct device *dev); 23void mxs_pcm_platform_unregister(struct device *dev);
31 24
diff --git a/sound/soc/mxs/mxs-saif.c b/sound/soc/mxs/mxs-saif.c
index d31dc52fa862..49d870034bc3 100644
--- a/sound/soc/mxs/mxs-saif.c
+++ b/sound/soc/mxs/mxs-saif.c
@@ -26,8 +26,6 @@
26#include <linux/clk.h> 26#include <linux/clk.h>
27#include <linux/delay.h> 27#include <linux/delay.h>
28#include <linux/time.h> 28#include <linux/time.h>
29#include <linux/fsl/mxs-dma.h>
30#include <linux/pinctrl/consumer.h>
31#include <sound/core.h> 29#include <sound/core.h>
32#include <sound/pcm.h> 30#include <sound/pcm.h>
33#include <sound/pcm_params.h> 31#include <sound/pcm_params.h>
@@ -605,8 +603,6 @@ static int mxs_saif_dai_probe(struct snd_soc_dai *dai)
605 struct mxs_saif *saif = dev_get_drvdata(dai->dev); 603 struct mxs_saif *saif = dev_get_drvdata(dai->dev);
606 604
607 snd_soc_dai_set_drvdata(dai, saif); 605 snd_soc_dai_set_drvdata(dai, saif);
608 dai->playback_dma_data = &saif->dma_param;
609 dai->capture_dma_data = &saif->dma_param;
610 606
611 return 0; 607 return 0;
612} 608}
@@ -665,9 +661,8 @@ static irqreturn_t mxs_saif_irq(int irq, void *dev_id)
665static int mxs_saif_probe(struct platform_device *pdev) 661static int mxs_saif_probe(struct platform_device *pdev)
666{ 662{
667 struct device_node *np = pdev->dev.of_node; 663 struct device_node *np = pdev->dev.of_node;
668 struct resource *iores, *dmares; 664 struct resource *iores;
669 struct mxs_saif *saif; 665 struct mxs_saif *saif;
670 struct pinctrl *pinctrl;
671 int ret = 0; 666 int ret = 0;
672 struct device_node *master; 667 struct device_node *master;
673 668
@@ -707,12 +702,6 @@ static int mxs_saif_probe(struct platform_device *pdev)
707 702
708 mxs_saif[saif->id] = saif; 703 mxs_saif[saif->id] = saif;
709 704
710 pinctrl = devm_pinctrl_get_select_default(&pdev->dev);
711 if (IS_ERR(pinctrl)) {
712 ret = PTR_ERR(pinctrl);
713 return ret;
714 }
715
716 saif->clk = devm_clk_get(&pdev->dev, NULL); 705 saif->clk = devm_clk_get(&pdev->dev, NULL);
717 if (IS_ERR(saif->clk)) { 706 if (IS_ERR(saif->clk)) {
718 ret = PTR_ERR(saif->clk); 707 ret = PTR_ERR(saif->clk);
@@ -727,22 +716,6 @@ static int mxs_saif_probe(struct platform_device *pdev)
727 if (IS_ERR(saif->base)) 716 if (IS_ERR(saif->base))
728 return PTR_ERR(saif->base); 717 return PTR_ERR(saif->base);
729 718
730 dmares = platform_get_resource(pdev, IORESOURCE_DMA, 0);
731 if (!dmares) {
732 /*
733 * TODO: This is a temporary solution and should be changed
734 * to use generic DMA binding later when the helplers get in.
735 */
736 ret = of_property_read_u32(np, "fsl,saif-dma-channel",
737 &saif->dma_param.chan_num);
738 if (ret) {
739 dev_err(&pdev->dev, "failed to get dma channel\n");
740 return ret;
741 }
742 } else {
743 saif->dma_param.chan_num = dmares->start;
744 }
745
746 saif->irq = platform_get_irq(pdev, 0); 719 saif->irq = platform_get_irq(pdev, 0);
747 if (saif->irq < 0) { 720 if (saif->irq < 0) {
748 ret = saif->irq; 721 ret = saif->irq;
@@ -759,14 +732,6 @@ static int mxs_saif_probe(struct platform_device *pdev)
759 return ret; 732 return ret;
760 } 733 }
761 734
762 saif->dma_param.dma_data.chan_irq = platform_get_irq(pdev, 1);
763 if (saif->dma_param.dma_data.chan_irq < 0) {
764 ret = saif->dma_param.dma_data.chan_irq;
765 dev_err(&pdev->dev, "failed to get dma irq resource: %d\n",
766 ret);
767 return ret;
768 }
769
770 platform_set_drvdata(pdev, saif); 735 platform_set_drvdata(pdev, saif);
771 736
772 ret = snd_soc_register_component(&pdev->dev, &mxs_saif_component, 737 ret = snd_soc_register_component(&pdev->dev, &mxs_saif_component,
diff --git a/sound/soc/mxs/mxs-saif.h b/sound/soc/mxs/mxs-saif.h
index 3cb342e5bc90..53eaa4bf0e27 100644
--- a/sound/soc/mxs/mxs-saif.h
+++ b/sound/soc/mxs/mxs-saif.h
@@ -117,7 +117,6 @@ struct mxs_saif {
117 unsigned int mclk_in_use; 117 unsigned int mclk_in_use;
118 void __iomem *base; 118 void __iomem *base;
119 int irq; 119 int irq;
120 struct mxs_pcm_dma_params dma_param;
121 unsigned int id; 120 unsigned int id;
122 unsigned int master_id; 121 unsigned int master_id;
123 unsigned int cur_rate; 122 unsigned int cur_rate;
diff --git a/sound/soc/mxs/mxs-sgtl5000.c b/sound/soc/mxs/mxs-sgtl5000.c
index b1d9b5ebeeeb..1b134d72f120 100644
--- a/sound/soc/mxs/mxs-sgtl5000.c
+++ b/sound/soc/mxs/mxs-sgtl5000.c
@@ -90,17 +90,11 @@ static struct snd_soc_dai_link mxs_sgtl5000_dai[] = {
90 .name = "HiFi Tx", 90 .name = "HiFi Tx",
91 .stream_name = "HiFi Playback", 91 .stream_name = "HiFi Playback",
92 .codec_dai_name = "sgtl5000", 92 .codec_dai_name = "sgtl5000",
93 .codec_name = "sgtl5000.0-000a",
94 .cpu_dai_name = "mxs-saif.0",
95 .platform_name = "mxs-saif.0",
96 .ops = &mxs_sgtl5000_hifi_ops, 93 .ops = &mxs_sgtl5000_hifi_ops,
97 }, { 94 }, {
98 .name = "HiFi Rx", 95 .name = "HiFi Rx",
99 .stream_name = "HiFi Capture", 96 .stream_name = "HiFi Capture",
100 .codec_dai_name = "sgtl5000", 97 .codec_dai_name = "sgtl5000",
101 .codec_name = "sgtl5000.0-000a",
102 .cpu_dai_name = "mxs-saif.1",
103 .platform_name = "mxs-saif.1",
104 .ops = &mxs_sgtl5000_hifi_ops, 98 .ops = &mxs_sgtl5000_hifi_ops,
105 }, 99 },
106}; 100};
@@ -116,7 +110,7 @@ static int mxs_sgtl5000_probe_dt(struct platform_device *pdev)
116{ 110{
117 struct device_node *np = pdev->dev.of_node; 111 struct device_node *np = pdev->dev.of_node;
118 struct device_node *saif_np[2], *codec_np; 112 struct device_node *saif_np[2], *codec_np;
119 int i, ret = 0; 113 int i;
120 114
121 if (!np) 115 if (!np)
122 return 1; /* no device tree */ 116 return 1; /* no device tree */
@@ -142,7 +136,7 @@ static int mxs_sgtl5000_probe_dt(struct platform_device *pdev)
142 of_node_put(saif_np[0]); 136 of_node_put(saif_np[0]);
143 of_node_put(saif_np[1]); 137 of_node_put(saif_np[1]);
144 138
145 return ret; 139 return 0;
146} 140}
147 141
148static int mxs_sgtl5000_probe(struct platform_device *pdev) 142static int mxs_sgtl5000_probe(struct platform_device *pdev)
diff --git a/sound/soc/nuc900/nuc900-ac97.c b/sound/soc/nuc900/nuc900-ac97.c
index fe3285ceaf5b..f4c2417a8730 100644
--- a/sound/soc/nuc900/nuc900-ac97.c
+++ b/sound/soc/nuc900/nuc900-ac97.c
@@ -197,13 +197,12 @@ static void nuc900_ac97_cold_reset(struct snd_ac97 *ac97)
197} 197}
198 198
199/* AC97 controller operations */ 199/* AC97 controller operations */
200struct snd_ac97_bus_ops soc_ac97_ops = { 200static struct snd_ac97_bus_ops nuc900_ac97_ops = {
201 .read = nuc900_ac97_read, 201 .read = nuc900_ac97_read,
202 .write = nuc900_ac97_write, 202 .write = nuc900_ac97_write,
203 .reset = nuc900_ac97_cold_reset, 203 .reset = nuc900_ac97_cold_reset,
204 .warm_reset = nuc900_ac97_warm_reset, 204 .warm_reset = nuc900_ac97_warm_reset,
205} 205};
206EXPORT_SYMBOL_GPL(soc_ac97_ops);
207 206
208static int nuc900_ac97_trigger(struct snd_pcm_substream *substream, 207static int nuc900_ac97_trigger(struct snd_pcm_substream *substream,
209 int cmd, struct snd_soc_dai *dai) 208 int cmd, struct snd_soc_dai *dai)
@@ -326,64 +325,52 @@ static int nuc900_ac97_drvprobe(struct platform_device *pdev)
326 if (nuc900_ac97_data) 325 if (nuc900_ac97_data)
327 return -EBUSY; 326 return -EBUSY;
328 327
329 nuc900_audio = kzalloc(sizeof(struct nuc900_audio), GFP_KERNEL); 328 nuc900_audio = devm_kzalloc(&pdev->dev, sizeof(struct nuc900_audio),
329 GFP_KERNEL);
330 if (!nuc900_audio) 330 if (!nuc900_audio)
331 return -ENOMEM; 331 return -ENOMEM;
332 332
333 spin_lock_init(&nuc900_audio->lock); 333 spin_lock_init(&nuc900_audio->lock);
334 334
335 nuc900_audio->res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 335 nuc900_audio->res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
336 if (!nuc900_audio->res) { 336 if (!nuc900_audio->res)
337 ret = -ENODEV; 337 return ret;
338 goto out0;
339 }
340
341 if (!request_mem_region(nuc900_audio->res->start,
342 resource_size(nuc900_audio->res), pdev->name)) {
343 ret = -EBUSY;
344 goto out0;
345 }
346 338
347 nuc900_audio->mmio = ioremap(nuc900_audio->res->start, 339 nuc900_audio->mmio = devm_ioremap_resource(&pdev->dev,
348 resource_size(nuc900_audio->res)); 340 nuc900_audio->res);
349 if (!nuc900_audio->mmio) { 341 if (IS_ERR(nuc900_audio->mmio))
350 ret = -ENOMEM; 342 return PTR_ERR(nuc900_audio->mmio);
351 goto out1;
352 }
353 343
354 nuc900_audio->clk = clk_get(&pdev->dev, NULL); 344 nuc900_audio->clk = devm_clk_get(&pdev->dev, NULL);
355 if (IS_ERR(nuc900_audio->clk)) { 345 if (IS_ERR(nuc900_audio->clk)) {
356 ret = PTR_ERR(nuc900_audio->clk); 346 ret = PTR_ERR(nuc900_audio->clk);
357 goto out2; 347 goto out;
358 } 348 }
359 349
360 nuc900_audio->irq_num = platform_get_irq(pdev, 0); 350 nuc900_audio->irq_num = platform_get_irq(pdev, 0);
361 if (!nuc900_audio->irq_num) { 351 if (!nuc900_audio->irq_num) {
362 ret = -EBUSY; 352 ret = -EBUSY;
363 goto out3; 353 goto out;
364 } 354 }
365 355
366 nuc900_ac97_data = nuc900_audio; 356 nuc900_ac97_data = nuc900_audio;
367 357
358 ret = snd_soc_set_ac97_ops(&nuc900_ac97_ops);
359 if (ret)
360 goto out;
361
368 ret = snd_soc_register_component(&pdev->dev, &nuc900_ac97_component, 362 ret = snd_soc_register_component(&pdev->dev, &nuc900_ac97_component,
369 &nuc900_ac97_dai, 1); 363 &nuc900_ac97_dai, 1);
370 if (ret) 364 if (ret)
371 goto out3; 365 goto out;
372 366
373 /* enbale ac97 multifunction pin */ 367 /* enbale ac97 multifunction pin */
374 mfp_set_groupg(nuc900_audio->dev, NULL); 368 mfp_set_groupg(nuc900_audio->dev, NULL);
375 369
376 return 0; 370 return 0;
377 371
378out3: 372out:
379 clk_put(nuc900_audio->clk); 373 snd_soc_set_ac97_ops(NULL);
380out2:
381 iounmap(nuc900_audio->mmio);
382out1:
383 release_mem_region(nuc900_audio->res->start,
384 resource_size(nuc900_audio->res));
385out0:
386 kfree(nuc900_audio);
387 return ret; 374 return ret;
388} 375}
389 376
@@ -391,13 +378,8 @@ static int nuc900_ac97_drvremove(struct platform_device *pdev)
391{ 378{
392 snd_soc_unregister_component(&pdev->dev); 379 snd_soc_unregister_component(&pdev->dev);
393 380
394 clk_put(nuc900_ac97_data->clk);
395 iounmap(nuc900_ac97_data->mmio);
396 release_mem_region(nuc900_ac97_data->res->start,
397 resource_size(nuc900_ac97_data->res));
398
399 kfree(nuc900_ac97_data);
400 nuc900_ac97_data = NULL; 381 nuc900_ac97_data = NULL;
382 snd_soc_set_ac97_ops(NULL);
401 383
402 return 0; 384 return 0;
403} 385}
diff --git a/sound/soc/omap/Kconfig b/sound/soc/omap/Kconfig
index 60259f2f3f2c..9f5d55e6b17a 100644
--- a/sound/soc/omap/Kconfig
+++ b/sound/soc/omap/Kconfig
@@ -103,7 +103,7 @@ config SND_OMAP_SOC_OMAP_HDMI
103 tristate "SoC Audio support for Texas Instruments OMAP HDMI" 103 tristate "SoC Audio support for Texas Instruments OMAP HDMI"
104 depends on SND_OMAP_SOC && OMAP4_DSS_HDMI && OMAP2_DSS 104 depends on SND_OMAP_SOC && OMAP4_DSS_HDMI && OMAP2_DSS
105 select SND_OMAP_SOC_HDMI 105 select SND_OMAP_SOC_HDMI
106 select SND_SOC_OMAP_HDMI_CODEC 106 select SND_SOC_HDMI_CODEC
107 select OMAP4_DSS_HDMI_AUDIO 107 select OMAP4_DSS_HDMI_AUDIO
108 help 108 help
109 Say Y if you want to add support for SoC HDMI audio on Texas Instruments 109 Say Y if you want to add support for SoC HDMI audio on Texas Instruments
diff --git a/sound/soc/omap/Makefile b/sound/soc/omap/Makefile
index 2b225945359b..a725905b2c68 100644
--- a/sound/soc/omap/Makefile
+++ b/sound/soc/omap/Makefile
@@ -26,7 +26,6 @@ obj-$(CONFIG_SND_OMAP_SOC_N810) += snd-soc-n810.o
26obj-$(CONFIG_SND_OMAP_SOC_RX51) += snd-soc-rx51.o 26obj-$(CONFIG_SND_OMAP_SOC_RX51) += snd-soc-rx51.o
27obj-$(CONFIG_SND_OMAP_SOC_AMS_DELTA) += snd-soc-ams-delta.o 27obj-$(CONFIG_SND_OMAP_SOC_AMS_DELTA) += snd-soc-ams-delta.o
28obj-$(CONFIG_SND_OMAP_SOC_OSK5912) += snd-soc-osk5912.o 28obj-$(CONFIG_SND_OMAP_SOC_OSK5912) += snd-soc-osk5912.o
29obj-$(CONFIG_SND_OMAP_SOC_OMAP2EVM) += snd-soc-omap2evm.o
30obj-$(CONFIG_SND_OMAP_SOC_AM3517EVM) += snd-soc-am3517evm.o 29obj-$(CONFIG_SND_OMAP_SOC_AM3517EVM) += snd-soc-am3517evm.o
31obj-$(CONFIG_SND_OMAP_SOC_OMAP_ABE_TWL6040) += snd-soc-omap-abe-twl6040.o 30obj-$(CONFIG_SND_OMAP_SOC_OMAP_ABE_TWL6040) += snd-soc-omap-abe-twl6040.o
32obj-$(CONFIG_SND_OMAP_SOC_OMAP_TWL4030) += snd-soc-omap-twl4030.o 31obj-$(CONFIG_SND_OMAP_SOC_OMAP_TWL4030) += snd-soc-omap-twl4030.o
diff --git a/sound/soc/omap/omap-hdmi-card.c b/sound/soc/omap/omap-hdmi-card.c
index d4eaa92e518e..7e66e9cba5a8 100644
--- a/sound/soc/omap/omap-hdmi-card.c
+++ b/sound/soc/omap/omap-hdmi-card.c
@@ -35,7 +35,7 @@ static struct snd_soc_dai_link omap_hdmi_dai = {
35 .cpu_dai_name = "omap-hdmi-audio-dai", 35 .cpu_dai_name = "omap-hdmi-audio-dai",
36 .platform_name = "omap-pcm-audio", 36 .platform_name = "omap-pcm-audio",
37 .codec_name = "hdmi-audio-codec", 37 .codec_name = "hdmi-audio-codec",
38 .codec_dai_name = "omap-hdmi-hifi", 38 .codec_dai_name = "hdmi-hifi",
39}; 39};
40 40
41static struct snd_soc_card snd_soc_omap_hdmi = { 41static struct snd_soc_card snd_soc_omap_hdmi = {
diff --git a/sound/soc/omap/omap-mcbsp.c b/sound/soc/omap/omap-mcbsp.c
index eadbfb6b5000..7483efb6dc67 100644
--- a/sound/soc/omap/omap-mcbsp.c
+++ b/sound/soc/omap/omap-mcbsp.c
@@ -814,8 +814,6 @@ static int asoc_mcbsp_remove(struct platform_device *pdev)
814 814
815 clk_put(mcbsp->fclk); 815 clk_put(mcbsp->fclk);
816 816
817 platform_set_drvdata(pdev, NULL);
818
819 return 0; 817 return 0;
820} 818}
821 819
diff --git a/sound/soc/pxa/Kconfig b/sound/soc/pxa/Kconfig
index 4d2e46fae77c..b35809467547 100644
--- a/sound/soc/pxa/Kconfig
+++ b/sound/soc/pxa/Kconfig
@@ -130,26 +130,6 @@ config SND_PXA2XX_SOC_PALM27X
130 Say Y if you want to add support for SoC audio on 130 Say Y if you want to add support for SoC audio on
131 Palm T|X, T5, E2 or LifeDrive handheld computer. 131 Palm T|X, T5, E2 or LifeDrive handheld computer.
132 132
133config SND_SOC_SAARB
134 tristate "SoC Audio support for Marvell Saarb"
135 depends on SND_PXA2XX_SOC && MACH_SAARB
136 select MFD_88PM860X
137 select SND_PXA_SOC_SSP
138 select SND_SOC_88PM860X
139 help
140 Say Y if you want to add support for SoC audio on the
141 Marvell Saarb reference platform.
142
143config SND_SOC_TAVOREVB3
144 tristate "SoC Audio support for Marvell Tavor EVB3"
145 depends on SND_PXA2XX_SOC && MACH_TAVOREVB3
146 select MFD_88PM860X
147 select SND_PXA_SOC_SSP
148 select SND_SOC_88PM860X
149 help
150 Say Y if you want to add support for SoC audio on the
151 Marvell Saarb reference platform.
152
153config SND_PXA910_SOC 133config SND_PXA910_SOC
154 tristate "SoC Audio for Marvell PXA910 chip" 134 tristate "SoC Audio for Marvell PXA910 chip"
155 depends on ARCH_MMP && SND 135 depends on ARCH_MMP && SND
diff --git a/sound/soc/pxa/Makefile b/sound/soc/pxa/Makefile
index d8a265d2d5d7..2cff67b61dc3 100644
--- a/sound/soc/pxa/Makefile
+++ b/sound/soc/pxa/Makefile
@@ -23,8 +23,6 @@ snd-soc-e800-objs := e800_wm9712.o
23snd-soc-spitz-objs := spitz.o 23snd-soc-spitz-objs := spitz.o
24snd-soc-em-x270-objs := em-x270.o 24snd-soc-em-x270-objs := em-x270.o
25snd-soc-palm27x-objs := palm27x.o 25snd-soc-palm27x-objs := palm27x.o
26snd-soc-saarb-objs := saarb.o
27snd-soc-tavorevb3-objs := tavorevb3.o
28snd-soc-zylonite-objs := zylonite.o 26snd-soc-zylonite-objs := zylonite.o
29snd-soc-hx4700-objs := hx4700.o 27snd-soc-hx4700-objs := hx4700.o
30snd-soc-magician-objs := magician.o 28snd-soc-magician-objs := magician.o
@@ -48,8 +46,6 @@ obj-$(CONFIG_SND_PXA2XX_SOC_HX4700) += snd-soc-hx4700.o
48obj-$(CONFIG_SND_PXA2XX_SOC_MAGICIAN) += snd-soc-magician.o 46obj-$(CONFIG_SND_PXA2XX_SOC_MAGICIAN) += snd-soc-magician.o
49obj-$(CONFIG_SND_PXA2XX_SOC_MIOA701) += snd-soc-mioa701.o 47obj-$(CONFIG_SND_PXA2XX_SOC_MIOA701) += snd-soc-mioa701.o
50obj-$(CONFIG_SND_PXA2XX_SOC_Z2) += snd-soc-z2.o 48obj-$(CONFIG_SND_PXA2XX_SOC_Z2) += snd-soc-z2.o
51obj-$(CONFIG_SND_SOC_SAARB) += snd-soc-saarb.o
52obj-$(CONFIG_SND_SOC_TAVOREVB3) += snd-soc-tavorevb3.o
53obj-$(CONFIG_SND_SOC_ZYLONITE) += snd-soc-zylonite.o 49obj-$(CONFIG_SND_SOC_ZYLONITE) += snd-soc-zylonite.o
54obj-$(CONFIG_SND_PXA2XX_SOC_IMOTE2) += snd-soc-imote2.o 50obj-$(CONFIG_SND_PXA2XX_SOC_IMOTE2) += snd-soc-imote2.o
55obj-$(CONFIG_SND_SOC_RAUMFELD) += snd-soc-raumfeld.o 51obj-$(CONFIG_SND_SOC_RAUMFELD) += snd-soc-raumfeld.o
diff --git a/sound/soc/pxa/mmp-pcm.c b/sound/soc/pxa/mmp-pcm.c
index 349930015264..5d57e071cdf5 100644
--- a/sound/soc/pxa/mmp-pcm.c
+++ b/sound/soc/pxa/mmp-pcm.c
@@ -147,7 +147,7 @@ static int mmp_pcm_mmap(struct snd_pcm_substream *substream,
147 vma->vm_end - vma->vm_start, vma->vm_page_prot); 147 vma->vm_end - vma->vm_start, vma->vm_page_prot);
148} 148}
149 149
150struct snd_pcm_ops mmp_pcm_ops = { 150static struct snd_pcm_ops mmp_pcm_ops = {
151 .open = mmp_pcm_open, 151 .open = mmp_pcm_open,
152 .close = snd_dmaengine_pcm_close_release_chan, 152 .close = snd_dmaengine_pcm_close_release_chan,
153 .ioctl = snd_pcm_lib_ioctl, 153 .ioctl = snd_pcm_lib_ioctl,
@@ -208,7 +208,7 @@ static int mmp_pcm_preallocate_dma_buffer(struct snd_pcm_substream *substream,
208 return 0; 208 return 0;
209} 209}
210 210
211int mmp_pcm_new(struct snd_soc_pcm_runtime *rtd) 211static int mmp_pcm_new(struct snd_soc_pcm_runtime *rtd)
212{ 212{
213 struct snd_pcm_substream *substream; 213 struct snd_pcm_substream *substream;
214 struct snd_pcm *pcm = rtd->pcm; 214 struct snd_pcm *pcm = rtd->pcm;
@@ -229,7 +229,7 @@ err:
229 return ret; 229 return ret;
230} 230}
231 231
232struct snd_soc_platform_driver mmp_soc_platform = { 232static struct snd_soc_platform_driver mmp_soc_platform = {
233 .ops = &mmp_pcm_ops, 233 .ops = &mmp_pcm_ops,
234 .pcm_new = mmp_pcm_new, 234 .pcm_new = mmp_pcm_new,
235 .pcm_free = mmp_pcm_free_dma_buffers, 235 .pcm_free = mmp_pcm_free_dma_buffers,
diff --git a/sound/soc/pxa/mmp-sspa.c b/sound/soc/pxa/mmp-sspa.c
index a64779980177..62142ce367c7 100644
--- a/sound/soc/pxa/mmp-sspa.c
+++ b/sound/soc/pxa/mmp-sspa.c
@@ -388,7 +388,7 @@ static struct snd_soc_dai_ops mmp_sspa_dai_ops = {
388 .set_fmt = mmp_sspa_set_dai_fmt, 388 .set_fmt = mmp_sspa_set_dai_fmt,
389}; 389};
390 390
391struct snd_soc_dai_driver mmp_sspa_dai = { 391static struct snd_soc_dai_driver mmp_sspa_dai = {
392 .probe = mmp_sspa_probe, 392 .probe = mmp_sspa_probe,
393 .playback = { 393 .playback = {
394 .channels_min = 1, 394 .channels_min = 1,
diff --git a/sound/soc/pxa/pxa2xx-ac97.c b/sound/soc/pxa/pxa2xx-ac97.c
index 57ea8e6c5488..1475515712e6 100644
--- a/sound/soc/pxa/pxa2xx-ac97.c
+++ b/sound/soc/pxa/pxa2xx-ac97.c
@@ -41,13 +41,12 @@ static void pxa2xx_ac97_cold_reset(struct snd_ac97 *ac97)
41 pxa2xx_ac97_finish_reset(ac97); 41 pxa2xx_ac97_finish_reset(ac97);
42} 42}
43 43
44struct snd_ac97_bus_ops soc_ac97_ops = { 44static struct snd_ac97_bus_ops pxa2xx_ac97_ops = {
45 .read = pxa2xx_ac97_read, 45 .read = pxa2xx_ac97_read,
46 .write = pxa2xx_ac97_write, 46 .write = pxa2xx_ac97_write,
47 .warm_reset = pxa2xx_ac97_warm_reset, 47 .warm_reset = pxa2xx_ac97_warm_reset,
48 .reset = pxa2xx_ac97_cold_reset, 48 .reset = pxa2xx_ac97_cold_reset,
49}; 49};
50EXPORT_SYMBOL_GPL(soc_ac97_ops);
51 50
52static struct pxa2xx_pcm_dma_params pxa2xx_ac97_pcm_stereo_out = { 51static struct pxa2xx_pcm_dma_params pxa2xx_ac97_pcm_stereo_out = {
53 .name = "AC97 PCM Stereo out", 52 .name = "AC97 PCM Stereo out",
@@ -239,11 +238,17 @@ static const struct snd_soc_component_driver pxa_ac97_component = {
239 238
240static int pxa2xx_ac97_dev_probe(struct platform_device *pdev) 239static int pxa2xx_ac97_dev_probe(struct platform_device *pdev)
241{ 240{
241 int ret;
242
242 if (pdev->id != -1) { 243 if (pdev->id != -1) {
243 dev_err(&pdev->dev, "PXA2xx has only one AC97 port.\n"); 244 dev_err(&pdev->dev, "PXA2xx has only one AC97 port.\n");
244 return -ENXIO; 245 return -ENXIO;
245 } 246 }
246 247
248 ret = snd_soc_set_ac97_ops(&pxa2xx_ac97_ops);
249 if (ret != 0)
250 return ret;
251
247 /* Punt most of the init to the SoC probe; we may need the machine 252 /* Punt most of the init to the SoC probe; we may need the machine
248 * driver to do interesting things with the clocking to get us up 253 * driver to do interesting things with the clocking to get us up
249 * and running. 254 * and running.
@@ -255,6 +260,7 @@ static int pxa2xx_ac97_dev_probe(struct platform_device *pdev)
255static int pxa2xx_ac97_dev_remove(struct platform_device *pdev) 260static int pxa2xx_ac97_dev_remove(struct platform_device *pdev)
256{ 261{
257 snd_soc_unregister_component(&pdev->dev); 262 snd_soc_unregister_component(&pdev->dev);
263 snd_soc_set_ac97_ops(NULL);
258 return 0; 264 return 0;
259} 265}
260 266
diff --git a/sound/soc/pxa/pxa2xx-ac97.h b/sound/soc/pxa/pxa2xx-ac97.h
index eda891e6f31b..a49c21ba3842 100644
--- a/sound/soc/pxa/pxa2xx-ac97.h
+++ b/sound/soc/pxa/pxa2xx-ac97.h
@@ -14,7 +14,4 @@
14#define PXA2XX_DAI_AC97_AUX 1 14#define PXA2XX_DAI_AC97_AUX 1
15#define PXA2XX_DAI_AC97_MIC 2 15#define PXA2XX_DAI_AC97_MIC 2
16 16
17/* platform data */
18extern struct snd_ac97_bus_ops pxa2xx_ac97_ops;
19
20#endif 17#endif
diff --git a/sound/soc/pxa/saarb.c b/sound/soc/pxa/saarb.c
deleted file mode 100644
index c34146b776b4..000000000000
--- a/sound/soc/pxa/saarb.c
+++ /dev/null
@@ -1,190 +0,0 @@
1/*
2 * saarb.c -- SoC audio for saarb
3 *
4 * Copyright (C) 2010 Marvell International Ltd.
5 * Haojian Zhuang <haojian.zhuang@marvell.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11
12#include <linux/module.h>
13#include <linux/moduleparam.h>
14#include <linux/device.h>
15#include <linux/clk.h>
16#include <linux/i2c.h>
17#include <sound/core.h>
18#include <sound/pcm.h>
19#include <sound/pcm_params.h>
20#include <sound/soc.h>
21#include <sound/jack.h>
22
23#include <asm/mach-types.h>
24
25#include "../codecs/88pm860x-codec.h"
26#include "pxa-ssp.h"
27
28static int saarb_pm860x_init(struct snd_soc_pcm_runtime *rtd);
29
30static struct platform_device *saarb_snd_device;
31
32static struct snd_soc_jack hs_jack, mic_jack;
33
34static struct snd_soc_jack_pin hs_jack_pins[] = {
35 { .pin = "Headset Stereophone", .mask = SND_JACK_HEADPHONE, },
36};
37
38static struct snd_soc_jack_pin mic_jack_pins[] = {
39 { .pin = "Headset Mic 2", .mask = SND_JACK_MICROPHONE, },
40};
41
42/* saarb machine dapm widgets */
43static const struct snd_soc_dapm_widget saarb_dapm_widgets[] = {
44 SND_SOC_DAPM_HP("Headphone Stereophone", NULL),
45 SND_SOC_DAPM_LINE("Lineout Out 1", NULL),
46 SND_SOC_DAPM_LINE("Lineout Out 2", NULL),
47 SND_SOC_DAPM_SPK("Ext Speaker", NULL),
48 SND_SOC_DAPM_MIC("Ext Mic 1", NULL),
49 SND_SOC_DAPM_MIC("Headset Mic", NULL),
50 SND_SOC_DAPM_MIC("Ext Mic 3", NULL),
51};
52
53/* saarb machine audio map */
54static const struct snd_soc_dapm_route saarb_audio_map[] = {
55 {"Headset Stereophone", NULL, "HS1"},
56 {"Headset Stereophone", NULL, "HS2"},
57
58 {"Ext Speaker", NULL, "LSP"},
59 {"Ext Speaker", NULL, "LSN"},
60
61 {"Lineout Out 1", NULL, "LINEOUT1"},
62 {"Lineout Out 2", NULL, "LINEOUT2"},
63
64 {"MIC1P", NULL, "Mic1 Bias"},
65 {"MIC1N", NULL, "Mic1 Bias"},
66 {"Mic1 Bias", NULL, "Ext Mic 1"},
67
68 {"MIC2P", NULL, "Mic1 Bias"},
69 {"MIC2N", NULL, "Mic1 Bias"},
70 {"Mic1 Bias", NULL, "Headset Mic 2"},
71
72 {"MIC3P", NULL, "Mic3 Bias"},
73 {"MIC3N", NULL, "Mic3 Bias"},
74 {"Mic3 Bias", NULL, "Ext Mic 3"},
75};
76
77static int saarb_i2s_hw_params(struct snd_pcm_substream *substream,
78 struct snd_pcm_hw_params *params)
79{
80 struct snd_soc_pcm_runtime *rtd = substream->private_data;
81 struct snd_soc_dai *codec_dai = rtd->codec_dai;
82 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
83 int width = snd_pcm_format_physical_width(params_format(params));
84 int ret;
85
86 ret = snd_soc_dai_set_sysclk(cpu_dai, PXA_SSP_CLK_NET_PLL, 0,
87 PM860X_CLK_DIR_OUT);
88 if (ret < 0)
89 return ret;
90
91 ret = snd_soc_dai_set_sysclk(codec_dai, 0, 0, PM860X_CLK_DIR_OUT);
92 if (ret < 0)
93 return ret;
94
95 ret = snd_soc_dai_set_tdm_slot(cpu_dai, 3, 3, 2, width);
96
97 return ret;
98}
99
100static struct snd_soc_ops saarb_i2s_ops = {
101 .hw_params = saarb_i2s_hw_params,
102};
103
104static struct snd_soc_dai_link saarb_dai[] = {
105 {
106 .name = "88PM860x I2S",
107 .stream_name = "I2S Audio",
108 .cpu_dai_name = "pxa-ssp-dai.1",
109 .codec_dai_name = "88pm860x-i2s",
110 .platform_name = "pxa-pcm-audio",
111 .codec_name = "88pm860x-codec",
112 .init = saarb_pm860x_init,
113 .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
114 SND_SOC_DAIFMT_CBM_CFM,
115 .ops = &saarb_i2s_ops,
116 },
117};
118
119static struct snd_soc_card snd_soc_card_saarb = {
120 .name = "Saarb",
121 .owner = THIS_MODULE,
122 .dai_link = saarb_dai,
123 .num_links = ARRAY_SIZE(saarb_dai),
124
125 .dapm_widgets = saarb_dapm_widgets,
126 .num_dapm_widgets = ARRAY_SIZE(saarb_dapm_widgets),
127 .dapm_routes = saarb_audio_map,
128 .num_dapm_routes = ARRAY_SIZE(saarb_audio_map),
129};
130
131static int saarb_pm860x_init(struct snd_soc_pcm_runtime *rtd)
132{
133 struct snd_soc_codec *codec = rtd->codec;
134 struct snd_soc_dapm_context *dapm = &codec->dapm;
135
136 /* connected pins */
137 snd_soc_dapm_enable_pin(dapm, "Ext Speaker");
138 snd_soc_dapm_enable_pin(dapm, "Ext Mic 1");
139 snd_soc_dapm_enable_pin(dapm, "Ext Mic 3");
140 snd_soc_dapm_disable_pin(dapm, "Headset Mic 2");
141 snd_soc_dapm_disable_pin(dapm, "Headset Stereophone");
142
143 /* Headset jack detection */
144 snd_soc_jack_new(codec, "Headphone Jack", SND_JACK_HEADPHONE
145 | SND_JACK_BTN_0 | SND_JACK_BTN_1 | SND_JACK_BTN_2,
146 &hs_jack);
147 snd_soc_jack_add_pins(&hs_jack, ARRAY_SIZE(hs_jack_pins),
148 hs_jack_pins);
149 snd_soc_jack_new(codec, "Microphone Jack", SND_JACK_MICROPHONE,
150 &mic_jack);
151 snd_soc_jack_add_pins(&mic_jack, ARRAY_SIZE(mic_jack_pins),
152 mic_jack_pins);
153
154 /* headphone, microphone detection & headset short detection */
155 pm860x_hs_jack_detect(codec, &hs_jack, SND_JACK_HEADPHONE,
156 SND_JACK_BTN_0, SND_JACK_BTN_1, SND_JACK_BTN_2);
157 pm860x_mic_jack_detect(codec, &hs_jack, SND_JACK_MICROPHONE);
158 return 0;
159}
160
161static int __init saarb_init(void)
162{
163 int ret;
164
165 if (!machine_is_saarb())
166 return -ENODEV;
167 saarb_snd_device = platform_device_alloc("soc-audio", -1);
168 if (!saarb_snd_device)
169 return -ENOMEM;
170
171 platform_set_drvdata(saarb_snd_device, &snd_soc_card_saarb);
172
173 ret = platform_device_add(saarb_snd_device);
174 if (ret)
175 platform_device_put(saarb_snd_device);
176
177 return ret;
178}
179
180static void __exit saarb_exit(void)
181{
182 platform_device_unregister(saarb_snd_device);
183}
184
185module_init(saarb_init);
186module_exit(saarb_exit);
187
188MODULE_AUTHOR("Haojian Zhuang <haojian.zhuang@marvell.com>");
189MODULE_DESCRIPTION("ALSA SoC 88PM860x Saarb");
190MODULE_LICENSE("GPL");
diff --git a/sound/soc/pxa/tavorevb3.c b/sound/soc/pxa/tavorevb3.c
deleted file mode 100644
index 8b5ab8f72726..000000000000
--- a/sound/soc/pxa/tavorevb3.c
+++ /dev/null
@@ -1,189 +0,0 @@
1/*
2 * tavorevb3.c -- SoC audio for Tavor EVB3
3 *
4 * Copyright (C) 2010 Marvell International Ltd.
5 * Haojian Zhuang <haojian.zhuang@marvell.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11
12#include <linux/module.h>
13#include <linux/moduleparam.h>
14#include <linux/device.h>
15#include <linux/clk.h>
16#include <linux/i2c.h>
17#include <sound/core.h>
18#include <sound/pcm.h>
19#include <sound/pcm_params.h>
20#include <sound/soc.h>
21#include <sound/jack.h>
22
23#include <asm/mach-types.h>
24
25#include "../codecs/88pm860x-codec.h"
26#include "pxa-ssp.h"
27
28static int evb3_pm860x_init(struct snd_soc_pcm_runtime *rtd);
29
30static struct platform_device *evb3_snd_device;
31
32static struct snd_soc_jack hs_jack, mic_jack;
33
34static struct snd_soc_jack_pin hs_jack_pins[] = {
35 { .pin = "Headset Stereophone", .mask = SND_JACK_HEADPHONE, },
36};
37
38static struct snd_soc_jack_pin mic_jack_pins[] = {
39 { .pin = "Headset Mic 2", .mask = SND_JACK_MICROPHONE, },
40};
41
42/* tavorevb3 machine dapm widgets */
43static const struct snd_soc_dapm_widget evb3_dapm_widgets[] = {
44 SND_SOC_DAPM_HP("Headset Stereophone", NULL),
45 SND_SOC_DAPM_LINE("Lineout Out 1", NULL),
46 SND_SOC_DAPM_LINE("Lineout Out 2", NULL),
47 SND_SOC_DAPM_SPK("Ext Speaker", NULL),
48 SND_SOC_DAPM_MIC("Ext Mic 1", NULL),
49 SND_SOC_DAPM_MIC("Headset Mic 2", NULL),
50 SND_SOC_DAPM_MIC("Ext Mic 3", NULL),
51};
52
53/* tavorevb3 machine audio map */
54static const struct snd_soc_dapm_route evb3_audio_map[] = {
55 {"Headset Stereophone", NULL, "HS1"},
56 {"Headset Stereophone", NULL, "HS2"},
57
58 {"Ext Speaker", NULL, "LSP"},
59 {"Ext Speaker", NULL, "LSN"},
60
61 {"Lineout Out 1", NULL, "LINEOUT1"},
62 {"Lineout Out 2", NULL, "LINEOUT2"},
63
64 {"MIC1P", NULL, "Mic1 Bias"},
65 {"MIC1N", NULL, "Mic1 Bias"},
66 {"Mic1 Bias", NULL, "Ext Mic 1"},
67
68 {"MIC2P", NULL, "Mic1 Bias"},
69 {"MIC2N", NULL, "Mic1 Bias"},
70 {"Mic1 Bias", NULL, "Headset Mic 2"},
71
72 {"MIC3P", NULL, "Mic3 Bias"},
73 {"MIC3N", NULL, "Mic3 Bias"},
74 {"Mic3 Bias", NULL, "Ext Mic 3"},
75};
76
77static int evb3_i2s_hw_params(struct snd_pcm_substream *substream,
78 struct snd_pcm_hw_params *params)
79{
80 struct snd_soc_pcm_runtime *rtd = substream->private_data;
81 struct snd_soc_dai *codec_dai = rtd->codec_dai;
82 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
83 int width = snd_pcm_format_physical_width(params_format(params));
84 int ret;
85
86 ret = snd_soc_dai_set_sysclk(cpu_dai, PXA_SSP_CLK_NET_PLL, 0,
87 PM860X_CLK_DIR_OUT);
88 if (ret < 0)
89 return ret;
90
91 ret = snd_soc_dai_set_sysclk(codec_dai, 0, 0, PM860X_CLK_DIR_OUT);
92 if (ret < 0)
93 return ret;
94
95 ret = snd_soc_dai_set_tdm_slot(cpu_dai, 3, 3, 2, width);
96 return ret;
97}
98
99static struct snd_soc_ops evb3_i2s_ops = {
100 .hw_params = evb3_i2s_hw_params,
101};
102
103static struct snd_soc_dai_link evb3_dai[] = {
104 {
105 .name = "88PM860x I2S",
106 .stream_name = "I2S Audio",
107 .cpu_dai_name = "pxa-ssp-dai.1",
108 .codec_dai_name = "88pm860x-i2s",
109 .platform_name = "pxa-pcm-audio",
110 .codec_name = "88pm860x-codec",
111 .init = evb3_pm860x_init,
112 .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
113 SND_SOC_DAIFMT_CBM_CFM,
114 .ops = &evb3_i2s_ops,
115 },
116};
117
118static struct snd_soc_card snd_soc_card_evb3 = {
119 .name = "Tavor EVB3",
120 .owner = THIS_MODULE,
121 .dai_link = evb3_dai,
122 .num_links = ARRAY_SIZE(evb3_dai),
123
124 .dapm_widgets = evb3_dapm_widgets,
125 .num_dapm_widgets = ARRAY_SIZE(evb3_dapm_widgets),
126 .dapm_routes = evb3_audio_map,
127 .num_dapm_routes = ARRAY_SIZE(evb3_audio_map),
128};
129
130static int evb3_pm860x_init(struct snd_soc_pcm_runtime *rtd)
131{
132 struct snd_soc_codec *codec = rtd->codec;
133 struct snd_soc_dapm_context *dapm = &codec->dapm;
134
135 /* connected pins */
136 snd_soc_dapm_enable_pin(dapm, "Ext Speaker");
137 snd_soc_dapm_enable_pin(dapm, "Ext Mic 1");
138 snd_soc_dapm_enable_pin(dapm, "Ext Mic 3");
139 snd_soc_dapm_disable_pin(dapm, "Headset Mic 2");
140 snd_soc_dapm_disable_pin(dapm, "Headset Stereophone");
141
142 /* Headset jack detection */
143 snd_soc_jack_new(codec, "Headphone Jack", SND_JACK_HEADPHONE
144 | SND_JACK_BTN_0 | SND_JACK_BTN_1 | SND_JACK_BTN_2,
145 &hs_jack);
146 snd_soc_jack_add_pins(&hs_jack, ARRAY_SIZE(hs_jack_pins),
147 hs_jack_pins);
148 snd_soc_jack_new(codec, "Microphone Jack", SND_JACK_MICROPHONE,
149 &mic_jack);
150 snd_soc_jack_add_pins(&mic_jack, ARRAY_SIZE(mic_jack_pins),
151 mic_jack_pins);
152
153 /* headphone, microphone detection & headset short detection */
154 pm860x_hs_jack_detect(codec, &hs_jack, SND_JACK_HEADPHONE,
155 SND_JACK_BTN_0, SND_JACK_BTN_1, SND_JACK_BTN_2);
156 pm860x_mic_jack_detect(codec, &hs_jack, SND_JACK_MICROPHONE);
157 return 0;
158}
159
160static int __init tavorevb3_init(void)
161{
162 int ret;
163
164 if (!machine_is_tavorevb3())
165 return -ENODEV;
166 evb3_snd_device = platform_device_alloc("soc-audio", -1);
167 if (!evb3_snd_device)
168 return -ENOMEM;
169
170 platform_set_drvdata(evb3_snd_device, &snd_soc_card_evb3);
171
172 ret = platform_device_add(evb3_snd_device);
173 if (ret)
174 platform_device_put(evb3_snd_device);
175
176 return ret;
177}
178
179static void __exit tavorevb3_exit(void)
180{
181 platform_device_unregister(evb3_snd_device);
182}
183
184module_init(tavorevb3_init);
185module_exit(tavorevb3_exit);
186
187MODULE_AUTHOR("Haojian Zhuang <haojian.zhuang@marvell.com>");
188MODULE_DESCRIPTION("ALSA SoC 88PM860x Tavor EVB3");
189MODULE_LICENSE("GPL");
diff --git a/sound/soc/pxa/zylonite.c b/sound/soc/pxa/zylonite.c
index ceb656695b0f..db8aadf8932d 100644
--- a/sound/soc/pxa/zylonite.c
+++ b/sound/soc/pxa/zylonite.c
@@ -256,7 +256,6 @@ static struct snd_soc_card zylonite = {
256 .resume_pre = &zylonite_resume_pre, 256 .resume_pre = &zylonite_resume_pre,
257 .dai_link = zylonite_dai, 257 .dai_link = zylonite_dai,
258 .num_links = ARRAY_SIZE(zylonite_dai), 258 .num_links = ARRAY_SIZE(zylonite_dai),
259 .owner = THIS_MODULE,
260}; 259};
261 260
262static struct platform_device *zylonite_snd_ac97_device; 261static struct platform_device *zylonite_snd_ac97_device;
diff --git a/sound/soc/samsung/Kconfig b/sound/soc/samsung/Kconfig
index 475fb0d8b3c6..9855dfc3e3ec 100644
--- a/sound/soc/samsung/Kconfig
+++ b/sound/soc/samsung/Kconfig
@@ -39,7 +39,7 @@ config SND_SOC_SAMSUNG_NEO1973_WM8753
39 depends on SND_SOC_SAMSUNG && MACH_NEO1973_GTA02 39 depends on SND_SOC_SAMSUNG && MACH_NEO1973_GTA02
40 select SND_S3C24XX_I2S 40 select SND_S3C24XX_I2S
41 select SND_SOC_WM8753 41 select SND_SOC_WM8753
42 select SND_SOC_DFBMCS320 42 select SND_SOC_BT_SCO
43 help 43 help
44 Say Y here to enable audio support for the Openmoko Neo1973 44 Say Y here to enable audio support for the Openmoko Neo1973
45 Smartphones. 45 Smartphones.
diff --git a/sound/soc/samsung/ac97.c b/sound/soc/samsung/ac97.c
index cb88ead98917..2dd623fa3882 100644
--- a/sound/soc/samsung/ac97.c
+++ b/sound/soc/samsung/ac97.c
@@ -214,13 +214,12 @@ static irqreturn_t s3c_ac97_irq(int irq, void *dev_id)
214 return IRQ_HANDLED; 214 return IRQ_HANDLED;
215} 215}
216 216
217struct snd_ac97_bus_ops soc_ac97_ops = { 217static struct snd_ac97_bus_ops s3c_ac97_ops = {
218 .read = s3c_ac97_read, 218 .read = s3c_ac97_read,
219 .write = s3c_ac97_write, 219 .write = s3c_ac97_write,
220 .warm_reset = s3c_ac97_warm_reset, 220 .warm_reset = s3c_ac97_warm_reset,
221 .reset = s3c_ac97_cold_reset, 221 .reset = s3c_ac97_cold_reset,
222}; 222};
223EXPORT_SYMBOL_GPL(soc_ac97_ops);
224 223
225static int s3c_ac97_hw_params(struct snd_pcm_substream *substream, 224static int s3c_ac97_hw_params(struct snd_pcm_substream *substream,
226 struct snd_pcm_hw_params *params, 225 struct snd_pcm_hw_params *params,
@@ -417,11 +416,9 @@ static int s3c_ac97_probe(struct platform_device *pdev)
417 return -ENXIO; 416 return -ENXIO;
418 } 417 }
419 418
420 if (!request_mem_region(mem_res->start, 419 s3c_ac97.regs = devm_ioremap_resource(&pdev->dev, mem_res);
421 resource_size(mem_res), "ac97")) { 420 if (IS_ERR(s3c_ac97.regs))
422 dev_err(&pdev->dev, "Unable to request register region\n"); 421 return PTR_ERR(s3c_ac97.regs);
423 return -EBUSY;
424 }
425 422
426 s3c_ac97_pcm_out.channel = dmatx_res->start; 423 s3c_ac97_pcm_out.channel = dmatx_res->start;
427 s3c_ac97_pcm_out.dma_addr = mem_res->start + S3C_AC97_PCM_DATA; 424 s3c_ac97_pcm_out.dma_addr = mem_res->start + S3C_AC97_PCM_DATA;
@@ -433,14 +430,7 @@ static int s3c_ac97_probe(struct platform_device *pdev)
433 init_completion(&s3c_ac97.done); 430 init_completion(&s3c_ac97.done);
434 mutex_init(&s3c_ac97.lock); 431 mutex_init(&s3c_ac97.lock);
435 432
436 s3c_ac97.regs = ioremap(mem_res->start, resource_size(mem_res)); 433 s3c_ac97.ac97_clk = devm_clk_get(&pdev->dev, "ac97");
437 if (s3c_ac97.regs == NULL) {
438 dev_err(&pdev->dev, "Unable to ioremap register region\n");
439 ret = -ENXIO;
440 goto err1;
441 }
442
443 s3c_ac97.ac97_clk = clk_get(&pdev->dev, "ac97");
444 if (IS_ERR(s3c_ac97.ac97_clk)) { 434 if (IS_ERR(s3c_ac97.ac97_clk)) {
445 dev_err(&pdev->dev, "ac97 failed to get ac97_clock\n"); 435 dev_err(&pdev->dev, "ac97 failed to get ac97_clock\n");
446 ret = -ENODEV; 436 ret = -ENODEV;
@@ -461,6 +451,12 @@ static int s3c_ac97_probe(struct platform_device *pdev)
461 goto err4; 451 goto err4;
462 } 452 }
463 453
454 ret = snd_soc_set_ac97_ops(&s3c_ac97_ops);
455 if (ret != 0) {
456 dev_err(&pdev->dev, "Failed to set AC'97 ops: %d\n", ret);
457 goto err4;
458 }
459
464 ret = snd_soc_register_component(&pdev->dev, &s3c_ac97_component, 460 ret = snd_soc_register_component(&pdev->dev, &s3c_ac97_component,
465 s3c_ac97_dai, ARRAY_SIZE(s3c_ac97_dai)); 461 s3c_ac97_dai, ARRAY_SIZE(s3c_ac97_dai));
466 if (ret) 462 if (ret)
@@ -480,18 +476,14 @@ err5:
480err4: 476err4:
481err3: 477err3:
482 clk_disable_unprepare(s3c_ac97.ac97_clk); 478 clk_disable_unprepare(s3c_ac97.ac97_clk);
483 clk_put(s3c_ac97.ac97_clk);
484err2: 479err2:
485 iounmap(s3c_ac97.regs); 480 snd_soc_set_ac97_ops(NULL);
486err1:
487 release_mem_region(mem_res->start, resource_size(mem_res));
488
489 return ret; 481 return ret;
490} 482}
491 483
492static int s3c_ac97_remove(struct platform_device *pdev) 484static int s3c_ac97_remove(struct platform_device *pdev)
493{ 485{
494 struct resource *mem_res, *irq_res; 486 struct resource *irq_res;
495 487
496 asoc_dma_platform_unregister(&pdev->dev); 488 asoc_dma_platform_unregister(&pdev->dev);
497 snd_soc_unregister_component(&pdev->dev); 489 snd_soc_unregister_component(&pdev->dev);
@@ -501,13 +493,7 @@ static int s3c_ac97_remove(struct platform_device *pdev)
501 free_irq(irq_res->start, NULL); 493 free_irq(irq_res->start, NULL);
502 494
503 clk_disable_unprepare(s3c_ac97.ac97_clk); 495 clk_disable_unprepare(s3c_ac97.ac97_clk);
504 clk_put(s3c_ac97.ac97_clk); 496 snd_soc_set_ac97_ops(NULL);
505
506 iounmap(s3c_ac97.regs);
507
508 mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
509 if (mem_res)
510 release_mem_region(mem_res->start, resource_size(mem_res));
511 497
512 return 0; 498 return 0;
513} 499}
diff --git a/sound/soc/samsung/bells.c b/sound/soc/samsung/bells.c
index ceed466af9ff..29e246803626 100644
--- a/sound/soc/samsung/bells.c
+++ b/sound/soc/samsung/bells.c
@@ -350,8 +350,16 @@ static struct snd_soc_codec_conf bells_codec_conf[] = {
350 }, 350 },
351}; 351};
352 352
353static struct snd_soc_dapm_widget bells_widgets[] = {
354 SND_SOC_DAPM_MIC("DMIC", NULL),
355};
356
353static struct snd_soc_dapm_route bells_routes[] = { 357static struct snd_soc_dapm_route bells_routes[] = {
354 { "Sub CLK_SYS", NULL, "OPCLK" }, 358 { "Sub CLK_SYS", NULL, "OPCLK" },
359
360 { "DMIC", NULL, "MICBIAS2" },
361 { "IN2L", NULL, "DMIC" },
362 { "IN2R", NULL, "DMIC" },
355}; 363};
356 364
357static struct snd_soc_card bells_cards[] = { 365static struct snd_soc_card bells_cards[] = {
@@ -365,6 +373,8 @@ static struct snd_soc_card bells_cards[] = {
365 373
366 .late_probe = bells_late_probe, 374 .late_probe = bells_late_probe,
367 375
376 .dapm_widgets = bells_widgets,
377 .num_dapm_widgets = ARRAY_SIZE(bells_widgets),
368 .dapm_routes = bells_routes, 378 .dapm_routes = bells_routes,
369 .num_dapm_routes = ARRAY_SIZE(bells_routes), 379 .num_dapm_routes = ARRAY_SIZE(bells_routes),
370 380
@@ -383,6 +393,8 @@ static struct snd_soc_card bells_cards[] = {
383 393
384 .late_probe = bells_late_probe, 394 .late_probe = bells_late_probe,
385 395
396 .dapm_widgets = bells_widgets,
397 .num_dapm_widgets = ARRAY_SIZE(bells_widgets),
386 .dapm_routes = bells_routes, 398 .dapm_routes = bells_routes,
387 .num_dapm_routes = ARRAY_SIZE(bells_routes), 399 .num_dapm_routes = ARRAY_SIZE(bells_routes),
388 400
@@ -401,6 +413,8 @@ static struct snd_soc_card bells_cards[] = {
401 413
402 .late_probe = bells_late_probe, 414 .late_probe = bells_late_probe,
403 415
416 .dapm_widgets = bells_widgets,
417 .num_dapm_widgets = ARRAY_SIZE(bells_widgets),
404 .dapm_routes = bells_routes, 418 .dapm_routes = bells_routes,
405 .num_dapm_routes = ARRAY_SIZE(bells_routes), 419 .num_dapm_routes = ARRAY_SIZE(bells_routes),
406 420
diff --git a/sound/soc/samsung/neo1973_wm8753.c b/sound/soc/samsung/neo1973_wm8753.c
index e591c386917a..807db417d234 100644
--- a/sound/soc/samsung/neo1973_wm8753.c
+++ b/sound/soc/samsung/neo1973_wm8753.c
@@ -373,7 +373,7 @@ static struct snd_soc_dai_link neo1973_dai[] = {
373{ /* Voice via BT */ 373{ /* Voice via BT */
374 .name = "Bluetooth", 374 .name = "Bluetooth",
375 .stream_name = "Voice", 375 .stream_name = "Voice",
376 .cpu_dai_name = "dfbmcs320-pcm", 376 .cpu_dai_name = "bt-sco-pcm",
377 .codec_dai_name = "wm8753-voice", 377 .codec_dai_name = "wm8753-voice",
378 .codec_name = "wm8753.0-001a", 378 .codec_name = "wm8753.0-001a",
379 .ops = &neo1973_voice_ops, 379 .ops = &neo1973_voice_ops,
diff --git a/sound/soc/samsung/smdk_wm8580pcm.c b/sound/soc/samsung/smdk_wm8580pcm.c
index e43bd4294f99..23a9204b106d 100644
--- a/sound/soc/samsung/smdk_wm8580pcm.c
+++ b/sound/soc/samsung/smdk_wm8580pcm.c
@@ -176,7 +176,6 @@ static int snd_smdk_probe(struct platform_device *pdev)
176static int snd_smdk_remove(struct platform_device *pdev) 176static int snd_smdk_remove(struct platform_device *pdev)
177{ 177{
178 snd_soc_unregister_card(&smdk_pcm); 178 snd_soc_unregister_card(&smdk_pcm);
179 platform_set_drvdata(pdev, NULL);
180 return 0; 179 return 0;
181} 180}
182 181
diff --git a/sound/soc/samsung/smdk_wm8994pcm.c b/sound/soc/samsung/smdk_wm8994pcm.c
index 3688a32000a2..0c84ca099612 100644
--- a/sound/soc/samsung/smdk_wm8994pcm.c
+++ b/sound/soc/samsung/smdk_wm8994pcm.c
@@ -146,7 +146,6 @@ static int snd_smdk_probe(struct platform_device *pdev)
146static int snd_smdk_remove(struct platform_device *pdev) 146static int snd_smdk_remove(struct platform_device *pdev)
147{ 147{
148 snd_soc_unregister_card(&smdk_pcm); 148 snd_soc_unregister_card(&smdk_pcm);
149 platform_set_drvdata(pdev, NULL);
150 return 0; 149 return 0;
151} 150}
152 151
diff --git a/sound/soc/sh/fsi.c b/sound/soc/sh/fsi.c
index f830c41f97dd..30390260bb67 100644
--- a/sound/soc/sh/fsi.c
+++ b/sound/soc/sh/fsi.c
@@ -276,7 +276,7 @@ struct fsi_stream_handler {
276 int (*probe)(struct fsi_priv *fsi, struct fsi_stream *io, struct device *dev); 276 int (*probe)(struct fsi_priv *fsi, struct fsi_stream *io, struct device *dev);
277 int (*transfer)(struct fsi_priv *fsi, struct fsi_stream *io); 277 int (*transfer)(struct fsi_priv *fsi, struct fsi_stream *io);
278 int (*remove)(struct fsi_priv *fsi, struct fsi_stream *io); 278 int (*remove)(struct fsi_priv *fsi, struct fsi_stream *io);
279 void (*start_stop)(struct fsi_priv *fsi, struct fsi_stream *io, 279 int (*start_stop)(struct fsi_priv *fsi, struct fsi_stream *io,
280 int enable); 280 int enable);
281}; 281};
282#define fsi_stream_handler_call(io, func, args...) \ 282#define fsi_stream_handler_call(io, func, args...) \
@@ -1188,7 +1188,7 @@ static int fsi_pio_push(struct fsi_priv *fsi, struct fsi_stream *io)
1188 samples); 1188 samples);
1189} 1189}
1190 1190
1191static void fsi_pio_start_stop(struct fsi_priv *fsi, struct fsi_stream *io, 1191static int fsi_pio_start_stop(struct fsi_priv *fsi, struct fsi_stream *io,
1192 int enable) 1192 int enable)
1193{ 1193{
1194 struct fsi_master *master = fsi_get_master(fsi); 1194 struct fsi_master *master = fsi_get_master(fsi);
@@ -1201,6 +1201,8 @@ static void fsi_pio_start_stop(struct fsi_priv *fsi, struct fsi_stream *io,
1201 1201
1202 if (fsi_is_clk_master(fsi)) 1202 if (fsi_is_clk_master(fsi))
1203 fsi_master_mask_set(master, CLK_RST, clk, (enable) ? clk : 0); 1203 fsi_master_mask_set(master, CLK_RST, clk, (enable) ? clk : 0);
1204
1205 return 0;
1204} 1206}
1205 1207
1206static int fsi_pio_push_init(struct fsi_priv *fsi, struct fsi_stream *io) 1208static int fsi_pio_push_init(struct fsi_priv *fsi, struct fsi_stream *io)
@@ -1409,7 +1411,7 @@ static int fsi_dma_transfer(struct fsi_priv *fsi, struct fsi_stream *io)
1409 return 0; 1411 return 0;
1410} 1412}
1411 1413
1412static void fsi_dma_push_start_stop(struct fsi_priv *fsi, struct fsi_stream *io, 1414static int fsi_dma_push_start_stop(struct fsi_priv *fsi, struct fsi_stream *io,
1413 int start) 1415 int start)
1414{ 1416{
1415 struct fsi_master *master = fsi_get_master(fsi); 1417 struct fsi_master *master = fsi_get_master(fsi);
@@ -1422,6 +1424,8 @@ static void fsi_dma_push_start_stop(struct fsi_priv *fsi, struct fsi_stream *io,
1422 1424
1423 if (fsi_is_clk_master(fsi)) 1425 if (fsi_is_clk_master(fsi))
1424 fsi_master_mask_set(master, CLK_RST, clk, (enable) ? clk : 0); 1426 fsi_master_mask_set(master, CLK_RST, clk, (enable) ? clk : 0);
1427
1428 return 0;
1425} 1429}
1426 1430
1427static int fsi_dma_probe(struct fsi_priv *fsi, struct fsi_stream *io, struct device *dev) 1431static int fsi_dma_probe(struct fsi_priv *fsi, struct fsi_stream *io, struct device *dev)
diff --git a/sound/soc/sh/hac.c b/sound/soc/sh/hac.c
index af19f77b7bf0..0af2e4dfd139 100644
--- a/sound/soc/sh/hac.c
+++ b/sound/soc/sh/hac.c
@@ -227,13 +227,12 @@ static void hac_ac97_coldrst(struct snd_ac97 *ac97)
227 hac_ac97_warmrst(ac97); 227 hac_ac97_warmrst(ac97);
228} 228}
229 229
230struct snd_ac97_bus_ops soc_ac97_ops = { 230static struct snd_ac97_bus_ops hac_ac97_ops = {
231 .read = hac_ac97_read, 231 .read = hac_ac97_read,
232 .write = hac_ac97_write, 232 .write = hac_ac97_write,
233 .reset = hac_ac97_coldrst, 233 .reset = hac_ac97_coldrst,
234 .warm_reset = hac_ac97_warmrst, 234 .warm_reset = hac_ac97_warmrst,
235}; 235};
236EXPORT_SYMBOL_GPL(soc_ac97_ops);
237 236
238static int hac_hw_params(struct snd_pcm_substream *substream, 237static int hac_hw_params(struct snd_pcm_substream *substream,
239 struct snd_pcm_hw_params *params, 238 struct snd_pcm_hw_params *params,
@@ -316,6 +315,10 @@ static const struct snd_soc_component_driver sh4_hac_component = {
316 315
317static int hac_soc_platform_probe(struct platform_device *pdev) 316static int hac_soc_platform_probe(struct platform_device *pdev)
318{ 317{
318 ret = snd_soc_set_ac97_ops(&hac_ac97_ops);
319 if (ret != 0)
320 return ret;
321
319 return snd_soc_register_component(&pdev->dev, &sh4_hac_component, 322 return snd_soc_register_component(&pdev->dev, &sh4_hac_component,
320 sh4_hac_dai, ARRAY_SIZE(sh4_hac_dai)); 323 sh4_hac_dai, ARRAY_SIZE(sh4_hac_dai));
321} 324}
@@ -323,6 +326,7 @@ static int hac_soc_platform_probe(struct platform_device *pdev)
323static int hac_soc_platform_remove(struct platform_device *pdev) 326static int hac_soc_platform_remove(struct platform_device *pdev)
324{ 327{
325 snd_soc_unregister_component(&pdev->dev); 328 snd_soc_unregister_component(&pdev->dev);
329 snd_soc_set_ac97_ops(NULL);
326 return 0; 330 return 0;
327} 331}
328 332
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index d56bbea6e75e..0ec070cf7231 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -272,8 +272,8 @@ static void soc_init_codec_debugfs(struct snd_soc_codec *codec)
272 codec->debugfs_codec_root = debugfs_create_dir(codec->name, 272 codec->debugfs_codec_root = debugfs_create_dir(codec->name,
273 debugfs_card_root); 273 debugfs_card_root);
274 if (!codec->debugfs_codec_root) { 274 if (!codec->debugfs_codec_root) {
275 dev_warn(codec->dev, "ASoC: Failed to create codec debugfs" 275 dev_warn(codec->dev,
276 " directory\n"); 276 "ASoC: Failed to create codec debugfs directory\n");
277 return; 277 return;
278 } 278 }
279 279
@@ -286,8 +286,8 @@ static void soc_init_codec_debugfs(struct snd_soc_codec *codec)
286 codec->debugfs_codec_root, 286 codec->debugfs_codec_root,
287 codec, &codec_reg_fops); 287 codec, &codec_reg_fops);
288 if (!codec->debugfs_reg) 288 if (!codec->debugfs_reg)
289 dev_warn(codec->dev, "ASoC: Failed to create codec register" 289 dev_warn(codec->dev,
290 " debugfs file\n"); 290 "ASoC: Failed to create codec register debugfs file\n");
291 291
292 snd_soc_dapm_debugfs_init(&codec->dapm, codec->debugfs_codec_root); 292 snd_soc_dapm_debugfs_init(&codec->dapm, codec->debugfs_codec_root);
293} 293}
@@ -631,8 +631,7 @@ int snd_soc_suspend(struct device *dev)
631 */ 631 */
632 if (codec->dapm.idle_bias_off) { 632 if (codec->dapm.idle_bias_off) {
633 dev_dbg(codec->dev, 633 dev_dbg(codec->dev,
634 "ASoC: idle_bias_off CODEC on" 634 "ASoC: idle_bias_off CODEC on over suspend\n");
635 " over suspend\n");
636 break; 635 break;
637 } 636 }
638 case SND_SOC_BIAS_OFF: 637 case SND_SOC_BIAS_OFF:
@@ -643,8 +642,8 @@ int snd_soc_suspend(struct device *dev)
643 regcache_mark_dirty(codec->control_data); 642 regcache_mark_dirty(codec->control_data);
644 break; 643 break;
645 default: 644 default:
646 dev_dbg(codec->dev, "ASoC: CODEC is on" 645 dev_dbg(codec->dev,
647 " over suspend\n"); 646 "ASoC: CODEC is on over suspend\n");
648 break; 647 break;
649 } 648 }
650 } 649 }
@@ -713,8 +712,8 @@ static void soc_resume_deferred(struct work_struct *work)
713 codec->suspended = 0; 712 codec->suspended = 0;
714 break; 713 break;
715 default: 714 default:
716 dev_dbg(codec->dev, "ASoC: CODEC was on over" 715 dev_dbg(codec->dev,
717 " suspend\n"); 716 "ASoC: CODEC was on over suspend\n");
718 break; 717 break;
719 } 718 }
720 } 719 }
@@ -1110,8 +1109,8 @@ static int soc_probe_codec(struct snd_soc_card *card,
1110 } 1109 }
1111 WARN(codec->dapm.idle_bias_off && 1110 WARN(codec->dapm.idle_bias_off &&
1112 codec->dapm.bias_level != SND_SOC_BIAS_OFF, 1111 codec->dapm.bias_level != SND_SOC_BIAS_OFF,
1113 "codec %s can not start from non-off bias" 1112 "codec %s can not start from non-off bias with idle_bias_off==1\n",
1114 " with idle_bias_off==1\n", codec->name); 1113 codec->name);
1115 } 1114 }
1116 1115
1117 /* If the driver didn't set I/O up try regmap */ 1116 /* If the driver didn't set I/O up try regmap */
@@ -1582,8 +1581,9 @@ static int snd_soc_init_codec_cache(struct snd_soc_codec *codec,
1582 codec->compress_type = compress_type; 1581 codec->compress_type = compress_type;
1583 ret = snd_soc_cache_init(codec); 1582 ret = snd_soc_cache_init(codec);
1584 if (ret < 0) { 1583 if (ret < 0) {
1585 dev_err(codec->dev, "ASoC: Failed to set cache compression" 1584 dev_err(codec->dev,
1586 " type: %d\n", ret); 1585 "ASoC: Failed to set cache compression type: %d\n",
1586 ret);
1587 return ret; 1587 return ret;
1588 } 1588 }
1589 codec->cache_init = 1; 1589 codec->cache_init = 1;
@@ -1639,8 +1639,9 @@ static int snd_soc_instantiate_card(struct snd_soc_card *card)
1639 ret = snd_card_create(SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1, 1639 ret = snd_card_create(SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1,
1640 card->owner, 0, &card->snd_card); 1640 card->owner, 0, &card->snd_card);
1641 if (ret < 0) { 1641 if (ret < 0) {
1642 dev_err(card->dev, "ASoC: can't create sound card for" 1642 dev_err(card->dev,
1643 " card %s: %d\n", card->name, ret); 1643 "ASoC: can't create sound card for card %s: %d\n",
1644 card->name, ret);
1644 goto base_error; 1645 goto base_error;
1645 } 1646 }
1646 card->snd_card->dev = card->dev; 1647 card->snd_card->dev = card->dev;
@@ -1815,8 +1816,8 @@ static int snd_soc_instantiate_card(struct snd_soc_card *card)
1815 for (i = 0; i < card->num_rtd; i++) { 1816 for (i = 0; i < card->num_rtd; i++) {
1816 ret = soc_register_ac97_dai_link(&card->rtd[i]); 1817 ret = soc_register_ac97_dai_link(&card->rtd[i]);
1817 if (ret < 0) { 1818 if (ret < 0) {
1818 dev_err(card->dev, "ASoC: failed to register AC97:" 1819 dev_err(card->dev,
1819 " %d\n", ret); 1820 "ASoC: failed to register AC97: %d\n", ret);
1820 while (--i >= 0) 1821 while (--i >= 0)
1821 soc_unregister_ac97_dai_link(card->rtd[i].codec); 1822 soc_unregister_ac97_dai_link(card->rtd[i].codec);
1822 goto probe_aux_dev_err; 1823 goto probe_aux_dev_err;
@@ -2079,6 +2080,23 @@ int snd_soc_new_ac97_codec(struct snd_soc_codec *codec,
2079} 2080}
2080EXPORT_SYMBOL_GPL(snd_soc_new_ac97_codec); 2081EXPORT_SYMBOL_GPL(snd_soc_new_ac97_codec);
2081 2082
2083struct snd_ac97_bus_ops *soc_ac97_ops;
2084EXPORT_SYMBOL_GPL(soc_ac97_ops);
2085
2086int snd_soc_set_ac97_ops(struct snd_ac97_bus_ops *ops)
2087{
2088 if (ops == soc_ac97_ops)
2089 return 0;
2090
2091 if (soc_ac97_ops && ops)
2092 return -EBUSY;
2093
2094 soc_ac97_ops = ops;
2095
2096 return 0;
2097}
2098EXPORT_SYMBOL_GPL(snd_soc_set_ac97_ops);
2099
2082/** 2100/**
2083 * snd_soc_free_ac97_codec - free AC97 codec device 2101 * snd_soc_free_ac97_codec - free AC97 codec device
2084 * @codec: audio codec 2102 * @codec: audio codec
@@ -2219,29 +2237,6 @@ int snd_soc_test_bits(struct snd_soc_codec *codec, unsigned short reg,
2219EXPORT_SYMBOL_GPL(snd_soc_test_bits); 2237EXPORT_SYMBOL_GPL(snd_soc_test_bits);
2220 2238
2221/** 2239/**
2222 * snd_soc_set_runtime_hwparams - set the runtime hardware parameters
2223 * @substream: the pcm substream
2224 * @hw: the hardware parameters
2225 *
2226 * Sets the substream runtime hardware parameters.
2227 */
2228int snd_soc_set_runtime_hwparams(struct snd_pcm_substream *substream,
2229 const struct snd_pcm_hardware *hw)
2230{
2231 struct snd_pcm_runtime *runtime = substream->runtime;
2232 runtime->hw.info = hw->info;
2233 runtime->hw.formats = hw->formats;
2234 runtime->hw.period_bytes_min = hw->period_bytes_min;
2235 runtime->hw.period_bytes_max = hw->period_bytes_max;
2236 runtime->hw.periods_min = hw->periods_min;
2237 runtime->hw.periods_max = hw->periods_max;
2238 runtime->hw.buffer_bytes_max = hw->buffer_bytes_max;
2239 runtime->hw.fifo_size = hw->fifo_size;
2240 return 0;
2241}
2242EXPORT_SYMBOL_GPL(snd_soc_set_runtime_hwparams);
2243
2244/**
2245 * snd_soc_cnew - create new control 2240 * snd_soc_cnew - create new control
2246 * @_template: control template 2241 * @_template: control template
2247 * @data: control private data 2242 * @data: control private data
@@ -2259,7 +2254,6 @@ struct snd_kcontrol *snd_soc_cnew(const struct snd_kcontrol_new *_template,
2259 struct snd_kcontrol_new template; 2254 struct snd_kcontrol_new template;
2260 struct snd_kcontrol *kcontrol; 2255 struct snd_kcontrol *kcontrol;
2261 char *name = NULL; 2256 char *name = NULL;
2262 int name_len;
2263 2257
2264 memcpy(&template, _template, sizeof(template)); 2258 memcpy(&template, _template, sizeof(template));
2265 template.index = 0; 2259 template.index = 0;
@@ -2268,13 +2262,10 @@ struct snd_kcontrol *snd_soc_cnew(const struct snd_kcontrol_new *_template,
2268 long_name = template.name; 2262 long_name = template.name;
2269 2263
2270 if (prefix) { 2264 if (prefix) {
2271 name_len = strlen(long_name) + strlen(prefix) + 2; 2265 name = kasprintf(GFP_KERNEL, "%s %s", prefix, long_name);
2272 name = kmalloc(name_len, GFP_KERNEL);
2273 if (!name) 2266 if (!name)
2274 return NULL; 2267 return NULL;
2275 2268
2276 snprintf(name, name_len, "%s %s", prefix, long_name);
2277
2278 template.name = name; 2269 template.name = name;
2279 } else { 2270 } else {
2280 template.name = long_name; 2271 template.name = long_name;
@@ -3586,14 +3577,16 @@ int snd_soc_register_card(struct snd_soc_card *card)
3586 * not both or neither. 3577 * not both or neither.
3587 */ 3578 */
3588 if (!!link->codec_name == !!link->codec_of_node) { 3579 if (!!link->codec_name == !!link->codec_of_node) {
3589 dev_err(card->dev, "ASoC: Neither/both codec" 3580 dev_err(card->dev,
3590 " name/of_node are set for %s\n", link->name); 3581 "ASoC: Neither/both codec name/of_node are set for %s\n",
3582 link->name);
3591 return -EINVAL; 3583 return -EINVAL;
3592 } 3584 }
3593 /* Codec DAI name must be specified */ 3585 /* Codec DAI name must be specified */
3594 if (!link->codec_dai_name) { 3586 if (!link->codec_dai_name) {
3595 dev_err(card->dev, "ASoC: codec_dai_name not" 3587 dev_err(card->dev,
3596 " set for %s\n", link->name); 3588 "ASoC: codec_dai_name not set for %s\n",
3589 link->name);
3597 return -EINVAL; 3590 return -EINVAL;
3598 } 3591 }
3599 3592
@@ -3602,8 +3595,9 @@ int snd_soc_register_card(struct snd_soc_card *card)
3602 * can be left unspecified, and a dummy platform will be used. 3595 * can be left unspecified, and a dummy platform will be used.
3603 */ 3596 */
3604 if (link->platform_name && link->platform_of_node) { 3597 if (link->platform_name && link->platform_of_node) {
3605 dev_err(card->dev, "ASoC: Both platform name/of_node" 3598 dev_err(card->dev,
3606 " are set for %s\n", link->name); 3599 "ASoC: Both platform name/of_node are set for %s\n",
3600 link->name);
3607 return -EINVAL; 3601 return -EINVAL;
3608 } 3602 }
3609 3603
@@ -3613,8 +3607,9 @@ int snd_soc_register_card(struct snd_soc_card *card)
3613 * name alone.. 3607 * name alone..
3614 */ 3608 */
3615 if (link->cpu_name && link->cpu_of_node) { 3609 if (link->cpu_name && link->cpu_of_node) {
3616 dev_err(card->dev, "ASoC: Neither/both " 3610 dev_err(card->dev,
3617 "cpu name/of_node are set for %s\n",link->name); 3611 "ASoC: Neither/both cpu name/of_node are set for %s\n",
3612 link->name);
3618 return -EINVAL; 3613 return -EINVAL;
3619 } 3614 }
3620 /* 3615 /*
@@ -3623,8 +3618,9 @@ int snd_soc_register_card(struct snd_soc_card *card)
3623 */ 3618 */
3624 if (!link->cpu_dai_name && 3619 if (!link->cpu_dai_name &&
3625 !(link->cpu_name || link->cpu_of_node)) { 3620 !(link->cpu_name || link->cpu_of_node)) {
3626 dev_err(card->dev, "ASoC: Neither cpu_dai_name nor " 3621 dev_err(card->dev,
3627 "cpu_name/of_node are set for %s\n", link->name); 3622 "ASoC: Neither cpu_dai_name nor cpu_name/of_node are set for %s\n",
3623 link->name);
3628 return -EINVAL; 3624 return -EINVAL;
3629 } 3625 }
3630 } 3626 }
@@ -3728,8 +3724,9 @@ static inline char *fmt_multiple_name(struct device *dev,
3728 struct snd_soc_dai_driver *dai_drv) 3724 struct snd_soc_dai_driver *dai_drv)
3729{ 3725{
3730 if (dai_drv->name == NULL) { 3726 if (dai_drv->name == NULL) {
3731 dev_err(dev, "ASoC: error - multiple DAI %s registered with" 3727 dev_err(dev,
3732 " no name\n", dev_name(dev)); 3728 "ASoC: error - multiple DAI %s registered with no name\n",
3729 dev_name(dev));
3733 return NULL; 3730 return NULL;
3734 } 3731 }
3735 3732
@@ -3859,8 +3856,9 @@ static int snd_soc_register_dais(struct device *dev,
3859 3856
3860 list_for_each_entry(codec, &codec_list, list) { 3857 list_for_each_entry(codec, &codec_list, list) {
3861 if (codec->dev == dev) { 3858 if (codec->dev == dev) {
3862 dev_dbg(dev, "ASoC: Mapped DAI %s to " 3859 dev_dbg(dev,
3863 "CODEC %s\n", dai->name, codec->name); 3860 "ASoC: Mapped DAI %s to CODEC %s\n",
3861 dai->name, codec->name);
3864 dai->codec = codec; 3862 dai->codec = codec;
3865 break; 3863 break;
3866 } 3864 }
@@ -4296,8 +4294,9 @@ int snd_soc_of_parse_audio_routing(struct snd_soc_card *card,
4296 4294
4297 num_routes = of_property_count_strings(np, propname); 4295 num_routes = of_property_count_strings(np, propname);
4298 if (num_routes < 0 || num_routes & 1) { 4296 if (num_routes < 0 || num_routes & 1) {
4299 dev_err(card->dev, "ASoC: Property '%s' does not exist or its" 4297 dev_err(card->dev,
4300 " length is not even\n", propname); 4298 "ASoC: Property '%s' does not exist or its length is not even\n",
4299 propname);
4301 return -EINVAL; 4300 return -EINVAL;
4302 } 4301 }
4303 num_routes /= 2; 4302 num_routes /= 2;
diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c
index c7051c457b75..b94190820e8c 100644
--- a/sound/soc/soc-dapm.c
+++ b/sound/soc/soc-dapm.c
@@ -64,6 +64,7 @@ static int dapm_up_seq[] = {
64 [snd_soc_dapm_virt_mux] = 5, 64 [snd_soc_dapm_virt_mux] = 5,
65 [snd_soc_dapm_value_mux] = 5, 65 [snd_soc_dapm_value_mux] = 5,
66 [snd_soc_dapm_dac] = 6, 66 [snd_soc_dapm_dac] = 6,
67 [snd_soc_dapm_switch] = 7,
67 [snd_soc_dapm_mixer] = 7, 68 [snd_soc_dapm_mixer] = 7,
68 [snd_soc_dapm_mixer_named_ctl] = 7, 69 [snd_soc_dapm_mixer_named_ctl] = 7,
69 [snd_soc_dapm_pga] = 8, 70 [snd_soc_dapm_pga] = 8,
@@ -83,6 +84,7 @@ static int dapm_down_seq[] = {
83 [snd_soc_dapm_line] = 2, 84 [snd_soc_dapm_line] = 2,
84 [snd_soc_dapm_out_drv] = 2, 85 [snd_soc_dapm_out_drv] = 2,
85 [snd_soc_dapm_pga] = 4, 86 [snd_soc_dapm_pga] = 4,
87 [snd_soc_dapm_switch] = 5,
86 [snd_soc_dapm_mixer_named_ctl] = 5, 88 [snd_soc_dapm_mixer_named_ctl] = 5,
87 [snd_soc_dapm_mixer] = 5, 89 [snd_soc_dapm_mixer] = 5,
88 [snd_soc_dapm_dac] = 6, 90 [snd_soc_dapm_dac] = 6,
@@ -365,11 +367,10 @@ static void dapm_set_path_status(struct snd_soc_dapm_widget *w,
365 val = soc_widget_read(w, e->reg); 367 val = soc_widget_read(w, e->reg);
366 item = (val >> e->shift_l) & e->mask; 368 item = (val >> e->shift_l) & e->mask;
367 369
368 p->connect = 0; 370 if (item < e->max && !strcmp(p->name, e->texts[item]))
369 for (i = 0; i < e->max; i++) { 371 p->connect = 1;
370 if (!(strcmp(p->name, e->texts[i])) && item == i) 372 else
371 p->connect = 1; 373 p->connect = 0;
372 }
373 } 374 }
374 break; 375 break;
375 case snd_soc_dapm_virt_mux: { 376 case snd_soc_dapm_virt_mux: {
@@ -399,11 +400,10 @@ static void dapm_set_path_status(struct snd_soc_dapm_widget *w,
399 break; 400 break;
400 } 401 }
401 402
402 p->connect = 0; 403 if (item < e->max && !strcmp(p->name, e->texts[item]))
403 for (i = 0; i < e->max; i++) { 404 p->connect = 1;
404 if (!(strcmp(p->name, e->texts[i])) && item == i) 405 else
405 p->connect = 1; 406 p->connect = 0;
406 }
407 } 407 }
408 break; 408 break;
409 /* does not affect routing - always connected */ 409 /* does not affect routing - always connected */
@@ -507,6 +507,11 @@ static int dapm_is_shared_kcontrol(struct snd_soc_dapm_context *dapm,
507 return 0; 507 return 0;
508} 508}
509 509
510static void dapm_kcontrol_free(struct snd_kcontrol *kctl)
511{
512 kfree(kctl->private_data);
513}
514
510/* 515/*
511 * Determine if a kcontrol is shared. If it is, look it up. If it isn't, 516 * Determine if a kcontrol is shared. If it is, look it up. If it isn't,
512 * create it. Either way, add the widget into the control's widget list 517 * create it. Either way, add the widget into the control's widget list
@@ -524,7 +529,6 @@ static int dapm_create_or_share_mixmux_kcontrol(struct snd_soc_dapm_widget *w,
524 int wlistentries; 529 int wlistentries;
525 size_t wlistsize; 530 size_t wlistsize;
526 bool wname_in_long_name, kcname_in_long_name; 531 bool wname_in_long_name, kcname_in_long_name;
527 size_t name_len;
528 char *long_name; 532 char *long_name;
529 const char *name; 533 const char *name;
530 int ret; 534 int ret;
@@ -589,25 +593,19 @@ static int dapm_create_or_share_mixmux_kcontrol(struct snd_soc_dapm_widget *w,
589 } 593 }
590 594
591 if (wname_in_long_name && kcname_in_long_name) { 595 if (wname_in_long_name && kcname_in_long_name) {
592 name_len = strlen(w->name) - prefix_len + 1 +
593 strlen(w->kcontrol_news[kci].name) + 1;
594
595 long_name = kmalloc(name_len, GFP_KERNEL);
596 if (long_name == NULL) {
597 kfree(wlist);
598 return -ENOMEM;
599 }
600
601 /* 596 /*
602 * The control will get a prefix from the control 597 * The control will get a prefix from the control
603 * creation process but we're also using the same 598 * creation process but we're also using the same
604 * prefix for widgets so cut the prefix off the 599 * prefix for widgets so cut the prefix off the
605 * front of the widget name. 600 * front of the widget name.
606 */ 601 */
607 snprintf(long_name, name_len, "%s %s", 602 long_name = kasprintf(GFP_KERNEL, "%s %s",
608 w->name + prefix_len, 603 w->name + prefix_len,
609 w->kcontrol_news[kci].name); 604 w->kcontrol_news[kci].name);
610 long_name[name_len - 1] = '\0'; 605 if (long_name == NULL) {
606 kfree(wlist);
607 return -ENOMEM;
608 }
611 609
612 name = long_name; 610 name = long_name;
613 } else if (wname_in_long_name) { 611 } else if (wname_in_long_name) {
@@ -620,17 +618,16 @@ static int dapm_create_or_share_mixmux_kcontrol(struct snd_soc_dapm_widget *w,
620 618
621 kcontrol = snd_soc_cnew(&w->kcontrol_news[kci], wlist, name, 619 kcontrol = snd_soc_cnew(&w->kcontrol_news[kci], wlist, name,
622 prefix); 620 prefix);
621 kcontrol->private_free = dapm_kcontrol_free;
622 kfree(long_name);
623 ret = snd_ctl_add(card, kcontrol); 623 ret = snd_ctl_add(card, kcontrol);
624 if (ret < 0) { 624 if (ret < 0) {
625 dev_err(dapm->dev, 625 dev_err(dapm->dev,
626 "ASoC: failed to add widget %s dapm kcontrol %s: %d\n", 626 "ASoC: failed to add widget %s dapm kcontrol %s: %d\n",
627 w->name, name, ret); 627 w->name, name, ret);
628 kfree(wlist); 628 kfree(wlist);
629 kfree(long_name);
630 return ret; 629 return ret;
631 } 630 }
632
633 path->long_name = long_name;
634 } 631 }
635 632
636 kcontrol->private_data = wlist; 633 kcontrol->private_data = wlist;
@@ -1270,6 +1267,14 @@ static void dapm_seq_check_event(struct snd_soc_dapm_context *dapm,
1270 ev_name = "POST_PMD"; 1267 ev_name = "POST_PMD";
1271 power = 0; 1268 power = 0;
1272 break; 1269 break;
1270 case SND_SOC_DAPM_WILL_PMU:
1271 ev_name = "WILL_PMU";
1272 power = 1;
1273 break;
1274 case SND_SOC_DAPM_WILL_PMD:
1275 ev_name = "WILL_PMD";
1276 power = 0;
1277 break;
1273 default: 1278 default:
1274 BUG(); 1279 BUG();
1275 return; 1280 return;
@@ -1730,6 +1735,14 @@ static int dapm_power_widgets(struct snd_soc_dapm_context *dapm, int event)
1730 &async_domain); 1735 &async_domain);
1731 async_synchronize_full_domain(&async_domain); 1736 async_synchronize_full_domain(&async_domain);
1732 1737
1738 list_for_each_entry(w, &down_list, power_list) {
1739 dapm_seq_check_event(dapm, w, SND_SOC_DAPM_WILL_PMD);
1740 }
1741
1742 list_for_each_entry(w, &up_list, power_list) {
1743 dapm_seq_check_event(dapm, w, SND_SOC_DAPM_WILL_PMU);
1744 }
1745
1733 /* Power down widgets first; try to avoid amplifying pops. */ 1746 /* Power down widgets first; try to avoid amplifying pops. */
1734 dapm_seq_run(dapm, &down_list, event, false); 1747 dapm_seq_run(dapm, &down_list, event, false);
1735 1748
@@ -2094,6 +2107,14 @@ static void snd_soc_dapm_sys_remove(struct device *dev)
2094 device_remove_file(dev, &dev_attr_dapm_widget); 2107 device_remove_file(dev, &dev_attr_dapm_widget);
2095} 2108}
2096 2109
2110static void dapm_free_path(struct snd_soc_dapm_path *path)
2111{
2112 list_del(&path->list_sink);
2113 list_del(&path->list_source);
2114 list_del(&path->list);
2115 kfree(path);
2116}
2117
2097/* free all dapm widgets and resources */ 2118/* free all dapm widgets and resources */
2098static void dapm_free_widgets(struct snd_soc_dapm_context *dapm) 2119static void dapm_free_widgets(struct snd_soc_dapm_context *dapm)
2099{ 2120{
@@ -2109,20 +2130,12 @@ static void dapm_free_widgets(struct snd_soc_dapm_context *dapm)
2109 * While removing the path, remove reference to it from both 2130 * While removing the path, remove reference to it from both
2110 * source and sink widgets so that path is removed only once. 2131 * source and sink widgets so that path is removed only once.
2111 */ 2132 */
2112 list_for_each_entry_safe(p, next_p, &w->sources, list_sink) { 2133 list_for_each_entry_safe(p, next_p, &w->sources, list_sink)
2113 list_del(&p->list_sink); 2134 dapm_free_path(p);
2114 list_del(&p->list_source); 2135
2115 list_del(&p->list); 2136 list_for_each_entry_safe(p, next_p, &w->sinks, list_source)
2116 kfree(p->long_name); 2137 dapm_free_path(p);
2117 kfree(p); 2138
2118 }
2119 list_for_each_entry_safe(p, next_p, &w->sinks, list_source) {
2120 list_del(&p->list_sink);
2121 list_del(&p->list_source);
2122 list_del(&p->list);
2123 kfree(p->long_name);
2124 kfree(p);
2125 }
2126 kfree(w->kcontrols); 2139 kfree(w->kcontrols);
2127 kfree(w->name); 2140 kfree(w->name);
2128 kfree(w); 2141 kfree(w);
@@ -2398,10 +2411,7 @@ static int snd_soc_dapm_del_route(struct snd_soc_dapm_context *dapm,
2398 dapm_mark_dirty(path->source, "Route removed"); 2411 dapm_mark_dirty(path->source, "Route removed");
2399 dapm_mark_dirty(path->sink, "Route removed"); 2412 dapm_mark_dirty(path->sink, "Route removed");
2400 2413
2401 list_del(&path->list); 2414 dapm_free_path(path);
2402 list_del(&path->list_sink);
2403 list_del(&path->list_source);
2404 kfree(path);
2405 } else { 2415 } else {
2406 dev_warn(dapm->dev, "ASoC: Route %s->%s does not exist\n", 2416 dev_warn(dapm->dev, "ASoC: Route %s->%s does not exist\n",
2407 source, sink); 2417 source, sink);
@@ -3055,7 +3065,6 @@ snd_soc_dapm_new_control(struct snd_soc_dapm_context *dapm,
3055 const struct snd_soc_dapm_widget *widget) 3065 const struct snd_soc_dapm_widget *widget)
3056{ 3066{
3057 struct snd_soc_dapm_widget *w; 3067 struct snd_soc_dapm_widget *w;
3058 size_t name_len;
3059 int ret; 3068 int ret;
3060 3069
3061 if ((w = dapm_cnew_widget(widget)) == NULL) 3070 if ((w = dapm_cnew_widget(widget)) == NULL)
@@ -3096,19 +3105,16 @@ snd_soc_dapm_new_control(struct snd_soc_dapm_context *dapm,
3096 break; 3105 break;
3097 } 3106 }
3098 3107
3099 name_len = strlen(widget->name) + 1;
3100 if (dapm->codec && dapm->codec->name_prefix) 3108 if (dapm->codec && dapm->codec->name_prefix)
3101 name_len += 1 + strlen(dapm->codec->name_prefix); 3109 w->name = kasprintf(GFP_KERNEL, "%s %s",
3102 w->name = kmalloc(name_len, GFP_KERNEL); 3110 dapm->codec->name_prefix, widget->name);
3111 else
3112 w->name = kasprintf(GFP_KERNEL, "%s", widget->name);
3113
3103 if (w->name == NULL) { 3114 if (w->name == NULL) {
3104 kfree(w); 3115 kfree(w);
3105 return NULL; 3116 return NULL;
3106 } 3117 }
3107 if (dapm->codec && dapm->codec->name_prefix)
3108 snprintf((char *)w->name, name_len, "%s %s",
3109 dapm->codec->name_prefix, widget->name);
3110 else
3111 snprintf((char *)w->name, name_len, "%s", widget->name);
3112 3118
3113 switch (w->id) { 3119 switch (w->id) {
3114 case snd_soc_dapm_switch: 3120 case snd_soc_dapm_switch:
diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c
index ccb6be4d658d..b6c640332a17 100644
--- a/sound/soc/soc-pcm.c
+++ b/sound/soc/soc-pcm.c
@@ -33,6 +33,29 @@
33 33
34#define DPCM_MAX_BE_USERS 8 34#define DPCM_MAX_BE_USERS 8
35 35
36/**
37 * snd_soc_set_runtime_hwparams - set the runtime hardware parameters
38 * @substream: the pcm substream
39 * @hw: the hardware parameters
40 *
41 * Sets the substream runtime hardware parameters.
42 */
43int snd_soc_set_runtime_hwparams(struct snd_pcm_substream *substream,
44 const struct snd_pcm_hardware *hw)
45{
46 struct snd_pcm_runtime *runtime = substream->runtime;
47 runtime->hw.info = hw->info;
48 runtime->hw.formats = hw->formats;
49 runtime->hw.period_bytes_min = hw->period_bytes_min;
50 runtime->hw.period_bytes_max = hw->period_bytes_max;
51 runtime->hw.periods_min = hw->periods_min;
52 runtime->hw.periods_max = hw->periods_max;
53 runtime->hw.buffer_bytes_max = hw->buffer_bytes_max;
54 runtime->hw.fifo_size = hw->fifo_size;
55 return 0;
56}
57EXPORT_SYMBOL_GPL(snd_soc_set_runtime_hwparams);
58
36/* DPCM stream event, send event to FE and all active BEs. */ 59/* DPCM stream event, send event to FE and all active BEs. */
37static int dpcm_dapm_stream_event(struct snd_soc_pcm_runtime *fe, int dir, 60static int dpcm_dapm_stream_event(struct snd_soc_pcm_runtime *fe, int dir,
38 int event) 61 int event)
@@ -124,6 +147,26 @@ static void soc_pcm_apply_msb(struct snd_pcm_substream *substream,
124 } 147 }
125} 148}
126 149
150static void soc_pcm_init_runtime_hw(struct snd_pcm_hardware *hw,
151 struct snd_soc_pcm_stream *codec_stream,
152 struct snd_soc_pcm_stream *cpu_stream)
153{
154 hw->rate_min = max(codec_stream->rate_min, cpu_stream->rate_min);
155 hw->rate_max = max(codec_stream->rate_max, cpu_stream->rate_max);
156 hw->channels_min = max(codec_stream->channels_min,
157 cpu_stream->channels_min);
158 hw->channels_max = min(codec_stream->channels_max,
159 cpu_stream->channels_max);
160 hw->formats = codec_stream->formats & cpu_stream->formats;
161 hw->rates = codec_stream->rates & cpu_stream->rates;
162 if (codec_stream->rates
163 & (SNDRV_PCM_RATE_KNOT | SNDRV_PCM_RATE_CONTINUOUS))
164 hw->rates |= cpu_stream->rates;
165 if (cpu_stream->rates
166 & (SNDRV_PCM_RATE_KNOT | SNDRV_PCM_RATE_CONTINUOUS))
167 hw->rates |= codec_stream->rates;
168}
169
127/* 170/*
128 * Called by ALSA when a PCM substream is opened, the runtime->hw record is 171 * Called by ALSA when a PCM substream is opened, the runtime->hw record is
129 * then initialized and any private data can be allocated. This also calls 172 * then initialized and any private data can be allocated. This also calls
@@ -189,51 +232,11 @@ static int soc_pcm_open(struct snd_pcm_substream *substream)
189 232
190 /* Check that the codec and cpu DAIs are compatible */ 233 /* Check that the codec and cpu DAIs are compatible */
191 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { 234 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
192 runtime->hw.rate_min = 235 soc_pcm_init_runtime_hw(&runtime->hw, &codec_dai_drv->playback,
193 max(codec_dai_drv->playback.rate_min, 236 &cpu_dai_drv->playback);
194 cpu_dai_drv->playback.rate_min);
195 runtime->hw.rate_max =
196 min(codec_dai_drv->playback.rate_max,
197 cpu_dai_drv->playback.rate_max);
198 runtime->hw.channels_min =
199 max(codec_dai_drv->playback.channels_min,
200 cpu_dai_drv->playback.channels_min);
201 runtime->hw.channels_max =
202 min(codec_dai_drv->playback.channels_max,
203 cpu_dai_drv->playback.channels_max);
204 runtime->hw.formats =
205 codec_dai_drv->playback.formats & cpu_dai_drv->playback.formats;
206 runtime->hw.rates =
207 codec_dai_drv->playback.rates & cpu_dai_drv->playback.rates;
208 if (codec_dai_drv->playback.rates
209 & (SNDRV_PCM_RATE_KNOT | SNDRV_PCM_RATE_CONTINUOUS))
210 runtime->hw.rates |= cpu_dai_drv->playback.rates;
211 if (cpu_dai_drv->playback.rates
212 & (SNDRV_PCM_RATE_KNOT | SNDRV_PCM_RATE_CONTINUOUS))
213 runtime->hw.rates |= codec_dai_drv->playback.rates;
214 } else { 237 } else {
215 runtime->hw.rate_min = 238 soc_pcm_init_runtime_hw(&runtime->hw, &codec_dai_drv->capture,
216 max(codec_dai_drv->capture.rate_min, 239 &cpu_dai_drv->capture);
217 cpu_dai_drv->capture.rate_min);
218 runtime->hw.rate_max =
219 min(codec_dai_drv->capture.rate_max,
220 cpu_dai_drv->capture.rate_max);
221 runtime->hw.channels_min =
222 max(codec_dai_drv->capture.channels_min,
223 cpu_dai_drv->capture.channels_min);
224 runtime->hw.channels_max =
225 min(codec_dai_drv->capture.channels_max,
226 cpu_dai_drv->capture.channels_max);
227 runtime->hw.formats =
228 codec_dai_drv->capture.formats & cpu_dai_drv->capture.formats;
229 runtime->hw.rates =
230 codec_dai_drv->capture.rates & cpu_dai_drv->capture.rates;
231 if (codec_dai_drv->capture.rates
232 & (SNDRV_PCM_RATE_KNOT | SNDRV_PCM_RATE_CONTINUOUS))
233 runtime->hw.rates |= cpu_dai_drv->capture.rates;
234 if (cpu_dai_drv->capture.rates
235 & (SNDRV_PCM_RATE_KNOT | SNDRV_PCM_RATE_CONTINUOUS))
236 runtime->hw.rates |= codec_dai_drv->capture.rates;
237 } 240 }
238 241
239 ret = -EINVAL; 242 ret = -EINVAL;
diff --git a/sound/soc/soc-utils.c b/sound/soc/soc-utils.c
index 4b3be6c3c91e..29b211e9c060 100644
--- a/sound/soc/soc-utils.c
+++ b/sound/soc/soc-utils.c
@@ -159,15 +159,10 @@ int __init snd_soc_util_init(void)
159{ 159{
160 int ret; 160 int ret;
161 161
162 soc_dummy_dev = platform_device_alloc("snd-soc-dummy", -1); 162 soc_dummy_dev =
163 if (!soc_dummy_dev) 163 platform_device_register_simple("snd-soc-dummy", -1, NULL, 0);
164 return -ENOMEM; 164 if (IS_ERR(soc_dummy_dev))
165 165 return PTR_ERR(soc_dummy_dev);
166 ret = platform_device_add(soc_dummy_dev);
167 if (ret != 0) {
168 platform_device_put(soc_dummy_dev);
169 return ret;
170 }
171 166
172 ret = platform_driver_register(&soc_dummy_driver); 167 ret = platform_driver_register(&soc_dummy_driver);
173 if (ret != 0) 168 if (ret != 0)
diff --git a/sound/soc/spear/Kconfig b/sound/soc/spear/Kconfig
new file mode 100644
index 000000000000..3567d73b218e
--- /dev/null
+++ b/sound/soc/spear/Kconfig
@@ -0,0 +1,9 @@
1config SND_SPEAR_SOC
2 tristate
3 select SND_SOC_DMAENGINE_PCM
4
5config SND_SPEAR_SPDIF_OUT
6 tristate
7
8config SND_SPEAR_SPDIF_IN
9 tristate
diff --git a/sound/soc/spear/Makefile b/sound/soc/spear/Makefile
new file mode 100644
index 000000000000..c4ea7161056c
--- /dev/null
+++ b/sound/soc/spear/Makefile
@@ -0,0 +1,8 @@
1# SPEAR Platform Support
2snd-soc-spear-pcm-objs := spear_pcm.o
3snd-soc-spear-spdif-in-objs := spdif_in.o
4snd-soc-spear-spdif-out-objs := spdif_out.o
5
6obj-$(CONFIG_SND_SPEAR_SOC) += snd-soc-spear-pcm.o
7obj-$(CONFIG_SND_SPEAR_SPDIF_IN) += snd-soc-spear-spdif-in.o
8obj-$(CONFIG_SND_SPEAR_SPDIF_OUT) += snd-soc-spear-spdif-out.o
diff --git a/sound/soc/spear/spdif_in.c b/sound/soc/spear/spdif_in.c
index 14d57e89bcba..63acfeb4b69d 100644
--- a/sound/soc/spear/spdif_in.c
+++ b/sound/soc/spear/spdif_in.c
@@ -49,15 +49,12 @@ static void spdif_in_configure(struct spdif_in_dev *host)
49 writel(0xF, host->io_base + SPDIF_IN_IRQ_MASK); 49 writel(0xF, host->io_base + SPDIF_IN_IRQ_MASK);
50} 50}
51 51
52static int spdif_in_startup(struct snd_pcm_substream *substream, 52static int spdif_in_dai_probe(struct snd_soc_dai *dai)
53 struct snd_soc_dai *cpu_dai)
54{ 53{
55 struct spdif_in_dev *host = snd_soc_dai_get_drvdata(cpu_dai); 54 struct spdif_in_dev *host = snd_soc_dai_get_drvdata(dai);
56 55
57 if (substream->stream != SNDRV_PCM_STREAM_CAPTURE) 56 dai->capture_dma_data = &host->dma_params;
58 return -EINVAL;
59 57
60 snd_soc_dai_set_dma_data(cpu_dai, substream, (void *)&host->dma_params);
61 return 0; 58 return 0;
62} 59}
63 60
@@ -70,7 +67,6 @@ static void spdif_in_shutdown(struct snd_pcm_substream *substream,
70 return; 67 return;
71 68
72 writel(0x0, host->io_base + SPDIF_IN_IRQ_MASK); 69 writel(0x0, host->io_base + SPDIF_IN_IRQ_MASK);
73 snd_soc_dai_set_dma_data(dai, substream, NULL);
74} 70}
75 71
76static void spdif_in_format(struct spdif_in_dev *host, u32 format) 72static void spdif_in_format(struct spdif_in_dev *host, u32 format)
@@ -151,13 +147,13 @@ static int spdif_in_trigger(struct snd_pcm_substream *substream, int cmd,
151} 147}
152 148
153static struct snd_soc_dai_ops spdif_in_dai_ops = { 149static struct snd_soc_dai_ops spdif_in_dai_ops = {
154 .startup = spdif_in_startup,
155 .shutdown = spdif_in_shutdown, 150 .shutdown = spdif_in_shutdown,
156 .trigger = spdif_in_trigger, 151 .trigger = spdif_in_trigger,
157 .hw_params = spdif_in_hw_params, 152 .hw_params = spdif_in_hw_params,
158}; 153};
159 154
160struct snd_soc_dai_driver spdif_in_dai = { 155static struct snd_soc_dai_driver spdif_in_dai = {
156 .probe = spdif_in_dai_probe,
161 .capture = { 157 .capture = {
162 .channels_min = 2, 158 .channels_min = 2,
163 .channels_max = 2, 159 .channels_max = 2,
@@ -235,7 +231,7 @@ static int spdif_in_probe(struct platform_device *pdev)
235 if (host->irq < 0) 231 if (host->irq < 0)
236 return -EINVAL; 232 return -EINVAL;
237 233
238 host->clk = clk_get(&pdev->dev, NULL); 234 host->clk = devm_clk_get(&pdev->dev, NULL);
239 if (IS_ERR(host->clk)) 235 if (IS_ERR(host->clk))
240 return PTR_ERR(host->clk); 236 return PTR_ERR(host->clk);
241 237
@@ -257,34 +253,21 @@ static int spdif_in_probe(struct platform_device *pdev)
257 ret = devm_request_irq(&pdev->dev, host->irq, spdif_in_irq, 0, 253 ret = devm_request_irq(&pdev->dev, host->irq, spdif_in_irq, 0,
258 "spdif-in", host); 254 "spdif-in", host);
259 if (ret) { 255 if (ret) {
260 clk_put(host->clk);
261 dev_warn(&pdev->dev, "request_irq failed\n"); 256 dev_warn(&pdev->dev, "request_irq failed\n");
262 return ret; 257 return ret;
263 } 258 }
264 259
265 ret = snd_soc_register_component(&pdev->dev, &spdif_in_component, 260 return snd_soc_register_component(&pdev->dev, &spdif_in_component,
266 &spdif_in_dai, 1); 261 &spdif_in_dai, 1);
267 if (ret != 0) {
268 clk_put(host->clk);
269 return ret;
270 }
271
272 return 0;
273} 262}
274 263
275static int spdif_in_remove(struct platform_device *pdev) 264static int spdif_in_remove(struct platform_device *pdev)
276{ 265{
277 struct spdif_in_dev *host = dev_get_drvdata(&pdev->dev);
278
279 snd_soc_unregister_component(&pdev->dev); 266 snd_soc_unregister_component(&pdev->dev);
280 dev_set_drvdata(&pdev->dev, NULL);
281
282 clk_put(host->clk);
283 267
284 return 0; 268 return 0;
285} 269}
286 270
287
288static struct platform_driver spdif_in_driver = { 271static struct platform_driver spdif_in_driver = {
289 .probe = spdif_in_probe, 272 .probe = spdif_in_probe,
290 .remove = spdif_in_remove, 273 .remove = spdif_in_remove,
diff --git a/sound/soc/spear/spdif_out.c b/sound/soc/spear/spdif_out.c
index 1e3c3dda3598..2fdf68c98d22 100644
--- a/sound/soc/spear/spdif_out.c
+++ b/sound/soc/spear/spdif_out.c
@@ -62,8 +62,6 @@ static int spdif_out_startup(struct snd_pcm_substream *substream,
62 if (substream->stream != SNDRV_PCM_STREAM_PLAYBACK) 62 if (substream->stream != SNDRV_PCM_STREAM_PLAYBACK)
63 return -EINVAL; 63 return -EINVAL;
64 64
65 snd_soc_dai_set_dma_data(cpu_dai, substream, (void *)&host->dma_params);
66
67 ret = clk_enable(host->clk); 65 ret = clk_enable(host->clk);
68 if (ret) 66 if (ret)
69 return ret; 67 return ret;
@@ -84,7 +82,6 @@ static void spdif_out_shutdown(struct snd_pcm_substream *substream,
84 82
85 clk_disable(host->clk); 83 clk_disable(host->clk);
86 host->running = false; 84 host->running = false;
87 snd_soc_dai_set_dma_data(dai, substream, NULL);
88} 85}
89 86
90static void spdif_out_clock(struct spdif_out_dev *host, u32 core_freq, 87static void spdif_out_clock(struct spdif_out_dev *host, u32 core_freq,
@@ -243,8 +240,12 @@ static const struct snd_kcontrol_new spdif_out_controls[] = {
243 spdif_mute_get, spdif_mute_put), 240 spdif_mute_get, spdif_mute_put),
244}; 241};
245 242
246int spdif_soc_dai_probe(struct snd_soc_dai *dai) 243static int spdif_soc_dai_probe(struct snd_soc_dai *dai)
247{ 244{
245 struct spdif_out_dev *host = snd_soc_dai_get_drvdata(dai);
246
247 dai->playback_dma_data = &host->dma_params;
248
248 return snd_soc_add_dai_controls(dai, spdif_out_controls, 249 return snd_soc_add_dai_controls(dai, spdif_out_controls,
249 ARRAY_SIZE(spdif_out_controls)); 250 ARRAY_SIZE(spdif_out_controls));
250} 251}
@@ -281,30 +282,18 @@ static int spdif_out_probe(struct platform_device *pdev)
281 struct resource *res; 282 struct resource *res;
282 int ret; 283 int ret;
283 284
284 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
285 if (!res)
286 return -EINVAL;
287
288 if (!devm_request_mem_region(&pdev->dev, res->start,
289 resource_size(res), pdev->name)) {
290 dev_warn(&pdev->dev, "Failed to get memory resourse\n");
291 return -ENOENT;
292 }
293
294 host = devm_kzalloc(&pdev->dev, sizeof(*host), GFP_KERNEL); 285 host = devm_kzalloc(&pdev->dev, sizeof(*host), GFP_KERNEL);
295 if (!host) { 286 if (!host) {
296 dev_warn(&pdev->dev, "kzalloc fail\n"); 287 dev_warn(&pdev->dev, "kzalloc fail\n");
297 return -ENOMEM; 288 return -ENOMEM;
298 } 289 }
299 290
300 host->io_base = devm_ioremap(&pdev->dev, res->start, 291 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
301 resource_size(res)); 292 host->io_base = devm_ioremap_resource(&pdev->dev, res);
302 if (!host->io_base) { 293 if (IS_ERR(host->io_base))
303 dev_warn(&pdev->dev, "ioremap failed\n"); 294 return PTR_ERR(host->io_base);
304 return -ENOMEM;
305 }
306 295
307 host->clk = clk_get(&pdev->dev, NULL); 296 host->clk = devm_clk_get(&pdev->dev, NULL);
308 if (IS_ERR(host->clk)) 297 if (IS_ERR(host->clk))
309 return PTR_ERR(host->clk); 298 return PTR_ERR(host->clk);
310 299
@@ -320,22 +309,12 @@ static int spdif_out_probe(struct platform_device *pdev)
320 309
321 ret = snd_soc_register_component(&pdev->dev, &spdif_out_component, 310 ret = snd_soc_register_component(&pdev->dev, &spdif_out_component,
322 &spdif_out_dai, 1); 311 &spdif_out_dai, 1);
323 if (ret != 0) { 312 return ret;
324 clk_put(host->clk);
325 return ret;
326 }
327
328 return 0;
329} 313}
330 314
331static int spdif_out_remove(struct platform_device *pdev) 315static int spdif_out_remove(struct platform_device *pdev)
332{ 316{
333 struct spdif_out_dev *host = dev_get_drvdata(&pdev->dev);
334
335 snd_soc_unregister_component(&pdev->dev); 317 snd_soc_unregister_component(&pdev->dev);
336 dev_set_drvdata(&pdev->dev, NULL);
337
338 clk_put(host->clk);
339 318
340 return 0; 319 return 0;
341} 320}
diff --git a/sound/soc/spear/spear_pcm.c b/sound/soc/spear/spear_pcm.c
index 2fbd4899d8ef..4707f2b862c3 100644
--- a/sound/soc/spear/spear_pcm.c
+++ b/sound/soc/spear/spear_pcm.c
@@ -13,19 +13,13 @@
13 13
14#include <linux/module.h> 14#include <linux/module.h>
15#include <linux/dmaengine.h> 15#include <linux/dmaengine.h>
16#include <linux/dma-mapping.h>
17#include <linux/init.h>
18#include <linux/platform_device.h> 16#include <linux/platform_device.h>
19#include <linux/scatterlist.h>
20#include <linux/slab.h>
21#include <sound/core.h>
22#include <sound/dmaengine_pcm.h> 17#include <sound/dmaengine_pcm.h>
23#include <sound/pcm.h> 18#include <sound/pcm.h>
24#include <sound/pcm_params.h>
25#include <sound/soc.h> 19#include <sound/soc.h>
26#include <sound/spear_dma.h> 20#include <sound/spear_dma.h>
27 21
28static struct snd_pcm_hardware spear_pcm_hardware = { 22static const struct snd_pcm_hardware spear_pcm_hardware = {
29 .info = (SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER | 23 .info = (SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER |
30 SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID | 24 SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID |
31 SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME), 25 SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME),
@@ -37,149 +31,33 @@ static struct snd_pcm_hardware spear_pcm_hardware = {
37 .fifo_size = 0, /* fifo size in bytes */ 31 .fifo_size = 0, /* fifo size in bytes */
38}; 32};
39 33
40static int spear_pcm_hw_params(struct snd_pcm_substream *substream, 34static struct dma_chan *spear_pcm_request_chan(struct snd_soc_pcm_runtime *rtd,
41 struct snd_pcm_hw_params *params) 35 struct snd_pcm_substream *substream)
42{ 36{
43 snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer); 37 struct spear_dma_data *dma_data;
44 38
45 return 0; 39 dma_data = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
46}
47
48static int spear_pcm_hw_free(struct snd_pcm_substream *substream)
49{
50 snd_pcm_set_runtime_buffer(substream, NULL);
51
52 return 0;
53}
54
55static int spear_pcm_open(struct snd_pcm_substream *substream)
56{
57 struct snd_soc_pcm_runtime *rtd = substream->private_data;
58
59 struct spear_dma_data *dma_data = (struct spear_dma_data *)
60 snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
61 int ret;
62
63 ret = snd_soc_set_runtime_hwparams(substream, &spear_pcm_hardware);
64 if (ret)
65 return ret;
66 40
67 return snd_dmaengine_pcm_open_request_chan(substream, dma_data->filter, 41 return snd_dmaengine_pcm_request_channel(dma_data->filter, dma_data);
68 dma_data);
69} 42}
70 43
71static int spear_pcm_mmap(struct snd_pcm_substream *substream, 44static const struct snd_dmaengine_pcm_config spear_dmaengine_pcm_config = {
72 struct vm_area_struct *vma) 45 .pcm_hardware = &spear_pcm_hardware,
73{ 46 .compat_request_channel = spear_pcm_request_chan,
74 struct snd_pcm_runtime *runtime = substream->runtime; 47 .prealloc_buffer_size = 16 * 1024,
75
76 return dma_mmap_writecombine(substream->pcm->card->dev, vma,
77 runtime->dma_area, runtime->dma_addr,
78 runtime->dma_bytes);
79}
80
81static struct snd_pcm_ops spear_pcm_ops = {
82 .open = spear_pcm_open,
83 .close = snd_dmaengine_pcm_close_release_chan,
84 .ioctl = snd_pcm_lib_ioctl,
85 .hw_params = spear_pcm_hw_params,
86 .hw_free = spear_pcm_hw_free,
87 .trigger = snd_dmaengine_pcm_trigger,
88 .pointer = snd_dmaengine_pcm_pointer,
89 .mmap = spear_pcm_mmap,
90};
91
92static int
93spear_pcm_preallocate_dma_buffer(struct snd_pcm *pcm, int stream,
94 size_t size)
95{
96 struct snd_pcm_substream *substream = pcm->streams[stream].substream;
97 struct snd_dma_buffer *buf = &substream->dma_buffer;
98
99 buf->dev.type = SNDRV_DMA_TYPE_DEV;
100 buf->dev.dev = pcm->card->dev;
101 buf->private_data = NULL;
102
103 buf->area = dma_alloc_writecombine(pcm->card->dev, size,
104 &buf->addr, GFP_KERNEL);
105 if (!buf->area)
106 return -ENOMEM;
107
108 dev_info(buf->dev.dev,
109 " preallocate_dma_buffer: area=%p, addr=%p, size=%d\n",
110 (void *)buf->area, (void *)buf->addr, size);
111
112 buf->bytes = size;
113 return 0;
114}
115
116static void spear_pcm_free(struct snd_pcm *pcm)
117{
118 struct snd_pcm_substream *substream;
119 struct snd_dma_buffer *buf;
120 int stream;
121
122 for (stream = 0; stream < 2; stream++) {
123 substream = pcm->streams[stream].substream;
124 if (!substream)
125 continue;
126
127 buf = &substream->dma_buffer;
128 if (!buf || !buf->area)
129 continue;
130
131 dma_free_writecombine(pcm->card->dev, buf->bytes,
132 buf->area, buf->addr);
133 buf->area = NULL;
134 }
135}
136
137static u64 spear_pcm_dmamask = DMA_BIT_MASK(32);
138
139static int spear_pcm_new(struct snd_soc_pcm_runtime *rtd)
140{
141 struct snd_card *card = rtd->card->snd_card;
142 int ret;
143
144 if (!card->dev->dma_mask)
145 card->dev->dma_mask = &spear_pcm_dmamask;
146 if (!card->dev->coherent_dma_mask)
147 card->dev->coherent_dma_mask = DMA_BIT_MASK(32);
148
149 if (rtd->cpu_dai->driver->playback.channels_min) {
150 ret = spear_pcm_preallocate_dma_buffer(rtd->pcm,
151 SNDRV_PCM_STREAM_PLAYBACK,
152 spear_pcm_hardware.buffer_bytes_max);
153 if (ret)
154 return ret;
155 }
156
157 if (rtd->cpu_dai->driver->capture.channels_min) {
158 ret = spear_pcm_preallocate_dma_buffer(rtd->pcm,
159 SNDRV_PCM_STREAM_CAPTURE,
160 spear_pcm_hardware.buffer_bytes_max);
161 if (ret)
162 return ret;
163 }
164
165 return 0;
166}
167
168static struct snd_soc_platform_driver spear_soc_platform = {
169 .ops = &spear_pcm_ops,
170 .pcm_new = spear_pcm_new,
171 .pcm_free = spear_pcm_free,
172}; 48};
173 49
174static int spear_soc_platform_probe(struct platform_device *pdev) 50static int spear_soc_platform_probe(struct platform_device *pdev)
175{ 51{
176 return snd_soc_register_platform(&pdev->dev, &spear_soc_platform); 52 return snd_dmaengine_pcm_register(&pdev->dev,
53 &spear_dmaengine_pcm_config,
54 SND_DMAENGINE_PCM_FLAG_NO_DT |
55 SND_DMAENGINE_PCM_FLAG_COMPAT);
177} 56}
178 57
179static int spear_soc_platform_remove(struct platform_device *pdev) 58static int spear_soc_platform_remove(struct platform_device *pdev)
180{ 59{
181 snd_soc_unregister_platform(&pdev->dev); 60 snd_dmaengine_pcm_unregister(&pdev->dev);
182
183 return 0; 61 return 0;
184} 62}
185 63
diff --git a/sound/soc/tegra/Kconfig b/sound/soc/tegra/Kconfig
index b1c9d573da05..995b120c2cd0 100644
--- a/sound/soc/tegra/Kconfig
+++ b/sound/soc/tegra/Kconfig
@@ -59,6 +59,16 @@ config SND_SOC_TEGRA30_I2S
59 Tegra30 I2S interface. You will also need to select the individual 59 Tegra30 I2S interface. You will also need to select the individual
60 machine drivers to support below. 60 machine drivers to support below.
61 61
62config SND_SOC_TEGRA_RT5640
63 tristate "SoC Audio support for Tegra boards using an RT5640 codec"
64 depends on SND_SOC_TEGRA && I2C
65 select SND_SOC_TEGRA20_I2S if ARCH_TEGRA_2x_SOC
66 select SND_SOC_TEGRA30_I2S if ARCH_TEGRA_3x_SOC
67 select SND_SOC_RT5640
68 help
69 Say Y or M here if you want to add support for SoC audio on Tegra
70 boards using the RT5640 codec, such as Dalmore.
71
62config SND_SOC_TEGRA_WM8753 72config SND_SOC_TEGRA_WM8753
63 tristate "SoC Audio support for Tegra boards using a WM8753 codec" 73 tristate "SoC Audio support for Tegra boards using a WM8753 codec"
64 depends on SND_SOC_TEGRA && I2C 74 depends on SND_SOC_TEGRA && I2C
diff --git a/sound/soc/tegra/Makefile b/sound/soc/tegra/Makefile
index 416a14bde41b..21d2550a08a4 100644
--- a/sound/soc/tegra/Makefile
+++ b/sound/soc/tegra/Makefile
@@ -18,12 +18,14 @@ obj-$(CONFIG_SND_SOC_TEGRA30_AHUB) += snd-soc-tegra30-ahub.o
18obj-$(CONFIG_SND_SOC_TEGRA30_I2S) += snd-soc-tegra30-i2s.o 18obj-$(CONFIG_SND_SOC_TEGRA30_I2S) += snd-soc-tegra30-i2s.o
19 19
20# Tegra machine Support 20# Tegra machine Support
21snd-soc-tegra-rt5640-objs := tegra_rt5640.o
21snd-soc-tegra-wm8753-objs := tegra_wm8753.o 22snd-soc-tegra-wm8753-objs := tegra_wm8753.o
22snd-soc-tegra-wm8903-objs := tegra_wm8903.o 23snd-soc-tegra-wm8903-objs := tegra_wm8903.o
23snd-soc-tegra-wm9712-objs := tegra_wm9712.o 24snd-soc-tegra-wm9712-objs := tegra_wm9712.o
24snd-soc-tegra-trimslice-objs := trimslice.o 25snd-soc-tegra-trimslice-objs := trimslice.o
25snd-soc-tegra-alc5632-objs := tegra_alc5632.o 26snd-soc-tegra-alc5632-objs := tegra_alc5632.o
26 27
28obj-$(CONFIG_SND_SOC_TEGRA_RT5640) += snd-soc-tegra-rt5640.o
27obj-$(CONFIG_SND_SOC_TEGRA_WM8753) += snd-soc-tegra-wm8753.o 29obj-$(CONFIG_SND_SOC_TEGRA_WM8753) += snd-soc-tegra-wm8753.o
28obj-$(CONFIG_SND_SOC_TEGRA_WM8903) += snd-soc-tegra-wm8903.o 30obj-$(CONFIG_SND_SOC_TEGRA_WM8903) += snd-soc-tegra-wm8903.o
29obj-$(CONFIG_SND_SOC_TEGRA_WM9712) += snd-soc-tegra-wm9712.o 31obj-$(CONFIG_SND_SOC_TEGRA_WM9712) += snd-soc-tegra-wm9712.o
diff --git a/sound/soc/tegra/tegra20_ac97.c b/sound/soc/tegra/tegra20_ac97.c
index 2f70ea7f6618..e58233f7df61 100644
--- a/sound/soc/tegra/tegra20_ac97.c
+++ b/sound/soc/tegra/tegra20_ac97.c
@@ -142,13 +142,12 @@ static void tegra20_ac97_codec_write(struct snd_ac97 *ac97_snd,
142 } while (!time_after(jiffies, timeout)); 142 } while (!time_after(jiffies, timeout));
143} 143}
144 144
145struct snd_ac97_bus_ops soc_ac97_ops = { 145static struct snd_ac97_bus_ops tegra20_ac97_ops = {
146 .read = tegra20_ac97_codec_read, 146 .read = tegra20_ac97_codec_read,
147 .write = tegra20_ac97_codec_write, 147 .write = tegra20_ac97_codec_write,
148 .reset = tegra20_ac97_codec_reset, 148 .reset = tegra20_ac97_codec_reset,
149 .warm_reset = tegra20_ac97_codec_warm_reset, 149 .warm_reset = tegra20_ac97_codec_warm_reset,
150}; 150};
151EXPORT_SYMBOL_GPL(soc_ac97_ops);
152 151
153static inline void tegra20_ac97_start_playback(struct tegra20_ac97 *ac97) 152static inline void tegra20_ac97_start_playback(struct tegra20_ac97 *ac97)
154{ 153{
@@ -313,7 +312,7 @@ static const struct regmap_config tegra20_ac97_regmap_config = {
313static int tegra20_ac97_platform_probe(struct platform_device *pdev) 312static int tegra20_ac97_platform_probe(struct platform_device *pdev)
314{ 313{
315 struct tegra20_ac97 *ac97; 314 struct tegra20_ac97 *ac97;
316 struct resource *mem, *memregion; 315 struct resource *mem;
317 u32 of_dma[2]; 316 u32 of_dma[2];
318 void __iomem *regs; 317 void __iomem *regs;
319 int ret = 0; 318 int ret = 0;
@@ -327,7 +326,7 @@ static int tegra20_ac97_platform_probe(struct platform_device *pdev)
327 } 326 }
328 dev_set_drvdata(&pdev->dev, ac97); 327 dev_set_drvdata(&pdev->dev, ac97);
329 328
330 ac97->clk_ac97 = clk_get(&pdev->dev, NULL); 329 ac97->clk_ac97 = devm_clk_get(&pdev->dev, NULL);
331 if (IS_ERR(ac97->clk_ac97)) { 330 if (IS_ERR(ac97->clk_ac97)) {
332 dev_err(&pdev->dev, "Can't retrieve ac97 clock\n"); 331 dev_err(&pdev->dev, "Can't retrieve ac97 clock\n");
333 ret = PTR_ERR(ac97->clk_ac97); 332 ret = PTR_ERR(ac97->clk_ac97);
@@ -341,18 +340,9 @@ static int tegra20_ac97_platform_probe(struct platform_device *pdev)
341 goto err_clk_put; 340 goto err_clk_put;
342 } 341 }
343 342
344 memregion = devm_request_mem_region(&pdev->dev, mem->start, 343 regs = devm_ioremap_resource(&pdev->dev, mem);
345 resource_size(mem), DRV_NAME); 344 if (IS_ERR(regs)) {
346 if (!memregion) { 345 ret = PTR_ERR(regs);
347 dev_err(&pdev->dev, "Memory region already claimed\n");
348 ret = -EBUSY;
349 goto err_clk_put;
350 }
351
352 regs = devm_ioremap(&pdev->dev, mem->start, resource_size(mem));
353 if (!regs) {
354 dev_err(&pdev->dev, "ioremap failed\n");
355 ret = -ENOMEM;
356 goto err_clk_put; 346 goto err_clk_put;
357 } 347 }
358 348
@@ -403,23 +393,9 @@ static int tegra20_ac97_platform_probe(struct platform_device *pdev)
403 ac97->capture_dma_data.maxburst = 4; 393 ac97->capture_dma_data.maxburst = 4;
404 ac97->capture_dma_data.slave_id = of_dma[0]; 394 ac97->capture_dma_data.slave_id = of_dma[0];
405 395
406 ret = snd_soc_register_component(&pdev->dev, &tegra20_ac97_component,
407 &tegra20_ac97_dai, 1);
408 if (ret) {
409 dev_err(&pdev->dev, "Could not register DAI: %d\n", ret);
410 ret = -ENOMEM;
411 goto err_clk_put;
412 }
413
414 ret = tegra_pcm_platform_register(&pdev->dev);
415 if (ret) {
416 dev_err(&pdev->dev, "Could not register PCM: %d\n", ret);
417 goto err_unregister_component;
418 }
419
420 ret = tegra_asoc_utils_init(&ac97->util_data, &pdev->dev); 396 ret = tegra_asoc_utils_init(&ac97->util_data, &pdev->dev);
421 if (ret) 397 if (ret)
422 goto err_unregister_pcm; 398 goto err_clk_put;
423 399
424 ret = tegra_asoc_utils_set_ac97_rate(&ac97->util_data); 400 ret = tegra_asoc_utils_set_ac97_rate(&ac97->util_data);
425 if (ret) 401 if (ret)
@@ -431,20 +407,40 @@ static int tegra20_ac97_platform_probe(struct platform_device *pdev)
431 goto err_asoc_utils_fini; 407 goto err_asoc_utils_fini;
432 } 408 }
433 409
410 ret = snd_soc_set_ac97_ops(&tegra20_ac97_ops);
411 if (ret) {
412 dev_err(&pdev->dev, "Failed to set AC'97 ops: %d\n", ret);
413 goto err_asoc_utils_fini;
414 }
415
416 ret = snd_soc_register_component(&pdev->dev, &tegra20_ac97_component,
417 &tegra20_ac97_dai, 1);
418 if (ret) {
419 dev_err(&pdev->dev, "Could not register DAI: %d\n", ret);
420 ret = -ENOMEM;
421 goto err_asoc_utils_fini;
422 }
423
424 ret = tegra_pcm_platform_register(&pdev->dev);
425 if (ret) {
426 dev_err(&pdev->dev, "Could not register PCM: %d\n", ret);
427 goto err_unregister_component;
428 }
429
434 /* XXX: crufty ASoC AC97 API - only one AC97 codec allowed */ 430 /* XXX: crufty ASoC AC97 API - only one AC97 codec allowed */
435 workdata = ac97; 431 workdata = ac97;
436 432
437 return 0; 433 return 0;
438 434
439err_asoc_utils_fini:
440 tegra_asoc_utils_fini(&ac97->util_data);
441err_unregister_pcm: 435err_unregister_pcm:
442 tegra_pcm_platform_unregister(&pdev->dev); 436 tegra_pcm_platform_unregister(&pdev->dev);
443err_unregister_component: 437err_unregister_component:
444 snd_soc_unregister_component(&pdev->dev); 438 snd_soc_unregister_component(&pdev->dev);
439err_asoc_utils_fini:
440 tegra_asoc_utils_fini(&ac97->util_data);
445err_clk_put: 441err_clk_put:
446 clk_put(ac97->clk_ac97);
447err: 442err:
443 snd_soc_set_ac97_ops(NULL);
448 return ret; 444 return ret;
449} 445}
450 446
@@ -458,7 +454,8 @@ static int tegra20_ac97_platform_remove(struct platform_device *pdev)
458 tegra_asoc_utils_fini(&ac97->util_data); 454 tegra_asoc_utils_fini(&ac97->util_data);
459 455
460 clk_disable_unprepare(ac97->clk_ac97); 456 clk_disable_unprepare(ac97->clk_ac97);
461 clk_put(ac97->clk_ac97); 457
458 snd_soc_set_ac97_ops(NULL);
462 459
463 return 0; 460 return 0;
464} 461}
diff --git a/sound/soc/tegra/tegra30_ahub.c b/sound/soc/tegra/tegra30_ahub.c
index 23e592f453fa..d554d46d08b5 100644
--- a/sound/soc/tegra/tegra30_ahub.c
+++ b/sound/soc/tegra/tegra30_ahub.c
@@ -627,9 +627,34 @@ static int tegra30_ahub_remove(struct platform_device *pdev)
627 return 0; 627 return 0;
628} 628}
629 629
630#ifdef CONFIG_PM_SLEEP
631static int tegra30_ahub_suspend(struct device *dev)
632{
633 regcache_mark_dirty(ahub->regmap_ahub);
634 regcache_mark_dirty(ahub->regmap_apbif);
635
636 return 0;
637}
638
639static int tegra30_ahub_resume(struct device *dev)
640{
641 int ret;
642
643 ret = pm_runtime_get_sync(dev);
644 if (ret < 0)
645 return ret;
646 ret = regcache_sync(ahub->regmap_ahub);
647 ret |= regcache_sync(ahub->regmap_apbif);
648 pm_runtime_put(dev);
649
650 return ret;
651}
652#endif
653
630static const struct dev_pm_ops tegra30_ahub_pm_ops = { 654static const struct dev_pm_ops tegra30_ahub_pm_ops = {
631 SET_RUNTIME_PM_OPS(tegra30_ahub_runtime_suspend, 655 SET_RUNTIME_PM_OPS(tegra30_ahub_runtime_suspend,
632 tegra30_ahub_runtime_resume, NULL) 656 tegra30_ahub_runtime_resume, NULL)
657 SET_SYSTEM_SLEEP_PM_OPS(tegra30_ahub_suspend, tegra30_ahub_resume)
633}; 658};
634 659
635static struct platform_driver tegra30_ahub_driver = { 660static struct platform_driver tegra30_ahub_driver = {
diff --git a/sound/soc/tegra/tegra30_i2s.c b/sound/soc/tegra/tegra30_i2s.c
index 31d092d83c71..d04146cad61f 100644
--- a/sound/soc/tegra/tegra30_i2s.c
+++ b/sound/soc/tegra/tegra30_i2s.c
@@ -514,6 +514,31 @@ static int tegra30_i2s_platform_remove(struct platform_device *pdev)
514 return 0; 514 return 0;
515} 515}
516 516
517#ifdef CONFIG_PM_SLEEP
518static int tegra30_i2s_suspend(struct device *dev)
519{
520 struct tegra30_i2s *i2s = dev_get_drvdata(dev);
521
522 regcache_mark_dirty(i2s->regmap);
523
524 return 0;
525}
526
527static int tegra30_i2s_resume(struct device *dev)
528{
529 struct tegra30_i2s *i2s = dev_get_drvdata(dev);
530 int ret;
531
532 ret = pm_runtime_get_sync(dev);
533 if (ret < 0)
534 return ret;
535 ret = regcache_sync(i2s->regmap);
536 pm_runtime_put(dev);
537
538 return ret;
539}
540#endif
541
517static const struct of_device_id tegra30_i2s_of_match[] = { 542static const struct of_device_id tegra30_i2s_of_match[] = {
518 { .compatible = "nvidia,tegra30-i2s", }, 543 { .compatible = "nvidia,tegra30-i2s", },
519 {}, 544 {},
@@ -522,6 +547,7 @@ static const struct of_device_id tegra30_i2s_of_match[] = {
522static const struct dev_pm_ops tegra30_i2s_pm_ops = { 547static const struct dev_pm_ops tegra30_i2s_pm_ops = {
523 SET_RUNTIME_PM_OPS(tegra30_i2s_runtime_suspend, 548 SET_RUNTIME_PM_OPS(tegra30_i2s_runtime_suspend,
524 tegra30_i2s_runtime_resume, NULL) 549 tegra30_i2s_runtime_resume, NULL)
550 SET_SYSTEM_SLEEP_PM_OPS(tegra30_i2s_suspend, tegra30_i2s_resume)
525}; 551};
526 552
527static struct platform_driver tegra30_i2s_driver = { 553static struct platform_driver tegra30_i2s_driver = {
diff --git a/sound/soc/tegra/tegra_asoc_utils.c b/sound/soc/tegra/tegra_asoc_utils.c
index 24fb001be7f4..d173880f290d 100644
--- a/sound/soc/tegra/tegra_asoc_utils.c
+++ b/sound/soc/tegra/tegra_asoc_utils.c
@@ -173,7 +173,6 @@ int tegra_asoc_utils_init(struct tegra_asoc_utils_data *data,
173 struct device *dev) 173 struct device *dev)
174{ 174{
175 int ret; 175 int ret;
176 bool new_clocks = false;
177 176
178 data->dev = dev; 177 data->dev = dev;
179 178
@@ -181,40 +180,28 @@ int tegra_asoc_utils_init(struct tegra_asoc_utils_data *data,
181 data->soc = TEGRA_ASOC_UTILS_SOC_TEGRA20; 180 data->soc = TEGRA_ASOC_UTILS_SOC_TEGRA20;
182 else if (of_machine_is_compatible("nvidia,tegra30")) 181 else if (of_machine_is_compatible("nvidia,tegra30"))
183 data->soc = TEGRA_ASOC_UTILS_SOC_TEGRA30; 182 data->soc = TEGRA_ASOC_UTILS_SOC_TEGRA30;
184 else if (of_machine_is_compatible("nvidia,tegra114")) { 183 else if (of_machine_is_compatible("nvidia,tegra114"))
185 data->soc = TEGRA_ASOC_UTILS_SOC_TEGRA114; 184 data->soc = TEGRA_ASOC_UTILS_SOC_TEGRA114;
186 new_clocks = true; 185 else {
187 } else {
188 dev_err(data->dev, "SoC unknown to Tegra ASoC utils\n"); 186 dev_err(data->dev, "SoC unknown to Tegra ASoC utils\n");
189 return -EINVAL; 187 return -EINVAL;
190 } 188 }
191 189
192 if (new_clocks) 190 data->clk_pll_a = clk_get(dev, "pll_a");
193 data->clk_pll_a = clk_get(dev, "pll_a");
194 else
195 data->clk_pll_a = clk_get_sys(NULL, "pll_a");
196 if (IS_ERR(data->clk_pll_a)) { 191 if (IS_ERR(data->clk_pll_a)) {
197 dev_err(data->dev, "Can't retrieve clk pll_a\n"); 192 dev_err(data->dev, "Can't retrieve clk pll_a\n");
198 ret = PTR_ERR(data->clk_pll_a); 193 ret = PTR_ERR(data->clk_pll_a);
199 goto err; 194 goto err;
200 } 195 }
201 196
202 if (new_clocks) 197 data->clk_pll_a_out0 = clk_get(dev, "pll_a_out0");
203 data->clk_pll_a_out0 = clk_get(dev, "pll_a_out0");
204 else
205 data->clk_pll_a_out0 = clk_get_sys(NULL, "pll_a_out0");
206 if (IS_ERR(data->clk_pll_a_out0)) { 198 if (IS_ERR(data->clk_pll_a_out0)) {
207 dev_err(data->dev, "Can't retrieve clk pll_a_out0\n"); 199 dev_err(data->dev, "Can't retrieve clk pll_a_out0\n");
208 ret = PTR_ERR(data->clk_pll_a_out0); 200 ret = PTR_ERR(data->clk_pll_a_out0);
209 goto err_put_pll_a; 201 goto err_put_pll_a;
210 } 202 }
211 203
212 if (new_clocks) 204 data->clk_cdev1 = clk_get(dev, "mclk");
213 data->clk_cdev1 = clk_get(dev, "mclk");
214 else if (data->soc == TEGRA_ASOC_UTILS_SOC_TEGRA20)
215 data->clk_cdev1 = clk_get_sys(NULL, "cdev1");
216 else
217 data->clk_cdev1 = clk_get_sys("extern1", NULL);
218 if (IS_ERR(data->clk_cdev1)) { 205 if (IS_ERR(data->clk_cdev1)) {
219 dev_err(data->dev, "Can't retrieve clk cdev1\n"); 206 dev_err(data->dev, "Can't retrieve clk cdev1\n");
220 ret = PTR_ERR(data->clk_cdev1); 207 ret = PTR_ERR(data->clk_cdev1);
diff --git a/sound/soc/tegra/tegra_rt5640.c b/sound/soc/tegra/tegra_rt5640.c
new file mode 100644
index 000000000000..08794f915a94
--- /dev/null
+++ b/sound/soc/tegra/tegra_rt5640.c
@@ -0,0 +1,257 @@
1/*
2* tegra_rt5640.c - Tegra machine ASoC driver for boards using WM8903 codec.
3 *
4 * Copyright (c) 2013, NVIDIA CORPORATION. All rights reserved.
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms and conditions of the GNU General Public License,
8 * version 2, as published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
13 * more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 *
18 * Based on code copyright/by:
19 *
20 * Copyright (C) 2010-2012 - NVIDIA, Inc.
21 * Copyright (C) 2011 The AC100 Kernel Team <ac100@lists.lauchpad.net>
22 * (c) 2009, 2010 Nvidia Graphics Pvt. Ltd.
23 * Copyright 2007 Wolfson Microelectronics PLC.
24 */
25
26#include <linux/module.h>
27#include <linux/platform_device.h>
28#include <linux/slab.h>
29#include <linux/gpio.h>
30#include <linux/of_gpio.h>
31
32#include <sound/core.h>
33#include <sound/jack.h>
34#include <sound/pcm.h>
35#include <sound/pcm_params.h>
36#include <sound/soc.h>
37
38#include "../codecs/rt5640.h"
39
40#include "tegra_asoc_utils.h"
41
42#define DRV_NAME "tegra-snd-rt5640"
43
44struct tegra_rt5640 {
45 struct tegra_asoc_utils_data util_data;
46 int gpio_hp_det;
47};
48
49static int tegra_rt5640_asoc_hw_params(struct snd_pcm_substream *substream,
50 struct snd_pcm_hw_params *params)
51{
52 struct snd_soc_pcm_runtime *rtd = substream->private_data;
53 struct snd_soc_dai *codec_dai = rtd->codec_dai;
54 struct snd_soc_codec *codec = codec_dai->codec;
55 struct snd_soc_card *card = codec->card;
56 struct tegra_rt5640 *machine = snd_soc_card_get_drvdata(card);
57 int srate, mclk;
58 int err;
59
60 srate = params_rate(params);
61 mclk = 256 * srate;
62
63 err = tegra_asoc_utils_set_rate(&machine->util_data, srate, mclk);
64 if (err < 0) {
65 dev_err(card->dev, "Can't configure clocks\n");
66 return err;
67 }
68
69 err = snd_soc_dai_set_sysclk(codec_dai, RT5640_SCLK_S_MCLK, mclk,
70 SND_SOC_CLOCK_IN);
71 if (err < 0) {
72 dev_err(card->dev, "codec_dai clock not set\n");
73 return err;
74 }
75
76 return 0;
77}
78
79static struct snd_soc_ops tegra_rt5640_ops = {
80 .hw_params = tegra_rt5640_asoc_hw_params,
81};
82
83static struct snd_soc_jack tegra_rt5640_hp_jack;
84
85static struct snd_soc_jack_pin tegra_rt5640_hp_jack_pins[] = {
86 {
87 .pin = "Headphones",
88 .mask = SND_JACK_HEADPHONE,
89 },
90};
91
92static struct snd_soc_jack_gpio tegra_rt5640_hp_jack_gpio = {
93 .name = "Headphone detection",
94 .report = SND_JACK_HEADPHONE,
95 .debounce_time = 150,
96 .invert = 1,
97};
98
99static const struct snd_soc_dapm_widget tegra_rt5640_dapm_widgets[] = {
100 SND_SOC_DAPM_HP("Headphones", NULL),
101 SND_SOC_DAPM_SPK("Speakers", NULL),
102};
103
104static const struct snd_kcontrol_new tegra_rt5640_controls[] = {
105 SOC_DAPM_PIN_SWITCH("Speakers"),
106};
107
108static int tegra_rt5640_asoc_init(struct snd_soc_pcm_runtime *rtd)
109{
110 struct snd_soc_dai *codec_dai = rtd->codec_dai;
111 struct snd_soc_codec *codec = codec_dai->codec;
112 struct tegra_rt5640 *machine = snd_soc_card_get_drvdata(codec->card);
113
114 snd_soc_jack_new(codec, "Headphones", SND_JACK_HEADPHONE,
115 &tegra_rt5640_hp_jack);
116 snd_soc_jack_add_pins(&tegra_rt5640_hp_jack,
117 ARRAY_SIZE(tegra_rt5640_hp_jack_pins),
118 tegra_rt5640_hp_jack_pins);
119
120 if (gpio_is_valid(machine->gpio_hp_det)) {
121 tegra_rt5640_hp_jack_gpio.gpio = machine->gpio_hp_det;
122 snd_soc_jack_add_gpios(&tegra_rt5640_hp_jack,
123 1,
124 &tegra_rt5640_hp_jack_gpio);
125 }
126
127 return 0;
128}
129
130static struct snd_soc_dai_link tegra_rt5640_dai = {
131 .name = "RT5640",
132 .stream_name = "RT5640 PCM",
133 .codec_dai_name = "rt5640-aif1",
134 .init = tegra_rt5640_asoc_init,
135 .ops = &tegra_rt5640_ops,
136 .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
137 SND_SOC_DAIFMT_CBS_CFS,
138};
139
140static struct snd_soc_card snd_soc_tegra_rt5640 = {
141 .name = "tegra-rt5640",
142 .owner = THIS_MODULE,
143 .dai_link = &tegra_rt5640_dai,
144 .num_links = 1,
145 .controls = tegra_rt5640_controls,
146 .num_controls = ARRAY_SIZE(tegra_rt5640_controls),
147 .dapm_widgets = tegra_rt5640_dapm_widgets,
148 .num_dapm_widgets = ARRAY_SIZE(tegra_rt5640_dapm_widgets),
149 .fully_routed = true,
150};
151
152static int tegra_rt5640_probe(struct platform_device *pdev)
153{
154 struct device_node *np = pdev->dev.of_node;
155 struct snd_soc_card *card = &snd_soc_tegra_rt5640;
156 struct tegra_rt5640 *machine;
157 int ret;
158
159 machine = devm_kzalloc(&pdev->dev,
160 sizeof(struct tegra_rt5640), GFP_KERNEL);
161 if (!machine) {
162 dev_err(&pdev->dev, "Can't allocate tegra_rt5640\n");
163 return -ENOMEM;
164 }
165
166 card->dev = &pdev->dev;
167 platform_set_drvdata(pdev, card);
168 snd_soc_card_set_drvdata(card, machine);
169
170 machine->gpio_hp_det = of_get_named_gpio(np, "nvidia,hp-det-gpios", 0);
171 if (machine->gpio_hp_det == -EPROBE_DEFER)
172 return -EPROBE_DEFER;
173
174 ret = snd_soc_of_parse_card_name(card, "nvidia,model");
175 if (ret)
176 goto err;
177
178 ret = snd_soc_of_parse_audio_routing(card, "nvidia,audio-routing");
179 if (ret)
180 goto err;
181
182 tegra_rt5640_dai.codec_of_node = of_parse_phandle(np,
183 "nvidia,audio-codec", 0);
184 if (!tegra_rt5640_dai.codec_of_node) {
185 dev_err(&pdev->dev,
186 "Property 'nvidia,audio-codec' missing or invalid\n");
187 ret = -EINVAL;
188 goto err;
189 }
190
191 tegra_rt5640_dai.cpu_of_node = of_parse_phandle(np,
192 "nvidia,i2s-controller", 0);
193 if (!tegra_rt5640_dai.cpu_of_node) {
194 dev_err(&pdev->dev,
195 "Property 'nvidia,i2s-controller' missing or invalid\n");
196 ret = -EINVAL;
197 goto err;
198 }
199
200 tegra_rt5640_dai.platform_of_node = tegra_rt5640_dai.cpu_of_node;
201
202 ret = tegra_asoc_utils_init(&machine->util_data, &pdev->dev);
203 if (ret)
204 goto err;
205
206 ret = snd_soc_register_card(card);
207 if (ret) {
208 dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n",
209 ret);
210 goto err_fini_utils;
211 }
212
213 return 0;
214
215err_fini_utils:
216 tegra_asoc_utils_fini(&machine->util_data);
217err:
218 return ret;
219}
220
221static int tegra_rt5640_remove(struct platform_device *pdev)
222{
223 struct snd_soc_card *card = platform_get_drvdata(pdev);
224 struct tegra_rt5640 *machine = snd_soc_card_get_drvdata(card);
225
226 snd_soc_jack_free_gpios(&tegra_rt5640_hp_jack, 1,
227 &tegra_rt5640_hp_jack_gpio);
228
229 snd_soc_unregister_card(card);
230
231 tegra_asoc_utils_fini(&machine->util_data);
232
233 return 0;
234}
235
236static const struct of_device_id tegra_rt5640_of_match[] = {
237 { .compatible = "nvidia,tegra-audio-rt5640", },
238 {},
239};
240
241static struct platform_driver tegra_rt5640_driver = {
242 .driver = {
243 .name = DRV_NAME,
244 .owner = THIS_MODULE,
245 .pm = &snd_soc_pm_ops,
246 .of_match_table = tegra_rt5640_of_match,
247 },
248 .probe = tegra_rt5640_probe,
249 .remove = tegra_rt5640_remove,
250};
251module_platform_driver(tegra_rt5640_driver);
252
253MODULE_AUTHOR("Stephen Warren <swarren@nvidia.com>");
254MODULE_DESCRIPTION("Tegra+RT5640 machine ASoC driver");
255MODULE_LICENSE("GPL v2");
256MODULE_ALIAS("platform:" DRV_NAME);
257MODULE_DEVICE_TABLE(of, tegra_rt5640_of_match);
diff --git a/sound/soc/txx9/txx9aclc-ac97.c b/sound/soc/txx9/txx9aclc-ac97.c
index 8a2840304d28..4bcce8a3cded 100644
--- a/sound/soc/txx9/txx9aclc-ac97.c
+++ b/sound/soc/txx9/txx9aclc-ac97.c
@@ -119,12 +119,11 @@ static void txx9aclc_ac97_cold_reset(struct snd_ac97 *ac97)
119} 119}
120 120
121/* AC97 controller operations */ 121/* AC97 controller operations */
122struct snd_ac97_bus_ops soc_ac97_ops = { 122static struct snd_ac97_bus_ops txx9aclc_ac97_ops = {
123 .read = txx9aclc_ac97_read, 123 .read = txx9aclc_ac97_read,
124 .write = txx9aclc_ac97_write, 124 .write = txx9aclc_ac97_write,
125 .reset = txx9aclc_ac97_cold_reset, 125 .reset = txx9aclc_ac97_cold_reset,
126}; 126};
127EXPORT_SYMBOL_GPL(soc_ac97_ops);
128 127
129static irqreturn_t txx9aclc_ac97_irq(int irq, void *dev_id) 128static irqreturn_t txx9aclc_ac97_irq(int irq, void *dev_id)
130{ 129{
@@ -188,9 +187,9 @@ static int txx9aclc_ac97_dev_probe(struct platform_device *pdev)
188 if (!r) 187 if (!r)
189 return -EBUSY; 188 return -EBUSY;
190 189
191 if (!devm_request_mem_region(&pdev->dev, r->start, resource_size(r), 190 drvdata->base = devm_ioremap_resource(&pdev->dev, r);
192 dev_name(&pdev->dev))) 191 if (IS_ERR(drvdata->base))
193 return -EBUSY; 192 return PTR_ERR(drvdata->base);
194 193
195 drvdata = devm_kzalloc(&pdev->dev, sizeof(*drvdata), GFP_KERNEL); 194 drvdata = devm_kzalloc(&pdev->dev, sizeof(*drvdata), GFP_KERNEL);
196 if (!drvdata) 195 if (!drvdata)
@@ -201,14 +200,15 @@ static int txx9aclc_ac97_dev_probe(struct platform_device *pdev)
201 r->start >= TXX9_DIRECTMAP_BASE && 200 r->start >= TXX9_DIRECTMAP_BASE &&
202 r->start < TXX9_DIRECTMAP_BASE + 0x400000) 201 r->start < TXX9_DIRECTMAP_BASE + 0x400000)
203 drvdata->physbase |= 0xf00000000ull; 202 drvdata->physbase |= 0xf00000000ull;
204 drvdata->base = devm_ioremap(&pdev->dev, r->start, resource_size(r));
205 if (!drvdata->base)
206 return -EBUSY;
207 err = devm_request_irq(&pdev->dev, irq, txx9aclc_ac97_irq, 203 err = devm_request_irq(&pdev->dev, irq, txx9aclc_ac97_irq,
208 0, dev_name(&pdev->dev), drvdata); 204 0, dev_name(&pdev->dev), drvdata);
209 if (err < 0) 205 if (err < 0)
210 return err; 206 return err;
211 207
208 err = snd_soc_set_ac97_ops(&txx9aclc_ac97_ops);
209 if (err < 0)
210 return err;
211
212 return snd_soc_register_component(&pdev->dev, &txx9aclc_ac97_component, 212 return snd_soc_register_component(&pdev->dev, &txx9aclc_ac97_component,
213 &txx9aclc_ac97_dai, 1); 213 &txx9aclc_ac97_dai, 1);
214} 214}
@@ -216,6 +216,7 @@ static int txx9aclc_ac97_dev_probe(struct platform_device *pdev)
216static int txx9aclc_ac97_dev_remove(struct platform_device *pdev) 216static int txx9aclc_ac97_dev_remove(struct platform_device *pdev)
217{ 217{
218 snd_soc_unregister_component(&pdev->dev); 218 snd_soc_unregister_component(&pdev->dev);
219 snd_soc_set_ac97_ops(NULL);
219 return 0; 220 return 0;
220} 221}
221 222
diff --git a/sound/soc/ux500/mop500.c b/sound/soc/ux500/mop500.c
index 204b899c2311..8f5cd00a6e46 100644
--- a/sound/soc/ux500/mop500.c
+++ b/sound/soc/ux500/mop500.c
@@ -27,7 +27,7 @@
27#include "mop500_ab8500.h" 27#include "mop500_ab8500.h"
28 28
29/* Define the whole MOP500 soundcard, linking platform to the codec-drivers */ 29/* Define the whole MOP500 soundcard, linking platform to the codec-drivers */
30struct snd_soc_dai_link mop500_dai_links[] = { 30static struct snd_soc_dai_link mop500_dai_links[] = {
31 { 31 {
32 .name = "ab8500_0", 32 .name = "ab8500_0",
33 .stream_name = "ab8500_0", 33 .stream_name = "ab8500_0",
diff --git a/sound/soc/ux500/mop500_ab8500.c b/sound/soc/ux500/mop500_ab8500.c
index 892ad9a05c9f..7e923ecf8901 100644
--- a/sound/soc/ux500/mop500_ab8500.c
+++ b/sound/soc/ux500/mop500_ab8500.c
@@ -16,6 +16,7 @@
16#include <linux/device.h> 16#include <linux/device.h>
17#include <linux/io.h> 17#include <linux/io.h>
18#include <linux/clk.h> 18#include <linux/clk.h>
19#include <linux/mutex.h>
19 20
20#include <sound/soc.h> 21#include <sound/soc.h>
21#include <sound/soc-dapm.h> 22#include <sound/soc-dapm.h>
@@ -24,6 +25,7 @@
24 25
25#include "ux500_pcm.h" 26#include "ux500_pcm.h"
26#include "ux500_msp_dai.h" 27#include "ux500_msp_dai.h"
28#include "mop500_ab8500.h"
27#include "../codecs/ab8500-codec.h" 29#include "../codecs/ab8500-codec.h"
28 30
29#define TX_SLOT_MONO 0x0008 31#define TX_SLOT_MONO 0x0008
@@ -43,6 +45,12 @@
43static unsigned int tx_slots = DEF_TX_SLOTS; 45static unsigned int tx_slots = DEF_TX_SLOTS;
44static unsigned int rx_slots = DEF_RX_SLOTS; 46static unsigned int rx_slots = DEF_RX_SLOTS;
45 47
48/* Configuration consistency parameters */
49static DEFINE_MUTEX(mop500_ab8500_params_lock);
50static unsigned long mop500_ab8500_usage;
51static int mop500_ab8500_rate;
52static int mop500_ab8500_channels;
53
46/* Clocks */ 54/* Clocks */
47static const char * const enum_mclk[] = { 55static const char * const enum_mclk[] = {
48 "SYSCLK", 56 "SYSCLK",
@@ -125,9 +133,9 @@ static int mop500_ab8500_set_mclk(struct device *dev,
125static int mclk_input_control_get(struct snd_kcontrol *kcontrol, 133static int mclk_input_control_get(struct snd_kcontrol *kcontrol,
126 struct snd_ctl_elem_value *ucontrol) 134 struct snd_ctl_elem_value *ucontrol)
127{ 135{
128 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); 136 struct snd_soc_card *card = snd_kcontrol_chip(kcontrol);
129 struct mop500_ab8500_drvdata *drvdata = 137 struct mop500_ab8500_drvdata *drvdata =
130 snd_soc_card_get_drvdata(codec->card); 138 snd_soc_card_get_drvdata(card);
131 139
132 ucontrol->value.enumerated.item[0] = drvdata->mclk_sel; 140 ucontrol->value.enumerated.item[0] = drvdata->mclk_sel;
133 141
@@ -137,9 +145,9 @@ static int mclk_input_control_get(struct snd_kcontrol *kcontrol,
137static int mclk_input_control_put(struct snd_kcontrol *kcontrol, 145static int mclk_input_control_put(struct snd_kcontrol *kcontrol,
138 struct snd_ctl_elem_value *ucontrol) 146 struct snd_ctl_elem_value *ucontrol)
139{ 147{
140 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); 148 struct snd_soc_card *card = snd_kcontrol_chip(kcontrol);
141 struct mop500_ab8500_drvdata *drvdata = 149 struct mop500_ab8500_drvdata *drvdata =
142 snd_soc_card_get_drvdata(codec->card); 150 snd_soc_card_get_drvdata(card);
143 unsigned int val = ucontrol->value.enumerated.item[0]; 151 unsigned int val = ucontrol->value.enumerated.item[0];
144 152
145 if (val > (unsigned int)MCLK_ULPCLK) 153 if (val > (unsigned int)MCLK_ULPCLK)
@@ -160,16 +168,6 @@ static struct snd_kcontrol_new mop500_ab8500_ctrls[] = {
160 SOC_ENUM_EXT("Master Clock Select", 168 SOC_ENUM_EXT("Master Clock Select",
161 soc_enum_mclk, 169 soc_enum_mclk,
162 mclk_input_control_get, mclk_input_control_put), 170 mclk_input_control_get, mclk_input_control_put),
163 /* Digital interface - Clocks */
164 SOC_SINGLE("Digital Interface Master Generator Switch",
165 AB8500_DIGIFCONF1, AB8500_DIGIFCONF1_ENMASTGEN,
166 1, 0),
167 SOC_SINGLE("Digital Interface 0 Bit-clock Switch",
168 AB8500_DIGIFCONF1, AB8500_DIGIFCONF1_ENFSBITCLK0,
169 1, 0),
170 SOC_SINGLE("Digital Interface 1 Bit-clock Switch",
171 AB8500_DIGIFCONF1, AB8500_DIGIFCONF1_ENFSBITCLK1,
172 1, 0),
173 SOC_DAPM_PIN_SWITCH("Headset Left"), 171 SOC_DAPM_PIN_SWITCH("Headset Left"),
174 SOC_DAPM_PIN_SWITCH("Headset Right"), 172 SOC_DAPM_PIN_SWITCH("Headset Right"),
175 SOC_DAPM_PIN_SWITCH("Earpiece"), 173 SOC_DAPM_PIN_SWITCH("Earpiece"),
@@ -193,7 +191,7 @@ static struct snd_kcontrol_new mop500_ab8500_ctrls[] = {
193 191
194/* ASoC */ 192/* ASoC */
195 193
196int mop500_ab8500_startup(struct snd_pcm_substream *substream) 194static int mop500_ab8500_startup(struct snd_pcm_substream *substream)
197{ 195{
198 struct snd_soc_pcm_runtime *rtd = substream->private_data; 196 struct snd_soc_pcm_runtime *rtd = substream->private_data;
199 197
@@ -202,7 +200,7 @@ int mop500_ab8500_startup(struct snd_pcm_substream *substream)
202 snd_soc_card_get_drvdata(rtd->card)); 200 snd_soc_card_get_drvdata(rtd->card));
203} 201}
204 202
205void mop500_ab8500_shutdown(struct snd_pcm_substream *substream) 203static void mop500_ab8500_shutdown(struct snd_pcm_substream *substream)
206{ 204{
207 struct snd_soc_pcm_runtime *rtd = substream->private_data; 205 struct snd_soc_pcm_runtime *rtd = substream->private_data;
208 struct device *dev = rtd->card->dev; 206 struct device *dev = rtd->card->dev;
@@ -216,7 +214,7 @@ void mop500_ab8500_shutdown(struct snd_pcm_substream *substream)
216 rx_slots = DEF_RX_SLOTS; 214 rx_slots = DEF_RX_SLOTS;
217} 215}
218 216
219int mop500_ab8500_hw_params(struct snd_pcm_substream *substream, 217static int mop500_ab8500_hw_params(struct snd_pcm_substream *substream,
220 struct snd_pcm_hw_params *params) 218 struct snd_pcm_hw_params *params)
221{ 219{
222 struct snd_soc_pcm_runtime *rtd = substream->private_data; 220 struct snd_soc_pcm_runtime *rtd = substream->private_data;
@@ -240,6 +238,21 @@ int mop500_ab8500_hw_params(struct snd_pcm_substream *substream,
240 substream->name, 238 substream->name,
241 substream->number); 239 substream->number);
242 240
241 /* Ensure configuration consistency between DAIs */
242 mutex_lock(&mop500_ab8500_params_lock);
243 if (mop500_ab8500_usage) {
244 if (mop500_ab8500_rate != params_rate(params) ||
245 mop500_ab8500_channels != params_channels(params)) {
246 mutex_unlock(&mop500_ab8500_params_lock);
247 return -EBUSY;
248 }
249 } else {
250 mop500_ab8500_rate = params_rate(params);
251 mop500_ab8500_channels = params_channels(params);
252 }
253 __set_bit(cpu_dai->id, &mop500_ab8500_usage);
254 mutex_unlock(&mop500_ab8500_params_lock);
255
243 channels = params_channels(params); 256 channels = params_channels(params);
244 257
245 switch (params_format(params)) { 258 switch (params_format(params)) {
@@ -338,9 +351,22 @@ int mop500_ab8500_hw_params(struct snd_pcm_substream *substream,
338 return 0; 351 return 0;
339} 352}
340 353
354static int mop500_ab8500_hw_free(struct snd_pcm_substream *substream)
355{
356 struct snd_soc_pcm_runtime *rtd = substream->private_data;
357 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
358
359 mutex_lock(&mop500_ab8500_params_lock);
360 __clear_bit(cpu_dai->id, &mop500_ab8500_usage);
361 mutex_unlock(&mop500_ab8500_params_lock);
362
363 return 0;
364}
365
341struct snd_soc_ops mop500_ab8500_ops[] = { 366struct snd_soc_ops mop500_ab8500_ops[] = {
342 { 367 {
343 .hw_params = mop500_ab8500_hw_params, 368 .hw_params = mop500_ab8500_hw_params,
369 .hw_free = mop500_ab8500_hw_free,
344 .startup = mop500_ab8500_startup, 370 .startup = mop500_ab8500_startup,
345 .shutdown = mop500_ab8500_shutdown, 371 .shutdown = mop500_ab8500_shutdown,
346 } 372 }
@@ -385,7 +411,7 @@ int mop500_ab8500_machine_init(struct snd_soc_pcm_runtime *rtd)
385 drvdata->mclk_sel = MCLK_ULPCLK; 411 drvdata->mclk_sel = MCLK_ULPCLK;
386 412
387 /* Add controls */ 413 /* Add controls */
388 ret = snd_soc_add_codec_controls(codec, mop500_ab8500_ctrls, 414 ret = snd_soc_add_card_controls(codec->card, mop500_ab8500_ctrls,
389 ARRAY_SIZE(mop500_ab8500_ctrls)); 415 ARRAY_SIZE(mop500_ab8500_ctrls));
390 if (ret < 0) { 416 if (ret < 0) {
391 pr_err("%s: Failed to add machine-controls (%d)!\n", 417 pr_err("%s: Failed to add machine-controls (%d)!\n",
diff --git a/sound/soc/ux500/ux500_msp_dai.c b/sound/soc/ux500/ux500_msp_dai.c
index 7d5fc1328523..c6fb5cce980e 100644
--- a/sound/soc/ux500/ux500_msp_dai.c
+++ b/sound/soc/ux500/ux500_msp_dai.c
@@ -658,14 +658,11 @@ static int ux500_msp_dai_probe(struct snd_soc_dai *dai)
658{ 658{
659 struct ux500_msp_i2s_drvdata *drvdata = dev_get_drvdata(dai->dev); 659 struct ux500_msp_i2s_drvdata *drvdata = dev_get_drvdata(dai->dev);
660 660
661 drvdata->playback_dma_data.dma_cfg = drvdata->msp->dma_cfg_tx; 661 dai->playback_dma_data = &drvdata->msp->playback_dma_data;
662 drvdata->capture_dma_data.dma_cfg = drvdata->msp->dma_cfg_rx; 662 dai->capture_dma_data = &drvdata->msp->capture_dma_data;
663 663
664 dai->playback_dma_data = &drvdata->playback_dma_data; 664 drvdata->msp->playback_dma_data.data_size = drvdata->slot_width;
665 dai->capture_dma_data = &drvdata->capture_dma_data; 665 drvdata->msp->capture_dma_data.data_size = drvdata->slot_width;
666
667 drvdata->playback_dma_data.data_size = drvdata->slot_width;
668 drvdata->capture_dma_data.data_size = drvdata->slot_width;
669 666
670 return 0; 667 return 0;
671} 668}
diff --git a/sound/soc/ux500/ux500_msp_dai.h b/sound/soc/ux500/ux500_msp_dai.h
index f53104359f15..312ae535e351 100644
--- a/sound/soc/ux500/ux500_msp_dai.h
+++ b/sound/soc/ux500/ux500_msp_dai.h
@@ -51,15 +51,11 @@ enum ux500_msp_clock_id {
51struct ux500_msp_i2s_drvdata { 51struct ux500_msp_i2s_drvdata {
52 struct ux500_msp *msp; 52 struct ux500_msp *msp;
53 struct regulator *reg_vape; 53 struct regulator *reg_vape;
54 struct ux500_msp_dma_params playback_dma_data;
55 struct ux500_msp_dma_params capture_dma_data;
56 unsigned int fmt; 54 unsigned int fmt;
57 unsigned int tx_mask; 55 unsigned int tx_mask;
58 unsigned int rx_mask; 56 unsigned int rx_mask;
59 int slots; 57 int slots;
60 int slot_width; 58 int slot_width;
61 u8 configured;
62 int data_delay;
63 59
64 /* Clocks */ 60 /* Clocks */
65 unsigned int master_clk; 61 unsigned int master_clk;
diff --git a/sound/soc/ux500/ux500_msp_i2s.c b/sound/soc/ux500/ux500_msp_i2s.c
index f2db6c90a9e2..1ca8b08ae993 100644
--- a/sound/soc/ux500/ux500_msp_i2s.c
+++ b/sound/soc/ux500/ux500_msp_i2s.c
@@ -15,7 +15,6 @@
15 15
16#include <linux/module.h> 16#include <linux/module.h>
17#include <linux/platform_device.h> 17#include <linux/platform_device.h>
18#include <linux/pinctrl/consumer.h>
19#include <linux/delay.h> 18#include <linux/delay.h>
20#include <linux/slab.h> 19#include <linux/slab.h>
21#include <linux/io.h> 20#include <linux/io.h>
@@ -26,9 +25,6 @@
26 25
27#include "ux500_msp_i2s.h" 26#include "ux500_msp_i2s.h"
28 27
29/* MSP1/3 Tx/Rx usage protection */
30static DEFINE_SPINLOCK(msp_rxtx_lock);
31
32 /* Protocol desciptors */ 28 /* Protocol desciptors */
33static const struct msp_protdesc prot_descs[] = { 29static const struct msp_protdesc prot_descs[] = {
34 { /* I2S */ 30 { /* I2S */
@@ -356,24 +352,8 @@ static int configure_multichannel(struct ux500_msp *msp,
356 352
357static int enable_msp(struct ux500_msp *msp, struct ux500_msp_config *config) 353static int enable_msp(struct ux500_msp *msp, struct ux500_msp_config *config)
358{ 354{
359 int status = 0, retval = 0; 355 int status = 0;
360 u32 reg_val_DMACR, reg_val_GCR; 356 u32 reg_val_DMACR, reg_val_GCR;
361 unsigned long flags;
362
363 /* Check msp state whether in RUN or CONFIGURED Mode */
364 if (msp->msp_state == MSP_STATE_IDLE) {
365 spin_lock_irqsave(&msp_rxtx_lock, flags);
366 if (msp->pinctrl_rxtx_ref == 0 &&
367 !(IS_ERR(msp->pinctrl_p) || IS_ERR(msp->pinctrl_def))) {
368 retval = pinctrl_select_state(msp->pinctrl_p,
369 msp->pinctrl_def);
370 if (retval)
371 pr_err("could not set MSP defstate\n");
372 }
373 if (!retval)
374 msp->pinctrl_rxtx_ref++;
375 spin_unlock_irqrestore(&msp_rxtx_lock, flags);
376 }
377 357
378 /* Configure msp with protocol dependent settings */ 358 /* Configure msp with protocol dependent settings */
379 configure_protocol(msp, config); 359 configure_protocol(msp, config);
@@ -387,12 +367,14 @@ static int enable_msp(struct ux500_msp *msp, struct ux500_msp_config *config)
387 } 367 }
388 368
389 /* Make sure the correct DMA-directions are configured */ 369 /* Make sure the correct DMA-directions are configured */
390 if ((config->direction & MSP_DIR_RX) && (!msp->dma_cfg_rx)) { 370 if ((config->direction & MSP_DIR_RX) &&
371 !msp->capture_dma_data.dma_cfg) {
391 dev_err(msp->dev, "%s: ERROR: MSP RX-mode is not configured!", 372 dev_err(msp->dev, "%s: ERROR: MSP RX-mode is not configured!",
392 __func__); 373 __func__);
393 return -EINVAL; 374 return -EINVAL;
394 } 375 }
395 if ((config->direction == MSP_DIR_TX) && (!msp->dma_cfg_tx)) { 376 if ((config->direction == MSP_DIR_TX) &&
377 !msp->playback_dma_data.dma_cfg) {
396 dev_err(msp->dev, "%s: ERROR: MSP TX-mode is not configured!", 378 dev_err(msp->dev, "%s: ERROR: MSP TX-mode is not configured!",
397 __func__); 379 __func__);
398 return -EINVAL; 380 return -EINVAL;
@@ -630,8 +612,7 @@ int ux500_msp_i2s_trigger(struct ux500_msp *msp, int cmd, int direction)
630 612
631int ux500_msp_i2s_close(struct ux500_msp *msp, unsigned int dir) 613int ux500_msp_i2s_close(struct ux500_msp *msp, unsigned int dir)
632{ 614{
633 int status = 0, retval = 0; 615 int status = 0;
634 unsigned long flags;
635 616
636 dev_dbg(msp->dev, "%s: Enter (dir = 0x%01x).\n", __func__, dir); 617 dev_dbg(msp->dev, "%s: Enter (dir = 0x%01x).\n", __func__, dir);
637 618
@@ -643,18 +624,6 @@ int ux500_msp_i2s_close(struct ux500_msp *msp, unsigned int dir)
643 (~(FRAME_GEN_ENABLE | SRG_ENABLE))), 624 (~(FRAME_GEN_ENABLE | SRG_ENABLE))),
644 msp->registers + MSP_GCR); 625 msp->registers + MSP_GCR);
645 626
646 spin_lock_irqsave(&msp_rxtx_lock, flags);
647 WARN_ON(!msp->pinctrl_rxtx_ref);
648 msp->pinctrl_rxtx_ref--;
649 if (msp->pinctrl_rxtx_ref == 0 &&
650 !(IS_ERR(msp->pinctrl_p) || IS_ERR(msp->pinctrl_sleep))) {
651 retval = pinctrl_select_state(msp->pinctrl_p,
652 msp->pinctrl_sleep);
653 if (retval)
654 pr_err("could not set MSP sleepstate\n");
655 }
656 spin_unlock_irqrestore(&msp_rxtx_lock, flags);
657
658 writel(0, msp->registers + MSP_GCR); 627 writel(0, msp->registers + MSP_GCR);
659 writel(0, msp->registers + MSP_TCF); 628 writel(0, msp->registers + MSP_TCF);
660 writel(0, msp->registers + MSP_RCF); 629 writel(0, msp->registers + MSP_RCF);
@@ -682,7 +651,6 @@ int ux500_msp_i2s_init_msp(struct platform_device *pdev,
682 struct msp_i2s_platform_data *platform_data) 651 struct msp_i2s_platform_data *platform_data)
683{ 652{
684 struct resource *res = NULL; 653 struct resource *res = NULL;
685 struct i2s_controller *i2s_cont;
686 struct device_node *np = pdev->dev.of_node; 654 struct device_node *np = pdev->dev.of_node;
687 struct ux500_msp *msp; 655 struct ux500_msp *msp;
688 656
@@ -707,8 +675,8 @@ int ux500_msp_i2s_init_msp(struct platform_device *pdev,
707 675
708 msp->id = platform_data->id; 676 msp->id = platform_data->id;
709 msp->dev = &pdev->dev; 677 msp->dev = &pdev->dev;
710 msp->dma_cfg_rx = platform_data->msp_i2s_dma_rx; 678 msp->playback_dma_data.dma_cfg = platform_data->msp_i2s_dma_tx;
711 msp->dma_cfg_tx = platform_data->msp_i2s_dma_tx; 679 msp->capture_dma_data.dma_cfg = platform_data->msp_i2s_dma_rx;
712 680
713 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 681 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
714 if (res == NULL) { 682 if (res == NULL) {
@@ -717,6 +685,9 @@ int ux500_msp_i2s_init_msp(struct platform_device *pdev,
717 return -ENOMEM; 685 return -ENOMEM;
718 } 686 }
719 687
688 msp->playback_dma_data.tx_rx_addr = res->start + MSP_DR;
689 msp->capture_dma_data.tx_rx_addr = res->start + MSP_DR;
690
720 msp->registers = devm_ioremap(&pdev->dev, res->start, 691 msp->registers = devm_ioremap(&pdev->dev, res->start,
721 resource_size(res)); 692 resource_size(res));
722 if (msp->registers == NULL) { 693 if (msp->registers == NULL) {
@@ -727,41 +698,6 @@ int ux500_msp_i2s_init_msp(struct platform_device *pdev,
727 msp->msp_state = MSP_STATE_IDLE; 698 msp->msp_state = MSP_STATE_IDLE;
728 msp->loopback_enable = 0; 699 msp->loopback_enable = 0;
729 700
730 /* I2S-controller is allocated and added in I2S controller class. */
731 i2s_cont = devm_kzalloc(&pdev->dev, sizeof(*i2s_cont), GFP_KERNEL);
732 if (!i2s_cont) {
733 dev_err(&pdev->dev,
734 "%s: ERROR: Failed to allocate I2S-controller!\n",
735 __func__);
736 return -ENOMEM;
737 }
738 i2s_cont->dev.parent = &pdev->dev;
739 i2s_cont->data = (void *)msp;
740 i2s_cont->id = (s16)msp->id;
741 snprintf(i2s_cont->name, sizeof(i2s_cont->name), "ux500-msp-i2s.%04x",
742 msp->id);
743 dev_dbg(&pdev->dev, "I2S device-name: '%s'\n", i2s_cont->name);
744 msp->i2s_cont = i2s_cont;
745
746 msp->pinctrl_p = pinctrl_get(msp->dev);
747 if (IS_ERR(msp->pinctrl_p))
748 dev_err(&pdev->dev, "could not get MSP pinctrl\n");
749 else {
750 msp->pinctrl_def = pinctrl_lookup_state(msp->pinctrl_p,
751 PINCTRL_STATE_DEFAULT);
752 if (IS_ERR(msp->pinctrl_def)) {
753 dev_err(&pdev->dev,
754 "could not get MSP defstate (%li)\n",
755 PTR_ERR(msp->pinctrl_def));
756 }
757 msp->pinctrl_sleep = pinctrl_lookup_state(msp->pinctrl_p,
758 PINCTRL_STATE_SLEEP);
759 if (IS_ERR(msp->pinctrl_sleep))
760 dev_err(&pdev->dev,
761 "could not get MSP idlestate (%li)\n",
762 PTR_ERR(msp->pinctrl_def));
763 }
764
765 return 0; 701 return 0;
766} 702}
767 703
@@ -769,8 +705,6 @@ void ux500_msp_i2s_cleanup_msp(struct platform_device *pdev,
769 struct ux500_msp *msp) 705 struct ux500_msp *msp)
770{ 706{
771 dev_dbg(msp->dev, "%s: Enter (id = %d).\n", __func__, msp->id); 707 dev_dbg(msp->dev, "%s: Enter (id = %d).\n", __func__, msp->id);
772
773 device_unregister(&msp->i2s_cont->dev);
774} 708}
775 709
776MODULE_LICENSE("GPL v2"); 710MODULE_LICENSE("GPL v2");
diff --git a/sound/soc/ux500/ux500_msp_i2s.h b/sound/soc/ux500/ux500_msp_i2s.h
index e5cd105c90f9..258d0bcee0bd 100644
--- a/sound/soc/ux500/ux500_msp_i2s.h
+++ b/sound/soc/ux500/ux500_msp_i2s.h
@@ -16,6 +16,7 @@
16#define UX500_MSP_I2S_H 16#define UX500_MSP_I2S_H
17 17
18#include <linux/platform_device.h> 18#include <linux/platform_device.h>
19#include <linux/platform_data/asoc-ux500-msp.h>
19 20
20#define MSP_INPUT_FREQ_APB 48000000 21#define MSP_INPUT_FREQ_APB 48000000
21 22
@@ -341,11 +342,6 @@ enum msp_compress_mode {
341 MSP_COMPRESS_MODE_A_LAW = 3 342 MSP_COMPRESS_MODE_A_LAW = 3
342}; 343};
343 344
344enum msp_spi_burst_mode {
345 MSP_SPI_BURST_MODE_DISABLE = 0,
346 MSP_SPI_BURST_MODE_ENABLE = 1
347};
348
349enum msp_expand_mode { 345enum msp_expand_mode {
350 MSP_EXPAND_MODE_LINEAR = 0, 346 MSP_EXPAND_MODE_LINEAR = 0,
351 MSP_EXPAND_MODE_LINEAR_SIGNED = 1, 347 MSP_EXPAND_MODE_LINEAR_SIGNED = 1,
@@ -370,13 +366,6 @@ enum msp_protocol {
370 */ 366 */
371#define MAX_MSP_BACKUP_REGS 36 367#define MAX_MSP_BACKUP_REGS 36
372 368
373enum enum_i2s_controller {
374 MSP_0_I2S_CONTROLLER = 0,
375 MSP_1_I2S_CONTROLLER,
376 MSP_2_I2S_CONTROLLER,
377 MSP_3_I2S_CONTROLLER,
378};
379
380enum i2s_direction_t { 369enum i2s_direction_t {
381 MSP_DIR_TX = 0x01, 370 MSP_DIR_TX = 0x01,
382 MSP_DIR_RX = 0x02, 371 MSP_DIR_RX = 0x02,
@@ -454,32 +443,6 @@ struct msp_protdesc {
454 u32 clocks_per_frame; 443 u32 clocks_per_frame;
455}; 444};
456 445
457struct i2s_message {
458 enum i2s_direction_t i2s_direction;
459 void *txdata;
460 void *rxdata;
461 size_t txbytes;
462 size_t rxbytes;
463 int dma_flag;
464 int tx_offset;
465 int rx_offset;
466 bool cyclic_dma;
467 dma_addr_t buf_addr;
468 size_t buf_len;
469 size_t period_len;
470};
471
472struct i2s_controller {
473 struct module *owner;
474 unsigned int id;
475 unsigned int class;
476 const struct i2s_algorithm *algo; /* the algorithm to access the bus */
477 void *data;
478 struct mutex bus_lock;
479 struct device dev; /* the controller device */
480 char name[48];
481};
482
483struct ux500_msp_config { 446struct ux500_msp_config {
484 unsigned int f_inputclk; 447 unsigned int f_inputclk;
485 unsigned int rx_clk_sel; 448 unsigned int rx_clk_sel;
@@ -491,8 +454,6 @@ struct ux500_msp_config {
491 unsigned int tx_fsync_sel; 454 unsigned int tx_fsync_sel;
492 unsigned int rx_fifo_config; 455 unsigned int rx_fifo_config;
493 unsigned int tx_fifo_config; 456 unsigned int tx_fifo_config;
494 unsigned int spi_clk_mode;
495 unsigned int spi_burst_mode;
496 unsigned int loopback_enable; 457 unsigned int loopback_enable;
497 unsigned int tx_data_enable; 458 unsigned int tx_data_enable;
498 unsigned int default_protdesc; 459 unsigned int default_protdesc;
@@ -502,43 +463,28 @@ struct ux500_msp_config {
502 unsigned int direction; 463 unsigned int direction;
503 unsigned int protocol; 464 unsigned int protocol;
504 unsigned int frame_freq; 465 unsigned int frame_freq;
505 unsigned int frame_size;
506 enum msp_data_size data_size; 466 enum msp_data_size data_size;
507 unsigned int def_elem_len; 467 unsigned int def_elem_len;
508 unsigned int iodelay; 468 unsigned int iodelay;
509 void (*handler) (void *data); 469};
510 void *tx_callback_data; 470
511 void *rx_callback_data; 471struct ux500_msp_dma_params {
472 unsigned int data_size;
473 dma_addr_t tx_rx_addr;
474 struct stedma40_chan_cfg *dma_cfg;
512}; 475};
513 476
514struct ux500_msp { 477struct ux500_msp {
515 enum enum_i2s_controller id; 478 enum msp_i2s_id id;
516 void __iomem *registers; 479 void __iomem *registers;
517 struct device *dev; 480 struct device *dev;
518 struct i2s_controller *i2s_cont; 481 struct ux500_msp_dma_params playback_dma_data;
519 struct stedma40_chan_cfg *dma_cfg_rx; 482 struct ux500_msp_dma_params capture_dma_data;
520 struct stedma40_chan_cfg *dma_cfg_tx;
521 struct dma_chan *tx_pipeid;
522 struct dma_chan *rx_pipeid;
523 enum msp_state msp_state; 483 enum msp_state msp_state;
524 int (*transfer) (struct ux500_msp *msp, struct i2s_message *message);
525 struct timer_list notify_timer;
526 int def_elem_len; 484 int def_elem_len;
527 unsigned int dir_busy; 485 unsigned int dir_busy;
528 int loopback_enable; 486 int loopback_enable;
529 u32 backup_regs[MAX_MSP_BACKUP_REGS];
530 unsigned int f_bitclk; 487 unsigned int f_bitclk;
531 /* Pin modes */
532 struct pinctrl *pinctrl_p;
533 struct pinctrl_state *pinctrl_def;
534 struct pinctrl_state *pinctrl_sleep;
535 /* Reference Count */
536 int pinctrl_rxtx_ref;
537};
538
539struct ux500_msp_dma_params {
540 unsigned int data_size;
541 struct stedma40_chan_cfg *dma_cfg;
542}; 488};
543 489
544struct msp_i2s_platform_data; 490struct msp_i2s_platform_data;
diff --git a/sound/soc/ux500/ux500_pcm.c b/sound/soc/ux500/ux500_pcm.c
index 31f9bbc74521..ce554de5d9dc 100644
--- a/sound/soc/ux500/ux500_pcm.c
+++ b/sound/soc/ux500/ux500_pcm.c
@@ -103,10 +103,40 @@ static struct dma_chan *ux500_pcm_request_chan(struct snd_soc_pcm_runtime *rtd,
103 return snd_dmaengine_pcm_request_channel(stedma40_filter, dma_cfg); 103 return snd_dmaengine_pcm_request_channel(stedma40_filter, dma_cfg);
104} 104}
105 105
106static int ux500_pcm_prepare_slave_config(struct snd_pcm_substream *substream,
107 struct snd_pcm_hw_params *params,
108 struct dma_slave_config *slave_config)
109{
110 struct snd_soc_pcm_runtime *rtd = substream->private_data;
111 struct ux500_msp_dma_params *dma_params;
112 struct stedma40_chan_cfg *dma_cfg;
113 int ret;
114
115 dma_params = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
116 dma_cfg = dma_params->dma_cfg;
117
118 ret = snd_hwparams_to_dma_slave_config(substream, params, slave_config);
119 if (ret)
120 return ret;
121
122 slave_config->dst_maxburst = 4;
123 slave_config->dst_addr_width = dma_cfg->dst_info.data_width;
124 slave_config->src_maxburst = 4;
125 slave_config->src_addr_width = dma_cfg->src_info.data_width;
126
127 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
128 slave_config->dst_addr = dma_params->tx_rx_addr;
129 else
130 slave_config->src_addr = dma_params->tx_rx_addr;
131
132 return 0;
133}
134
106static const struct snd_dmaengine_pcm_config ux500_dmaengine_pcm_config = { 135static const struct snd_dmaengine_pcm_config ux500_dmaengine_pcm_config = {
107 .pcm_hardware = &ux500_pcm_hw, 136 .pcm_hardware = &ux500_pcm_hw,
108 .compat_request_channel = ux500_pcm_request_chan, 137 .compat_request_channel = ux500_pcm_request_chan,
109 .prealloc_buffer_size = 128 * 1024, 138 .prealloc_buffer_size = 128 * 1024,
139 .prepare_slave_config = ux500_pcm_prepare_slave_config,
110}; 140};
111 141
112int ux500_pcm_register_platform(struct platform_device *pdev) 142int ux500_pcm_register_platform(struct platform_device *pdev)
diff --git a/sound/sparc/dbri.c b/sound/sparc/dbri.c
index 75e6016d3efe..eee7afcae375 100644
--- a/sound/sparc/dbri.c
+++ b/sound/sparc/dbri.c
@@ -2670,8 +2670,6 @@ static int dbri_remove(struct platform_device *op)
2670 snd_dbri_free(card->private_data); 2670 snd_dbri_free(card->private_data);
2671 snd_card_free(card); 2671 snd_card_free(card);
2672 2672
2673 dev_set_drvdata(&op->dev, NULL);
2674
2675 return 0; 2673 return 0;
2676} 2674}
2677 2675
diff --git a/sound/spi/at73c213.c b/sound/spi/at73c213.c
index a1a24b979ed2..8e3d9a6c7a3b 100644
--- a/sound/spi/at73c213.c
+++ b/sound/spi/at73c213.c
@@ -1070,7 +1070,6 @@ out:
1070 1070
1071 ssc_free(chip->ssc); 1071 ssc_free(chip->ssc);
1072 snd_card_free(card); 1072 snd_card_free(card);
1073 dev_set_drvdata(&spi->dev, NULL);
1074 1073
1075 return 0; 1074 return 0;
1076} 1075}
diff --git a/sound/usb/6fire/chip.c b/sound/usb/6fire/chip.c
index 4394ae796356..c39c77978468 100644
--- a/sound/usb/6fire/chip.c
+++ b/sound/usb/6fire/chip.c
@@ -30,7 +30,7 @@
30MODULE_AUTHOR("Torsten Schenk <torsten.schenk@zoho.com>"); 30MODULE_AUTHOR("Torsten Schenk <torsten.schenk@zoho.com>");
31MODULE_DESCRIPTION("TerraTec DMX 6Fire USB audio driver"); 31MODULE_DESCRIPTION("TerraTec DMX 6Fire USB audio driver");
32MODULE_LICENSE("GPL v2"); 32MODULE_LICENSE("GPL v2");
33MODULE_SUPPORTED_DEVICE("{{TerraTec, DMX 6Fire USB}}"); 33MODULE_SUPPORTED_DEVICE("{{TerraTec,DMX 6Fire USB}}");
34 34
35static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-max */ 35static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-max */
36static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* Id for card */ 36static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* Id for card */
diff --git a/sound/usb/6fire/pcm.c b/sound/usb/6fire/pcm.c
index 40dd50a80f55..c5b9cac37dc4 100644
--- a/sound/usb/6fire/pcm.c
+++ b/sound/usb/6fire/pcm.c
@@ -450,13 +450,13 @@ static int usb6fire_pcm_close(struct snd_pcm_substream *alsa_sub)
450static int usb6fire_pcm_hw_params(struct snd_pcm_substream *alsa_sub, 450static int usb6fire_pcm_hw_params(struct snd_pcm_substream *alsa_sub,
451 struct snd_pcm_hw_params *hw_params) 451 struct snd_pcm_hw_params *hw_params)
452{ 452{
453 return snd_pcm_lib_malloc_pages(alsa_sub, 453 return snd_pcm_lib_alloc_vmalloc_buffer(alsa_sub,
454 params_buffer_bytes(hw_params)); 454 params_buffer_bytes(hw_params));
455} 455}
456 456
457static int usb6fire_pcm_hw_free(struct snd_pcm_substream *alsa_sub) 457static int usb6fire_pcm_hw_free(struct snd_pcm_substream *alsa_sub)
458{ 458{
459 return snd_pcm_lib_free_pages(alsa_sub); 459 return snd_pcm_lib_free_vmalloc_buffer(alsa_sub);
460} 460}
461 461
462static int usb6fire_pcm_prepare(struct snd_pcm_substream *alsa_sub) 462static int usb6fire_pcm_prepare(struct snd_pcm_substream *alsa_sub)
@@ -560,6 +560,8 @@ static struct snd_pcm_ops pcm_ops = {
560 .prepare = usb6fire_pcm_prepare, 560 .prepare = usb6fire_pcm_prepare,
561 .trigger = usb6fire_pcm_trigger, 561 .trigger = usb6fire_pcm_trigger,
562 .pointer = usb6fire_pcm_pointer, 562 .pointer = usb6fire_pcm_pointer,
563 .page = snd_pcm_lib_get_vmalloc_page,
564 .mmap = snd_pcm_lib_mmap_vmalloc,
563}; 565};
564 566
565static void usb6fire_pcm_init_urb(struct pcm_urb *urb, 567static void usb6fire_pcm_init_urb(struct pcm_urb *urb,
@@ -622,10 +624,6 @@ int usb6fire_pcm_init(struct sfire_chip *chip)
622 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &pcm_ops); 624 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &pcm_ops);
623 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &pcm_ops); 625 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &pcm_ops);
624 626
625 ret = snd_pcm_lib_preallocate_pages_for_all(pcm,
626 SNDRV_DMA_TYPE_CONTINUOUS,
627 snd_dma_continuous_data(GFP_KERNEL),
628 MAX_BUFSIZE, MAX_BUFSIZE);
629 if (ret) { 627 if (ret) {
630 kfree(rt); 628 kfree(rt);
631 snd_printk(KERN_ERR PREFIX 629 snd_printk(KERN_ERR PREFIX
diff --git a/sound/usb/Kconfig b/sound/usb/Kconfig
index 225dfd737265..de9408b83f75 100644
--- a/sound/usb/Kconfig
+++ b/sound/usb/Kconfig
@@ -115,5 +115,36 @@ config SND_USB_6FIRE
115 and further help can be found at 115 and further help can be found at
116 http://sixfireusb.sourceforge.net 116 http://sixfireusb.sourceforge.net
117 117
118config SND_USB_HIFACE
119 tristate "M2Tech hiFace USB-SPDIF driver"
120 select SND_PCM
121 help
122 Select this option to include support for M2Tech hiFace USB-SPDIF
123 interface.
124
125 This driver supports the original M2Tech hiFace and some other
126 compatible devices. The supported products are:
127
128 * M2Tech Young
129 * M2Tech hiFace
130 * M2Tech North Star
131 * M2Tech W4S Young
132 * M2Tech Corrson
133 * M2Tech AUDIA
134 * M2Tech SL Audio
135 * M2Tech Empirical
136 * M2Tech Rockna
137 * M2Tech Pathos
138 * M2Tech Metronome
139 * M2Tech CAD
140 * M2Tech Audio Esclusive
141 * M2Tech Rotel
142 * M2Tech Eeaudio
143 * The Chord Company CHORD
144 * AVA Group A/S Vitus
145
146 To compile this driver as a module, choose M here: the module
147 will be called snd-usb-hiface.
148
118endif # SND_USB 149endif # SND_USB
119 150
diff --git a/sound/usb/Makefile b/sound/usb/Makefile
index ac256dc4c6be..abe668f660d1 100644
--- a/sound/usb/Makefile
+++ b/sound/usb/Makefile
@@ -23,4 +23,4 @@ obj-$(CONFIG_SND_USB_UA101) += snd-usbmidi-lib.o
23obj-$(CONFIG_SND_USB_USX2Y) += snd-usbmidi-lib.o 23obj-$(CONFIG_SND_USB_USX2Y) += snd-usbmidi-lib.o
24obj-$(CONFIG_SND_USB_US122L) += snd-usbmidi-lib.o 24obj-$(CONFIG_SND_USB_US122L) += snd-usbmidi-lib.o
25 25
26obj-$(CONFIG_SND) += misc/ usx2y/ caiaq/ 6fire/ 26obj-$(CONFIG_SND) += misc/ usx2y/ caiaq/ 6fire/ hiface/
diff --git a/sound/usb/caiaq/audio.c b/sound/usb/caiaq/audio.c
index c1916184e2e1..7103b0908d13 100644
--- a/sound/usb/caiaq/audio.c
+++ b/sound/usb/caiaq/audio.c
@@ -183,14 +183,15 @@ static int snd_usb_caiaq_substream_close(struct snd_pcm_substream *substream)
183static int snd_usb_caiaq_pcm_hw_params(struct snd_pcm_substream *sub, 183static int snd_usb_caiaq_pcm_hw_params(struct snd_pcm_substream *sub,
184 struct snd_pcm_hw_params *hw_params) 184 struct snd_pcm_hw_params *hw_params)
185{ 185{
186 return snd_pcm_lib_malloc_pages(sub, params_buffer_bytes(hw_params)); 186 return snd_pcm_lib_alloc_vmalloc_buffer(sub,
187 params_buffer_bytes(hw_params));
187} 188}
188 189
189static int snd_usb_caiaq_pcm_hw_free(struct snd_pcm_substream *sub) 190static int snd_usb_caiaq_pcm_hw_free(struct snd_pcm_substream *sub)
190{ 191{
191 struct snd_usb_caiaqdev *cdev = snd_pcm_substream_chip(sub); 192 struct snd_usb_caiaqdev *cdev = snd_pcm_substream_chip(sub);
192 deactivate_substream(cdev, sub); 193 deactivate_substream(cdev, sub);
193 return snd_pcm_lib_free_pages(sub); 194 return snd_pcm_lib_free_vmalloc_buffer(sub);
194} 195}
195 196
196/* this should probably go upstream */ 197/* this should probably go upstream */
@@ -345,7 +346,9 @@ static struct snd_pcm_ops snd_usb_caiaq_ops = {
345 .hw_free = snd_usb_caiaq_pcm_hw_free, 346 .hw_free = snd_usb_caiaq_pcm_hw_free,
346 .prepare = snd_usb_caiaq_pcm_prepare, 347 .prepare = snd_usb_caiaq_pcm_prepare,
347 .trigger = snd_usb_caiaq_pcm_trigger, 348 .trigger = snd_usb_caiaq_pcm_trigger,
348 .pointer = snd_usb_caiaq_pcm_pointer 349 .pointer = snd_usb_caiaq_pcm_pointer,
350 .page = snd_pcm_lib_get_vmalloc_page,
351 .mmap = snd_pcm_lib_mmap_vmalloc,
349}; 352};
350 353
351static void check_for_elapsed_periods(struct snd_usb_caiaqdev *cdev, 354static void check_for_elapsed_periods(struct snd_usb_caiaqdev *cdev,
@@ -852,11 +855,6 @@ int snd_usb_caiaq_audio_init(struct snd_usb_caiaqdev *cdev)
852 snd_pcm_set_ops(cdev->pcm, SNDRV_PCM_STREAM_CAPTURE, 855 snd_pcm_set_ops(cdev->pcm, SNDRV_PCM_STREAM_CAPTURE,
853 &snd_usb_caiaq_ops); 856 &snd_usb_caiaq_ops);
854 857
855 snd_pcm_lib_preallocate_pages_for_all(cdev->pcm,
856 SNDRV_DMA_TYPE_CONTINUOUS,
857 snd_dma_continuous_data(GFP_KERNEL),
858 MAX_BUFFER_SIZE, MAX_BUFFER_SIZE);
859
860 cdev->data_cb_info = 858 cdev->data_cb_info =
861 kmalloc(sizeof(struct snd_usb_caiaq_cb_info) * N_URBS, 859 kmalloc(sizeof(struct snd_usb_caiaq_cb_info) * N_URBS,
862 GFP_KERNEL); 860 GFP_KERNEL);
diff --git a/sound/usb/caiaq/device.c b/sound/usb/caiaq/device.c
index 48b63ccc78c7..1a61dd12fe38 100644
--- a/sound/usb/caiaq/device.c
+++ b/sound/usb/caiaq/device.c
@@ -39,25 +39,24 @@
39MODULE_AUTHOR("Daniel Mack <daniel@caiaq.de>"); 39MODULE_AUTHOR("Daniel Mack <daniel@caiaq.de>");
40MODULE_DESCRIPTION("caiaq USB audio"); 40MODULE_DESCRIPTION("caiaq USB audio");
41MODULE_LICENSE("GPL"); 41MODULE_LICENSE("GPL");
42MODULE_SUPPORTED_DEVICE("{{Native Instruments, RigKontrol2}," 42MODULE_SUPPORTED_DEVICE("{{Native Instruments,RigKontrol2},"
43 "{Native Instruments, RigKontrol3}," 43 "{Native Instruments,RigKontrol3},"
44 "{Native Instruments, Kore Controller}," 44 "{Native Instruments,Kore Controller},"
45 "{Native Instruments, Kore Controller 2}," 45 "{Native Instruments,Kore Controller 2},"
46 "{Native Instruments, Audio Kontrol 1}," 46 "{Native Instruments,Audio Kontrol 1},"
47 "{Native Instruments, Audio 2 DJ}," 47 "{Native Instruments,Audio 2 DJ},"
48 "{Native Instruments, Audio 4 DJ}," 48 "{Native Instruments,Audio 4 DJ},"
49 "{Native Instruments, Audio 8 DJ}," 49 "{Native Instruments,Audio 8 DJ},"
50 "{Native Instruments, Traktor Audio 2}," 50 "{Native Instruments,Traktor Audio 2},"
51 "{Native Instruments, Session I/O}," 51 "{Native Instruments,Session I/O},"
52 "{Native Instruments, GuitarRig mobile}," 52 "{Native Instruments,GuitarRig mobile},"
53 "{Native Instruments, Traktor Kontrol X1}," 53 "{Native Instruments,Traktor Kontrol X1},"
54 "{Native Instruments, Traktor Kontrol S4}," 54 "{Native Instruments,Traktor Kontrol S4},"
55 "{Native Instruments, Maschine Controller}}"); 55 "{Native Instruments,Maschine Controller}}");
56 56
57static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-max */ 57static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-max */
58static char* id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* Id for this card */ 58static char* id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* Id for this card */
59static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */ 59static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */
60static int snd_card_used[SNDRV_CARDS];
61 60
62module_param_array(index, int, NULL, 0444); 61module_param_array(index, int, NULL, 0444);
63MODULE_PARM_DESC(index, "Index value for the caiaq sound device"); 62MODULE_PARM_DESC(index, "Index value for the caiaq sound device");
@@ -388,7 +387,7 @@ static int create_card(struct usb_device *usb_dev,
388 struct snd_usb_caiaqdev *cdev; 387 struct snd_usb_caiaqdev *cdev;
389 388
390 for (devnum = 0; devnum < SNDRV_CARDS; devnum++) 389 for (devnum = 0; devnum < SNDRV_CARDS; devnum++)
391 if (enable[devnum] && !snd_card_used[devnum]) 390 if (enable[devnum])
392 break; 391 break;
393 392
394 if (devnum >= SNDRV_CARDS) 393 if (devnum >= SNDRV_CARDS)
diff --git a/sound/usb/card.h b/sound/usb/card.h
index bf2889a2cae5..5ecacaa90b53 100644
--- a/sound/usb/card.h
+++ b/sound/usb/card.h
@@ -21,6 +21,7 @@ struct audioformat {
21 unsigned char endpoint; /* endpoint */ 21 unsigned char endpoint; /* endpoint */
22 unsigned char ep_attr; /* endpoint attributes */ 22 unsigned char ep_attr; /* endpoint attributes */
23 unsigned char datainterval; /* log_2 of data packet interval */ 23 unsigned char datainterval; /* log_2 of data packet interval */
24 unsigned char protocol; /* UAC_VERSION_1/2 */
24 unsigned int maxpacksize; /* max. packet size */ 25 unsigned int maxpacksize; /* max. packet size */
25 unsigned int rates; /* rate bitmasks */ 26 unsigned int rates; /* rate bitmasks */
26 unsigned int rate_min, rate_max; /* min/max rates */ 27 unsigned int rate_min, rate_max; /* min/max rates */
diff --git a/sound/usb/clock.c b/sound/usb/clock.c
index 3a2ce390e278..86f80c60b21f 100644
--- a/sound/usb/clock.c
+++ b/sound/usb/clock.c
@@ -407,9 +407,7 @@ int snd_usb_init_sample_rate(struct snd_usb_audio *chip, int iface,
407 struct usb_host_interface *alts, 407 struct usb_host_interface *alts,
408 struct audioformat *fmt, int rate) 408 struct audioformat *fmt, int rate)
409{ 409{
410 struct usb_interface_descriptor *altsd = get_iface_desc(alts); 410 switch (fmt->protocol) {
411
412 switch (altsd->bInterfaceProtocol) {
413 case UAC_VERSION_1: 411 case UAC_VERSION_1:
414 default: 412 default:
415 return set_sample_rate_v1(chip, iface, alts, fmt, rate); 413 return set_sample_rate_v1(chip, iface, alts, fmt, rate);
diff --git a/sound/usb/format.c b/sound/usb/format.c
index 99299ffb33ac..3525231c6b97 100644
--- a/sound/usb/format.c
+++ b/sound/usb/format.c
@@ -43,13 +43,12 @@
43 */ 43 */
44static u64 parse_audio_format_i_type(struct snd_usb_audio *chip, 44static u64 parse_audio_format_i_type(struct snd_usb_audio *chip,
45 struct audioformat *fp, 45 struct audioformat *fp,
46 unsigned int format, void *_fmt, 46 unsigned int format, void *_fmt)
47 int protocol)
48{ 47{
49 int sample_width, sample_bytes; 48 int sample_width, sample_bytes;
50 u64 pcm_formats = 0; 49 u64 pcm_formats = 0;
51 50
52 switch (protocol) { 51 switch (fp->protocol) {
53 case UAC_VERSION_1: 52 case UAC_VERSION_1:
54 default: { 53 default: {
55 struct uac_format_type_i_discrete_descriptor *fmt = _fmt; 54 struct uac_format_type_i_discrete_descriptor *fmt = _fmt;
@@ -360,11 +359,8 @@ err:
360 */ 359 */
361static int parse_audio_format_i(struct snd_usb_audio *chip, 360static int parse_audio_format_i(struct snd_usb_audio *chip,
362 struct audioformat *fp, unsigned int format, 361 struct audioformat *fp, unsigned int format,
363 struct uac_format_type_i_continuous_descriptor *fmt, 362 struct uac_format_type_i_continuous_descriptor *fmt)
364 struct usb_host_interface *iface)
365{ 363{
366 struct usb_interface_descriptor *altsd = get_iface_desc(iface);
367 int protocol = altsd->bInterfaceProtocol;
368 snd_pcm_format_t pcm_format; 364 snd_pcm_format_t pcm_format;
369 int ret; 365 int ret;
370 366
@@ -387,8 +383,7 @@ static int parse_audio_format_i(struct snd_usb_audio *chip,
387 } 383 }
388 fp->formats = pcm_format_to_bits(pcm_format); 384 fp->formats = pcm_format_to_bits(pcm_format);
389 } else { 385 } else {
390 fp->formats = parse_audio_format_i_type(chip, fp, format, 386 fp->formats = parse_audio_format_i_type(chip, fp, format, fmt);
391 fmt, protocol);
392 if (!fp->formats) 387 if (!fp->formats)
393 return -EINVAL; 388 return -EINVAL;
394 } 389 }
@@ -398,11 +393,8 @@ static int parse_audio_format_i(struct snd_usb_audio *chip,
398 * proprietary class specific descriptor. 393 * proprietary class specific descriptor.
399 * audio class v2 uses class specific EP0 range requests for that. 394 * audio class v2 uses class specific EP0 range requests for that.
400 */ 395 */
401 switch (protocol) { 396 switch (fp->protocol) {
402 default: 397 default:
403 snd_printdd(KERN_WARNING "%d:%u:%d : invalid protocol version %d, assuming v1\n",
404 chip->dev->devnum, fp->iface, fp->altsetting, protocol);
405 /* fall through */
406 case UAC_VERSION_1: 398 case UAC_VERSION_1:
407 fp->channels = fmt->bNrChannels; 399 fp->channels = fmt->bNrChannels;
408 ret = parse_audio_format_rates_v1(chip, fp, (unsigned char *) fmt, 7); 400 ret = parse_audio_format_rates_v1(chip, fp, (unsigned char *) fmt, 7);
@@ -427,12 +419,9 @@ static int parse_audio_format_i(struct snd_usb_audio *chip,
427 */ 419 */
428static int parse_audio_format_ii(struct snd_usb_audio *chip, 420static int parse_audio_format_ii(struct snd_usb_audio *chip,
429 struct audioformat *fp, 421 struct audioformat *fp,
430 int format, void *_fmt, 422 int format, void *_fmt)
431 struct usb_host_interface *iface)
432{ 423{
433 int brate, framesize, ret; 424 int brate, framesize, ret;
434 struct usb_interface_descriptor *altsd = get_iface_desc(iface);
435 int protocol = altsd->bInterfaceProtocol;
436 425
437 switch (format) { 426 switch (format) {
438 case UAC_FORMAT_TYPE_II_AC3: 427 case UAC_FORMAT_TYPE_II_AC3:
@@ -452,11 +441,8 @@ static int parse_audio_format_ii(struct snd_usb_audio *chip,
452 441
453 fp->channels = 1; 442 fp->channels = 1;
454 443
455 switch (protocol) { 444 switch (fp->protocol) {
456 default: 445 default:
457 snd_printdd(KERN_WARNING "%d:%u:%d : invalid protocol version %d, assuming v1\n",
458 chip->dev->devnum, fp->iface, fp->altsetting, protocol);
459 /* fall through */
460 case UAC_VERSION_1: { 446 case UAC_VERSION_1: {
461 struct uac_format_type_ii_discrete_descriptor *fmt = _fmt; 447 struct uac_format_type_ii_discrete_descriptor *fmt = _fmt;
462 brate = le16_to_cpu(fmt->wMaxBitRate); 448 brate = le16_to_cpu(fmt->wMaxBitRate);
@@ -483,17 +469,17 @@ static int parse_audio_format_ii(struct snd_usb_audio *chip,
483int snd_usb_parse_audio_format(struct snd_usb_audio *chip, 469int snd_usb_parse_audio_format(struct snd_usb_audio *chip,
484 struct audioformat *fp, unsigned int format, 470 struct audioformat *fp, unsigned int format,
485 struct uac_format_type_i_continuous_descriptor *fmt, 471 struct uac_format_type_i_continuous_descriptor *fmt,
486 int stream, struct usb_host_interface *iface) 472 int stream)
487{ 473{
488 int err; 474 int err;
489 475
490 switch (fmt->bFormatType) { 476 switch (fmt->bFormatType) {
491 case UAC_FORMAT_TYPE_I: 477 case UAC_FORMAT_TYPE_I:
492 case UAC_FORMAT_TYPE_III: 478 case UAC_FORMAT_TYPE_III:
493 err = parse_audio_format_i(chip, fp, format, fmt, iface); 479 err = parse_audio_format_i(chip, fp, format, fmt);
494 break; 480 break;
495 case UAC_FORMAT_TYPE_II: 481 case UAC_FORMAT_TYPE_II:
496 err = parse_audio_format_ii(chip, fp, format, fmt, iface); 482 err = parse_audio_format_ii(chip, fp, format, fmt);
497 break; 483 break;
498 default: 484 default:
499 snd_printd(KERN_INFO "%d:%u:%d : format type %d is not supported yet\n", 485 snd_printd(KERN_INFO "%d:%u:%d : format type %d is not supported yet\n",
diff --git a/sound/usb/format.h b/sound/usb/format.h
index 6f315226f320..4b8a01129f24 100644
--- a/sound/usb/format.h
+++ b/sound/usb/format.h
@@ -4,6 +4,6 @@
4int snd_usb_parse_audio_format(struct snd_usb_audio *chip, 4int snd_usb_parse_audio_format(struct snd_usb_audio *chip,
5 struct audioformat *fp, unsigned int format, 5 struct audioformat *fp, unsigned int format,
6 struct uac_format_type_i_continuous_descriptor *fmt, 6 struct uac_format_type_i_continuous_descriptor *fmt,
7 int stream, struct usb_host_interface *iface); 7 int stream);
8 8
9#endif /* __USBAUDIO_FORMAT_H */ 9#endif /* __USBAUDIO_FORMAT_H */
diff --git a/sound/usb/hiface/Makefile b/sound/usb/hiface/Makefile
new file mode 100644
index 000000000000..463b136d1d89
--- /dev/null
+++ b/sound/usb/hiface/Makefile
@@ -0,0 +1,2 @@
1snd-usb-hiface-objs := chip.o pcm.o
2obj-$(CONFIG_SND_USB_HIFACE) += snd-usb-hiface.o
diff --git a/sound/usb/hiface/chip.c b/sound/usb/hiface/chip.c
new file mode 100644
index 000000000000..b0dcb3924ce5
--- /dev/null
+++ b/sound/usb/hiface/chip.c
@@ -0,0 +1,297 @@
1/*
2 * Linux driver for M2Tech hiFace compatible devices
3 *
4 * Copyright 2012-2013 (C) M2TECH S.r.l and Amarula Solutions B.V.
5 *
6 * Authors: Michael Trimarchi <michael@amarulasolutions.com>
7 * Antonio Ospite <ao2@amarulasolutions.com>
8 *
9 * The driver is based on the work done in TerraTec DMX 6Fire USB
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 */
16
17#include <linux/module.h>
18#include <linux/slab.h>
19#include <sound/initval.h>
20
21#include "chip.h"
22#include "pcm.h"
23
24MODULE_AUTHOR("Michael Trimarchi <michael@amarulasolutions.com>");
25MODULE_AUTHOR("Antonio Ospite <ao2@amarulasolutions.com>");
26MODULE_DESCRIPTION("M2Tech hiFace USB-SPDIF audio driver");
27MODULE_LICENSE("GPL v2");
28MODULE_SUPPORTED_DEVICE("{{M2Tech,Young},"
29 "{M2Tech,hiFace},"
30 "{M2Tech,North Star},"
31 "{M2Tech,W4S Young},"
32 "{M2Tech,Corrson},"
33 "{M2Tech,AUDIA},"
34 "{M2Tech,SL Audio},"
35 "{M2Tech,Empirical},"
36 "{M2Tech,Rockna},"
37 "{M2Tech,Pathos},"
38 "{M2Tech,Metronome},"
39 "{M2Tech,CAD},"
40 "{M2Tech,Audio Esclusive},"
41 "{M2Tech,Rotel},"
42 "{M2Tech,Eeaudio},"
43 "{The Chord Company,CHORD},"
44 "{AVA Group A/S,Vitus}}");
45
46static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-max */
47static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* Id for card */
48static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */
49
50#define DRIVER_NAME "snd-usb-hiface"
51#define CARD_NAME "hiFace"
52
53module_param_array(index, int, NULL, 0444);
54MODULE_PARM_DESC(index, "Index value for " CARD_NAME " soundcard.");
55module_param_array(id, charp, NULL, 0444);
56MODULE_PARM_DESC(id, "ID string for " CARD_NAME " soundcard.");
57module_param_array(enable, bool, NULL, 0444);
58MODULE_PARM_DESC(enable, "Enable " CARD_NAME " soundcard.");
59
60static DEFINE_MUTEX(register_mutex);
61
62struct hiface_vendor_quirk {
63 const char *device_name;
64 u8 extra_freq;
65};
66
67static int hiface_chip_create(struct usb_device *device, int idx,
68 const struct hiface_vendor_quirk *quirk,
69 struct hiface_chip **rchip)
70{
71 struct snd_card *card = NULL;
72 struct hiface_chip *chip;
73 int ret;
74 int len;
75
76 *rchip = NULL;
77
78 /* if we are here, card can be registered in alsa. */
79 ret = snd_card_create(index[idx], id[idx], THIS_MODULE, sizeof(*chip), &card);
80 if (ret < 0) {
81 dev_err(&device->dev, "cannot create alsa card.\n");
82 return ret;
83 }
84
85 strlcpy(card->driver, DRIVER_NAME, sizeof(card->driver));
86
87 if (quirk && quirk->device_name)
88 strlcpy(card->shortname, quirk->device_name, sizeof(card->shortname));
89 else
90 strlcpy(card->shortname, "M2Tech generic audio", sizeof(card->shortname));
91
92 strlcat(card->longname, card->shortname, sizeof(card->longname));
93 len = strlcat(card->longname, " at ", sizeof(card->longname));
94 if (len < sizeof(card->longname))
95 usb_make_path(device, card->longname + len,
96 sizeof(card->longname) - len);
97
98 chip = card->private_data;
99 chip->dev = device;
100 chip->card = card;
101
102 *rchip = chip;
103 return 0;
104}
105
106static int hiface_chip_probe(struct usb_interface *intf,
107 const struct usb_device_id *usb_id)
108{
109 const struct hiface_vendor_quirk *quirk = (struct hiface_vendor_quirk *)usb_id->driver_info;
110 int ret;
111 int i;
112 struct hiface_chip *chip;
113 struct usb_device *device = interface_to_usbdev(intf);
114
115 ret = usb_set_interface(device, 0, 0);
116 if (ret != 0) {
117 dev_err(&device->dev, "can't set first interface for " CARD_NAME " device.\n");
118 return -EIO;
119 }
120
121 /* check whether the card is already registered */
122 chip = NULL;
123 mutex_lock(&register_mutex);
124
125 for (i = 0; i < SNDRV_CARDS; i++)
126 if (enable[i])
127 break;
128
129 if (i >= SNDRV_CARDS) {
130 dev_err(&device->dev, "no available " CARD_NAME " audio device\n");
131 ret = -ENODEV;
132 goto err;
133 }
134
135 ret = hiface_chip_create(device, i, quirk, &chip);
136 if (ret < 0)
137 goto err;
138
139 snd_card_set_dev(chip->card, &intf->dev);
140
141 ret = hiface_pcm_init(chip, quirk ? quirk->extra_freq : 0);
142 if (ret < 0)
143 goto err_chip_destroy;
144
145 ret = snd_card_register(chip->card);
146 if (ret < 0) {
147 dev_err(&device->dev, "cannot register " CARD_NAME " card\n");
148 goto err_chip_destroy;
149 }
150
151 mutex_unlock(&register_mutex);
152
153 usb_set_intfdata(intf, chip);
154 return 0;
155
156err_chip_destroy:
157 snd_card_free(chip->card);
158err:
159 mutex_unlock(&register_mutex);
160 return ret;
161}
162
163static void hiface_chip_disconnect(struct usb_interface *intf)
164{
165 struct hiface_chip *chip;
166 struct snd_card *card;
167
168 chip = usb_get_intfdata(intf);
169 if (!chip)
170 return;
171
172 card = chip->card;
173
174 /* Make sure that the userspace cannot create new request */
175 snd_card_disconnect(card);
176
177 hiface_pcm_abort(chip);
178 snd_card_free_when_closed(card);
179}
180
181static const struct usb_device_id device_table[] = {
182 {
183 USB_DEVICE(0x04b4, 0x0384),
184 .driver_info = (unsigned long)&(const struct hiface_vendor_quirk) {
185 .device_name = "Young",
186 .extra_freq = 1,
187 }
188 },
189 {
190 USB_DEVICE(0x04b4, 0x930b),
191 .driver_info = (unsigned long)&(const struct hiface_vendor_quirk) {
192 .device_name = "hiFace",
193 }
194 },
195 {
196 USB_DEVICE(0x04b4, 0x931b),
197 .driver_info = (unsigned long)&(const struct hiface_vendor_quirk) {
198 .device_name = "North Star",
199 }
200 },
201 {
202 USB_DEVICE(0x04b4, 0x931c),
203 .driver_info = (unsigned long)&(const struct hiface_vendor_quirk) {
204 .device_name = "W4S Young",
205 }
206 },
207 {
208 USB_DEVICE(0x04b4, 0x931d),
209 .driver_info = (unsigned long)&(const struct hiface_vendor_quirk) {
210 .device_name = "Corrson",
211 }
212 },
213 {
214 USB_DEVICE(0x04b4, 0x931e),
215 .driver_info = (unsigned long)&(const struct hiface_vendor_quirk) {
216 .device_name = "AUDIA",
217 }
218 },
219 {
220 USB_DEVICE(0x04b4, 0x931f),
221 .driver_info = (unsigned long)&(const struct hiface_vendor_quirk) {
222 .device_name = "SL Audio",
223 }
224 },
225 {
226 USB_DEVICE(0x04b4, 0x9320),
227 .driver_info = (unsigned long)&(const struct hiface_vendor_quirk) {
228 .device_name = "Empirical",
229 }
230 },
231 {
232 USB_DEVICE(0x04b4, 0x9321),
233 .driver_info = (unsigned long)&(const struct hiface_vendor_quirk) {
234 .device_name = "Rockna",
235 }
236 },
237 {
238 USB_DEVICE(0x249c, 0x9001),
239 .driver_info = (unsigned long)&(const struct hiface_vendor_quirk) {
240 .device_name = "Pathos",
241 }
242 },
243 {
244 USB_DEVICE(0x249c, 0x9002),
245 .driver_info = (unsigned long)&(const struct hiface_vendor_quirk) {
246 .device_name = "Metronome",
247 }
248 },
249 {
250 USB_DEVICE(0x249c, 0x9006),
251 .driver_info = (unsigned long)&(const struct hiface_vendor_quirk) {
252 .device_name = "CAD",
253 }
254 },
255 {
256 USB_DEVICE(0x249c, 0x9008),
257 .driver_info = (unsigned long)&(const struct hiface_vendor_quirk) {
258 .device_name = "Audio Esclusive",
259 }
260 },
261 {
262 USB_DEVICE(0x249c, 0x931c),
263 .driver_info = (unsigned long)&(const struct hiface_vendor_quirk) {
264 .device_name = "Rotel",
265 }
266 },
267 {
268 USB_DEVICE(0x249c, 0x932c),
269 .driver_info = (unsigned long)&(const struct hiface_vendor_quirk) {
270 .device_name = "Eeaudio",
271 }
272 },
273 {
274 USB_DEVICE(0x245f, 0x931c),
275 .driver_info = (unsigned long)&(const struct hiface_vendor_quirk) {
276 .device_name = "CHORD",
277 }
278 },
279 {
280 USB_DEVICE(0x25c6, 0x9002),
281 .driver_info = (unsigned long)&(const struct hiface_vendor_quirk) {
282 .device_name = "Vitus",
283 }
284 },
285 {}
286};
287
288MODULE_DEVICE_TABLE(usb, device_table);
289
290static struct usb_driver hiface_usb_driver = {
291 .name = DRIVER_NAME,
292 .probe = hiface_chip_probe,
293 .disconnect = hiface_chip_disconnect,
294 .id_table = device_table,
295};
296
297module_usb_driver(hiface_usb_driver);
diff --git a/sound/usb/hiface/chip.h b/sound/usb/hiface/chip.h
new file mode 100644
index 000000000000..189a1371b7c4
--- /dev/null
+++ b/sound/usb/hiface/chip.h
@@ -0,0 +1,30 @@
1/*
2 * Linux driver for M2Tech hiFace compatible devices
3 *
4 * Copyright 2012-2013 (C) M2TECH S.r.l and Amarula Solutions B.V.
5 *
6 * Authors: Michael Trimarchi <michael@amarulasolutions.com>
7 * Antonio Ospite <ao2@amarulasolutions.com>
8 *
9 * The driver is based on the work done in TerraTec DMX 6Fire USB
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 */
16
17#ifndef HIFACE_CHIP_H
18#define HIFACE_CHIP_H
19
20#include <linux/usb.h>
21#include <sound/core.h>
22
23struct pcm_runtime;
24
25struct hiface_chip {
26 struct usb_device *dev;
27 struct snd_card *card;
28 struct pcm_runtime *pcm;
29};
30#endif /* HIFACE_CHIP_H */
diff --git a/sound/usb/hiface/pcm.c b/sound/usb/hiface/pcm.c
new file mode 100644
index 000000000000..6430ed2a9f65
--- /dev/null
+++ b/sound/usb/hiface/pcm.c
@@ -0,0 +1,621 @@
1/*
2 * Linux driver for M2Tech hiFace compatible devices
3 *
4 * Copyright 2012-2013 (C) M2TECH S.r.l and Amarula Solutions B.V.
5 *
6 * Authors: Michael Trimarchi <michael@amarulasolutions.com>
7 * Antonio Ospite <ao2@amarulasolutions.com>
8 *
9 * The driver is based on the work done in TerraTec DMX 6Fire USB
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 */
16
17#include <linux/slab.h>
18#include <sound/pcm.h>
19
20#include "pcm.h"
21#include "chip.h"
22
23#define OUT_EP 0x2
24#define PCM_N_URBS 8
25#define PCM_PACKET_SIZE 4096
26#define PCM_BUFFER_SIZE (2 * PCM_N_URBS * PCM_PACKET_SIZE)
27
28struct pcm_urb {
29 struct hiface_chip *chip;
30
31 struct urb instance;
32 struct usb_anchor submitted;
33 u8 *buffer;
34};
35
36struct pcm_substream {
37 spinlock_t lock;
38 struct snd_pcm_substream *instance;
39
40 bool active;
41 snd_pcm_uframes_t dma_off; /* current position in alsa dma_area */
42 snd_pcm_uframes_t period_off; /* current position in current period */
43};
44
45enum { /* pcm streaming states */
46 STREAM_DISABLED, /* no pcm streaming */
47 STREAM_STARTING, /* pcm streaming requested, waiting to become ready */
48 STREAM_RUNNING, /* pcm streaming running */
49 STREAM_STOPPING
50};
51
52struct pcm_runtime {
53 struct hiface_chip *chip;
54 struct snd_pcm *instance;
55
56 struct pcm_substream playback;
57 bool panic; /* if set driver won't do anymore pcm on device */
58
59 struct pcm_urb out_urbs[PCM_N_URBS];
60
61 struct mutex stream_mutex;
62 u8 stream_state; /* one of STREAM_XXX */
63 u8 extra_freq;
64 wait_queue_head_t stream_wait_queue;
65 bool stream_wait_cond;
66};
67
68static const unsigned int rates[] = { 44100, 48000, 88200, 96000, 176400, 192000,
69 352800, 384000 };
70static const struct snd_pcm_hw_constraint_list constraints_extra_rates = {
71 .count = ARRAY_SIZE(rates),
72 .list = rates,
73 .mask = 0,
74};
75
76static const struct snd_pcm_hardware pcm_hw = {
77 .info = SNDRV_PCM_INFO_MMAP |
78 SNDRV_PCM_INFO_INTERLEAVED |
79 SNDRV_PCM_INFO_BLOCK_TRANSFER |
80 SNDRV_PCM_INFO_PAUSE |
81 SNDRV_PCM_INFO_MMAP_VALID |
82 SNDRV_PCM_INFO_BATCH,
83
84 .formats = SNDRV_PCM_FMTBIT_S32_LE,
85
86 .rates = SNDRV_PCM_RATE_44100 |
87 SNDRV_PCM_RATE_48000 |
88 SNDRV_PCM_RATE_88200 |
89 SNDRV_PCM_RATE_96000 |
90 SNDRV_PCM_RATE_176400 |
91 SNDRV_PCM_RATE_192000,
92
93 .rate_min = 44100,
94 .rate_max = 192000, /* changes in hiface_pcm_open to support extra rates */
95 .channels_min = 2,
96 .channels_max = 2,
97 .buffer_bytes_max = PCM_BUFFER_SIZE,
98 .period_bytes_min = PCM_PACKET_SIZE,
99 .period_bytes_max = PCM_BUFFER_SIZE,
100 .periods_min = 2,
101 .periods_max = 1024
102};
103
104/* message values used to change the sample rate */
105#define HIFACE_SET_RATE_REQUEST 0xb0
106
107#define HIFACE_RATE_44100 0x43
108#define HIFACE_RATE_48000 0x4b
109#define HIFACE_RATE_88200 0x42
110#define HIFACE_RATE_96000 0x4a
111#define HIFACE_RATE_176400 0x40
112#define HIFACE_RATE_192000 0x48
113#define HIFACE_RATE_352000 0x58
114#define HIFACE_RATE_384000 0x68
115
116static int hiface_pcm_set_rate(struct pcm_runtime *rt, unsigned int rate)
117{
118 struct usb_device *device = rt->chip->dev;
119 u16 rate_value;
120 int ret;
121
122 /* We are already sure that the rate is supported here thanks to
123 * ALSA constraints
124 */
125 switch (rate) {
126 case 44100:
127 rate_value = HIFACE_RATE_44100;
128 break;
129 case 48000:
130 rate_value = HIFACE_RATE_48000;
131 break;
132 case 88200:
133 rate_value = HIFACE_RATE_88200;
134 break;
135 case 96000:
136 rate_value = HIFACE_RATE_96000;
137 break;
138 case 176400:
139 rate_value = HIFACE_RATE_176400;
140 break;
141 case 192000:
142 rate_value = HIFACE_RATE_192000;
143 break;
144 case 352000:
145 rate_value = HIFACE_RATE_352000;
146 break;
147 case 384000:
148 rate_value = HIFACE_RATE_384000;
149 break;
150 default:
151 dev_err(&device->dev, "Unsupported rate %d\n", rate);
152 return -EINVAL;
153 }
154
155 /*
156 * USBIO: Vendor 0xb0(wValue=0x0043, wIndex=0x0000)
157 * 43 b0 43 00 00 00 00 00
158 * USBIO: Vendor 0xb0(wValue=0x004b, wIndex=0x0000)
159 * 43 b0 4b 00 00 00 00 00
160 * This control message doesn't have any ack from the
161 * other side
162 */
163 ret = usb_control_msg(device, usb_sndctrlpipe(device, 0),
164 HIFACE_SET_RATE_REQUEST,
165 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_OTHER,
166 rate_value, 0, NULL, 0, 100);
167 if (ret < 0) {
168 dev_err(&device->dev, "Error setting samplerate %d.\n", rate);
169 return ret;
170 }
171
172 return 0;
173}
174
175static struct pcm_substream *hiface_pcm_get_substream(struct snd_pcm_substream
176 *alsa_sub)
177{
178 struct pcm_runtime *rt = snd_pcm_substream_chip(alsa_sub);
179 struct device *device = &rt->chip->dev->dev;
180
181 if (alsa_sub->stream == SNDRV_PCM_STREAM_PLAYBACK)
182 return &rt->playback;
183
184 dev_err(device, "Error getting pcm substream slot.\n");
185 return NULL;
186}
187
188/* call with stream_mutex locked */
189static void hiface_pcm_stream_stop(struct pcm_runtime *rt)
190{
191 int i, time;
192
193 if (rt->stream_state != STREAM_DISABLED) {
194 rt->stream_state = STREAM_STOPPING;
195
196 for (i = 0; i < PCM_N_URBS; i++) {
197 time = usb_wait_anchor_empty_timeout(
198 &rt->out_urbs[i].submitted, 100);
199 if (!time)
200 usb_kill_anchored_urbs(
201 &rt->out_urbs[i].submitted);
202 usb_kill_urb(&rt->out_urbs[i].instance);
203 }
204
205 rt->stream_state = STREAM_DISABLED;
206 }
207}
208
209/* call with stream_mutex locked */
210static int hiface_pcm_stream_start(struct pcm_runtime *rt)
211{
212 int ret = 0;
213 int i;
214
215 if (rt->stream_state == STREAM_DISABLED) {
216
217 /* reset panic state when starting a new stream */
218 rt->panic = false;
219
220 /* submit our out urbs zero init */
221 rt->stream_state = STREAM_STARTING;
222 for (i = 0; i < PCM_N_URBS; i++) {
223 memset(rt->out_urbs[i].buffer, 0, PCM_PACKET_SIZE);
224 usb_anchor_urb(&rt->out_urbs[i].instance,
225 &rt->out_urbs[i].submitted);
226 ret = usb_submit_urb(&rt->out_urbs[i].instance,
227 GFP_ATOMIC);
228 if (ret) {
229 hiface_pcm_stream_stop(rt);
230 return ret;
231 }
232 }
233
234 /* wait for first out urb to return (sent in in urb handler) */
235 wait_event_timeout(rt->stream_wait_queue, rt->stream_wait_cond,
236 HZ);
237 if (rt->stream_wait_cond) {
238 struct device *device = &rt->chip->dev->dev;
239 dev_dbg(device, "%s: Stream is running wakeup event\n",
240 __func__);
241 rt->stream_state = STREAM_RUNNING;
242 } else {
243 hiface_pcm_stream_stop(rt);
244 return -EIO;
245 }
246 }
247 return ret;
248}
249
250/* The hardware wants word-swapped 32-bit values */
251static void memcpy_swahw32(u8 *dest, u8 *src, unsigned int n)
252{
253 unsigned int i;
254
255 for (i = 0; i < n / 4; i++)
256 ((u32 *)dest)[i] = swahw32(((u32 *)src)[i]);
257}
258
259/* call with substream locked */
260/* returns true if a period elapsed */
261static bool hiface_pcm_playback(struct pcm_substream *sub, struct pcm_urb *urb)
262{
263 struct snd_pcm_runtime *alsa_rt = sub->instance->runtime;
264 struct device *device = &urb->chip->dev->dev;
265 u8 *source;
266 unsigned int pcm_buffer_size;
267
268 WARN_ON(alsa_rt->format != SNDRV_PCM_FORMAT_S32_LE);
269
270 pcm_buffer_size = snd_pcm_lib_buffer_bytes(sub->instance);
271
272 if (sub->dma_off + PCM_PACKET_SIZE <= pcm_buffer_size) {
273 dev_dbg(device, "%s: (1) buffer_size %#x dma_offset %#x\n", __func__,
274 (unsigned int) pcm_buffer_size,
275 (unsigned int) sub->dma_off);
276
277 source = alsa_rt->dma_area + sub->dma_off;
278 memcpy_swahw32(urb->buffer, source, PCM_PACKET_SIZE);
279 } else {
280 /* wrap around at end of ring buffer */
281 unsigned int len;
282
283 dev_dbg(device, "%s: (2) buffer_size %#x dma_offset %#x\n", __func__,
284 (unsigned int) pcm_buffer_size,
285 (unsigned int) sub->dma_off);
286
287 len = pcm_buffer_size - sub->dma_off;
288
289 source = alsa_rt->dma_area + sub->dma_off;
290 memcpy_swahw32(urb->buffer, source, len);
291
292 source = alsa_rt->dma_area;
293 memcpy_swahw32(urb->buffer + len, source,
294 PCM_PACKET_SIZE - len);
295 }
296 sub->dma_off += PCM_PACKET_SIZE;
297 if (sub->dma_off >= pcm_buffer_size)
298 sub->dma_off -= pcm_buffer_size;
299
300 sub->period_off += PCM_PACKET_SIZE;
301 if (sub->period_off >= alsa_rt->period_size) {
302 sub->period_off %= alsa_rt->period_size;
303 return true;
304 }
305 return false;
306}
307
308static void hiface_pcm_out_urb_handler(struct urb *usb_urb)
309{
310 struct pcm_urb *out_urb = usb_urb->context;
311 struct pcm_runtime *rt = out_urb->chip->pcm;
312 struct pcm_substream *sub;
313 bool do_period_elapsed = false;
314 unsigned long flags;
315 int ret;
316
317 if (rt->panic || rt->stream_state == STREAM_STOPPING)
318 return;
319
320 if (unlikely(usb_urb->status == -ENOENT || /* unlinked */
321 usb_urb->status == -ENODEV || /* device removed */
322 usb_urb->status == -ECONNRESET || /* unlinked */
323 usb_urb->status == -ESHUTDOWN)) { /* device disabled */
324 goto out_fail;
325 }
326
327 if (rt->stream_state == STREAM_STARTING) {
328 rt->stream_wait_cond = true;
329 wake_up(&rt->stream_wait_queue);
330 }
331
332 /* now send our playback data (if a free out urb was found) */
333 sub = &rt->playback;
334 spin_lock_irqsave(&sub->lock, flags);
335 if (sub->active)
336 do_period_elapsed = hiface_pcm_playback(sub, out_urb);
337 else
338 memset(out_urb->buffer, 0, PCM_PACKET_SIZE);
339
340 spin_unlock_irqrestore(&sub->lock, flags);
341
342 if (do_period_elapsed)
343 snd_pcm_period_elapsed(sub->instance);
344
345 ret = usb_submit_urb(&out_urb->instance, GFP_ATOMIC);
346 if (ret < 0)
347 goto out_fail;
348
349 return;
350
351out_fail:
352 rt->panic = true;
353}
354
355static int hiface_pcm_open(struct snd_pcm_substream *alsa_sub)
356{
357 struct pcm_runtime *rt = snd_pcm_substream_chip(alsa_sub);
358 struct pcm_substream *sub = NULL;
359 struct snd_pcm_runtime *alsa_rt = alsa_sub->runtime;
360 int ret;
361
362 if (rt->panic)
363 return -EPIPE;
364
365 mutex_lock(&rt->stream_mutex);
366 alsa_rt->hw = pcm_hw;
367
368 if (alsa_sub->stream == SNDRV_PCM_STREAM_PLAYBACK)
369 sub = &rt->playback;
370
371 if (!sub) {
372 struct device *device = &rt->chip->dev->dev;
373 mutex_unlock(&rt->stream_mutex);
374 dev_err(device, "Invalid stream type\n");
375 return -EINVAL;
376 }
377
378 if (rt->extra_freq) {
379 alsa_rt->hw.rates |= SNDRV_PCM_RATE_KNOT;
380 alsa_rt->hw.rate_max = 384000;
381
382 /* explicit constraints needed as we added SNDRV_PCM_RATE_KNOT */
383 ret = snd_pcm_hw_constraint_list(alsa_sub->runtime, 0,
384 SNDRV_PCM_HW_PARAM_RATE,
385 &constraints_extra_rates);
386 if (ret < 0) {
387 mutex_unlock(&rt->stream_mutex);
388 return ret;
389 }
390 }
391
392 sub->instance = alsa_sub;
393 sub->active = false;
394 mutex_unlock(&rt->stream_mutex);
395 return 0;
396}
397
398static int hiface_pcm_close(struct snd_pcm_substream *alsa_sub)
399{
400 struct pcm_runtime *rt = snd_pcm_substream_chip(alsa_sub);
401 struct pcm_substream *sub = hiface_pcm_get_substream(alsa_sub);
402 unsigned long flags;
403
404 if (rt->panic)
405 return 0;
406
407 mutex_lock(&rt->stream_mutex);
408 if (sub) {
409 hiface_pcm_stream_stop(rt);
410
411 /* deactivate substream */
412 spin_lock_irqsave(&sub->lock, flags);
413 sub->instance = NULL;
414 sub->active = false;
415 spin_unlock_irqrestore(&sub->lock, flags);
416
417 }
418 mutex_unlock(&rt->stream_mutex);
419 return 0;
420}
421
422static int hiface_pcm_hw_params(struct snd_pcm_substream *alsa_sub,
423 struct snd_pcm_hw_params *hw_params)
424{
425 return snd_pcm_lib_alloc_vmalloc_buffer(alsa_sub,
426 params_buffer_bytes(hw_params));
427}
428
429static int hiface_pcm_hw_free(struct snd_pcm_substream *alsa_sub)
430{
431 return snd_pcm_lib_free_vmalloc_buffer(alsa_sub);
432}
433
434static int hiface_pcm_prepare(struct snd_pcm_substream *alsa_sub)
435{
436 struct pcm_runtime *rt = snd_pcm_substream_chip(alsa_sub);
437 struct pcm_substream *sub = hiface_pcm_get_substream(alsa_sub);
438 struct snd_pcm_runtime *alsa_rt = alsa_sub->runtime;
439 int ret;
440
441 if (rt->panic)
442 return -EPIPE;
443 if (!sub)
444 return -ENODEV;
445
446 mutex_lock(&rt->stream_mutex);
447
448 sub->dma_off = 0;
449 sub->period_off = 0;
450
451 if (rt->stream_state == STREAM_DISABLED) {
452
453 ret = hiface_pcm_set_rate(rt, alsa_rt->rate);
454 if (ret) {
455 mutex_unlock(&rt->stream_mutex);
456 return ret;
457 }
458 ret = hiface_pcm_stream_start(rt);
459 if (ret) {
460 mutex_unlock(&rt->stream_mutex);
461 return ret;
462 }
463 }
464 mutex_unlock(&rt->stream_mutex);
465 return 0;
466}
467
468static int hiface_pcm_trigger(struct snd_pcm_substream *alsa_sub, int cmd)
469{
470 struct pcm_substream *sub = hiface_pcm_get_substream(alsa_sub);
471 struct pcm_runtime *rt = snd_pcm_substream_chip(alsa_sub);
472
473 if (rt->panic)
474 return -EPIPE;
475 if (!sub)
476 return -ENODEV;
477
478 switch (cmd) {
479 case SNDRV_PCM_TRIGGER_START:
480 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
481 spin_lock_irq(&sub->lock);
482 sub->active = true;
483 spin_unlock_irq(&sub->lock);
484 return 0;
485
486 case SNDRV_PCM_TRIGGER_STOP:
487 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
488 spin_lock_irq(&sub->lock);
489 sub->active = false;
490 spin_unlock_irq(&sub->lock);
491 return 0;
492
493 default:
494 return -EINVAL;
495 }
496}
497
498static snd_pcm_uframes_t hiface_pcm_pointer(struct snd_pcm_substream *alsa_sub)
499{
500 struct pcm_substream *sub = hiface_pcm_get_substream(alsa_sub);
501 struct pcm_runtime *rt = snd_pcm_substream_chip(alsa_sub);
502 unsigned long flags;
503 snd_pcm_uframes_t dma_offset;
504
505 if (rt->panic || !sub)
506 return SNDRV_PCM_STATE_XRUN;
507
508 spin_lock_irqsave(&sub->lock, flags);
509 dma_offset = sub->dma_off;
510 spin_unlock_irqrestore(&sub->lock, flags);
511 return bytes_to_frames(alsa_sub->runtime, dma_offset);
512}
513
514static struct snd_pcm_ops pcm_ops = {
515 .open = hiface_pcm_open,
516 .close = hiface_pcm_close,
517 .ioctl = snd_pcm_lib_ioctl,
518 .hw_params = hiface_pcm_hw_params,
519 .hw_free = hiface_pcm_hw_free,
520 .prepare = hiface_pcm_prepare,
521 .trigger = hiface_pcm_trigger,
522 .pointer = hiface_pcm_pointer,
523 .page = snd_pcm_lib_get_vmalloc_page,
524 .mmap = snd_pcm_lib_mmap_vmalloc,
525};
526
527static int hiface_pcm_init_urb(struct pcm_urb *urb,
528 struct hiface_chip *chip,
529 unsigned int ep,
530 void (*handler)(struct urb *))
531{
532 urb->chip = chip;
533 usb_init_urb(&urb->instance);
534
535 urb->buffer = kzalloc(PCM_PACKET_SIZE, GFP_KERNEL);
536 if (!urb->buffer)
537 return -ENOMEM;
538
539 usb_fill_bulk_urb(&urb->instance, chip->dev,
540 usb_sndbulkpipe(chip->dev, ep), (void *)urb->buffer,
541 PCM_PACKET_SIZE, handler, urb);
542 init_usb_anchor(&urb->submitted);
543
544 return 0;
545}
546
547void hiface_pcm_abort(struct hiface_chip *chip)
548{
549 struct pcm_runtime *rt = chip->pcm;
550
551 if (rt) {
552 rt->panic = true;
553
554 mutex_lock(&rt->stream_mutex);
555 hiface_pcm_stream_stop(rt);
556 mutex_unlock(&rt->stream_mutex);
557 }
558}
559
560static void hiface_pcm_destroy(struct hiface_chip *chip)
561{
562 struct pcm_runtime *rt = chip->pcm;
563 int i;
564
565 for (i = 0; i < PCM_N_URBS; i++)
566 kfree(rt->out_urbs[i].buffer);
567
568 kfree(chip->pcm);
569 chip->pcm = NULL;
570}
571
572static void hiface_pcm_free(struct snd_pcm *pcm)
573{
574 struct pcm_runtime *rt = pcm->private_data;
575
576 if (rt)
577 hiface_pcm_destroy(rt->chip);
578}
579
580int hiface_pcm_init(struct hiface_chip *chip, u8 extra_freq)
581{
582 int i;
583 int ret;
584 struct snd_pcm *pcm;
585 struct pcm_runtime *rt;
586
587 rt = kzalloc(sizeof(*rt), GFP_KERNEL);
588 if (!rt)
589 return -ENOMEM;
590
591 rt->chip = chip;
592 rt->stream_state = STREAM_DISABLED;
593 if (extra_freq)
594 rt->extra_freq = 1;
595
596 init_waitqueue_head(&rt->stream_wait_queue);
597 mutex_init(&rt->stream_mutex);
598 spin_lock_init(&rt->playback.lock);
599
600 for (i = 0; i < PCM_N_URBS; i++)
601 hiface_pcm_init_urb(&rt->out_urbs[i], chip, OUT_EP,
602 hiface_pcm_out_urb_handler);
603
604 ret = snd_pcm_new(chip->card, "USB-SPDIF Audio", 0, 1, 0, &pcm);
605 if (ret < 0) {
606 kfree(rt);
607 dev_err(&chip->dev->dev, "Cannot create pcm instance\n");
608 return ret;
609 }
610
611 pcm->private_data = rt;
612 pcm->private_free = hiface_pcm_free;
613
614 strlcpy(pcm->name, "USB-SPDIF Audio", sizeof(pcm->name));
615 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &pcm_ops);
616
617 rt->instance = pcm;
618
619 chip->pcm = rt;
620 return 0;
621}
diff --git a/sound/usb/hiface/pcm.h b/sound/usb/hiface/pcm.h
new file mode 100644
index 000000000000..77edd7c12e19
--- /dev/null
+++ b/sound/usb/hiface/pcm.h
@@ -0,0 +1,24 @@
1/*
2 * Linux driver for M2Tech hiFace compatible devices
3 *
4 * Copyright 2012-2013 (C) M2TECH S.r.l and Amarula Solutions B.V.
5 *
6 * Authors: Michael Trimarchi <michael@amarulasolutions.com>
7 * Antonio Ospite <ao2@amarulasolutions.com>
8 *
9 * The driver is based on the work done in TerraTec DMX 6Fire USB
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 */
16
17#ifndef HIFACE_PCM_H
18#define HIFACE_PCM_H
19
20struct hiface_chip;
21
22int hiface_pcm_init(struct hiface_chip *chip, u8 extra_freq);
23void hiface_pcm_abort(struct hiface_chip *chip);
24#endif /* HIFACE_PCM_H */
diff --git a/sound/usb/midi.c b/sound/usb/midi.c
index 8e01fa4991c5..b901f468b67a 100644
--- a/sound/usb/midi.c
+++ b/sound/usb/midi.c
@@ -1575,8 +1575,41 @@ static struct port_info {
1575 EXTERNAL_PORT(0x0582, 0x004d, 0, "%s MIDI"), 1575 EXTERNAL_PORT(0x0582, 0x004d, 0, "%s MIDI"),
1576 EXTERNAL_PORT(0x0582, 0x004d, 1, "%s 1"), 1576 EXTERNAL_PORT(0x0582, 0x004d, 1, "%s 1"),
1577 EXTERNAL_PORT(0x0582, 0x004d, 2, "%s 2"), 1577 EXTERNAL_PORT(0x0582, 0x004d, 2, "%s 2"),
1578 /* BOSS GT-PRO */
1579 CONTROL_PORT(0x0582, 0x0089, 0, "%s Control"),
1578 /* Edirol UM-3EX */ 1580 /* Edirol UM-3EX */
1579 CONTROL_PORT(0x0582, 0x009a, 3, "%s Control"), 1581 CONTROL_PORT(0x0582, 0x009a, 3, "%s Control"),
1582 /* Roland VG-99 */
1583 CONTROL_PORT(0x0582, 0x00b2, 0, "%s Control"),
1584 EXTERNAL_PORT(0x0582, 0x00b2, 1, "%s MIDI"),
1585 /* Cakewalk Sonar V-Studio 100 */
1586 EXTERNAL_PORT(0x0582, 0x00eb, 0, "%s MIDI"),
1587 CONTROL_PORT(0x0582, 0x00eb, 1, "%s Control"),
1588 /* Roland VB-99 */
1589 CONTROL_PORT(0x0582, 0x0102, 0, "%s Control"),
1590 EXTERNAL_PORT(0x0582, 0x0102, 1, "%s MIDI"),
1591 /* Roland A-PRO */
1592 EXTERNAL_PORT(0x0582, 0x010f, 0, "%s MIDI"),
1593 CONTROL_PORT(0x0582, 0x010f, 1, "%s 1"),
1594 CONTROL_PORT(0x0582, 0x010f, 2, "%s 2"),
1595 /* Roland SD-50 */
1596 ROLAND_SYNTH_PORT(0x0582, 0x0114, 0, "%s Synth", 128),
1597 EXTERNAL_PORT(0x0582, 0x0114, 1, "%s MIDI"),
1598 CONTROL_PORT(0x0582, 0x0114, 2, "%s Control"),
1599 /* Roland OCTA-CAPTURE */
1600 EXTERNAL_PORT(0x0582, 0x0120, 0, "%s MIDI"),
1601 CONTROL_PORT(0x0582, 0x0120, 1, "%s Control"),
1602 EXTERNAL_PORT(0x0582, 0x0121, 0, "%s MIDI"),
1603 CONTROL_PORT(0x0582, 0x0121, 1, "%s Control"),
1604 /* Roland SPD-SX */
1605 CONTROL_PORT(0x0582, 0x0145, 0, "%s Control"),
1606 EXTERNAL_PORT(0x0582, 0x0145, 1, "%s MIDI"),
1607 /* Roland A-Series */
1608 CONTROL_PORT(0x0582, 0x0156, 0, "%s Keyboard"),
1609 EXTERNAL_PORT(0x0582, 0x0156, 1, "%s MIDI"),
1610 /* Roland INTEGRA-7 */
1611 ROLAND_SYNTH_PORT(0x0582, 0x015b, 0, "%s Synth", 128),
1612 CONTROL_PORT(0x0582, 0x015b, 1, "%s Control"),
1580 /* M-Audio MidiSport 8x8 */ 1613 /* M-Audio MidiSport 8x8 */
1581 CONTROL_PORT(0x0763, 0x1031, 8, "%s Control"), 1614 CONTROL_PORT(0x0763, 0x1031, 8, "%s Control"),
1582 CONTROL_PORT(0x0763, 0x1033, 8, "%s Control"), 1615 CONTROL_PORT(0x0763, 0x1033, 8, "%s Control"),
@@ -1948,6 +1981,44 @@ static int snd_usbmidi_detect_yamaha(struct snd_usb_midi* umidi,
1948} 1981}
1949 1982
1950/* 1983/*
1984 * Detects the endpoints and ports of Roland devices.
1985 */
1986static int snd_usbmidi_detect_roland(struct snd_usb_midi* umidi,
1987 struct snd_usb_midi_endpoint_info* endpoint)
1988{
1989 struct usb_interface* intf;
1990 struct usb_host_interface *hostif;
1991 u8* cs_desc;
1992
1993 intf = umidi->iface;
1994 if (!intf)
1995 return -ENOENT;
1996 hostif = intf->altsetting;
1997 /*
1998 * Some devices have a descriptor <06 24 F1 02 <inputs> <outputs>>,
1999 * some have standard class descriptors, or both kinds, or neither.
2000 */
2001 for (cs_desc = hostif->extra;
2002 cs_desc < hostif->extra + hostif->extralen && cs_desc[0] >= 2;
2003 cs_desc += cs_desc[0]) {
2004 if (cs_desc[0] >= 6 &&
2005 cs_desc[1] == USB_DT_CS_INTERFACE &&
2006 cs_desc[2] == 0xf1 &&
2007 cs_desc[3] == 0x02) {
2008 endpoint->in_cables = (1 << cs_desc[4]) - 1;
2009 endpoint->out_cables = (1 << cs_desc[5]) - 1;
2010 return snd_usbmidi_detect_endpoints(umidi, endpoint, 1);
2011 } else if (cs_desc[0] >= 7 &&
2012 cs_desc[1] == USB_DT_CS_INTERFACE &&
2013 cs_desc[2] == UAC_HEADER) {
2014 return snd_usbmidi_get_ms_info(umidi, endpoint);
2015 }
2016 }
2017
2018 return -ENODEV;
2019}
2020
2021/*
1951 * Creates the endpoints and their ports for Midiman devices. 2022 * Creates the endpoints and their ports for Midiman devices.
1952 */ 2023 */
1953static int snd_usbmidi_create_endpoints_midiman(struct snd_usb_midi* umidi, 2024static int snd_usbmidi_create_endpoints_midiman(struct snd_usb_midi* umidi,
@@ -2162,6 +2233,9 @@ int snd_usbmidi_create(struct snd_card *card,
2162 case QUIRK_MIDI_YAMAHA: 2233 case QUIRK_MIDI_YAMAHA:
2163 err = snd_usbmidi_detect_yamaha(umidi, &endpoints[0]); 2234 err = snd_usbmidi_detect_yamaha(umidi, &endpoints[0]);
2164 break; 2235 break;
2236 case QUIRK_MIDI_ROLAND:
2237 err = snd_usbmidi_detect_roland(umidi, &endpoints[0]);
2238 break;
2165 case QUIRK_MIDI_MIDIMAN: 2239 case QUIRK_MIDI_MIDIMAN:
2166 umidi->usb_protocol_ops = &snd_usbmidi_midiman_ops; 2240 umidi->usb_protocol_ops = &snd_usbmidi_midiman_ops;
2167 memcpy(&endpoints[0], quirk->data, 2241 memcpy(&endpoints[0], quirk->data,
diff --git a/sound/usb/misc/ua101.c b/sound/usb/misc/ua101.c
index 6ad617b94732..8b5d2c564e04 100644
--- a/sound/usb/misc/ua101.c
+++ b/sound/usb/misc/ua101.c
@@ -1349,7 +1349,7 @@ static void ua101_disconnect(struct usb_interface *interface)
1349 snd_card_disconnect(ua->card); 1349 snd_card_disconnect(ua->card);
1350 1350
1351 /* make sure that there are no pending USB requests */ 1351 /* make sure that there are no pending USB requests */
1352 __list_for_each(midi, &ua->midi_list) 1352 list_for_each(midi, &ua->midi_list)
1353 snd_usbmidi_disconnect(midi); 1353 snd_usbmidi_disconnect(midi);
1354 abort_alsa_playback(ua); 1354 abort_alsa_playback(ua);
1355 abort_alsa_capture(ua); 1355 abort_alsa_capture(ua);
diff --git a/sound/usb/mixer_quirks.c b/sound/usb/mixer_quirks.c
index ebe91440a068..d42a584cf829 100644
--- a/sound/usb/mixer_quirks.c
+++ b/sound/usb/mixer_quirks.c
@@ -9,6 +9,8 @@
9 * Alan Cox (alan@lxorguk.ukuu.org.uk) 9 * Alan Cox (alan@lxorguk.ukuu.org.uk)
10 * Thomas Sailer (sailer@ife.ee.ethz.ch) 10 * Thomas Sailer (sailer@ife.ee.ethz.ch)
11 * 11 *
12 * Audio Advantage Micro II support added by:
13 * Przemek Rudy (prudy1@o2.pl)
12 * 14 *
13 * This program is free software; you can redistribute it and/or modify 15 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by 16 * it under the terms of the GNU General Public License as published by
@@ -30,6 +32,7 @@
30#include <linux/usb.h> 32#include <linux/usb.h>
31#include <linux/usb/audio.h> 33#include <linux/usb/audio.h>
32 34
35#include <sound/asoundef.h>
33#include <sound/core.h> 36#include <sound/core.h>
34#include <sound/control.h> 37#include <sound/control.h>
35#include <sound/hwdep.h> 38#include <sound/hwdep.h>
@@ -1315,6 +1318,211 @@ static struct std_mono_table ebox44_table[] = {
1315 {} 1318 {}
1316}; 1319};
1317 1320
1321/* Audio Advantage Micro II findings:
1322 *
1323 * Mapping spdif AES bits to vendor register.bit:
1324 * AES0: [0 0 0 0 2.3 2.2 2.1 2.0] - default 0x00
1325 * AES1: [3.3 3.2.3.1.3.0 2.7 2.6 2.5 2.4] - default: 0x01
1326 * AES2: [0 0 0 0 0 0 0 0]
1327 * AES3: [0 0 0 0 0 0 x 0] - 'x' bit is set basing on standard usb request
1328 * (UAC_EP_CS_ATTR_SAMPLE_RATE) for Audio Devices
1329 *
1330 * power on values:
1331 * r2: 0x10
1332 * r3: 0x20 (b7 is zeroed just before playback (except IEC61937) and set
1333 * just after it to 0xa0, presumably it disables/mutes some analog
1334 * parts when there is no audio.)
1335 * r9: 0x28
1336 *
1337 * Optical transmitter on/off:
1338 * vendor register.bit: 9.1
1339 * 0 - on (0x28 register value)
1340 * 1 - off (0x2a register value)
1341 *
1342 */
1343static int snd_microii_spdif_info(struct snd_kcontrol *kcontrol,
1344 struct snd_ctl_elem_info *uinfo)
1345{
1346 uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
1347 uinfo->count = 1;
1348 return 0;
1349}
1350
1351static int snd_microii_spdif_default_get(struct snd_kcontrol *kcontrol,
1352 struct snd_ctl_elem_value *ucontrol)
1353{
1354 struct usb_mixer_interface *mixer = snd_kcontrol_chip(kcontrol);
1355 int err;
1356 struct usb_interface *iface;
1357 struct usb_host_interface *alts;
1358 unsigned int ep;
1359 unsigned char data[3];
1360 int rate;
1361
1362 ucontrol->value.iec958.status[0] = kcontrol->private_value & 0xff;
1363 ucontrol->value.iec958.status[1] = (kcontrol->private_value >> 8) & 0xff;
1364 ucontrol->value.iec958.status[2] = 0x00;
1365
1366 /* use known values for that card: interface#1 altsetting#1 */
1367 iface = usb_ifnum_to_if(mixer->chip->dev, 1);
1368 alts = &iface->altsetting[1];
1369 ep = get_endpoint(alts, 0)->bEndpointAddress;
1370
1371 err = snd_usb_ctl_msg(mixer->chip->dev,
1372 usb_rcvctrlpipe(mixer->chip->dev, 0),
1373 UAC_GET_CUR,
1374 USB_TYPE_CLASS | USB_RECIP_ENDPOINT | USB_DIR_IN,
1375 UAC_EP_CS_ATTR_SAMPLE_RATE << 8,
1376 ep,
1377 data,
1378 sizeof(data));
1379 if (err < 0)
1380 goto end;
1381
1382 rate = data[0] | (data[1] << 8) | (data[2] << 16);
1383 ucontrol->value.iec958.status[3] = (rate == 48000) ?
1384 IEC958_AES3_CON_FS_48000 : IEC958_AES3_CON_FS_44100;
1385
1386 err = 0;
1387end:
1388 return err;
1389}
1390
1391static int snd_microii_spdif_default_put(struct snd_kcontrol *kcontrol,
1392 struct snd_ctl_elem_value *ucontrol)
1393{
1394 struct usb_mixer_interface *mixer = snd_kcontrol_chip(kcontrol);
1395 int err;
1396 u8 reg;
1397 unsigned long priv_backup = kcontrol->private_value;
1398
1399 reg = ((ucontrol->value.iec958.status[1] & 0x0f) << 4) |
1400 (ucontrol->value.iec958.status[0] & 0x0f);
1401 err = snd_usb_ctl_msg(mixer->chip->dev,
1402 usb_sndctrlpipe(mixer->chip->dev, 0),
1403 UAC_SET_CUR,
1404 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_OTHER,
1405 reg,
1406 2,
1407 NULL,
1408 0);
1409 if (err < 0)
1410 goto end;
1411
1412 kcontrol->private_value &= 0xfffff0f0;
1413 kcontrol->private_value |= (ucontrol->value.iec958.status[1] & 0x0f) << 8;
1414 kcontrol->private_value |= (ucontrol->value.iec958.status[0] & 0x0f);
1415
1416 reg = (ucontrol->value.iec958.status[0] & IEC958_AES0_NONAUDIO) ?
1417 0xa0 : 0x20;
1418 reg |= (ucontrol->value.iec958.status[1] >> 4) & 0x0f;
1419 err = snd_usb_ctl_msg(mixer->chip->dev,
1420 usb_sndctrlpipe(mixer->chip->dev, 0),
1421 UAC_SET_CUR,
1422 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_OTHER,
1423 reg,
1424 3,
1425 NULL,
1426 0);
1427 if (err < 0)
1428 goto end;
1429
1430 kcontrol->private_value &= 0xffff0fff;
1431 kcontrol->private_value |= (ucontrol->value.iec958.status[1] & 0xf0) << 8;
1432
1433 /* The frequency bits in AES3 cannot be set via register access. */
1434
1435 /* Silently ignore any bits from the request that cannot be set. */
1436
1437 err = (priv_backup != kcontrol->private_value);
1438end:
1439 return err;
1440}
1441
1442static int snd_microii_spdif_mask_get(struct snd_kcontrol *kcontrol,
1443 struct snd_ctl_elem_value *ucontrol)
1444{
1445 ucontrol->value.iec958.status[0] = 0x0f;
1446 ucontrol->value.iec958.status[1] = 0xff;
1447 ucontrol->value.iec958.status[2] = 0x00;
1448 ucontrol->value.iec958.status[3] = 0x00;
1449
1450 return 0;
1451}
1452
1453static int snd_microii_spdif_switch_get(struct snd_kcontrol *kcontrol,
1454 struct snd_ctl_elem_value *ucontrol)
1455{
1456 ucontrol->value.integer.value[0] = !(kcontrol->private_value & 0x02);
1457
1458 return 0;
1459}
1460
1461static int snd_microii_spdif_switch_put(struct snd_kcontrol *kcontrol,
1462 struct snd_ctl_elem_value *ucontrol)
1463{
1464 struct usb_mixer_interface *mixer = snd_kcontrol_chip(kcontrol);
1465 int err;
1466 u8 reg = ucontrol->value.integer.value[0] ? 0x28 : 0x2a;
1467
1468 err = snd_usb_ctl_msg(mixer->chip->dev,
1469 usb_sndctrlpipe(mixer->chip->dev, 0),
1470 UAC_SET_CUR,
1471 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_OTHER,
1472 reg,
1473 9,
1474 NULL,
1475 0);
1476
1477 if (!err) {
1478 err = (reg != (kcontrol->private_value & 0x0ff));
1479 if (err)
1480 kcontrol->private_value = reg;
1481 }
1482
1483 return err;
1484}
1485
1486static struct snd_kcontrol_new snd_microii_mixer_spdif[] = {
1487 {
1488 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
1489 .name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, DEFAULT),
1490 .info = snd_microii_spdif_info,
1491 .get = snd_microii_spdif_default_get,
1492 .put = snd_microii_spdif_default_put,
1493 .private_value = 0x00000100UL,/* reset value */
1494 },
1495 {
1496 .access = SNDRV_CTL_ELEM_ACCESS_READ,
1497 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
1498 .name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, MASK),
1499 .info = snd_microii_spdif_info,
1500 .get = snd_microii_spdif_mask_get,
1501 },
1502 {
1503 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1504 .name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, SWITCH),
1505 .info = snd_ctl_boolean_mono_info,
1506 .get = snd_microii_spdif_switch_get,
1507 .put = snd_microii_spdif_switch_put,
1508 .private_value = 0x00000028UL,/* reset value */
1509 }
1510};
1511
1512static int snd_microii_controls_create(struct usb_mixer_interface *mixer)
1513{
1514 int err, i;
1515
1516 for (i = 0; i < ARRAY_SIZE(snd_microii_mixer_spdif); ++i) {
1517 err = snd_ctl_add(mixer->chip->card,
1518 snd_ctl_new1(&snd_microii_mixer_spdif[i], mixer));
1519 if (err < 0)
1520 return err;
1521 }
1522
1523 return err;
1524}
1525
1318int snd_usb_mixer_apply_create_quirk(struct usb_mixer_interface *mixer) 1526int snd_usb_mixer_apply_create_quirk(struct usb_mixer_interface *mixer)
1319{ 1527{
1320 int err = 0; 1528 int err = 0;
@@ -1353,6 +1561,10 @@ int snd_usb_mixer_apply_create_quirk(struct usb_mixer_interface *mixer)
1353 err = snd_xonar_u1_controls_create(mixer); 1561 err = snd_xonar_u1_controls_create(mixer);
1354 break; 1562 break;
1355 1563
1564 case USB_ID(0x0d8c, 0x0103): /* Audio Advantage Micro II */
1565 err = snd_microii_controls_create(mixer);
1566 break;
1567
1356 case USB_ID(0x17cc, 0x1011): /* Traktor Audio 6 */ 1568 case USB_ID(0x17cc, 0x1011): /* Traktor Audio 6 */
1357 err = snd_nativeinstruments_create_mixer(mixer, 1569 err = snd_nativeinstruments_create_mixer(mixer,
1358 snd_nativeinstruments_ta6_mixers, 1570 snd_nativeinstruments_ta6_mixers,
diff --git a/sound/usb/pcm.c b/sound/usb/pcm.c
index 93b6e32cfead..15b151ed4899 100644
--- a/sound/usb/pcm.c
+++ b/sound/usb/pcm.c
@@ -202,13 +202,11 @@ int snd_usb_init_pitch(struct snd_usb_audio *chip, int iface,
202 struct usb_host_interface *alts, 202 struct usb_host_interface *alts,
203 struct audioformat *fmt) 203 struct audioformat *fmt)
204{ 204{
205 struct usb_interface_descriptor *altsd = get_iface_desc(alts);
206
207 /* if endpoint doesn't have pitch control, bail out */ 205 /* if endpoint doesn't have pitch control, bail out */
208 if (!(fmt->attributes & UAC_EP_CS_ATTR_PITCH_CONTROL)) 206 if (!(fmt->attributes & UAC_EP_CS_ATTR_PITCH_CONTROL))
209 return 0; 207 return 0;
210 208
211 switch (altsd->bInterfaceProtocol) { 209 switch (fmt->protocol) {
212 case UAC_VERSION_1: 210 case UAC_VERSION_1:
213 default: 211 default:
214 return init_pitch_v1(chip, iface, alts, fmt); 212 return init_pitch_v1(chip, iface, alts, fmt);
@@ -300,6 +298,35 @@ static int deactivate_endpoints(struct snd_usb_substream *subs)
300 return 0; 298 return 0;
301} 299}
302 300
301static int search_roland_implicit_fb(struct usb_device *dev, int ifnum,
302 unsigned int altsetting,
303 struct usb_host_interface **alts,
304 unsigned int *ep)
305{
306 struct usb_interface *iface;
307 struct usb_interface_descriptor *altsd;
308 struct usb_endpoint_descriptor *epd;
309
310 iface = usb_ifnum_to_if(dev, ifnum);
311 if (!iface || iface->num_altsetting < altsetting + 1)
312 return -ENOENT;
313 *alts = &iface->altsetting[altsetting];
314 altsd = get_iface_desc(*alts);
315 if (altsd->bAlternateSetting != altsetting ||
316 altsd->bInterfaceClass != USB_CLASS_VENDOR_SPEC ||
317 (altsd->bInterfaceSubClass != 2 &&
318 altsd->bInterfaceProtocol != 2 ) ||
319 altsd->bNumEndpoints < 1)
320 return -ENOENT;
321 epd = get_endpoint(*alts, 0);
322 if (!usb_endpoint_is_isoc_in(epd) ||
323 (epd->bmAttributes & USB_ENDPOINT_USAGE_MASK) !=
324 USB_ENDPOINT_USAGE_IMPLICIT_FB)
325 return -ENOENT;
326 *ep = epd->bEndpointAddress;
327 return 0;
328}
329
303/* 330/*
304 * find a matching format and set up the interface 331 * find a matching format and set up the interface
305 */ 332 */
@@ -395,6 +422,18 @@ static int set_format(struct snd_usb_substream *subs, struct audioformat *fmt)
395 goto add_sync_ep; 422 goto add_sync_ep;
396 } 423 }
397 } 424 }
425 if (is_playback &&
426 attr == USB_ENDPOINT_SYNC_ASYNC &&
427 altsd->bInterfaceClass == USB_CLASS_VENDOR_SPEC &&
428 altsd->bInterfaceProtocol == 2 &&
429 altsd->bNumEndpoints == 1 &&
430 USB_ID_VENDOR(subs->stream->chip->usb_id) == 0x0582 /* Roland */ &&
431 search_roland_implicit_fb(dev, altsd->bInterfaceNumber + 1,
432 altsd->bAlternateSetting,
433 &alts, &ep) >= 0) {
434 implicit_fb = 1;
435 goto add_sync_ep;
436 }
398 437
399 if (((is_playback && attr == USB_ENDPOINT_SYNC_ASYNC) || 438 if (((is_playback && attr == USB_ENDPOINT_SYNC_ASYNC) ||
400 (!is_playback && attr == USB_ENDPOINT_SYNC_ADAPTIVE)) && 439 (!is_playback && attr == USB_ENDPOINT_SYNC_ADAPTIVE)) &&
diff --git a/sound/usb/quirks-table.h b/sound/usb/quirks-table.h
index 8b75bcf136f6..f5f0595ef9c7 100644
--- a/sound/usb/quirks-table.h
+++ b/sound/usb/quirks-table.h
@@ -461,6 +461,17 @@ YAMAHA_DEVICE(0x7000, "DTX"),
461YAMAHA_DEVICE(0x7010, "UB99"), 461YAMAHA_DEVICE(0x7010, "UB99"),
462#undef YAMAHA_DEVICE 462#undef YAMAHA_DEVICE
463#undef YAMAHA_INTERFACE 463#undef YAMAHA_INTERFACE
464/* this catches most recent vendor-specific Yamaha devices */
465{
466 .match_flags = USB_DEVICE_ID_MATCH_VENDOR |
467 USB_DEVICE_ID_MATCH_INT_CLASS,
468 .idVendor = 0x0499,
469 .bInterfaceClass = USB_CLASS_VENDOR_SPEC,
470 .driver_info = (unsigned long) &(const struct snd_usb_audio_quirk) {
471 .ifnum = QUIRK_ANY_INTERFACE,
472 .type = QUIRK_AUTODETECT
473 }
474},
464 475
465/* 476/*
466 * Roland/RolandED/Edirol/BOSS devices 477 * Roland/RolandED/Edirol/BOSS devices
@@ -1136,7 +1147,6 @@ YAMAHA_DEVICE(0x7010, "UB99"),
1136 } 1147 }
1137 } 1148 }
1138}, 1149},
1139 /* TODO: add Roland M-1000 support */
1140{ 1150{
1141 /* 1151 /*
1142 * Has ID 0x0038 when not in "Advanced Driver" mode; 1152 * Has ID 0x0038 when not in "Advanced Driver" mode;
@@ -1251,7 +1261,6 @@ YAMAHA_DEVICE(0x7010, "UB99"),
1251 } 1261 }
1252 } 1262 }
1253}, 1263},
1254 /* TODO: add Edirol M-100FX support */
1255{ 1264{
1256 /* has ID 0x004e when not in "Advanced Driver" mode */ 1265 /* has ID 0x004e when not in "Advanced Driver" mode */
1257 USB_DEVICE(0x0582, 0x004c), 1266 USB_DEVICE(0x0582, 0x004c),
@@ -1371,20 +1380,6 @@ YAMAHA_DEVICE(0x7010, "UB99"),
1371 } 1380 }
1372}, 1381},
1373{ 1382{
1374 /* has ID 0x006b when not in "Advanced Driver" mode */
1375 USB_DEVICE_VENDOR_SPEC(0x0582, 0x006a),
1376 .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
1377 .vendor_name = "Roland",
1378 .product_name = "SP-606",
1379 .ifnum = 3,
1380 .type = QUIRK_MIDI_FIXED_ENDPOINT,
1381 .data = & (const struct snd_usb_midi_endpoint_info) {
1382 .out_cables = 0x0001,
1383 .in_cables = 0x0001
1384 }
1385 }
1386},
1387{
1388 /* has ID 0x006e when not in "Advanced Driver" mode */ 1383 /* has ID 0x006e when not in "Advanced Driver" mode */
1389 USB_DEVICE(0x0582, 0x006d), 1384 USB_DEVICE(0x0582, 0x006d),
1390 .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) { 1385 .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
@@ -1471,8 +1466,6 @@ YAMAHA_DEVICE(0x7010, "UB99"),
1471 } 1466 }
1472 } 1467 }
1473}, 1468},
1474 /* TODO: add Roland V-SYNTH XT support */
1475 /* TODO: add BOSS GT-PRO support */
1476{ 1469{
1477 /* has ID 0x008c when not in "Advanced Driver" mode */ 1470 /* has ID 0x008c when not in "Advanced Driver" mode */
1478 USB_DEVICE(0x0582, 0x008b), 1471 USB_DEVICE(0x0582, 0x008b),
@@ -1487,42 +1480,6 @@ YAMAHA_DEVICE(0x7010, "UB99"),
1487 } 1480 }
1488 } 1481 }
1489}, 1482},
1490 /* TODO: add Edirol PC-80 support */
1491{
1492 USB_DEVICE(0x0582, 0x0096),
1493 .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
1494 .vendor_name = "EDIROL",
1495 .product_name = "UA-1EX",
1496 .ifnum = QUIRK_ANY_INTERFACE,
1497 .type = QUIRK_COMPOSITE,
1498 .data = (const struct snd_usb_audio_quirk[]) {
1499 {
1500 .ifnum = 0,
1501 .type = QUIRK_AUDIO_STANDARD_INTERFACE
1502 },
1503 {
1504 .ifnum = 1,
1505 .type = QUIRK_AUDIO_STANDARD_INTERFACE
1506 },
1507 {
1508 .ifnum = -1
1509 }
1510 }
1511 }
1512},
1513{
1514 USB_DEVICE(0x0582, 0x009a),
1515 .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
1516 .vendor_name = "EDIROL",
1517 .product_name = "UM-3EX",
1518 .ifnum = 0,
1519 .type = QUIRK_MIDI_FIXED_ENDPOINT,
1520 .data = & (const struct snd_usb_midi_endpoint_info) {
1521 .out_cables = 0x000f,
1522 .in_cables = 0x000f
1523 }
1524 }
1525},
1526{ 1483{
1527 /* 1484 /*
1528 * This quirk is for the "Advanced Driver" mode. If off, the UA-4FX 1485 * This quirk is for the "Advanced Driver" mode. If off, the UA-4FX
@@ -1553,124 +1510,8 @@ YAMAHA_DEVICE(0x7010, "UB99"),
1553 } 1510 }
1554 } 1511 }
1555}, 1512},
1556 /* TODO: add Edirol MD-P1 support */
1557{
1558 USB_DEVICE(0x582, 0x00a6),
1559 .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
1560 .vendor_name = "Roland",
1561 .product_name = "Juno-G",
1562 .ifnum = 0,
1563 .type = QUIRK_MIDI_FIXED_ENDPOINT,
1564 .data = & (const struct snd_usb_midi_endpoint_info) {
1565 .out_cables = 0x0001,
1566 .in_cables = 0x0001
1567 }
1568 }
1569},
1570{
1571 /* Roland SH-201 */
1572 USB_DEVICE(0x0582, 0x00ad),
1573 .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
1574 .vendor_name = "Roland",
1575 .product_name = "SH-201",
1576 .ifnum = QUIRK_ANY_INTERFACE,
1577 .type = QUIRK_COMPOSITE,
1578 .data = (const struct snd_usb_audio_quirk[]) {
1579 {
1580 .ifnum = 0,
1581 .type = QUIRK_AUDIO_STANDARD_INTERFACE
1582 },
1583 {
1584 .ifnum = 1,
1585 .type = QUIRK_AUDIO_STANDARD_INTERFACE
1586 },
1587 {
1588 .ifnum = 2,
1589 .type = QUIRK_MIDI_FIXED_ENDPOINT,
1590 .data = & (const struct snd_usb_midi_endpoint_info) {
1591 .out_cables = 0x0001,
1592 .in_cables = 0x0001
1593 }
1594 },
1595 {
1596 .ifnum = -1
1597 }
1598 }
1599 }
1600},
1601{
1602 /* Advanced mode of the Roland VG-99, with MIDI and 24-bit PCM at 44.1
1603 * kHz. In standard mode, the device has ID 0582:00b3, and offers
1604 * 16-bit PCM at 44.1 kHz with no MIDI.
1605 */
1606 USB_DEVICE(0x0582, 0x00b2),
1607 .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
1608 .vendor_name = "Roland",
1609 .product_name = "VG-99",
1610 .ifnum = QUIRK_ANY_INTERFACE,
1611 .type = QUIRK_COMPOSITE,
1612 .data = (const struct snd_usb_audio_quirk[]) {
1613 {
1614 .ifnum = 0,
1615 .type = QUIRK_AUDIO_STANDARD_INTERFACE
1616 },
1617 {
1618 .ifnum = 1,
1619 .type = QUIRK_AUDIO_STANDARD_INTERFACE
1620 },
1621 {
1622 .ifnum = 2,
1623 .type = QUIRK_MIDI_FIXED_ENDPOINT,
1624 .data = & (const struct snd_usb_midi_endpoint_info) {
1625 .out_cables = 0x0003,
1626 .in_cables = 0x0003
1627 }
1628 },
1629 {
1630 .ifnum = -1
1631 }
1632 }
1633 }
1634},
1635{
1636 /* Roland SonicCell */
1637 USB_DEVICE(0x0582, 0x00c2),
1638 .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
1639 .vendor_name = "Roland",
1640 .product_name = "SonicCell",
1641 .ifnum = QUIRK_ANY_INTERFACE,
1642 .type = QUIRK_COMPOSITE,
1643 .data = (const struct snd_usb_audio_quirk[]) {
1644 {
1645 .ifnum = 0,
1646 .type = QUIRK_AUDIO_STANDARD_INTERFACE
1647 },
1648 {
1649 .ifnum = 1,
1650 .type = QUIRK_AUDIO_STANDARD_INTERFACE
1651 },
1652 {
1653 .ifnum = 2,
1654 .type = QUIRK_MIDI_FIXED_ENDPOINT,
1655 .data = & (const struct snd_usb_midi_endpoint_info) {
1656 .out_cables = 0x0001,
1657 .in_cables = 0x0001
1658 }
1659 },
1660 {
1661 .ifnum = -1
1662 }
1663 }
1664 }
1665},
1666{ 1513{
1667 /* Edirol M-16DX */ 1514 /* Edirol M-16DX */
1668 /* FIXME: This quirk gives a good-working capture stream but the
1669 * playback seems problematic because of lacking of sync
1670 * with capture stream. It needs to sync with the capture
1671 * clock. As now, you'll get frequent sound distortions
1672 * via the playback.
1673 */
1674 USB_DEVICE(0x0582, 0x00c4), 1515 USB_DEVICE(0x0582, 0x00c4),
1675 .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) { 1516 .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
1676 .ifnum = QUIRK_ANY_INTERFACE, 1517 .ifnum = QUIRK_ANY_INTERFACE,
@@ -1699,35 +1540,6 @@ YAMAHA_DEVICE(0x7010, "UB99"),
1699 } 1540 }
1700}, 1541},
1701{ 1542{
1702 /* BOSS GT-10 */
1703 USB_DEVICE(0x0582, 0x00da),
1704 .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
1705 .ifnum = QUIRK_ANY_INTERFACE,
1706 .type = QUIRK_COMPOSITE,
1707 .data = (const struct snd_usb_audio_quirk[]) {
1708 {
1709 .ifnum = 0,
1710 .type = QUIRK_AUDIO_STANDARD_INTERFACE
1711 },
1712 {
1713 .ifnum = 1,
1714 .type = QUIRK_AUDIO_STANDARD_INTERFACE
1715 },
1716 {
1717 .ifnum = 2,
1718 .type = QUIRK_MIDI_FIXED_ENDPOINT,
1719 .data = & (const struct snd_usb_midi_endpoint_info) {
1720 .out_cables = 0x0001,
1721 .in_cables = 0x0001
1722 }
1723 },
1724 {
1725 .ifnum = -1
1726 }
1727 }
1728 }
1729},
1730{
1731 /* Advanced modes of the Edirol UA-25EX. 1543 /* Advanced modes of the Edirol UA-25EX.
1732 * For the standard mode, UA-25EX has ID 0582:00e7, which 1544 * For the standard mode, UA-25EX has ID 0582:00e7, which
1733 * offers only 16-bit PCM at 44.1 kHz and no MIDI. 1545 * offers only 16-bit PCM at 44.1 kHz and no MIDI.
@@ -1758,42 +1570,6 @@ YAMAHA_DEVICE(0x7010, "UB99"),
1758 } 1570 }
1759}, 1571},
1760{ 1572{
1761 /* has ID 0x00ea when not in Advanced Driver mode */
1762 USB_DEVICE_VENDOR_SPEC(0x0582, 0x00e9),
1763 .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
1764 /* .vendor_name = "Roland", */
1765 /* .product_name = "UA-1G", */
1766 .ifnum = QUIRK_ANY_INTERFACE,
1767 .type = QUIRK_COMPOSITE,
1768 .data = (const struct snd_usb_audio_quirk[]) {
1769 {
1770 .ifnum = 0,
1771 .type = QUIRK_AUDIO_STANDARD_INTERFACE
1772 },
1773 {
1774 .ifnum = 1,
1775 .type = QUIRK_AUDIO_STANDARD_INTERFACE
1776 },
1777 {
1778 .ifnum = -1
1779 }
1780 }
1781 }
1782},
1783{
1784 USB_DEVICE_VENDOR_SPEC(0x0582, 0x0104),
1785 .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
1786 /* .vendor_name = "Roland", */
1787 /* .product_name = "UM-1G", */
1788 .ifnum = 0,
1789 .type = QUIRK_MIDI_FIXED_ENDPOINT,
1790 .data = & (const struct snd_usb_midi_endpoint_info) {
1791 .out_cables = 0x0001,
1792 .in_cables = 0x0001
1793 }
1794 }
1795},
1796{
1797 /* Edirol UM-3G */ 1573 /* Edirol UM-3G */
1798 USB_DEVICE_VENDOR_SPEC(0x0582, 0x0108), 1574 USB_DEVICE_VENDOR_SPEC(0x0582, 0x0108),
1799 .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) { 1575 .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
@@ -1806,92 +1582,49 @@ YAMAHA_DEVICE(0x7010, "UB99"),
1806 } 1582 }
1807}, 1583},
1808{ 1584{
1809 /* Boss JS-8 Jam Station */ 1585 /* only 44.1 kHz works at the moment */
1810 USB_DEVICE(0x0582, 0x0109), 1586 USB_DEVICE(0x0582, 0x0120),
1811 .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
1812 /* .vendor_name = "BOSS", */
1813 /* .product_name = "JS-8", */
1814 .ifnum = QUIRK_ANY_INTERFACE,
1815 .type = QUIRK_COMPOSITE,
1816 .data = (const struct snd_usb_audio_quirk[]) {
1817 {
1818 .ifnum = 0,
1819 .type = QUIRK_AUDIO_STANDARD_INTERFACE
1820 },
1821 {
1822 .ifnum = 1,
1823 .type = QUIRK_AUDIO_STANDARD_INTERFACE
1824 },
1825 {
1826 .ifnum = 2,
1827 .type = QUIRK_MIDI_STANDARD_INTERFACE
1828 },
1829 {
1830 .ifnum = -1
1831 }
1832 }
1833 }
1834},
1835{
1836 /* has ID 0x0110 when not in Advanced Driver mode */
1837 USB_DEVICE_VENDOR_SPEC(0x0582, 0x010f),
1838 .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) { 1587 .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
1839 /* .vendor_name = "Roland", */ 1588 /* .vendor_name = "Roland", */
1840 /* .product_name = "A-PRO", */ 1589 /* .product_name = "OCTO-CAPTURE", */
1841 .ifnum = 0,
1842 .type = QUIRK_MIDI_FIXED_ENDPOINT,
1843 .data = & (const struct snd_usb_midi_endpoint_info) {
1844 .out_cables = 0x0003,
1845 .in_cables = 0x0007
1846 }
1847 }
1848},
1849{
1850 /* Roland GAIA SH-01 */
1851 USB_DEVICE(0x0582, 0x0111),
1852 .driver_info = (unsigned long) &(const struct snd_usb_audio_quirk) {
1853 .vendor_name = "Roland",
1854 .product_name = "GAIA",
1855 .ifnum = QUIRK_ANY_INTERFACE, 1590 .ifnum = QUIRK_ANY_INTERFACE,
1856 .type = QUIRK_COMPOSITE, 1591 .type = QUIRK_COMPOSITE,
1857 .data = (const struct snd_usb_audio_quirk[]) { 1592 .data = (const struct snd_usb_audio_quirk[]) {
1858 { 1593 {
1859 .ifnum = 0, 1594 .ifnum = 0,
1860 .type = QUIRK_AUDIO_STANDARD_INTERFACE 1595 .type = QUIRK_AUDIO_FIXED_ENDPOINT,
1861 }, 1596 .data = & (const struct audioformat) {
1862 { 1597 .formats = SNDRV_PCM_FMTBIT_S32_LE,
1863 .ifnum = 1, 1598 .channels = 10,
1864 .type = QUIRK_AUDIO_STANDARD_INTERFACE 1599 .iface = 0,
1865 }, 1600 .altsetting = 1,
1866 { 1601 .altset_idx = 1,
1867 .ifnum = 2, 1602 .endpoint = 0x05,
1868 .type = QUIRK_MIDI_FIXED_ENDPOINT, 1603 .ep_attr = 0x05,
1869 .data = &(const struct snd_usb_midi_endpoint_info) { 1604 .rates = SNDRV_PCM_RATE_44100,
1870 .out_cables = 0x0003, 1605 .rate_min = 44100,
1871 .in_cables = 0x0003 1606 .rate_max = 44100,
1607 .nr_rates = 1,
1608 .rate_table = (unsigned int[]) { 44100 }
1872 } 1609 }
1873 }, 1610 },
1874 { 1611 {
1875 .ifnum = -1
1876 }
1877 }
1878 }
1879},
1880{
1881 USB_DEVICE(0x0582, 0x0113),
1882 .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
1883 /* .vendor_name = "BOSS", */
1884 /* .product_name = "ME-25", */
1885 .ifnum = QUIRK_ANY_INTERFACE,
1886 .type = QUIRK_COMPOSITE,
1887 .data = (const struct snd_usb_audio_quirk[]) {
1888 {
1889 .ifnum = 0,
1890 .type = QUIRK_AUDIO_STANDARD_INTERFACE
1891 },
1892 {
1893 .ifnum = 1, 1612 .ifnum = 1,
1894 .type = QUIRK_AUDIO_STANDARD_INTERFACE 1613 .type = QUIRK_AUDIO_FIXED_ENDPOINT,
1614 .data = & (const struct audioformat) {
1615 .formats = SNDRV_PCM_FMTBIT_S32_LE,
1616 .channels = 12,
1617 .iface = 1,
1618 .altsetting = 1,
1619 .altset_idx = 1,
1620 .endpoint = 0x85,
1621 .ep_attr = 0x25,
1622 .rates = SNDRV_PCM_RATE_44100,
1623 .rate_min = 44100,
1624 .rate_max = 44100,
1625 .nr_rates = 1,
1626 .rate_table = (unsigned int[]) { 44100 }
1627 }
1895 }, 1628 },
1896 { 1629 {
1897 .ifnum = 2, 1630 .ifnum = 2,
@@ -1902,30 +1635,12 @@ YAMAHA_DEVICE(0x7010, "UB99"),
1902 } 1635 }
1903 }, 1636 },
1904 { 1637 {
1905 .ifnum = -1 1638 .ifnum = 3,
1906 } 1639 .type = QUIRK_IGNORE_INTERFACE
1907 }
1908 }
1909},
1910{
1911 USB_DEVICE(0x0582, 0x0127),
1912 .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
1913 /* .vendor_name = "Roland", */
1914 /* .product_name = "GR-55", */
1915 .ifnum = QUIRK_ANY_INTERFACE,
1916 .type = QUIRK_COMPOSITE,
1917 .data = (const struct snd_usb_audio_quirk[]) {
1918 {
1919 .ifnum = 0,
1920 .type = QUIRK_AUDIO_STANDARD_INTERFACE
1921 },
1922 {
1923 .ifnum = 1,
1924 .type = QUIRK_AUDIO_STANDARD_INTERFACE
1925 }, 1640 },
1926 { 1641 {
1927 .ifnum = 2, 1642 .ifnum = 4,
1928 .type = QUIRK_MIDI_STANDARD_INTERFACE 1643 .type = QUIRK_IGNORE_INTERFACE
1929 }, 1644 },
1930 { 1645 {
1931 .ifnum = -1 1646 .ifnum = -1
@@ -1934,34 +1649,49 @@ YAMAHA_DEVICE(0x7010, "UB99"),
1934 } 1649 }
1935}, 1650},
1936{ 1651{
1937 /* Added support for Roland UM-ONE which differs from UM-1 */ 1652 /* only 44.1 kHz works at the moment */
1938 USB_DEVICE(0x0582, 0x012a), 1653 USB_DEVICE(0x0582, 0x012f),
1939 .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
1940 /* .vendor_name = "ROLAND", */
1941 /* .product_name = "UM-ONE", */
1942 .ifnum = 0,
1943 .type = QUIRK_MIDI_FIXED_ENDPOINT,
1944 .data = & (const struct snd_usb_midi_endpoint_info) {
1945 .out_cables = 0x0001,
1946 .in_cables = 0x0003
1947 }
1948 }
1949},
1950{
1951 USB_DEVICE(0x0582, 0x011e),
1952 .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) { 1654 .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
1953 /* .vendor_name = "BOSS", */ 1655 /* .vendor_name = "Roland", */
1954 /* .product_name = "BR-800", */ 1656 /* .product_name = "QUAD-CAPTURE", */
1955 .ifnum = QUIRK_ANY_INTERFACE, 1657 .ifnum = QUIRK_ANY_INTERFACE,
1956 .type = QUIRK_COMPOSITE, 1658 .type = QUIRK_COMPOSITE,
1957 .data = (const struct snd_usb_audio_quirk[]) { 1659 .data = (const struct snd_usb_audio_quirk[]) {
1958 { 1660 {
1959 .ifnum = 0, 1661 .ifnum = 0,
1960 .type = QUIRK_AUDIO_STANDARD_INTERFACE 1662 .type = QUIRK_AUDIO_FIXED_ENDPOINT,
1663 .data = & (const struct audioformat) {
1664 .formats = SNDRV_PCM_FMTBIT_S32_LE,
1665 .channels = 4,
1666 .iface = 0,
1667 .altsetting = 1,
1668 .altset_idx = 1,
1669 .endpoint = 0x05,
1670 .ep_attr = 0x05,
1671 .rates = SNDRV_PCM_RATE_44100,
1672 .rate_min = 44100,
1673 .rate_max = 44100,
1674 .nr_rates = 1,
1675 .rate_table = (unsigned int[]) { 44100 }
1676 }
1961 }, 1677 },
1962 { 1678 {
1963 .ifnum = 1, 1679 .ifnum = 1,
1964 .type = QUIRK_AUDIO_STANDARD_INTERFACE 1680 .type = QUIRK_AUDIO_FIXED_ENDPOINT,
1681 .data = & (const struct audioformat) {
1682 .formats = SNDRV_PCM_FMTBIT_S32_LE,
1683 .channels = 6,
1684 .iface = 1,
1685 .altsetting = 1,
1686 .altset_idx = 1,
1687 .endpoint = 0x85,
1688 .ep_attr = 0x25,
1689 .rates = SNDRV_PCM_RATE_44100,
1690 .rate_min = 44100,
1691 .rate_max = 44100,
1692 .nr_rates = 1,
1693 .rate_table = (unsigned int[]) { 44100 }
1694 }
1965 }, 1695 },
1966 { 1696 {
1967 .ifnum = 2, 1697 .ifnum = 2,
@@ -1972,38 +1702,12 @@ YAMAHA_DEVICE(0x7010, "UB99"),
1972 } 1702 }
1973 }, 1703 },
1974 { 1704 {
1975 .ifnum = -1 1705 .ifnum = 3,
1976 }
1977 }
1978 }
1979},
1980{
1981 USB_DEVICE(0x0582, 0x0130),
1982 .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
1983 /* .vendor_name = "BOSS", */
1984 /* .product_name = "MICRO BR-80", */
1985 .ifnum = QUIRK_ANY_INTERFACE,
1986 .type = QUIRK_COMPOSITE,
1987 .data = (const struct snd_usb_audio_quirk[]) {
1988 {
1989 .ifnum = 0,
1990 .type = QUIRK_IGNORE_INTERFACE 1706 .type = QUIRK_IGNORE_INTERFACE
1991 }, 1707 },
1992 { 1708 {
1993 .ifnum = 1, 1709 .ifnum = 4,
1994 .type = QUIRK_AUDIO_STANDARD_INTERFACE 1710 .type = QUIRK_IGNORE_INTERFACE
1995 },
1996 {
1997 .ifnum = 2,
1998 .type = QUIRK_AUDIO_STANDARD_INTERFACE
1999 },
2000 {
2001 .ifnum = 3,
2002 .type = QUIRK_MIDI_FIXED_ENDPOINT,
2003 .data = & (const struct snd_usb_midi_endpoint_info) {
2004 .out_cables = 0x0001,
2005 .in_cables = 0x0001
2006 }
2007 }, 1711 },
2008 { 1712 {
2009 .ifnum = -1 1713 .ifnum = -1
@@ -2011,34 +1715,15 @@ YAMAHA_DEVICE(0x7010, "UB99"),
2011 } 1715 }
2012 } 1716 }
2013}, 1717},
1718/* this catches most recent vendor-specific Roland devices */
2014{ 1719{
2015 USB_DEVICE(0x0582, 0x014d), 1720 .match_flags = USB_DEVICE_ID_MATCH_VENDOR |
2016 .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) { 1721 USB_DEVICE_ID_MATCH_INT_CLASS,
2017 /* .vendor_name = "BOSS", */ 1722 .idVendor = 0x0582,
2018 /* .product_name = "GT-100", */ 1723 .bInterfaceClass = USB_CLASS_VENDOR_SPEC,
1724 .driver_info = (unsigned long) &(const struct snd_usb_audio_quirk) {
2019 .ifnum = QUIRK_ANY_INTERFACE, 1725 .ifnum = QUIRK_ANY_INTERFACE,
2020 .type = QUIRK_COMPOSITE, 1726 .type = QUIRK_AUTODETECT
2021 .data = (const struct snd_usb_audio_quirk[]) {
2022 {
2023 .ifnum = 1,
2024 .type = QUIRK_AUDIO_STANDARD_INTERFACE
2025 },
2026 {
2027 .ifnum = 2,
2028 .type = QUIRK_AUDIO_STANDARD_INTERFACE
2029 },
2030 {
2031 .ifnum = 3,
2032 .type = QUIRK_MIDI_FIXED_ENDPOINT,
2033 .data = & (const struct snd_usb_midi_endpoint_info) {
2034 .out_cables = 0x0001,
2035 .in_cables = 0x0001
2036 }
2037 },
2038 {
2039 .ifnum = -1
2040 }
2041 }
2042 } 1727 }
2043}, 1728},
2044 1729
@@ -3434,4 +3119,16 @@ YAMAHA_DEVICE(0x7010, "UB99"),
3434 } 3119 }
3435}, 3120},
3436 3121
3122{
3123 /*
3124 * The original product_name is "USB Sound Device", however this name
3125 * is also used by the CM106 based cards, so make it unique.
3126 */
3127 USB_DEVICE(0x0d8c, 0x0103),
3128 .driver_info = (unsigned long) &(const struct snd_usb_audio_quirk) {
3129 .product_name = "Audio Advantage MicroII",
3130 .ifnum = QUIRK_NO_INTERFACE
3131 }
3132},
3133
3437#undef USB_DEVICE_VENDOR_SPEC 3134#undef USB_DEVICE_VENDOR_SPEC
diff --git a/sound/usb/quirks.c b/sound/usb/quirks.c
index 3879eae7e874..5b01330b8452 100644
--- a/sound/usb/quirks.c
+++ b/sound/usb/quirks.c
@@ -18,6 +18,7 @@
18#include <linux/slab.h> 18#include <linux/slab.h>
19#include <linux/usb.h> 19#include <linux/usb.h>
20#include <linux/usb/audio.h> 20#include <linux/usb/audio.h>
21#include <linux/usb/midi.h>
21 22
22#include <sound/control.h> 23#include <sound/control.h>
23#include <sound/core.h> 24#include <sound/core.h>
@@ -175,6 +176,212 @@ static int create_fixed_stream_quirk(struct snd_usb_audio *chip,
175 return 0; 176 return 0;
176} 177}
177 178
179static int create_auto_pcm_quirk(struct snd_usb_audio *chip,
180 struct usb_interface *iface,
181 struct usb_driver *driver)
182{
183 struct usb_host_interface *alts;
184 struct usb_interface_descriptor *altsd;
185 struct usb_endpoint_descriptor *epd;
186 struct uac1_as_header_descriptor *ashd;
187 struct uac_format_type_i_discrete_descriptor *fmtd;
188
189 /*
190 * Most Roland/Yamaha audio streaming interfaces have more or less
191 * standard descriptors, but older devices might lack descriptors, and
192 * future ones might change, so ensure that we fail silently if the
193 * interface doesn't look exactly right.
194 */
195
196 /* must have a non-zero altsetting for streaming */
197 if (iface->num_altsetting < 2)
198 return -ENODEV;
199 alts = &iface->altsetting[1];
200 altsd = get_iface_desc(alts);
201
202 /* must have an isochronous endpoint for streaming */
203 if (altsd->bNumEndpoints < 1)
204 return -ENODEV;
205 epd = get_endpoint(alts, 0);
206 if (!usb_endpoint_xfer_isoc(epd))
207 return -ENODEV;
208
209 /* must have format descriptors */
210 ashd = snd_usb_find_csint_desc(alts->extra, alts->extralen, NULL,
211 UAC_AS_GENERAL);
212 fmtd = snd_usb_find_csint_desc(alts->extra, alts->extralen, NULL,
213 UAC_FORMAT_TYPE);
214 if (!ashd || ashd->bLength < 7 ||
215 !fmtd || fmtd->bLength < 8)
216 return -ENODEV;
217
218 return create_standard_audio_quirk(chip, iface, driver, NULL);
219}
220
221static int create_yamaha_midi_quirk(struct snd_usb_audio *chip,
222 struct usb_interface *iface,
223 struct usb_driver *driver,
224 struct usb_host_interface *alts)
225{
226 static const struct snd_usb_audio_quirk yamaha_midi_quirk = {
227 .type = QUIRK_MIDI_YAMAHA
228 };
229 struct usb_midi_in_jack_descriptor *injd;
230 struct usb_midi_out_jack_descriptor *outjd;
231
232 /* must have some valid jack descriptors */
233 injd = snd_usb_find_csint_desc(alts->extra, alts->extralen,
234 NULL, USB_MS_MIDI_IN_JACK);
235 outjd = snd_usb_find_csint_desc(alts->extra, alts->extralen,
236 NULL, USB_MS_MIDI_OUT_JACK);
237 if (!injd && !outjd)
238 return -ENODEV;
239 if (injd && (injd->bLength < 5 ||
240 (injd->bJackType != USB_MS_EMBEDDED &&
241 injd->bJackType != USB_MS_EXTERNAL)))
242 return -ENODEV;
243 if (outjd && (outjd->bLength < 6 ||
244 (outjd->bJackType != USB_MS_EMBEDDED &&
245 outjd->bJackType != USB_MS_EXTERNAL)))
246 return -ENODEV;
247 return create_any_midi_quirk(chip, iface, driver, &yamaha_midi_quirk);
248}
249
250static int create_roland_midi_quirk(struct snd_usb_audio *chip,
251 struct usb_interface *iface,
252 struct usb_driver *driver,
253 struct usb_host_interface *alts)
254{
255 static const struct snd_usb_audio_quirk roland_midi_quirk = {
256 .type = QUIRK_MIDI_ROLAND
257 };
258 u8 *roland_desc = NULL;
259
260 /* might have a vendor-specific descriptor <06 24 F1 02 ...> */
261 for (;;) {
262 roland_desc = snd_usb_find_csint_desc(alts->extra,
263 alts->extralen,
264 roland_desc, 0xf1);
265 if (!roland_desc)
266 return -ENODEV;
267 if (roland_desc[0] < 6 || roland_desc[3] != 2)
268 continue;
269 return create_any_midi_quirk(chip, iface, driver,
270 &roland_midi_quirk);
271 }
272}
273
274static int create_std_midi_quirk(struct snd_usb_audio *chip,
275 struct usb_interface *iface,
276 struct usb_driver *driver,
277 struct usb_host_interface *alts)
278{
279 struct usb_ms_header_descriptor *mshd;
280 struct usb_ms_endpoint_descriptor *msepd;
281
282 /* must have the MIDIStreaming interface header descriptor*/
283 mshd = (struct usb_ms_header_descriptor *)alts->extra;
284 if (alts->extralen < 7 ||
285 mshd->bLength < 7 ||
286 mshd->bDescriptorType != USB_DT_CS_INTERFACE ||
287 mshd->bDescriptorSubtype != USB_MS_HEADER)
288 return -ENODEV;
289 /* must have the MIDIStreaming endpoint descriptor*/
290 msepd = (struct usb_ms_endpoint_descriptor *)alts->endpoint[0].extra;
291 if (alts->endpoint[0].extralen < 4 ||
292 msepd->bLength < 4 ||
293 msepd->bDescriptorType != USB_DT_CS_ENDPOINT ||
294 msepd->bDescriptorSubtype != UAC_MS_GENERAL ||
295 msepd->bNumEmbMIDIJack < 1 ||
296 msepd->bNumEmbMIDIJack > 16)
297 return -ENODEV;
298
299 return create_any_midi_quirk(chip, iface, driver, NULL);
300}
301
302static int create_auto_midi_quirk(struct snd_usb_audio *chip,
303 struct usb_interface *iface,
304 struct usb_driver *driver)
305{
306 struct usb_host_interface *alts;
307 struct usb_interface_descriptor *altsd;
308 struct usb_endpoint_descriptor *epd;
309 int err;
310
311 alts = &iface->altsetting[0];
312 altsd = get_iface_desc(alts);
313
314 /* must have at least one bulk/interrupt endpoint for streaming */
315 if (altsd->bNumEndpoints < 1)
316 return -ENODEV;
317 epd = get_endpoint(alts, 0);
318 if (!usb_endpoint_xfer_bulk(epd) ||
319 !usb_endpoint_xfer_int(epd))
320 return -ENODEV;
321
322 switch (USB_ID_VENDOR(chip->usb_id)) {
323 case 0x0499: /* Yamaha */
324 err = create_yamaha_midi_quirk(chip, iface, driver, alts);
325 if (err < 0 && err != -ENODEV)
326 return err;
327 break;
328 case 0x0582: /* Roland */
329 err = create_roland_midi_quirk(chip, iface, driver, alts);
330 if (err < 0 && err != -ENODEV)
331 return err;
332 break;
333 }
334
335 return create_std_midi_quirk(chip, iface, driver, alts);
336}
337
338static int create_autodetect_quirk(struct snd_usb_audio *chip,
339 struct usb_interface *iface,
340 struct usb_driver *driver)
341{
342 int err;
343
344 err = create_auto_pcm_quirk(chip, iface, driver);
345 if (err == -ENODEV)
346 err = create_auto_midi_quirk(chip, iface, driver);
347 return err;
348}
349
350static int create_autodetect_quirks(struct snd_usb_audio *chip,
351 struct usb_interface *iface,
352 struct usb_driver *driver,
353 const struct snd_usb_audio_quirk *quirk)
354{
355 int probed_ifnum = get_iface_desc(iface->altsetting)->bInterfaceNumber;
356 int ifcount, ifnum, err;
357
358 err = create_autodetect_quirk(chip, iface, driver);
359 if (err < 0)
360 return err;
361
362 /*
363 * ALSA PCM playback/capture devices cannot be registered in two steps,
364 * so we have to claim the other corresponding interface here.
365 */
366 ifcount = chip->dev->actconfig->desc.bNumInterfaces;
367 for (ifnum = 0; ifnum < ifcount; ifnum++) {
368 if (ifnum == probed_ifnum || quirk->ifnum >= 0)
369 continue;
370 iface = usb_ifnum_to_if(chip->dev, ifnum);
371 if (!iface ||
372 usb_interface_claimed(iface) ||
373 get_iface_desc(iface->altsetting)->bInterfaceClass !=
374 USB_CLASS_VENDOR_SPEC)
375 continue;
376
377 err = create_autodetect_quirk(chip, iface, driver);
378 if (err >= 0)
379 usb_driver_claim_interface(driver, iface, (void *)-1L);
380 }
381
382 return 0;
383}
384
178/* 385/*
179 * Create a stream for an Edirol UA-700/UA-25/UA-4FX interface. 386 * Create a stream for an Edirol UA-700/UA-25/UA-4FX interface.
180 * The only way to detect the sample rate is by looking at wMaxPacketSize. 387 * The only way to detect the sample rate is by looking at wMaxPacketSize.
@@ -303,9 +510,11 @@ int snd_usb_create_quirk(struct snd_usb_audio *chip,
303 static const quirk_func_t quirk_funcs[] = { 510 static const quirk_func_t quirk_funcs[] = {
304 [QUIRK_IGNORE_INTERFACE] = ignore_interface_quirk, 511 [QUIRK_IGNORE_INTERFACE] = ignore_interface_quirk,
305 [QUIRK_COMPOSITE] = create_composite_quirk, 512 [QUIRK_COMPOSITE] = create_composite_quirk,
513 [QUIRK_AUTODETECT] = create_autodetect_quirks,
306 [QUIRK_MIDI_STANDARD_INTERFACE] = create_any_midi_quirk, 514 [QUIRK_MIDI_STANDARD_INTERFACE] = create_any_midi_quirk,
307 [QUIRK_MIDI_FIXED_ENDPOINT] = create_any_midi_quirk, 515 [QUIRK_MIDI_FIXED_ENDPOINT] = create_any_midi_quirk,
308 [QUIRK_MIDI_YAMAHA] = create_any_midi_quirk, 516 [QUIRK_MIDI_YAMAHA] = create_any_midi_quirk,
517 [QUIRK_MIDI_ROLAND] = create_any_midi_quirk,
309 [QUIRK_MIDI_MIDIMAN] = create_any_midi_quirk, 518 [QUIRK_MIDI_MIDIMAN] = create_any_midi_quirk,
310 [QUIRK_MIDI_NOVATION] = create_any_midi_quirk, 519 [QUIRK_MIDI_NOVATION] = create_any_midi_quirk,
311 [QUIRK_MIDI_RAW_BYTES] = create_any_midi_quirk, 520 [QUIRK_MIDI_RAW_BYTES] = create_any_midi_quirk,
diff --git a/sound/usb/stream.c b/sound/usb/stream.c
index 7db2f8958e79..c4339f97226b 100644
--- a/sound/usb/stream.c
+++ b/sound/usb/stream.c
@@ -493,10 +493,10 @@ int snd_usb_parse_audio_interface(struct snd_usb_audio *chip, int iface_no)
493 altsd = get_iface_desc(alts); 493 altsd = get_iface_desc(alts);
494 protocol = altsd->bInterfaceProtocol; 494 protocol = altsd->bInterfaceProtocol;
495 /* skip invalid one */ 495 /* skip invalid one */
496 if ((altsd->bInterfaceClass != USB_CLASS_AUDIO && 496 if (((altsd->bInterfaceClass != USB_CLASS_AUDIO ||
497 (altsd->bInterfaceSubClass != USB_SUBCLASS_AUDIOSTREAMING &&
498 altsd->bInterfaceSubClass != USB_SUBCLASS_VENDOR_SPEC)) &&
497 altsd->bInterfaceClass != USB_CLASS_VENDOR_SPEC) || 499 altsd->bInterfaceClass != USB_CLASS_VENDOR_SPEC) ||
498 (altsd->bInterfaceSubClass != USB_SUBCLASS_AUDIOSTREAMING &&
499 altsd->bInterfaceSubClass != USB_SUBCLASS_VENDOR_SPEC) ||
500 altsd->bNumEndpoints < 1 || 500 altsd->bNumEndpoints < 1 ||
501 le16_to_cpu(get_endpoint(alts, 0)->wMaxPacketSize) == 0) 501 le16_to_cpu(get_endpoint(alts, 0)->wMaxPacketSize) == 0)
502 continue; 502 continue;
@@ -512,6 +512,15 @@ int snd_usb_parse_audio_interface(struct snd_usb_audio *chip, int iface_no)
512 if (snd_usb_apply_interface_quirk(chip, iface_no, altno)) 512 if (snd_usb_apply_interface_quirk(chip, iface_no, altno))
513 continue; 513 continue;
514 514
515 /*
516 * Roland audio streaming interfaces are marked with protocols
517 * 0/1/2, but are UAC 1 compatible.
518 */
519 if (USB_ID_VENDOR(chip->usb_id) == 0x0582 &&
520 altsd->bInterfaceClass == USB_CLASS_VENDOR_SPEC &&
521 protocol <= 2)
522 protocol = UAC_VERSION_1;
523
515 chconfig = 0; 524 chconfig = 0;
516 /* get audio formats */ 525 /* get audio formats */
517 switch (protocol) { 526 switch (protocol) {
@@ -635,6 +644,7 @@ int snd_usb_parse_audio_interface(struct snd_usb_audio *chip, int iface_no)
635 fp->endpoint = get_endpoint(alts, 0)->bEndpointAddress; 644 fp->endpoint = get_endpoint(alts, 0)->bEndpointAddress;
636 fp->ep_attr = get_endpoint(alts, 0)->bmAttributes; 645 fp->ep_attr = get_endpoint(alts, 0)->bmAttributes;
637 fp->datainterval = snd_usb_parse_datainterval(chip, alts); 646 fp->datainterval = snd_usb_parse_datainterval(chip, alts);
647 fp->protocol = protocol;
638 fp->maxpacksize = le16_to_cpu(get_endpoint(alts, 0)->wMaxPacketSize); 648 fp->maxpacksize = le16_to_cpu(get_endpoint(alts, 0)->wMaxPacketSize);
639 fp->channels = num_channels; 649 fp->channels = num_channels;
640 if (snd_usb_get_speed(dev) == USB_SPEED_HIGH) 650 if (snd_usb_get_speed(dev) == USB_SPEED_HIGH)
@@ -676,7 +686,7 @@ int snd_usb_parse_audio_interface(struct snd_usb_audio *chip, int iface_no)
676 } 686 }
677 687
678 /* ok, let's parse further... */ 688 /* ok, let's parse further... */
679 if (snd_usb_parse_audio_format(chip, fp, format, fmt, stream, alts) < 0) { 689 if (snd_usb_parse_audio_format(chip, fp, format, fmt, stream) < 0) {
680 kfree(fp->rate_table); 690 kfree(fp->rate_table);
681 kfree(fp->chmap); 691 kfree(fp->chmap);
682 kfree(fp); 692 kfree(fp);
diff --git a/sound/usb/usbaudio.h b/sound/usb/usbaudio.h
index bc43bcaddf4d..caabe9b3af49 100644
--- a/sound/usb/usbaudio.h
+++ b/sound/usb/usbaudio.h
@@ -72,9 +72,11 @@ struct snd_usb_audio {
72enum quirk_type { 72enum quirk_type {
73 QUIRK_IGNORE_INTERFACE, 73 QUIRK_IGNORE_INTERFACE,
74 QUIRK_COMPOSITE, 74 QUIRK_COMPOSITE,
75 QUIRK_AUTODETECT,
75 QUIRK_MIDI_STANDARD_INTERFACE, 76 QUIRK_MIDI_STANDARD_INTERFACE,
76 QUIRK_MIDI_FIXED_ENDPOINT, 77 QUIRK_MIDI_FIXED_ENDPOINT,
77 QUIRK_MIDI_YAMAHA, 78 QUIRK_MIDI_YAMAHA,
79 QUIRK_MIDI_ROLAND,
78 QUIRK_MIDI_MIDIMAN, 80 QUIRK_MIDI_MIDIMAN,
79 QUIRK_MIDI_NOVATION, 81 QUIRK_MIDI_NOVATION,
80 QUIRK_MIDI_RAW_BYTES, 82 QUIRK_MIDI_RAW_BYTES,
diff --git a/sound/usb/usx2y/usbusx2y.c b/sound/usb/usx2y/usbusx2y.c
index 9af7c1f17413..1f9bbd55553f 100644
--- a/sound/usb/usx2y/usbusx2y.c
+++ b/sound/usb/usx2y/usbusx2y.c
@@ -150,7 +150,7 @@
150MODULE_AUTHOR("Karsten Wiese <annabellesgarden@yahoo.de>"); 150MODULE_AUTHOR("Karsten Wiese <annabellesgarden@yahoo.de>");
151MODULE_DESCRIPTION("TASCAM "NAME_ALLCAPS" Version 0.8.7.2"); 151MODULE_DESCRIPTION("TASCAM "NAME_ALLCAPS" Version 0.8.7.2");
152MODULE_LICENSE("GPL"); 152MODULE_LICENSE("GPL");
153MODULE_SUPPORTED_DEVICE("{{TASCAM(0x1604), "NAME_ALLCAPS"(0x8001)(0x8005)(0x8007) }}"); 153MODULE_SUPPORTED_DEVICE("{{TASCAM(0x1604),"NAME_ALLCAPS"(0x8001)(0x8005)(0x8007)}}");
154 154
155static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-max */ 155static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-max */
156static char* id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* Id for this card */ 156static char* id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* Id for this card */
diff --git a/sound/usb/usx2y/usbusx2yaudio.c b/sound/usb/usx2y/usbusx2yaudio.c
index b37653247ef4..4967fe9c938d 100644
--- a/sound/usb/usx2y/usbusx2yaudio.c
+++ b/sound/usb/usx2y/usbusx2yaudio.c
@@ -695,9 +695,6 @@ static int usX2Y_rate_set(struct usX2Ydev *usX2Y, int rate)
695 ((char*)(usbdata + i))[1] = ra[i].c2; 695 ((char*)(usbdata + i))[1] = ra[i].c2;
696 usb_fill_bulk_urb(us->urb[i], usX2Y->dev, usb_sndbulkpipe(usX2Y->dev, 4), 696 usb_fill_bulk_urb(us->urb[i], usX2Y->dev, usb_sndbulkpipe(usX2Y->dev, 4),
697 usbdata + i, 2, i_usX2Y_04Int, usX2Y); 697 usbdata + i, 2, i_usX2Y_04Int, usX2Y);
698#ifdef OLD_USB
699 us->urb[i]->transfer_flags = USB_QUEUE_BULK;
700#endif
701 } 698 }
702 us->submitted = 0; 699 us->submitted = 0;
703 us->len = NOOF_SETRATE_URBS; 700 us->len = NOOF_SETRATE_URBS;