aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2015-11-06 14:04:07 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2015-11-06 14:04:07 -0500
commit0280d1a099da1d211e76ec47cc0944c993a36316 (patch)
tree7a2961ded372ca6b6fa88d83a46a5bb5d40abbe4
parent5bc23a0cdee4a6757fcc2919eb26827fe11e3bee (diff)
parent5cf92c8b3dc5da59e05dc81bdc069cedf6f38313 (diff)
Merge tag 'sound-4.4-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound
Pull sound updates from Takashi Iwai: "Here is the first batch of updates for sound system on 4.4-rc1. Again at this time, the update looks fairly calm; no big changes in either ALSA core or ASoC infrastructures, rather all small cleanups, in addition to the new stuff as usual. The biggest changes are about Firewire sound devices. It gained lots of new device support, and MIDI functionality. Also there are updates for a few still working-in-progress stuff (topology API and ASoC skylake), too. But overall, this update should give no big surprise. Some highlights are below: Core: - A few more Kconfig items for tinification; it's marked as EXPERT, so normal user should't be bothered :) - Refactoring with a new PCM hw_constraint helper - Removal of unused transfer_ack_{begin,end} PCM callbacks Firewire: - Restructuring of code subtree, lots of refactoring - Support AMDTP variants - New driver for Digidesign 002/003 family - Adds support for TASCAM FireOne to ALSA OXFW driver - Add MIDI support to TASCAM and Digi00x devices HD-Audio: - Automated modalias generation for codec drivers, finally - Improvement on heuristics for setting mixer name - A few fixes for longstanding bugs on Creative CA0132 cards - Addition of audio rate callback with i915 communication - Fix suspend issue on recent Dell XPS - Intel Lewisburg controller support ASoC: - Updates to the topology userspace interface - Big updates to the Renesas support (rcar) - More updates for supporting Intel Sky Lake systems - New drivers for Asahi Kasei Microdevices AK4613, Allwinnner A10, Cirrus Logic WM8998, Dialog DA7219, Nuvoton NAU8825, Rockchip S/PDIF, and Atmel class D amplifier USB-Audio: - A fix for newer Roland MIDI devices - Quirks and workarounds for Zoom R16/24 device Misc: - A few fixes for some old Cirrus CS46xx PCI sound boards - Yet another fixes for some old ESS Maestro3 PCI sound boards" * tag 'sound-4.4-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound: (330 commits) ALSA: hda - Add Intel Lewisburg device IDs Audio ALSA: hda - Apply pin fixup for HP ProBook 6550b ALSA: hda - Fix lost 4k BDL boundary workaround ALSA: maestro3: Fix Allegro mute until master volume/mute is touched ALSA: maestro3: Enable docking support for Dell Latitude C810 ALSA: firewire-digi00x: add another rawmidi character device for MIDI control ports ALSA: firewire-digi00x: add MIDI operations for MIDI control port ALSA: firewire-digi00x: rename identifiers of MIDI operation for physical ports ALSA: cs46xx: Fix suspend for all channels ALSA: cs46xx: Fix Duplicate front for CS4294 and CS4298 codecs ALSA: DocBook: Add soc-ops.c and soc-compress.c ALSA: hda - Add / fix kernel doc comments ALSA: Constify ratden/ratnum constraints ALSA: hda - Disable 64bit address for Creative HDA controllers ALSA: hda/realtek - Dell XPS one ALC3260 speaker no sound after resume back ALSA: hda/ca0132 - Convert leftover pr_info() and pr_err() ASoC: fsl: Use #ifdef instead of #if for CONFIG_PM_SLEEP ASoC: rt5645: Sort the order for register bit defines ASoC: dwc: add check for master/slave format ASoC: rt5645: Add the HWEQ for the speaker output ...
-rw-r--r--Documentation/DocBook/alsa-driver-api.tmpl2
-rw-r--r--Documentation/DocBook/writing-an-alsa-driver.tmpl19
-rw-r--r--Documentation/devicetree/bindings/sound/ak4613.txt17
-rw-r--r--Documentation/devicetree/bindings/sound/ak4642.txt22
-rw-r--r--Documentation/devicetree/bindings/sound/atmel-classd.txt52
-rw-r--r--Documentation/devicetree/bindings/sound/da7213.txt41
-rw-r--r--Documentation/devicetree/bindings/sound/da7219.txt106
-rw-r--r--Documentation/devicetree/bindings/sound/fsl-asoc-card.txt10
-rw-r--r--Documentation/devicetree/bindings/sound/nau8825.txt102
-rw-r--r--Documentation/devicetree/bindings/sound/renesas,rsnd.txt7
-rw-r--r--Documentation/devicetree/bindings/sound/rockchip-i2s.txt6
-rw-r--r--Documentation/devicetree/bindings/sound/rockchip-spdif.txt40
-rw-r--r--Documentation/devicetree/bindings/sound/rt5640.txt9
-rw-r--r--Documentation/devicetree/bindings/sound/sun4i-codec.txt27
-rw-r--r--Documentation/devicetree/bindings/sound/tdm-slot.txt11
-rw-r--r--Documentation/sound/alsa/hda_codec.txt322
-rw-r--r--MAINTAINERS1
-rw-r--r--drivers/gpu/drm/i915/i915_dma.c1
-rw-r--r--drivers/gpu/drm/i915/i915_drv.h5
-rw-r--r--drivers/gpu/drm/i915/intel_audio.c179
-rw-r--r--include/drm/i915_component.h17
-rw-r--r--include/linux/mod_devicetable.h8
-rw-r--r--include/sound/da7213.h3
-rw-r--r--include/sound/da7219-aad.h99
-rw-r--r--include/sound/da7219.h55
-rw-r--r--include/sound/designware_i2s.h2
-rw-r--r--include/sound/hda_regmap.h4
-rw-r--r--include/sound/hdaudio.h19
-rw-r--r--include/sound/hdaudio_ext.h7
-rw-r--r--include/sound/pcm.h44
-rw-r--r--include/sound/pxa2xx-lib.h1
-rw-r--r--include/sound/rt5640.h3
-rw-r--r--include/sound/rt5645.h2
-rw-r--r--include/sound/simple_card.h2
-rw-r--r--include/sound/soc-dai.h19
-rw-r--r--include/sound/soc-dapm.h3
-rw-r--r--include/sound/soc.h27
-rw-r--r--include/uapi/sound/asoc.h76
-rw-r--r--include/uapi/sound/asound.h4
-rw-r--r--include/uapi/sound/emu10k1.h14
-rw-r--r--include/uapi/sound/firewire.h9
-rw-r--r--include/uapi/sound/hdspm.h40
-rw-r--r--scripts/mod/devicetable-offsets.c5
-rw-r--r--scripts/mod/file2alias.c17
-rw-r--r--sound/arm/pxa2xx-ac97.c13
-rw-r--r--sound/arm/pxa2xx-pcm-lib.c201
-rw-r--r--sound/arm/pxa2xx-pcm.c12
-rw-r--r--sound/arm/pxa2xx-pcm.h2
-rw-r--r--sound/core/Kconfig13
-rw-r--r--sound/core/Makefile3
-rw-r--r--sound/core/oss/mixer_oss.c3
-rw-r--r--sound/core/pcm.c3
-rw-r--r--sound/core/pcm_lib.c24
-rw-r--r--sound/core/pcm_native.c42
-rw-r--r--sound/core/seq/oss/seq_oss_readq.c6
-rw-r--r--sound/core/seq/oss/seq_oss_writeq.c4
-rw-r--r--sound/firewire/Kconfig27
-rw-r--r--sound/firewire/Makefile5
-rw-r--r--sound/firewire/amdtp-am824.c465
-rw-r--r--sound/firewire/amdtp-am824.h52
-rw-r--r--sound/firewire/amdtp-stream.c (renamed from sound/firewire/amdtp.c)379
-rw-r--r--sound/firewire/amdtp-stream.h (renamed from sound/firewire/amdtp.h)116
-rw-r--r--sound/firewire/bebob/Makefile2
-rw-r--r--sound/firewire/bebob/bebob.c9
-rw-r--r--sound/firewire/bebob/bebob.h34
-rw-r--r--sound/firewire/bebob/bebob_focusrite.c26
-rw-r--r--sound/firewire/bebob/bebob_maudio.c34
-rw-r--r--sound/firewire/bebob/bebob_midi.c16
-rw-r--r--sound/firewire/bebob/bebob_pcm.c16
-rw-r--r--sound/firewire/bebob/bebob_proc.c6
-rw-r--r--sound/firewire/bebob/bebob_stream.c40
-rw-r--r--sound/firewire/bebob/bebob_terratec.c10
-rw-r--r--sound/firewire/bebob/bebob_yamaha.c6
-rw-r--r--sound/firewire/dice/Makefile2
-rw-r--r--sound/firewire/dice/dice-midi.c12
-rw-r--r--sound/firewire/dice/dice-pcm.c12
-rw-r--r--sound/firewire/dice/dice-stream.c34
-rw-r--r--sound/firewire/dice/dice.c3
-rw-r--r--sound/firewire/dice/dice.h2
-rw-r--r--sound/firewire/digi00x/Makefile4
-rw-r--r--sound/firewire/digi00x/amdtp-dot.c442
-rw-r--r--sound/firewire/digi00x/digi00x-hwdep.c200
-rw-r--r--sound/firewire/digi00x/digi00x-midi.c223
-rw-r--r--sound/firewire/digi00x/digi00x-pcm.c373
-rw-r--r--sound/firewire/digi00x/digi00x-proc.c99
-rw-r--r--sound/firewire/digi00x/digi00x-stream.c422
-rw-r--r--sound/firewire/digi00x/digi00x-transaction.c137
-rw-r--r--sound/firewire/digi00x/digi00x.c170
-rw-r--r--sound/firewire/digi00x/digi00x.h157
-rw-r--r--sound/firewire/fcp.c2
-rw-r--r--sound/firewire/fireworks/Makefile2
-rw-r--r--sound/firewire/fireworks/fireworks.c12
-rw-r--r--sound/firewire/fireworks/fireworks.h2
-rw-r--r--sound/firewire/fireworks/fireworks_command.c2
-rw-r--r--sound/firewire/fireworks/fireworks_midi.c12
-rw-r--r--sound/firewire/fireworks/fireworks_pcm.c12
-rw-r--r--sound/firewire/fireworks/fireworks_stream.c8
-rw-r--r--sound/firewire/lib.c142
-rw-r--r--sound/firewire/lib.h56
-rw-r--r--sound/firewire/oxfw/Makefile2
-rw-r--r--sound/firewire/oxfw/oxfw-midi.c40
-rw-r--r--sound/firewire/oxfw/oxfw-pcm.c10
-rw-r--r--sound/firewire/oxfw/oxfw-stream.c53
-rw-r--r--sound/firewire/oxfw/oxfw.c46
-rw-r--r--sound/firewire/oxfw/oxfw.h3
-rw-r--r--sound/firewire/tascam/Makefile4
-rw-r--r--sound/firewire/tascam/amdtp-tascam.c243
-rw-r--r--sound/firewire/tascam/tascam-hwdep.c201
-rw-r--r--sound/firewire/tascam/tascam-midi.c135
-rw-r--r--sound/firewire/tascam/tascam-pcm.c312
-rw-r--r--sound/firewire/tascam/tascam-proc.c88
-rw-r--r--sound/firewire/tascam/tascam-stream.c496
-rw-r--r--sound/firewire/tascam/tascam-transaction.c302
-rw-r--r--sound/firewire/tascam/tascam.c209
-rw-r--r--sound/firewire/tascam/tascam.h147
-rw-r--r--sound/hda/ext/hdac_ext_stream.c9
-rw-r--r--sound/hda/hda_bus_type.c13
-rw-r--r--sound/hda/hdac_bus.c14
-rw-r--r--sound/hda/hdac_device.c124
-rw-r--r--sound/hda/hdac_i915.c70
-rw-r--r--sound/hda/hdac_regmap.c10
-rw-r--r--sound/hda/hdac_stream.c3
-rw-r--r--sound/hda/hdac_sysfs.c8
-rw-r--r--sound/pci/cs46xx/cs46xx_lib.c9
-rw-r--r--sound/pci/hda/hda_bind.c69
-rw-r--r--sound/pci/hda/hda_codec.c44
-rw-r--r--sound/pci/hda/hda_codec.h44
-rw-r--r--sound/pci/hda/hda_controller.c4
-rw-r--r--sound/pci/hda/hda_generic.c7
-rw-r--r--sound/pci/hda/hda_intel.c8
-rw-r--r--sound/pci/hda/hda_local.h7
-rw-r--r--sound/pci/hda/hda_sysfs.c3
-rw-r--r--sound/pci/hda/patch_analog.c37
-rw-r--r--sound/pci/hda/patch_ca0110.c15
-rw-r--r--sound/pci/hda/patch_ca0132.c15
-rw-r--r--sound/pci/hda/patch_cirrus.c22
-rw-r--r--sound/pci/hda/patch_cmedia.c15
-rw-r--r--sound/pci/hda/patch_conexant.c118
-rw-r--r--sound/pci/hda/patch_hdmi.c220
-rw-r--r--sound/pci/hda/patch_realtek.c147
-rw-r--r--sound/pci/hda/patch_si3054.c39
-rw-r--r--sound/pci/hda/patch_sigmatel.c215
-rw-r--r--sound/pci/hda/patch_via.c171
-rw-r--r--sound/pci/korg1212/korg1212.c8
-rw-r--r--sound/pci/lx6464es/lx6464es.c4
-rw-r--r--sound/pci/maestro3.c25
-rw-r--r--sound/pci/rme32.c4
-rw-r--r--sound/pci/rme96.c8
-rw-r--r--sound/pci/rme9652/hdsp.c1
-rw-r--r--sound/pci/rme9652/hdspm.c9
-rw-r--r--sound/soc/Kconfig6
-rw-r--r--sound/soc/Makefile4
-rw-r--r--sound/soc/atmel/Kconfig9
-rw-r--r--sound/soc/atmel/Makefile2
-rw-r--r--sound/soc/atmel/atmel-classd.c679
-rw-r--r--sound/soc/atmel/atmel-classd.h120
-rw-r--r--sound/soc/atmel/atmel_wm8904.c1
-rw-r--r--sound/soc/au1x/db1000.c10
-rw-r--r--sound/soc/au1x/db1200.c10
-rw-r--r--sound/soc/blackfin/bf5xx-ad1836.c11
-rw-r--r--sound/soc/blackfin/bfin-eval-adau1373.c12
-rw-r--r--sound/soc/blackfin/bfin-eval-adau1701.c12
-rw-r--r--sound/soc/blackfin/bfin-eval-adav80x.c12
-rw-r--r--sound/soc/codecs/Kconfig23
-rw-r--r--sound/soc/codecs/Makefile10
-rw-r--r--sound/soc/codecs/ad193x-i2c.c8
-rw-r--r--sound/soc/codecs/ad193x-spi.c16
-rw-r--r--sound/soc/codecs/ad193x.c128
-rw-r--r--sound/soc/codecs/ad193x.h9
-rw-r--r--sound/soc/codecs/adav80x.c4
-rw-r--r--sound/soc/codecs/ak4613.c497
-rw-r--r--sound/soc/codecs/ak4642.c153
-rw-r--r--sound/soc/codecs/arizona.c49
-rw-r--r--sound/soc/codecs/arizona.h14
-rw-r--r--sound/soc/codecs/da7213.c190
-rw-r--r--sound/soc/codecs/da7213.h8
-rw-r--r--sound/soc/codecs/da7219-aad.c823
-rw-r--r--sound/soc/codecs/da7219-aad.h212
-rw-r--r--sound/soc/codecs/da7219.c1955
-rw-r--r--sound/soc/codecs/da7219.h820
-rw-r--r--sound/soc/codecs/es8328.c2
-rw-r--r--sound/soc/codecs/hdmi.c109
-rw-r--r--sound/soc/codecs/nau8825.c1309
-rw-r--r--sound/soc/codecs/nau8825.h341
-rw-r--r--sound/soc/codecs/rl6347a.c19
-rw-r--r--sound/soc/codecs/rl6347a.h2
-rw-r--r--sound/soc/codecs/rt286.c9
-rw-r--r--sound/soc/codecs/rt298.c11
-rw-r--r--sound/soc/codecs/rt5640.c22
-rw-r--r--sound/soc/codecs/rt5645.c172
-rw-r--r--sound/soc/codecs/rt5645.h30
-rw-r--r--sound/soc/codecs/ssm2518.c6
-rw-r--r--sound/soc/codecs/tlv320aic3x.c30
-rw-r--r--sound/soc/codecs/twl4030.c13
-rw-r--r--sound/soc/codecs/uda134x.c6
-rw-r--r--sound/soc/codecs/wl1273.c9
-rw-r--r--sound/soc/codecs/wm2000.c4
-rw-r--r--sound/soc/codecs/wm5110.c187
-rw-r--r--sound/soc/codecs/wm8731.c2
-rw-r--r--sound/soc/codecs/wm8903.c2
-rw-r--r--sound/soc/codecs/wm8904.c2
-rw-r--r--sound/soc/codecs/wm8955.c2
-rw-r--r--sound/soc/codecs/wm8960.c2
-rw-r--r--sound/soc/codecs/wm8998.c1430
-rw-r--r--sound/soc/codecs/wm8998.h23
-rw-r--r--sound/soc/davinci/davinci-mcasp.c305
-rw-r--r--sound/soc/dwc/designware_i2s.c123
-rw-r--r--sound/soc/fsl/fsl-asoc-card.c141
-rw-r--r--sound/soc/fsl/fsl_esai.c88
-rw-r--r--sound/soc/fsl/fsl_sai.c38
-rw-r--r--sound/soc/fsl/fsl_spdif.c73
-rw-r--r--sound/soc/fsl/fsl_ssi.c102
-rw-r--r--sound/soc/fsl/imx-spdif.c1
-rw-r--r--sound/soc/generic/simple-card.c8
-rw-r--r--sound/soc/intel/Kconfig15
-rw-r--r--sound/soc/intel/atom/sst-mfld-platform-pcm.c19
-rw-r--r--sound/soc/intel/boards/Makefile2
-rw-r--r--sound/soc/intel/boards/broadwell.c9
-rw-r--r--sound/soc/intel/boards/bytcr_rt5640.c14
-rw-r--r--sound/soc/intel/boards/cht_bsw_max98090_ti.c14
-rw-r--r--sound/soc/intel/boards/cht_bsw_rt5645.c14
-rw-r--r--sound/soc/intel/boards/cht_bsw_rt5672.c14
-rw-r--r--sound/soc/intel/boards/skl_rt286.c259
-rw-r--r--sound/soc/intel/common/Makefile6
-rw-r--r--sound/soc/intel/common/sst-dsp-priv.h1
-rw-r--r--sound/soc/intel/common/sst-dsp.c2
-rw-r--r--sound/soc/intel/common/sst-dsp.h2
-rw-r--r--sound/soc/intel/common/sst-firmware.c10
-rw-r--r--sound/soc/intel/skylake/Makefile3
-rw-r--r--sound/soc/intel/skylake/skl-messages.c44
-rw-r--r--sound/soc/intel/skylake/skl-nhlt.c10
-rw-r--r--sound/soc/intel/skylake/skl-pcm.c176
-rw-r--r--sound/soc/intel/skylake/skl-sst-dsp.c7
-rw-r--r--sound/soc/intel/skylake/skl-sst-ipc.c12
-rw-r--r--sound/soc/intel/skylake/skl-sst-ipc.h1
-rw-r--r--sound/soc/intel/skylake/skl-sst.c56
-rw-r--r--sound/soc/intel/skylake/skl-topology.c1252
-rw-r--r--sound/soc/intel/skylake/skl-topology.h36
-rw-r--r--sound/soc/intel/skylake/skl-tplg-interface.h83
-rw-r--r--sound/soc/intel/skylake/skl.c32
-rw-r--r--sound/soc/intel/skylake/skl.h17
-rw-r--r--sound/soc/jz4740/jz4740-i2s.c1
-rw-r--r--sound/soc/kirkwood/armada-370-db.c1
-rw-r--r--sound/soc/mediatek/mt8173-max98090.c11
-rw-r--r--sound/soc/mediatek/mt8173-rt5650-rt5676.c11
-rw-r--r--sound/soc/mxs/mxs-sgtl5000.c6
-rw-r--r--sound/soc/omap/n810.c3
-rw-r--r--sound/soc/omap/rx51.c5
-rw-r--r--sound/soc/pxa/brownstone.c9
-rw-r--r--sound/soc/pxa/corgi.c11
-rw-r--r--sound/soc/pxa/e740_wm9705.c5
-rw-r--r--sound/soc/pxa/e750_wm9705.c5
-rw-r--r--sound/soc/pxa/e800_wm9712.c5
-rw-r--r--sound/soc/pxa/hx4700.c4
-rw-r--r--sound/soc/pxa/imote2.c11
-rw-r--r--sound/soc/pxa/mioa701_wm9713.c11
-rw-r--r--sound/soc/pxa/palm27x.c9
-rw-r--r--sound/soc/pxa/poodle.c11
-rw-r--r--sound/soc/pxa/pxa-ssp.c1
-rw-r--r--sound/soc/pxa/pxa2xx-ac97.c49
-rw-r--r--sound/soc/pxa/pxa2xx-i2s.c3
-rw-r--r--sound/soc/pxa/pxa2xx-pcm.c33
-rw-r--r--sound/soc/pxa/spitz.c5
-rw-r--r--sound/soc/pxa/tosa.c5
-rw-r--r--sound/soc/pxa/ttc-dkb.c12
-rw-r--r--sound/soc/qcom/lpass-cpu.c3
-rw-r--r--sound/soc/rockchip/Kconfig12
-rw-r--r--sound/soc/rockchip/Makefile6
-rw-r--r--sound/soc/rockchip/rockchip_i2s.c48
-rw-r--r--sound/soc/rockchip/rockchip_i2s.h16
-rw-r--r--sound/soc/rockchip/rockchip_spdif.c405
-rw-r--r--sound/soc/rockchip/rockchip_spdif.h63
-rw-r--r--sound/soc/samsung/h1940_uda1380.c5
-rw-r--r--sound/soc/samsung/rx1950_uda1380.c5
-rw-r--r--sound/soc/sh/Kconfig3
-rw-r--r--sound/soc/sh/rcar/adg.c306
-rw-r--r--sound/soc/sh/rcar/core.c66
-rw-r--r--sound/soc/sh/rcar/ctu.c16
-rw-r--r--sound/soc/sh/rcar/dma.c2
-rw-r--r--sound/soc/sh/rcar/dvc.c16
-rw-r--r--sound/soc/sh/rcar/gen.c14
-rw-r--r--sound/soc/sh/rcar/mix.c16
-rw-r--r--sound/soc/sh/rcar/rcar_snd.h (renamed from include/sound/rcar_snd.h)1
-rw-r--r--sound/soc/sh/rcar/rsnd.h29
-rw-r--r--sound/soc/sh/rcar/src.c27
-rw-r--r--sound/soc/sh/rcar/ssi.c113
-rw-r--r--sound/soc/sh/siu_dai.c85
-rw-r--r--sound/soc/soc-compress.c12
-rw-r--r--sound/soc/soc-core.c29
-rw-r--r--sound/soc/soc-dapm.c59
-rw-r--r--sound/soc/soc-ops.c8
-rw-r--r--sound/soc/soc-pcm.c59
-rw-r--r--sound/soc/soc-topology.c4
-rw-r--r--sound/soc/sunxi/Kconfig11
-rw-r--r--sound/soc/sunxi/Makefile2
-rw-r--r--sound/soc/sunxi/sun4i-codec.c712
-rw-r--r--sound/soc/ux500/mop500.c1
-rw-r--r--sound/soc/ux500/ux500_msp_dai.c5
-rw-r--r--sound/usb/card.h1
-rw-r--r--sound/usb/endpoint.c92
-rw-r--r--sound/usb/midi.c11
-rw-r--r--sound/usb/mixer_quirks.c2
-rw-r--r--sound/usb/pcm.c74
-rw-r--r--sound/usb/quirks-table.h23
-rw-r--r--sound/usb/quirks.c3
-rw-r--r--sound/usb/stream.c1
-rw-r--r--sound/usb/usbaudio.h1
307 files changed, 21221 insertions, 3293 deletions
diff --git a/Documentation/DocBook/alsa-driver-api.tmpl b/Documentation/DocBook/alsa-driver-api.tmpl
index e94a10bb4a9e..53f439dcc94b 100644
--- a/Documentation/DocBook/alsa-driver-api.tmpl
+++ b/Documentation/DocBook/alsa-driver-api.tmpl
@@ -112,6 +112,8 @@
112!Esound/soc/soc-devres.c 112!Esound/soc/soc-devres.c
113!Esound/soc/soc-io.c 113!Esound/soc/soc-io.c
114!Esound/soc/soc-pcm.c 114!Esound/soc/soc-pcm.c
115!Esound/soc/soc-ops.c
116!Esound/soc/soc-compress.c
115 </sect1> 117 </sect1>
116 <sect1><title>ASoC DAPM API</title> 118 <sect1><title>ASoC DAPM API</title>
117!Esound/soc/soc-dapm.c 119!Esound/soc/soc-dapm.c
diff --git a/Documentation/DocBook/writing-an-alsa-driver.tmpl b/Documentation/DocBook/writing-an-alsa-driver.tmpl
index 84ef6a90131c..a27ab9f53fb6 100644
--- a/Documentation/DocBook/writing-an-alsa-driver.tmpl
+++ b/Documentation/DocBook/writing-an-alsa-driver.tmpl
@@ -2181,10 +2181,6 @@ struct _snd_pcm_runtime {
2181 struct snd_pcm_hardware hw; 2181 struct snd_pcm_hardware hw;
2182 struct snd_pcm_hw_constraints hw_constraints; 2182 struct snd_pcm_hw_constraints hw_constraints;
2183 2183
2184 /* -- interrupt callbacks -- */
2185 void (*transfer_ack_begin)(struct snd_pcm_substream *substream);
2186 void (*transfer_ack_end)(struct snd_pcm_substream *substream);
2187
2188 /* -- timer -- */ 2184 /* -- timer -- */
2189 unsigned int timer_resolution; /* timer resolution */ 2185 unsigned int timer_resolution; /* timer resolution */
2190 2186
@@ -2209,9 +2205,8 @@ struct _snd_pcm_runtime {
2209 For the operators (callbacks) of each sound driver, most of 2205 For the operators (callbacks) of each sound driver, most of
2210 these records are supposed to be read-only. Only the PCM 2206 these records are supposed to be read-only. Only the PCM
2211 middle-layer changes / updates them. The exceptions are 2207 middle-layer changes / updates them. The exceptions are
2212 the hardware description (hw), interrupt callbacks 2208 the hardware description (hw) DMA buffer information and the
2213 (transfer_ack_xxx), DMA buffer information, and the private 2209 private data. Besides, if you use the standard buffer allocation
2214 data. Besides, if you use the standard buffer allocation
2215 method via <function>snd_pcm_lib_malloc_pages()</function>, 2210 method via <function>snd_pcm_lib_malloc_pages()</function>,
2216 you don't need to set the DMA buffer information by yourself. 2211 you don't need to set the DMA buffer information by yourself.
2217 </para> 2212 </para>
@@ -2538,16 +2533,6 @@ struct _snd_pcm_runtime {
2538 </para> 2533 </para>
2539 </section> 2534 </section>
2540 2535
2541 <section id="pcm-interface-runtime-intr">
2542 <title>Interrupt Callbacks</title>
2543 <para>
2544 The field <structfield>transfer_ack_begin</structfield> and
2545 <structfield>transfer_ack_end</structfield> are called at
2546 the beginning and at the end of
2547 <function>snd_pcm_period_elapsed()</function>, respectively.
2548 </para>
2549 </section>
2550
2551 </section> 2536 </section>
2552 2537
2553 <section id="pcm-interface-operators"> 2538 <section id="pcm-interface-operators">
diff --git a/Documentation/devicetree/bindings/sound/ak4613.txt b/Documentation/devicetree/bindings/sound/ak4613.txt
new file mode 100644
index 000000000000..15a919522b42
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/ak4613.txt
@@ -0,0 +1,17 @@
1AK4613 I2C transmitter
2
3This device supports I2C mode only.
4
5Required properties:
6
7- compatible : "asahi-kasei,ak4613"
8- reg : The chip select number on the I2C bus
9
10Example:
11
12&i2c {
13 ak4613: ak4613@0x10 {
14 compatible = "asahi-kasei,ak4613";
15 reg = <0x10>;
16 };
17};
diff --git a/Documentation/devicetree/bindings/sound/ak4642.txt b/Documentation/devicetree/bindings/sound/ak4642.txt
index 623d4e70ae11..340784db6808 100644
--- a/Documentation/devicetree/bindings/sound/ak4642.txt
+++ b/Documentation/devicetree/bindings/sound/ak4642.txt
@@ -7,7 +7,14 @@ Required properties:
7 - compatible : "asahi-kasei,ak4642" or "asahi-kasei,ak4643" or "asahi-kasei,ak4648" 7 - compatible : "asahi-kasei,ak4642" or "asahi-kasei,ak4643" or "asahi-kasei,ak4648"
8 - reg : The chip select number on the I2C bus 8 - reg : The chip select number on the I2C bus
9 9
10Example: 10Optional properties:
11
12 - #clock-cells : common clock binding; shall be set to 0
13 - clocks : common clock binding; MCKI clock
14 - clock-frequency : common clock binding; frequency of MCKO
15 - clock-output-names : common clock binding; MCKO clock name
16
17Example 1:
11 18
12&i2c { 19&i2c {
13 ak4648: ak4648@0x12 { 20 ak4648: ak4648@0x12 {
@@ -15,3 +22,16 @@ Example:
15 reg = <0x12>; 22 reg = <0x12>;
16 }; 23 };
17}; 24};
25
26Example 2:
27
28&i2c {
29 ak4643: codec@12 {
30 compatible = "asahi-kasei,ak4643";
31 reg = <0x12>;
32 #clock-cells = <0>;
33 clocks = <&audio_clock>;
34 clock-frequency = <12288000>;
35 clock-output-names = "ak4643_mcko";
36 };
37};
diff --git a/Documentation/devicetree/bindings/sound/atmel-classd.txt b/Documentation/devicetree/bindings/sound/atmel-classd.txt
new file mode 100644
index 000000000000..0018451c4351
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/atmel-classd.txt
@@ -0,0 +1,52 @@
1* Atmel ClassD driver under ALSA SoC architecture
2
3Required properties:
4- compatible
5 Should be "atmel,sama5d2-classd".
6- reg
7 Should contain ClassD registers location and length.
8- interrupts
9 Should contain the IRQ line for the ClassD.
10- dmas
11 One DMA specifiers as described in atmel-dma.txt and dma.txt files.
12- dma-names
13 Must be "tx".
14- clock-names
15 Tuple listing input clock names.
16 Required elements: "pclk", "gclk" and "aclk".
17- clocks
18 Please refer to clock-bindings.txt.
19
20Optional properties:
21- pinctrl-names, pinctrl-0
22 Please refer to pinctrl-bindings.txt.
23- atmel,model
24 The user-visible name of this sound complex.
25 The default value is "CLASSD".
26- atmel,pwm-type
27 PWM modulation type, "single" or "diff".
28 The default value is "single".
29- atmel,non-overlap-time
30 Set non-overlapping time, the unit is nanosecond(ns).
31 There are four values,
32 <5>, <10>, <15>, <20>, the default value is <10>.
33 Non-overlapping will be disabled if not specified.
34
35Example:
36classd: classd@fc048000 {
37 compatible = "atmel,sama5d2-classd";
38 reg = <0xfc048000 0x100>;
39 interrupts = <59 IRQ_TYPE_LEVEL_HIGH 7>;
40 dmas = <&dma0
41 (AT91_XDMAC_DT_MEM_IF(0) | AT91_XDMAC_DT_PER_IF(1)
42 | AT91_XDMAC_DT_PERID(47))>;
43 dma-names = "tx";
44 clocks = <&classd_clk>, <&classd_gclk>, <&audio_pll_pmc>;
45 clock-names = "pclk", "gclk", "aclk";
46
47 pinctrl-names = "default";
48 pinctrl-0 = <&pinctrl_classd_default>;
49 atmel,model = "classd @ SAMA5D2-Xplained";
50 atmel,pwm-type = "diff";
51 atmel,non-overlap-time = <10>;
52};
diff --git a/Documentation/devicetree/bindings/sound/da7213.txt b/Documentation/devicetree/bindings/sound/da7213.txt
new file mode 100644
index 000000000000..58902802d56c
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/da7213.txt
@@ -0,0 +1,41 @@
1Dialog Semiconductor DA7213 Audio Codec bindings
2
3======
4
5Required properties:
6- compatible : Should be "dlg,da7213"
7- reg: Specifies the I2C slave address
8
9Optional properties:
10- clocks : phandle and clock specifier for codec MCLK.
11- clock-names : Clock name string for 'clocks' attribute, should be "mclk".
12
13- dlg,micbias1-lvl : Voltage (mV) for Mic Bias 1
14 [<1600>, <2200>, <2500>, <3000>]
15- dlg,micbias2-lvl : Voltage (mV) for Mic Bias 2
16 [<1600>, <2200>, <2500>, <3000>]
17- dlg,dmic-data-sel : DMIC channel select based on clock edge.
18 ["lrise_rfall", "lfall_rrise"]
19- dlg,dmic-samplephase : When to sample audio from DMIC.
20 ["on_clkedge", "between_clkedge"]
21- dlg,dmic-clkrate : DMIC clock frequency (Hz).
22 [<1500000>, <3000000>]
23
24======
25
26Example:
27
28 codec_i2c: da7213@1a {
29 compatible = "dlg,da7213";
30 reg = <0x1a>;
31
32 clocks = <&clks 201>;
33 clock-names = "mclk";
34
35 dlg,micbias1-lvl = <2500>;
36 dlg,micbias2-lvl = <2500>;
37
38 dlg,dmic-data-sel = "lrise_rfall";
39 dlg,dmic-samplephase = "between_clkedge";
40 dlg,dmic-clkrate = <3000000>;
41 };
diff --git a/Documentation/devicetree/bindings/sound/da7219.txt b/Documentation/devicetree/bindings/sound/da7219.txt
new file mode 100644
index 000000000000..1b7030911a3b
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/da7219.txt
@@ -0,0 +1,106 @@
1Dialog Semiconductor DA7219 Audio Codec bindings
2
3DA7219 is an audio codec with advanced accessory detect features.
4
5======
6
7Required properties:
8- compatible : Should be "dlg,da7219"
9- reg: Specifies the I2C slave address
10
11- interrupt-parent : Specifies the phandle of the interrupt controller to which
12 the IRQs from DA7219 are delivered to.
13- interrupts : IRQ line info for DA7219.
14 (See Documentation/devicetree/bindings/interrupt-controller/interrupts.txt for
15 further information relating to interrupt properties)
16
17- VDD-supply: VDD power supply for the device
18- VDDMIC-supply: VDDMIC power supply for the device
19- VDDIO-supply: VDDIO power supply for the device
20 (See Documentation/devicetree/bindings/regulator/regulator.txt for further
21 information relating to regulators)
22
23Optional properties:
24- interrupt-names : Name associated with interrupt line. Should be "wakeup" if
25 interrupt is to be used to wake system, otherwise "irq" should be used.
26- wakeup-source: Flag to indicate this device can wake system (suspend/resume).
27
28- clocks : phandle and clock specifier for codec MCLK.
29- clock-names : Clock name string for 'clocks' attribute, should be "mclk".
30
31- dlg,ldo-lvl : Required internal LDO voltage (mV) level for digital engine
32 [<1050>, <1100>, <1200>, <1400>]
33- dlg,micbias-lvl : Voltage (mV) for Mic Bias
34 [<1800>, <2000>, <2200>, <2400>, <2600>]
35- dlg,mic-amp-in-sel : Mic input source type
36 ["diff", "se_p", "se_n"]
37
38======
39
40Child node - 'da7219_aad':
41
42Optional properties:
43- dlg,micbias-pulse-lvl : Mic bias higher voltage pulse level (mV).
44 [<2800>, <2900>]
45- dlg,micbias-pulse-time : Mic bias higher voltage pulse duration (ms)
46- dlg,btn-cfg : Periodic button press measurements for 4-pole jack (ms)
47 [<2>, <5>, <10>, <50>, <100>, <200>, <500>]
48- dlg,mic-det-thr : Impedance threshold for mic detection measurement (Ohms)
49 [<200>, <500>, <750>, <1000>]
50- dlg,jack-ins-deb : Debounce time for jack insertion (ms)
51 [<5>, <10>, <20>, <50>, <100>, <200>, <500>, <1000>]
52- dlg,jack-det-rate: Jack type detection latency (3/4 pole)
53 ["32ms_64ms", "64ms_128ms", "128ms_256ms", "256ms_512ms"]
54- dlg,jack-rem-deb : Debounce time for jack removal (ms)
55 [<1>, <5>, <10>, <20>]
56- dlg,a-d-btn-thr : Impedance threshold between buttons A and D
57 [0x0 - 0xFF]
58- dlg,d-b-btn-thr : Impedance threshold between buttons D and B
59 [0x0 - 0xFF]
60- dlg,b-c-btn-thr : Impedance threshold between buttons B and C
61 [0x0 - 0xFF]
62- dlg,c-mic-btn-thr : Impedance threshold between button C and Mic
63 [0x0 - 0xFF]
64- dlg,btn-avg : Number of 8-bit readings for averaged button measurement
65 [<1>, <2>, <4>, <8>]
66- dlg,adc-1bit-rpt : Repeat count for 1-bit button measurement
67 [<1>, <2>, <4>, <8>]
68
69======
70
71Example:
72
73 codec: da7219@1a {
74 compatible = "dlg,da7219";
75 reg = <0x1a>;
76
77 interrupt-parent = <&gpio6>;
78 interrupts = <11 IRQ_TYPE_LEVEL_HIGH>;
79
80 VDD-supply = <&reg_audio>;
81 VDDMIC-supply = <&reg_audio>;
82 VDDIO-supply = <&reg_audio>;
83
84 clocks = <&clks 201>;
85 clock-names = "mclk";
86
87 dlg,ldo-lvl = <1200>;
88 dlg,micbias-lvl = <2600>;
89 dlg,mic-amp-in-sel = "diff";
90
91 da7219_aad {
92 dlg,btn-cfg = <50>;
93 dlg,mic-det-thr = <500>;
94 dlg,jack-ins-deb = <20>;
95 dlg,jack-det-rate = "32ms_64ms";
96 dlg,jack-rem-deb = <1>;
97
98 dlg,a-d-btn-thr = <0xa>;
99 dlg,d-b-btn-thr = <0x16>;
100 dlg,b-c-btn-thr = <0x21>;
101 dlg,c-mic-btn-thr = <0x3E>;
102
103 dlg,btn-avg = <4>;
104 dlg,adc-1bit-rpt = <1>;
105 };
106 };
diff --git a/Documentation/devicetree/bindings/sound/fsl-asoc-card.txt b/Documentation/devicetree/bindings/sound/fsl-asoc-card.txt
index a96774c194c8..ce55c0a6f757 100644
--- a/Documentation/devicetree/bindings/sound/fsl-asoc-card.txt
+++ b/Documentation/devicetree/bindings/sound/fsl-asoc-card.txt
@@ -13,13 +13,15 @@ So having this generic sound card allows all Freescale SoC users to benefit
13from the simplification of a new card support and the capability of the wide 13from the simplification of a new card support and the capability of the wide
14sample rates support through ASRC. 14sample rates support through ASRC.
15 15
16Note: The card is initially designed for those sound cards who use I2S and 16Note: The card is initially designed for those sound cards who use AC'97, I2S
17 PCM DAI formats. However, it'll be also possible to support those non 17 and PCM DAI formats. However, it'll be also possible to support those non
18 I2S/PCM type sound cards, such as S/PDIF audio and HDMI audio, as long 18 AC'97/I2S/PCM type sound cards, such as S/PDIF audio and HDMI audio, as
19 as the driver has been properly upgraded. 19 long as the driver has been properly upgraded.
20 20
21 21
22The compatible list for this generic sound card currently: 22The compatible list for this generic sound card currently:
23 "fsl,imx-audio-ac97"
24
23 "fsl,imx-audio-cs42888" 25 "fsl,imx-audio-cs42888"
24 26
25 "fsl,imx-audio-wm8962" 27 "fsl,imx-audio-wm8962"
diff --git a/Documentation/devicetree/bindings/sound/nau8825.txt b/Documentation/devicetree/bindings/sound/nau8825.txt
new file mode 100644
index 000000000000..d3374231c871
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/nau8825.txt
@@ -0,0 +1,102 @@
1Nuvoton NAU8825 audio codec
2
3This device supports I2C only.
4
5Required properties:
6 - compatible : Must be "nuvoton,nau8825"
7
8 - reg : the I2C address of the device. This is either 0x1a (CSB=0) or 0x1b (CSB=1).
9
10Optional properties:
11 - nuvoton,jkdet-enable: Enable jack detection via JKDET pin.
12 - nuvoton,jkdet-pull-enable: Enable JKDET pin pull. If set - pin pull enabled,
13 otherwise pin in high impedance state.
14 - nuvoton,jkdet-pull-up: Pull-up JKDET pin. If set then JKDET pin is pull up, otherwise pull down.
15 - nuvoton,jkdet-polarity: JKDET pin polarity. 0 - active high, 1 - active low.
16
17 - nuvoton,vref-impedance: VREF Impedance selection
18 0 - Open
19 1 - 25 kOhm
20 2 - 125 kOhm
21 3 - 2.5 kOhm
22
23 - nuvoton,micbias-voltage: Micbias voltage level.
24 0 - VDDA
25 1 - VDDA
26 2 - VDDA * 1.1
27 3 - VDDA * 1.2
28 4 - VDDA * 1.3
29 5 - VDDA * 1.4
30 6 - VDDA * 1.53
31 7 - VDDA * 1.53
32
33 - nuvoton,sar-threshold-num: Number of buttons supported
34 - nuvoton,sar-threshold: Impedance threshold for each button. Array that contains up to 8 buttons configuration. SAR value is calculated as
35 SAR = 255 * MICBIAS / SAR_VOLTAGE * R / (2000 + R)
36 where MICBIAS is configured by 'nuvoton,micbias-voltage', SAR_VOLTAGE is configured by 'nuvoton,sar-voltage', R - button impedance.
37 Refer datasheet section 10.2 for more information about threshold calculation.
38
39 - nuvoton,sar-hysteresis: Button impedance measurement hysteresis.
40
41 - nuvoton,sar-voltage: Reference voltage for button impedance measurement.
42 0 - VDDA
43 1 - VDDA
44 2 - VDDA * 1.1
45 3 - VDDA * 1.2
46 4 - VDDA * 1.3
47 5 - VDDA * 1.4
48 6 - VDDA * 1.53
49 7 - VDDA * 1.53
50
51 - nuvoton,sar-compare-time: SAR compare time
52 0 - 500 ns
53 1 - 1 us
54 2 - 2 us
55 3 - 4 us
56
57 - nuvoton,sar-sampling-time: SAR sampling time
58 0 - 2 us
59 1 - 4 us
60 2 - 8 us
61 3 - 16 us
62
63 - nuvoton,short-key-debounce: Button short key press debounce time.
64 0 - 30 ms
65 1 - 50 ms
66 2 - 100 ms
67 3 - 30 ms
68
69 - nuvoton,jack-insert-debounce: number from 0 to 7 that sets debounce time to 2^(n+2) ms
70 - nuvoton,jack-eject-debounce: number from 0 to 7 that sets debounce time to 2^(n+2) ms
71
72 - clocks: list of phandle and clock specifier pairs according to common clock bindings for the
73 clocks described in clock-names
74 - clock-names: should include "mclk" for the MCLK master clock
75
76Example:
77
78 headset: nau8825@1a {
79 compatible = "nuvoton,nau8825";
80 reg = <0x1a>;
81 interrupt-parent = <&gpio>;
82 interrupts = <TEGRA_GPIO(E, 6) IRQ_TYPE_LEVEL_LOW>;
83 nuvoton,jkdet-enable;
84 nuvoton,jkdet-pull-enable;
85 nuvoton,jkdet-pull-up;
86 nuvoton,jkdet-polarity = <GPIO_ACTIVE_LOW>;
87 nuvoton,vref-impedance = <2>;
88 nuvoton,micbias-voltage = <6>;
89 // Setup 4 buttons impedance according to Android specification
90 nuvoton,sar-threshold-num = <4>;
91 nuvoton,sar-threshold = <0xc 0x1e 0x38 0x60>;
92 nuvoton,sar-hysteresis = <1>;
93 nuvoton,sar-voltage = <0>;
94 nuvoton,sar-compare-time = <0>;
95 nuvoton,sar-sampling-time = <0>;
96 nuvoton,short-key-debounce = <2>;
97 nuvoton,jack-insert-debounce = <7>;
98 nuvoton,jack-eject-debounce = <7>;
99
100 clock-names = "mclk";
101 clocks = <&tegra_car TEGRA210_CLK_CLK_OUT_2>;
102 };
diff --git a/Documentation/devicetree/bindings/sound/renesas,rsnd.txt b/Documentation/devicetree/bindings/sound/renesas,rsnd.txt
index 1173395b5e5c..c57cbd65736c 100644
--- a/Documentation/devicetree/bindings/sound/renesas,rsnd.txt
+++ b/Documentation/devicetree/bindings/sound/renesas,rsnd.txt
@@ -4,10 +4,12 @@ Required properties:
4- compatible : "renesas,rcar_sound-<soctype>", fallbacks 4- compatible : "renesas,rcar_sound-<soctype>", fallbacks
5 "renesas,rcar_sound-gen1" if generation1, and 5 "renesas,rcar_sound-gen1" if generation1, and
6 "renesas,rcar_sound-gen2" if generation2 6 "renesas,rcar_sound-gen2" if generation2
7 "renesas,rcar_sound-gen3" if generation3
7 Examples with soctypes are: 8 Examples with soctypes are:
8 - "renesas,rcar_sound-r8a7778" (R-Car M1A) 9 - "renesas,rcar_sound-r8a7778" (R-Car M1A)
9 - "renesas,rcar_sound-r8a7790" (R-Car H2) 10 - "renesas,rcar_sound-r8a7790" (R-Car H2)
10 - "renesas,rcar_sound-r8a7791" (R-Car M2-W) 11 - "renesas,rcar_sound-r8a7791" (R-Car M2-W)
12 - "renesas,rcar_sound-r8a7795" (R-Car H3)
11- reg : Should contain the register physical address. 13- reg : Should contain the register physical address.
12 required register is 14 required register is
13 SRU/ADG/SSI if generation1 15 SRU/ADG/SSI if generation1
@@ -30,6 +32,11 @@ Required properties:
30- rcar_sound,dai : DAI contents. 32- rcar_sound,dai : DAI contents.
31 The number of DAI subnode should be same as HW. 33 The number of DAI subnode should be same as HW.
32 see below for detail. 34 see below for detail.
35- #sound-dai-cells : it must be 0 if your system is using single DAI
36 it must be 1 if your system is using multi DAI
37- #clock-cells : it must be 0 if your system has audio_clkout
38 it must be 1 if your system has audio_clkout0/1/2/3
39- clock-frequency : for all audio_clkout0/1/2/3
33 40
34SSI subnode properties: 41SSI subnode properties:
35- interrupts : Should contain SSI interrupt for PIO transfer 42- interrupts : Should contain SSI interrupt for PIO transfer
diff --git a/Documentation/devicetree/bindings/sound/rockchip-i2s.txt b/Documentation/devicetree/bindings/sound/rockchip-i2s.txt
index 9b82c20b306b..2267d249ca0e 100644
--- a/Documentation/devicetree/bindings/sound/rockchip-i2s.txt
+++ b/Documentation/devicetree/bindings/sound/rockchip-i2s.txt
@@ -12,8 +12,6 @@ Required properties:
12- reg: physical base address of the controller and length of memory mapped 12- reg: physical base address of the controller and length of memory mapped
13 region. 13 region.
14- interrupts: should contain the I2S interrupt. 14- interrupts: should contain the I2S interrupt.
15- #address-cells: should be 1.
16- #size-cells: should be 0.
17- dmas: DMA specifiers for tx and rx dma. See the DMA client binding, 15- dmas: DMA specifiers for tx and rx dma. See the DMA client binding,
18 Documentation/devicetree/bindings/dma/dma.txt 16 Documentation/devicetree/bindings/dma/dma.txt
19- dma-names: should include "tx" and "rx". 17- dma-names: should include "tx" and "rx".
@@ -21,6 +19,7 @@ Required properties:
21- clock-names: should contain followings: 19- clock-names: should contain followings:
22 - "i2s_hclk": clock for I2S BUS 20 - "i2s_hclk": clock for I2S BUS
23 - "i2s_clk" : clock for I2S controller 21 - "i2s_clk" : clock for I2S controller
22- rockchip,capture-channels: max capture channels, if not set, 2 channels default.
24 23
25Example for rk3288 I2S controller: 24Example for rk3288 I2S controller:
26 25
@@ -28,10 +27,9 @@ i2s@ff890000 {
28 compatible = "rockchip,rk3288-i2s", "rockchip,rk3066-i2s"; 27 compatible = "rockchip,rk3288-i2s", "rockchip,rk3066-i2s";
29 reg = <0xff890000 0x10000>; 28 reg = <0xff890000 0x10000>;
30 interrupts = <GIC_SPI 85 IRQ_TYPE_LEVEL_HIGH>; 29 interrupts = <GIC_SPI 85 IRQ_TYPE_LEVEL_HIGH>;
31 #address-cells = <1>;
32 #size-cells = <0>;
33 dmas = <&pdma1 0>, <&pdma1 1>; 30 dmas = <&pdma1 0>, <&pdma1 1>;
34 dma-names = "tx", "rx"; 31 dma-names = "tx", "rx";
35 clock-names = "i2s_hclk", "i2s_clk"; 32 clock-names = "i2s_hclk", "i2s_clk";
36 clocks = <&cru HCLK_I2S0>, <&cru SCLK_I2S0>; 33 clocks = <&cru HCLK_I2S0>, <&cru SCLK_I2S0>;
34 rockchip,capture-channels = <2>;
37}; 35};
diff --git a/Documentation/devicetree/bindings/sound/rockchip-spdif.txt b/Documentation/devicetree/bindings/sound/rockchip-spdif.txt
new file mode 100644
index 000000000000..e64dbdea7db9
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/rockchip-spdif.txt
@@ -0,0 +1,40 @@
1* Rockchip SPDIF transceiver
2
3The S/PDIF audio block is a stereo transceiver that allows the
4processor to receive and transmit digital audio via an coaxial cable or
5a fibre cable.
6
7Required properties:
8
9- compatible: should be one of the following:
10 - "rockchip,rk3288-spdif", "rockchip,rk3188-spdif" or
11 "rockchip,rk3066-spdif"
12- reg: physical base address of the controller and length of memory mapped
13 region.
14- interrupts: should contain the SPDIF interrupt.
15- dmas: DMA specifiers for tx dma. See the DMA client binding,
16 Documentation/devicetree/bindings/dma/dma.txt
17- dma-names: should be "tx"
18- clocks: a list of phandle + clock-specifier pairs, one for each entry
19 in clock-names.
20- clock-names: should contain following:
21 - "hclk": clock for SPDIF controller
22 - "mclk" : clock for SPDIF bus
23
24Required properties on RK3288:
25 - rockchip,grf: the phandle of the syscon node for the general register
26 file (GRF)
27
28Example for the rk3188 SPDIF controller:
29
30spdif: spdif@0x1011e000 {
31 compatible = "rockchip,rk3188-spdif", "rockchip,rk3066-spdif";
32 reg = <0x1011e000 0x2000>;
33 interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>;
34 dmas = <&dmac1_s 8>;
35 dma-names = "tx";
36 clock-names = "hclk", "mclk";
37 clocks = <&cru HCLK_SPDIF>, <&cru SCLK_SPDIF>;
38 status = "disabled";
39 #sound-dai-cells = <0>;
40};
diff --git a/Documentation/devicetree/bindings/sound/rt5640.txt b/Documentation/devicetree/bindings/sound/rt5640.txt
index bac4d9ac1edc..9e62f6eb348f 100644
--- a/Documentation/devicetree/bindings/sound/rt5640.txt
+++ b/Documentation/devicetree/bindings/sound/rt5640.txt
@@ -14,7 +14,8 @@ Optional properties:
14 14
15- realtek,in1-differential 15- realtek,in1-differential
16- realtek,in2-differential 16- realtek,in2-differential
17 Boolean. Indicate MIC1/2 input are differential, rather than single-ended. 17- realtek,in3-differential
18 Boolean. Indicate MIC1/2/3 input are differential, rather than single-ended.
18 19
19- realtek,ldo1-en-gpios : The GPIO that controls the CODEC's LDO1_EN pin. 20- realtek,ldo1-en-gpios : The GPIO that controls the CODEC's LDO1_EN pin.
20 21
@@ -24,9 +25,11 @@ Pins on the device (for linking into audio routes) for RT5639/RT5640:
24 * DMIC2 25 * DMIC2
25 * MICBIAS1 26 * MICBIAS1
26 * IN1P 27 * IN1P
27 * IN1R 28 * IN1N
28 * IN2P 29 * IN2P
29 * IN2R 30 * IN2N
31 * IN3P
32 * IN3N
30 * HPOL 33 * HPOL
31 * HPOR 34 * HPOR
32 * LOUTL 35 * LOUTL
diff --git a/Documentation/devicetree/bindings/sound/sun4i-codec.txt b/Documentation/devicetree/bindings/sound/sun4i-codec.txt
new file mode 100644
index 000000000000..c92966bd5488
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/sun4i-codec.txt
@@ -0,0 +1,27 @@
1* Allwinner A10 Codec
2
3Required properties:
4- compatible: must be either "allwinner,sun4i-a10-codec" or
5 "allwinner,sun7i-a20-codec"
6- reg: must contain the registers location and length
7- interrupts: must contain the codec interrupt
8- dmas: DMA channels for tx and rx dma. See the DMA client binding,
9 Documentation/devicetree/bindings/dma/dma.txt
10- dma-names: should include "tx" and "rx".
11- clocks: a list of phandle + clock-specifer pairs, one for each entry
12 in clock-names.
13- clock-names: should contain followings:
14 - "apb": the parent APB clock for this controller
15 - "codec": the parent module clock
16
17Example:
18codec: codec@01c22c00 {
19 #sound-dai-cells = <0>;
20 compatible = "allwinner,sun7i-a20-codec";
21 reg = <0x01c22c00 0x40>;
22 interrupts = <0 30 4>;
23 clocks = <&apb0_gates 0>, <&codec_clk>;
24 clock-names = "apb", "codec";
25 dmas = <&dma 0 19>, <&dma 0 19>;
26 dma-names = "rx", "tx";
27};
diff --git a/Documentation/devicetree/bindings/sound/tdm-slot.txt b/Documentation/devicetree/bindings/sound/tdm-slot.txt
index 6a2c84247f91..34cf70e2cbc4 100644
--- a/Documentation/devicetree/bindings/sound/tdm-slot.txt
+++ b/Documentation/devicetree/bindings/sound/tdm-slot.txt
@@ -4,11 +4,15 @@ This specifies audio DAI's TDM slot.
4 4
5TDM slot properties: 5TDM slot properties:
6dai-tdm-slot-num : Number of slots in use. 6dai-tdm-slot-num : Number of slots in use.
7dai-tdm-slot-width : Width in bits for each slot. 7dai-tdm-slot-width : Width in bits for each slot.
8dai-tdm-slot-tx-mask : Transmit direction slot mask, optional
9dai-tdm-slot-rx-mask : Receive direction slot mask, optional
8 10
9For instance: 11For instance:
10 dai-tdm-slot-num = <2>; 12 dai-tdm-slot-num = <2>;
11 dai-tdm-slot-width = <8>; 13 dai-tdm-slot-width = <8>;
14 dai-tdm-slot-tx-mask = <0 1>;
15 dai-tdm-slot-rx-mask = <1 0>;
12 16
13And for each spcified driver, there could be one .of_xlate_tdm_slot_mask() 17And for each spcified driver, there could be one .of_xlate_tdm_slot_mask()
14to specify a explicit mapping of the channels and the slots. If it's absent 18to specify a explicit mapping of the channels and the slots. If it's absent
@@ -18,3 +22,8 @@ tx and rx masks.
18For snd_soc_of_xlate_tdm_slot_mask(), the tx and rx masks will use a 1 bit 22For snd_soc_of_xlate_tdm_slot_mask(), the tx and rx masks will use a 1 bit
19for an active slot as default, and the default active bits are at the LSB of 23for an active slot as default, and the default active bits are at the LSB of
20the masks. 24the masks.
25
26The explicit masks are given as array of integers, where the first
27number presents bit-0 (LSB), second presents bit-1, etc. Any non zero
28number is considered 1 and 0 is 0. snd_soc_of_xlate_tdm_slot_mask()
29does not do anything, if either mask is set non zero value.
diff --git a/Documentation/sound/alsa/hda_codec.txt b/Documentation/sound/alsa/hda_codec.txt
deleted file mode 100644
index de8efbc7e4bd..000000000000
--- a/Documentation/sound/alsa/hda_codec.txt
+++ /dev/null
@@ -1,322 +0,0 @@
1Notes on Universal Interface for Intel High Definition Audio Codec
2------------------------------------------------------------------
3
4Takashi Iwai <tiwai@suse.de>
5
6
7[Still a draft version]
8
9
10General
11=======
12
13The snd-hda-codec module supports the generic access function for the
14High Definition (HD) audio codecs. It's designed to be independent
15from the controller code like ac97 codec module. The real accessors
16from/to the controller must be implemented in the lowlevel driver.
17
18The structure of this module is similar with ac97_codec module.
19Each codec chip belongs to a bus class which communicates with the
20controller.
21
22
23Initialization of Bus Instance
24==============================
25
26The card driver has to create struct hda_bus at first. The template
27struct should be filled and passed to the constructor:
28
29struct hda_bus_template {
30 void *private_data;
31 struct pci_dev *pci;
32 const char *modelname;
33 struct hda_bus_ops ops;
34};
35
36The card driver can set and use the private_data field to retrieve its
37own data in callback functions. The pci field is used when the patch
38needs to check the PCI subsystem IDs, so on. For non-PCI system, it
39doesn't have to be set, of course.
40The modelname field specifies the board's specific configuration. The
41string is passed to the codec parser, and it depends on the parser how
42the string is used.
43These fields, private_data, pci and modelname are all optional.
44
45The ops field contains the callback functions as the following:
46
47struct hda_bus_ops {
48 int (*command)(struct hda_codec *codec, hda_nid_t nid, int direct,
49 unsigned int verb, unsigned int parm);
50 unsigned int (*get_response)(struct hda_codec *codec);
51 void (*private_free)(struct hda_bus *);
52#ifdef CONFIG_SND_HDA_POWER_SAVE
53 void (*pm_notify)(struct hda_codec *codec);
54#endif
55};
56
57The command callback is called when the codec module needs to send a
58VERB to the controller. It's always a single command.
59The get_response callback is called when the codec requires the answer
60for the last command. These two callbacks are mandatory and have to
61be given.
62The third, private_free callback, is optional. It's called in the
63destructor to release any necessary data in the lowlevel driver.
64
65The pm_notify callback is available only with
66CONFIG_SND_HDA_POWER_SAVE kconfig. It's called when the codec needs
67to power up or may power down. The controller should check the all
68belonging codecs on the bus whether they are actually powered off
69(check codec->power_on), and optionally the driver may power down the
70controller side, too.
71
72The bus instance is created via snd_hda_bus_new(). You need to pass
73the card instance, the template, and the pointer to store the
74resultant bus instance.
75
76int snd_hda_bus_new(struct snd_card *card, const struct hda_bus_template *temp,
77 struct hda_bus **busp);
78
79It returns zero if successful. A negative return value means any
80error during creation.
81
82
83Creation of Codec Instance
84==========================
85
86Each codec chip on the board is then created on the BUS instance.
87To create a codec instance, call snd_hda_codec_new().
88
89int snd_hda_codec_new(struct hda_bus *bus, unsigned int codec_addr,
90 struct hda_codec **codecp);
91
92The first argument is the BUS instance, the second argument is the
93address of the codec, and the last one is the pointer to store the
94resultant codec instance (can be NULL if not needed).
95
96The codec is stored in a linked list of bus instance. You can follow
97the codec list like:
98
99 struct hda_codec *codec;
100 list_for_each_entry(codec, &bus->codec_list, list) {
101 ...
102 }
103
104The codec isn't initialized at this stage properly. The
105initialization sequence is called when the controls are built later.
106
107
108Codec Access
109============
110
111To access codec, use snd_hda_codec_read() and snd_hda_codec_write().
112snd_hda_param_read() is for reading parameters.
113For writing a sequence of verbs, use snd_hda_sequence_write().
114
115There are variants of cached read/write, snd_hda_codec_write_cache(),
116snd_hda_sequence_write_cache(). These are used for recording the
117register states for the power-management resume. When no PM is needed,
118these are equivalent with non-cached version.
119
120To retrieve the number of sub nodes connected to the given node, use
121snd_hda_get_sub_nodes(). The connection list can be obtained via
122snd_hda_get_connections() call.
123
124When an unsolicited event happens, pass the event via
125snd_hda_queue_unsol_event() so that the codec routines will process it
126later.
127
128
129(Mixer) Controls
130================
131
132To create mixer controls of all codecs, call
133snd_hda_build_controls(). It then builds the mixers and does
134initialization stuff on each codec.
135
136
137PCM Stuff
138=========
139
140snd_hda_build_pcms() gives the necessary information to create PCM
141streams. When it's called, each codec belonging to the bus stores
142codec->num_pcms and codec->pcm_info fields. The num_pcms indicates
143the number of elements in pcm_info array. The card driver is supposed
144to traverse the codec linked list, read the pcm information in
145pcm_info array, and build pcm instances according to them.
146
147The pcm_info array contains the following record:
148
149/* PCM information for each substream */
150struct hda_pcm_stream {
151 unsigned int substreams; /* number of substreams, 0 = not exist */
152 unsigned int channels_min; /* min. number of channels */
153 unsigned int channels_max; /* max. number of channels */
154 hda_nid_t nid; /* default NID to query rates/formats/bps, or set up */
155 u32 rates; /* supported rates */
156 u64 formats; /* supported formats (SNDRV_PCM_FMTBIT_) */
157 unsigned int maxbps; /* supported max. bit per sample */
158 struct hda_pcm_ops ops;
159};
160
161/* for PCM creation */
162struct hda_pcm {
163 char *name;
164 struct hda_pcm_stream stream[2];
165};
166
167The name can be passed to snd_pcm_new(). The stream field contains
168the information for playback (SNDRV_PCM_STREAM_PLAYBACK = 0) and
169capture (SNDRV_PCM_STREAM_CAPTURE = 1) directions. The card driver
170should pass substreams to snd_pcm_new() for the number of substreams
171to create.
172
173The channels_min, channels_max, rates and formats should be copied to
174runtime->hw record. They and maxbps fields are used also to compute
175the format value for the HDA codec and controller. Call
176snd_hda_calc_stream_format() to get the format value.
177
178The ops field contains the following callback functions:
179
180struct hda_pcm_ops {
181 int (*open)(struct hda_pcm_stream *info, struct hda_codec *codec,
182 struct snd_pcm_substream *substream);
183 int (*close)(struct hda_pcm_stream *info, struct hda_codec *codec,
184 struct snd_pcm_substream *substream);
185 int (*prepare)(struct hda_pcm_stream *info, struct hda_codec *codec,
186 unsigned int stream_tag, unsigned int format,
187 struct snd_pcm_substream *substream);
188 int (*cleanup)(struct hda_pcm_stream *info, struct hda_codec *codec,
189 struct snd_pcm_substream *substream);
190};
191
192All are non-NULL, so you can call them safely without NULL check.
193
194The open callback should be called in PCM open after runtime->hw is
195set up. It may override some setting and constraints additionally.
196Similarly, the close callback should be called in the PCM close.
197
198The prepare callback should be called in PCM prepare. This will set
199up the codec chip properly for the operation. The cleanup should be
200called in hw_free to clean up the configuration.
201
202The caller should check the return value, at least for open and
203prepare callbacks. When a negative value is returned, some error
204occurred.
205
206
207Proc Files
208==========
209
210Each codec dumps the widget node information in
211/proc/asound/card*/codec#* file. This information would be really
212helpful for debugging. Please provide its contents together with the
213bug report.
214
215
216Power Management
217================
218
219It's simple:
220Call snd_hda_suspend() in the PM suspend callback.
221Call snd_hda_resume() in the PM resume callback.
222
223
224Codec Preset (Patch)
225====================
226
227To set up and handle the codec functionality fully, each codec may
228have a codec preset (patch). It's defined in struct hda_codec_preset:
229
230 struct hda_codec_preset {
231 unsigned int id;
232 unsigned int mask;
233 unsigned int subs;
234 unsigned int subs_mask;
235 unsigned int rev;
236 const char *name;
237 int (*patch)(struct hda_codec *codec);
238 };
239
240When the codec id and codec subsystem id match with the given id and
241subs fields bitwise (with bitmask mask and subs_mask), the callback
242patch is called. The patch callback should initialize the codec and
243set the codec->patch_ops field. This is defined as below:
244
245 struct hda_codec_ops {
246 int (*build_controls)(struct hda_codec *codec);
247 int (*build_pcms)(struct hda_codec *codec);
248 int (*init)(struct hda_codec *codec);
249 void (*free)(struct hda_codec *codec);
250 void (*unsol_event)(struct hda_codec *codec, unsigned int res);
251 #ifdef CONFIG_PM
252 int (*suspend)(struct hda_codec *codec, pm_message_t state);
253 int (*resume)(struct hda_codec *codec);
254 #endif
255 #ifdef CONFIG_SND_HDA_POWER_SAVE
256 int (*check_power_status)(struct hda_codec *codec,
257 hda_nid_t nid);
258 #endif
259 };
260
261The build_controls callback is called from snd_hda_build_controls().
262Similarly, the build_pcms callback is called from
263snd_hda_build_pcms(). The init callback is called after
264build_controls to initialize the hardware.
265The free callback is called as a destructor.
266
267The unsol_event callback is called when an unsolicited event is
268received.
269
270The suspend and resume callbacks are for power management.
271They can be NULL if no special sequence is required. When the resume
272callback is NULL, the driver calls the init callback and resumes the
273registers from the cache. If other handling is needed, you'd need to
274write your own resume callback. There, the amp values can be resumed
275via
276 void snd_hda_codec_resume_amp(struct hda_codec *codec);
277and the other codec registers via
278 void snd_hda_codec_resume_cache(struct hda_codec *codec);
279
280The check_power_status callback is called when the amp value of the
281given widget NID is changed. The codec code can turn on/off the power
282appropriately from this information.
283
284Each entry can be NULL if not necessary to be called.
285
286
287Generic Parser
288==============
289
290When the device doesn't match with any given presets, the widgets are
291parsed via th generic parser (hda_generic.c). Its support is
292limited: no multi-channel support, for example.
293
294
295Digital I/O
296===========
297
298Call snd_hda_create_spdif_out_ctls() from the patch to create controls
299related with SPDIF out.
300
301
302Helper Functions
303================
304
305snd_hda_get_codec_name() stores the codec name on the given string.
306
307snd_hda_check_board_config() can be used to obtain the configuration
308information matching with the device. Define the model string table
309and the table with struct snd_pci_quirk entries (zero-terminated),
310and pass it to the function. The function checks the modelname given
311as a module parameter, and PCI subsystem IDs. If the matching entry
312is found, it returns the config field value.
313
314snd_hda_add_new_ctls() can be used to create and add control entries.
315Pass the zero-terminated array of struct snd_kcontrol_new
316
317Macros HDA_CODEC_VOLUME(), HDA_CODEC_MUTE() and their variables can be
318used for the entry of struct snd_kcontrol_new.
319
320The input MUX helper callbacks for such a control are provided, too:
321snd_hda_input_mux_info() and snd_hda_input_mux_put(). See
322patch_realtek.c for example.
diff --git a/MAINTAINERS b/MAINTAINERS
index 653ee9a7a3b8..4e65fdf92347 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -3403,6 +3403,7 @@ M: Support Opensource <support.opensource@diasemi.com>
3403W: http://www.dialog-semiconductor.com/products 3403W: http://www.dialog-semiconductor.com/products
3404S: Supported 3404S: Supported
3405F: Documentation/hwmon/da90?? 3405F: Documentation/hwmon/da90??
3406F: Documentation/devicetree/bindings/sound/da[79]*.txt
3406F: drivers/gpio/gpio-da90??.c 3407F: drivers/gpio/gpio-da90??.c
3407F: drivers/hwmon/da90??-hwmon.c 3408F: drivers/hwmon/da90??-hwmon.c
3408F: drivers/iio/adc/da91??-*.c 3409F: drivers/iio/adc/da91??-*.c
diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c
index ab37d1121be8..990f656e6ab0 100644
--- a/drivers/gpu/drm/i915/i915_dma.c
+++ b/drivers/gpu/drm/i915/i915_dma.c
@@ -832,6 +832,7 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
832 mutex_init(&dev_priv->sb_lock); 832 mutex_init(&dev_priv->sb_lock);
833 mutex_init(&dev_priv->modeset_restore_lock); 833 mutex_init(&dev_priv->modeset_restore_lock);
834 mutex_init(&dev_priv->csr_lock); 834 mutex_init(&dev_priv->csr_lock);
835 mutex_init(&dev_priv->av_mutex);
835 836
836 intel_pm_setup(dev); 837 intel_pm_setup(dev);
837 838
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index e1db8de52851..22dd7043c9ef 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -1885,6 +1885,11 @@ struct drm_i915_private {
1885 /* hda/i915 audio component */ 1885 /* hda/i915 audio component */
1886 struct i915_audio_component *audio_component; 1886 struct i915_audio_component *audio_component;
1887 bool audio_component_registered; 1887 bool audio_component_registered;
1888 /**
1889 * av_mutex - mutex for audio/video sync
1890 *
1891 */
1892 struct mutex av_mutex;
1888 1893
1889 uint32_t hw_context_size; 1894 uint32_t hw_context_size;
1890 struct list_head context_list; 1895 struct list_head context_list;
diff --git a/drivers/gpu/drm/i915/intel_audio.c b/drivers/gpu/drm/i915/intel_audio.c
index 2a5c76faf9f8..ae8df0a43de6 100644
--- a/drivers/gpu/drm/i915/intel_audio.c
+++ b/drivers/gpu/drm/i915/intel_audio.c
@@ -68,6 +68,31 @@ static const struct {
68 { 148500, AUD_CONFIG_PIXEL_CLOCK_HDMI_148500 }, 68 { 148500, AUD_CONFIG_PIXEL_CLOCK_HDMI_148500 },
69}; 69};
70 70
71/* HDMI N/CTS table */
72#define TMDS_297M 297000
73#define TMDS_296M DIV_ROUND_UP(297000 * 1000, 1001)
74static const struct {
75 int sample_rate;
76 int clock;
77 int n;
78 int cts;
79} aud_ncts[] = {
80 { 44100, TMDS_296M, 4459, 234375 },
81 { 44100, TMDS_297M, 4704, 247500 },
82 { 48000, TMDS_296M, 5824, 281250 },
83 { 48000, TMDS_297M, 5120, 247500 },
84 { 32000, TMDS_296M, 5824, 421875 },
85 { 32000, TMDS_297M, 3072, 222750 },
86 { 88200, TMDS_296M, 8918, 234375 },
87 { 88200, TMDS_297M, 9408, 247500 },
88 { 96000, TMDS_296M, 11648, 281250 },
89 { 96000, TMDS_297M, 10240, 247500 },
90 { 176400, TMDS_296M, 17836, 234375 },
91 { 176400, TMDS_297M, 18816, 247500 },
92 { 192000, TMDS_296M, 23296, 281250 },
93 { 192000, TMDS_297M, 20480, 247500 },
94};
95
71/* get AUD_CONFIG_PIXEL_CLOCK_HDMI_* value for mode */ 96/* get AUD_CONFIG_PIXEL_CLOCK_HDMI_* value for mode */
72static u32 audio_config_hdmi_pixel_clock(struct drm_display_mode *mode) 97static u32 audio_config_hdmi_pixel_clock(struct drm_display_mode *mode)
73{ 98{
@@ -90,6 +115,45 @@ static u32 audio_config_hdmi_pixel_clock(struct drm_display_mode *mode)
90 return hdmi_audio_clock[i].config; 115 return hdmi_audio_clock[i].config;
91} 116}
92 117
118static int audio_config_get_n(const struct drm_display_mode *mode, int rate)
119{
120 int i;
121
122 for (i = 0; i < ARRAY_SIZE(aud_ncts); i++) {
123 if ((rate == aud_ncts[i].sample_rate) &&
124 (mode->clock == aud_ncts[i].clock)) {
125 return aud_ncts[i].n;
126 }
127 }
128 return 0;
129}
130
131static uint32_t audio_config_setup_n_reg(int n, uint32_t val)
132{
133 int n_low, n_up;
134 uint32_t tmp = val;
135
136 n_low = n & 0xfff;
137 n_up = (n >> 12) & 0xff;
138 tmp &= ~(AUD_CONFIG_UPPER_N_MASK | AUD_CONFIG_LOWER_N_MASK);
139 tmp |= ((n_up << AUD_CONFIG_UPPER_N_SHIFT) |
140 (n_low << AUD_CONFIG_LOWER_N_SHIFT) |
141 AUD_CONFIG_N_PROG_ENABLE);
142 return tmp;
143}
144
145/* check whether N/CTS/M need be set manually */
146static bool audio_rate_need_prog(struct intel_crtc *crtc,
147 const struct drm_display_mode *mode)
148{
149 if (((mode->clock == TMDS_297M) ||
150 (mode->clock == TMDS_296M)) &&
151 intel_pipe_has_type(crtc, INTEL_OUTPUT_HDMI))
152 return true;
153 else
154 return false;
155}
156
93static bool intel_eld_uptodate(struct drm_connector *connector, 157static bool intel_eld_uptodate(struct drm_connector *connector,
94 int reg_eldv, uint32_t bits_eldv, 158 int reg_eldv, uint32_t bits_eldv,
95 int reg_elda, uint32_t bits_elda, 159 int reg_elda, uint32_t bits_elda,
@@ -184,6 +248,8 @@ static void hsw_audio_codec_disable(struct intel_encoder *encoder)
184 248
185 DRM_DEBUG_KMS("Disable audio codec on pipe %c\n", pipe_name(pipe)); 249 DRM_DEBUG_KMS("Disable audio codec on pipe %c\n", pipe_name(pipe));
186 250
251 mutex_lock(&dev_priv->av_mutex);
252
187 /* Disable timestamps */ 253 /* Disable timestamps */
188 tmp = I915_READ(HSW_AUD_CFG(pipe)); 254 tmp = I915_READ(HSW_AUD_CFG(pipe));
189 tmp &= ~AUD_CONFIG_N_VALUE_INDEX; 255 tmp &= ~AUD_CONFIG_N_VALUE_INDEX;
@@ -199,6 +265,8 @@ static void hsw_audio_codec_disable(struct intel_encoder *encoder)
199 tmp &= ~AUDIO_ELD_VALID(pipe); 265 tmp &= ~AUDIO_ELD_VALID(pipe);
200 tmp &= ~AUDIO_OUTPUT_ENABLE(pipe); 266 tmp &= ~AUDIO_OUTPUT_ENABLE(pipe);
201 I915_WRITE(HSW_AUD_PIN_ELD_CP_VLD, tmp); 267 I915_WRITE(HSW_AUD_PIN_ELD_CP_VLD, tmp);
268
269 mutex_unlock(&dev_priv->av_mutex);
202} 270}
203 271
204static void hsw_audio_codec_enable(struct drm_connector *connector, 272static void hsw_audio_codec_enable(struct drm_connector *connector,
@@ -208,13 +276,20 @@ static void hsw_audio_codec_enable(struct drm_connector *connector,
208 struct drm_i915_private *dev_priv = connector->dev->dev_private; 276 struct drm_i915_private *dev_priv = connector->dev->dev_private;
209 struct intel_crtc *intel_crtc = to_intel_crtc(encoder->base.crtc); 277 struct intel_crtc *intel_crtc = to_intel_crtc(encoder->base.crtc);
210 enum pipe pipe = intel_crtc->pipe; 278 enum pipe pipe = intel_crtc->pipe;
279 struct i915_audio_component *acomp = dev_priv->audio_component;
211 const uint8_t *eld = connector->eld; 280 const uint8_t *eld = connector->eld;
281 struct intel_digital_port *intel_dig_port =
282 enc_to_dig_port(&encoder->base);
283 enum port port = intel_dig_port->port;
212 uint32_t tmp; 284 uint32_t tmp;
213 int len, i; 285 int len, i;
286 int n, rate;
214 287
215 DRM_DEBUG_KMS("Enable audio codec on pipe %c, %u bytes ELD\n", 288 DRM_DEBUG_KMS("Enable audio codec on pipe %c, %u bytes ELD\n",
216 pipe_name(pipe), drm_eld_size(eld)); 289 pipe_name(pipe), drm_eld_size(eld));
217 290
291 mutex_lock(&dev_priv->av_mutex);
292
218 /* Enable audio presence detect, invalidate ELD */ 293 /* Enable audio presence detect, invalidate ELD */
219 tmp = I915_READ(HSW_AUD_PIN_ELD_CP_VLD); 294 tmp = I915_READ(HSW_AUD_PIN_ELD_CP_VLD);
220 tmp |= AUDIO_OUTPUT_ENABLE(pipe); 295 tmp |= AUDIO_OUTPUT_ENABLE(pipe);
@@ -246,13 +321,32 @@ static void hsw_audio_codec_enable(struct drm_connector *connector,
246 /* Enable timestamps */ 321 /* Enable timestamps */
247 tmp = I915_READ(HSW_AUD_CFG(pipe)); 322 tmp = I915_READ(HSW_AUD_CFG(pipe));
248 tmp &= ~AUD_CONFIG_N_VALUE_INDEX; 323 tmp &= ~AUD_CONFIG_N_VALUE_INDEX;
249 tmp &= ~AUD_CONFIG_N_PROG_ENABLE;
250 tmp &= ~AUD_CONFIG_PIXEL_CLOCK_HDMI_MASK; 324 tmp &= ~AUD_CONFIG_PIXEL_CLOCK_HDMI_MASK;
251 if (intel_pipe_has_type(intel_crtc, INTEL_OUTPUT_DISPLAYPORT)) 325 if (intel_pipe_has_type(intel_crtc, INTEL_OUTPUT_DISPLAYPORT))
252 tmp |= AUD_CONFIG_N_VALUE_INDEX; 326 tmp |= AUD_CONFIG_N_VALUE_INDEX;
253 else 327 else
254 tmp |= audio_config_hdmi_pixel_clock(mode); 328 tmp |= audio_config_hdmi_pixel_clock(mode);
329
330 tmp &= ~AUD_CONFIG_N_PROG_ENABLE;
331 if (audio_rate_need_prog(intel_crtc, mode)) {
332 if (!acomp)
333 rate = 0;
334 else if (port >= PORT_A && port <= PORT_E)
335 rate = acomp->aud_sample_rate[port];
336 else {
337 DRM_ERROR("invalid port: %d\n", port);
338 rate = 0;
339 }
340 n = audio_config_get_n(mode, rate);
341 if (n != 0)
342 tmp = audio_config_setup_n_reg(n, tmp);
343 else
344 DRM_DEBUG_KMS("no suitable N value is found\n");
345 }
346
255 I915_WRITE(HSW_AUD_CFG(pipe), tmp); 347 I915_WRITE(HSW_AUD_CFG(pipe), tmp);
348
349 mutex_unlock(&dev_priv->av_mutex);
256} 350}
257 351
258static void ilk_audio_codec_disable(struct intel_encoder *encoder) 352static void ilk_audio_codec_disable(struct intel_encoder *encoder)
@@ -527,12 +621,91 @@ static int i915_audio_component_get_cdclk_freq(struct device *dev)
527 return ret; 621 return ret;
528} 622}
529 623
624static int i915_audio_component_sync_audio_rate(struct device *dev,
625 int port, int rate)
626{
627 struct drm_i915_private *dev_priv = dev_to_i915(dev);
628 struct drm_device *drm_dev = dev_priv->dev;
629 struct intel_encoder *intel_encoder;
630 struct intel_digital_port *intel_dig_port;
631 struct intel_crtc *crtc;
632 struct drm_display_mode *mode;
633 struct i915_audio_component *acomp = dev_priv->audio_component;
634 enum pipe pipe = -1;
635 u32 tmp;
636 int n;
637
638 /* HSW, BDW SKL need this fix */
639 if (!IS_SKYLAKE(dev_priv) &&
640 !IS_BROADWELL(dev_priv) &&
641 !IS_HASWELL(dev_priv))
642 return 0;
643
644 mutex_lock(&dev_priv->av_mutex);
645 /* 1. get the pipe */
646 for_each_intel_encoder(drm_dev, intel_encoder) {
647 if (intel_encoder->type != INTEL_OUTPUT_HDMI)
648 continue;
649 intel_dig_port = enc_to_dig_port(&intel_encoder->base);
650 if (port == intel_dig_port->port) {
651 crtc = to_intel_crtc(intel_encoder->base.crtc);
652 if (!crtc) {
653 DRM_DEBUG_KMS("%s: crtc is NULL\n", __func__);
654 continue;
655 }
656 pipe = crtc->pipe;
657 break;
658 }
659 }
660
661 if (pipe == INVALID_PIPE) {
662 DRM_DEBUG_KMS("no pipe for the port %c\n", port_name(port));
663 mutex_unlock(&dev_priv->av_mutex);
664 return -ENODEV;
665 }
666 DRM_DEBUG_KMS("pipe %c connects port %c\n",
667 pipe_name(pipe), port_name(port));
668 mode = &crtc->config->base.adjusted_mode;
669
670 /* port must be valid now, otherwise the pipe will be invalid */
671 acomp->aud_sample_rate[port] = rate;
672
673 /* 2. check whether to set the N/CTS/M manually or not */
674 if (!audio_rate_need_prog(crtc, mode)) {
675 tmp = I915_READ(HSW_AUD_CFG(pipe));
676 tmp &= ~AUD_CONFIG_N_PROG_ENABLE;
677 I915_WRITE(HSW_AUD_CFG(pipe), tmp);
678 mutex_unlock(&dev_priv->av_mutex);
679 return 0;
680 }
681
682 n = audio_config_get_n(mode, rate);
683 if (n == 0) {
684 DRM_DEBUG_KMS("Using automatic mode for N value on port %c\n",
685 port_name(port));
686 tmp = I915_READ(HSW_AUD_CFG(pipe));
687 tmp &= ~AUD_CONFIG_N_PROG_ENABLE;
688 I915_WRITE(HSW_AUD_CFG(pipe), tmp);
689 mutex_unlock(&dev_priv->av_mutex);
690 return 0;
691 }
692
693 /* 3. set the N/CTS/M */
694 tmp = I915_READ(HSW_AUD_CFG(pipe));
695 tmp = audio_config_setup_n_reg(n, tmp);
696 I915_WRITE(HSW_AUD_CFG(pipe), tmp);
697
698 mutex_unlock(&dev_priv->av_mutex);
699 return 0;
700}
701
530static const struct i915_audio_component_ops i915_audio_component_ops = { 702static const struct i915_audio_component_ops i915_audio_component_ops = {
531 .owner = THIS_MODULE, 703 .owner = THIS_MODULE,
532 .get_power = i915_audio_component_get_power, 704 .get_power = i915_audio_component_get_power,
533 .put_power = i915_audio_component_put_power, 705 .put_power = i915_audio_component_put_power,
534 .codec_wake_override = i915_audio_component_codec_wake_override, 706 .codec_wake_override = i915_audio_component_codec_wake_override,
535 .get_cdclk_freq = i915_audio_component_get_cdclk_freq, 707 .get_cdclk_freq = i915_audio_component_get_cdclk_freq,
708 .sync_audio_rate = i915_audio_component_sync_audio_rate,
536}; 709};
537 710
538static int i915_audio_component_bind(struct device *i915_dev, 711static int i915_audio_component_bind(struct device *i915_dev,
@@ -540,6 +713,7 @@ static int i915_audio_component_bind(struct device *i915_dev,
540{ 713{
541 struct i915_audio_component *acomp = data; 714 struct i915_audio_component *acomp = data;
542 struct drm_i915_private *dev_priv = dev_to_i915(i915_dev); 715 struct drm_i915_private *dev_priv = dev_to_i915(i915_dev);
716 int i;
543 717
544 if (WARN_ON(acomp->ops || acomp->dev)) 718 if (WARN_ON(acomp->ops || acomp->dev))
545 return -EEXIST; 719 return -EEXIST;
@@ -547,6 +721,9 @@ static int i915_audio_component_bind(struct device *i915_dev,
547 drm_modeset_lock_all(dev_priv->dev); 721 drm_modeset_lock_all(dev_priv->dev);
548 acomp->ops = &i915_audio_component_ops; 722 acomp->ops = &i915_audio_component_ops;
549 acomp->dev = i915_dev; 723 acomp->dev = i915_dev;
724 BUILD_BUG_ON(MAX_PORTS != I915_MAX_PORTS);
725 for (i = 0; i < ARRAY_SIZE(acomp->aud_sample_rate); i++)
726 acomp->aud_sample_rate[i] = 0;
550 dev_priv->audio_component = acomp; 727 dev_priv->audio_component = acomp;
551 drm_modeset_unlock_all(dev_priv->dev); 728 drm_modeset_unlock_all(dev_priv->dev);
552 729
diff --git a/include/drm/i915_component.h b/include/drm/i915_component.h
index b2d56dd483d9..89dc7d6bc1cc 100644
--- a/include/drm/i915_component.h
+++ b/include/drm/i915_component.h
@@ -24,8 +24,18 @@
24#ifndef _I915_COMPONENT_H_ 24#ifndef _I915_COMPONENT_H_
25#define _I915_COMPONENT_H_ 25#define _I915_COMPONENT_H_
26 26
27/* MAX_PORT is the number of port
28 * It must be sync with I915_MAX_PORTS defined i915_drv.h
29 * 5 should be enough as only HSW, BDW, SKL need such fix.
30 */
31#define MAX_PORTS 5
32
27struct i915_audio_component { 33struct i915_audio_component {
28 struct device *dev; 34 struct device *dev;
35 /**
36 * @aud_sample_rate: the array of audio sample rate per port
37 */
38 int aud_sample_rate[MAX_PORTS];
29 39
30 const struct i915_audio_component_ops { 40 const struct i915_audio_component_ops {
31 struct module *owner; 41 struct module *owner;
@@ -33,6 +43,13 @@ struct i915_audio_component {
33 void (*put_power)(struct device *); 43 void (*put_power)(struct device *);
34 void (*codec_wake_override)(struct device *, bool enable); 44 void (*codec_wake_override)(struct device *, bool enable);
35 int (*get_cdclk_freq)(struct device *); 45 int (*get_cdclk_freq)(struct device *);
46 /**
47 * @sync_audio_rate: set n/cts based on the sample rate
48 *
49 * Called from audio driver. After audio driver sets the
50 * sample rate, it will call this function to set n/cts
51 */
52 int (*sync_audio_rate)(struct device *, int port, int rate);
36 } *ops; 53 } *ops;
37 54
38 const struct i915_audio_component_audio_ops { 55 const struct i915_audio_component_audio_ops {
diff --git a/include/linux/mod_devicetable.h b/include/linux/mod_devicetable.h
index 6975cbf1435b..64f36e09a790 100644
--- a/include/linux/mod_devicetable.h
+++ b/include/linux/mod_devicetable.h
@@ -219,6 +219,14 @@ struct serio_device_id {
219 __u8 proto; 219 __u8 proto;
220}; 220};
221 221
222struct hda_device_id {
223 __u32 vendor_id;
224 __u32 rev_id;
225 __u8 api_version;
226 const char *name;
227 unsigned long driver_data;
228};
229
222/* 230/*
223 * Struct used for matching a device 231 * Struct used for matching a device
224 */ 232 */
diff --git a/include/sound/da7213.h b/include/sound/da7213.h
index 673f5c39cbf2..e7eac8979995 100644
--- a/include/sound/da7213.h
+++ b/include/sound/da7213.h
@@ -44,9 +44,6 @@ struct da7213_platform_data {
44 enum da7213_dmic_data_sel dmic_data_sel; 44 enum da7213_dmic_data_sel dmic_data_sel;
45 enum da7213_dmic_samplephase dmic_samplephase; 45 enum da7213_dmic_samplephase dmic_samplephase;
46 enum da7213_dmic_clk_rate dmic_clk_rate; 46 enum da7213_dmic_clk_rate dmic_clk_rate;
47
48 /* MCLK squaring config */
49 bool mclk_squaring;
50}; 47};
51 48
52#endif /* _DA7213_PDATA_H */ 49#endif /* _DA7213_PDATA_H */
diff --git a/include/sound/da7219-aad.h b/include/sound/da7219-aad.h
new file mode 100644
index 000000000000..17802fb86ec4
--- /dev/null
+++ b/include/sound/da7219-aad.h
@@ -0,0 +1,99 @@
1/*
2 * da7219-aad.h - DA7322 ASoC Codec AAD Driver Platform Data
3 *
4 * Copyright (c) 2015 Dialog Semiconductor Ltd.
5 *
6 * Author: Adam Thomson <Adam.Thomson.Opensource@diasemi.com>
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the
10 * Free Software Foundation; either version 2 of the License, or (at your
11 * option) any later version.
12 */
13
14#ifndef __DA7219_AAD_PDATA_H
15#define __DA7219_AAD_PDATA_H
16
17enum da7219_aad_micbias_pulse_lvl {
18 DA7219_AAD_MICBIAS_PULSE_LVL_OFF = 0,
19 DA7219_AAD_MICBIAS_PULSE_LVL_2_8V = 6,
20 DA7219_AAD_MICBIAS_PULSE_LVL_2_9V,
21};
22
23enum da7219_aad_btn_cfg {
24 DA7219_AAD_BTN_CFG_2MS = 1,
25 DA7219_AAD_BTN_CFG_5MS,
26 DA7219_AAD_BTN_CFG_10MS,
27 DA7219_AAD_BTN_CFG_50MS,
28 DA7219_AAD_BTN_CFG_100MS,
29 DA7219_AAD_BTN_CFG_200MS,
30 DA7219_AAD_BTN_CFG_500MS,
31};
32
33enum da7219_aad_mic_det_thr {
34 DA7219_AAD_MIC_DET_THR_200_OHMS = 0,
35 DA7219_AAD_MIC_DET_THR_500_OHMS,
36 DA7219_AAD_MIC_DET_THR_750_OHMS,
37 DA7219_AAD_MIC_DET_THR_1000_OHMS,
38};
39
40enum da7219_aad_jack_ins_deb {
41 DA7219_AAD_JACK_INS_DEB_5MS = 0,
42 DA7219_AAD_JACK_INS_DEB_10MS,
43 DA7219_AAD_JACK_INS_DEB_20MS,
44 DA7219_AAD_JACK_INS_DEB_50MS,
45 DA7219_AAD_JACK_INS_DEB_100MS,
46 DA7219_AAD_JACK_INS_DEB_200MS,
47 DA7219_AAD_JACK_INS_DEB_500MS,
48 DA7219_AAD_JACK_INS_DEB_1S,
49};
50
51enum da7219_aad_jack_det_rate {
52 DA7219_AAD_JACK_DET_RATE_32_64MS = 0,
53 DA7219_AAD_JACK_DET_RATE_64_128MS,
54 DA7219_AAD_JACK_DET_RATE_128_256MS,
55 DA7219_AAD_JACK_DET_RATE_256_512MS,
56};
57
58enum da7219_aad_jack_rem_deb {
59 DA7219_AAD_JACK_REM_DEB_1MS = 0,
60 DA7219_AAD_JACK_REM_DEB_5MS,
61 DA7219_AAD_JACK_REM_DEB_10MS,
62 DA7219_AAD_JACK_REM_DEB_20MS,
63};
64
65enum da7219_aad_btn_avg {
66 DA7219_AAD_BTN_AVG_1 = 0,
67 DA7219_AAD_BTN_AVG_2,
68 DA7219_AAD_BTN_AVG_4,
69 DA7219_AAD_BTN_AVG_8,
70};
71
72enum da7219_aad_adc_1bit_rpt {
73 DA7219_AAD_ADC_1BIT_RPT_1 = 0,
74 DA7219_AAD_ADC_1BIT_RPT_2,
75 DA7219_AAD_ADC_1BIT_RPT_4,
76 DA7219_AAD_ADC_1BIT_RPT_8,
77};
78
79struct da7219_aad_pdata {
80 int irq;
81
82 enum da7219_aad_micbias_pulse_lvl micbias_pulse_lvl;
83 u32 micbias_pulse_time;
84 enum da7219_aad_btn_cfg btn_cfg;
85 enum da7219_aad_mic_det_thr mic_det_thr;
86 enum da7219_aad_jack_ins_deb jack_ins_deb;
87 enum da7219_aad_jack_det_rate jack_det_rate;
88 enum da7219_aad_jack_rem_deb jack_rem_deb;
89
90 u8 a_d_btn_thr;
91 u8 d_b_btn_thr;
92 u8 b_c_btn_thr;
93 u8 c_mic_btn_thr;
94
95 enum da7219_aad_btn_avg btn_avg;
96 enum da7219_aad_adc_1bit_rpt adc_1bit_rpt;
97};
98
99#endif /* __DA7219_AAD_PDATA_H */
diff --git a/include/sound/da7219.h b/include/sound/da7219.h
new file mode 100644
index 000000000000..3f39e135312d
--- /dev/null
+++ b/include/sound/da7219.h
@@ -0,0 +1,55 @@
1/*
2 * da7219.h - DA7219 ASoC Codec Driver Platform Data
3 *
4 * Copyright (c) 2015 Dialog Semiconductor
5 *
6 * Author: Adam Thomson <Adam.Thomson.Opensource@diasemi.com>
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the
10 * Free Software Foundation; either version 2 of the License, or (at your
11 * option) any later version.
12 */
13
14#ifndef __DA7219_PDATA_H
15#define __DA7219_PDATA_H
16
17/* LDO */
18enum da7219_ldo_lvl_sel {
19 DA7219_LDO_LVL_SEL_1_05V = 0,
20 DA7219_LDO_LVL_SEL_1_10V,
21 DA7219_LDO_LVL_SEL_1_20V,
22 DA7219_LDO_LVL_SEL_1_40V,
23};
24
25/* Mic Bias */
26enum da7219_micbias_voltage {
27 DA7219_MICBIAS_1_8V = 1,
28 DA7219_MICBIAS_2_0V,
29 DA7219_MICBIAS_2_2V,
30 DA7219_MICBIAS_2_4V,
31 DA7219_MICBIAS_2_6V,
32};
33
34/* Mic input type */
35enum da7219_mic_amp_in_sel {
36 DA7219_MIC_AMP_IN_SEL_DIFF = 0,
37 DA7219_MIC_AMP_IN_SEL_SE_P,
38 DA7219_MIC_AMP_IN_SEL_SE_N,
39};
40
41struct da7219_aad_pdata;
42
43struct da7219_pdata {
44 /* Internal LDO */
45 enum da7219_ldo_lvl_sel ldo_lvl_sel;
46
47 /* Mic */
48 enum da7219_micbias_voltage micbias_lvl;
49 enum da7219_mic_amp_in_sel mic_amp_in_sel;
50
51 /* AAD */
52 struct da7219_aad_pdata *aad_pdata;
53};
54
55#endif /* __DA7219_PDATA_H */
diff --git a/include/sound/designware_i2s.h b/include/sound/designware_i2s.h
index 3a8fca9409a7..8966ba7c9629 100644
--- a/include/sound/designware_i2s.h
+++ b/include/sound/designware_i2s.h
@@ -38,6 +38,8 @@ struct i2s_clk_config_data {
38struct i2s_platform_data { 38struct i2s_platform_data {
39 #define DWC_I2S_PLAY (1 << 0) 39 #define DWC_I2S_PLAY (1 << 0)
40 #define DWC_I2S_RECORD (1 << 1) 40 #define DWC_I2S_RECORD (1 << 1)
41 #define DW_I2S_SLAVE (1 << 2)
42 #define DW_I2S_MASTER (1 << 3)
41 unsigned int cap; 43 unsigned int cap;
42 int channel; 44 int channel;
43 u32 snd_fmts; 45 u32 snd_fmts;
diff --git a/include/sound/hda_regmap.h b/include/sound/hda_regmap.h
index df705908480a..2767c55a641e 100644
--- a/include/sound/hda_regmap.h
+++ b/include/sound/hda_regmap.h
@@ -67,7 +67,7 @@ int snd_hdac_regmap_update_raw(struct hdac_device *codec, unsigned int reg,
67 * @reg: verb to write 67 * @reg: verb to write
68 * @val: value to write 68 * @val: value to write
69 * 69 *
70 * For writing an amp value, use snd_hda_regmap_amp_update(). 70 * For writing an amp value, use snd_hdac_regmap_update_amp().
71 */ 71 */
72static inline int 72static inline int
73snd_hdac_regmap_write(struct hdac_device *codec, hda_nid_t nid, 73snd_hdac_regmap_write(struct hdac_device *codec, hda_nid_t nid,
@@ -85,7 +85,7 @@ snd_hdac_regmap_write(struct hdac_device *codec, hda_nid_t nid,
85 * @mask: bit mask to update 85 * @mask: bit mask to update
86 * @val: value to update 86 * @val: value to update
87 * 87 *
88 * For updating an amp value, use snd_hda_regmap_amp_update(). 88 * For updating an amp value, use snd_hdac_regmap_update_amp().
89 */ 89 */
90static inline int 90static inline int
91snd_hdac_regmap_update(struct hdac_device *codec, hda_nid_t nid, 91snd_hdac_regmap_update(struct hdac_device *codec, hda_nid_t nid,
diff --git a/include/sound/hdaudio.h b/include/sound/hdaudio.h
index 49bc836fcd84..e2b712c90d3f 100644
--- a/include/sound/hdaudio.h
+++ b/include/sound/hdaudio.h
@@ -21,6 +21,7 @@ struct hdac_stream;
21struct hdac_device; 21struct hdac_device;
22struct hdac_driver; 22struct hdac_driver;
23struct hdac_widget_tree; 23struct hdac_widget_tree;
24struct hda_device_id;
24 25
25/* 26/*
26 * exported bus type 27 * exported bus type
@@ -28,16 +29,6 @@ struct hdac_widget_tree;
28extern struct bus_type snd_hda_bus_type; 29extern struct bus_type snd_hda_bus_type;
29 30
30/* 31/*
31 * HDA device table
32 */
33struct hda_device_id {
34 __u32 vendor_id;
35 __u32 rev_id;
36 const char *name;
37 unsigned long driver_data;
38};
39
40/*
41 * generic arrays 32 * generic arrays
42 */ 33 */
43struct snd_array { 34struct snd_array {
@@ -117,6 +108,8 @@ int snd_hdac_device_init(struct hdac_device *dev, struct hdac_bus *bus,
117void snd_hdac_device_exit(struct hdac_device *dev); 108void snd_hdac_device_exit(struct hdac_device *dev);
118int snd_hdac_device_register(struct hdac_device *codec); 109int snd_hdac_device_register(struct hdac_device *codec);
119void snd_hdac_device_unregister(struct hdac_device *codec); 110void snd_hdac_device_unregister(struct hdac_device *codec);
111int snd_hdac_device_set_chip_name(struct hdac_device *codec, const char *name);
112int snd_hdac_codec_modalias(struct hdac_device *hdac, char *buf, size_t size);
120 113
121int snd_hdac_refresh_widgets(struct hdac_device *codec); 114int snd_hdac_refresh_widgets(struct hdac_device *codec);
122int snd_hdac_refresh_widget_sysfs(struct hdac_device *codec); 115int snd_hdac_refresh_widget_sysfs(struct hdac_device *codec);
@@ -147,6 +140,12 @@ int snd_hdac_query_supported_pcm(struct hdac_device *codec, hda_nid_t nid,
147bool snd_hdac_is_supported_format(struct hdac_device *codec, hda_nid_t nid, 140bool snd_hdac_is_supported_format(struct hdac_device *codec, hda_nid_t nid,
148 unsigned int format); 141 unsigned int format);
149 142
143int snd_hdac_codec_read(struct hdac_device *hdac, hda_nid_t nid,
144 int flags, unsigned int verb, unsigned int parm);
145int snd_hdac_codec_write(struct hdac_device *hdac, hda_nid_t nid,
146 int flags, unsigned int verb, unsigned int parm);
147bool snd_hdac_check_power_state(struct hdac_device *hdac,
148 hda_nid_t nid, unsigned int target_state);
150/** 149/**
151 * snd_hdac_read_parm - read a codec parameter 150 * snd_hdac_read_parm - read a codec parameter
152 * @codec: the codec object 151 * @codec: the codec object
diff --git a/include/sound/hdaudio_ext.h b/include/sound/hdaudio_ext.h
index 94210dcdb6ea..a4cadd9c297a 100644
--- a/include/sound/hdaudio_ext.h
+++ b/include/sound/hdaudio_ext.h
@@ -40,6 +40,13 @@ void snd_hdac_ext_bus_device_remove(struct hdac_ext_bus *ebus);
40#define hbus_to_ebus(_bus) \ 40#define hbus_to_ebus(_bus) \
41 container_of(_bus, struct hdac_ext_bus, bus) 41 container_of(_bus, struct hdac_ext_bus, bus)
42 42
43#define HDA_CODEC_REV_EXT_ENTRY(_vid, _rev, _name, drv_data) \
44 { .vendor_id = (_vid), .rev_id = (_rev), .name = (_name), \
45 .api_version = HDA_DEV_ASOC, \
46 .driver_data = (unsigned long)(drv_data) }
47#define HDA_CODEC_EXT_ENTRY(_vid, _revid, _name, _drv_data) \
48 HDA_CODEC_REV_EXT_ENTRY(_vid, _revid, _name, _drv_data)
49
43int snd_hdac_ext_bus_parse_capabilities(struct hdac_ext_bus *sbus); 50int snd_hdac_ext_bus_parse_capabilities(struct hdac_ext_bus *sbus);
44void snd_hdac_ext_bus_ppcap_enable(struct hdac_ext_bus *chip, bool enable); 51void snd_hdac_ext_bus_ppcap_enable(struct hdac_ext_bus *chip, bool enable);
45void snd_hdac_ext_bus_ppcap_int_enable(struct hdac_ext_bus *chip, bool enable); 52void snd_hdac_ext_bus_ppcap_int_enable(struct hdac_ext_bus *chip, bool enable);
diff --git a/include/sound/pcm.h b/include/sound/pcm.h
index 691e7ee0a510..b0be09279943 100644
--- a/include/sound/pcm.h
+++ b/include/sound/pcm.h
@@ -265,12 +265,12 @@ struct snd_ratden {
265 265
266struct snd_pcm_hw_constraint_ratnums { 266struct snd_pcm_hw_constraint_ratnums {
267 int nrats; 267 int nrats;
268 struct snd_ratnum *rats; 268 const struct snd_ratnum *rats;
269}; 269};
270 270
271struct snd_pcm_hw_constraint_ratdens { 271struct snd_pcm_hw_constraint_ratdens {
272 int nrats; 272 int nrats;
273 struct snd_ratden *rats; 273 const struct snd_ratden *rats;
274}; 274};
275 275
276struct snd_pcm_hw_constraint_list { 276struct snd_pcm_hw_constraint_list {
@@ -285,8 +285,6 @@ struct snd_pcm_hw_constraint_ranges {
285 unsigned int mask; 285 unsigned int mask;
286}; 286};
287 287
288struct snd_pcm_hwptr_log;
289
290/* 288/*
291 * userspace-provided audio timestamp config to kernel, 289 * userspace-provided audio timestamp config to kernel,
292 * structure is for internal use only and filled with dedicated unpack routine 290 * structure is for internal use only and filled with dedicated unpack routine
@@ -404,10 +402,6 @@ struct snd_pcm_runtime {
404 struct snd_pcm_hardware hw; 402 struct snd_pcm_hardware hw;
405 struct snd_pcm_hw_constraints hw_constraints; 403 struct snd_pcm_hw_constraints hw_constraints;
406 404
407 /* -- interrupt callbacks -- */
408 void (*transfer_ack_begin)(struct snd_pcm_substream *substream);
409 void (*transfer_ack_end)(struct snd_pcm_substream *substream);
410
411 /* -- timer -- */ 405 /* -- timer -- */
412 unsigned int timer_resolution; /* timer resolution */ 406 unsigned int timer_resolution; /* timer resolution */
413 int tstamp_type; /* timestamp type */ 407 int tstamp_type; /* timestamp type */
@@ -428,10 +422,6 @@ struct snd_pcm_runtime {
428 /* -- OSS things -- */ 422 /* -- OSS things -- */
429 struct snd_pcm_oss_runtime oss; 423 struct snd_pcm_oss_runtime oss;
430#endif 424#endif
431
432#ifdef CONFIG_SND_PCM_XRUN_DEBUG
433 struct snd_pcm_hwptr_log *hwptr_log;
434#endif
435}; 425};
436 426
437struct snd_pcm_group { /* keep linked substreams */ 427struct snd_pcm_group { /* keep linked substreams */
@@ -980,7 +970,7 @@ int snd_interval_list(struct snd_interval *i, unsigned int count,
980int snd_interval_ranges(struct snd_interval *i, unsigned int count, 970int snd_interval_ranges(struct snd_interval *i, unsigned int count,
981 const struct snd_interval *list, unsigned int mask); 971 const struct snd_interval *list, unsigned int mask);
982int snd_interval_ratnum(struct snd_interval *i, 972int snd_interval_ratnum(struct snd_interval *i,
983 unsigned int rats_count, struct snd_ratnum *rats, 973 unsigned int rats_count, const struct snd_ratnum *rats,
984 unsigned int *nump, unsigned int *denp); 974 unsigned int *nump, unsigned int *denp);
985 975
986void _snd_pcm_hw_params_any(struct snd_pcm_hw_params *params); 976void _snd_pcm_hw_params_any(struct snd_pcm_hw_params *params);
@@ -1010,11 +1000,11 @@ int snd_pcm_hw_constraint_ranges(struct snd_pcm_runtime *runtime,
1010int snd_pcm_hw_constraint_ratnums(struct snd_pcm_runtime *runtime, 1000int snd_pcm_hw_constraint_ratnums(struct snd_pcm_runtime *runtime,
1011 unsigned int cond, 1001 unsigned int cond,
1012 snd_pcm_hw_param_t var, 1002 snd_pcm_hw_param_t var,
1013 struct snd_pcm_hw_constraint_ratnums *r); 1003 const struct snd_pcm_hw_constraint_ratnums *r);
1014int snd_pcm_hw_constraint_ratdens(struct snd_pcm_runtime *runtime, 1004int snd_pcm_hw_constraint_ratdens(struct snd_pcm_runtime *runtime,
1015 unsigned int cond, 1005 unsigned int cond,
1016 snd_pcm_hw_param_t var, 1006 snd_pcm_hw_param_t var,
1017 struct snd_pcm_hw_constraint_ratdens *r); 1007 const struct snd_pcm_hw_constraint_ratdens *r);
1018int snd_pcm_hw_constraint_msbits(struct snd_pcm_runtime *runtime, 1008int snd_pcm_hw_constraint_msbits(struct snd_pcm_runtime *runtime,
1019 unsigned int cond, 1009 unsigned int cond,
1020 unsigned int width, 1010 unsigned int width,
@@ -1034,6 +1024,22 @@ int snd_pcm_hw_rule_add(struct snd_pcm_runtime *runtime,
1034 snd_pcm_hw_rule_func_t func, void *private, 1024 snd_pcm_hw_rule_func_t func, void *private,
1035 int dep, ...); 1025 int dep, ...);
1036 1026
1027/**
1028 * snd_pcm_hw_constraint_single() - Constrain parameter to a single value
1029 * @runtime: PCM runtime instance
1030 * @var: The hw_params variable to constrain
1031 * @val: The value to constrain to
1032 *
1033 * Return: Positive if the value is changed, zero if it's not changed, or a
1034 * negative error code.
1035 */
1036static inline int snd_pcm_hw_constraint_single(
1037 struct snd_pcm_runtime *runtime, snd_pcm_hw_param_t var,
1038 unsigned int val)
1039{
1040 return snd_pcm_hw_constraint_minmax(runtime, var, val, val);
1041}
1042
1037int snd_pcm_format_signed(snd_pcm_format_t format); 1043int snd_pcm_format_signed(snd_pcm_format_t format);
1038int snd_pcm_format_unsigned(snd_pcm_format_t format); 1044int snd_pcm_format_unsigned(snd_pcm_format_t format);
1039int snd_pcm_format_linear(snd_pcm_format_t format); 1045int snd_pcm_format_linear(snd_pcm_format_t format);
@@ -1117,10 +1123,16 @@ static inline void snd_pcm_set_runtime_buffer(struct snd_pcm_substream *substrea
1117 * Timer interface 1123 * Timer interface
1118 */ 1124 */
1119 1125
1126#ifdef CONFIG_SND_PCM_TIMER
1120void snd_pcm_timer_resolution_change(struct snd_pcm_substream *substream); 1127void snd_pcm_timer_resolution_change(struct snd_pcm_substream *substream);
1121void snd_pcm_timer_init(struct snd_pcm_substream *substream); 1128void snd_pcm_timer_init(struct snd_pcm_substream *substream);
1122void snd_pcm_timer_done(struct snd_pcm_substream *substream); 1129void snd_pcm_timer_done(struct snd_pcm_substream *substream);
1123 1130#else
1131static inline void
1132snd_pcm_timer_resolution_change(struct snd_pcm_substream *substream) {}
1133static inline void snd_pcm_timer_init(struct snd_pcm_substream *substream) {}
1134static inline void snd_pcm_timer_done(struct snd_pcm_substream *substream) {}
1135#endif
1124/** 1136/**
1125 * snd_pcm_gettime - Fill the timespec depending on the timestamp mode 1137 * snd_pcm_gettime - Fill the timespec depending on the timestamp mode
1126 * @runtime: PCM runtime instance 1138 * @runtime: PCM runtime instance
diff --git a/include/sound/pxa2xx-lib.h b/include/sound/pxa2xx-lib.h
index 56e818e4a1cb..6ef629bde164 100644
--- a/include/sound/pxa2xx-lib.h
+++ b/include/sound/pxa2xx-lib.h
@@ -12,7 +12,6 @@ extern int __pxa2xx_pcm_hw_free(struct snd_pcm_substream *substream);
12extern int pxa2xx_pcm_trigger(struct snd_pcm_substream *substream, int cmd); 12extern int pxa2xx_pcm_trigger(struct snd_pcm_substream *substream, int cmd);
13extern snd_pcm_uframes_t pxa2xx_pcm_pointer(struct snd_pcm_substream *substream); 13extern snd_pcm_uframes_t pxa2xx_pcm_pointer(struct snd_pcm_substream *substream);
14extern int __pxa2xx_pcm_prepare(struct snd_pcm_substream *substream); 14extern int __pxa2xx_pcm_prepare(struct snd_pcm_substream *substream);
15extern void pxa2xx_pcm_dma_irq(int dma_ch, void *dev_id);
16extern int __pxa2xx_pcm_open(struct snd_pcm_substream *substream); 15extern int __pxa2xx_pcm_open(struct snd_pcm_substream *substream);
17extern int __pxa2xx_pcm_close(struct snd_pcm_substream *substream); 16extern int __pxa2xx_pcm_close(struct snd_pcm_substream *substream);
18extern int pxa2xx_pcm_mmap(struct snd_pcm_substream *substream, 17extern int pxa2xx_pcm_mmap(struct snd_pcm_substream *substream,
diff --git a/include/sound/rt5640.h b/include/sound/rt5640.h
index 59d26dd81e45..e3c84b92ff70 100644
--- a/include/sound/rt5640.h
+++ b/include/sound/rt5640.h
@@ -12,9 +12,10 @@
12#define __LINUX_SND_RT5640_H 12#define __LINUX_SND_RT5640_H
13 13
14struct rt5640_platform_data { 14struct rt5640_platform_data {
15 /* IN1 & IN2 can optionally be differential */ 15 /* IN1 & IN2 & IN3 can optionally be differential */
16 bool in1_diff; 16 bool in1_diff;
17 bool in2_diff; 17 bool in2_diff;
18 bool in3_diff;
18 19
19 bool dmic_en; 20 bool dmic_en;
20 bool dmic1_data_pin; /* 0 = IN1P; 1 = GPIO3 */ 21 bool dmic1_data_pin; /* 0 = IN1P; 1 = GPIO3 */
diff --git a/include/sound/rt5645.h b/include/sound/rt5645.h
index 22734bc3ffd4..a5cf6152e778 100644
--- a/include/sound/rt5645.h
+++ b/include/sound/rt5645.h
@@ -21,6 +21,8 @@ struct rt5645_platform_data {
21 /* 0 = IN2P; 1 = GPIO6; 2 = GPIO10; 3 = GPIO12 */ 21 /* 0 = IN2P; 1 = GPIO6; 2 = GPIO10; 3 = GPIO12 */
22 22
23 unsigned int jd_mode; 23 unsigned int jd_mode;
24 /* Invert JD when jack insert */
25 bool jd_invert;
24}; 26};
25 27
26#endif 28#endif
diff --git a/include/sound/simple_card.h b/include/sound/simple_card.h
index b9b4f289fe6b..0399352f3a62 100644
--- a/include/sound/simple_card.h
+++ b/include/sound/simple_card.h
@@ -19,6 +19,8 @@ struct asoc_simple_dai {
19 unsigned int sysclk; 19 unsigned int sysclk;
20 int slots; 20 int slots;
21 int slot_width; 21 int slot_width;
22 unsigned int tx_slot_mask;
23 unsigned int rx_slot_mask;
22 struct clk *clk; 24 struct clk *clk;
23}; 25};
24 26
diff --git a/include/sound/soc-dai.h b/include/sound/soc-dai.h
index 2df96b1384c7..212eaaf172ed 100644
--- a/include/sound/soc-dai.h
+++ b/include/sound/soc-dai.h
@@ -48,10 +48,25 @@ struct snd_compr_stream;
48#define SND_SOC_DAIFMT_GATED (0 << 4) /* clock is gated */ 48#define SND_SOC_DAIFMT_GATED (0 << 4) /* clock is gated */
49 49
50/* 50/*
51 * DAI hardware signal inversions. 51 * DAI hardware signal polarity.
52 * 52 *
53 * Specifies whether the DAI can also support inverted clocks for the specified 53 * Specifies whether the DAI can also support inverted clocks for the specified
54 * format. 54 * format.
55 *
56 * BCLK:
57 * - "normal" polarity means signal is available at rising edge of BCLK
58 * - "inverted" polarity means signal is available at falling edge of BCLK
59 *
60 * FSYNC "normal" polarity depends on the frame format:
61 * - I2S: frame consists of left then right channel data. Left channel starts
62 * with falling FSYNC edge, right channel starts with rising FSYNC edge.
63 * - Left/Right Justified: frame consists of left then right channel data.
64 * Left channel starts with rising FSYNC edge, right channel starts with
65 * falling FSYNC edge.
66 * - DSP A/B: Frame starts with rising FSYNC edge.
67 * - AC97: Frame starts with rising FSYNC edge.
68 *
69 * "Negative" FSYNC polarity is the one opposite of "normal" polarity.
55 */ 70 */
56#define SND_SOC_DAIFMT_NB_NF (0 << 8) /* normal bit clock + frame */ 71#define SND_SOC_DAIFMT_NB_NF (0 << 8) /* normal bit clock + frame */
57#define SND_SOC_DAIFMT_NB_IF (2 << 8) /* normal BCLK + inv FRM */ 72#define SND_SOC_DAIFMT_NB_IF (2 << 8) /* normal BCLK + inv FRM */
@@ -214,7 +229,7 @@ struct snd_soc_dai_driver {
214 int (*suspend)(struct snd_soc_dai *dai); 229 int (*suspend)(struct snd_soc_dai *dai);
215 int (*resume)(struct snd_soc_dai *dai); 230 int (*resume)(struct snd_soc_dai *dai);
216 /* compress dai */ 231 /* compress dai */
217 bool compress_dai; 232 int (*compress_new)(struct snd_soc_pcm_runtime *rtd, int num);
218 /* DAI is also used for the control bus */ 233 /* DAI is also used for the control bus */
219 bool bus_control; 234 bool bus_control;
220 235
diff --git a/include/sound/soc-dapm.h b/include/sound/soc-dapm.h
index 5abba037d245..7855cfe46b69 100644
--- a/include/sound/soc-dapm.h
+++ b/include/sound/soc-dapm.h
@@ -451,6 +451,9 @@ int snd_soc_dapm_dai_get_connected_widgets(struct snd_soc_dai *dai, int stream,
451struct snd_soc_dapm_context *snd_soc_dapm_kcontrol_dapm( 451struct snd_soc_dapm_context *snd_soc_dapm_kcontrol_dapm(
452 struct snd_kcontrol *kcontrol); 452 struct snd_kcontrol *kcontrol);
453 453
454struct snd_soc_dapm_widget *snd_soc_dapm_kcontrol_widget(
455 struct snd_kcontrol *kcontrol);
456
454int snd_soc_dapm_force_bias_level(struct snd_soc_dapm_context *dapm, 457int snd_soc_dapm_force_bias_level(struct snd_soc_dapm_context *dapm,
455 enum snd_soc_bias_level level); 458 enum snd_soc_bias_level level);
456 459
diff --git a/include/sound/soc.h b/include/sound/soc.h
index 26ede14597da..a8b4b9c8b1d2 100644
--- a/include/sound/soc.h
+++ b/include/sound/soc.h
@@ -217,6 +217,13 @@
217 .get = xhandler_get, .put = xhandler_put, \ 217 .get = xhandler_get, .put = xhandler_put, \
218 .private_value = \ 218 .private_value = \
219 SOC_DOUBLE_VALUE(reg, shift_left, shift_right, max, invert, 0) } 219 SOC_DOUBLE_VALUE(reg, shift_left, shift_right, max, invert, 0) }
220#define SOC_DOUBLE_R_EXT(xname, reg_left, reg_right, xshift, xmax, xinvert,\
221 xhandler_get, xhandler_put) \
222{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \
223 .info = snd_soc_info_volsw, \
224 .get = xhandler_get, .put = xhandler_put, \
225 .private_value = SOC_DOUBLE_R_VALUE(reg_left, reg_right, xshift, \
226 xmax, xinvert) }
220#define SOC_SINGLE_EXT_TLV(xname, xreg, xshift, xmax, xinvert,\ 227#define SOC_SINGLE_EXT_TLV(xname, xreg, xshift, xmax, xinvert,\
221 xhandler_get, xhandler_put, tlv_array) \ 228 xhandler_get, xhandler_put, tlv_array) \
222{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \ 229{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
@@ -226,6 +233,18 @@
226 .info = snd_soc_info_volsw, \ 233 .info = snd_soc_info_volsw, \
227 .get = xhandler_get, .put = xhandler_put, \ 234 .get = xhandler_get, .put = xhandler_put, \
228 .private_value = SOC_SINGLE_VALUE(xreg, xshift, xmax, xinvert, 0) } 235 .private_value = SOC_SINGLE_VALUE(xreg, xshift, xmax, xinvert, 0) }
236#define SOC_SINGLE_RANGE_EXT_TLV(xname, xreg, xshift, xmin, xmax, xinvert, \
237 xhandler_get, xhandler_put, tlv_array) \
238{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname),\
239 .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ |\
240 SNDRV_CTL_ELEM_ACCESS_READWRITE,\
241 .tlv.p = (tlv_array), \
242 .info = snd_soc_info_volsw_range, \
243 .get = xhandler_get, .put = xhandler_put, \
244 .private_value = (unsigned long)&(struct soc_mixer_control) \
245 {.reg = xreg, .rreg = xreg, .shift = xshift, \
246 .rshift = xshift, .min = xmin, .max = xmax, \
247 .platform_max = xmax, .invert = xinvert} }
229#define SOC_DOUBLE_EXT_TLV(xname, xreg, shift_left, shift_right, xmax, xinvert,\ 248#define SOC_DOUBLE_EXT_TLV(xname, xreg, shift_left, shift_right, xmax, xinvert,\
230 xhandler_get, xhandler_put, tlv_array) \ 249 xhandler_get, xhandler_put, tlv_array) \
231{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \ 250{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \
@@ -440,7 +459,9 @@ int snd_soc_platform_read(struct snd_soc_platform *platform,
440int snd_soc_platform_write(struct snd_soc_platform *platform, 459int snd_soc_platform_write(struct snd_soc_platform *platform,
441 unsigned int reg, unsigned int val); 460 unsigned int reg, unsigned int val);
442int soc_new_pcm(struct snd_soc_pcm_runtime *rtd, int num); 461int soc_new_pcm(struct snd_soc_pcm_runtime *rtd, int num);
443int soc_new_compress(struct snd_soc_pcm_runtime *rtd, int num); 462#ifdef CONFIG_SND_SOC_COMPRESS
463int snd_soc_new_compress(struct snd_soc_pcm_runtime *rtd, int num);
464#endif
444 465
445struct snd_pcm_substream *snd_soc_get_dai_substream(struct snd_soc_card *card, 466struct snd_pcm_substream *snd_soc_get_dai_substream(struct snd_soc_card *card,
446 const char *dai_link, int stream); 467 const char *dai_link, int stream);
@@ -593,7 +614,7 @@ int snd_soc_put_volsw_range(struct snd_kcontrol *kcontrol,
593 struct snd_ctl_elem_value *ucontrol); 614 struct snd_ctl_elem_value *ucontrol);
594int snd_soc_get_volsw_range(struct snd_kcontrol *kcontrol, 615int snd_soc_get_volsw_range(struct snd_kcontrol *kcontrol,
595 struct snd_ctl_elem_value *ucontrol); 616 struct snd_ctl_elem_value *ucontrol);
596int snd_soc_limit_volume(struct snd_soc_codec *codec, 617int snd_soc_limit_volume(struct snd_soc_card *card,
597 const char *name, int max); 618 const char *name, int max);
598int snd_soc_bytes_info(struct snd_kcontrol *kcontrol, 619int snd_soc_bytes_info(struct snd_kcontrol *kcontrol,
599 struct snd_ctl_elem_info *uinfo); 620 struct snd_ctl_elem_info *uinfo);
@@ -1603,6 +1624,8 @@ int snd_soc_of_parse_card_name(struct snd_soc_card *card,
1603int snd_soc_of_parse_audio_simple_widgets(struct snd_soc_card *card, 1624int snd_soc_of_parse_audio_simple_widgets(struct snd_soc_card *card,
1604 const char *propname); 1625 const char *propname);
1605int snd_soc_of_parse_tdm_slot(struct device_node *np, 1626int snd_soc_of_parse_tdm_slot(struct device_node *np,
1627 unsigned int *tx_mask,
1628 unsigned int *rx_mask,
1606 unsigned int *slots, 1629 unsigned int *slots,
1607 unsigned int *slot_width); 1630 unsigned int *slot_width);
1608void snd_soc_of_parse_audio_prefix(struct snd_soc_card *card, 1631void snd_soc_of_parse_audio_prefix(struct snd_soc_card *card,
diff --git a/include/uapi/sound/asoc.h b/include/uapi/sound/asoc.h
index 247c50bd60f0..26539a7e4880 100644
--- a/include/uapi/sound/asoc.h
+++ b/include/uapi/sound/asoc.h
@@ -83,7 +83,7 @@
83#define SND_SOC_TPLG_NUM_TEXTS 16 83#define SND_SOC_TPLG_NUM_TEXTS 16
84 84
85/* ABI version */ 85/* ABI version */
86#define SND_SOC_TPLG_ABI_VERSION 0x3 86#define SND_SOC_TPLG_ABI_VERSION 0x4
87 87
88/* Max size of TLV data */ 88/* Max size of TLV data */
89#define SND_SOC_TPLG_TLV_SIZE 32 89#define SND_SOC_TPLG_TLV_SIZE 32
@@ -103,7 +103,8 @@
103#define SND_SOC_TPLG_TYPE_PCM 7 103#define SND_SOC_TPLG_TYPE_PCM 7
104#define SND_SOC_TPLG_TYPE_MANIFEST 8 104#define SND_SOC_TPLG_TYPE_MANIFEST 8
105#define SND_SOC_TPLG_TYPE_CODEC_LINK 9 105#define SND_SOC_TPLG_TYPE_CODEC_LINK 9
106#define SND_SOC_TPLG_TYPE_PDATA 10 106#define SND_SOC_TPLG_TYPE_BACKEND_LINK 10
107#define SND_SOC_TPLG_TYPE_PDATA 11
107#define SND_SOC_TPLG_TYPE_MAX SND_SOC_TPLG_TYPE_PDATA 108#define SND_SOC_TPLG_TYPE_MAX SND_SOC_TPLG_TYPE_PDATA
108 109
109/* vendor block IDs - please add new vendor types to end */ 110/* vendor block IDs - please add new vendor types to end */
@@ -198,7 +199,7 @@ struct snd_soc_tplg_ctl_hdr {
198struct snd_soc_tplg_stream_caps { 199struct snd_soc_tplg_stream_caps {
199 __le32 size; /* in bytes of this structure */ 200 __le32 size; /* in bytes of this structure */
200 char name[SNDRV_CTL_ELEM_ID_NAME_MAXLEN]; 201 char name[SNDRV_CTL_ELEM_ID_NAME_MAXLEN];
201 __le64 formats[SND_SOC_TPLG_MAX_FORMATS]; /* supported formats SNDRV_PCM_FMTBIT_* */ 202 __le64 formats; /* supported formats SNDRV_PCM_FMTBIT_* */
202 __le32 rates; /* supported rates SNDRV_PCM_RATE_* */ 203 __le32 rates; /* supported rates SNDRV_PCM_RATE_* */
203 __le32 rate_min; /* min rate */ 204 __le32 rate_min; /* min rate */
204 __le32 rate_max; /* max rate */ 205 __le32 rate_max; /* max rate */
@@ -217,23 +218,12 @@ struct snd_soc_tplg_stream_caps {
217 */ 218 */
218struct snd_soc_tplg_stream { 219struct snd_soc_tplg_stream {
219 __le32 size; /* in bytes of this structure */ 220 __le32 size; /* in bytes of this structure */
221 char name[SNDRV_CTL_ELEM_ID_NAME_MAXLEN]; /* Name of the stream */
220 __le64 format; /* SNDRV_PCM_FMTBIT_* */ 222 __le64 format; /* SNDRV_PCM_FMTBIT_* */
221 __le32 rate; /* SNDRV_PCM_RATE_* */ 223 __le32 rate; /* SNDRV_PCM_RATE_* */
222 __le32 period_bytes; /* size of period in bytes */ 224 __le32 period_bytes; /* size of period in bytes */
223 __le32 buffer_bytes; /* size of buffer in bytes */ 225 __le32 buffer_bytes; /* size of buffer in bytes */
224 __le32 channels; /* channels */ 226 __le32 channels; /* channels */
225 __le32 tdm_slot; /* optional BE bitmask of supported TDM slots */
226 __le32 dai_fmt; /* SND_SOC_DAIFMT_ */
227} __attribute__((packed));
228
229/*
230 * Duplex stream configuration supported by SW/FW.
231 */
232struct snd_soc_tplg_stream_config {
233 __le32 size; /* in bytes of this structure */
234 char name[SNDRV_CTL_ELEM_ID_NAME_MAXLEN];
235 struct snd_soc_tplg_stream playback;
236 struct snd_soc_tplg_stream capture;
237} __attribute__((packed)); 227} __attribute__((packed));
238 228
239/* 229/*
@@ -366,11 +356,11 @@ struct snd_soc_tplg_dapm_widget {
366 __le32 shift; /* bits to shift */ 356 __le32 shift; /* bits to shift */
367 __le32 mask; /* non-shifted mask */ 357 __le32 mask; /* non-shifted mask */
368 __le32 subseq; /* sort within widget type */ 358 __le32 subseq; /* sort within widget type */
369 __u32 invert; /* invert the power bit */ 359 __le32 invert; /* invert the power bit */
370 __u32 ignore_suspend; /* kept enabled over suspend */ 360 __le32 ignore_suspend; /* kept enabled over suspend */
371 __u16 event_flags; 361 __le16 event_flags;
372 __u16 event_type; 362 __le16 event_type;
373 __u16 num_kcontrols; 363 __le32 num_kcontrols;
374 struct snd_soc_tplg_private priv; 364 struct snd_soc_tplg_private priv;
375 /* 365 /*
376 * kcontrols that relate to this widget 366 * kcontrols that relate to this widget
@@ -378,30 +368,46 @@ struct snd_soc_tplg_dapm_widget {
378 */ 368 */
379} __attribute__((packed)); 369} __attribute__((packed));
380 370
381struct snd_soc_tplg_pcm_cfg_caps {
382 struct snd_soc_tplg_stream_caps caps;
383 struct snd_soc_tplg_stream_config configs[SND_SOC_TPLG_STREAM_CONFIG_MAX];
384 __le32 num_configs; /* number of configs */
385} __attribute__((packed));
386 371
387/* 372/*
388 * Describes SW/FW specific features of PCM or DAI link. 373 * Describes SW/FW specific features of PCM (FE DAI & DAI link).
389 * 374 *
390 * File block representation for PCM/DAI-Link :- 375 * File block representation for PCM :-
391 * +-----------------------------------+-----+ 376 * +-----------------------------------+-----+
392 * | struct snd_soc_tplg_hdr | 1 | 377 * | struct snd_soc_tplg_hdr | 1 |
393 * +-----------------------------------+-----+ 378 * +-----------------------------------+-----+
394 * | struct snd_soc_tplg_dapm_pcm_dai | N | 379 * | struct snd_soc_tplg_pcm | N |
395 * +-----------------------------------+-----+ 380 * +-----------------------------------+-----+
396 */ 381 */
397struct snd_soc_tplg_pcm_dai { 382struct snd_soc_tplg_pcm {
398 __le32 size; /* in bytes of this structure */ 383 __le32 size; /* in bytes of this structure */
399 char name[SNDRV_CTL_ELEM_ID_NAME_MAXLEN]; 384 char pcm_name[SNDRV_CTL_ELEM_ID_NAME_MAXLEN];
400 __le32 id; /* unique ID - used to match */ 385 char dai_name[SNDRV_CTL_ELEM_ID_NAME_MAXLEN];
401 __le32 playback; /* supports playback mode */ 386 __le32 pcm_id; /* unique ID - used to match */
402 __le32 capture; /* supports capture mode */ 387 __le32 dai_id; /* unique ID - used to match */
403 __le32 compress; /* 1 = compressed; 0 = PCM */ 388 __le32 playback; /* supports playback mode */
404 struct snd_soc_tplg_pcm_cfg_caps capconf[2]; /* capabilities and configs */ 389 __le32 capture; /* supports capture mode */
390 __le32 compress; /* 1 = compressed; 0 = PCM */
391 struct snd_soc_tplg_stream stream[SND_SOC_TPLG_STREAM_CONFIG_MAX]; /* for DAI link */
392 __le32 num_streams; /* number of streams */
393 struct snd_soc_tplg_stream_caps caps[2]; /* playback and capture for DAI */
405} __attribute__((packed)); 394} __attribute__((packed));
406 395
396
397/*
398 * Describes the BE or CC link runtime supported configs or params
399 *
400 * File block representation for BE/CC link config :-
401 * +-----------------------------------+-----+
402 * | struct snd_soc_tplg_hdr | 1 |
403 * +-----------------------------------+-----+
404 * | struct snd_soc_tplg_link_config | N |
405 * +-----------------------------------+-----+
406 */
407struct snd_soc_tplg_link_config {
408 __le32 size; /* in bytes of this structure */
409 __le32 id; /* unique ID - used to match */
410 struct snd_soc_tplg_stream stream[SND_SOC_TPLG_STREAM_CONFIG_MAX]; /* supported configs playback and captrure */
411 __le32 num_streams; /* number of streams */
412} __attribute__((packed));
407#endif 413#endif
diff --git a/include/uapi/sound/asound.h b/include/uapi/sound/asound.h
index a45be6bdcf5b..a82108e5d1c0 100644
--- a/include/uapi/sound/asound.h
+++ b/include/uapi/sound/asound.h
@@ -100,9 +100,11 @@ enum {
100 SNDRV_HWDEP_IFACE_FW_FIREWORKS, /* Echo Audio Fireworks based device */ 100 SNDRV_HWDEP_IFACE_FW_FIREWORKS, /* Echo Audio Fireworks based device */
101 SNDRV_HWDEP_IFACE_FW_BEBOB, /* BridgeCo BeBoB based device */ 101 SNDRV_HWDEP_IFACE_FW_BEBOB, /* BridgeCo BeBoB based device */
102 SNDRV_HWDEP_IFACE_FW_OXFW, /* Oxford OXFW970/971 based device */ 102 SNDRV_HWDEP_IFACE_FW_OXFW, /* Oxford OXFW970/971 based device */
103 SNDRV_HWDEP_IFACE_FW_DIGI00X, /* Digidesign Digi 002/003 family */
104 SNDRV_HWDEP_IFACE_FW_TASCAM, /* TASCAM FireWire series */
103 105
104 /* Don't forget to change the following: */ 106 /* Don't forget to change the following: */
105 SNDRV_HWDEP_IFACE_LAST = SNDRV_HWDEP_IFACE_FW_OXFW 107 SNDRV_HWDEP_IFACE_LAST = SNDRV_HWDEP_IFACE_FW_TASCAM
106}; 108};
107 109
108struct snd_hwdep_info { 110struct snd_hwdep_info {
diff --git a/include/uapi/sound/emu10k1.h b/include/uapi/sound/emu10k1.h
index ec1535bb6aed..5175e166987d 100644
--- a/include/uapi/sound/emu10k1.h
+++ b/include/uapi/sound/emu10k1.h
@@ -34,6 +34,14 @@
34 34
35#define EMU10K1_FX8010_PCM_COUNT 8 35#define EMU10K1_FX8010_PCM_COUNT 8
36 36
37/*
38 * Following definition is copied from linux/types.h to support compiling
39 * this header file in userspace since they are not generally available for
40 * uapi headers.
41 */
42#define __EMU10K1_DECLARE_BITMAP(name,bits) \
43 unsigned long name[(bits) / (sizeof(unsigned long) * 8)]
44
37/* instruction set */ 45/* instruction set */
38#define iMAC0 0x00 /* R = A + (X * Y >> 31) ; saturation */ 46#define iMAC0 0x00 /* R = A + (X * Y >> 31) ; saturation */
39#define iMAC1 0x01 /* R = A + (-X * Y >> 31) ; saturation */ 47#define iMAC1 0x01 /* R = A + (-X * Y >> 31) ; saturation */
@@ -300,7 +308,7 @@ struct snd_emu10k1_fx8010_control_old_gpr {
300struct snd_emu10k1_fx8010_code { 308struct snd_emu10k1_fx8010_code {
301 char name[128]; 309 char name[128];
302 310
303 DECLARE_BITMAP(gpr_valid, 0x200); /* bitmask of valid initializers */ 311 __EMU10K1_DECLARE_BITMAP(gpr_valid, 0x200); /* bitmask of valid initializers */
304 __u32 __user *gpr_map; /* initializers */ 312 __u32 __user *gpr_map; /* initializers */
305 313
306 unsigned int gpr_add_control_count; /* count of GPR controls to add/replace */ 314 unsigned int gpr_add_control_count; /* count of GPR controls to add/replace */
@@ -313,11 +321,11 @@ struct snd_emu10k1_fx8010_code {
313 unsigned int gpr_list_control_total; /* total count of GPR controls */ 321 unsigned int gpr_list_control_total; /* total count of GPR controls */
314 struct snd_emu10k1_fx8010_control_gpr __user *gpr_list_controls; /* listed GPR controls */ 322 struct snd_emu10k1_fx8010_control_gpr __user *gpr_list_controls; /* listed GPR controls */
315 323
316 DECLARE_BITMAP(tram_valid, 0x100); /* bitmask of valid initializers */ 324 __EMU10K1_DECLARE_BITMAP(tram_valid, 0x100); /* bitmask of valid initializers */
317 __u32 __user *tram_data_map; /* data initializers */ 325 __u32 __user *tram_data_map; /* data initializers */
318 __u32 __user *tram_addr_map; /* map initializers */ 326 __u32 __user *tram_addr_map; /* map initializers */
319 327
320 DECLARE_BITMAP(code_valid, 1024); /* bitmask of valid instructions */ 328 __EMU10K1_DECLARE_BITMAP(code_valid, 1024); /* bitmask of valid instructions */
321 __u32 __user *code; /* one instruction - 64 bits */ 329 __u32 __user *code; /* one instruction - 64 bits */
322}; 330};
323 331
diff --git a/include/uapi/sound/firewire.h b/include/uapi/sound/firewire.h
index 49122df3b56b..db79a12fcc78 100644
--- a/include/uapi/sound/firewire.h
+++ b/include/uapi/sound/firewire.h
@@ -9,6 +9,7 @@
9#define SNDRV_FIREWIRE_EVENT_LOCK_STATUS 0x000010cc 9#define SNDRV_FIREWIRE_EVENT_LOCK_STATUS 0x000010cc
10#define SNDRV_FIREWIRE_EVENT_DICE_NOTIFICATION 0xd1ce004e 10#define SNDRV_FIREWIRE_EVENT_DICE_NOTIFICATION 0xd1ce004e
11#define SNDRV_FIREWIRE_EVENT_EFW_RESPONSE 0x4e617475 11#define SNDRV_FIREWIRE_EVENT_EFW_RESPONSE 0x4e617475
12#define SNDRV_FIREWIRE_EVENT_DIGI00X_MESSAGE 0x746e736c
12 13
13struct snd_firewire_event_common { 14struct snd_firewire_event_common {
14 unsigned int type; /* SNDRV_FIREWIRE_EVENT_xxx */ 15 unsigned int type; /* SNDRV_FIREWIRE_EVENT_xxx */
@@ -40,11 +41,17 @@ struct snd_firewire_event_efw_response {
40 __be32 response[0]; /* some responses */ 41 __be32 response[0]; /* some responses */
41}; 42};
42 43
44struct snd_firewire_event_digi00x_message {
45 unsigned int type;
46 __u32 message; /* Digi00x-specific message */
47};
48
43union snd_firewire_event { 49union snd_firewire_event {
44 struct snd_firewire_event_common common; 50 struct snd_firewire_event_common common;
45 struct snd_firewire_event_lock_status lock_status; 51 struct snd_firewire_event_lock_status lock_status;
46 struct snd_firewire_event_dice_notification dice_notification; 52 struct snd_firewire_event_dice_notification dice_notification;
47 struct snd_firewire_event_efw_response efw_response; 53 struct snd_firewire_event_efw_response efw_response;
54 struct snd_firewire_event_digi00x_message digi00x_message;
48}; 55};
49 56
50 57
@@ -56,6 +63,8 @@ union snd_firewire_event {
56#define SNDRV_FIREWIRE_TYPE_FIREWORKS 2 63#define SNDRV_FIREWIRE_TYPE_FIREWORKS 2
57#define SNDRV_FIREWIRE_TYPE_BEBOB 3 64#define SNDRV_FIREWIRE_TYPE_BEBOB 3
58#define SNDRV_FIREWIRE_TYPE_OXFW 4 65#define SNDRV_FIREWIRE_TYPE_OXFW 4
66#define SNDRV_FIREWIRE_TYPE_DIGI00X 5
67#define SNDRV_FIREWIRE_TYPE_TASCAM 6
59/* RME, MOTU, ... */ 68/* RME, MOTU, ... */
60 69
61struct snd_firewire_get_info { 70struct snd_firewire_get_info {
diff --git a/include/uapi/sound/hdspm.h b/include/uapi/sound/hdspm.h
index 5737332d38f2..c4db6f5b306e 100644
--- a/include/uapi/sound/hdspm.h
+++ b/include/uapi/sound/hdspm.h
@@ -20,11 +20,7 @@
20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 */ 21 */
22 22
23#ifdef __KERNEL__
24#include <linux/types.h> 23#include <linux/types.h>
25#else
26#include <stdint.h>
27#endif
28 24
29/* Maximum channels is 64 even on 56Mode you have 64playbacks to matrix */ 25/* Maximum channels is 64 even on 56Mode you have 64playbacks to matrix */
30#define HDSPM_MAX_CHANNELS 64 26#define HDSPM_MAX_CHANNELS 64
@@ -46,15 +42,15 @@ enum hdspm_speed {
46/* -------------------- IOCTL Peak/RMS Meters -------------------- */ 42/* -------------------- IOCTL Peak/RMS Meters -------------------- */
47 43
48struct hdspm_peak_rms { 44struct hdspm_peak_rms {
49 uint32_t input_peaks[64]; 45 __u32 input_peaks[64];
50 uint32_t playback_peaks[64]; 46 __u32 playback_peaks[64];
51 uint32_t output_peaks[64]; 47 __u32 output_peaks[64];
52 48
53 uint64_t input_rms[64]; 49 __u64 input_rms[64];
54 uint64_t playback_rms[64]; 50 __u64 playback_rms[64];
55 uint64_t output_rms[64]; 51 __u64 output_rms[64];
56 52
57 uint8_t speed; /* enum {ss, ds, qs} */ 53 __u8 speed; /* enum {ss, ds, qs} */
58 int status2; 54 int status2;
59}; 55};
60 56
@@ -155,21 +151,21 @@ enum hdspm_syncsource {
155}; 151};
156 152
157struct hdspm_status { 153struct hdspm_status {
158 uint8_t card_type; /* enum hdspm_io_type */ 154 __u8 card_type; /* enum hdspm_io_type */
159 enum hdspm_syncsource autosync_source; 155 enum hdspm_syncsource autosync_source;
160 156
161 uint64_t card_clock; 157 __u64 card_clock;
162 uint32_t master_period; 158 __u32 master_period;
163 159
164 union { 160 union {
165 struct { 161 struct {
166 uint8_t sync_wc; /* enum hdspm_sync */ 162 __u8 sync_wc; /* enum hdspm_sync */
167 uint8_t sync_madi; /* enum hdspm_sync */ 163 __u8 sync_madi; /* enum hdspm_sync */
168 uint8_t sync_tco; /* enum hdspm_sync */ 164 __u8 sync_tco; /* enum hdspm_sync */
169 uint8_t sync_in; /* enum hdspm_sync */ 165 __u8 sync_in; /* enum hdspm_sync */
170 uint8_t madi_input; /* enum hdspm_madi_input */ 166 __u8 madi_input; /* enum hdspm_madi_input */
171 uint8_t channel_format; /* enum hdspm_madi_channel_format */ 167 __u8 channel_format; /* enum hdspm_madi_channel_format */
172 uint8_t frame_format; /* enum hdspm_madi_frame_format */ 168 __u8 frame_format; /* enum hdspm_madi_frame_format */
173 } madi; 169 } madi;
174 } card_specific; 170 } card_specific;
175}; 171};
@@ -184,7 +180,7 @@ struct hdspm_status {
184#define HDSPM_ADDON_TCO 1 180#define HDSPM_ADDON_TCO 1
185 181
186struct hdspm_version { 182struct hdspm_version {
187 uint8_t card_type; /* enum hdspm_io_type */ 183 __u8 card_type; /* enum hdspm_io_type */
188 char cardname[20]; 184 char cardname[20];
189 unsigned int serial; 185 unsigned int serial;
190 unsigned short firmware_rev; 186 unsigned short firmware_rev;
diff --git a/scripts/mod/devicetable-offsets.c b/scripts/mod/devicetable-offsets.c
index 5a6edacc85d9..840b97328b39 100644
--- a/scripts/mod/devicetable-offsets.c
+++ b/scripts/mod/devicetable-offsets.c
@@ -197,5 +197,10 @@ int main(void)
197 DEVID_FIELD(ulpi_device_id, vendor); 197 DEVID_FIELD(ulpi_device_id, vendor);
198 DEVID_FIELD(ulpi_device_id, product); 198 DEVID_FIELD(ulpi_device_id, product);
199 199
200 DEVID(hda_device_id);
201 DEVID_FIELD(hda_device_id, vendor_id);
202 DEVID_FIELD(hda_device_id, rev_id);
203 DEVID_FIELD(hda_device_id, api_version);
204
200 return 0; 205 return 0;
201} 206}
diff --git a/scripts/mod/file2alias.c b/scripts/mod/file2alias.c
index 9bc2cfe0ee37..5b96206e9aab 100644
--- a/scripts/mod/file2alias.c
+++ b/scripts/mod/file2alias.c
@@ -1254,6 +1254,23 @@ static int do_ulpi_entry(const char *filename, void *symval,
1254} 1254}
1255ADD_TO_DEVTABLE("ulpi", ulpi_device_id, do_ulpi_entry); 1255ADD_TO_DEVTABLE("ulpi", ulpi_device_id, do_ulpi_entry);
1256 1256
1257/* Looks like: hdaudio:vNrNaN */
1258static int do_hda_entry(const char *filename, void *symval, char *alias)
1259{
1260 DEF_FIELD(symval, hda_device_id, vendor_id);
1261 DEF_FIELD(symval, hda_device_id, rev_id);
1262 DEF_FIELD(symval, hda_device_id, api_version);
1263
1264 strcpy(alias, "hdaudio:");
1265 ADD(alias, "v", vendor_id != 0, vendor_id);
1266 ADD(alias, "r", rev_id != 0, rev_id);
1267 ADD(alias, "a", api_version != 0, api_version);
1268
1269 add_wildcard(alias);
1270 return 1;
1271}
1272ADD_TO_DEVTABLE("hdaudio", hda_device_id, do_hda_entry);
1273
1257/* Does namelen bytes of name exactly match the symbol? */ 1274/* Does namelen bytes of name exactly match the symbol? */
1258static bool sym_is(const char *name, unsigned namelen, const char *symbol) 1275static bool sym_is(const char *name, unsigned namelen, const char *symbol)
1259{ 1276{
diff --git a/sound/arm/pxa2xx-ac97.c b/sound/arm/pxa2xx-ac97.c
index 38590b322c54..fbd5dad0c484 100644
--- a/sound/arm/pxa2xx-ac97.c
+++ b/sound/arm/pxa2xx-ac97.c
@@ -15,6 +15,7 @@
15#include <linux/module.h> 15#include <linux/module.h>
16#include <linux/platform_device.h> 16#include <linux/platform_device.h>
17#include <linux/dmaengine.h> 17#include <linux/dmaengine.h>
18#include <linux/dma/pxa-dma.h>
18 19
19#include <sound/core.h> 20#include <sound/core.h>
20#include <sound/pcm.h> 21#include <sound/pcm.h>
@@ -43,7 +44,11 @@ static struct snd_ac97_bus_ops pxa2xx_ac97_ops = {
43 .reset = pxa2xx_ac97_reset, 44 .reset = pxa2xx_ac97_reset,
44}; 45};
45 46
46static unsigned long pxa2xx_ac97_pcm_out_req = 12; 47static struct pxad_param pxa2xx_ac97_pcm_out_req = {
48 .prio = PXAD_PRIO_LOWEST,
49 .drcmr = 12,
50};
51
47static struct snd_dmaengine_dai_dma_data pxa2xx_ac97_pcm_out = { 52static struct snd_dmaengine_dai_dma_data pxa2xx_ac97_pcm_out = {
48 .addr = __PREG(PCDR), 53 .addr = __PREG(PCDR),
49 .addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES, 54 .addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES,
@@ -51,7 +56,11 @@ static struct snd_dmaengine_dai_dma_data pxa2xx_ac97_pcm_out = {
51 .filter_data = &pxa2xx_ac97_pcm_out_req, 56 .filter_data = &pxa2xx_ac97_pcm_out_req,
52}; 57};
53 58
54static unsigned long pxa2xx_ac97_pcm_in_req = 11; 59static struct pxad_param pxa2xx_ac97_pcm_in_req = {
60 .prio = PXAD_PRIO_LOWEST,
61 .drcmr = 11,
62};
63
55static struct snd_dmaengine_dai_dma_data pxa2xx_ac97_pcm_in = { 64static struct snd_dmaengine_dai_dma_data pxa2xx_ac97_pcm_in = {
56 .addr = __PREG(PCDR), 65 .addr = __PREG(PCDR),
57 .addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES, 66 .addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES,
diff --git a/sound/arm/pxa2xx-pcm-lib.c b/sound/arm/pxa2xx-pcm-lib.c
index 01f8fdc42b1b..e9b98af6b52c 100644
--- a/sound/arm/pxa2xx-pcm-lib.c
+++ b/sound/arm/pxa2xx-pcm-lib.c
@@ -8,6 +8,7 @@
8#include <linux/module.h> 8#include <linux/module.h>
9#include <linux/dma-mapping.h> 9#include <linux/dma-mapping.h>
10#include <linux/dmaengine.h> 10#include <linux/dmaengine.h>
11#include <linux/dma/pxa-dma.h>
11 12
12#include <sound/core.h> 13#include <sound/core.h>
13#include <sound/pcm.h> 14#include <sound/pcm.h>
@@ -15,8 +16,6 @@
15#include <sound/pxa2xx-lib.h> 16#include <sound/pxa2xx-lib.h>
16#include <sound/dmaengine_pcm.h> 17#include <sound/dmaengine_pcm.h>
17 18
18#include <mach/dma.h>
19
20#include "pxa2xx-pcm.h" 19#include "pxa2xx-pcm.h"
21 20
22static const struct snd_pcm_hardware pxa2xx_pcm_hardware = { 21static const struct snd_pcm_hardware pxa2xx_pcm_hardware = {
@@ -31,7 +30,7 @@ static const struct snd_pcm_hardware pxa2xx_pcm_hardware = {
31 .period_bytes_min = 32, 30 .period_bytes_min = 32,
32 .period_bytes_max = 8192 - 32, 31 .period_bytes_max = 8192 - 32,
33 .periods_min = 1, 32 .periods_min = 1,
34 .periods_max = PAGE_SIZE/sizeof(pxa_dma_desc), 33 .periods_max = 256,
35 .buffer_bytes_max = 128 * 1024, 34 .buffer_bytes_max = 128 * 1024,
36 .fifo_size = 32, 35 .fifo_size = 32,
37}; 36};
@@ -39,65 +38,29 @@ static const struct snd_pcm_hardware pxa2xx_pcm_hardware = {
39int __pxa2xx_pcm_hw_params(struct snd_pcm_substream *substream, 38int __pxa2xx_pcm_hw_params(struct snd_pcm_substream *substream,
40 struct snd_pcm_hw_params *params) 39 struct snd_pcm_hw_params *params)
41{ 40{
42 struct snd_pcm_runtime *runtime = substream->runtime; 41 struct dma_chan *chan = snd_dmaengine_pcm_get_chan(substream);
43 struct pxa2xx_runtime_data *rtd = runtime->private_data; 42 struct snd_soc_pcm_runtime *rtd = substream->private_data;
44 size_t totsize = params_buffer_bytes(params); 43 struct snd_dmaengine_dai_dma_data *dma_params;
45 size_t period = params_period_bytes(params); 44 struct dma_slave_config config;
46 pxa_dma_desc *dma_desc; 45 int ret;
47 dma_addr_t dma_buff_phys, next_desc_phys;
48 u32 dcmd = DCMD_INCSRCADDR | DCMD_FLOWTRG;
49 46
50 /* temporary transition hack */ 47 dma_params = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
51 switch (rtd->params->addr_width) { 48 if (!dma_params)
52 case DMA_SLAVE_BUSWIDTH_1_BYTE: 49 return 0;
53 dcmd |= DCMD_WIDTH1;
54 break;
55 case DMA_SLAVE_BUSWIDTH_2_BYTES:
56 dcmd |= DCMD_WIDTH2;
57 break;
58 case DMA_SLAVE_BUSWIDTH_4_BYTES:
59 dcmd |= DCMD_WIDTH4;
60 break;
61 default:
62 /* can't happen */
63 break;
64 }
65 50
66 switch (rtd->params->maxburst) { 51 ret = snd_hwparams_to_dma_slave_config(substream, params, &config);
67 case 8: 52 if (ret)
68 dcmd |= DCMD_BURST8; 53 return ret;
69 break;
70 case 16:
71 dcmd |= DCMD_BURST16;
72 break;
73 case 32:
74 dcmd |= DCMD_BURST32;
75 break;
76 }
77 54
78 snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer); 55 snd_dmaengine_pcm_set_config_from_dai_data(substream,
79 runtime->dma_bytes = totsize; 56 snd_soc_dai_get_dma_data(rtd->cpu_dai, substream),
57 &config);
80 58
81 dma_desc = rtd->dma_desc_array; 59 ret = dmaengine_slave_config(chan, &config);
82 next_desc_phys = rtd->dma_desc_array_phys; 60 if (ret)
83 dma_buff_phys = runtime->dma_addr; 61 return ret;
84 do { 62
85 next_desc_phys += sizeof(pxa_dma_desc); 63 snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer);
86 dma_desc->ddadr = next_desc_phys;
87 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
88 dma_desc->dsadr = dma_buff_phys;
89 dma_desc->dtadr = rtd->params->addr;
90 } else {
91 dma_desc->dsadr = rtd->params->addr;
92 dma_desc->dtadr = dma_buff_phys;
93 }
94 if (period > totsize)
95 period = totsize;
96 dma_desc->dcmd = dcmd | period | DCMD_ENDIRQEN;
97 dma_desc++;
98 dma_buff_phys += period;
99 } while (totsize -= period);
100 dma_desc[-1].ddadr = rtd->dma_desc_array_phys;
101 64
102 return 0; 65 return 0;
103} 66}
@@ -105,13 +68,6 @@ EXPORT_SYMBOL(__pxa2xx_pcm_hw_params);
105 68
106int __pxa2xx_pcm_hw_free(struct snd_pcm_substream *substream) 69int __pxa2xx_pcm_hw_free(struct snd_pcm_substream *substream)
107{ 70{
108 struct pxa2xx_runtime_data *rtd = substream->runtime->private_data;
109
110 if (rtd && rtd->params && rtd->params->filter_data) {
111 unsigned long req = *(unsigned long *) rtd->params->filter_data;
112 DRCMR(req) = 0;
113 }
114
115 snd_pcm_set_runtime_buffer(substream, NULL); 71 snd_pcm_set_runtime_buffer(substream, NULL);
116 return 0; 72 return 0;
117} 73}
@@ -119,100 +75,36 @@ EXPORT_SYMBOL(__pxa2xx_pcm_hw_free);
119 75
120int pxa2xx_pcm_trigger(struct snd_pcm_substream *substream, int cmd) 76int pxa2xx_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
121{ 77{
122 struct pxa2xx_runtime_data *prtd = substream->runtime->private_data; 78 return snd_dmaengine_pcm_trigger(substream, cmd);
123 int ret = 0;
124
125 switch (cmd) {
126 case SNDRV_PCM_TRIGGER_START:
127 DDADR(prtd->dma_ch) = prtd->dma_desc_array_phys;
128 DCSR(prtd->dma_ch) = DCSR_RUN;
129 break;
130
131 case SNDRV_PCM_TRIGGER_STOP:
132 case SNDRV_PCM_TRIGGER_SUSPEND:
133 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
134 DCSR(prtd->dma_ch) &= ~DCSR_RUN;
135 break;
136
137 case SNDRV_PCM_TRIGGER_RESUME:
138 DCSR(prtd->dma_ch) |= DCSR_RUN;
139 break;
140 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
141 DDADR(prtd->dma_ch) = prtd->dma_desc_array_phys;
142 DCSR(prtd->dma_ch) |= DCSR_RUN;
143 break;
144
145 default:
146 ret = -EINVAL;
147 }
148
149 return ret;
150} 79}
151EXPORT_SYMBOL(pxa2xx_pcm_trigger); 80EXPORT_SYMBOL(pxa2xx_pcm_trigger);
152 81
153snd_pcm_uframes_t 82snd_pcm_uframes_t
154pxa2xx_pcm_pointer(struct snd_pcm_substream *substream) 83pxa2xx_pcm_pointer(struct snd_pcm_substream *substream)
155{ 84{
156 struct snd_pcm_runtime *runtime = substream->runtime; 85 return snd_dmaengine_pcm_pointer(substream);
157 struct pxa2xx_runtime_data *prtd = runtime->private_data;
158
159 dma_addr_t ptr = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) ?
160 DSADR(prtd->dma_ch) : DTADR(prtd->dma_ch);
161 snd_pcm_uframes_t x = bytes_to_frames(runtime, ptr - runtime->dma_addr);
162
163 if (x == runtime->buffer_size)
164 x = 0;
165 return x;
166} 86}
167EXPORT_SYMBOL(pxa2xx_pcm_pointer); 87EXPORT_SYMBOL(pxa2xx_pcm_pointer);
168 88
169int __pxa2xx_pcm_prepare(struct snd_pcm_substream *substream) 89int __pxa2xx_pcm_prepare(struct snd_pcm_substream *substream)
170{ 90{
171 struct pxa2xx_runtime_data *prtd = substream->runtime->private_data;
172 unsigned long req;
173
174 if (!prtd || !prtd->params)
175 return 0;
176
177 if (prtd->dma_ch == -1)
178 return -EINVAL;
179
180 DCSR(prtd->dma_ch) &= ~DCSR_RUN;
181 DCSR(prtd->dma_ch) = 0;
182 DCMD(prtd->dma_ch) = 0;
183 req = *(unsigned long *) prtd->params->filter_data;
184 DRCMR(req) = prtd->dma_ch | DRCMR_MAPVLD;
185
186 return 0; 91 return 0;
187} 92}
188EXPORT_SYMBOL(__pxa2xx_pcm_prepare); 93EXPORT_SYMBOL(__pxa2xx_pcm_prepare);
189 94
190void pxa2xx_pcm_dma_irq(int dma_ch, void *dev_id)
191{
192 struct snd_pcm_substream *substream = dev_id;
193 int dcsr;
194
195 dcsr = DCSR(dma_ch);
196 DCSR(dma_ch) = dcsr & ~DCSR_STOPIRQEN;
197
198 if (dcsr & DCSR_ENDINTR) {
199 snd_pcm_period_elapsed(substream);
200 } else {
201 printk(KERN_ERR "DMA error on channel %d (DCSR=%#x)\n",
202 dma_ch, dcsr);
203 snd_pcm_stop_xrun(substream);
204 }
205}
206EXPORT_SYMBOL(pxa2xx_pcm_dma_irq);
207
208int __pxa2xx_pcm_open(struct snd_pcm_substream *substream) 95int __pxa2xx_pcm_open(struct snd_pcm_substream *substream)
209{ 96{
97 struct snd_soc_pcm_runtime *rtd = substream->private_data;
210 struct snd_pcm_runtime *runtime = substream->runtime; 98 struct snd_pcm_runtime *runtime = substream->runtime;
211 struct pxa2xx_runtime_data *rtd; 99 struct snd_dmaengine_dai_dma_data *dma_params;
212 int ret; 100 int ret;
213 101
214 runtime->hw = pxa2xx_pcm_hardware; 102 runtime->hw = pxa2xx_pcm_hardware;
215 103
104 dma_params = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
105 if (!dma_params)
106 return 0;
107
216 /* 108 /*
217 * For mysterious reasons (and despite what the manual says) 109 * For mysterious reasons (and despite what the manual says)
218 * playback samples are lost if the DMA count is not a multiple 110 * playback samples are lost if the DMA count is not a multiple
@@ -221,48 +113,27 @@ int __pxa2xx_pcm_open(struct snd_pcm_substream *substream)
221 ret = snd_pcm_hw_constraint_step(runtime, 0, 113 ret = snd_pcm_hw_constraint_step(runtime, 0,
222 SNDRV_PCM_HW_PARAM_PERIOD_BYTES, 32); 114 SNDRV_PCM_HW_PARAM_PERIOD_BYTES, 32);
223 if (ret) 115 if (ret)
224 goto out; 116 return ret;
225 117
226 ret = snd_pcm_hw_constraint_step(runtime, 0, 118 ret = snd_pcm_hw_constraint_step(runtime, 0,
227 SNDRV_PCM_HW_PARAM_BUFFER_BYTES, 32); 119 SNDRV_PCM_HW_PARAM_BUFFER_BYTES, 32);
228 if (ret) 120 if (ret)
229 goto out; 121 return ret;
230 122
231 ret = snd_pcm_hw_constraint_integer(runtime, 123 ret = snd_pcm_hw_constraint_integer(runtime,
232 SNDRV_PCM_HW_PARAM_PERIODS); 124 SNDRV_PCM_HW_PARAM_PERIODS);
233 if (ret < 0) 125 if (ret < 0)
234 goto out; 126 return ret;
235
236 ret = -ENOMEM;
237 rtd = kzalloc(sizeof(*rtd), GFP_KERNEL);
238 if (!rtd)
239 goto out;
240 rtd->dma_desc_array =
241 dma_alloc_writecombine(substream->pcm->card->dev, PAGE_SIZE,
242 &rtd->dma_desc_array_phys, GFP_KERNEL);
243 if (!rtd->dma_desc_array)
244 goto err1;
245 127
246 rtd->dma_ch = -1; 128 return snd_dmaengine_pcm_open_request_chan(substream,
247 runtime->private_data = rtd; 129 pxad_filter_fn,
248 return 0; 130 dma_params->filter_data);
249
250 err1:
251 kfree(rtd);
252 out:
253 return ret;
254} 131}
255EXPORT_SYMBOL(__pxa2xx_pcm_open); 132EXPORT_SYMBOL(__pxa2xx_pcm_open);
256 133
257int __pxa2xx_pcm_close(struct snd_pcm_substream *substream) 134int __pxa2xx_pcm_close(struct snd_pcm_substream *substream)
258{ 135{
259 struct snd_pcm_runtime *runtime = substream->runtime; 136 return snd_dmaengine_pcm_close_release_chan(substream);
260 struct pxa2xx_runtime_data *rtd = runtime->private_data;
261
262 dma_free_writecombine(substream->pcm->card->dev, PAGE_SIZE,
263 rtd->dma_desc_array, rtd->dma_desc_array_phys);
264 kfree(rtd);
265 return 0;
266} 137}
267EXPORT_SYMBOL(__pxa2xx_pcm_close); 138EXPORT_SYMBOL(__pxa2xx_pcm_close);
268 139
diff --git a/sound/arm/pxa2xx-pcm.c b/sound/arm/pxa2xx-pcm.c
index 83be8e3f095e..83fcfac97739 100644
--- a/sound/arm/pxa2xx-pcm.c
+++ b/sound/arm/pxa2xx-pcm.c
@@ -46,17 +46,13 @@ static int pxa2xx_pcm_open(struct snd_pcm_substream *substream)
46 46
47 rtd->params = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) ? 47 rtd->params = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) ?
48 client->playback_params : client->capture_params; 48 client->playback_params : client->capture_params;
49 ret = pxa_request_dma("dma", DMA_PRIO_LOW,
50 pxa2xx_pcm_dma_irq, substream);
51 if (ret < 0)
52 goto err2;
53 rtd->dma_ch = ret;
54 49
55 ret = client->startup(substream); 50 ret = client->startup(substream);
56 if (!ret) 51 if (!ret)
57 goto out; 52 goto err2;
53
54 return 0;
58 55
59 pxa_free_dma(rtd->dma_ch);
60 err2: 56 err2:
61 __pxa2xx_pcm_close(substream); 57 __pxa2xx_pcm_close(substream);
62 out: 58 out:
@@ -66,9 +62,7 @@ static int pxa2xx_pcm_open(struct snd_pcm_substream *substream)
66static int pxa2xx_pcm_close(struct snd_pcm_substream *substream) 62static int pxa2xx_pcm_close(struct snd_pcm_substream *substream)
67{ 63{
68 struct pxa2xx_pcm_client *client = substream->private_data; 64 struct pxa2xx_pcm_client *client = substream->private_data;
69 struct pxa2xx_runtime_data *rtd = substream->runtime->private_data;
70 65
71 pxa_free_dma(rtd->dma_ch);
72 client->shutdown(substream); 66 client->shutdown(substream);
73 67
74 return __pxa2xx_pcm_close(substream); 68 return __pxa2xx_pcm_close(substream);
diff --git a/sound/arm/pxa2xx-pcm.h b/sound/arm/pxa2xx-pcm.h
index 00330985beec..8fa2b7c9e6b8 100644
--- a/sound/arm/pxa2xx-pcm.h
+++ b/sound/arm/pxa2xx-pcm.h
@@ -13,8 +13,6 @@
13struct pxa2xx_runtime_data { 13struct pxa2xx_runtime_data {
14 int dma_ch; 14 int dma_ch;
15 struct snd_dmaengine_dai_dma_data *params; 15 struct snd_dmaengine_dai_dma_data *params;
16 struct pxa_dma_desc *dma_desc_array;
17 dma_addr_t dma_desc_array_phys;
18}; 16};
19 17
20struct pxa2xx_pcm_client { 18struct pxa2xx_pcm_client {
diff --git a/sound/core/Kconfig b/sound/core/Kconfig
index 6c96feeaf01e..e3e949126a56 100644
--- a/sound/core/Kconfig
+++ b/sound/core/Kconfig
@@ -4,7 +4,7 @@ config SND_TIMER
4 4
5config SND_PCM 5config SND_PCM
6 tristate 6 tristate
7 select SND_TIMER 7 select SND_TIMER if SND_PCM_TIMER
8 8
9config SND_PCM_ELD 9config SND_PCM_ELD
10 bool 10 bool
@@ -93,6 +93,17 @@ config SND_PCM_OSS_PLUGINS
93 support conversion of channels, formats and rates. It will 93 support conversion of channels, formats and rates. It will
94 behave like most of new OSS/Free drivers in 2.4/2.6 kernels. 94 behave like most of new OSS/Free drivers in 2.4/2.6 kernels.
95 95
96config SND_PCM_TIMER
97 bool "PCM timer interface" if EXPERT
98 default y
99 help
100 If you disable this option, pcm timer will be inavailable, so
101 those stubs used pcm timer (e.g. dmix, dsnoop & co) may work
102 incorrectlly.
103
104 For some embedded device, we may disable it to reduce memory
105 footprint, about 20KB on x86_64 platform.
106
96config SND_SEQUENCER_OSS 107config SND_SEQUENCER_OSS
97 bool "OSS Sequencer API" 108 bool "OSS Sequencer API"
98 depends on SND_SEQUENCER 109 depends on SND_SEQUENCER
diff --git a/sound/core/Makefile b/sound/core/Makefile
index 3354f91e003a..48ab4b8f8279 100644
--- a/sound/core/Makefile
+++ b/sound/core/Makefile
@@ -13,8 +13,9 @@ snd-$(CONFIG_SND_OSSEMUL) += sound_oss.o
13snd-$(CONFIG_SND_VMASTER) += vmaster.o 13snd-$(CONFIG_SND_VMASTER) += vmaster.o
14snd-$(CONFIG_SND_JACK) += ctljack.o jack.o 14snd-$(CONFIG_SND_JACK) += ctljack.o jack.o
15 15
16snd-pcm-y := pcm.o pcm_native.o pcm_lib.o pcm_timer.o pcm_misc.o \ 16snd-pcm-y := pcm.o pcm_native.o pcm_lib.o pcm_misc.o \
17 pcm_memory.o memalloc.o 17 pcm_memory.o memalloc.o
18snd-pcm-$(CONFIG_SND_PCM_TIMER) += pcm_timer.o
18snd-pcm-$(CONFIG_SND_DMA_SGBUF) += sgbuf.o 19snd-pcm-$(CONFIG_SND_DMA_SGBUF) += sgbuf.o
19snd-pcm-$(CONFIG_SND_PCM_ELD) += pcm_drm_eld.o 20snd-pcm-$(CONFIG_SND_PCM_ELD) += pcm_drm_eld.o
20snd-pcm-$(CONFIG_SND_PCM_IEC958) += pcm_iec958.o 21snd-pcm-$(CONFIG_SND_PCM_IEC958) += pcm_iec958.o
diff --git a/sound/core/oss/mixer_oss.c b/sound/core/oss/mixer_oss.c
index a99f7200ff3f..7a8c79dd9734 100644
--- a/sound/core/oss/mixer_oss.c
+++ b/sound/core/oss/mixer_oss.c
@@ -1177,7 +1177,8 @@ static void snd_mixer_oss_proc_write(struct snd_info_entry *entry,
1177 struct snd_mixer_oss *mixer = entry->private_data; 1177 struct snd_mixer_oss *mixer = entry->private_data;
1178 char line[128], str[32], idxstr[16]; 1178 char line[128], str[32], idxstr[16];
1179 const char *cptr; 1179 const char *cptr;
1180 int ch, idx; 1180 unsigned int idx;
1181 int ch;
1181 struct snd_mixer_oss_assign_table *tbl; 1182 struct snd_mixer_oss_assign_table *tbl;
1182 struct slot *slot; 1183 struct slot *slot;
1183 1184
diff --git a/sound/core/pcm.c b/sound/core/pcm.c
index 02bd96954dc4..308c9ecf73db 100644
--- a/sound/core/pcm.c
+++ b/sound/core/pcm.c
@@ -1014,9 +1014,6 @@ void snd_pcm_detach_substream(struct snd_pcm_substream *substream)
1014 snd_free_pages((void*)runtime->control, 1014 snd_free_pages((void*)runtime->control,
1015 PAGE_ALIGN(sizeof(struct snd_pcm_mmap_control))); 1015 PAGE_ALIGN(sizeof(struct snd_pcm_mmap_control)));
1016 kfree(runtime->hw_constraints.rules); 1016 kfree(runtime->hw_constraints.rules);
1017#ifdef CONFIG_SND_PCM_XRUN_DEBUG
1018 kfree(runtime->hwptr_log);
1019#endif
1020 kfree(runtime); 1017 kfree(runtime);
1021 substream->runtime = NULL; 1018 substream->runtime = NULL;
1022 put_pid(substream->pid); 1019 put_pid(substream->pid);
diff --git a/sound/core/pcm_lib.c b/sound/core/pcm_lib.c
index 7d45645f10ba..6b5a811e01a5 100644
--- a/sound/core/pcm_lib.c
+++ b/sound/core/pcm_lib.c
@@ -801,7 +801,7 @@ void snd_interval_mulkdiv(const struct snd_interval *a, unsigned int k,
801 * negative error code. 801 * negative error code.
802 */ 802 */
803int snd_interval_ratnum(struct snd_interval *i, 803int snd_interval_ratnum(struct snd_interval *i,
804 unsigned int rats_count, struct snd_ratnum *rats, 804 unsigned int rats_count, const struct snd_ratnum *rats,
805 unsigned int *nump, unsigned int *denp) 805 unsigned int *nump, unsigned int *denp)
806{ 806{
807 unsigned int best_num, best_den; 807 unsigned int best_num, best_den;
@@ -920,7 +920,8 @@ EXPORT_SYMBOL(snd_interval_ratnum);
920 * negative error code. 920 * negative error code.
921 */ 921 */
922static int snd_interval_ratden(struct snd_interval *i, 922static int snd_interval_ratden(struct snd_interval *i,
923 unsigned int rats_count, struct snd_ratden *rats, 923 unsigned int rats_count,
924 const struct snd_ratden *rats,
924 unsigned int *nump, unsigned int *denp) 925 unsigned int *nump, unsigned int *denp)
925{ 926{
926 unsigned int best_num, best_diff, best_den; 927 unsigned int best_num, best_diff, best_den;
@@ -1339,7 +1340,7 @@ EXPORT_SYMBOL(snd_pcm_hw_constraint_ranges);
1339static int snd_pcm_hw_rule_ratnums(struct snd_pcm_hw_params *params, 1340static int snd_pcm_hw_rule_ratnums(struct snd_pcm_hw_params *params,
1340 struct snd_pcm_hw_rule *rule) 1341 struct snd_pcm_hw_rule *rule)
1341{ 1342{
1342 struct snd_pcm_hw_constraint_ratnums *r = rule->private; 1343 const struct snd_pcm_hw_constraint_ratnums *r = rule->private;
1343 unsigned int num = 0, den = 0; 1344 unsigned int num = 0, den = 0;
1344 int err; 1345 int err;
1345 err = snd_interval_ratnum(hw_param_interval(params, rule->var), 1346 err = snd_interval_ratnum(hw_param_interval(params, rule->var),
@@ -1363,10 +1364,10 @@ static int snd_pcm_hw_rule_ratnums(struct snd_pcm_hw_params *params,
1363int snd_pcm_hw_constraint_ratnums(struct snd_pcm_runtime *runtime, 1364int snd_pcm_hw_constraint_ratnums(struct snd_pcm_runtime *runtime,
1364 unsigned int cond, 1365 unsigned int cond,
1365 snd_pcm_hw_param_t var, 1366 snd_pcm_hw_param_t var,
1366 struct snd_pcm_hw_constraint_ratnums *r) 1367 const struct snd_pcm_hw_constraint_ratnums *r)
1367{ 1368{
1368 return snd_pcm_hw_rule_add(runtime, cond, var, 1369 return snd_pcm_hw_rule_add(runtime, cond, var,
1369 snd_pcm_hw_rule_ratnums, r, 1370 snd_pcm_hw_rule_ratnums, (void *)r,
1370 var, -1); 1371 var, -1);
1371} 1372}
1372 1373
@@ -1375,7 +1376,7 @@ EXPORT_SYMBOL(snd_pcm_hw_constraint_ratnums);
1375static int snd_pcm_hw_rule_ratdens(struct snd_pcm_hw_params *params, 1376static int snd_pcm_hw_rule_ratdens(struct snd_pcm_hw_params *params,
1376 struct snd_pcm_hw_rule *rule) 1377 struct snd_pcm_hw_rule *rule)
1377{ 1378{
1378 struct snd_pcm_hw_constraint_ratdens *r = rule->private; 1379 const struct snd_pcm_hw_constraint_ratdens *r = rule->private;
1379 unsigned int num = 0, den = 0; 1380 unsigned int num = 0, den = 0;
1380 int err = snd_interval_ratden(hw_param_interval(params, rule->var), 1381 int err = snd_interval_ratden(hw_param_interval(params, rule->var),
1381 r->nrats, r->rats, &num, &den); 1382 r->nrats, r->rats, &num, &den);
@@ -1398,10 +1399,10 @@ static int snd_pcm_hw_rule_ratdens(struct snd_pcm_hw_params *params,
1398int snd_pcm_hw_constraint_ratdens(struct snd_pcm_runtime *runtime, 1399int snd_pcm_hw_constraint_ratdens(struct snd_pcm_runtime *runtime,
1399 unsigned int cond, 1400 unsigned int cond,
1400 snd_pcm_hw_param_t var, 1401 snd_pcm_hw_param_t var,
1401 struct snd_pcm_hw_constraint_ratdens *r) 1402 const struct snd_pcm_hw_constraint_ratdens *r)
1402{ 1403{
1403 return snd_pcm_hw_rule_add(runtime, cond, var, 1404 return snd_pcm_hw_rule_add(runtime, cond, var,
1404 snd_pcm_hw_rule_ratdens, r, 1405 snd_pcm_hw_rule_ratdens, (void *)r,
1405 var, -1); 1406 var, -1);
1406} 1407}
1407 1408
@@ -1875,20 +1876,17 @@ void snd_pcm_period_elapsed(struct snd_pcm_substream *substream)
1875 return; 1876 return;
1876 runtime = substream->runtime; 1877 runtime = substream->runtime;
1877 1878
1878 if (runtime->transfer_ack_begin)
1879 runtime->transfer_ack_begin(substream);
1880
1881 snd_pcm_stream_lock_irqsave(substream, flags); 1879 snd_pcm_stream_lock_irqsave(substream, flags);
1882 if (!snd_pcm_running(substream) || 1880 if (!snd_pcm_running(substream) ||
1883 snd_pcm_update_hw_ptr0(substream, 1) < 0) 1881 snd_pcm_update_hw_ptr0(substream, 1) < 0)
1884 goto _end; 1882 goto _end;
1885 1883
1884#ifdef CONFIG_SND_PCM_TIMER
1886 if (substream->timer_running) 1885 if (substream->timer_running)
1887 snd_timer_interrupt(substream->timer, 1); 1886 snd_timer_interrupt(substream->timer, 1);
1887#endif
1888 _end: 1888 _end:
1889 snd_pcm_stream_unlock_irqrestore(substream, flags); 1889 snd_pcm_stream_unlock_irqrestore(substream, flags);
1890 if (runtime->transfer_ack_end)
1891 runtime->transfer_ack_end(substream);
1892 kill_fasync(&runtime->fasync, SIGIO, POLL_IN); 1890 kill_fasync(&runtime->fasync, SIGIO, POLL_IN);
1893} 1891}
1894 1892
diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c
index 75888dd38a7f..a8b27cdc2844 100644
--- a/sound/core/pcm_native.c
+++ b/sound/core/pcm_native.c
@@ -486,6 +486,16 @@ static void snd_pcm_set_state(struct snd_pcm_substream *substream, int state)
486 snd_pcm_stream_unlock_irq(substream); 486 snd_pcm_stream_unlock_irq(substream);
487} 487}
488 488
489static inline void snd_pcm_timer_notify(struct snd_pcm_substream *substream,
490 int event)
491{
492#ifdef CONFIG_SND_PCM_TIMER
493 if (substream->timer)
494 snd_timer_notify(substream->timer, event,
495 &substream->runtime->trigger_tstamp);
496#endif
497}
498
489static int snd_pcm_hw_params(struct snd_pcm_substream *substream, 499static int snd_pcm_hw_params(struct snd_pcm_substream *substream,
490 struct snd_pcm_hw_params *params) 500 struct snd_pcm_hw_params *params)
491{ 501{
@@ -650,7 +660,8 @@ static int snd_pcm_sw_params(struct snd_pcm_substream *substream,
650 } 660 }
651 snd_pcm_stream_unlock_irq(substream); 661 snd_pcm_stream_unlock_irq(substream);
652 662
653 if (params->tstamp_mode > SNDRV_PCM_TSTAMP_LAST) 663 if (params->tstamp_mode < 0 ||
664 params->tstamp_mode > SNDRV_PCM_TSTAMP_LAST)
654 return -EINVAL; 665 return -EINVAL;
655 if (params->proto >= SNDRV_PROTOCOL_VERSION(2, 0, 12) && 666 if (params->proto >= SNDRV_PROTOCOL_VERSION(2, 0, 12) &&
656 params->tstamp_type > SNDRV_PCM_TSTAMP_TYPE_LAST) 667 params->tstamp_type > SNDRV_PCM_TSTAMP_TYPE_LAST)
@@ -1042,9 +1053,7 @@ static void snd_pcm_post_start(struct snd_pcm_substream *substream, int state)
1042 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK && 1053 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK &&
1043 runtime->silence_size > 0) 1054 runtime->silence_size > 0)
1044 snd_pcm_playback_silence(substream, ULONG_MAX); 1055 snd_pcm_playback_silence(substream, ULONG_MAX);
1045 if (substream->timer) 1056 snd_pcm_timer_notify(substream, SNDRV_TIMER_EVENT_MSTART);
1046 snd_timer_notify(substream->timer, SNDRV_TIMER_EVENT_MSTART,
1047 &runtime->trigger_tstamp);
1048} 1057}
1049 1058
1050static struct action_ops snd_pcm_action_start = { 1059static struct action_ops snd_pcm_action_start = {
@@ -1092,9 +1101,7 @@ static void snd_pcm_post_stop(struct snd_pcm_substream *substream, int state)
1092 if (runtime->status->state != state) { 1101 if (runtime->status->state != state) {
1093 snd_pcm_trigger_tstamp(substream); 1102 snd_pcm_trigger_tstamp(substream);
1094 runtime->status->state = state; 1103 runtime->status->state = state;
1095 if (substream->timer) 1104 snd_pcm_timer_notify(substream, SNDRV_TIMER_EVENT_MSTOP);
1096 snd_timer_notify(substream->timer, SNDRV_TIMER_EVENT_MSTOP,
1097 &runtime->trigger_tstamp);
1098 } 1105 }
1099 wake_up(&runtime->sleep); 1106 wake_up(&runtime->sleep);
1100 wake_up(&runtime->tsleep); 1107 wake_up(&runtime->tsleep);
@@ -1208,18 +1215,12 @@ static void snd_pcm_post_pause(struct snd_pcm_substream *substream, int push)
1208 snd_pcm_trigger_tstamp(substream); 1215 snd_pcm_trigger_tstamp(substream);
1209 if (push) { 1216 if (push) {
1210 runtime->status->state = SNDRV_PCM_STATE_PAUSED; 1217 runtime->status->state = SNDRV_PCM_STATE_PAUSED;
1211 if (substream->timer) 1218 snd_pcm_timer_notify(substream, SNDRV_TIMER_EVENT_MPAUSE);
1212 snd_timer_notify(substream->timer,
1213 SNDRV_TIMER_EVENT_MPAUSE,
1214 &runtime->trigger_tstamp);
1215 wake_up(&runtime->sleep); 1219 wake_up(&runtime->sleep);
1216 wake_up(&runtime->tsleep); 1220 wake_up(&runtime->tsleep);
1217 } else { 1221 } else {
1218 runtime->status->state = SNDRV_PCM_STATE_RUNNING; 1222 runtime->status->state = SNDRV_PCM_STATE_RUNNING;
1219 if (substream->timer) 1223 snd_pcm_timer_notify(substream, SNDRV_TIMER_EVENT_MCONTINUE);
1220 snd_timer_notify(substream->timer,
1221 SNDRV_TIMER_EVENT_MCONTINUE,
1222 &runtime->trigger_tstamp);
1223 } 1224 }
1224} 1225}
1225 1226
@@ -1267,9 +1268,7 @@ static void snd_pcm_post_suspend(struct snd_pcm_substream *substream, int state)
1267 snd_pcm_trigger_tstamp(substream); 1268 snd_pcm_trigger_tstamp(substream);
1268 runtime->status->suspended_state = runtime->status->state; 1269 runtime->status->suspended_state = runtime->status->state;
1269 runtime->status->state = SNDRV_PCM_STATE_SUSPENDED; 1270 runtime->status->state = SNDRV_PCM_STATE_SUSPENDED;
1270 if (substream->timer) 1271 snd_pcm_timer_notify(substream, SNDRV_TIMER_EVENT_MSUSPEND);
1271 snd_timer_notify(substream->timer, SNDRV_TIMER_EVENT_MSUSPEND,
1272 &runtime->trigger_tstamp);
1273 wake_up(&runtime->sleep); 1272 wake_up(&runtime->sleep);
1274 wake_up(&runtime->tsleep); 1273 wake_up(&runtime->tsleep);
1275} 1274}
@@ -1373,9 +1372,7 @@ static void snd_pcm_post_resume(struct snd_pcm_substream *substream, int state)
1373 struct snd_pcm_runtime *runtime = substream->runtime; 1372 struct snd_pcm_runtime *runtime = substream->runtime;
1374 snd_pcm_trigger_tstamp(substream); 1373 snd_pcm_trigger_tstamp(substream);
1375 runtime->status->state = runtime->status->suspended_state; 1374 runtime->status->state = runtime->status->suspended_state;
1376 if (substream->timer) 1375 snd_pcm_timer_notify(substream, SNDRV_TIMER_EVENT_MRESUME);
1377 snd_timer_notify(substream->timer, SNDRV_TIMER_EVENT_MRESUME,
1378 &runtime->trigger_tstamp);
1379} 1376}
1380 1377
1381static struct action_ops snd_pcm_action_resume = { 1378static struct action_ops snd_pcm_action_resume = {
@@ -2226,7 +2223,8 @@ void snd_pcm_release_substream(struct snd_pcm_substream *substream)
2226 2223
2227 snd_pcm_drop(substream); 2224 snd_pcm_drop(substream);
2228 if (substream->hw_opened) { 2225 if (substream->hw_opened) {
2229 if (substream->ops->hw_free != NULL) 2226 if (substream->ops->hw_free &&
2227 substream->runtime->status->state != SNDRV_PCM_STATE_OPEN)
2230 substream->ops->hw_free(substream); 2228 substream->ops->hw_free(substream);
2231 substream->ops->close(substream); 2229 substream->ops->close(substream);
2232 substream->hw_opened = 0; 2230 substream->hw_opened = 0;
diff --git a/sound/core/seq/oss/seq_oss_readq.c b/sound/core/seq/oss/seq_oss_readq.c
index ccd893566f1d..046cb586fb2f 100644
--- a/sound/core/seq/oss/seq_oss_readq.c
+++ b/sound/core/seq/oss/seq_oss_readq.c
@@ -91,8 +91,7 @@ snd_seq_oss_readq_clear(struct seq_oss_readq *q)
91 q->head = q->tail = 0; 91 q->head = q->tail = 0;
92 } 92 }
93 /* if someone sleeping, wake'em up */ 93 /* if someone sleeping, wake'em up */
94 if (waitqueue_active(&q->midi_sleep)) 94 wake_up(&q->midi_sleep);
95 wake_up(&q->midi_sleep);
96 q->input_time = (unsigned long)-1; 95 q->input_time = (unsigned long)-1;
97} 96}
98 97
@@ -138,8 +137,7 @@ snd_seq_oss_readq_put_event(struct seq_oss_readq *q, union evrec *ev)
138 q->qlen++; 137 q->qlen++;
139 138
140 /* wake up sleeper */ 139 /* wake up sleeper */
141 if (waitqueue_active(&q->midi_sleep)) 140 wake_up(&q->midi_sleep);
142 wake_up(&q->midi_sleep);
143 141
144 spin_unlock_irqrestore(&q->lock, flags); 142 spin_unlock_irqrestore(&q->lock, flags);
145 143
diff --git a/sound/core/seq/oss/seq_oss_writeq.c b/sound/core/seq/oss/seq_oss_writeq.c
index d50338bbc21f..1f6788a18444 100644
--- a/sound/core/seq/oss/seq_oss_writeq.c
+++ b/sound/core/seq/oss/seq_oss_writeq.c
@@ -138,9 +138,7 @@ snd_seq_oss_writeq_wakeup(struct seq_oss_writeq *q, abstime_t time)
138 spin_lock_irqsave(&q->sync_lock, flags); 138 spin_lock_irqsave(&q->sync_lock, flags);
139 q->sync_time = time; 139 q->sync_time = time;
140 q->sync_event_put = 0; 140 q->sync_event_put = 0;
141 if (waitqueue_active(&q->sync_sleep)) { 141 wake_up(&q->sync_sleep);
142 wake_up(&q->sync_sleep);
143 }
144 spin_unlock_irqrestore(&q->sync_lock, flags); 142 spin_unlock_irqrestore(&q->sync_lock, flags);
145} 143}
146 144
diff --git a/sound/firewire/Kconfig b/sound/firewire/Kconfig
index 8850b7de1d38..bee0e5f1a116 100644
--- a/sound/firewire/Kconfig
+++ b/sound/firewire/Kconfig
@@ -120,4 +120,31 @@ config SND_BEBOB
120 To compile this driver as a module, choose M here: the module 120 To compile this driver as a module, choose M here: the module
121 will be called snd-bebob. 121 will be called snd-bebob.
122 122
123config SND_FIREWIRE_DIGI00X
124 tristate "Digidesign Digi 002/003 family support"
125 select SND_FIREWIRE_LIB
126 select SND_HWDEP
127 help
128 Say Y here to include support for Digidesign Digi 002/003 family.
129 * Digi 002 Console
130 * Digi 002 Rack
131 * Digi 003 Console
132 * Digi 003 Rack
133 * Digi 003 Rack+
134
135 To compile this driver as a module, choose M here: the module
136 will be called snd-firewire-digi00x.
137
138config SND_FIREWIRE_TASCAM
139 tristate "TASCAM FireWire series support"
140 select SND_FIREWIRE_LIB
141 select SND_HWDEP
142 help
143 Say Y here to include support for TASCAM.
144 * FW-1884
145 * FW-1082
146
147 To compile this driver as a module, choose M here: the module
148 will be called snd-firewire-tascam.
149
123endif # SND_FIREWIRE 150endif # SND_FIREWIRE
diff --git a/sound/firewire/Makefile b/sound/firewire/Makefile
index 8b37f084b2ab..f5fb62551c60 100644
--- a/sound/firewire/Makefile
+++ b/sound/firewire/Makefile
@@ -1,6 +1,5 @@
1snd-firewire-lib-objs := lib.o iso-resources.o packets-buffer.o \ 1snd-firewire-lib-objs := lib.o iso-resources.o packets-buffer.o \
2 fcp.o cmp.o amdtp.o 2 fcp.o cmp.o amdtp-stream.o amdtp-am824.o
3snd-oxfw-objs := oxfw.o
4snd-isight-objs := isight.o 3snd-isight-objs := isight.o
5snd-scs1x-objs := scs1x.o 4snd-scs1x-objs := scs1x.o
6 5
@@ -11,3 +10,5 @@ obj-$(CONFIG_SND_ISIGHT) += snd-isight.o
11obj-$(CONFIG_SND_SCS1X) += snd-scs1x.o 10obj-$(CONFIG_SND_SCS1X) += snd-scs1x.o
12obj-$(CONFIG_SND_FIREWORKS) += fireworks/ 11obj-$(CONFIG_SND_FIREWORKS) += fireworks/
13obj-$(CONFIG_SND_BEBOB) += bebob/ 12obj-$(CONFIG_SND_BEBOB) += bebob/
13obj-$(CONFIG_SND_FIREWIRE_DIGI00X) += digi00x/
14obj-$(CONFIG_SND_FIREWIRE_TASCAM) += tascam/
diff --git a/sound/firewire/amdtp-am824.c b/sound/firewire/amdtp-am824.c
new file mode 100644
index 000000000000..bebddc60fde8
--- /dev/null
+++ b/sound/firewire/amdtp-am824.c
@@ -0,0 +1,465 @@
1/*
2 * AM824 format in Audio and Music Data Transmission Protocol (IEC 61883-6)
3 *
4 * Copyright (c) Clemens Ladisch <clemens@ladisch.de>
5 * Copyright (c) 2015 Takashi Sakamoto <o-takashi@sakamocchi.jp>
6 *
7 * Licensed under the terms of the GNU General Public License, version 2.
8 */
9
10#include <linux/slab.h>
11
12#include "amdtp-am824.h"
13
14#define CIP_FMT_AM 0x10
15
16/* "Clock-based rate control mode" is just supported. */
17#define AMDTP_FDF_AM824 0x00
18
19/*
20 * Nominally 3125 bytes/second, but the MIDI port's clock might be
21 * 1% too slow, and the bus clock 100 ppm too fast.
22 */
23#define MIDI_BYTES_PER_SECOND 3093
24
25/*
26 * Several devices look only at the first eight data blocks.
27 * In any case, this is more than enough for the MIDI data rate.
28 */
29#define MAX_MIDI_RX_BLOCKS 8
30
31struct amdtp_am824 {
32 struct snd_rawmidi_substream *midi[AM824_MAX_CHANNELS_FOR_MIDI * 8];
33 int midi_fifo_limit;
34 int midi_fifo_used[AM824_MAX_CHANNELS_FOR_MIDI * 8];
35 unsigned int pcm_channels;
36 unsigned int midi_ports;
37
38 u8 pcm_positions[AM824_MAX_CHANNELS_FOR_PCM];
39 u8 midi_position;
40
41 void (*transfer_samples)(struct amdtp_stream *s,
42 struct snd_pcm_substream *pcm,
43 __be32 *buffer, unsigned int frames);
44
45 unsigned int frame_multiplier;
46};
47
48/**
49 * amdtp_am824_set_parameters - set stream parameters
50 * @s: the AMDTP stream to configure
51 * @rate: the sample rate
52 * @pcm_channels: the number of PCM samples in each data block, to be encoded
53 * as AM824 multi-bit linear audio
54 * @midi_ports: the number of MIDI ports (i.e., MPX-MIDI Data Channels)
55 * @double_pcm_frames: one data block transfers two PCM frames
56 *
57 * The parameters must be set before the stream is started, and must not be
58 * changed while the stream is running.
59 */
60int amdtp_am824_set_parameters(struct amdtp_stream *s, unsigned int rate,
61 unsigned int pcm_channels,
62 unsigned int midi_ports,
63 bool double_pcm_frames)
64{
65 struct amdtp_am824 *p = s->protocol;
66 unsigned int midi_channels;
67 unsigned int i;
68 int err;
69
70 if (amdtp_stream_running(s))
71 return -EINVAL;
72
73 if (pcm_channels > AM824_MAX_CHANNELS_FOR_PCM)
74 return -EINVAL;
75
76 midi_channels = DIV_ROUND_UP(midi_ports, 8);
77 if (midi_channels > AM824_MAX_CHANNELS_FOR_MIDI)
78 return -EINVAL;
79
80 if (WARN_ON(amdtp_stream_running(s)) ||
81 WARN_ON(pcm_channels > AM824_MAX_CHANNELS_FOR_PCM) ||
82 WARN_ON(midi_channels > AM824_MAX_CHANNELS_FOR_MIDI))
83 return -EINVAL;
84
85 err = amdtp_stream_set_parameters(s, rate,
86 pcm_channels + midi_channels);
87 if (err < 0)
88 return err;
89
90 s->fdf = AMDTP_FDF_AM824 | s->sfc;
91
92 p->pcm_channels = pcm_channels;
93 p->midi_ports = midi_ports;
94
95 /*
96 * In IEC 61883-6, one data block represents one event. In ALSA, one
97 * event equals to one PCM frame. But Dice has a quirk at higher
98 * sampling rate to transfer two PCM frames in one data block.
99 */
100 if (double_pcm_frames)
101 p->frame_multiplier = 2;
102 else
103 p->frame_multiplier = 1;
104
105 /* init the position map for PCM and MIDI channels */
106 for (i = 0; i < pcm_channels; i++)
107 p->pcm_positions[i] = i;
108 p->midi_position = p->pcm_channels;
109
110 /*
111 * We do not know the actual MIDI FIFO size of most devices. Just
112 * assume two bytes, i.e., one byte can be received over the bus while
113 * the previous one is transmitted over MIDI.
114 * (The value here is adjusted for midi_ratelimit_per_packet().)
115 */
116 p->midi_fifo_limit = rate - MIDI_BYTES_PER_SECOND * s->syt_interval + 1;
117
118 return 0;
119}
120EXPORT_SYMBOL_GPL(amdtp_am824_set_parameters);
121
122/**
123 * amdtp_am824_set_pcm_position - set an index of data channel for a channel
124 * of PCM frame
125 * @s: the AMDTP stream
126 * @index: the index of data channel in an data block
127 * @position: the channel of PCM frame
128 */
129void amdtp_am824_set_pcm_position(struct amdtp_stream *s, unsigned int index,
130 unsigned int position)
131{
132 struct amdtp_am824 *p = s->protocol;
133
134 if (index < p->pcm_channels)
135 p->pcm_positions[index] = position;
136}
137EXPORT_SYMBOL_GPL(amdtp_am824_set_pcm_position);
138
139/**
140 * amdtp_am824_set_midi_position - set a index of data channel for MIDI
141 * conformant data channel
142 * @s: the AMDTP stream
143 * @position: the index of data channel in an data block
144 */
145void amdtp_am824_set_midi_position(struct amdtp_stream *s,
146 unsigned int position)
147{
148 struct amdtp_am824 *p = s->protocol;
149
150 p->midi_position = position;
151}
152EXPORT_SYMBOL_GPL(amdtp_am824_set_midi_position);
153
154static void write_pcm_s32(struct amdtp_stream *s,
155 struct snd_pcm_substream *pcm,
156 __be32 *buffer, unsigned int frames)
157{
158 struct amdtp_am824 *p = s->protocol;
159 struct snd_pcm_runtime *runtime = pcm->runtime;
160 unsigned int channels, remaining_frames, i, c;
161 const u32 *src;
162
163 channels = p->pcm_channels;
164 src = (void *)runtime->dma_area +
165 frames_to_bytes(runtime, s->pcm_buffer_pointer);
166 remaining_frames = runtime->buffer_size - s->pcm_buffer_pointer;
167
168 for (i = 0; i < frames; ++i) {
169 for (c = 0; c < channels; ++c) {
170 buffer[p->pcm_positions[c]] =
171 cpu_to_be32((*src >> 8) | 0x40000000);
172 src++;
173 }
174 buffer += s->data_block_quadlets;
175 if (--remaining_frames == 0)
176 src = (void *)runtime->dma_area;
177 }
178}
179
180static void write_pcm_s16(struct amdtp_stream *s,
181 struct snd_pcm_substream *pcm,
182 __be32 *buffer, unsigned int frames)
183{
184 struct amdtp_am824 *p = s->protocol;
185 struct snd_pcm_runtime *runtime = pcm->runtime;
186 unsigned int channels, remaining_frames, i, c;
187 const u16 *src;
188
189 channels = p->pcm_channels;
190 src = (void *)runtime->dma_area +
191 frames_to_bytes(runtime, s->pcm_buffer_pointer);
192 remaining_frames = runtime->buffer_size - s->pcm_buffer_pointer;
193
194 for (i = 0; i < frames; ++i) {
195 for (c = 0; c < channels; ++c) {
196 buffer[p->pcm_positions[c]] =
197 cpu_to_be32((*src << 8) | 0x42000000);
198 src++;
199 }
200 buffer += s->data_block_quadlets;
201 if (--remaining_frames == 0)
202 src = (void *)runtime->dma_area;
203 }
204}
205
206static void read_pcm_s32(struct amdtp_stream *s,
207 struct snd_pcm_substream *pcm,
208 __be32 *buffer, unsigned int frames)
209{
210 struct amdtp_am824 *p = s->protocol;
211 struct snd_pcm_runtime *runtime = pcm->runtime;
212 unsigned int channels, remaining_frames, i, c;
213 u32 *dst;
214
215 channels = p->pcm_channels;
216 dst = (void *)runtime->dma_area +
217 frames_to_bytes(runtime, s->pcm_buffer_pointer);
218 remaining_frames = runtime->buffer_size - s->pcm_buffer_pointer;
219
220 for (i = 0; i < frames; ++i) {
221 for (c = 0; c < channels; ++c) {
222 *dst = be32_to_cpu(buffer[p->pcm_positions[c]]) << 8;
223 dst++;
224 }
225 buffer += s->data_block_quadlets;
226 if (--remaining_frames == 0)
227 dst = (void *)runtime->dma_area;
228 }
229}
230
231static void write_pcm_silence(struct amdtp_stream *s,
232 __be32 *buffer, unsigned int frames)
233{
234 struct amdtp_am824 *p = s->protocol;
235 unsigned int i, c, channels = p->pcm_channels;
236
237 for (i = 0; i < frames; ++i) {
238 for (c = 0; c < channels; ++c)
239 buffer[p->pcm_positions[c]] = cpu_to_be32(0x40000000);
240 buffer += s->data_block_quadlets;
241 }
242}
243
244/**
245 * amdtp_am824_set_pcm_format - set the PCM format
246 * @s: the AMDTP stream to configure
247 * @format: the format of the ALSA PCM device
248 *
249 * The sample format must be set after the other parameters (rate/PCM channels/
250 * MIDI) and before the stream is started, and must not be changed while the
251 * stream is running.
252 */
253void amdtp_am824_set_pcm_format(struct amdtp_stream *s, snd_pcm_format_t format)
254{
255 struct amdtp_am824 *p = s->protocol;
256
257 if (WARN_ON(amdtp_stream_pcm_running(s)))
258 return;
259
260 switch (format) {
261 default:
262 WARN_ON(1);
263 /* fall through */
264 case SNDRV_PCM_FORMAT_S16:
265 if (s->direction == AMDTP_OUT_STREAM) {
266 p->transfer_samples = write_pcm_s16;
267 break;
268 }
269 WARN_ON(1);
270 /* fall through */
271 case SNDRV_PCM_FORMAT_S32:
272 if (s->direction == AMDTP_OUT_STREAM)
273 p->transfer_samples = write_pcm_s32;
274 else
275 p->transfer_samples = read_pcm_s32;
276 break;
277 }
278}
279EXPORT_SYMBOL_GPL(amdtp_am824_set_pcm_format);
280
281/**
282 * amdtp_am824_add_pcm_hw_constraints - add hw constraints for PCM substream
283 * @s: the AMDTP stream for AM824 data block, must be initialized.
284 * @runtime: the PCM substream runtime
285 *
286 */
287int amdtp_am824_add_pcm_hw_constraints(struct amdtp_stream *s,
288 struct snd_pcm_runtime *runtime)
289{
290 int err;
291
292 err = amdtp_stream_add_pcm_hw_constraints(s, runtime);
293 if (err < 0)
294 return err;
295
296 /* AM824 in IEC 61883-6 can deliver 24bit data. */
297 return snd_pcm_hw_constraint_msbits(runtime, 0, 32, 24);
298}
299EXPORT_SYMBOL_GPL(amdtp_am824_add_pcm_hw_constraints);
300
301/**
302 * amdtp_am824_midi_trigger - start/stop playback/capture with a MIDI device
303 * @s: the AMDTP stream
304 * @port: index of MIDI port
305 * @midi: the MIDI device to be started, or %NULL to stop the current device
306 *
307 * Call this function on a running isochronous stream to enable the actual
308 * transmission of MIDI data. This function should be called from the MIDI
309 * device's .trigger callback.
310 */
311void amdtp_am824_midi_trigger(struct amdtp_stream *s, unsigned int port,
312 struct snd_rawmidi_substream *midi)
313{
314 struct amdtp_am824 *p = s->protocol;
315
316 if (port < p->midi_ports)
317 ACCESS_ONCE(p->midi[port]) = midi;
318}
319EXPORT_SYMBOL_GPL(amdtp_am824_midi_trigger);
320
321/*
322 * To avoid sending MIDI bytes at too high a rate, assume that the receiving
323 * device has a FIFO, and track how much it is filled. This values increases
324 * by one whenever we send one byte in a packet, but the FIFO empties at
325 * a constant rate independent of our packet rate. One packet has syt_interval
326 * samples, so the number of bytes that empty out of the FIFO, per packet(!),
327 * is MIDI_BYTES_PER_SECOND * syt_interval / sample_rate. To avoid storing
328 * fractional values, the values in midi_fifo_used[] are measured in bytes
329 * multiplied by the sample rate.
330 */
331static bool midi_ratelimit_per_packet(struct amdtp_stream *s, unsigned int port)
332{
333 struct amdtp_am824 *p = s->protocol;
334 int used;
335
336 used = p->midi_fifo_used[port];
337 if (used == 0) /* common shortcut */
338 return true;
339
340 used -= MIDI_BYTES_PER_SECOND * s->syt_interval;
341 used = max(used, 0);
342 p->midi_fifo_used[port] = used;
343
344 return used < p->midi_fifo_limit;
345}
346
347static void midi_rate_use_one_byte(struct amdtp_stream *s, unsigned int port)
348{
349 struct amdtp_am824 *p = s->protocol;
350
351 p->midi_fifo_used[port] += amdtp_rate_table[s->sfc];
352}
353
354static void write_midi_messages(struct amdtp_stream *s, __be32 *buffer,
355 unsigned int frames)
356{
357 struct amdtp_am824 *p = s->protocol;
358 unsigned int f, port;
359 u8 *b;
360
361 for (f = 0; f < frames; f++) {
362 b = (u8 *)&buffer[p->midi_position];
363
364 port = (s->data_block_counter + f) % 8;
365 if (f < MAX_MIDI_RX_BLOCKS &&
366 midi_ratelimit_per_packet(s, port) &&
367 p->midi[port] != NULL &&
368 snd_rawmidi_transmit(p->midi[port], &b[1], 1) == 1) {
369 midi_rate_use_one_byte(s, port);
370 b[0] = 0x81;
371 } else {
372 b[0] = 0x80;
373 b[1] = 0;
374 }
375 b[2] = 0;
376 b[3] = 0;
377
378 buffer += s->data_block_quadlets;
379 }
380}
381
382static void read_midi_messages(struct amdtp_stream *s,
383 __be32 *buffer, unsigned int frames)
384{
385 struct amdtp_am824 *p = s->protocol;
386 unsigned int f, port;
387 int len;
388 u8 *b;
389
390 for (f = 0; f < frames; f++) {
391 port = (s->data_block_counter + f) % 8;
392 b = (u8 *)&buffer[p->midi_position];
393
394 len = b[0] - 0x80;
395 if ((1 <= len) && (len <= 3) && (p->midi[port]))
396 snd_rawmidi_receive(p->midi[port], b + 1, len);
397
398 buffer += s->data_block_quadlets;
399 }
400}
401
402static unsigned int process_rx_data_blocks(struct amdtp_stream *s, __be32 *buffer,
403 unsigned int data_blocks, unsigned int *syt)
404{
405 struct amdtp_am824 *p = s->protocol;
406 struct snd_pcm_substream *pcm = ACCESS_ONCE(s->pcm);
407 unsigned int pcm_frames;
408
409 if (pcm) {
410 p->transfer_samples(s, pcm, buffer, data_blocks);
411 pcm_frames = data_blocks * p->frame_multiplier;
412 } else {
413 write_pcm_silence(s, buffer, data_blocks);
414 pcm_frames = 0;
415 }
416
417 if (p->midi_ports)
418 write_midi_messages(s, buffer, data_blocks);
419
420 return pcm_frames;
421}
422
423static unsigned int process_tx_data_blocks(struct amdtp_stream *s, __be32 *buffer,
424 unsigned int data_blocks, unsigned int *syt)
425{
426 struct amdtp_am824 *p = s->protocol;
427 struct snd_pcm_substream *pcm = ACCESS_ONCE(s->pcm);
428 unsigned int pcm_frames;
429
430 if (pcm) {
431 p->transfer_samples(s, pcm, buffer, data_blocks);
432 pcm_frames = data_blocks * p->frame_multiplier;
433 } else {
434 pcm_frames = 0;
435 }
436
437 if (p->midi_ports)
438 read_midi_messages(s, buffer, data_blocks);
439
440 return pcm_frames;
441}
442
443/**
444 * amdtp_am824_init - initialize an AMDTP stream structure to handle AM824
445 * data block
446 * @s: the AMDTP stream to initialize
447 * @unit: the target of the stream
448 * @dir: the direction of stream
449 * @flags: the packet transmission method to use
450 */
451int amdtp_am824_init(struct amdtp_stream *s, struct fw_unit *unit,
452 enum amdtp_stream_direction dir, enum cip_flags flags)
453{
454 amdtp_stream_process_data_blocks_t process_data_blocks;
455
456 if (dir == AMDTP_IN_STREAM)
457 process_data_blocks = process_tx_data_blocks;
458 else
459 process_data_blocks = process_rx_data_blocks;
460
461 return amdtp_stream_init(s, unit, dir, flags, CIP_FMT_AM,
462 process_data_blocks,
463 sizeof(struct amdtp_am824));
464}
465EXPORT_SYMBOL_GPL(amdtp_am824_init);
diff --git a/sound/firewire/amdtp-am824.h b/sound/firewire/amdtp-am824.h
new file mode 100644
index 000000000000..73b07b3109db
--- /dev/null
+++ b/sound/firewire/amdtp-am824.h
@@ -0,0 +1,52 @@
1#ifndef SOUND_FIREWIRE_AMDTP_AM824_H_INCLUDED
2#define SOUND_FIREWIRE_AMDTP_AM824_H_INCLUDED
3
4#include <sound/pcm.h>
5#include <sound/rawmidi.h>
6
7#include "amdtp-stream.h"
8
9#define AM824_IN_PCM_FORMAT_BITS SNDRV_PCM_FMTBIT_S32
10
11#define AM824_OUT_PCM_FORMAT_BITS (SNDRV_PCM_FMTBIT_S16 | \
12 SNDRV_PCM_FMTBIT_S32)
13
14/*
15 * This module supports maximum 64 PCM channels for one PCM stream
16 * This is for our convenience.
17 */
18#define AM824_MAX_CHANNELS_FOR_PCM 64
19
20/*
21 * AMDTP packet can include channels for MIDI conformant data.
22 * Each MIDI conformant data channel includes 8 MPX-MIDI data stream.
23 * Each MPX-MIDI data stream includes one data stream from/to MIDI ports.
24 *
25 * This module supports maximum 1 MIDI conformant data channels.
26 * Then this AMDTP packets can transfer maximum 8 MIDI data streams.
27 */
28#define AM824_MAX_CHANNELS_FOR_MIDI 1
29
30int amdtp_am824_set_parameters(struct amdtp_stream *s, unsigned int rate,
31 unsigned int pcm_channels,
32 unsigned int midi_ports,
33 bool double_pcm_frames);
34
35void amdtp_am824_set_pcm_position(struct amdtp_stream *s, unsigned int index,
36 unsigned int position);
37
38void amdtp_am824_set_midi_position(struct amdtp_stream *s,
39 unsigned int position);
40
41int amdtp_am824_add_pcm_hw_constraints(struct amdtp_stream *s,
42 struct snd_pcm_runtime *runtime);
43
44void amdtp_am824_set_pcm_format(struct amdtp_stream *s,
45 snd_pcm_format_t format);
46
47void amdtp_am824_midi_trigger(struct amdtp_stream *s, unsigned int port,
48 struct snd_rawmidi_substream *midi);
49
50int amdtp_am824_init(struct amdtp_stream *s, struct fw_unit *unit,
51 enum amdtp_stream_direction dir, enum cip_flags flags);
52#endif
diff --git a/sound/firewire/amdtp.c b/sound/firewire/amdtp-stream.c
index 2a153d260836..ed2902609a4c 100644
--- a/sound/firewire/amdtp.c
+++ b/sound/firewire/amdtp-stream.c
@@ -11,28 +11,14 @@
11#include <linux/firewire.h> 11#include <linux/firewire.h>
12#include <linux/module.h> 12#include <linux/module.h>
13#include <linux/slab.h> 13#include <linux/slab.h>
14#include <linux/sched.h>
15#include <sound/pcm.h> 14#include <sound/pcm.h>
16#include <sound/pcm_params.h> 15#include <sound/pcm_params.h>
17#include <sound/rawmidi.h> 16#include "amdtp-stream.h"
18#include "amdtp.h"
19 17
20#define TICKS_PER_CYCLE 3072 18#define TICKS_PER_CYCLE 3072
21#define CYCLES_PER_SECOND 8000 19#define CYCLES_PER_SECOND 8000
22#define TICKS_PER_SECOND (TICKS_PER_CYCLE * CYCLES_PER_SECOND) 20#define TICKS_PER_SECOND (TICKS_PER_CYCLE * CYCLES_PER_SECOND)
23 21
24/*
25 * Nominally 3125 bytes/second, but the MIDI port's clock might be
26 * 1% too slow, and the bus clock 100 ppm too fast.
27 */
28#define MIDI_BYTES_PER_SECOND 3093
29
30/*
31 * Several devices look only at the first eight data blocks.
32 * In any case, this is more than enough for the MIDI data rate.
33 */
34#define MAX_MIDI_RX_BLOCKS 8
35
36#define TRANSFER_DELAY_TICKS 0x2e00 /* 479.17 microseconds */ 22#define TRANSFER_DELAY_TICKS 0x2e00 /* 479.17 microseconds */
37 23
38/* isochronous header parameters */ 24/* isochronous header parameters */
@@ -55,12 +41,8 @@
55#define CIP_SYT_MASK 0x0000ffff 41#define CIP_SYT_MASK 0x0000ffff
56#define CIP_SYT_NO_INFO 0xffff 42#define CIP_SYT_NO_INFO 0xffff
57 43
58/* 44/* Audio and Music transfer protocol specific parameters */
59 * Audio and Music transfer protocol specific parameters 45#define CIP_FMT_AM 0x10
60 * only "Clock-based rate control mode" is supported
61 */
62#define CIP_FMT_AM (0x10 << CIP_FMT_SHIFT)
63#define AMDTP_FDF_AM824 (0 << (CIP_FDF_SHIFT + 3))
64#define AMDTP_FDF_NO_DATA 0xff 46#define AMDTP_FDF_NO_DATA 0xff
65 47
66/* TODO: make these configurable */ 48/* TODO: make these configurable */
@@ -78,10 +60,23 @@ static void pcm_period_tasklet(unsigned long data);
78 * @unit: the target of the stream 60 * @unit: the target of the stream
79 * @dir: the direction of stream 61 * @dir: the direction of stream
80 * @flags: the packet transmission method to use 62 * @flags: the packet transmission method to use
63 * @fmt: the value of fmt field in CIP header
64 * @process_data_blocks: callback handler to process data blocks
65 * @protocol_size: the size to allocate newly for protocol
81 */ 66 */
82int amdtp_stream_init(struct amdtp_stream *s, struct fw_unit *unit, 67int amdtp_stream_init(struct amdtp_stream *s, struct fw_unit *unit,
83 enum amdtp_stream_direction dir, enum cip_flags flags) 68 enum amdtp_stream_direction dir, enum cip_flags flags,
69 unsigned int fmt,
70 amdtp_stream_process_data_blocks_t process_data_blocks,
71 unsigned int protocol_size)
84{ 72{
73 if (process_data_blocks == NULL)
74 return -EINVAL;
75
76 s->protocol = kzalloc(protocol_size, GFP_KERNEL);
77 if (!s->protocol)
78 return -ENOMEM;
79
85 s->unit = unit; 80 s->unit = unit;
86 s->direction = dir; 81 s->direction = dir;
87 s->flags = flags; 82 s->flags = flags;
@@ -94,6 +89,9 @@ int amdtp_stream_init(struct amdtp_stream *s, struct fw_unit *unit,
94 s->callbacked = false; 89 s->callbacked = false;
95 s->sync_slave = NULL; 90 s->sync_slave = NULL;
96 91
92 s->fmt = fmt;
93 s->process_data_blocks = process_data_blocks;
94
97 return 0; 95 return 0;
98} 96}
99EXPORT_SYMBOL(amdtp_stream_init); 97EXPORT_SYMBOL(amdtp_stream_init);
@@ -105,6 +103,7 @@ EXPORT_SYMBOL(amdtp_stream_init);
105void amdtp_stream_destroy(struct amdtp_stream *s) 103void amdtp_stream_destroy(struct amdtp_stream *s)
106{ 104{
107 WARN_ON(amdtp_stream_running(s)); 105 WARN_ON(amdtp_stream_running(s));
106 kfree(s->protocol);
108 mutex_destroy(&s->mutex); 107 mutex_destroy(&s->mutex);
109} 108}
110EXPORT_SYMBOL(amdtp_stream_destroy); 109EXPORT_SYMBOL(amdtp_stream_destroy);
@@ -141,11 +140,6 @@ int amdtp_stream_add_pcm_hw_constraints(struct amdtp_stream *s,
141{ 140{
142 int err; 141 int err;
143 142
144 /* AM824 in IEC 61883-6 can deliver 24bit data */
145 err = snd_pcm_hw_constraint_msbits(runtime, 0, 32, 24);
146 if (err < 0)
147 goto end;
148
149 /* 143 /*
150 * Currently firewire-lib processes 16 packets in one software 144 * Currently firewire-lib processes 16 packets in one software
151 * interrupt callback. This equals to 2msec but actually the 145 * interrupt callback. This equals to 2msec but actually the
@@ -190,39 +184,25 @@ EXPORT_SYMBOL(amdtp_stream_add_pcm_hw_constraints);
190 * amdtp_stream_set_parameters - set stream parameters 184 * amdtp_stream_set_parameters - set stream parameters
191 * @s: the AMDTP stream to configure 185 * @s: the AMDTP stream to configure
192 * @rate: the sample rate 186 * @rate: the sample rate
193 * @pcm_channels: the number of PCM samples in each data block, to be encoded 187 * @data_block_quadlets: the size of a data block in quadlet unit
194 * as AM824 multi-bit linear audio
195 * @midi_ports: the number of MIDI ports (i.e., MPX-MIDI Data Channels)
196 * 188 *
197 * The parameters must be set before the stream is started, and must not be 189 * The parameters must be set before the stream is started, and must not be
198 * changed while the stream is running. 190 * changed while the stream is running.
199 */ 191 */
200void amdtp_stream_set_parameters(struct amdtp_stream *s, 192int amdtp_stream_set_parameters(struct amdtp_stream *s, unsigned int rate,
201 unsigned int rate, 193 unsigned int data_block_quadlets)
202 unsigned int pcm_channels,
203 unsigned int midi_ports)
204{ 194{
205 unsigned int i, sfc, midi_channels; 195 unsigned int sfc;
206 196
207 midi_channels = DIV_ROUND_UP(midi_ports, 8); 197 for (sfc = 0; sfc < ARRAY_SIZE(amdtp_rate_table); ++sfc) {
208
209 if (WARN_ON(amdtp_stream_running(s)) |
210 WARN_ON(pcm_channels > AMDTP_MAX_CHANNELS_FOR_PCM) |
211 WARN_ON(midi_channels > AMDTP_MAX_CHANNELS_FOR_MIDI))
212 return;
213
214 for (sfc = 0; sfc < ARRAY_SIZE(amdtp_rate_table); ++sfc)
215 if (amdtp_rate_table[sfc] == rate) 198 if (amdtp_rate_table[sfc] == rate)
216 goto sfc_found; 199 break;
217 WARN_ON(1); 200 }
218 return; 201 if (sfc == ARRAY_SIZE(amdtp_rate_table))
202 return -EINVAL;
219 203
220sfc_found:
221 s->pcm_channels = pcm_channels;
222 s->sfc = sfc; 204 s->sfc = sfc;
223 s->data_block_quadlets = s->pcm_channels + midi_channels; 205 s->data_block_quadlets = data_block_quadlets;
224 s->midi_ports = midi_ports;
225
226 s->syt_interval = amdtp_syt_intervals[sfc]; 206 s->syt_interval = amdtp_syt_intervals[sfc];
227 207
228 /* default buffering in the device */ 208 /* default buffering in the device */
@@ -231,18 +211,7 @@ sfc_found:
231 /* additional buffering needed to adjust for no-data packets */ 211 /* additional buffering needed to adjust for no-data packets */
232 s->transfer_delay += TICKS_PER_SECOND * s->syt_interval / rate; 212 s->transfer_delay += TICKS_PER_SECOND * s->syt_interval / rate;
233 213
234 /* init the position map for PCM and MIDI channels */ 214 return 0;
235 for (i = 0; i < pcm_channels; i++)
236 s->pcm_positions[i] = i;
237 s->midi_position = s->pcm_channels;
238
239 /*
240 * We do not know the actual MIDI FIFO size of most devices. Just
241 * assume two bytes, i.e., one byte can be received over the bus while
242 * the previous one is transmitted over MIDI.
243 * (The value here is adjusted for midi_ratelimit_per_packet().)
244 */
245 s->midi_fifo_limit = rate - MIDI_BYTES_PER_SECOND * s->syt_interval + 1;
246} 215}
247EXPORT_SYMBOL(amdtp_stream_set_parameters); 216EXPORT_SYMBOL(amdtp_stream_set_parameters);
248 217
@@ -264,52 +233,6 @@ unsigned int amdtp_stream_get_max_payload(struct amdtp_stream *s)
264} 233}
265EXPORT_SYMBOL(amdtp_stream_get_max_payload); 234EXPORT_SYMBOL(amdtp_stream_get_max_payload);
266 235
267static void write_pcm_s16(struct amdtp_stream *s,
268 struct snd_pcm_substream *pcm,
269 __be32 *buffer, unsigned int frames);
270static void write_pcm_s32(struct amdtp_stream *s,
271 struct snd_pcm_substream *pcm,
272 __be32 *buffer, unsigned int frames);
273static void read_pcm_s32(struct amdtp_stream *s,
274 struct snd_pcm_substream *pcm,
275 __be32 *buffer, unsigned int frames);
276
277/**
278 * amdtp_stream_set_pcm_format - set the PCM format
279 * @s: the AMDTP stream to configure
280 * @format: the format of the ALSA PCM device
281 *
282 * The sample format must be set after the other parameters (rate/PCM channels/
283 * MIDI) and before the stream is started, and must not be changed while the
284 * stream is running.
285 */
286void amdtp_stream_set_pcm_format(struct amdtp_stream *s,
287 snd_pcm_format_t format)
288{
289 if (WARN_ON(amdtp_stream_pcm_running(s)))
290 return;
291
292 switch (format) {
293 default:
294 WARN_ON(1);
295 /* fall through */
296 case SNDRV_PCM_FORMAT_S16:
297 if (s->direction == AMDTP_OUT_STREAM) {
298 s->transfer_samples = write_pcm_s16;
299 break;
300 }
301 WARN_ON(1);
302 /* fall through */
303 case SNDRV_PCM_FORMAT_S32:
304 if (s->direction == AMDTP_OUT_STREAM)
305 s->transfer_samples = write_pcm_s32;
306 else
307 s->transfer_samples = read_pcm_s32;
308 break;
309 }
310}
311EXPORT_SYMBOL(amdtp_stream_set_pcm_format);
312
313/** 236/**
314 * amdtp_stream_pcm_prepare - prepare PCM device for running 237 * amdtp_stream_pcm_prepare - prepare PCM device for running
315 * @s: the AMDTP stream 238 * @s: the AMDTP stream
@@ -412,182 +335,12 @@ static unsigned int calculate_syt(struct amdtp_stream *s,
412 } 335 }
413} 336}
414 337
415static void write_pcm_s32(struct amdtp_stream *s,
416 struct snd_pcm_substream *pcm,
417 __be32 *buffer, unsigned int frames)
418{
419 struct snd_pcm_runtime *runtime = pcm->runtime;
420 unsigned int channels, remaining_frames, i, c;
421 const u32 *src;
422
423 channels = s->pcm_channels;
424 src = (void *)runtime->dma_area +
425 frames_to_bytes(runtime, s->pcm_buffer_pointer);
426 remaining_frames = runtime->buffer_size - s->pcm_buffer_pointer;
427
428 for (i = 0; i < frames; ++i) {
429 for (c = 0; c < channels; ++c) {
430 buffer[s->pcm_positions[c]] =
431 cpu_to_be32((*src >> 8) | 0x40000000);
432 src++;
433 }
434 buffer += s->data_block_quadlets;
435 if (--remaining_frames == 0)
436 src = (void *)runtime->dma_area;
437 }
438}
439
440static void write_pcm_s16(struct amdtp_stream *s,
441 struct snd_pcm_substream *pcm,
442 __be32 *buffer, unsigned int frames)
443{
444 struct snd_pcm_runtime *runtime = pcm->runtime;
445 unsigned int channels, remaining_frames, i, c;
446 const u16 *src;
447
448 channels = s->pcm_channels;
449 src = (void *)runtime->dma_area +
450 frames_to_bytes(runtime, s->pcm_buffer_pointer);
451 remaining_frames = runtime->buffer_size - s->pcm_buffer_pointer;
452
453 for (i = 0; i < frames; ++i) {
454 for (c = 0; c < channels; ++c) {
455 buffer[s->pcm_positions[c]] =
456 cpu_to_be32((*src << 8) | 0x42000000);
457 src++;
458 }
459 buffer += s->data_block_quadlets;
460 if (--remaining_frames == 0)
461 src = (void *)runtime->dma_area;
462 }
463}
464
465static void read_pcm_s32(struct amdtp_stream *s,
466 struct snd_pcm_substream *pcm,
467 __be32 *buffer, unsigned int frames)
468{
469 struct snd_pcm_runtime *runtime = pcm->runtime;
470 unsigned int channels, remaining_frames, i, c;
471 u32 *dst;
472
473 channels = s->pcm_channels;
474 dst = (void *)runtime->dma_area +
475 frames_to_bytes(runtime, s->pcm_buffer_pointer);
476 remaining_frames = runtime->buffer_size - s->pcm_buffer_pointer;
477
478 for (i = 0; i < frames; ++i) {
479 for (c = 0; c < channels; ++c) {
480 *dst = be32_to_cpu(buffer[s->pcm_positions[c]]) << 8;
481 dst++;
482 }
483 buffer += s->data_block_quadlets;
484 if (--remaining_frames == 0)
485 dst = (void *)runtime->dma_area;
486 }
487}
488
489static void write_pcm_silence(struct amdtp_stream *s,
490 __be32 *buffer, unsigned int frames)
491{
492 unsigned int i, c;
493
494 for (i = 0; i < frames; ++i) {
495 for (c = 0; c < s->pcm_channels; ++c)
496 buffer[s->pcm_positions[c]] = cpu_to_be32(0x40000000);
497 buffer += s->data_block_quadlets;
498 }
499}
500
501/*
502 * To avoid sending MIDI bytes at too high a rate, assume that the receiving
503 * device has a FIFO, and track how much it is filled. This values increases
504 * by one whenever we send one byte in a packet, but the FIFO empties at
505 * a constant rate independent of our packet rate. One packet has syt_interval
506 * samples, so the number of bytes that empty out of the FIFO, per packet(!),
507 * is MIDI_BYTES_PER_SECOND * syt_interval / sample_rate. To avoid storing
508 * fractional values, the values in midi_fifo_used[] are measured in bytes
509 * multiplied by the sample rate.
510 */
511static bool midi_ratelimit_per_packet(struct amdtp_stream *s, unsigned int port)
512{
513 int used;
514
515 used = s->midi_fifo_used[port];
516 if (used == 0) /* common shortcut */
517 return true;
518
519 used -= MIDI_BYTES_PER_SECOND * s->syt_interval;
520 used = max(used, 0);
521 s->midi_fifo_used[port] = used;
522
523 return used < s->midi_fifo_limit;
524}
525
526static void midi_rate_use_one_byte(struct amdtp_stream *s, unsigned int port)
527{
528 s->midi_fifo_used[port] += amdtp_rate_table[s->sfc];
529}
530
531static void write_midi_messages(struct amdtp_stream *s,
532 __be32 *buffer, unsigned int frames)
533{
534 unsigned int f, port;
535 u8 *b;
536
537 for (f = 0; f < frames; f++) {
538 b = (u8 *)&buffer[s->midi_position];
539
540 port = (s->data_block_counter + f) % 8;
541 if (f < MAX_MIDI_RX_BLOCKS &&
542 midi_ratelimit_per_packet(s, port) &&
543 s->midi[port] != NULL &&
544 snd_rawmidi_transmit(s->midi[port], &b[1], 1) == 1) {
545 midi_rate_use_one_byte(s, port);
546 b[0] = 0x81;
547 } else {
548 b[0] = 0x80;
549 b[1] = 0;
550 }
551 b[2] = 0;
552 b[3] = 0;
553
554 buffer += s->data_block_quadlets;
555 }
556}
557
558static void read_midi_messages(struct amdtp_stream *s,
559 __be32 *buffer, unsigned int frames)
560{
561 unsigned int f, port;
562 int len;
563 u8 *b;
564
565 for (f = 0; f < frames; f++) {
566 port = (s->data_block_counter + f) % 8;
567 b = (u8 *)&buffer[s->midi_position];
568
569 len = b[0] - 0x80;
570 if ((1 <= len) && (len <= 3) && (s->midi[port]))
571 snd_rawmidi_receive(s->midi[port], b + 1, len);
572
573 buffer += s->data_block_quadlets;
574 }
575}
576
577static void update_pcm_pointers(struct amdtp_stream *s, 338static void update_pcm_pointers(struct amdtp_stream *s,
578 struct snd_pcm_substream *pcm, 339 struct snd_pcm_substream *pcm,
579 unsigned int frames) 340 unsigned int frames)
580{ 341{
581 unsigned int ptr; 342 unsigned int ptr;
582 343
583 /*
584 * In IEC 61883-6, one data block represents one event. In ALSA, one
585 * event equals to one PCM frame. But Dice has a quirk to transfer
586 * two PCM frames in one data block.
587 */
588 if (s->double_pcm_frames)
589 frames *= 2;
590
591 ptr = s->pcm_buffer_pointer + frames; 344 ptr = s->pcm_buffer_pointer + frames;
592 if (ptr >= pcm->runtime->buffer_size) 345 if (ptr >= pcm->runtime->buffer_size)
593 ptr -= pcm->runtime->buffer_size; 346 ptr -= pcm->runtime->buffer_size;
@@ -656,23 +409,19 @@ static int handle_out_packet(struct amdtp_stream *s, unsigned int data_blocks,
656{ 409{
657 __be32 *buffer; 410 __be32 *buffer;
658 unsigned int payload_length; 411 unsigned int payload_length;
412 unsigned int pcm_frames;
659 struct snd_pcm_substream *pcm; 413 struct snd_pcm_substream *pcm;
660 414
661 buffer = s->buffer.packets[s->packet_index].buffer; 415 buffer = s->buffer.packets[s->packet_index].buffer;
416 pcm_frames = s->process_data_blocks(s, buffer + 2, data_blocks, &syt);
417
662 buffer[0] = cpu_to_be32(ACCESS_ONCE(s->source_node_id_field) | 418 buffer[0] = cpu_to_be32(ACCESS_ONCE(s->source_node_id_field) |
663 (s->data_block_quadlets << CIP_DBS_SHIFT) | 419 (s->data_block_quadlets << CIP_DBS_SHIFT) |
664 s->data_block_counter); 420 s->data_block_counter);
665 buffer[1] = cpu_to_be32(CIP_EOH | CIP_FMT_AM | AMDTP_FDF_AM824 | 421 buffer[1] = cpu_to_be32(CIP_EOH |
666 (s->sfc << CIP_FDF_SHIFT) | syt); 422 ((s->fmt << CIP_FMT_SHIFT) & CIP_FMT_MASK) |
667 buffer += 2; 423 ((s->fdf << CIP_FDF_SHIFT) & CIP_FDF_MASK) |
668 424 (syt & CIP_SYT_MASK));
669 pcm = ACCESS_ONCE(s->pcm);
670 if (pcm)
671 s->transfer_samples(s, pcm, buffer, data_blocks);
672 else
673 write_pcm_silence(s, buffer, data_blocks);
674 if (s->midi_ports)
675 write_midi_messages(s, buffer, data_blocks);
676 425
677 s->data_block_counter = (s->data_block_counter + data_blocks) & 0xff; 426 s->data_block_counter = (s->data_block_counter + data_blocks) & 0xff;
678 427
@@ -680,8 +429,9 @@ static int handle_out_packet(struct amdtp_stream *s, unsigned int data_blocks,
680 if (queue_out_packet(s, payload_length, false) < 0) 429 if (queue_out_packet(s, payload_length, false) < 0)
681 return -EIO; 430 return -EIO;
682 431
683 if (pcm) 432 pcm = ACCESS_ONCE(s->pcm);
684 update_pcm_pointers(s, pcm, data_blocks); 433 if (pcm && pcm_frames > 0)
434 update_pcm_pointers(s, pcm, pcm_frames);
685 435
686 /* No need to return the number of handled data blocks. */ 436 /* No need to return the number of handled data blocks. */
687 return 0; 437 return 0;
@@ -689,11 +439,13 @@ static int handle_out_packet(struct amdtp_stream *s, unsigned int data_blocks,
689 439
690static int handle_in_packet(struct amdtp_stream *s, 440static int handle_in_packet(struct amdtp_stream *s,
691 unsigned int payload_quadlets, __be32 *buffer, 441 unsigned int payload_quadlets, __be32 *buffer,
692 unsigned int *data_blocks) 442 unsigned int *data_blocks, unsigned int syt)
693{ 443{
694 u32 cip_header[2]; 444 u32 cip_header[2];
445 unsigned int fmt, fdf;
695 unsigned int data_block_quadlets, data_block_counter, dbc_interval; 446 unsigned int data_block_quadlets, data_block_counter, dbc_interval;
696 struct snd_pcm_substream *pcm = NULL; 447 struct snd_pcm_substream *pcm;
448 unsigned int pcm_frames;
697 bool lost; 449 bool lost;
698 450
699 cip_header[0] = be32_to_cpu(buffer[0]); 451 cip_header[0] = be32_to_cpu(buffer[0]);
@@ -704,19 +456,30 @@ static int handle_in_packet(struct amdtp_stream *s,
704 * For convenience, also check FMT field is AM824 or not. 456 * For convenience, also check FMT field is AM824 or not.
705 */ 457 */
706 if (((cip_header[0] & CIP_EOH_MASK) == CIP_EOH) || 458 if (((cip_header[0] & CIP_EOH_MASK) == CIP_EOH) ||
707 ((cip_header[1] & CIP_EOH_MASK) != CIP_EOH) || 459 ((cip_header[1] & CIP_EOH_MASK) != CIP_EOH)) {
708 ((cip_header[1] & CIP_FMT_MASK) != CIP_FMT_AM)) {
709 dev_info_ratelimited(&s->unit->device, 460 dev_info_ratelimited(&s->unit->device,
710 "Invalid CIP header for AMDTP: %08X:%08X\n", 461 "Invalid CIP header for AMDTP: %08X:%08X\n",
711 cip_header[0], cip_header[1]); 462 cip_header[0], cip_header[1]);
712 *data_blocks = 0; 463 *data_blocks = 0;
464 pcm_frames = 0;
465 goto end;
466 }
467
468 /* Check valid protocol or not. */
469 fmt = (cip_header[1] & CIP_FMT_MASK) >> CIP_FMT_SHIFT;
470 if (fmt != s->fmt) {
471 dev_info_ratelimited(&s->unit->device,
472 "Detect unexpected protocol: %08x %08x\n",
473 cip_header[0], cip_header[1]);
474 *data_blocks = 0;
475 pcm_frames = 0;
713 goto end; 476 goto end;
714 } 477 }
715 478
716 /* Calculate data blocks */ 479 /* Calculate data blocks */
480 fdf = (cip_header[1] & CIP_FDF_MASK) >> CIP_FDF_SHIFT;
717 if (payload_quadlets < 3 || 481 if (payload_quadlets < 3 ||
718 ((cip_header[1] & CIP_FDF_MASK) == 482 (fmt == CIP_FMT_AM && fdf == AMDTP_FDF_NO_DATA)) {
719 (AMDTP_FDF_NO_DATA << CIP_FDF_SHIFT))) {
720 *data_blocks = 0; 483 *data_blocks = 0;
721 } else { 484 } else {
722 data_block_quadlets = 485 data_block_quadlets =
@@ -763,16 +526,7 @@ static int handle_in_packet(struct amdtp_stream *s,
763 return -EIO; 526 return -EIO;
764 } 527 }
765 528
766 if (*data_blocks > 0) { 529 pcm_frames = s->process_data_blocks(s, buffer + 2, *data_blocks, &syt);
767 buffer += 2;
768
769 pcm = ACCESS_ONCE(s->pcm);
770 if (pcm)
771 s->transfer_samples(s, pcm, buffer, *data_blocks);
772
773 if (s->midi_ports)
774 read_midi_messages(s, buffer, *data_blocks);
775 }
776 530
777 if (s->flags & CIP_DBC_IS_END_EVENT) 531 if (s->flags & CIP_DBC_IS_END_EVENT)
778 s->data_block_counter = data_block_counter; 532 s->data_block_counter = data_block_counter;
@@ -783,8 +537,9 @@ end:
783 if (queue_in_packet(s) < 0) 537 if (queue_in_packet(s) < 0)
784 return -EIO; 538 return -EIO;
785 539
786 if (pcm) 540 pcm = ACCESS_ONCE(s->pcm);
787 update_pcm_pointers(s, pcm, *data_blocks); 541 if (pcm && pcm_frames > 0)
542 update_pcm_pointers(s, pcm, pcm_frames);
788 543
789 return 0; 544 return 0;
790} 545}
@@ -854,15 +609,15 @@ static void in_stream_callback(struct fw_iso_context *context, u32 cycle,
854 break; 609 break;
855 } 610 }
856 611
612 syt = be32_to_cpu(buffer[1]) & CIP_SYT_MASK;
857 if (handle_in_packet(s, payload_quadlets, buffer, 613 if (handle_in_packet(s, payload_quadlets, buffer,
858 &data_blocks) < 0) { 614 &data_blocks, syt) < 0) {
859 s->packet_index = -1; 615 s->packet_index = -1;
860 break; 616 break;
861 } 617 }
862 618
863 /* Process sync slave stream */ 619 /* Process sync slave stream */
864 if (s->sync_slave && s->sync_slave->callbacked) { 620 if (s->sync_slave && s->sync_slave->callbacked) {
865 syt = be32_to_cpu(buffer[1]) & CIP_SYT_MASK;
866 if (handle_out_packet(s->sync_slave, 621 if (handle_out_packet(s->sync_slave,
867 data_blocks, syt) < 0) { 622 data_blocks, syt) < 0) {
868 s->packet_index = -1; 623 s->packet_index = -1;
diff --git a/sound/firewire/amdtp.h b/sound/firewire/amdtp-stream.h
index b2cf9e75693b..8775704a3665 100644
--- a/sound/firewire/amdtp.h
+++ b/sound/firewire/amdtp-stream.h
@@ -4,6 +4,7 @@
4#include <linux/err.h> 4#include <linux/err.h>
5#include <linux/interrupt.h> 5#include <linux/interrupt.h>
6#include <linux/mutex.h> 6#include <linux/mutex.h>
7#include <linux/sched.h>
7#include <sound/asound.h> 8#include <sound/asound.h>
8#include "packets-buffer.h" 9#include "packets-buffer.h"
9 10
@@ -80,100 +81,78 @@ enum cip_sfc {
80 CIP_SFC_COUNT 81 CIP_SFC_COUNT
81}; 82};
82 83
83#define AMDTP_IN_PCM_FORMAT_BITS SNDRV_PCM_FMTBIT_S32
84
85#define AMDTP_OUT_PCM_FORMAT_BITS (SNDRV_PCM_FMTBIT_S16 | \
86 SNDRV_PCM_FMTBIT_S32)
87
88
89/*
90 * This module supports maximum 64 PCM channels for one PCM stream
91 * This is for our convenience.
92 */
93#define AMDTP_MAX_CHANNELS_FOR_PCM 64
94
95/*
96 * AMDTP packet can include channels for MIDI conformant data.
97 * Each MIDI conformant data channel includes 8 MPX-MIDI data stream.
98 * Each MPX-MIDI data stream includes one data stream from/to MIDI ports.
99 *
100 * This module supports maximum 1 MIDI conformant data channels.
101 * Then this AMDTP packets can transfer maximum 8 MIDI data streams.
102 */
103#define AMDTP_MAX_CHANNELS_FOR_MIDI 1
104
105struct fw_unit; 84struct fw_unit;
106struct fw_iso_context; 85struct fw_iso_context;
107struct snd_pcm_substream; 86struct snd_pcm_substream;
108struct snd_pcm_runtime; 87struct snd_pcm_runtime;
109struct snd_rawmidi_substream;
110 88
111enum amdtp_stream_direction { 89enum amdtp_stream_direction {
112 AMDTP_OUT_STREAM = 0, 90 AMDTP_OUT_STREAM = 0,
113 AMDTP_IN_STREAM 91 AMDTP_IN_STREAM
114}; 92};
115 93
94struct amdtp_stream;
95typedef unsigned int (*amdtp_stream_process_data_blocks_t)(
96 struct amdtp_stream *s,
97 __be32 *buffer,
98 unsigned int data_blocks,
99 unsigned int *syt);
116struct amdtp_stream { 100struct amdtp_stream {
117 struct fw_unit *unit; 101 struct fw_unit *unit;
118 enum cip_flags flags; 102 enum cip_flags flags;
119 enum amdtp_stream_direction direction; 103 enum amdtp_stream_direction direction;
120 struct fw_iso_context *context;
121 struct mutex mutex; 104 struct mutex mutex;
122 105
123 enum cip_sfc sfc; 106 /* For packet processing. */
124 unsigned int data_block_quadlets; 107 struct fw_iso_context *context;
125 unsigned int pcm_channels;
126 unsigned int midi_ports;
127 void (*transfer_samples)(struct amdtp_stream *s,
128 struct snd_pcm_substream *pcm,
129 __be32 *buffer, unsigned int frames);
130 u8 pcm_positions[AMDTP_MAX_CHANNELS_FOR_PCM];
131 u8 midi_position;
132
133 unsigned int syt_interval;
134 unsigned int transfer_delay;
135 unsigned int source_node_id_field;
136 struct iso_packets_buffer buffer; 108 struct iso_packets_buffer buffer;
137
138 struct snd_pcm_substream *pcm;
139 struct tasklet_struct period_tasklet;
140
141 int packet_index; 109 int packet_index;
110
111 /* For CIP headers. */
112 unsigned int source_node_id_field;
113 unsigned int data_block_quadlets;
142 unsigned int data_block_counter; 114 unsigned int data_block_counter;
115 unsigned int fmt;
116 unsigned int fdf;
117 /* quirk: fixed interval of dbc between previos/current packets. */
118 unsigned int tx_dbc_interval;
119 /* quirk: indicate the value of dbc field in a first packet. */
120 unsigned int tx_first_dbc;
143 121
122 /* Internal flags. */
123 enum cip_sfc sfc;
124 unsigned int syt_interval;
125 unsigned int transfer_delay;
144 unsigned int data_block_state; 126 unsigned int data_block_state;
145
146 unsigned int last_syt_offset; 127 unsigned int last_syt_offset;
147 unsigned int syt_offset_state; 128 unsigned int syt_offset_state;
148 129
130 /* For a PCM substream processing. */
131 struct snd_pcm_substream *pcm;
132 struct tasklet_struct period_tasklet;
149 unsigned int pcm_buffer_pointer; 133 unsigned int pcm_buffer_pointer;
150 unsigned int pcm_period_pointer; 134 unsigned int pcm_period_pointer;
151 bool pointer_flush; 135 bool pointer_flush;
152 bool double_pcm_frames;
153
154 struct snd_rawmidi_substream *midi[AMDTP_MAX_CHANNELS_FOR_MIDI * 8];
155 int midi_fifo_limit;
156 int midi_fifo_used[AMDTP_MAX_CHANNELS_FOR_MIDI * 8];
157
158 /* quirk: fixed interval of dbc between previos/current packets. */
159 unsigned int tx_dbc_interval;
160 /* quirk: indicate the value of dbc field in a first packet. */
161 unsigned int tx_first_dbc;
162 136
137 /* To wait for first packet. */
163 bool callbacked; 138 bool callbacked;
164 wait_queue_head_t callback_wait; 139 wait_queue_head_t callback_wait;
165 struct amdtp_stream *sync_slave; 140 struct amdtp_stream *sync_slave;
141
142 /* For backends to process data blocks. */
143 void *protocol;
144 amdtp_stream_process_data_blocks_t process_data_blocks;
166}; 145};
167 146
168int amdtp_stream_init(struct amdtp_stream *s, struct fw_unit *unit, 147int amdtp_stream_init(struct amdtp_stream *s, struct fw_unit *unit,
169 enum amdtp_stream_direction dir, 148 enum amdtp_stream_direction dir, enum cip_flags flags,
170 enum cip_flags flags); 149 unsigned int fmt,
150 amdtp_stream_process_data_blocks_t process_data_blocks,
151 unsigned int protocol_size);
171void amdtp_stream_destroy(struct amdtp_stream *s); 152void amdtp_stream_destroy(struct amdtp_stream *s);
172 153
173void amdtp_stream_set_parameters(struct amdtp_stream *s, 154int amdtp_stream_set_parameters(struct amdtp_stream *s, unsigned int rate,
174 unsigned int rate, 155 unsigned int data_block_quadlets);
175 unsigned int pcm_channels,
176 unsigned int midi_ports);
177unsigned int amdtp_stream_get_max_payload(struct amdtp_stream *s); 156unsigned int amdtp_stream_get_max_payload(struct amdtp_stream *s);
178 157
179int amdtp_stream_start(struct amdtp_stream *s, int channel, int speed); 158int amdtp_stream_start(struct amdtp_stream *s, int channel, int speed);
@@ -182,8 +161,7 @@ void amdtp_stream_stop(struct amdtp_stream *s);
182 161
183int amdtp_stream_add_pcm_hw_constraints(struct amdtp_stream *s, 162int amdtp_stream_add_pcm_hw_constraints(struct amdtp_stream *s,
184 struct snd_pcm_runtime *runtime); 163 struct snd_pcm_runtime *runtime);
185void amdtp_stream_set_pcm_format(struct amdtp_stream *s, 164
186 snd_pcm_format_t format);
187void amdtp_stream_pcm_prepare(struct amdtp_stream *s); 165void amdtp_stream_pcm_prepare(struct amdtp_stream *s);
188unsigned long amdtp_stream_pcm_pointer(struct amdtp_stream *s); 166unsigned long amdtp_stream_pcm_pointer(struct amdtp_stream *s);
189void amdtp_stream_pcm_abort(struct amdtp_stream *s); 167void amdtp_stream_pcm_abort(struct amdtp_stream *s);
@@ -240,24 +218,6 @@ static inline void amdtp_stream_pcm_trigger(struct amdtp_stream *s,
240 ACCESS_ONCE(s->pcm) = pcm; 218 ACCESS_ONCE(s->pcm) = pcm;
241} 219}
242 220
243/**
244 * amdtp_stream_midi_trigger - start/stop playback/capture with a MIDI device
245 * @s: the AMDTP stream
246 * @port: index of MIDI port
247 * @midi: the MIDI device to be started, or %NULL to stop the current device
248 *
249 * Call this function on a running isochronous stream to enable the actual
250 * transmission of MIDI data. This function should be called from the MIDI
251 * device's .trigger callback.
252 */
253static inline void amdtp_stream_midi_trigger(struct amdtp_stream *s,
254 unsigned int port,
255 struct snd_rawmidi_substream *midi)
256{
257 if (port < s->midi_ports)
258 ACCESS_ONCE(s->midi[port]) = midi;
259}
260
261static inline bool cip_sfc_is_base_44100(enum cip_sfc sfc) 221static inline bool cip_sfc_is_base_44100(enum cip_sfc sfc)
262{ 222{
263 return sfc & 1; 223 return sfc & 1;
diff --git a/sound/firewire/bebob/Makefile b/sound/firewire/bebob/Makefile
index 6cf470c80d1f..af7ed6643266 100644
--- a/sound/firewire/bebob/Makefile
+++ b/sound/firewire/bebob/Makefile
@@ -1,4 +1,4 @@
1snd-bebob-objs := bebob_command.o bebob_stream.o bebob_proc.o bebob_midi.o \ 1snd-bebob-objs := bebob_command.o bebob_stream.o bebob_proc.o bebob_midi.o \
2 bebob_pcm.o bebob_hwdep.o bebob_terratec.o bebob_yamaha.o \ 2 bebob_pcm.o bebob_hwdep.o bebob_terratec.o bebob_yamaha.o \
3 bebob_focusrite.o bebob_maudio.o bebob.o 3 bebob_focusrite.o bebob_maudio.o bebob.o
4obj-m += snd-bebob.o 4obj-$(CONFIG_SND_BEBOB) += snd-bebob.o
diff --git a/sound/firewire/bebob/bebob.c b/sound/firewire/bebob/bebob.c
index 27a04ac8ffee..091290d1f3ea 100644
--- a/sound/firewire/bebob/bebob.c
+++ b/sound/firewire/bebob/bebob.c
@@ -41,7 +41,8 @@ static DECLARE_BITMAP(devices_used, SNDRV_CARDS);
41#define VEN_EDIROL 0x000040ab 41#define VEN_EDIROL 0x000040ab
42#define VEN_PRESONUS 0x00000a92 42#define VEN_PRESONUS 0x00000a92
43#define VEN_BRIDGECO 0x000007f5 43#define VEN_BRIDGECO 0x000007f5
44#define VEN_MACKIE 0x0000000f 44#define VEN_MACKIE1 0x0000000f
45#define VEN_MACKIE2 0x00000ff2
45#define VEN_STANTON 0x00001260 46#define VEN_STANTON 0x00001260
46#define VEN_TASCAM 0x0000022e 47#define VEN_TASCAM 0x0000022e
47#define VEN_BEHRINGER 0x00001564 48#define VEN_BEHRINGER 0x00001564
@@ -334,7 +335,7 @@ static void bebob_remove(struct fw_unit *unit)
334 snd_card_free_when_closed(bebob->card); 335 snd_card_free_when_closed(bebob->card);
335} 336}
336 337
337static struct snd_bebob_rate_spec normal_rate_spec = { 338static const struct snd_bebob_rate_spec normal_rate_spec = {
338 .get = &snd_bebob_stream_get_rate, 339 .get = &snd_bebob_stream_get_rate,
339 .set = &snd_bebob_stream_set_rate 340 .set = &snd_bebob_stream_set_rate
340}; 341};
@@ -360,9 +361,9 @@ static const struct ieee1394_device_id bebob_id_table[] = {
360 /* BridgeCo, Audio5 */ 361 /* BridgeCo, Audio5 */
361 SND_BEBOB_DEV_ENTRY(VEN_BRIDGECO, 0x00010049, &spec_normal), 362 SND_BEBOB_DEV_ENTRY(VEN_BRIDGECO, 0x00010049, &spec_normal),
362 /* Mackie, Onyx 1220/1620/1640 (Firewire I/O Card) */ 363 /* Mackie, Onyx 1220/1620/1640 (Firewire I/O Card) */
363 SND_BEBOB_DEV_ENTRY(VEN_MACKIE, 0x00010065, &spec_normal), 364 SND_BEBOB_DEV_ENTRY(VEN_MACKIE2, 0x00010065, &spec_normal),
364 /* Mackie, d.2 (Firewire Option) */ 365 /* Mackie, d.2 (Firewire Option) */
365 SND_BEBOB_DEV_ENTRY(VEN_MACKIE, 0x00010067, &spec_normal), 366 SND_BEBOB_DEV_ENTRY(VEN_MACKIE1, 0x00010067, &spec_normal),
366 /* Stanton, ScratchAmp */ 367 /* Stanton, ScratchAmp */
367 SND_BEBOB_DEV_ENTRY(VEN_STANTON, 0x00000001, &spec_normal), 368 SND_BEBOB_DEV_ENTRY(VEN_STANTON, 0x00000001, &spec_normal),
368 /* Tascam, IF-FW DM */ 369 /* Tascam, IF-FW DM */
diff --git a/sound/firewire/bebob/bebob.h b/sound/firewire/bebob/bebob.h
index d23caca7f369..4d8fcc78e747 100644
--- a/sound/firewire/bebob/bebob.h
+++ b/sound/firewire/bebob/bebob.h
@@ -31,7 +31,7 @@
31#include "../fcp.h" 31#include "../fcp.h"
32#include "../packets-buffer.h" 32#include "../packets-buffer.h"
33#include "../iso-resources.h" 33#include "../iso-resources.h"
34#include "../amdtp.h" 34#include "../amdtp-am824.h"
35#include "../cmp.h" 35#include "../cmp.h"
36 36
37/* basic register addresses on DM1000/DM1100/DM1500 */ 37/* basic register addresses on DM1000/DM1100/DM1500 */
@@ -70,9 +70,9 @@ struct snd_bebob_meter_spec {
70 int (*get)(struct snd_bebob *bebob, u32 *target, unsigned int size); 70 int (*get)(struct snd_bebob *bebob, u32 *target, unsigned int size);
71}; 71};
72struct snd_bebob_spec { 72struct snd_bebob_spec {
73 struct snd_bebob_clock_spec *clock; 73 const struct snd_bebob_clock_spec *clock;
74 struct snd_bebob_rate_spec *rate; 74 const struct snd_bebob_rate_spec *rate;
75 struct snd_bebob_meter_spec *meter; 75 const struct snd_bebob_meter_spec *meter;
76}; 76};
77 77
78struct snd_bebob { 78struct snd_bebob {
@@ -235,19 +235,19 @@ int snd_bebob_create_pcm_devices(struct snd_bebob *bebob);
235int snd_bebob_create_hwdep_device(struct snd_bebob *bebob); 235int snd_bebob_create_hwdep_device(struct snd_bebob *bebob);
236 236
237/* model specific operations */ 237/* model specific operations */
238extern struct snd_bebob_spec phase88_rack_spec; 238extern const struct snd_bebob_spec phase88_rack_spec;
239extern struct snd_bebob_spec phase24_series_spec; 239extern const struct snd_bebob_spec phase24_series_spec;
240extern struct snd_bebob_spec yamaha_go_spec; 240extern const struct snd_bebob_spec yamaha_go_spec;
241extern struct snd_bebob_spec saffirepro_26_spec; 241extern const struct snd_bebob_spec saffirepro_26_spec;
242extern struct snd_bebob_spec saffirepro_10_spec; 242extern const struct snd_bebob_spec saffirepro_10_spec;
243extern struct snd_bebob_spec saffire_le_spec; 243extern const struct snd_bebob_spec saffire_le_spec;
244extern struct snd_bebob_spec saffire_spec; 244extern const struct snd_bebob_spec saffire_spec;
245extern struct snd_bebob_spec maudio_fw410_spec; 245extern const struct snd_bebob_spec maudio_fw410_spec;
246extern struct snd_bebob_spec maudio_audiophile_spec; 246extern const struct snd_bebob_spec maudio_audiophile_spec;
247extern struct snd_bebob_spec maudio_solo_spec; 247extern const struct snd_bebob_spec maudio_solo_spec;
248extern struct snd_bebob_spec maudio_ozonic_spec; 248extern const struct snd_bebob_spec maudio_ozonic_spec;
249extern struct snd_bebob_spec maudio_nrv10_spec; 249extern const struct snd_bebob_spec maudio_nrv10_spec;
250extern struct snd_bebob_spec maudio_special_spec; 250extern const struct snd_bebob_spec maudio_special_spec;
251int snd_bebob_maudio_special_discover(struct snd_bebob *bebob, bool is1814); 251int snd_bebob_maudio_special_discover(struct snd_bebob *bebob, bool is1814);
252int snd_bebob_maudio_load_firmware(struct fw_unit *unit); 252int snd_bebob_maudio_load_firmware(struct fw_unit *unit);
253 253
diff --git a/sound/firewire/bebob/bebob_focusrite.c b/sound/firewire/bebob/bebob_focusrite.c
index a1a39494ea6c..f11090057949 100644
--- a/sound/firewire/bebob/bebob_focusrite.c
+++ b/sound/firewire/bebob/bebob_focusrite.c
@@ -200,7 +200,7 @@ end:
200 return err; 200 return err;
201} 201}
202 202
203struct snd_bebob_spec saffire_le_spec; 203const struct snd_bebob_spec saffire_le_spec;
204static enum snd_bebob_clock_type saffire_both_clk_src_types[] = { 204static enum snd_bebob_clock_type saffire_both_clk_src_types[] = {
205 SND_BEBOB_CLOCK_TYPE_INTERNAL, 205 SND_BEBOB_CLOCK_TYPE_INTERNAL,
206 SND_BEBOB_CLOCK_TYPE_EXTERNAL, 206 SND_BEBOB_CLOCK_TYPE_EXTERNAL,
@@ -229,7 +229,7 @@ static const char *const saffire_meter_labels[] = {
229static int 229static int
230saffire_meter_get(struct snd_bebob *bebob, u32 *buf, unsigned int size) 230saffire_meter_get(struct snd_bebob *bebob, u32 *buf, unsigned int size)
231{ 231{
232 struct snd_bebob_meter_spec *spec = bebob->spec->meter; 232 const struct snd_bebob_meter_spec *spec = bebob->spec->meter;
233 unsigned int channels; 233 unsigned int channels;
234 u64 offset; 234 u64 offset;
235 int err; 235 int err;
@@ -260,60 +260,60 @@ saffire_meter_get(struct snd_bebob *bebob, u32 *buf, unsigned int size)
260 return err; 260 return err;
261} 261}
262 262
263static struct snd_bebob_rate_spec saffirepro_both_rate_spec = { 263static const struct snd_bebob_rate_spec saffirepro_both_rate_spec = {
264 .get = &saffirepro_both_clk_freq_get, 264 .get = &saffirepro_both_clk_freq_get,
265 .set = &saffirepro_both_clk_freq_set, 265 .set = &saffirepro_both_clk_freq_set,
266}; 266};
267/* Saffire Pro 26 I/O */ 267/* Saffire Pro 26 I/O */
268static struct snd_bebob_clock_spec saffirepro_26_clk_spec = { 268static const struct snd_bebob_clock_spec saffirepro_26_clk_spec = {
269 .num = ARRAY_SIZE(saffirepro_26_clk_src_types), 269 .num = ARRAY_SIZE(saffirepro_26_clk_src_types),
270 .types = saffirepro_26_clk_src_types, 270 .types = saffirepro_26_clk_src_types,
271 .get = &saffirepro_both_clk_src_get, 271 .get = &saffirepro_both_clk_src_get,
272}; 272};
273struct snd_bebob_spec saffirepro_26_spec = { 273const struct snd_bebob_spec saffirepro_26_spec = {
274 .clock = &saffirepro_26_clk_spec, 274 .clock = &saffirepro_26_clk_spec,
275 .rate = &saffirepro_both_rate_spec, 275 .rate = &saffirepro_both_rate_spec,
276 .meter = NULL 276 .meter = NULL
277}; 277};
278/* Saffire Pro 10 I/O */ 278/* Saffire Pro 10 I/O */
279static struct snd_bebob_clock_spec saffirepro_10_clk_spec = { 279static const struct snd_bebob_clock_spec saffirepro_10_clk_spec = {
280 .num = ARRAY_SIZE(saffirepro_10_clk_src_types), 280 .num = ARRAY_SIZE(saffirepro_10_clk_src_types),
281 .types = saffirepro_10_clk_src_types, 281 .types = saffirepro_10_clk_src_types,
282 .get = &saffirepro_both_clk_src_get, 282 .get = &saffirepro_both_clk_src_get,
283}; 283};
284struct snd_bebob_spec saffirepro_10_spec = { 284const struct snd_bebob_spec saffirepro_10_spec = {
285 .clock = &saffirepro_10_clk_spec, 285 .clock = &saffirepro_10_clk_spec,
286 .rate = &saffirepro_both_rate_spec, 286 .rate = &saffirepro_both_rate_spec,
287 .meter = NULL 287 .meter = NULL
288}; 288};
289 289
290static struct snd_bebob_rate_spec saffire_both_rate_spec = { 290static const struct snd_bebob_rate_spec saffire_both_rate_spec = {
291 .get = &snd_bebob_stream_get_rate, 291 .get = &snd_bebob_stream_get_rate,
292 .set = &snd_bebob_stream_set_rate, 292 .set = &snd_bebob_stream_set_rate,
293}; 293};
294static struct snd_bebob_clock_spec saffire_both_clk_spec = { 294static const struct snd_bebob_clock_spec saffire_both_clk_spec = {
295 .num = ARRAY_SIZE(saffire_both_clk_src_types), 295 .num = ARRAY_SIZE(saffire_both_clk_src_types),
296 .types = saffire_both_clk_src_types, 296 .types = saffire_both_clk_src_types,
297 .get = &saffire_both_clk_src_get, 297 .get = &saffire_both_clk_src_get,
298}; 298};
299/* Saffire LE */ 299/* Saffire LE */
300static struct snd_bebob_meter_spec saffire_le_meter_spec = { 300static const struct snd_bebob_meter_spec saffire_le_meter_spec = {
301 .num = ARRAY_SIZE(saffire_le_meter_labels), 301 .num = ARRAY_SIZE(saffire_le_meter_labels),
302 .labels = saffire_le_meter_labels, 302 .labels = saffire_le_meter_labels,
303 .get = &saffire_meter_get, 303 .get = &saffire_meter_get,
304}; 304};
305struct snd_bebob_spec saffire_le_spec = { 305const struct snd_bebob_spec saffire_le_spec = {
306 .clock = &saffire_both_clk_spec, 306 .clock = &saffire_both_clk_spec,
307 .rate = &saffire_both_rate_spec, 307 .rate = &saffire_both_rate_spec,
308 .meter = &saffire_le_meter_spec 308 .meter = &saffire_le_meter_spec
309}; 309};
310/* Saffire */ 310/* Saffire */
311static struct snd_bebob_meter_spec saffire_meter_spec = { 311static const struct snd_bebob_meter_spec saffire_meter_spec = {
312 .num = ARRAY_SIZE(saffire_meter_labels), 312 .num = ARRAY_SIZE(saffire_meter_labels),
313 .labels = saffire_meter_labels, 313 .labels = saffire_meter_labels,
314 .get = &saffire_meter_get, 314 .get = &saffire_meter_get,
315}; 315};
316struct snd_bebob_spec saffire_spec = { 316const struct snd_bebob_spec saffire_spec = {
317 .clock = &saffire_both_clk_spec, 317 .clock = &saffire_both_clk_spec,
318 .rate = &saffire_both_rate_spec, 318 .rate = &saffire_both_rate_spec,
319 .meter = &saffire_meter_spec 319 .meter = &saffire_meter_spec
diff --git a/sound/firewire/bebob/bebob_maudio.c b/sound/firewire/bebob/bebob_maudio.c
index 057495d54ab0..07e5abdbceb5 100644
--- a/sound/firewire/bebob/bebob_maudio.c
+++ b/sound/firewire/bebob/bebob_maudio.c
@@ -628,7 +628,7 @@ static const char *const special_meter_labels[] = {
628static int 628static int
629special_meter_get(struct snd_bebob *bebob, u32 *target, unsigned int size) 629special_meter_get(struct snd_bebob *bebob, u32 *target, unsigned int size)
630{ 630{
631 u16 *buf; 631 __be16 *buf;
632 unsigned int i, c, channels; 632 unsigned int i, c, channels;
633 int err; 633 int err;
634 634
@@ -687,7 +687,7 @@ static const char *const nrv10_meter_labels[] = {
687static int 687static int
688normal_meter_get(struct snd_bebob *bebob, u32 *buf, unsigned int size) 688normal_meter_get(struct snd_bebob *bebob, u32 *buf, unsigned int size)
689{ 689{
690 struct snd_bebob_meter_spec *spec = bebob->spec->meter; 690 const struct snd_bebob_meter_spec *spec = bebob->spec->meter;
691 unsigned int c, channels; 691 unsigned int c, channels;
692 int err; 692 int err;
693 693
@@ -712,85 +712,85 @@ end:
712} 712}
713 713
714/* for special customized devices */ 714/* for special customized devices */
715static struct snd_bebob_rate_spec special_rate_spec = { 715static const struct snd_bebob_rate_spec special_rate_spec = {
716 .get = &special_get_rate, 716 .get = &special_get_rate,
717 .set = &special_set_rate, 717 .set = &special_set_rate,
718}; 718};
719static struct snd_bebob_clock_spec special_clk_spec = { 719static const struct snd_bebob_clock_spec special_clk_spec = {
720 .num = ARRAY_SIZE(special_clk_types), 720 .num = ARRAY_SIZE(special_clk_types),
721 .types = special_clk_types, 721 .types = special_clk_types,
722 .get = &special_clk_get, 722 .get = &special_clk_get,
723}; 723};
724static struct snd_bebob_meter_spec special_meter_spec = { 724static const struct snd_bebob_meter_spec special_meter_spec = {
725 .num = ARRAY_SIZE(special_meter_labels), 725 .num = ARRAY_SIZE(special_meter_labels),
726 .labels = special_meter_labels, 726 .labels = special_meter_labels,
727 .get = &special_meter_get 727 .get = &special_meter_get
728}; 728};
729struct snd_bebob_spec maudio_special_spec = { 729const struct snd_bebob_spec maudio_special_spec = {
730 .clock = &special_clk_spec, 730 .clock = &special_clk_spec,
731 .rate = &special_rate_spec, 731 .rate = &special_rate_spec,
732 .meter = &special_meter_spec 732 .meter = &special_meter_spec
733}; 733};
734 734
735/* Firewire 410 specification */ 735/* Firewire 410 specification */
736static struct snd_bebob_rate_spec usual_rate_spec = { 736static const struct snd_bebob_rate_spec usual_rate_spec = {
737 .get = &snd_bebob_stream_get_rate, 737 .get = &snd_bebob_stream_get_rate,
738 .set = &snd_bebob_stream_set_rate, 738 .set = &snd_bebob_stream_set_rate,
739}; 739};
740static struct snd_bebob_meter_spec fw410_meter_spec = { 740static const struct snd_bebob_meter_spec fw410_meter_spec = {
741 .num = ARRAY_SIZE(fw410_meter_labels), 741 .num = ARRAY_SIZE(fw410_meter_labels),
742 .labels = fw410_meter_labels, 742 .labels = fw410_meter_labels,
743 .get = &normal_meter_get 743 .get = &normal_meter_get
744}; 744};
745struct snd_bebob_spec maudio_fw410_spec = { 745const struct snd_bebob_spec maudio_fw410_spec = {
746 .clock = NULL, 746 .clock = NULL,
747 .rate = &usual_rate_spec, 747 .rate = &usual_rate_spec,
748 .meter = &fw410_meter_spec 748 .meter = &fw410_meter_spec
749}; 749};
750 750
751/* Firewire Audiophile specification */ 751/* Firewire Audiophile specification */
752static struct snd_bebob_meter_spec audiophile_meter_spec = { 752static const struct snd_bebob_meter_spec audiophile_meter_spec = {
753 .num = ARRAY_SIZE(audiophile_meter_labels), 753 .num = ARRAY_SIZE(audiophile_meter_labels),
754 .labels = audiophile_meter_labels, 754 .labels = audiophile_meter_labels,
755 .get = &normal_meter_get 755 .get = &normal_meter_get
756}; 756};
757struct snd_bebob_spec maudio_audiophile_spec = { 757const struct snd_bebob_spec maudio_audiophile_spec = {
758 .clock = NULL, 758 .clock = NULL,
759 .rate = &usual_rate_spec, 759 .rate = &usual_rate_spec,
760 .meter = &audiophile_meter_spec 760 .meter = &audiophile_meter_spec
761}; 761};
762 762
763/* Firewire Solo specification */ 763/* Firewire Solo specification */
764static struct snd_bebob_meter_spec solo_meter_spec = { 764static const struct snd_bebob_meter_spec solo_meter_spec = {
765 .num = ARRAY_SIZE(solo_meter_labels), 765 .num = ARRAY_SIZE(solo_meter_labels),
766 .labels = solo_meter_labels, 766 .labels = solo_meter_labels,
767 .get = &normal_meter_get 767 .get = &normal_meter_get
768}; 768};
769struct snd_bebob_spec maudio_solo_spec = { 769const struct snd_bebob_spec maudio_solo_spec = {
770 .clock = NULL, 770 .clock = NULL,
771 .rate = &usual_rate_spec, 771 .rate = &usual_rate_spec,
772 .meter = &solo_meter_spec 772 .meter = &solo_meter_spec
773}; 773};
774 774
775/* Ozonic specification */ 775/* Ozonic specification */
776static struct snd_bebob_meter_spec ozonic_meter_spec = { 776static const struct snd_bebob_meter_spec ozonic_meter_spec = {
777 .num = ARRAY_SIZE(ozonic_meter_labels), 777 .num = ARRAY_SIZE(ozonic_meter_labels),
778 .labels = ozonic_meter_labels, 778 .labels = ozonic_meter_labels,
779 .get = &normal_meter_get 779 .get = &normal_meter_get
780}; 780};
781struct snd_bebob_spec maudio_ozonic_spec = { 781const struct snd_bebob_spec maudio_ozonic_spec = {
782 .clock = NULL, 782 .clock = NULL,
783 .rate = &usual_rate_spec, 783 .rate = &usual_rate_spec,
784 .meter = &ozonic_meter_spec 784 .meter = &ozonic_meter_spec
785}; 785};
786 786
787/* NRV10 specification */ 787/* NRV10 specification */
788static struct snd_bebob_meter_spec nrv10_meter_spec = { 788static const struct snd_bebob_meter_spec nrv10_meter_spec = {
789 .num = ARRAY_SIZE(nrv10_meter_labels), 789 .num = ARRAY_SIZE(nrv10_meter_labels),
790 .labels = nrv10_meter_labels, 790 .labels = nrv10_meter_labels,
791 .get = &normal_meter_get 791 .get = &normal_meter_get
792}; 792};
793struct snd_bebob_spec maudio_nrv10_spec = { 793const struct snd_bebob_spec maudio_nrv10_spec = {
794 .clock = NULL, 794 .clock = NULL,
795 .rate = &usual_rate_spec, 795 .rate = &usual_rate_spec,
796 .meter = &nrv10_meter_spec 796 .meter = &nrv10_meter_spec
diff --git a/sound/firewire/bebob/bebob_midi.c b/sound/firewire/bebob/bebob_midi.c
index 5681143925cd..90d95be499b0 100644
--- a/sound/firewire/bebob/bebob_midi.c
+++ b/sound/firewire/bebob/bebob_midi.c
@@ -72,11 +72,11 @@ static void midi_capture_trigger(struct snd_rawmidi_substream *substrm, int up)
72 spin_lock_irqsave(&bebob->lock, flags); 72 spin_lock_irqsave(&bebob->lock, flags);
73 73
74 if (up) 74 if (up)
75 amdtp_stream_midi_trigger(&bebob->tx_stream, 75 amdtp_am824_midi_trigger(&bebob->tx_stream,
76 substrm->number, substrm); 76 substrm->number, substrm);
77 else 77 else
78 amdtp_stream_midi_trigger(&bebob->tx_stream, 78 amdtp_am824_midi_trigger(&bebob->tx_stream,
79 substrm->number, NULL); 79 substrm->number, NULL);
80 80
81 spin_unlock_irqrestore(&bebob->lock, flags); 81 spin_unlock_irqrestore(&bebob->lock, flags);
82} 82}
@@ -89,11 +89,11 @@ static void midi_playback_trigger(struct snd_rawmidi_substream *substrm, int up)
89 spin_lock_irqsave(&bebob->lock, flags); 89 spin_lock_irqsave(&bebob->lock, flags);
90 90
91 if (up) 91 if (up)
92 amdtp_stream_midi_trigger(&bebob->rx_stream, 92 amdtp_am824_midi_trigger(&bebob->rx_stream,
93 substrm->number, substrm); 93 substrm->number, substrm);
94 else 94 else
95 amdtp_stream_midi_trigger(&bebob->rx_stream, 95 amdtp_am824_midi_trigger(&bebob->rx_stream,
96 substrm->number, NULL); 96 substrm->number, NULL);
97 97
98 spin_unlock_irqrestore(&bebob->lock, flags); 98 spin_unlock_irqrestore(&bebob->lock, flags);
99} 99}
diff --git a/sound/firewire/bebob/bebob_pcm.c b/sound/firewire/bebob/bebob_pcm.c
index c0f018a61fdc..ef224d6f5c24 100644
--- a/sound/firewire/bebob/bebob_pcm.c
+++ b/sound/firewire/bebob/bebob_pcm.c
@@ -122,11 +122,11 @@ pcm_init_hw_params(struct snd_bebob *bebob,
122 SNDRV_PCM_INFO_MMAP_VALID; 122 SNDRV_PCM_INFO_MMAP_VALID;
123 123
124 if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) { 124 if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
125 runtime->hw.formats = AMDTP_IN_PCM_FORMAT_BITS; 125 runtime->hw.formats = AM824_IN_PCM_FORMAT_BITS;
126 s = &bebob->tx_stream; 126 s = &bebob->tx_stream;
127 formations = bebob->tx_stream_formations; 127 formations = bebob->tx_stream_formations;
128 } else { 128 } else {
129 runtime->hw.formats = AMDTP_OUT_PCM_FORMAT_BITS; 129 runtime->hw.formats = AM824_OUT_PCM_FORMAT_BITS;
130 s = &bebob->rx_stream; 130 s = &bebob->rx_stream;
131 formations = bebob->rx_stream_formations; 131 formations = bebob->rx_stream_formations;
132 } 132 }
@@ -146,7 +146,7 @@ pcm_init_hw_params(struct snd_bebob *bebob,
146 if (err < 0) 146 if (err < 0)
147 goto end; 147 goto end;
148 148
149 err = amdtp_stream_add_pcm_hw_constraints(s, runtime); 149 err = amdtp_am824_add_pcm_hw_constraints(s, runtime);
150end: 150end:
151 return err; 151 return err;
152} 152}
@@ -155,7 +155,7 @@ static int
155pcm_open(struct snd_pcm_substream *substream) 155pcm_open(struct snd_pcm_substream *substream)
156{ 156{
157 struct snd_bebob *bebob = substream->private_data; 157 struct snd_bebob *bebob = substream->private_data;
158 struct snd_bebob_rate_spec *spec = bebob->spec->rate; 158 const struct snd_bebob_rate_spec *spec = bebob->spec->rate;
159 unsigned int sampling_rate; 159 unsigned int sampling_rate;
160 enum snd_bebob_clock_type src; 160 enum snd_bebob_clock_type src;
161 int err; 161 int err;
@@ -220,8 +220,8 @@ pcm_capture_hw_params(struct snd_pcm_substream *substream,
220 220
221 if (substream->runtime->status->state == SNDRV_PCM_STATE_OPEN) 221 if (substream->runtime->status->state == SNDRV_PCM_STATE_OPEN)
222 atomic_inc(&bebob->substreams_counter); 222 atomic_inc(&bebob->substreams_counter);
223 amdtp_stream_set_pcm_format(&bebob->tx_stream, 223
224 params_format(hw_params)); 224 amdtp_am824_set_pcm_format(&bebob->tx_stream, params_format(hw_params));
225 225
226 return 0; 226 return 0;
227} 227}
@@ -239,8 +239,8 @@ pcm_playback_hw_params(struct snd_pcm_substream *substream,
239 239
240 if (substream->runtime->status->state == SNDRV_PCM_STATE_OPEN) 240 if (substream->runtime->status->state == SNDRV_PCM_STATE_OPEN)
241 atomic_inc(&bebob->substreams_counter); 241 atomic_inc(&bebob->substreams_counter);
242 amdtp_stream_set_pcm_format(&bebob->rx_stream, 242
243 params_format(hw_params)); 243 amdtp_am824_set_pcm_format(&bebob->rx_stream, params_format(hw_params));
244 244
245 return 0; 245 return 0;
246} 246}
diff --git a/sound/firewire/bebob/bebob_proc.c b/sound/firewire/bebob/bebob_proc.c
index 301cc6a93945..ec24f96794f5 100644
--- a/sound/firewire/bebob/bebob_proc.c
+++ b/sound/firewire/bebob/bebob_proc.c
@@ -73,7 +73,7 @@ proc_read_meters(struct snd_info_entry *entry,
73 struct snd_info_buffer *buffer) 73 struct snd_info_buffer *buffer)
74{ 74{
75 struct snd_bebob *bebob = entry->private_data; 75 struct snd_bebob *bebob = entry->private_data;
76 struct snd_bebob_meter_spec *spec = bebob->spec->meter; 76 const struct snd_bebob_meter_spec *spec = bebob->spec->meter;
77 u32 *buf; 77 u32 *buf;
78 unsigned int i, c, channels, size; 78 unsigned int i, c, channels, size;
79 79
@@ -138,8 +138,8 @@ proc_read_clock(struct snd_info_entry *entry,
138 "SYT-Match", 138 "SYT-Match",
139 }; 139 };
140 struct snd_bebob *bebob = entry->private_data; 140 struct snd_bebob *bebob = entry->private_data;
141 struct snd_bebob_rate_spec *rate_spec = bebob->spec->rate; 141 const struct snd_bebob_rate_spec *rate_spec = bebob->spec->rate;
142 struct snd_bebob_clock_spec *clk_spec = bebob->spec->clock; 142 const struct snd_bebob_clock_spec *clk_spec = bebob->spec->clock;
143 enum snd_bebob_clock_type src; 143 enum snd_bebob_clock_type src;
144 unsigned int rate; 144 unsigned int rate;
145 145
diff --git a/sound/firewire/bebob/bebob_stream.c b/sound/firewire/bebob/bebob_stream.c
index 5be5242e1ed8..926e5dcbb66a 100644
--- a/sound/firewire/bebob/bebob_stream.c
+++ b/sound/firewire/bebob/bebob_stream.c
@@ -119,7 +119,7 @@ end:
119int snd_bebob_stream_get_clock_src(struct snd_bebob *bebob, 119int snd_bebob_stream_get_clock_src(struct snd_bebob *bebob,
120 enum snd_bebob_clock_type *src) 120 enum snd_bebob_clock_type *src)
121{ 121{
122 struct snd_bebob_clock_spec *clk_spec = bebob->spec->clock; 122 const struct snd_bebob_clock_spec *clk_spec = bebob->spec->clock;
123 u8 addr[AVC_BRIDGECO_ADDR_BYTES], input[7]; 123 u8 addr[AVC_BRIDGECO_ADDR_BYTES], input[7];
124 unsigned int id; 124 unsigned int id;
125 enum avc_bridgeco_plug_type type; 125 enum avc_bridgeco_plug_type type;
@@ -338,7 +338,7 @@ map_data_channels(struct snd_bebob *bebob, struct amdtp_stream *s)
338 err = -ENOSYS; 338 err = -ENOSYS;
339 goto end; 339 goto end;
340 } 340 }
341 s->midi_position = stm_pos; 341 amdtp_am824_set_midi_position(s, stm_pos);
342 midi = stm_pos; 342 midi = stm_pos;
343 break; 343 break;
344 /* for PCM data channel */ 344 /* for PCM data channel */
@@ -354,11 +354,12 @@ map_data_channels(struct snd_bebob *bebob, struct amdtp_stream *s)
354 case 0x09: /* Digital */ 354 case 0x09: /* Digital */
355 default: 355 default:
356 location = pcm + sec_loc; 356 location = pcm + sec_loc;
357 if (location >= AMDTP_MAX_CHANNELS_FOR_PCM) { 357 if (location >= AM824_MAX_CHANNELS_FOR_PCM) {
358 err = -ENOSYS; 358 err = -ENOSYS;
359 goto end; 359 goto end;
360 } 360 }
361 s->pcm_positions[location] = stm_pos; 361 amdtp_am824_set_pcm_position(s, location,
362 stm_pos);
362 break; 363 break;
363 } 364 }
364 } 365 }
@@ -427,12 +428,19 @@ make_both_connections(struct snd_bebob *bebob, unsigned int rate)
427 index = get_formation_index(rate); 428 index = get_formation_index(rate);
428 pcm_channels = bebob->tx_stream_formations[index].pcm; 429 pcm_channels = bebob->tx_stream_formations[index].pcm;
429 midi_channels = bebob->tx_stream_formations[index].midi; 430 midi_channels = bebob->tx_stream_formations[index].midi;
430 amdtp_stream_set_parameters(&bebob->tx_stream, 431 err = amdtp_am824_set_parameters(&bebob->tx_stream, rate,
431 rate, pcm_channels, midi_channels * 8); 432 pcm_channels, midi_channels * 8,
433 false);
434 if (err < 0)
435 goto end;
436
432 pcm_channels = bebob->rx_stream_formations[index].pcm; 437 pcm_channels = bebob->rx_stream_formations[index].pcm;
433 midi_channels = bebob->rx_stream_formations[index].midi; 438 midi_channels = bebob->rx_stream_formations[index].midi;
434 amdtp_stream_set_parameters(&bebob->rx_stream, 439 err = amdtp_am824_set_parameters(&bebob->rx_stream, rate,
435 rate, pcm_channels, midi_channels * 8); 440 pcm_channels, midi_channels * 8,
441 false);
442 if (err < 0)
443 goto end;
436 444
437 /* establish connections for both streams */ 445 /* establish connections for both streams */
438 err = cmp_connection_establish(&bebob->out_conn, 446 err = cmp_connection_establish(&bebob->out_conn,
@@ -530,8 +538,8 @@ int snd_bebob_stream_init_duplex(struct snd_bebob *bebob)
530 if (err < 0) 538 if (err < 0)
531 goto end; 539 goto end;
532 540
533 err = amdtp_stream_init(&bebob->tx_stream, bebob->unit, 541 err = amdtp_am824_init(&bebob->tx_stream, bebob->unit,
534 AMDTP_IN_STREAM, CIP_BLOCKING); 542 AMDTP_IN_STREAM, CIP_BLOCKING);
535 if (err < 0) { 543 if (err < 0) {
536 amdtp_stream_destroy(&bebob->tx_stream); 544 amdtp_stream_destroy(&bebob->tx_stream);
537 destroy_both_connections(bebob); 545 destroy_both_connections(bebob);
@@ -559,8 +567,8 @@ int snd_bebob_stream_init_duplex(struct snd_bebob *bebob)
559 if (bebob->maudio_special_quirk) 567 if (bebob->maudio_special_quirk)
560 bebob->tx_stream.flags |= CIP_EMPTY_HAS_WRONG_DBC; 568 bebob->tx_stream.flags |= CIP_EMPTY_HAS_WRONG_DBC;
561 569
562 err = amdtp_stream_init(&bebob->rx_stream, bebob->unit, 570 err = amdtp_am824_init(&bebob->rx_stream, bebob->unit,
563 AMDTP_OUT_STREAM, CIP_BLOCKING); 571 AMDTP_OUT_STREAM, CIP_BLOCKING);
564 if (err < 0) { 572 if (err < 0) {
565 amdtp_stream_destroy(&bebob->tx_stream); 573 amdtp_stream_destroy(&bebob->tx_stream);
566 amdtp_stream_destroy(&bebob->rx_stream); 574 amdtp_stream_destroy(&bebob->rx_stream);
@@ -572,7 +580,7 @@ end:
572 580
573int snd_bebob_stream_start_duplex(struct snd_bebob *bebob, unsigned int rate) 581int snd_bebob_stream_start_duplex(struct snd_bebob *bebob, unsigned int rate)
574{ 582{
575 struct snd_bebob_rate_spec *rate_spec = bebob->spec->rate; 583 const struct snd_bebob_rate_spec *rate_spec = bebob->spec->rate;
576 struct amdtp_stream *master, *slave; 584 struct amdtp_stream *master, *slave;
577 enum cip_flags sync_mode; 585 enum cip_flags sync_mode;
578 unsigned int curr_rate; 586 unsigned int curr_rate;
@@ -864,8 +872,8 @@ parse_stream_formation(u8 *buf, unsigned int len,
864 } 872 }
865 } 873 }
866 874
867 if (formation[i].pcm > AMDTP_MAX_CHANNELS_FOR_PCM || 875 if (formation[i].pcm > AM824_MAX_CHANNELS_FOR_PCM ||
868 formation[i].midi > AMDTP_MAX_CHANNELS_FOR_MIDI) 876 formation[i].midi > AM824_MAX_CHANNELS_FOR_MIDI)
869 return -ENOSYS; 877 return -ENOSYS;
870 878
871 return 0; 879 return 0;
@@ -959,7 +967,7 @@ end:
959 967
960int snd_bebob_stream_discover(struct snd_bebob *bebob) 968int snd_bebob_stream_discover(struct snd_bebob *bebob)
961{ 969{
962 struct snd_bebob_clock_spec *clk_spec = bebob->spec->clock; 970 const struct snd_bebob_clock_spec *clk_spec = bebob->spec->clock;
963 u8 plugs[AVC_PLUG_INFO_BUF_BYTES], addr[AVC_BRIDGECO_ADDR_BYTES]; 971 u8 plugs[AVC_PLUG_INFO_BUF_BYTES], addr[AVC_BRIDGECO_ADDR_BYTES];
964 enum avc_bridgeco_plug_type type; 972 enum avc_bridgeco_plug_type type;
965 unsigned int i; 973 unsigned int i;
diff --git a/sound/firewire/bebob/bebob_terratec.c b/sound/firewire/bebob/bebob_terratec.c
index 9242e33d2cf1..c38358b82ada 100644
--- a/sound/firewire/bebob/bebob_terratec.c
+++ b/sound/firewire/bebob/bebob_terratec.c
@@ -55,30 +55,30 @@ phase24_series_clk_src_get(struct snd_bebob *bebob, unsigned int *id)
55 return 0; 55 return 0;
56} 56}
57 57
58static struct snd_bebob_rate_spec phase_series_rate_spec = { 58static const struct snd_bebob_rate_spec phase_series_rate_spec = {
59 .get = &snd_bebob_stream_get_rate, 59 .get = &snd_bebob_stream_get_rate,
60 .set = &snd_bebob_stream_set_rate, 60 .set = &snd_bebob_stream_set_rate,
61}; 61};
62 62
63/* PHASE 88 Rack FW */ 63/* PHASE 88 Rack FW */
64static struct snd_bebob_clock_spec phase88_rack_clk = { 64static const struct snd_bebob_clock_spec phase88_rack_clk = {
65 .num = ARRAY_SIZE(phase88_rack_clk_src_types), 65 .num = ARRAY_SIZE(phase88_rack_clk_src_types),
66 .types = phase88_rack_clk_src_types, 66 .types = phase88_rack_clk_src_types,
67 .get = &phase88_rack_clk_src_get, 67 .get = &phase88_rack_clk_src_get,
68}; 68};
69struct snd_bebob_spec phase88_rack_spec = { 69const struct snd_bebob_spec phase88_rack_spec = {
70 .clock = &phase88_rack_clk, 70 .clock = &phase88_rack_clk,
71 .rate = &phase_series_rate_spec, 71 .rate = &phase_series_rate_spec,
72 .meter = NULL 72 .meter = NULL
73}; 73};
74 74
75/* 'PHASE 24 FW' and 'PHASE X24 FW' */ 75/* 'PHASE 24 FW' and 'PHASE X24 FW' */
76static struct snd_bebob_clock_spec phase24_series_clk = { 76static const struct snd_bebob_clock_spec phase24_series_clk = {
77 .num = ARRAY_SIZE(phase24_series_clk_src_types), 77 .num = ARRAY_SIZE(phase24_series_clk_src_types),
78 .types = phase24_series_clk_src_types, 78 .types = phase24_series_clk_src_types,
79 .get = &phase24_series_clk_src_get, 79 .get = &phase24_series_clk_src_get,
80}; 80};
81struct snd_bebob_spec phase24_series_spec = { 81const struct snd_bebob_spec phase24_series_spec = {
82 .clock = &phase24_series_clk, 82 .clock = &phase24_series_clk,
83 .rate = &phase_series_rate_spec, 83 .rate = &phase_series_rate_spec,
84 .meter = NULL 84 .meter = NULL
diff --git a/sound/firewire/bebob/bebob_yamaha.c b/sound/firewire/bebob/bebob_yamaha.c
index 58101702410b..90d4404f77ce 100644
--- a/sound/firewire/bebob/bebob_yamaha.c
+++ b/sound/firewire/bebob/bebob_yamaha.c
@@ -46,16 +46,16 @@ clk_src_get(struct snd_bebob *bebob, unsigned int *id)
46 46
47 return 0; 47 return 0;
48} 48}
49static struct snd_bebob_clock_spec clock_spec = { 49static const struct snd_bebob_clock_spec clock_spec = {
50 .num = ARRAY_SIZE(clk_src_types), 50 .num = ARRAY_SIZE(clk_src_types),
51 .types = clk_src_types, 51 .types = clk_src_types,
52 .get = &clk_src_get, 52 .get = &clk_src_get,
53}; 53};
54static struct snd_bebob_rate_spec rate_spec = { 54static const struct snd_bebob_rate_spec rate_spec = {
55 .get = &snd_bebob_stream_get_rate, 55 .get = &snd_bebob_stream_get_rate,
56 .set = &snd_bebob_stream_set_rate, 56 .set = &snd_bebob_stream_set_rate,
57}; 57};
58struct snd_bebob_spec yamaha_go_spec = { 58const struct snd_bebob_spec yamaha_go_spec = {
59 .clock = &clock_spec, 59 .clock = &clock_spec,
60 .rate = &rate_spec, 60 .rate = &rate_spec,
61 .meter = NULL 61 .meter = NULL
diff --git a/sound/firewire/dice/Makefile b/sound/firewire/dice/Makefile
index 9ef228ef7baf..55b4be9b0034 100644
--- a/sound/firewire/dice/Makefile
+++ b/sound/firewire/dice/Makefile
@@ -1,3 +1,3 @@
1snd-dice-objs := dice-transaction.o dice-stream.o dice-proc.o dice-midi.o \ 1snd-dice-objs := dice-transaction.o dice-stream.o dice-proc.o dice-midi.o \
2 dice-pcm.o dice-hwdep.o dice.o 2 dice-pcm.o dice-hwdep.o dice.o
3obj-m += snd-dice.o 3obj-$(CONFIG_SND_DICE) += snd-dice.o
diff --git a/sound/firewire/dice/dice-midi.c b/sound/firewire/dice/dice-midi.c
index fe43ce791f84..151b09f240f2 100644
--- a/sound/firewire/dice/dice-midi.c
+++ b/sound/firewire/dice/dice-midi.c
@@ -52,10 +52,10 @@ static void midi_capture_trigger(struct snd_rawmidi_substream *substrm, int up)
52 spin_lock_irqsave(&dice->lock, flags); 52 spin_lock_irqsave(&dice->lock, flags);
53 53
54 if (up) 54 if (up)
55 amdtp_stream_midi_trigger(&dice->tx_stream, 55 amdtp_am824_midi_trigger(&dice->tx_stream,
56 substrm->number, substrm); 56 substrm->number, substrm);
57 else 57 else
58 amdtp_stream_midi_trigger(&dice->tx_stream, 58 amdtp_am824_midi_trigger(&dice->tx_stream,
59 substrm->number, NULL); 59 substrm->number, NULL);
60 60
61 spin_unlock_irqrestore(&dice->lock, flags); 61 spin_unlock_irqrestore(&dice->lock, flags);
@@ -69,11 +69,11 @@ static void midi_playback_trigger(struct snd_rawmidi_substream *substrm, int up)
69 spin_lock_irqsave(&dice->lock, flags); 69 spin_lock_irqsave(&dice->lock, flags);
70 70
71 if (up) 71 if (up)
72 amdtp_stream_midi_trigger(&dice->rx_stream, 72 amdtp_am824_midi_trigger(&dice->rx_stream,
73 substrm->number, substrm); 73 substrm->number, substrm);
74 else 74 else
75 amdtp_stream_midi_trigger(&dice->rx_stream, 75 amdtp_am824_midi_trigger(&dice->rx_stream,
76 substrm->number, NULL); 76 substrm->number, NULL);
77 77
78 spin_unlock_irqrestore(&dice->lock, flags); 78 spin_unlock_irqrestore(&dice->lock, flags);
79} 79}
diff --git a/sound/firewire/dice/dice-pcm.c b/sound/firewire/dice/dice-pcm.c
index 4e67b1da0fe6..9b3431999fc8 100644
--- a/sound/firewire/dice/dice-pcm.c
+++ b/sound/firewire/dice/dice-pcm.c
@@ -133,11 +133,11 @@ static int init_hw_info(struct snd_dice *dice,
133 SNDRV_PCM_INFO_BLOCK_TRANSFER; 133 SNDRV_PCM_INFO_BLOCK_TRANSFER;
134 134
135 if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) { 135 if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
136 hw->formats = AMDTP_IN_PCM_FORMAT_BITS; 136 hw->formats = AM824_IN_PCM_FORMAT_BITS;
137 stream = &dice->tx_stream; 137 stream = &dice->tx_stream;
138 pcm_channels = dice->tx_channels; 138 pcm_channels = dice->tx_channels;
139 } else { 139 } else {
140 hw->formats = AMDTP_OUT_PCM_FORMAT_BITS; 140 hw->formats = AM824_OUT_PCM_FORMAT_BITS;
141 stream = &dice->rx_stream; 141 stream = &dice->rx_stream;
142 pcm_channels = dice->rx_channels; 142 pcm_channels = dice->rx_channels;
143 } 143 }
@@ -156,7 +156,7 @@ static int init_hw_info(struct snd_dice *dice,
156 if (err < 0) 156 if (err < 0)
157 goto end; 157 goto end;
158 158
159 err = amdtp_stream_add_pcm_hw_constraints(stream, runtime); 159 err = amdtp_am824_add_pcm_hw_constraints(stream, runtime);
160end: 160end:
161 return err; 161 return err;
162} 162}
@@ -243,8 +243,7 @@ static int capture_hw_params(struct snd_pcm_substream *substream,
243 mutex_unlock(&dice->mutex); 243 mutex_unlock(&dice->mutex);
244 } 244 }
245 245
246 amdtp_stream_set_pcm_format(&dice->tx_stream, 246 amdtp_am824_set_pcm_format(&dice->tx_stream, params_format(hw_params));
247 params_format(hw_params));
248 247
249 return 0; 248 return 0;
250} 249}
@@ -265,8 +264,7 @@ static int playback_hw_params(struct snd_pcm_substream *substream,
265 mutex_unlock(&dice->mutex); 264 mutex_unlock(&dice->mutex);
266 } 265 }
267 266
268 amdtp_stream_set_pcm_format(&dice->rx_stream, 267 amdtp_am824_set_pcm_format(&dice->rx_stream, params_format(hw_params));
269 params_format(hw_params));
270 268
271 return 0; 269 return 0;
272} 270}
diff --git a/sound/firewire/dice/dice-stream.c b/sound/firewire/dice/dice-stream.c
index 07dbd01d7a6b..a6a39f7ef58d 100644
--- a/sound/firewire/dice/dice-stream.c
+++ b/sound/firewire/dice/dice-stream.c
@@ -44,16 +44,16 @@ int snd_dice_stream_get_rate_mode(struct snd_dice *dice, unsigned int rate,
44static void release_resources(struct snd_dice *dice, 44static void release_resources(struct snd_dice *dice,
45 struct fw_iso_resources *resources) 45 struct fw_iso_resources *resources)
46{ 46{
47 unsigned int channel; 47 __be32 channel;
48 48
49 /* Reset channel number */ 49 /* Reset channel number */
50 channel = cpu_to_be32((u32)-1); 50 channel = cpu_to_be32((u32)-1);
51 if (resources == &dice->tx_resources) 51 if (resources == &dice->tx_resources)
52 snd_dice_transaction_write_tx(dice, TX_ISOCHRONOUS, 52 snd_dice_transaction_write_tx(dice, TX_ISOCHRONOUS,
53 &channel, 4); 53 &channel, sizeof(channel));
54 else 54 else
55 snd_dice_transaction_write_rx(dice, RX_ISOCHRONOUS, 55 snd_dice_transaction_write_rx(dice, RX_ISOCHRONOUS,
56 &channel, 4); 56 &channel, sizeof(channel));
57 57
58 fw_iso_resources_free(resources); 58 fw_iso_resources_free(resources);
59} 59}
@@ -62,7 +62,7 @@ static int keep_resources(struct snd_dice *dice,
62 struct fw_iso_resources *resources, 62 struct fw_iso_resources *resources,
63 unsigned int max_payload_bytes) 63 unsigned int max_payload_bytes)
64{ 64{
65 unsigned int channel; 65 __be32 channel;
66 int err; 66 int err;
67 67
68 err = fw_iso_resources_allocate(resources, max_payload_bytes, 68 err = fw_iso_resources_allocate(resources, max_payload_bytes,
@@ -74,10 +74,10 @@ static int keep_resources(struct snd_dice *dice,
74 channel = cpu_to_be32(resources->channel); 74 channel = cpu_to_be32(resources->channel);
75 if (resources == &dice->tx_resources) 75 if (resources == &dice->tx_resources)
76 err = snd_dice_transaction_write_tx(dice, TX_ISOCHRONOUS, 76 err = snd_dice_transaction_write_tx(dice, TX_ISOCHRONOUS,
77 &channel, 4); 77 &channel, sizeof(channel));
78 else 78 else
79 err = snd_dice_transaction_write_rx(dice, RX_ISOCHRONOUS, 79 err = snd_dice_transaction_write_rx(dice, RX_ISOCHRONOUS,
80 &channel, 4); 80 &channel, sizeof(channel));
81 if (err < 0) 81 if (err < 0)
82 release_resources(dice, resources); 82 release_resources(dice, resources);
83end: 83end:
@@ -100,6 +100,7 @@ static int start_stream(struct snd_dice *dice, struct amdtp_stream *stream,
100{ 100{
101 struct fw_iso_resources *resources; 101 struct fw_iso_resources *resources;
102 unsigned int i, mode, pcm_chs, midi_ports; 102 unsigned int i, mode, pcm_chs, midi_ports;
103 bool double_pcm_frames;
103 int err; 104 int err;
104 105
105 err = snd_dice_stream_get_rate_mode(dice, rate, &mode); 106 err = snd_dice_stream_get_rate_mode(dice, rate, &mode);
@@ -125,21 +126,24 @@ static int start_stream(struct snd_dice *dice, struct amdtp_stream *stream,
125 * For this quirk, blocking mode is required and PCM buffer size should 126 * For this quirk, blocking mode is required and PCM buffer size should
126 * be aligned to SYT_INTERVAL. 127 * be aligned to SYT_INTERVAL.
127 */ 128 */
128 if (mode > 1) { 129 double_pcm_frames = mode > 1;
130 if (double_pcm_frames) {
129 rate /= 2; 131 rate /= 2;
130 pcm_chs *= 2; 132 pcm_chs *= 2;
131 stream->double_pcm_frames = true;
132 } else {
133 stream->double_pcm_frames = false;
134 } 133 }
135 134
136 amdtp_stream_set_parameters(stream, rate, pcm_chs, midi_ports); 135 err = amdtp_am824_set_parameters(stream, rate, pcm_chs, midi_ports,
137 if (mode > 1) { 136 double_pcm_frames);
137 if (err < 0)
138 goto end;
139
140 if (double_pcm_frames) {
138 pcm_chs /= 2; 141 pcm_chs /= 2;
139 142
140 for (i = 0; i < pcm_chs; i++) { 143 for (i = 0; i < pcm_chs; i++) {
141 stream->pcm_positions[i] = i * 2; 144 amdtp_am824_set_pcm_position(stream, i, i * 2);
142 stream->pcm_positions[i + pcm_chs] = i * 2 + 1; 145 amdtp_am824_set_pcm_position(stream, i + pcm_chs,
146 i * 2 + 1);
143 } 147 }
144 } 148 }
145 149
@@ -302,7 +306,7 @@ static int init_stream(struct snd_dice *dice, struct amdtp_stream *stream)
302 goto end; 306 goto end;
303 resources->channels_mask = 0x00000000ffffffffuLL; 307 resources->channels_mask = 0x00000000ffffffffuLL;
304 308
305 err = amdtp_stream_init(stream, dice->unit, dir, CIP_BLOCKING); 309 err = amdtp_am824_init(stream, dice->unit, dir, CIP_BLOCKING);
306 if (err < 0) { 310 if (err < 0) {
307 amdtp_stream_destroy(stream); 311 amdtp_stream_destroy(stream);
308 fw_iso_resources_destroy(resources); 312 fw_iso_resources_destroy(resources);
diff --git a/sound/firewire/dice/dice.c b/sound/firewire/dice/dice.c
index 70a111d7f428..5d99436dfcae 100644
--- a/sound/firewire/dice/dice.c
+++ b/sound/firewire/dice/dice.c
@@ -29,7 +29,8 @@ static int dice_interface_check(struct fw_unit *unit)
29 struct fw_csr_iterator it; 29 struct fw_csr_iterator it;
30 int key, val, vendor = -1, model = -1, err; 30 int key, val, vendor = -1, model = -1, err;
31 unsigned int category, i; 31 unsigned int category, i;
32 __be32 *pointers, value; 32 __be32 *pointers;
33 u32 value;
33 __be32 version; 34 __be32 version;
34 35
35 pointers = kmalloc_array(ARRAY_SIZE(min_values), sizeof(__be32), 36 pointers = kmalloc_array(ARRAY_SIZE(min_values), sizeof(__be32),
diff --git a/sound/firewire/dice/dice.h b/sound/firewire/dice/dice.h
index ecf5dc862235..101550ac1a24 100644
--- a/sound/firewire/dice/dice.h
+++ b/sound/firewire/dice/dice.h
@@ -34,7 +34,7 @@
34#include <sound/pcm_params.h> 34#include <sound/pcm_params.h>
35#include <sound/rawmidi.h> 35#include <sound/rawmidi.h>
36 36
37#include "../amdtp.h" 37#include "../amdtp-am824.h"
38#include "../iso-resources.h" 38#include "../iso-resources.h"
39#include "../lib.h" 39#include "../lib.h"
40#include "dice-interface.h" 40#include "dice-interface.h"
diff --git a/sound/firewire/digi00x/Makefile b/sound/firewire/digi00x/Makefile
new file mode 100644
index 000000000000..1123e68c8b28
--- /dev/null
+++ b/sound/firewire/digi00x/Makefile
@@ -0,0 +1,4 @@
1snd-firewire-digi00x-objs := amdtp-dot.o digi00x-stream.o digi00x-proc.o \
2 digi00x-pcm.o digi00x-hwdep.o \
3 digi00x-transaction.o digi00x-midi.o digi00x.o
4obj-$(CONFIG_SND_FIREWIRE_DIGI00X) += snd-firewire-digi00x.o
diff --git a/sound/firewire/digi00x/amdtp-dot.c b/sound/firewire/digi00x/amdtp-dot.c
new file mode 100644
index 000000000000..b02a5e8cad44
--- /dev/null
+++ b/sound/firewire/digi00x/amdtp-dot.c
@@ -0,0 +1,442 @@
1/*
2 * amdtp-dot.c - a part of driver for Digidesign Digi 002/003 family
3 *
4 * Copyright (c) 2014-2015 Takashi Sakamoto
5 * Copyright (C) 2012 Robin Gareus <robin@gareus.org>
6 * Copyright (C) 2012 Damien Zammit <damien@zamaudio.com>
7 *
8 * Licensed under the terms of the GNU General Public License, version 2.
9 */
10
11#include <sound/pcm.h>
12#include "digi00x.h"
13
14#define CIP_FMT_AM 0x10
15
16/* 'Clock-based rate control mode' is just supported. */
17#define AMDTP_FDF_AM824 0x00
18
19/*
20 * Nominally 3125 bytes/second, but the MIDI port's clock might be
21 * 1% too slow, and the bus clock 100 ppm too fast.
22 */
23#define MIDI_BYTES_PER_SECOND 3093
24
25/*
26 * Several devices look only at the first eight data blocks.
27 * In any case, this is more than enough for the MIDI data rate.
28 */
29#define MAX_MIDI_RX_BLOCKS 8
30
31/*
32 * The double-oh-three algorithm was discovered by Robin Gareus and Damien
33 * Zammit in 2012, with reverse-engineering for Digi 003 Rack.
34 */
35struct dot_state {
36 u8 carry;
37 u8 idx;
38 unsigned int off;
39};
40
41struct amdtp_dot {
42 unsigned int pcm_channels;
43 struct dot_state state;
44
45 unsigned int midi_ports;
46 /* 2 = MAX(DOT_MIDI_IN_PORTS, DOT_MIDI_OUT_PORTS) */
47 struct snd_rawmidi_substream *midi[2];
48 int midi_fifo_used[2];
49 int midi_fifo_limit;
50
51 void (*transfer_samples)(struct amdtp_stream *s,
52 struct snd_pcm_substream *pcm,
53 __be32 *buffer, unsigned int frames);
54};
55
56/*
57 * double-oh-three look up table
58 *
59 * @param idx index byte (audio-sample data) 0x00..0xff
60 * @param off channel offset shift
61 * @return salt to XOR with given data
62 */
63#define BYTE_PER_SAMPLE (4)
64#define MAGIC_DOT_BYTE (2)
65#define MAGIC_BYTE_OFF(x) (((x) * BYTE_PER_SAMPLE) + MAGIC_DOT_BYTE)
66static const u8 dot_scrt(const u8 idx, const unsigned int off)
67{
68 /*
69 * the length of the added pattern only depends on the lower nibble
70 * of the last non-zero data
71 */
72 static const u8 len[16] = {0, 1, 3, 5, 7, 9, 11, 13, 14,
73 12, 10, 8, 6, 4, 2, 0};
74
75 /*
76 * the lower nibble of the salt. Interleaved sequence.
77 * this is walked backwards according to len[]
78 */
79 static const u8 nib[15] = {0x8, 0x7, 0x9, 0x6, 0xa, 0x5, 0xb, 0x4,
80 0xc, 0x3, 0xd, 0x2, 0xe, 0x1, 0xf};
81
82 /* circular list for the salt's hi nibble. */
83 static const u8 hir[15] = {0x0, 0x6, 0xf, 0x8, 0x7, 0x5, 0x3, 0x4,
84 0xc, 0xd, 0xe, 0x1, 0x2, 0xb, 0xa};
85
86 /*
87 * start offset for upper nibble mapping.
88 * note: 9 is /special/. In the case where the high nibble == 0x9,
89 * hir[] is not used and - coincidentally - the salt's hi nibble is
90 * 0x09 regardless of the offset.
91 */
92 static const u8 hio[16] = {0, 11, 12, 6, 7, 5, 1, 4,
93 3, 0x00, 14, 13, 8, 9, 10, 2};
94
95 const u8 ln = idx & 0xf;
96 const u8 hn = (idx >> 4) & 0xf;
97 const u8 hr = (hn == 0x9) ? 0x9 : hir[(hio[hn] + off) % 15];
98
99 if (len[ln] < off)
100 return 0x00;
101
102 return ((nib[14 + off - len[ln]]) | (hr << 4));
103}
104
105static void dot_encode_step(struct dot_state *state, __be32 *const buffer)
106{
107 u8 * const data = (u8 *) buffer;
108
109 if (data[MAGIC_DOT_BYTE] != 0x00) {
110 state->off = 0;
111 state->idx = data[MAGIC_DOT_BYTE] ^ state->carry;
112 }
113 data[MAGIC_DOT_BYTE] ^= state->carry;
114 state->carry = dot_scrt(state->idx, ++(state->off));
115}
116
117int amdtp_dot_set_parameters(struct amdtp_stream *s, unsigned int rate,
118 unsigned int pcm_channels)
119{
120 struct amdtp_dot *p = s->protocol;
121 int err;
122
123 if (amdtp_stream_running(s))
124 return -EBUSY;
125
126 /*
127 * A first data channel is for MIDI conformant data channel, the rest is
128 * Multi Bit Linear Audio data channel.
129 */
130 err = amdtp_stream_set_parameters(s, rate, pcm_channels + 1);
131 if (err < 0)
132 return err;
133
134 s->fdf = AMDTP_FDF_AM824 | s->sfc;
135
136 p->pcm_channels = pcm_channels;
137
138 if (s->direction == AMDTP_IN_STREAM)
139 p->midi_ports = DOT_MIDI_IN_PORTS;
140 else
141 p->midi_ports = DOT_MIDI_OUT_PORTS;
142
143 /*
144 * We do not know the actual MIDI FIFO size of most devices. Just
145 * assume two bytes, i.e., one byte can be received over the bus while
146 * the previous one is transmitted over MIDI.
147 * (The value here is adjusted for midi_ratelimit_per_packet().)
148 */
149 p->midi_fifo_limit = rate - MIDI_BYTES_PER_SECOND * s->syt_interval + 1;
150
151 return 0;
152}
153
154static void write_pcm_s32(struct amdtp_stream *s, struct snd_pcm_substream *pcm,
155 __be32 *buffer, unsigned int frames)
156{
157 struct amdtp_dot *p = s->protocol;
158 struct snd_pcm_runtime *runtime = pcm->runtime;
159 unsigned int channels, remaining_frames, i, c;
160 const u32 *src;
161
162 channels = p->pcm_channels;
163 src = (void *)runtime->dma_area +
164 frames_to_bytes(runtime, s->pcm_buffer_pointer);
165 remaining_frames = runtime->buffer_size - s->pcm_buffer_pointer;
166
167 buffer++;
168 for (i = 0; i < frames; ++i) {
169 for (c = 0; c < channels; ++c) {
170 buffer[c] = cpu_to_be32((*src >> 8) | 0x40000000);
171 dot_encode_step(&p->state, &buffer[c]);
172 src++;
173 }
174 buffer += s->data_block_quadlets;
175 if (--remaining_frames == 0)
176 src = (void *)runtime->dma_area;
177 }
178}
179
180static void write_pcm_s16(struct amdtp_stream *s, struct snd_pcm_substream *pcm,
181 __be32 *buffer, unsigned int frames)
182{
183 struct amdtp_dot *p = s->protocol;
184 struct snd_pcm_runtime *runtime = pcm->runtime;
185 unsigned int channels, remaining_frames, i, c;
186 const u16 *src;
187
188 channels = p->pcm_channels;
189 src = (void *)runtime->dma_area +
190 frames_to_bytes(runtime, s->pcm_buffer_pointer);
191 remaining_frames = runtime->buffer_size - s->pcm_buffer_pointer;
192
193 buffer++;
194 for (i = 0; i < frames; ++i) {
195 for (c = 0; c < channels; ++c) {
196 buffer[c] = cpu_to_be32((*src << 8) | 0x40000000);
197 dot_encode_step(&p->state, &buffer[c]);
198 src++;
199 }
200 buffer += s->data_block_quadlets;
201 if (--remaining_frames == 0)
202 src = (void *)runtime->dma_area;
203 }
204}
205
206static void read_pcm_s32(struct amdtp_stream *s, struct snd_pcm_substream *pcm,
207 __be32 *buffer, unsigned int frames)
208{
209 struct amdtp_dot *p = s->protocol;
210 struct snd_pcm_runtime *runtime = pcm->runtime;
211 unsigned int channels, remaining_frames, i, c;
212 u32 *dst;
213
214 channels = p->pcm_channels;
215 dst = (void *)runtime->dma_area +
216 frames_to_bytes(runtime, s->pcm_buffer_pointer);
217 remaining_frames = runtime->buffer_size - s->pcm_buffer_pointer;
218
219 buffer++;
220 for (i = 0; i < frames; ++i) {
221 for (c = 0; c < channels; ++c) {
222 *dst = be32_to_cpu(buffer[c]) << 8;
223 dst++;
224 }
225 buffer += s->data_block_quadlets;
226 if (--remaining_frames == 0)
227 dst = (void *)runtime->dma_area;
228 }
229}
230
231static void write_pcm_silence(struct amdtp_stream *s, __be32 *buffer,
232 unsigned int data_blocks)
233{
234 struct amdtp_dot *p = s->protocol;
235 unsigned int channels, i, c;
236
237 channels = p->pcm_channels;
238
239 buffer++;
240 for (i = 0; i < data_blocks; ++i) {
241 for (c = 0; c < channels; ++c)
242 buffer[c] = cpu_to_be32(0x40000000);
243 buffer += s->data_block_quadlets;
244 }
245}
246
247static bool midi_ratelimit_per_packet(struct amdtp_stream *s, unsigned int port)
248{
249 struct amdtp_dot *p = s->protocol;
250 int used;
251
252 used = p->midi_fifo_used[port];
253 if (used == 0)
254 return true;
255
256 used -= MIDI_BYTES_PER_SECOND * s->syt_interval;
257 used = max(used, 0);
258 p->midi_fifo_used[port] = used;
259
260 return used < p->midi_fifo_limit;
261}
262
263static inline void midi_use_bytes(struct amdtp_stream *s,
264 unsigned int port, unsigned int count)
265{
266 struct amdtp_dot *p = s->protocol;
267
268 p->midi_fifo_used[port] += amdtp_rate_table[s->sfc] * count;
269}
270
271static void write_midi_messages(struct amdtp_stream *s, __be32 *buffer,
272 unsigned int data_blocks)
273{
274 struct amdtp_dot *p = s->protocol;
275 unsigned int f, port;
276 int len;
277 u8 *b;
278
279 for (f = 0; f < data_blocks; f++) {
280 port = (s->data_block_counter + f) % 8;
281 b = (u8 *)&buffer[0];
282
283 len = 0;
284 if (port < p->midi_ports &&
285 midi_ratelimit_per_packet(s, port) &&
286 p->midi[port] != NULL)
287 len = snd_rawmidi_transmit(p->midi[port], b + 1, 2);
288
289 if (len > 0) {
290 b[3] = (0x10 << port) | len;
291 midi_use_bytes(s, port, len);
292 } else {
293 b[1] = 0;
294 b[2] = 0;
295 b[3] = 0;
296 }
297 b[0] = 0x80;
298
299 buffer += s->data_block_quadlets;
300 }
301}
302
303static void read_midi_messages(struct amdtp_stream *s, __be32 *buffer,
304 unsigned int data_blocks)
305{
306 struct amdtp_dot *p = s->protocol;
307 unsigned int f, port, len;
308 u8 *b;
309
310 for (f = 0; f < data_blocks; f++) {
311 b = (u8 *)&buffer[0];
312 port = b[3] >> 4;
313 len = b[3] & 0x0f;
314
315 if (port < p->midi_ports && p->midi[port] && len > 0)
316 snd_rawmidi_receive(p->midi[port], b + 1, len);
317
318 buffer += s->data_block_quadlets;
319 }
320}
321
322int amdtp_dot_add_pcm_hw_constraints(struct amdtp_stream *s,
323 struct snd_pcm_runtime *runtime)
324{
325 int err;
326
327 /* This protocol delivers 24 bit data in 32bit data channel. */
328 err = snd_pcm_hw_constraint_msbits(runtime, 0, 32, 24);
329 if (err < 0)
330 return err;
331
332 return amdtp_stream_add_pcm_hw_constraints(s, runtime);
333}
334
335void amdtp_dot_set_pcm_format(struct amdtp_stream *s, snd_pcm_format_t format)
336{
337 struct amdtp_dot *p = s->protocol;
338
339 if (WARN_ON(amdtp_stream_pcm_running(s)))
340 return;
341
342 switch (format) {
343 default:
344 WARN_ON(1);
345 /* fall through */
346 case SNDRV_PCM_FORMAT_S16:
347 if (s->direction == AMDTP_OUT_STREAM) {
348 p->transfer_samples = write_pcm_s16;
349 break;
350 }
351 WARN_ON(1);
352 /* fall through */
353 case SNDRV_PCM_FORMAT_S32:
354 if (s->direction == AMDTP_OUT_STREAM)
355 p->transfer_samples = write_pcm_s32;
356 else
357 p->transfer_samples = read_pcm_s32;
358 break;
359 }
360}
361
362void amdtp_dot_midi_trigger(struct amdtp_stream *s, unsigned int port,
363 struct snd_rawmidi_substream *midi)
364{
365 struct amdtp_dot *p = s->protocol;
366
367 if (port < p->midi_ports)
368 ACCESS_ONCE(p->midi[port]) = midi;
369}
370
371static unsigned int process_tx_data_blocks(struct amdtp_stream *s,
372 __be32 *buffer,
373 unsigned int data_blocks,
374 unsigned int *syt)
375{
376 struct amdtp_dot *p = (struct amdtp_dot *)s->protocol;
377 struct snd_pcm_substream *pcm;
378 unsigned int pcm_frames;
379
380 pcm = ACCESS_ONCE(s->pcm);
381 if (pcm) {
382 p->transfer_samples(s, pcm, buffer, data_blocks);
383 pcm_frames = data_blocks;
384 } else {
385 pcm_frames = 0;
386 }
387
388 read_midi_messages(s, buffer, data_blocks);
389
390 return pcm_frames;
391}
392
393static unsigned int process_rx_data_blocks(struct amdtp_stream *s,
394 __be32 *buffer,
395 unsigned int data_blocks,
396 unsigned int *syt)
397{
398 struct amdtp_dot *p = (struct amdtp_dot *)s->protocol;
399 struct snd_pcm_substream *pcm;
400 unsigned int pcm_frames;
401
402 pcm = ACCESS_ONCE(s->pcm);
403 if (pcm) {
404 p->transfer_samples(s, pcm, buffer, data_blocks);
405 pcm_frames = data_blocks;
406 } else {
407 write_pcm_silence(s, buffer, data_blocks);
408 pcm_frames = 0;
409 }
410
411 write_midi_messages(s, buffer, data_blocks);
412
413 return pcm_frames;
414}
415
416int amdtp_dot_init(struct amdtp_stream *s, struct fw_unit *unit,
417 enum amdtp_stream_direction dir)
418{
419 amdtp_stream_process_data_blocks_t process_data_blocks;
420 enum cip_flags flags;
421
422 /* Use different mode between incoming/outgoing. */
423 if (dir == AMDTP_IN_STREAM) {
424 flags = CIP_NONBLOCKING | CIP_SKIP_INIT_DBC_CHECK;
425 process_data_blocks = process_tx_data_blocks;
426 } else {
427 flags = CIP_BLOCKING;
428 process_data_blocks = process_rx_data_blocks;
429 }
430
431 return amdtp_stream_init(s, unit, dir, flags, CIP_FMT_AM,
432 process_data_blocks, sizeof(struct amdtp_dot));
433}
434
435void amdtp_dot_reset(struct amdtp_stream *s)
436{
437 struct amdtp_dot *p = s->protocol;
438
439 p->state.carry = 0x00;
440 p->state.idx = 0x00;
441 p->state.off = 0;
442}
diff --git a/sound/firewire/digi00x/digi00x-hwdep.c b/sound/firewire/digi00x/digi00x-hwdep.c
new file mode 100644
index 000000000000..f188e4758fd2
--- /dev/null
+++ b/sound/firewire/digi00x/digi00x-hwdep.c
@@ -0,0 +1,200 @@
1/*
2 * digi00x-hwdep.c - a part of driver for Digidesign Digi 002/003 family
3 *
4 * Copyright (c) 2014-2015 Takashi Sakamoto
5 *
6 * Licensed under the terms of the GNU General Public License, version 2.
7 */
8
9/*
10 * This codes give three functionality.
11 *
12 * 1.get firewire node information
13 * 2.get notification about starting/stopping stream
14 * 3.lock/unlock stream
15 * 4.get asynchronous messaging
16 */
17
18#include "digi00x.h"
19
20static long hwdep_read(struct snd_hwdep *hwdep, char __user *buf, long count,
21 loff_t *offset)
22{
23 struct snd_dg00x *dg00x = hwdep->private_data;
24 DEFINE_WAIT(wait);
25 union snd_firewire_event event;
26
27 spin_lock_irq(&dg00x->lock);
28
29 while (!dg00x->dev_lock_changed && dg00x->msg == 0) {
30 prepare_to_wait(&dg00x->hwdep_wait, &wait, TASK_INTERRUPTIBLE);
31 spin_unlock_irq(&dg00x->lock);
32 schedule();
33 finish_wait(&dg00x->hwdep_wait, &wait);
34 if (signal_pending(current))
35 return -ERESTARTSYS;
36 spin_lock_irq(&dg00x->lock);
37 }
38
39 memset(&event, 0, sizeof(event));
40 if (dg00x->dev_lock_changed) {
41 event.lock_status.type = SNDRV_FIREWIRE_EVENT_LOCK_STATUS;
42 event.lock_status.status = (dg00x->dev_lock_count > 0);
43 dg00x->dev_lock_changed = false;
44
45 count = min_t(long, count, sizeof(event.lock_status));
46 } else {
47 event.digi00x_message.type =
48 SNDRV_FIREWIRE_EVENT_DIGI00X_MESSAGE;
49 event.digi00x_message.message = dg00x->msg;
50 dg00x->msg = 0;
51
52 count = min_t(long, count, sizeof(event.digi00x_message));
53 }
54
55 spin_unlock_irq(&dg00x->lock);
56
57 if (copy_to_user(buf, &event, count))
58 return -EFAULT;
59
60 return count;
61}
62
63static unsigned int hwdep_poll(struct snd_hwdep *hwdep, struct file *file,
64 poll_table *wait)
65{
66 struct snd_dg00x *dg00x = hwdep->private_data;
67 unsigned int events;
68
69 poll_wait(file, &dg00x->hwdep_wait, wait);
70
71 spin_lock_irq(&dg00x->lock);
72 if (dg00x->dev_lock_changed || dg00x->msg)
73 events = POLLIN | POLLRDNORM;
74 else
75 events = 0;
76 spin_unlock_irq(&dg00x->lock);
77
78 return events;
79}
80
81static int hwdep_get_info(struct snd_dg00x *dg00x, void __user *arg)
82{
83 struct fw_device *dev = fw_parent_device(dg00x->unit);
84 struct snd_firewire_get_info info;
85
86 memset(&info, 0, sizeof(info));
87 info.type = SNDRV_FIREWIRE_TYPE_DIGI00X;
88 info.card = dev->card->index;
89 *(__be32 *)&info.guid[0] = cpu_to_be32(dev->config_rom[3]);
90 *(__be32 *)&info.guid[4] = cpu_to_be32(dev->config_rom[4]);
91 strlcpy(info.device_name, dev_name(&dev->device),
92 sizeof(info.device_name));
93
94 if (copy_to_user(arg, &info, sizeof(info)))
95 return -EFAULT;
96
97 return 0;
98}
99
100static int hwdep_lock(struct snd_dg00x *dg00x)
101{
102 int err;
103
104 spin_lock_irq(&dg00x->lock);
105
106 if (dg00x->dev_lock_count == 0) {
107 dg00x->dev_lock_count = -1;
108 err = 0;
109 } else {
110 err = -EBUSY;
111 }
112
113 spin_unlock_irq(&dg00x->lock);
114
115 return err;
116}
117
118static int hwdep_unlock(struct snd_dg00x *dg00x)
119{
120 int err;
121
122 spin_lock_irq(&dg00x->lock);
123
124 if (dg00x->dev_lock_count == -1) {
125 dg00x->dev_lock_count = 0;
126 err = 0;
127 } else {
128 err = -EBADFD;
129 }
130
131 spin_unlock_irq(&dg00x->lock);
132
133 return err;
134}
135
136static int hwdep_release(struct snd_hwdep *hwdep, struct file *file)
137{
138 struct snd_dg00x *dg00x = hwdep->private_data;
139
140 spin_lock_irq(&dg00x->lock);
141 if (dg00x->dev_lock_count == -1)
142 dg00x->dev_lock_count = 0;
143 spin_unlock_irq(&dg00x->lock);
144
145 return 0;
146}
147
148static int hwdep_ioctl(struct snd_hwdep *hwdep, struct file *file,
149 unsigned int cmd, unsigned long arg)
150{
151 struct snd_dg00x *dg00x = hwdep->private_data;
152
153 switch (cmd) {
154 case SNDRV_FIREWIRE_IOCTL_GET_INFO:
155 return hwdep_get_info(dg00x, (void __user *)arg);
156 case SNDRV_FIREWIRE_IOCTL_LOCK:
157 return hwdep_lock(dg00x);
158 case SNDRV_FIREWIRE_IOCTL_UNLOCK:
159 return hwdep_unlock(dg00x);
160 default:
161 return -ENOIOCTLCMD;
162 }
163}
164
165#ifdef CONFIG_COMPAT
166static int hwdep_compat_ioctl(struct snd_hwdep *hwdep, struct file *file,
167 unsigned int cmd, unsigned long arg)
168{
169 return hwdep_ioctl(hwdep, file, cmd,
170 (unsigned long)compat_ptr(arg));
171}
172#else
173#define hwdep_compat_ioctl NULL
174#endif
175
176static const struct snd_hwdep_ops hwdep_ops = {
177 .read = hwdep_read,
178 .release = hwdep_release,
179 .poll = hwdep_poll,
180 .ioctl = hwdep_ioctl,
181 .ioctl_compat = hwdep_compat_ioctl,
182};
183
184int snd_dg00x_create_hwdep_device(struct snd_dg00x *dg00x)
185{
186 struct snd_hwdep *hwdep;
187 int err;
188
189 err = snd_hwdep_new(dg00x->card, "Digi00x", 0, &hwdep);
190 if (err < 0)
191 return err;
192
193 strcpy(hwdep->name, "Digi00x");
194 hwdep->iface = SNDRV_HWDEP_IFACE_FW_DIGI00X;
195 hwdep->ops = hwdep_ops;
196 hwdep->private_data = dg00x;
197 hwdep->exclusive = true;
198
199 return err;
200}
diff --git a/sound/firewire/digi00x/digi00x-midi.c b/sound/firewire/digi00x/digi00x-midi.c
new file mode 100644
index 000000000000..1a72a382b384
--- /dev/null
+++ b/sound/firewire/digi00x/digi00x-midi.c
@@ -0,0 +1,223 @@
1/*
2 * digi00x-midi.h - a part of driver for Digidesign Digi 002/003 family
3 *
4 * Copyright (c) 2014-2015 Takashi Sakamoto
5 *
6 * Licensed under the terms of the GNU General Public License, version 2.
7 */
8
9#include "digi00x.h"
10
11static int midi_phys_open(struct snd_rawmidi_substream *substream)
12{
13 struct snd_dg00x *dg00x = substream->rmidi->private_data;
14 int err;
15
16 err = snd_dg00x_stream_lock_try(dg00x);
17 if (err < 0)
18 return err;
19
20 mutex_lock(&dg00x->mutex);
21 dg00x->substreams_counter++;
22 err = snd_dg00x_stream_start_duplex(dg00x, 0);
23 mutex_unlock(&dg00x->mutex);
24 if (err < 0)
25 snd_dg00x_stream_lock_release(dg00x);
26
27 return err;
28}
29
30static int midi_phys_close(struct snd_rawmidi_substream *substream)
31{
32 struct snd_dg00x *dg00x = substream->rmidi->private_data;
33
34 mutex_lock(&dg00x->mutex);
35 dg00x->substreams_counter--;
36 snd_dg00x_stream_stop_duplex(dg00x);
37 mutex_unlock(&dg00x->mutex);
38
39 snd_dg00x_stream_lock_release(dg00x);
40 return 0;
41}
42
43static void midi_phys_capture_trigger(struct snd_rawmidi_substream *substream,
44 int up)
45{
46 struct snd_dg00x *dg00x = substream->rmidi->private_data;
47 unsigned long flags;
48
49 spin_lock_irqsave(&dg00x->lock, flags);
50
51 if (up)
52 amdtp_dot_midi_trigger(&dg00x->tx_stream, substream->number,
53 substream);
54 else
55 amdtp_dot_midi_trigger(&dg00x->tx_stream, substream->number,
56 NULL);
57
58 spin_unlock_irqrestore(&dg00x->lock, flags);
59}
60
61static void midi_phys_playback_trigger(struct snd_rawmidi_substream *substream,
62 int up)
63{
64 struct snd_dg00x *dg00x = substream->rmidi->private_data;
65 unsigned long flags;
66
67 spin_lock_irqsave(&dg00x->lock, flags);
68
69 if (up)
70 amdtp_dot_midi_trigger(&dg00x->rx_stream, substream->number,
71 substream);
72 else
73 amdtp_dot_midi_trigger(&dg00x->rx_stream, substream->number,
74 NULL);
75
76 spin_unlock_irqrestore(&dg00x->lock, flags);
77}
78
79static struct snd_rawmidi_ops midi_phys_capture_ops = {
80 .open = midi_phys_open,
81 .close = midi_phys_close,
82 .trigger = midi_phys_capture_trigger,
83};
84
85static struct snd_rawmidi_ops midi_phys_playback_ops = {
86 .open = midi_phys_open,
87 .close = midi_phys_close,
88 .trigger = midi_phys_playback_trigger,
89};
90
91static int midi_ctl_open(struct snd_rawmidi_substream *substream)
92{
93 /* Do nothing. */
94 return 0;
95}
96
97static int midi_ctl_capture_close(struct snd_rawmidi_substream *substream)
98{
99 /* Do nothing. */
100 return 0;
101}
102
103static int midi_ctl_playback_close(struct snd_rawmidi_substream *substream)
104{
105 struct snd_dg00x *dg00x = substream->rmidi->private_data;
106
107 snd_fw_async_midi_port_finish(&dg00x->out_control);
108
109 return 0;
110}
111
112static void midi_ctl_capture_trigger(struct snd_rawmidi_substream *substream,
113 int up)
114{
115 struct snd_dg00x *dg00x = substream->rmidi->private_data;
116 unsigned long flags;
117
118 spin_lock_irqsave(&dg00x->lock, flags);
119
120 if (up)
121 dg00x->in_control = substream;
122 else
123 dg00x->in_control = NULL;
124
125 spin_unlock_irqrestore(&dg00x->lock, flags);
126}
127
128static void midi_ctl_playback_trigger(struct snd_rawmidi_substream *substream,
129 int up)
130{
131 struct snd_dg00x *dg00x = substream->rmidi->private_data;
132 unsigned long flags;
133
134 spin_lock_irqsave(&dg00x->lock, flags);
135
136 if (up)
137 snd_fw_async_midi_port_run(&dg00x->out_control, substream);
138
139 spin_unlock_irqrestore(&dg00x->lock, flags);
140}
141
142static struct snd_rawmidi_ops midi_ctl_capture_ops = {
143 .open = midi_ctl_open,
144 .close = midi_ctl_capture_close,
145 .trigger = midi_ctl_capture_trigger,
146};
147
148static struct snd_rawmidi_ops midi_ctl_playback_ops = {
149 .open = midi_ctl_open,
150 .close = midi_ctl_playback_close,
151 .trigger = midi_ctl_playback_trigger,
152};
153
154static void set_midi_substream_names(struct snd_dg00x *dg00x,
155 struct snd_rawmidi_str *str,
156 bool is_ctl)
157{
158 struct snd_rawmidi_substream *subs;
159
160 list_for_each_entry(subs, &str->substreams, list) {
161 if (!is_ctl)
162 snprintf(subs->name, sizeof(subs->name),
163 "%s MIDI %d",
164 dg00x->card->shortname, subs->number + 1);
165 else
166 /* This port is for asynchronous transaction. */
167 snprintf(subs->name, sizeof(subs->name),
168 "%s control",
169 dg00x->card->shortname);
170 }
171}
172
173int snd_dg00x_create_midi_devices(struct snd_dg00x *dg00x)
174{
175 struct snd_rawmidi *rmidi[2];
176 struct snd_rawmidi_str *str;
177 unsigned int i;
178 int err;
179
180 /* Add physical midi ports. */
181 err = snd_rawmidi_new(dg00x->card, dg00x->card->driver, 0,
182 DOT_MIDI_OUT_PORTS, DOT_MIDI_IN_PORTS, &rmidi[0]);
183 if (err < 0)
184 return err;
185
186 snprintf(rmidi[0]->name, sizeof(rmidi[0]->name),
187 "%s MIDI", dg00x->card->shortname);
188
189 snd_rawmidi_set_ops(rmidi[0], SNDRV_RAWMIDI_STREAM_INPUT,
190 &midi_phys_capture_ops);
191 snd_rawmidi_set_ops(rmidi[0], SNDRV_RAWMIDI_STREAM_OUTPUT,
192 &midi_phys_playback_ops);
193
194 /* Add a pair of control midi ports. */
195 err = snd_rawmidi_new(dg00x->card, dg00x->card->driver, 1,
196 1, 1, &rmidi[1]);
197 if (err < 0)
198 return err;
199
200 snprintf(rmidi[1]->name, sizeof(rmidi[1]->name),
201 "%s control", dg00x->card->shortname);
202
203 snd_rawmidi_set_ops(rmidi[1], SNDRV_RAWMIDI_STREAM_INPUT,
204 &midi_ctl_capture_ops);
205 snd_rawmidi_set_ops(rmidi[1], SNDRV_RAWMIDI_STREAM_OUTPUT,
206 &midi_ctl_playback_ops);
207
208 for (i = 0; i < ARRAY_SIZE(rmidi); i++) {
209 rmidi[i]->private_data = dg00x;
210
211 rmidi[i]->info_flags |= SNDRV_RAWMIDI_INFO_INPUT;
212 str = &rmidi[i]->streams[SNDRV_RAWMIDI_STREAM_INPUT];
213 set_midi_substream_names(dg00x, str, i);
214
215 rmidi[i]->info_flags |= SNDRV_RAWMIDI_INFO_OUTPUT;
216 str = &rmidi[i]->streams[SNDRV_RAWMIDI_STREAM_OUTPUT];
217 set_midi_substream_names(dg00x, str, i);
218
219 rmidi[i]->info_flags |= SNDRV_RAWMIDI_INFO_DUPLEX;
220 }
221
222 return 0;
223}
diff --git a/sound/firewire/digi00x/digi00x-pcm.c b/sound/firewire/digi00x/digi00x-pcm.c
new file mode 100644
index 000000000000..cac28f70aef7
--- /dev/null
+++ b/sound/firewire/digi00x/digi00x-pcm.c
@@ -0,0 +1,373 @@
1/*
2 * digi00x-pcm.c - a part of driver for Digidesign Digi 002/003 family
3 *
4 * Copyright (c) 2014-2015 Takashi Sakamoto
5 *
6 * Licensed under the terms of the GNU General Public License, version 2.
7 */
8
9#include "digi00x.h"
10
11static int hw_rule_rate(struct snd_pcm_hw_params *params,
12 struct snd_pcm_hw_rule *rule)
13{
14 struct snd_interval *r =
15 hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE);
16 const struct snd_interval *c =
17 hw_param_interval_c(params, SNDRV_PCM_HW_PARAM_CHANNELS);
18 struct snd_interval t = {
19 .min = UINT_MAX, .max = 0, .integer = 1,
20 };
21 unsigned int i;
22
23 for (i = 0; i < SND_DG00X_RATE_COUNT; i++) {
24 if (!snd_interval_test(c,
25 snd_dg00x_stream_pcm_channels[i]))
26 continue;
27
28 t.min = min(t.min, snd_dg00x_stream_rates[i]);
29 t.max = max(t.max, snd_dg00x_stream_rates[i]);
30 }
31
32 return snd_interval_refine(r, &t);
33}
34
35static int hw_rule_channels(struct snd_pcm_hw_params *params,
36 struct snd_pcm_hw_rule *rule)
37{
38 struct snd_interval *c =
39 hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS);
40 const struct snd_interval *r =
41 hw_param_interval_c(params, SNDRV_PCM_HW_PARAM_RATE);
42 struct snd_interval t = {
43 .min = UINT_MAX, .max = 0, .integer = 1,
44 };
45 unsigned int i;
46
47 for (i = 0; i < SND_DG00X_RATE_COUNT; i++) {
48 if (!snd_interval_test(r, snd_dg00x_stream_rates[i]))
49 continue;
50
51 t.min = min(t.min, snd_dg00x_stream_pcm_channels[i]);
52 t.max = max(t.max, snd_dg00x_stream_pcm_channels[i]);
53 }
54
55 return snd_interval_refine(c, &t);
56}
57
58static int pcm_init_hw_params(struct snd_dg00x *dg00x,
59 struct snd_pcm_substream *substream)
60{
61 static const struct snd_pcm_hardware hardware = {
62 .info = SNDRV_PCM_INFO_BATCH |
63 SNDRV_PCM_INFO_BLOCK_TRANSFER |
64 SNDRV_PCM_INFO_INTERLEAVED |
65 SNDRV_PCM_INFO_JOINT_DUPLEX |
66 SNDRV_PCM_INFO_MMAP |
67 SNDRV_PCM_INFO_MMAP_VALID,
68 .rates = SNDRV_PCM_RATE_44100 |
69 SNDRV_PCM_RATE_48000 |
70 SNDRV_PCM_RATE_88200 |
71 SNDRV_PCM_RATE_96000,
72 .rate_min = 44100,
73 .rate_max = 96000,
74 .channels_min = 10,
75 .channels_max = 18,
76 .period_bytes_min = 4 * 18,
77 .period_bytes_max = 4 * 18 * 2048,
78 .buffer_bytes_max = 4 * 18 * 2048 * 2,
79 .periods_min = 2,
80 .periods_max = UINT_MAX,
81 };
82 struct amdtp_stream *s;
83 int err;
84
85 substream->runtime->hw = hardware;
86
87 if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
88 substream->runtime->hw.formats = SNDRV_PCM_FMTBIT_S32;
89 s = &dg00x->tx_stream;
90 } else {
91 substream->runtime->hw.formats = SNDRV_PCM_FMTBIT_S16 |
92 SNDRV_PCM_FMTBIT_S32;
93 s = &dg00x->rx_stream;
94 }
95
96 err = snd_pcm_hw_rule_add(substream->runtime, 0,
97 SNDRV_PCM_HW_PARAM_CHANNELS,
98 hw_rule_channels, NULL,
99 SNDRV_PCM_HW_PARAM_RATE, -1);
100 if (err < 0)
101 return err;
102
103 err = snd_pcm_hw_rule_add(substream->runtime, 0,
104 SNDRV_PCM_HW_PARAM_RATE,
105 hw_rule_rate, NULL,
106 SNDRV_PCM_HW_PARAM_CHANNELS, -1);
107 if (err < 0)
108 return err;
109
110 return amdtp_dot_add_pcm_hw_constraints(s, substream->runtime);
111}
112
113static int pcm_open(struct snd_pcm_substream *substream)
114{
115 struct snd_dg00x *dg00x = substream->private_data;
116 enum snd_dg00x_clock clock;
117 bool detect;
118 unsigned int rate;
119 int err;
120
121 err = snd_dg00x_stream_lock_try(dg00x);
122 if (err < 0)
123 goto end;
124
125 err = pcm_init_hw_params(dg00x, substream);
126 if (err < 0)
127 goto err_locked;
128
129 /* Check current clock source. */
130 err = snd_dg00x_stream_get_clock(dg00x, &clock);
131 if (err < 0)
132 goto err_locked;
133 if (clock != SND_DG00X_CLOCK_INTERNAL) {
134 err = snd_dg00x_stream_check_external_clock(dg00x, &detect);
135 if (err < 0)
136 goto err_locked;
137 if (!detect) {
138 err = -EBUSY;
139 goto err_locked;
140 }
141 }
142
143 if ((clock != SND_DG00X_CLOCK_INTERNAL) ||
144 amdtp_stream_pcm_running(&dg00x->rx_stream) ||
145 amdtp_stream_pcm_running(&dg00x->tx_stream)) {
146 err = snd_dg00x_stream_get_external_rate(dg00x, &rate);
147 if (err < 0)
148 goto err_locked;
149 substream->runtime->hw.rate_min = rate;
150 substream->runtime->hw.rate_max = rate;
151 }
152
153 snd_pcm_set_sync(substream);
154end:
155 return err;
156err_locked:
157 snd_dg00x_stream_lock_release(dg00x);
158 return err;
159}
160
161static int pcm_close(struct snd_pcm_substream *substream)
162{
163 struct snd_dg00x *dg00x = substream->private_data;
164
165 snd_dg00x_stream_lock_release(dg00x);
166
167 return 0;
168}
169
170static int pcm_capture_hw_params(struct snd_pcm_substream *substream,
171 struct snd_pcm_hw_params *hw_params)
172{
173 struct snd_dg00x *dg00x = substream->private_data;
174 int err;
175
176 err = snd_pcm_lib_alloc_vmalloc_buffer(substream,
177 params_buffer_bytes(hw_params));
178 if (err < 0)
179 return err;
180
181 if (substream->runtime->status->state == SNDRV_PCM_STATE_OPEN) {
182 mutex_lock(&dg00x->mutex);
183 dg00x->substreams_counter++;
184 mutex_unlock(&dg00x->mutex);
185 }
186
187 amdtp_dot_set_pcm_format(&dg00x->tx_stream, params_format(hw_params));
188
189 return 0;
190}
191
192static int pcm_playback_hw_params(struct snd_pcm_substream *substream,
193 struct snd_pcm_hw_params *hw_params)
194{
195 struct snd_dg00x *dg00x = substream->private_data;
196 int err;
197
198 err = snd_pcm_lib_alloc_vmalloc_buffer(substream,
199 params_buffer_bytes(hw_params));
200 if (err < 0)
201 return err;
202
203 if (substream->runtime->status->state == SNDRV_PCM_STATE_OPEN) {
204 mutex_lock(&dg00x->mutex);
205 dg00x->substreams_counter++;
206 mutex_unlock(&dg00x->mutex);
207 }
208
209 amdtp_dot_set_pcm_format(&dg00x->rx_stream, params_format(hw_params));
210
211 return 0;
212}
213
214static int pcm_capture_hw_free(struct snd_pcm_substream *substream)
215{
216 struct snd_dg00x *dg00x = substream->private_data;
217
218 mutex_lock(&dg00x->mutex);
219
220 if (substream->runtime->status->state != SNDRV_PCM_STATE_OPEN)
221 dg00x->substreams_counter--;
222
223 snd_dg00x_stream_stop_duplex(dg00x);
224
225 mutex_unlock(&dg00x->mutex);
226
227 return snd_pcm_lib_free_vmalloc_buffer(substream);
228}
229
230static int pcm_playback_hw_free(struct snd_pcm_substream *substream)
231{
232 struct snd_dg00x *dg00x = substream->private_data;
233
234 mutex_lock(&dg00x->mutex);
235
236 if (substream->runtime->status->state != SNDRV_PCM_STATE_OPEN)
237 dg00x->substreams_counter--;
238
239 snd_dg00x_stream_stop_duplex(dg00x);
240
241 mutex_unlock(&dg00x->mutex);
242
243 return snd_pcm_lib_free_vmalloc_buffer(substream);
244}
245
246static int pcm_capture_prepare(struct snd_pcm_substream *substream)
247{
248 struct snd_dg00x *dg00x = substream->private_data;
249 struct snd_pcm_runtime *runtime = substream->runtime;
250 int err;
251
252 mutex_lock(&dg00x->mutex);
253
254 err = snd_dg00x_stream_start_duplex(dg00x, runtime->rate);
255 if (err >= 0)
256 amdtp_stream_pcm_prepare(&dg00x->tx_stream);
257
258 mutex_unlock(&dg00x->mutex);
259
260 return err;
261}
262
263static int pcm_playback_prepare(struct snd_pcm_substream *substream)
264{
265 struct snd_dg00x *dg00x = substream->private_data;
266 struct snd_pcm_runtime *runtime = substream->runtime;
267 int err;
268
269 mutex_lock(&dg00x->mutex);
270
271 err = snd_dg00x_stream_start_duplex(dg00x, runtime->rate);
272 if (err >= 0) {
273 amdtp_stream_pcm_prepare(&dg00x->rx_stream);
274 amdtp_dot_reset(&dg00x->rx_stream);
275 }
276
277 mutex_unlock(&dg00x->mutex);
278
279 return err;
280}
281
282static int pcm_capture_trigger(struct snd_pcm_substream *substream, int cmd)
283{
284 struct snd_dg00x *dg00x = substream->private_data;
285
286 switch (cmd) {
287 case SNDRV_PCM_TRIGGER_START:
288 amdtp_stream_pcm_trigger(&dg00x->tx_stream, substream);
289 break;
290 case SNDRV_PCM_TRIGGER_STOP:
291 amdtp_stream_pcm_trigger(&dg00x->tx_stream, NULL);
292 break;
293 default:
294 return -EINVAL;
295 }
296
297 return 0;
298}
299
300static int pcm_playback_trigger(struct snd_pcm_substream *substream, int cmd)
301{
302 struct snd_dg00x *dg00x = substream->private_data;
303
304 switch (cmd) {
305 case SNDRV_PCM_TRIGGER_START:
306 amdtp_stream_pcm_trigger(&dg00x->rx_stream, substream);
307 break;
308 case SNDRV_PCM_TRIGGER_STOP:
309 amdtp_stream_pcm_trigger(&dg00x->rx_stream, NULL);
310 break;
311 default:
312 return -EINVAL;
313 }
314
315 return 0;
316}
317
318static snd_pcm_uframes_t pcm_capture_pointer(struct snd_pcm_substream *sbstrm)
319{
320 struct snd_dg00x *dg00x = sbstrm->private_data;
321
322 return amdtp_stream_pcm_pointer(&dg00x->tx_stream);
323}
324
325static snd_pcm_uframes_t pcm_playback_pointer(struct snd_pcm_substream *sbstrm)
326{
327 struct snd_dg00x *dg00x = sbstrm->private_data;
328
329 return amdtp_stream_pcm_pointer(&dg00x->rx_stream);
330}
331
332static struct snd_pcm_ops pcm_capture_ops = {
333 .open = pcm_open,
334 .close = pcm_close,
335 .ioctl = snd_pcm_lib_ioctl,
336 .hw_params = pcm_capture_hw_params,
337 .hw_free = pcm_capture_hw_free,
338 .prepare = pcm_capture_prepare,
339 .trigger = pcm_capture_trigger,
340 .pointer = pcm_capture_pointer,
341 .page = snd_pcm_lib_get_vmalloc_page,
342};
343
344static struct snd_pcm_ops pcm_playback_ops = {
345 .open = pcm_open,
346 .close = pcm_close,
347 .ioctl = snd_pcm_lib_ioctl,
348 .hw_params = pcm_playback_hw_params,
349 .hw_free = pcm_playback_hw_free,
350 .prepare = pcm_playback_prepare,
351 .trigger = pcm_playback_trigger,
352 .pointer = pcm_playback_pointer,
353 .page = snd_pcm_lib_get_vmalloc_page,
354 .mmap = snd_pcm_lib_mmap_vmalloc,
355};
356
357int snd_dg00x_create_pcm_devices(struct snd_dg00x *dg00x)
358{
359 struct snd_pcm *pcm;
360 int err;
361
362 err = snd_pcm_new(dg00x->card, dg00x->card->driver, 0, 1, 1, &pcm);
363 if (err < 0)
364 return err;
365
366 pcm->private_data = dg00x;
367 snprintf(pcm->name, sizeof(pcm->name),
368 "%s PCM", dg00x->card->shortname);
369 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &pcm_playback_ops);
370 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &pcm_capture_ops);
371
372 return 0;
373}
diff --git a/sound/firewire/digi00x/digi00x-proc.c b/sound/firewire/digi00x/digi00x-proc.c
new file mode 100644
index 000000000000..a1d601f31165
--- /dev/null
+++ b/sound/firewire/digi00x/digi00x-proc.c
@@ -0,0 +1,99 @@
1/*
2 * digi00x-proc.c - a part of driver for Digidesign Digi 002/003 family
3 *
4 * Copyright (c) 2014-2015 Takashi Sakamoto
5 *
6 * Licensed under the terms of the GNU General Public License, version 2.
7 */
8
9#include "digi00x.h"
10
11static int get_optical_iface_mode(struct snd_dg00x *dg00x,
12 enum snd_dg00x_optical_mode *mode)
13{
14 __be32 data;
15 int err;
16
17 err = snd_fw_transaction(dg00x->unit, TCODE_READ_QUADLET_REQUEST,
18 DG00X_ADDR_BASE + DG00X_OFFSET_OPT_IFACE_MODE,
19 &data, sizeof(data), 0);
20 if (err >= 0)
21 *mode = be32_to_cpu(data) & 0x01;
22
23 return err;
24}
25
26static void proc_read_clock(struct snd_info_entry *entry,
27 struct snd_info_buffer *buf)
28{
29 static const char *const source_name[] = {
30 [SND_DG00X_CLOCK_INTERNAL] = "internal",
31 [SND_DG00X_CLOCK_SPDIF] = "s/pdif",
32 [SND_DG00X_CLOCK_ADAT] = "adat",
33 [SND_DG00X_CLOCK_WORD] = "word clock",
34 };
35 static const char *const optical_name[] = {
36 [SND_DG00X_OPT_IFACE_MODE_ADAT] = "adat",
37 [SND_DG00X_OPT_IFACE_MODE_SPDIF] = "s/pdif",
38 };
39 struct snd_dg00x *dg00x = entry->private_data;
40 enum snd_dg00x_optical_mode mode;
41 unsigned int rate;
42 enum snd_dg00x_clock clock;
43 bool detect;
44
45 if (get_optical_iface_mode(dg00x, &mode) < 0)
46 return;
47 if (snd_dg00x_stream_get_local_rate(dg00x, &rate) < 0)
48 return;
49 if (snd_dg00x_stream_get_clock(dg00x, &clock) < 0)
50 return;
51
52 snd_iprintf(buf, "Optical mode: %s\n", optical_name[mode]);
53 snd_iprintf(buf, "Sampling Rate: %d\n", rate);
54 snd_iprintf(buf, "Clock Source: %s\n", source_name[clock]);
55
56 if (clock == SND_DG00X_CLOCK_INTERNAL)
57 return;
58
59 if (snd_dg00x_stream_check_external_clock(dg00x, &detect) < 0)
60 return;
61 snd_iprintf(buf, "External source: %s\n", detect ? "detected" : "not");
62 if (!detect)
63 return;
64
65 if (snd_dg00x_stream_get_external_rate(dg00x, &rate) >= 0)
66 snd_iprintf(buf, "External sampling rate: %d\n", rate);
67}
68
69void snd_dg00x_proc_init(struct snd_dg00x *dg00x)
70{
71 struct snd_info_entry *root, *entry;
72
73 /*
74 * All nodes are automatically removed at snd_card_disconnect(),
75 * by following to link list.
76 */
77 root = snd_info_create_card_entry(dg00x->card, "firewire",
78 dg00x->card->proc_root);
79 if (root == NULL)
80 return;
81
82 root->mode = S_IFDIR | S_IRUGO | S_IXUGO;
83 if (snd_info_register(root) < 0) {
84 snd_info_free_entry(root);
85 return;
86 }
87
88 entry = snd_info_create_card_entry(dg00x->card, "clock", root);
89 if (entry == NULL) {
90 snd_info_free_entry(root);
91 return;
92 }
93
94 snd_info_set_text_ops(entry, dg00x, proc_read_clock);
95 if (snd_info_register(entry) < 0) {
96 snd_info_free_entry(entry);
97 snd_info_free_entry(root);
98 }
99}
diff --git a/sound/firewire/digi00x/digi00x-stream.c b/sound/firewire/digi00x/digi00x-stream.c
new file mode 100644
index 000000000000..4d3b4ebbdd49
--- /dev/null
+++ b/sound/firewire/digi00x/digi00x-stream.c
@@ -0,0 +1,422 @@
1/*
2 * digi00x-stream.c - a part of driver for Digidesign Digi 002/003 family
3 *
4 * Copyright (c) 2014-2015 Takashi Sakamoto
5 *
6 * Licensed under the terms of the GNU General Public License, version 2.
7 */
8
9#include "digi00x.h"
10
11#define CALLBACK_TIMEOUT 500
12
13const unsigned int snd_dg00x_stream_rates[SND_DG00X_RATE_COUNT] = {
14 [SND_DG00X_RATE_44100] = 44100,
15 [SND_DG00X_RATE_48000] = 48000,
16 [SND_DG00X_RATE_88200] = 88200,
17 [SND_DG00X_RATE_96000] = 96000,
18};
19
20/* Multi Bit Linear Audio data channels for each sampling transfer frequency. */
21const unsigned int
22snd_dg00x_stream_pcm_channels[SND_DG00X_RATE_COUNT] = {
23 /* Analog/ADAT/SPDIF */
24 [SND_DG00X_RATE_44100] = (8 + 8 + 2),
25 [SND_DG00X_RATE_48000] = (8 + 8 + 2),
26 /* Analog/SPDIF */
27 [SND_DG00X_RATE_88200] = (8 + 2),
28 [SND_DG00X_RATE_96000] = (8 + 2),
29};
30
31int snd_dg00x_stream_get_local_rate(struct snd_dg00x *dg00x, unsigned int *rate)
32{
33 u32 data;
34 __be32 reg;
35 int err;
36
37 err = snd_fw_transaction(dg00x->unit, TCODE_READ_QUADLET_REQUEST,
38 DG00X_ADDR_BASE + DG00X_OFFSET_LOCAL_RATE,
39 &reg, sizeof(reg), 0);
40 if (err < 0)
41 return err;
42
43 data = be32_to_cpu(reg) & 0x0f;
44 if (data < ARRAY_SIZE(snd_dg00x_stream_rates))
45 *rate = snd_dg00x_stream_rates[data];
46 else
47 err = -EIO;
48
49 return err;
50}
51
52int snd_dg00x_stream_set_local_rate(struct snd_dg00x *dg00x, unsigned int rate)
53{
54 __be32 reg;
55 unsigned int i;
56
57 for (i = 0; i < ARRAY_SIZE(snd_dg00x_stream_rates); i++) {
58 if (rate == snd_dg00x_stream_rates[i])
59 break;
60 }
61 if (i == ARRAY_SIZE(snd_dg00x_stream_rates))
62 return -EINVAL;
63
64 reg = cpu_to_be32(i);
65 return snd_fw_transaction(dg00x->unit, TCODE_WRITE_QUADLET_REQUEST,
66 DG00X_ADDR_BASE + DG00X_OFFSET_LOCAL_RATE,
67 &reg, sizeof(reg), 0);
68}
69
70int snd_dg00x_stream_get_clock(struct snd_dg00x *dg00x,
71 enum snd_dg00x_clock *clock)
72{
73 __be32 reg;
74 int err;
75
76 err = snd_fw_transaction(dg00x->unit, TCODE_READ_QUADLET_REQUEST,
77 DG00X_ADDR_BASE + DG00X_OFFSET_CLOCK_SOURCE,
78 &reg, sizeof(reg), 0);
79 if (err < 0)
80 return err;
81
82 *clock = be32_to_cpu(reg) & 0x0f;
83 if (*clock >= SND_DG00X_CLOCK_COUNT)
84 err = -EIO;
85
86 return err;
87}
88
89int snd_dg00x_stream_check_external_clock(struct snd_dg00x *dg00x, bool *detect)
90{
91 __be32 reg;
92 int err;
93
94 err = snd_fw_transaction(dg00x->unit, TCODE_READ_QUADLET_REQUEST,
95 DG00X_ADDR_BASE + DG00X_OFFSET_DETECT_EXTERNAL,
96 &reg, sizeof(reg), 0);
97 if (err >= 0)
98 *detect = be32_to_cpu(reg) > 0;
99
100 return err;
101}
102
103int snd_dg00x_stream_get_external_rate(struct snd_dg00x *dg00x,
104 unsigned int *rate)
105{
106 u32 data;
107 __be32 reg;
108 int err;
109
110 err = snd_fw_transaction(dg00x->unit, TCODE_READ_QUADLET_REQUEST,
111 DG00X_ADDR_BASE + DG00X_OFFSET_EXTERNAL_RATE,
112 &reg, sizeof(reg), 0);
113 if (err < 0)
114 return err;
115
116 data = be32_to_cpu(reg) & 0x0f;
117 if (data < ARRAY_SIZE(snd_dg00x_stream_rates))
118 *rate = snd_dg00x_stream_rates[data];
119 /* This means desync. */
120 else
121 err = -EBUSY;
122
123 return err;
124}
125
126static void finish_session(struct snd_dg00x *dg00x)
127{
128 __be32 data = cpu_to_be32(0x00000003);
129
130 snd_fw_transaction(dg00x->unit, TCODE_WRITE_QUADLET_REQUEST,
131 DG00X_ADDR_BASE + DG00X_OFFSET_STREAMING_SET,
132 &data, sizeof(data), 0);
133}
134
135static int begin_session(struct snd_dg00x *dg00x)
136{
137 __be32 data;
138 u32 curr;
139 int err;
140
141 err = snd_fw_transaction(dg00x->unit, TCODE_READ_QUADLET_REQUEST,
142 DG00X_ADDR_BASE + DG00X_OFFSET_STREAMING_STATE,
143 &data, sizeof(data), 0);
144 if (err < 0)
145 goto error;
146 curr = be32_to_cpu(data);
147
148 if (curr == 0)
149 curr = 2;
150
151 curr--;
152 while (curr > 0) {
153 data = cpu_to_be32(curr);
154 err = snd_fw_transaction(dg00x->unit,
155 TCODE_WRITE_QUADLET_REQUEST,
156 DG00X_ADDR_BASE +
157 DG00X_OFFSET_STREAMING_SET,
158 &data, sizeof(data), 0);
159 if (err < 0)
160 goto error;
161
162 msleep(20);
163 curr--;
164 }
165
166 return 0;
167error:
168 finish_session(dg00x);
169 return err;
170}
171
172static void release_resources(struct snd_dg00x *dg00x)
173{
174 __be32 data = 0;
175
176 /* Unregister isochronous channels for both direction. */
177 snd_fw_transaction(dg00x->unit, TCODE_WRITE_QUADLET_REQUEST,
178 DG00X_ADDR_BASE + DG00X_OFFSET_ISOC_CHANNELS,
179 &data, sizeof(data), 0);
180
181 /* Release isochronous resources. */
182 fw_iso_resources_free(&dg00x->tx_resources);
183 fw_iso_resources_free(&dg00x->rx_resources);
184}
185
186static int keep_resources(struct snd_dg00x *dg00x, unsigned int rate)
187{
188 unsigned int i;
189 __be32 data;
190 int err;
191
192 /* Check sampling rate. */
193 for (i = 0; i < SND_DG00X_RATE_COUNT; i++) {
194 if (snd_dg00x_stream_rates[i] == rate)
195 break;
196 }
197 if (i == SND_DG00X_RATE_COUNT)
198 return -EINVAL;
199
200 /* Keep resources for out-stream. */
201 err = amdtp_dot_set_parameters(&dg00x->rx_stream, rate,
202 snd_dg00x_stream_pcm_channels[i]);
203 if (err < 0)
204 return err;
205 err = fw_iso_resources_allocate(&dg00x->rx_resources,
206 amdtp_stream_get_max_payload(&dg00x->rx_stream),
207 fw_parent_device(dg00x->unit)->max_speed);
208 if (err < 0)
209 return err;
210
211 /* Keep resources for in-stream. */
212 err = amdtp_dot_set_parameters(&dg00x->tx_stream, rate,
213 snd_dg00x_stream_pcm_channels[i]);
214 if (err < 0)
215 return err;
216 err = fw_iso_resources_allocate(&dg00x->tx_resources,
217 amdtp_stream_get_max_payload(&dg00x->tx_stream),
218 fw_parent_device(dg00x->unit)->max_speed);
219 if (err < 0)
220 goto error;
221
222 /* Register isochronous channels for both direction. */
223 data = cpu_to_be32((dg00x->tx_resources.channel << 16) |
224 dg00x->rx_resources.channel);
225 err = snd_fw_transaction(dg00x->unit, TCODE_WRITE_QUADLET_REQUEST,
226 DG00X_ADDR_BASE + DG00X_OFFSET_ISOC_CHANNELS,
227 &data, sizeof(data), 0);
228 if (err < 0)
229 goto error;
230
231 return 0;
232error:
233 release_resources(dg00x);
234 return err;
235}
236
237int snd_dg00x_stream_init_duplex(struct snd_dg00x *dg00x)
238{
239 int err;
240
241 /* For out-stream. */
242 err = fw_iso_resources_init(&dg00x->rx_resources, dg00x->unit);
243 if (err < 0)
244 goto error;
245 err = amdtp_dot_init(&dg00x->rx_stream, dg00x->unit, AMDTP_OUT_STREAM);
246 if (err < 0)
247 goto error;
248
249 /* For in-stream. */
250 err = fw_iso_resources_init(&dg00x->tx_resources, dg00x->unit);
251 if (err < 0)
252 goto error;
253 err = amdtp_dot_init(&dg00x->tx_stream, dg00x->unit, AMDTP_IN_STREAM);
254 if (err < 0)
255 goto error;
256
257 return 0;
258error:
259 snd_dg00x_stream_destroy_duplex(dg00x);
260 return err;
261}
262
263/*
264 * This function should be called before starting streams or after stopping
265 * streams.
266 */
267void snd_dg00x_stream_destroy_duplex(struct snd_dg00x *dg00x)
268{
269 amdtp_stream_destroy(&dg00x->rx_stream);
270 fw_iso_resources_destroy(&dg00x->rx_resources);
271
272 amdtp_stream_destroy(&dg00x->tx_stream);
273 fw_iso_resources_destroy(&dg00x->tx_resources);
274}
275
276int snd_dg00x_stream_start_duplex(struct snd_dg00x *dg00x, unsigned int rate)
277{
278 unsigned int curr_rate;
279 int err = 0;
280
281 if (dg00x->substreams_counter == 0)
282 goto end;
283
284 /* Check current sampling rate. */
285 err = snd_dg00x_stream_get_local_rate(dg00x, &curr_rate);
286 if (err < 0)
287 goto error;
288 if (rate == 0)
289 rate = curr_rate;
290 if (curr_rate != rate ||
291 amdtp_streaming_error(&dg00x->tx_stream) ||
292 amdtp_streaming_error(&dg00x->rx_stream)) {
293 finish_session(dg00x);
294
295 amdtp_stream_stop(&dg00x->tx_stream);
296 amdtp_stream_stop(&dg00x->rx_stream);
297 release_resources(dg00x);
298 }
299
300 /*
301 * No packets are transmitted without receiving packets, reagardless of
302 * which source of clock is used.
303 */
304 if (!amdtp_stream_running(&dg00x->rx_stream)) {
305 err = snd_dg00x_stream_set_local_rate(dg00x, rate);
306 if (err < 0)
307 goto error;
308
309 err = keep_resources(dg00x, rate);
310 if (err < 0)
311 goto error;
312
313 err = begin_session(dg00x);
314 if (err < 0)
315 goto error;
316
317 err = amdtp_stream_start(&dg00x->rx_stream,
318 dg00x->rx_resources.channel,
319 fw_parent_device(dg00x->unit)->max_speed);
320 if (err < 0)
321 goto error;
322
323 if (!amdtp_stream_wait_callback(&dg00x->rx_stream,
324 CALLBACK_TIMEOUT)) {
325 err = -ETIMEDOUT;
326 goto error;
327 }
328 }
329
330 /*
331 * The value of SYT field in transmitted packets is always 0x0000. Thus,
332 * duplex streams with timestamp synchronization cannot be built.
333 */
334 if (!amdtp_stream_running(&dg00x->tx_stream)) {
335 err = amdtp_stream_start(&dg00x->tx_stream,
336 dg00x->tx_resources.channel,
337 fw_parent_device(dg00x->unit)->max_speed);
338 if (err < 0)
339 goto error;
340
341 if (!amdtp_stream_wait_callback(&dg00x->tx_stream,
342 CALLBACK_TIMEOUT)) {
343 err = -ETIMEDOUT;
344 goto error;
345 }
346 }
347end:
348 return err;
349error:
350 finish_session(dg00x);
351
352 amdtp_stream_stop(&dg00x->tx_stream);
353 amdtp_stream_stop(&dg00x->rx_stream);
354 release_resources(dg00x);
355
356 return err;
357}
358
359void snd_dg00x_stream_stop_duplex(struct snd_dg00x *dg00x)
360{
361 if (dg00x->substreams_counter > 0)
362 return;
363
364 amdtp_stream_stop(&dg00x->tx_stream);
365 amdtp_stream_stop(&dg00x->rx_stream);
366 finish_session(dg00x);
367 release_resources(dg00x);
368
369 /*
370 * Just after finishing the session, the device may lost transmitting
371 * functionality for a short time.
372 */
373 msleep(50);
374}
375
376void snd_dg00x_stream_update_duplex(struct snd_dg00x *dg00x)
377{
378 fw_iso_resources_update(&dg00x->tx_resources);
379 fw_iso_resources_update(&dg00x->rx_resources);
380
381 amdtp_stream_update(&dg00x->tx_stream);
382 amdtp_stream_update(&dg00x->rx_stream);
383}
384
385void snd_dg00x_stream_lock_changed(struct snd_dg00x *dg00x)
386{
387 dg00x->dev_lock_changed = true;
388 wake_up(&dg00x->hwdep_wait);
389}
390
391int snd_dg00x_stream_lock_try(struct snd_dg00x *dg00x)
392{
393 int err;
394
395 spin_lock_irq(&dg00x->lock);
396
397 /* user land lock this */
398 if (dg00x->dev_lock_count < 0) {
399 err = -EBUSY;
400 goto end;
401 }
402
403 /* this is the first time */
404 if (dg00x->dev_lock_count++ == 0)
405 snd_dg00x_stream_lock_changed(dg00x);
406 err = 0;
407end:
408 spin_unlock_irq(&dg00x->lock);
409 return err;
410}
411
412void snd_dg00x_stream_lock_release(struct snd_dg00x *dg00x)
413{
414 spin_lock_irq(&dg00x->lock);
415
416 if (WARN_ON(dg00x->dev_lock_count <= 0))
417 goto end;
418 if (--dg00x->dev_lock_count == 0)
419 snd_dg00x_stream_lock_changed(dg00x);
420end:
421 spin_unlock_irq(&dg00x->lock);
422}
diff --git a/sound/firewire/digi00x/digi00x-transaction.c b/sound/firewire/digi00x/digi00x-transaction.c
new file mode 100644
index 000000000000..554324d8c602
--- /dev/null
+++ b/sound/firewire/digi00x/digi00x-transaction.c
@@ -0,0 +1,137 @@
1/*
2 * digi00x-transaction.c - a part of driver for Digidesign Digi 002/003 family
3 *
4 * Copyright (c) 2014-2015 Takashi Sakamoto
5 *
6 * Licensed under the terms of the GNU General Public License, version 2.
7 */
8
9#include <sound/asound.h>
10#include "digi00x.h"
11
12static int fill_midi_message(struct snd_rawmidi_substream *substream, u8 *buf)
13{
14 int bytes;
15
16 buf[0] = 0x80;
17 bytes = snd_rawmidi_transmit_peek(substream, buf + 1, 2);
18 if (bytes >= 0)
19 buf[3] = 0xc0 | bytes;
20
21 return bytes;
22}
23
24static void handle_midi_control(struct snd_dg00x *dg00x, __be32 *buf,
25 unsigned int length)
26{
27 struct snd_rawmidi_substream *substream;
28 unsigned int i;
29 unsigned int len;
30 u8 *b;
31
32 substream = ACCESS_ONCE(dg00x->in_control);
33 if (substream == NULL)
34 return;
35
36 length /= 4;
37
38 for (i = 0; i < length; i++) {
39 b = (u8 *)&buf[i];
40 len = b[3] & 0xf;
41 if (len > 0)
42 snd_rawmidi_receive(dg00x->in_control, b + 1, len);
43 }
44}
45
46static void handle_unknown_message(struct snd_dg00x *dg00x,
47 unsigned long long offset, __be32 *buf)
48{
49 unsigned long flags;
50
51 spin_lock_irqsave(&dg00x->lock, flags);
52 dg00x->msg = be32_to_cpu(*buf);
53 spin_unlock_irqrestore(&dg00x->lock, flags);
54
55 wake_up(&dg00x->hwdep_wait);
56}
57
58static void handle_message(struct fw_card *card, struct fw_request *request,
59 int tcode, int destination, int source,
60 int generation, unsigned long long offset,
61 void *data, size_t length, void *callback_data)
62{
63 struct snd_dg00x *dg00x = callback_data;
64 __be32 *buf = (__be32 *)data;
65
66 if (offset == dg00x->async_handler.offset)
67 handle_unknown_message(dg00x, offset, buf);
68 else if (offset == dg00x->async_handler.offset + 4)
69 handle_midi_control(dg00x, buf, length);
70
71 fw_send_response(card, request, RCODE_COMPLETE);
72}
73
74int snd_dg00x_transaction_reregister(struct snd_dg00x *dg00x)
75{
76 struct fw_device *device = fw_parent_device(dg00x->unit);
77 __be32 data[2];
78 int err;
79
80 /* Unknown. 4bytes. */
81 data[0] = cpu_to_be32((device->card->node_id << 16) |
82 (dg00x->async_handler.offset >> 32));
83 data[1] = cpu_to_be32(dg00x->async_handler.offset);
84 err = snd_fw_transaction(dg00x->unit, TCODE_WRITE_BLOCK_REQUEST,
85 DG00X_ADDR_BASE + DG00X_OFFSET_MESSAGE_ADDR,
86 &data, sizeof(data), 0);
87 if (err < 0)
88 return err;
89
90 /* Asynchronous transactions for MIDI control message. */
91 data[0] = cpu_to_be32((device->card->node_id << 16) |
92 (dg00x->async_handler.offset >> 32));
93 data[1] = cpu_to_be32(dg00x->async_handler.offset + 4);
94 return snd_fw_transaction(dg00x->unit, TCODE_WRITE_BLOCK_REQUEST,
95 DG00X_ADDR_BASE + DG00X_OFFSET_MIDI_CTL_ADDR,
96 &data, sizeof(data), 0);
97}
98
99int snd_dg00x_transaction_register(struct snd_dg00x *dg00x)
100{
101 static const struct fw_address_region resp_register_region = {
102 .start = 0xffffe0000000ull,
103 .end = 0xffffe000ffffull,
104 };
105 int err;
106
107 dg00x->async_handler.length = 12;
108 dg00x->async_handler.address_callback = handle_message;
109 dg00x->async_handler.callback_data = dg00x;
110
111 err = fw_core_add_address_handler(&dg00x->async_handler,
112 &resp_register_region);
113 if (err < 0)
114 return err;
115
116 err = snd_dg00x_transaction_reregister(dg00x);
117 if (err < 0)
118 goto error;
119
120 err = snd_fw_async_midi_port_init(&dg00x->out_control, dg00x->unit,
121 DG00X_ADDR_BASE + DG00X_OFFSET_MMC,
122 4, fill_midi_message);
123 if (err < 0)
124 goto error;
125
126 return err;
127error:
128 fw_core_remove_address_handler(&dg00x->async_handler);
129 dg00x->async_handler.address_callback = NULL;
130 return err;
131}
132
133void snd_dg00x_transaction_unregister(struct snd_dg00x *dg00x)
134{
135 snd_fw_async_midi_port_destroy(&dg00x->out_control);
136 fw_core_remove_address_handler(&dg00x->async_handler);
137}
diff --git a/sound/firewire/digi00x/digi00x.c b/sound/firewire/digi00x/digi00x.c
new file mode 100644
index 000000000000..1f33b7a1fca4
--- /dev/null
+++ b/sound/firewire/digi00x/digi00x.c
@@ -0,0 +1,170 @@
1/*
2 * digi00x.c - a part of driver for Digidesign Digi 002/003 family
3 *
4 * Copyright (c) 2014-2015 Takashi Sakamoto
5 *
6 * Licensed under the terms of the GNU General Public License, version 2.
7 */
8
9#include "digi00x.h"
10
11MODULE_DESCRIPTION("Digidesign Digi 002/003 family Driver");
12MODULE_AUTHOR("Takashi Sakamoto <o-takashi@sakamocchi.jp>");
13MODULE_LICENSE("GPL v2");
14
15#define VENDOR_DIGIDESIGN 0x00a07e
16#define MODEL_DIGI00X 0x000002
17
18static int name_card(struct snd_dg00x *dg00x)
19{
20 struct fw_device *fw_dev = fw_parent_device(dg00x->unit);
21 char name[32] = {0};
22 char *model;
23 int err;
24
25 err = fw_csr_string(dg00x->unit->directory, CSR_MODEL, name,
26 sizeof(name));
27 if (err < 0)
28 return err;
29
30 model = skip_spaces(name);
31
32 strcpy(dg00x->card->driver, "Digi00x");
33 strcpy(dg00x->card->shortname, model);
34 strcpy(dg00x->card->mixername, model);
35 snprintf(dg00x->card->longname, sizeof(dg00x->card->longname),
36 "Digidesign %s, GUID %08x%08x at %s, S%d", model,
37 fw_dev->config_rom[3], fw_dev->config_rom[4],
38 dev_name(&dg00x->unit->device), 100 << fw_dev->max_speed);
39
40 return 0;
41}
42
43static void dg00x_card_free(struct snd_card *card)
44{
45 struct snd_dg00x *dg00x = card->private_data;
46
47 snd_dg00x_stream_destroy_duplex(dg00x);
48 snd_dg00x_transaction_unregister(dg00x);
49
50 fw_unit_put(dg00x->unit);
51
52 mutex_destroy(&dg00x->mutex);
53}
54
55static int snd_dg00x_probe(struct fw_unit *unit,
56 const struct ieee1394_device_id *entry)
57{
58 struct snd_card *card;
59 struct snd_dg00x *dg00x;
60 int err;
61
62 /* create card */
63 err = snd_card_new(&unit->device, -1, NULL, THIS_MODULE,
64 sizeof(struct snd_dg00x), &card);
65 if (err < 0)
66 return err;
67 card->private_free = dg00x_card_free;
68
69 /* initialize myself */
70 dg00x = card->private_data;
71 dg00x->card = card;
72 dg00x->unit = fw_unit_get(unit);
73
74 mutex_init(&dg00x->mutex);
75 spin_lock_init(&dg00x->lock);
76 init_waitqueue_head(&dg00x->hwdep_wait);
77
78 err = name_card(dg00x);
79 if (err < 0)
80 goto error;
81
82 err = snd_dg00x_stream_init_duplex(dg00x);
83 if (err < 0)
84 goto error;
85
86 snd_dg00x_proc_init(dg00x);
87
88 err = snd_dg00x_create_pcm_devices(dg00x);
89 if (err < 0)
90 goto error;
91
92 err = snd_dg00x_create_midi_devices(dg00x);
93 if (err < 0)
94 goto error;
95
96 err = snd_dg00x_create_hwdep_device(dg00x);
97 if (err < 0)
98 goto error;
99
100 err = snd_dg00x_transaction_register(dg00x);
101 if (err < 0)
102 goto error;
103
104 err = snd_card_register(card);
105 if (err < 0)
106 goto error;
107
108 dev_set_drvdata(&unit->device, dg00x);
109
110 return err;
111error:
112 snd_card_free(card);
113 return err;
114}
115
116static void snd_dg00x_update(struct fw_unit *unit)
117{
118 struct snd_dg00x *dg00x = dev_get_drvdata(&unit->device);
119
120 snd_dg00x_transaction_reregister(dg00x);
121
122 mutex_lock(&dg00x->mutex);
123 snd_dg00x_stream_update_duplex(dg00x);
124 mutex_unlock(&dg00x->mutex);
125}
126
127static void snd_dg00x_remove(struct fw_unit *unit)
128{
129 struct snd_dg00x *dg00x = dev_get_drvdata(&unit->device);
130
131 /* No need to wait for releasing card object in this context. */
132 snd_card_free_when_closed(dg00x->card);
133}
134
135static const struct ieee1394_device_id snd_dg00x_id_table[] = {
136 /* Both of 002/003 use the same ID. */
137 {
138 .match_flags = IEEE1394_MATCH_VENDOR_ID |
139 IEEE1394_MATCH_MODEL_ID,
140 .vendor_id = VENDOR_DIGIDESIGN,
141 .model_id = MODEL_DIGI00X,
142 },
143 {}
144};
145MODULE_DEVICE_TABLE(ieee1394, snd_dg00x_id_table);
146
147static struct fw_driver dg00x_driver = {
148 .driver = {
149 .owner = THIS_MODULE,
150 .name = "snd-firewire-digi00x",
151 .bus = &fw_bus_type,
152 },
153 .probe = snd_dg00x_probe,
154 .update = snd_dg00x_update,
155 .remove = snd_dg00x_remove,
156 .id_table = snd_dg00x_id_table,
157};
158
159static int __init snd_dg00x_init(void)
160{
161 return driver_register(&dg00x_driver.driver);
162}
163
164static void __exit snd_dg00x_exit(void)
165{
166 driver_unregister(&dg00x_driver.driver);
167}
168
169module_init(snd_dg00x_init);
170module_exit(snd_dg00x_exit);
diff --git a/sound/firewire/digi00x/digi00x.h b/sound/firewire/digi00x/digi00x.h
new file mode 100644
index 000000000000..907e73993677
--- /dev/null
+++ b/sound/firewire/digi00x/digi00x.h
@@ -0,0 +1,157 @@
1/*
2 * digi00x.h - a part of driver for Digidesign Digi 002/003 family
3 *
4 * Copyright (c) 2014-2015 Takashi Sakamoto
5 *
6 * Licensed under the terms of the GNU General Public License, version 2.
7 */
8
9#ifndef SOUND_DIGI00X_H_INCLUDED
10#define SOUND_DIGI00X_H_INCLUDED
11
12#include <linux/compat.h>
13#include <linux/device.h>
14#include <linux/firewire.h>
15#include <linux/module.h>
16#include <linux/mod_devicetable.h>
17#include <linux/delay.h>
18#include <linux/slab.h>
19
20#include <sound/core.h>
21#include <sound/initval.h>
22#include <sound/info.h>
23#include <sound/pcm.h>
24#include <sound/pcm_params.h>
25#include <sound/firewire.h>
26#include <sound/hwdep.h>
27#include <sound/rawmidi.h>
28
29#include "../lib.h"
30#include "../iso-resources.h"
31#include "../amdtp-stream.h"
32
33struct snd_dg00x {
34 struct snd_card *card;
35 struct fw_unit *unit;
36
37 struct mutex mutex;
38 spinlock_t lock;
39
40 struct amdtp_stream tx_stream;
41 struct fw_iso_resources tx_resources;
42
43 struct amdtp_stream rx_stream;
44 struct fw_iso_resources rx_resources;
45
46 unsigned int substreams_counter;
47
48 /* for uapi */
49 int dev_lock_count;
50 bool dev_lock_changed;
51 wait_queue_head_t hwdep_wait;
52
53 /* For asynchronous messages. */
54 struct fw_address_handler async_handler;
55 u32 msg;
56
57 /* For asynchronous MIDI controls. */
58 struct snd_rawmidi_substream *in_control;
59 struct snd_fw_async_midi_port out_control;
60};
61
62#define DG00X_ADDR_BASE 0xffffe0000000ull
63
64#define DG00X_OFFSET_STREAMING_STATE 0x0000
65#define DG00X_OFFSET_STREAMING_SET 0x0004
66#define DG00X_OFFSET_MIDI_CTL_ADDR 0x0008
67/* For LSB of the address 0x000c */
68/* unknown 0x0010 */
69#define DG00X_OFFSET_MESSAGE_ADDR 0x0014
70/* For LSB of the address 0x0018 */
71/* unknown 0x001c */
72/* unknown 0x0020 */
73/* not used 0x0024--0x00ff */
74#define DG00X_OFFSET_ISOC_CHANNELS 0x0100
75/* unknown 0x0104 */
76/* unknown 0x0108 */
77/* unknown 0x010c */
78#define DG00X_OFFSET_LOCAL_RATE 0x0110
79#define DG00X_OFFSET_EXTERNAL_RATE 0x0114
80#define DG00X_OFFSET_CLOCK_SOURCE 0x0118
81#define DG00X_OFFSET_OPT_IFACE_MODE 0x011c
82/* unknown 0x0120 */
83/* Mixer control on/off 0x0124 */
84/* unknown 0x0128 */
85#define DG00X_OFFSET_DETECT_EXTERNAL 0x012c
86/* unknown 0x0138 */
87#define DG00X_OFFSET_MMC 0x0400
88
89enum snd_dg00x_rate {
90 SND_DG00X_RATE_44100 = 0,
91 SND_DG00X_RATE_48000,
92 SND_DG00X_RATE_88200,
93 SND_DG00X_RATE_96000,
94 SND_DG00X_RATE_COUNT,
95};
96
97enum snd_dg00x_clock {
98 SND_DG00X_CLOCK_INTERNAL = 0,
99 SND_DG00X_CLOCK_SPDIF,
100 SND_DG00X_CLOCK_ADAT,
101 SND_DG00X_CLOCK_WORD,
102 SND_DG00X_CLOCK_COUNT,
103};
104
105enum snd_dg00x_optical_mode {
106 SND_DG00X_OPT_IFACE_MODE_ADAT = 0,
107 SND_DG00X_OPT_IFACE_MODE_SPDIF,
108 SND_DG00X_OPT_IFACE_MODE_COUNT,
109};
110
111#define DOT_MIDI_IN_PORTS 1
112#define DOT_MIDI_OUT_PORTS 2
113
114int amdtp_dot_init(struct amdtp_stream *s, struct fw_unit *unit,
115 enum amdtp_stream_direction dir);
116int amdtp_dot_set_parameters(struct amdtp_stream *s, unsigned int rate,
117 unsigned int pcm_channels);
118void amdtp_dot_reset(struct amdtp_stream *s);
119int amdtp_dot_add_pcm_hw_constraints(struct amdtp_stream *s,
120 struct snd_pcm_runtime *runtime);
121void amdtp_dot_set_pcm_format(struct amdtp_stream *s, snd_pcm_format_t format);
122void amdtp_dot_midi_trigger(struct amdtp_stream *s, unsigned int port,
123 struct snd_rawmidi_substream *midi);
124
125int snd_dg00x_transaction_register(struct snd_dg00x *dg00x);
126int snd_dg00x_transaction_reregister(struct snd_dg00x *dg00x);
127void snd_dg00x_transaction_unregister(struct snd_dg00x *dg00x);
128
129extern const unsigned int snd_dg00x_stream_rates[SND_DG00X_RATE_COUNT];
130extern const unsigned int snd_dg00x_stream_pcm_channels[SND_DG00X_RATE_COUNT];
131int snd_dg00x_stream_get_external_rate(struct snd_dg00x *dg00x,
132 unsigned int *rate);
133int snd_dg00x_stream_get_local_rate(struct snd_dg00x *dg00x,
134 unsigned int *rate);
135int snd_dg00x_stream_set_local_rate(struct snd_dg00x *dg00x, unsigned int rate);
136int snd_dg00x_stream_get_clock(struct snd_dg00x *dg00x,
137 enum snd_dg00x_clock *clock);
138int snd_dg00x_stream_check_external_clock(struct snd_dg00x *dg00x,
139 bool *detect);
140int snd_dg00x_stream_init_duplex(struct snd_dg00x *dg00x);
141int snd_dg00x_stream_start_duplex(struct snd_dg00x *dg00x, unsigned int rate);
142void snd_dg00x_stream_stop_duplex(struct snd_dg00x *dg00x);
143void snd_dg00x_stream_update_duplex(struct snd_dg00x *dg00x);
144void snd_dg00x_stream_destroy_duplex(struct snd_dg00x *dg00x);
145
146void snd_dg00x_stream_lock_changed(struct snd_dg00x *dg00x);
147int snd_dg00x_stream_lock_try(struct snd_dg00x *dg00x);
148void snd_dg00x_stream_lock_release(struct snd_dg00x *dg00x);
149
150void snd_dg00x_proc_init(struct snd_dg00x *dg00x);
151
152int snd_dg00x_create_pcm_devices(struct snd_dg00x *dg00x);
153
154int snd_dg00x_create_midi_devices(struct snd_dg00x *dg00x);
155
156int snd_dg00x_create_hwdep_device(struct snd_dg00x *dg00x);
157#endif
diff --git a/sound/firewire/fcp.c b/sound/firewire/fcp.c
index 0619597e3a3f..cce19768f43d 100644
--- a/sound/firewire/fcp.c
+++ b/sound/firewire/fcp.c
@@ -17,7 +17,7 @@
17#include <linux/delay.h> 17#include <linux/delay.h>
18#include "fcp.h" 18#include "fcp.h"
19#include "lib.h" 19#include "lib.h"
20#include "amdtp.h" 20#include "amdtp-stream.h"
21 21
22#define CTS_AVC 0x00 22#define CTS_AVC 0x00
23 23
diff --git a/sound/firewire/fireworks/Makefile b/sound/firewire/fireworks/Makefile
index 0c7440826db8..15ef7f75a8ef 100644
--- a/sound/firewire/fireworks/Makefile
+++ b/sound/firewire/fireworks/Makefile
@@ -1,4 +1,4 @@
1snd-fireworks-objs := fireworks_transaction.o fireworks_command.o \ 1snd-fireworks-objs := fireworks_transaction.o fireworks_command.o \
2 fireworks_stream.o fireworks_proc.o fireworks_midi.o \ 2 fireworks_stream.o fireworks_proc.o fireworks_midi.o \
3 fireworks_pcm.o fireworks_hwdep.o fireworks.o 3 fireworks_pcm.o fireworks_hwdep.o fireworks.o
4obj-m += snd-fireworks.o 4obj-$(CONFIG_SND_FIREWORKS) += snd-fireworks.o
diff --git a/sound/firewire/fireworks/fireworks.c b/sound/firewire/fireworks/fireworks.c
index c94a432f7cc6..d5b19bc11e59 100644
--- a/sound/firewire/fireworks/fireworks.c
+++ b/sound/firewire/fireworks/fireworks.c
@@ -138,12 +138,12 @@ get_hardware_info(struct snd_efw *efw)
138 efw->midi_out_ports = hwinfo->midi_out_ports; 138 efw->midi_out_ports = hwinfo->midi_out_ports;
139 efw->midi_in_ports = hwinfo->midi_in_ports; 139 efw->midi_in_ports = hwinfo->midi_in_ports;
140 140
141 if (hwinfo->amdtp_tx_pcm_channels > AMDTP_MAX_CHANNELS_FOR_PCM || 141 if (hwinfo->amdtp_tx_pcm_channels > AM824_MAX_CHANNELS_FOR_PCM ||
142 hwinfo->amdtp_tx_pcm_channels_2x > AMDTP_MAX_CHANNELS_FOR_PCM || 142 hwinfo->amdtp_tx_pcm_channels_2x > AM824_MAX_CHANNELS_FOR_PCM ||
143 hwinfo->amdtp_tx_pcm_channels_4x > AMDTP_MAX_CHANNELS_FOR_PCM || 143 hwinfo->amdtp_tx_pcm_channels_4x > AM824_MAX_CHANNELS_FOR_PCM ||
144 hwinfo->amdtp_rx_pcm_channels > AMDTP_MAX_CHANNELS_FOR_PCM || 144 hwinfo->amdtp_rx_pcm_channels > AM824_MAX_CHANNELS_FOR_PCM ||
145 hwinfo->amdtp_rx_pcm_channels_2x > AMDTP_MAX_CHANNELS_FOR_PCM || 145 hwinfo->amdtp_rx_pcm_channels_2x > AM824_MAX_CHANNELS_FOR_PCM ||
146 hwinfo->amdtp_rx_pcm_channels_4x > AMDTP_MAX_CHANNELS_FOR_PCM) { 146 hwinfo->amdtp_rx_pcm_channels_4x > AM824_MAX_CHANNELS_FOR_PCM) {
147 err = -ENOSYS; 147 err = -ENOSYS;
148 goto end; 148 goto end;
149 } 149 }
diff --git a/sound/firewire/fireworks/fireworks.h b/sound/firewire/fireworks/fireworks.h
index 084d414b228c..c7cb7deafe48 100644
--- a/sound/firewire/fireworks/fireworks.h
+++ b/sound/firewire/fireworks/fireworks.h
@@ -29,7 +29,7 @@
29 29
30#include "../packets-buffer.h" 30#include "../packets-buffer.h"
31#include "../iso-resources.h" 31#include "../iso-resources.h"
32#include "../amdtp.h" 32#include "../amdtp-am824.h"
33#include "../cmp.h" 33#include "../cmp.h"
34#include "../lib.h" 34#include "../lib.h"
35 35
diff --git a/sound/firewire/fireworks/fireworks_command.c b/sound/firewire/fireworks/fireworks_command.c
index 166f80584c2a..94bab0476a65 100644
--- a/sound/firewire/fireworks/fireworks_command.c
+++ b/sound/firewire/fireworks/fireworks_command.c
@@ -257,7 +257,7 @@ int snd_efw_command_get_phys_meters(struct snd_efw *efw,
257 struct snd_efw_phys_meters *meters, 257 struct snd_efw_phys_meters *meters,
258 unsigned int len) 258 unsigned int len)
259{ 259{
260 __be32 *buf = (__be32 *)meters; 260 u32 *buf = (u32 *)meters;
261 unsigned int i; 261 unsigned int i;
262 int err; 262 int err;
263 263
diff --git a/sound/firewire/fireworks/fireworks_midi.c b/sound/firewire/fireworks/fireworks_midi.c
index cf9c65260439..fba01bbba456 100644
--- a/sound/firewire/fireworks/fireworks_midi.c
+++ b/sound/firewire/fireworks/fireworks_midi.c
@@ -73,10 +73,10 @@ static void midi_capture_trigger(struct snd_rawmidi_substream *substrm, int up)
73 spin_lock_irqsave(&efw->lock, flags); 73 spin_lock_irqsave(&efw->lock, flags);
74 74
75 if (up) 75 if (up)
76 amdtp_stream_midi_trigger(&efw->tx_stream, 76 amdtp_am824_midi_trigger(&efw->tx_stream,
77 substrm->number, substrm); 77 substrm->number, substrm);
78 else 78 else
79 amdtp_stream_midi_trigger(&efw->tx_stream, 79 amdtp_am824_midi_trigger(&efw->tx_stream,
80 substrm->number, NULL); 80 substrm->number, NULL);
81 81
82 spin_unlock_irqrestore(&efw->lock, flags); 82 spin_unlock_irqrestore(&efw->lock, flags);
@@ -90,11 +90,11 @@ static void midi_playback_trigger(struct snd_rawmidi_substream *substrm, int up)
90 spin_lock_irqsave(&efw->lock, flags); 90 spin_lock_irqsave(&efw->lock, flags);
91 91
92 if (up) 92 if (up)
93 amdtp_stream_midi_trigger(&efw->rx_stream, 93 amdtp_am824_midi_trigger(&efw->rx_stream,
94 substrm->number, substrm); 94 substrm->number, substrm);
95 else 95 else
96 amdtp_stream_midi_trigger(&efw->rx_stream, 96 amdtp_am824_midi_trigger(&efw->rx_stream,
97 substrm->number, NULL); 97 substrm->number, NULL);
98 98
99 spin_unlock_irqrestore(&efw->lock, flags); 99 spin_unlock_irqrestore(&efw->lock, flags);
100} 100}
diff --git a/sound/firewire/fireworks/fireworks_pcm.c b/sound/firewire/fireworks/fireworks_pcm.c
index c30b2ffa8dfb..d27135bac513 100644
--- a/sound/firewire/fireworks/fireworks_pcm.c
+++ b/sound/firewire/fireworks/fireworks_pcm.c
@@ -159,11 +159,11 @@ pcm_init_hw_params(struct snd_efw *efw,
159 SNDRV_PCM_INFO_MMAP_VALID; 159 SNDRV_PCM_INFO_MMAP_VALID;
160 160
161 if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) { 161 if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
162 runtime->hw.formats = AMDTP_IN_PCM_FORMAT_BITS; 162 runtime->hw.formats = AM824_IN_PCM_FORMAT_BITS;
163 s = &efw->tx_stream; 163 s = &efw->tx_stream;
164 pcm_channels = efw->pcm_capture_channels; 164 pcm_channels = efw->pcm_capture_channels;
165 } else { 165 } else {
166 runtime->hw.formats = AMDTP_OUT_PCM_FORMAT_BITS; 166 runtime->hw.formats = AM824_OUT_PCM_FORMAT_BITS;
167 s = &efw->rx_stream; 167 s = &efw->rx_stream;
168 pcm_channels = efw->pcm_playback_channels; 168 pcm_channels = efw->pcm_playback_channels;
169 } 169 }
@@ -187,7 +187,7 @@ pcm_init_hw_params(struct snd_efw *efw,
187 if (err < 0) 187 if (err < 0)
188 goto end; 188 goto end;
189 189
190 err = amdtp_stream_add_pcm_hw_constraints(s, runtime); 190 err = amdtp_am824_add_pcm_hw_constraints(s, runtime);
191end: 191end:
192 return err; 192 return err;
193} 193}
@@ -253,7 +253,8 @@ static int pcm_capture_hw_params(struct snd_pcm_substream *substream,
253 253
254 if (substream->runtime->status->state == SNDRV_PCM_STATE_OPEN) 254 if (substream->runtime->status->state == SNDRV_PCM_STATE_OPEN)
255 atomic_inc(&efw->capture_substreams); 255 atomic_inc(&efw->capture_substreams);
256 amdtp_stream_set_pcm_format(&efw->tx_stream, params_format(hw_params)); 256
257 amdtp_am824_set_pcm_format(&efw->tx_stream, params_format(hw_params));
257 258
258 return 0; 259 return 0;
259} 260}
@@ -270,7 +271,8 @@ static int pcm_playback_hw_params(struct snd_pcm_substream *substream,
270 271
271 if (substream->runtime->status->state == SNDRV_PCM_STATE_OPEN) 272 if (substream->runtime->status->state == SNDRV_PCM_STATE_OPEN)
272 atomic_inc(&efw->playback_substreams); 273 atomic_inc(&efw->playback_substreams);
273 amdtp_stream_set_pcm_format(&efw->rx_stream, params_format(hw_params)); 274
275 amdtp_am824_set_pcm_format(&efw->rx_stream, params_format(hw_params));
274 276
275 return 0; 277 return 0;
276} 278}
diff --git a/sound/firewire/fireworks/fireworks_stream.c b/sound/firewire/fireworks/fireworks_stream.c
index 7e353f1f7bff..759f6e3ed44a 100644
--- a/sound/firewire/fireworks/fireworks_stream.c
+++ b/sound/firewire/fireworks/fireworks_stream.c
@@ -31,7 +31,7 @@ init_stream(struct snd_efw *efw, struct amdtp_stream *stream)
31 if (err < 0) 31 if (err < 0)
32 goto end; 32 goto end;
33 33
34 err = amdtp_stream_init(stream, efw->unit, s_dir, CIP_BLOCKING); 34 err = amdtp_am824_init(stream, efw->unit, s_dir, CIP_BLOCKING);
35 if (err < 0) { 35 if (err < 0) {
36 amdtp_stream_destroy(stream); 36 amdtp_stream_destroy(stream);
37 cmp_connection_destroy(conn); 37 cmp_connection_destroy(conn);
@@ -73,8 +73,10 @@ start_stream(struct snd_efw *efw, struct amdtp_stream *stream,
73 midi_ports = efw->midi_in_ports; 73 midi_ports = efw->midi_in_ports;
74 } 74 }
75 75
76 amdtp_stream_set_parameters(stream, sampling_rate, 76 err = amdtp_am824_set_parameters(stream, sampling_rate,
77 pcm_channels, midi_ports); 77 pcm_channels, midi_ports, false);
78 if (err < 0)
79 goto end;
78 80
79 /* establish connection via CMP */ 81 /* establish connection via CMP */
80 err = cmp_connection_establish(conn, 82 err = cmp_connection_establish(conn,
diff --git a/sound/firewire/lib.c b/sound/firewire/lib.c
index 7409edba9f06..f80aafa44c89 100644
--- a/sound/firewire/lib.c
+++ b/sound/firewire/lib.c
@@ -9,6 +9,7 @@
9#include <linux/device.h> 9#include <linux/device.h>
10#include <linux/firewire.h> 10#include <linux/firewire.h>
11#include <linux/module.h> 11#include <linux/module.h>
12#include <linux/slab.h>
12#include "lib.h" 13#include "lib.h"
13 14
14#define ERROR_RETRY_DELAY_MS 20 15#define ERROR_RETRY_DELAY_MS 20
@@ -66,6 +67,147 @@ int snd_fw_transaction(struct fw_unit *unit, int tcode,
66} 67}
67EXPORT_SYMBOL(snd_fw_transaction); 68EXPORT_SYMBOL(snd_fw_transaction);
68 69
70static void async_midi_port_callback(struct fw_card *card, int rcode,
71 void *data, size_t length,
72 void *callback_data)
73{
74 struct snd_fw_async_midi_port *port = callback_data;
75 struct snd_rawmidi_substream *substream = ACCESS_ONCE(port->substream);
76
77 /* This port is closed. */
78 if (substream == NULL)
79 return;
80
81 if (rcode == RCODE_COMPLETE)
82 snd_rawmidi_transmit_ack(substream, port->consume_bytes);
83 else if (!rcode_is_permanent_error(rcode))
84 /* To start next transaction immediately for recovery. */
85 port->next_ktime = ktime_set(0, 0);
86 else
87 /* Don't continue processing. */
88 port->error = true;
89
90 port->idling = true;
91
92 if (!snd_rawmidi_transmit_empty(substream))
93 schedule_work(&port->work);
94}
95
96static void midi_port_work(struct work_struct *work)
97{
98 struct snd_fw_async_midi_port *port =
99 container_of(work, struct snd_fw_async_midi_port, work);
100 struct snd_rawmidi_substream *substream = ACCESS_ONCE(port->substream);
101 int generation;
102 int type;
103
104 /* Under transacting or error state. */
105 if (!port->idling || port->error)
106 return;
107
108 /* Nothing to do. */
109 if (substream == NULL || snd_rawmidi_transmit_empty(substream))
110 return;
111
112 /* Do it in next chance. */
113 if (ktime_after(port->next_ktime, ktime_get())) {
114 schedule_work(&port->work);
115 return;
116 }
117
118 /*
119 * Fill the buffer. The callee must use snd_rawmidi_transmit_peek().
120 * Later, snd_rawmidi_transmit_ack() is called.
121 */
122 memset(port->buf, 0, port->len);
123 port->consume_bytes = port->fill(substream, port->buf);
124 if (port->consume_bytes <= 0) {
125 /* Do it in next chance, immediately. */
126 if (port->consume_bytes == 0) {
127 port->next_ktime = ktime_set(0, 0);
128 schedule_work(&port->work);
129 } else {
130 /* Fatal error. */
131 port->error = true;
132 }
133 return;
134 }
135
136 /* Calculate type of transaction. */
137 if (port->len == 4)
138 type = TCODE_WRITE_QUADLET_REQUEST;
139 else
140 type = TCODE_WRITE_BLOCK_REQUEST;
141
142 /* Set interval to next transaction. */
143 port->next_ktime = ktime_add_ns(ktime_get(),
144 port->consume_bytes * 8 * NSEC_PER_SEC / 31250);
145
146 /* Start this transaction. */
147 port->idling = false;
148
149 /*
150 * In Linux FireWire core, when generation is updated with memory
151 * barrier, node id has already been updated. In this module, After
152 * this smp_rmb(), load/store instructions to memory are completed.
153 * Thus, both of generation and node id are available with recent
154 * values. This is a light-serialization solution to handle bus reset
155 * events on IEEE 1394 bus.
156 */
157 generation = port->parent->generation;
158 smp_rmb();
159
160 fw_send_request(port->parent->card, &port->transaction, type,
161 port->parent->node_id, generation,
162 port->parent->max_speed, port->addr,
163 port->buf, port->len, async_midi_port_callback,
164 port);
165}
166
167/**
168 * snd_fw_async_midi_port_init - initialize asynchronous MIDI port structure
169 * @port: the asynchronous MIDI port to initialize
170 * @unit: the target of the asynchronous transaction
171 * @addr: the address to which transactions are transferred
172 * @len: the length of transaction
173 * @fill: the callback function to fill given buffer, and returns the
174 * number of consumed bytes for MIDI message.
175 *
176 */
177int snd_fw_async_midi_port_init(struct snd_fw_async_midi_port *port,
178 struct fw_unit *unit, u64 addr, unsigned int len,
179 snd_fw_async_midi_port_fill fill)
180{
181 port->len = DIV_ROUND_UP(len, 4) * 4;
182 port->buf = kzalloc(port->len, GFP_KERNEL);
183 if (port->buf == NULL)
184 return -ENOMEM;
185
186 port->parent = fw_parent_device(unit);
187 port->addr = addr;
188 port->fill = fill;
189 port->idling = true;
190 port->next_ktime = ktime_set(0, 0);
191 port->error = false;
192
193 INIT_WORK(&port->work, midi_port_work);
194
195 return 0;
196}
197EXPORT_SYMBOL(snd_fw_async_midi_port_init);
198
199/**
200 * snd_fw_async_midi_port_destroy - free asynchronous MIDI port structure
201 * @port: the asynchronous MIDI port structure
202 */
203void snd_fw_async_midi_port_destroy(struct snd_fw_async_midi_port *port)
204{
205 snd_fw_async_midi_port_finish(port);
206 cancel_work_sync(&port->work);
207 kfree(port->buf);
208}
209EXPORT_SYMBOL(snd_fw_async_midi_port_destroy);
210
69MODULE_DESCRIPTION("FireWire audio helper functions"); 211MODULE_DESCRIPTION("FireWire audio helper functions");
70MODULE_AUTHOR("Clemens Ladisch <clemens@ladisch.de>"); 212MODULE_AUTHOR("Clemens Ladisch <clemens@ladisch.de>");
71MODULE_LICENSE("GPL v2"); 213MODULE_LICENSE("GPL v2");
diff --git a/sound/firewire/lib.h b/sound/firewire/lib.h
index 02cfabc9c3c4..f3f6f84c48d6 100644
--- a/sound/firewire/lib.h
+++ b/sound/firewire/lib.h
@@ -3,6 +3,8 @@
3 3
4#include <linux/firewire-constants.h> 4#include <linux/firewire-constants.h>
5#include <linux/types.h> 5#include <linux/types.h>
6#include <linux/sched.h>
7#include <sound/rawmidi.h>
6 8
7struct fw_unit; 9struct fw_unit;
8 10
@@ -20,4 +22,58 @@ static inline bool rcode_is_permanent_error(int rcode)
20 return rcode == RCODE_TYPE_ERROR || rcode == RCODE_ADDRESS_ERROR; 22 return rcode == RCODE_TYPE_ERROR || rcode == RCODE_ADDRESS_ERROR;
21} 23}
22 24
25struct snd_fw_async_midi_port;
26typedef int (*snd_fw_async_midi_port_fill)(
27 struct snd_rawmidi_substream *substream,
28 u8 *buf);
29
30struct snd_fw_async_midi_port {
31 struct fw_device *parent;
32 struct work_struct work;
33 bool idling;
34 ktime_t next_ktime;
35 bool error;
36
37 u64 addr;
38 struct fw_transaction transaction;
39
40 u8 *buf;
41 unsigned int len;
42
43 struct snd_rawmidi_substream *substream;
44 snd_fw_async_midi_port_fill fill;
45 unsigned int consume_bytes;
46};
47
48int snd_fw_async_midi_port_init(struct snd_fw_async_midi_port *port,
49 struct fw_unit *unit, u64 addr, unsigned int len,
50 snd_fw_async_midi_port_fill fill);
51void snd_fw_async_midi_port_destroy(struct snd_fw_async_midi_port *port);
52
53/**
54 * snd_fw_async_midi_port_run - run transactions for the async MIDI port
55 * @port: the asynchronous MIDI port
56 * @substream: the MIDI substream
57 */
58static inline void
59snd_fw_async_midi_port_run(struct snd_fw_async_midi_port *port,
60 struct snd_rawmidi_substream *substream)
61{
62 if (!port->error) {
63 port->substream = substream;
64 schedule_work(&port->work);
65 }
66}
67
68/**
69 * snd_fw_async_midi_port_finish - finish the asynchronous MIDI port
70 * @port: the asynchronous MIDI port
71 */
72static inline void
73snd_fw_async_midi_port_finish(struct snd_fw_async_midi_port *port)
74{
75 port->substream = NULL;
76 port->error = false;
77}
78
23#endif 79#endif
diff --git a/sound/firewire/oxfw/Makefile b/sound/firewire/oxfw/Makefile
index a926850864f6..06ff50f4e6c0 100644
--- a/sound/firewire/oxfw/Makefile
+++ b/sound/firewire/oxfw/Makefile
@@ -1,3 +1,3 @@
1snd-oxfw-objs := oxfw-command.o oxfw-stream.o oxfw-control.o oxfw-pcm.o \ 1snd-oxfw-objs := oxfw-command.o oxfw-stream.o oxfw-control.o oxfw-pcm.o \
2 oxfw-proc.o oxfw-midi.o oxfw-hwdep.o oxfw.o 2 oxfw-proc.o oxfw-midi.o oxfw-hwdep.o oxfw.o
3obj-m += snd-oxfw.o 3obj-$(CONFIG_SND_OXFW) += snd-oxfw.o
diff --git a/sound/firewire/oxfw/oxfw-midi.c b/sound/firewire/oxfw/oxfw-midi.c
index 540a30338516..8665e1043d41 100644
--- a/sound/firewire/oxfw/oxfw-midi.c
+++ b/sound/firewire/oxfw/oxfw-midi.c
@@ -90,11 +90,11 @@ static void midi_capture_trigger(struct snd_rawmidi_substream *substrm, int up)
90 spin_lock_irqsave(&oxfw->lock, flags); 90 spin_lock_irqsave(&oxfw->lock, flags);
91 91
92 if (up) 92 if (up)
93 amdtp_stream_midi_trigger(&oxfw->tx_stream, 93 amdtp_am824_midi_trigger(&oxfw->tx_stream,
94 substrm->number, substrm); 94 substrm->number, substrm);
95 else 95 else
96 amdtp_stream_midi_trigger(&oxfw->tx_stream, 96 amdtp_am824_midi_trigger(&oxfw->tx_stream,
97 substrm->number, NULL); 97 substrm->number, NULL);
98 98
99 spin_unlock_irqrestore(&oxfw->lock, flags); 99 spin_unlock_irqrestore(&oxfw->lock, flags);
100} 100}
@@ -107,11 +107,11 @@ static void midi_playback_trigger(struct snd_rawmidi_substream *substrm, int up)
107 spin_lock_irqsave(&oxfw->lock, flags); 107 spin_lock_irqsave(&oxfw->lock, flags);
108 108
109 if (up) 109 if (up)
110 amdtp_stream_midi_trigger(&oxfw->rx_stream, 110 amdtp_am824_midi_trigger(&oxfw->rx_stream,
111 substrm->number, substrm); 111 substrm->number, substrm);
112 else 112 else
113 amdtp_stream_midi_trigger(&oxfw->rx_stream, 113 amdtp_am824_midi_trigger(&oxfw->rx_stream,
114 substrm->number, NULL); 114 substrm->number, NULL);
115 115
116 spin_unlock_irqrestore(&oxfw->lock, flags); 116 spin_unlock_irqrestore(&oxfw->lock, flags);
117} 117}
@@ -142,29 +142,11 @@ static void set_midi_substream_names(struct snd_oxfw *oxfw,
142 142
143int snd_oxfw_create_midi(struct snd_oxfw *oxfw) 143int snd_oxfw_create_midi(struct snd_oxfw *oxfw)
144{ 144{
145 struct snd_oxfw_stream_formation formation;
146 struct snd_rawmidi *rmidi; 145 struct snd_rawmidi *rmidi;
147 struct snd_rawmidi_str *str; 146 struct snd_rawmidi_str *str;
148 u8 *format; 147 int err;
149 int i, err; 148
150 149 if (oxfw->midi_input_ports == 0 && oxfw->midi_output_ports == 0)
151 /* If its stream has MIDI conformant data channel, add one MIDI port */
152 for (i = 0; i < SND_OXFW_STREAM_FORMAT_ENTRIES; i++) {
153 format = oxfw->tx_stream_formats[i];
154 if (format != NULL) {
155 err = snd_oxfw_stream_parse_format(format, &formation);
156 if (err >= 0 && formation.midi > 0)
157 oxfw->midi_input_ports = 1;
158 }
159
160 format = oxfw->rx_stream_formats[i];
161 if (format != NULL) {
162 err = snd_oxfw_stream_parse_format(format, &formation);
163 if (err >= 0 && formation.midi > 0)
164 oxfw->midi_output_ports = 1;
165 }
166 }
167 if ((oxfw->midi_input_ports == 0) && (oxfw->midi_output_ports == 0))
168 return 0; 150 return 0;
169 151
170 /* create midi ports */ 152 /* create midi ports */
diff --git a/sound/firewire/oxfw/oxfw-pcm.c b/sound/firewire/oxfw/oxfw-pcm.c
index 9c73930d0278..8d233417695d 100644
--- a/sound/firewire/oxfw/oxfw-pcm.c
+++ b/sound/firewire/oxfw/oxfw-pcm.c
@@ -134,11 +134,11 @@ static int init_hw_params(struct snd_oxfw *oxfw,
134 SNDRV_PCM_INFO_MMAP_VALID; 134 SNDRV_PCM_INFO_MMAP_VALID;
135 135
136 if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) { 136 if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
137 runtime->hw.formats = AMDTP_IN_PCM_FORMAT_BITS; 137 runtime->hw.formats = AM824_IN_PCM_FORMAT_BITS;
138 stream = &oxfw->tx_stream; 138 stream = &oxfw->tx_stream;
139 formats = oxfw->tx_stream_formats; 139 formats = oxfw->tx_stream_formats;
140 } else { 140 } else {
141 runtime->hw.formats = AMDTP_OUT_PCM_FORMAT_BITS; 141 runtime->hw.formats = AM824_OUT_PCM_FORMAT_BITS;
142 stream = &oxfw->rx_stream; 142 stream = &oxfw->rx_stream;
143 formats = oxfw->rx_stream_formats; 143 formats = oxfw->rx_stream_formats;
144 } 144 }
@@ -158,7 +158,7 @@ static int init_hw_params(struct snd_oxfw *oxfw,
158 if (err < 0) 158 if (err < 0)
159 goto end; 159 goto end;
160 160
161 err = amdtp_stream_add_pcm_hw_constraints(stream, runtime); 161 err = amdtp_am824_add_pcm_hw_constraints(stream, runtime);
162end: 162end:
163 return err; 163 return err;
164} 164}
@@ -244,7 +244,7 @@ static int pcm_capture_hw_params(struct snd_pcm_substream *substream,
244 mutex_unlock(&oxfw->mutex); 244 mutex_unlock(&oxfw->mutex);
245 } 245 }
246 246
247 amdtp_stream_set_pcm_format(&oxfw->tx_stream, params_format(hw_params)); 247 amdtp_am824_set_pcm_format(&oxfw->tx_stream, params_format(hw_params));
248 248
249 return 0; 249 return 0;
250} 250}
@@ -265,7 +265,7 @@ static int pcm_playback_hw_params(struct snd_pcm_substream *substream,
265 mutex_unlock(&oxfw->mutex); 265 mutex_unlock(&oxfw->mutex);
266 } 266 }
267 267
268 amdtp_stream_set_pcm_format(&oxfw->rx_stream, params_format(hw_params)); 268 amdtp_am824_set_pcm_format(&oxfw->rx_stream, params_format(hw_params));
269 269
270 return 0; 270 return 0;
271} 271}
diff --git a/sound/firewire/oxfw/oxfw-stream.c b/sound/firewire/oxfw/oxfw-stream.c
index 77ad5b98e806..7cb5743c073b 100644
--- a/sound/firewire/oxfw/oxfw-stream.c
+++ b/sound/firewire/oxfw/oxfw-stream.c
@@ -148,14 +148,17 @@ static int start_stream(struct snd_oxfw *oxfw, struct amdtp_stream *stream,
148 } 148 }
149 149
150 pcm_channels = formation.pcm; 150 pcm_channels = formation.pcm;
151 midi_ports = DIV_ROUND_UP(formation.midi, 8); 151 midi_ports = formation.midi * 8;
152 152
153 /* The stream should have one pcm channels at least */ 153 /* The stream should have one pcm channels at least */
154 if (pcm_channels == 0) { 154 if (pcm_channels == 0) {
155 err = -EINVAL; 155 err = -EINVAL;
156 goto end; 156 goto end;
157 } 157 }
158 amdtp_stream_set_parameters(stream, rate, pcm_channels, midi_ports); 158 err = amdtp_am824_set_parameters(stream, rate, pcm_channels, midi_ports,
159 false);
160 if (err < 0)
161 goto end;
159 162
160 err = cmp_connection_establish(conn, 163 err = cmp_connection_establish(conn,
161 amdtp_stream_get_max_payload(stream)); 164 amdtp_stream_get_max_payload(stream));
@@ -225,7 +228,7 @@ int snd_oxfw_stream_init_simplex(struct snd_oxfw *oxfw,
225 if (err < 0) 228 if (err < 0)
226 goto end; 229 goto end;
227 230
228 err = amdtp_stream_init(stream, oxfw->unit, s_dir, CIP_NONBLOCKING); 231 err = amdtp_am824_init(stream, oxfw->unit, s_dir, CIP_NONBLOCKING);
229 if (err < 0) { 232 if (err < 0) {
230 amdtp_stream_destroy(stream); 233 amdtp_stream_destroy(stream);
231 cmp_connection_destroy(conn); 234 cmp_connection_destroy(conn);
@@ -238,9 +241,12 @@ int snd_oxfw_stream_init_simplex(struct snd_oxfw *oxfw,
238 * packets. As a result, next isochronous packet includes more data 241 * packets. As a result, next isochronous packet includes more data
239 * blocks than IEC 61883-6 defines. 242 * blocks than IEC 61883-6 defines.
240 */ 243 */
241 if (stream == &oxfw->tx_stream) 244 if (stream == &oxfw->tx_stream) {
242 oxfw->tx_stream.flags |= CIP_SKIP_INIT_DBC_CHECK | 245 oxfw->tx_stream.flags |= CIP_SKIP_INIT_DBC_CHECK |
243 CIP_JUMBO_PAYLOAD; 246 CIP_JUMBO_PAYLOAD;
247 if (oxfw->wrong_dbs)
248 oxfw->tx_stream.flags |= CIP_WRONG_DBS;
249 }
244end: 250end:
245 return err; 251 return err;
246} 252}
@@ -480,8 +486,8 @@ int snd_oxfw_stream_parse_format(u8 *format,
480 } 486 }
481 } 487 }
482 488
483 if (formation->pcm > AMDTP_MAX_CHANNELS_FOR_PCM || 489 if (formation->pcm > AM824_MAX_CHANNELS_FOR_PCM ||
484 formation->midi > AMDTP_MAX_CHANNELS_FOR_MIDI) 490 formation->midi > AM824_MAX_CHANNELS_FOR_MIDI)
485 return -ENOSYS; 491 return -ENOSYS;
486 492
487 return 0; 493 return 0;
@@ -623,6 +629,9 @@ end:
623int snd_oxfw_stream_discover(struct snd_oxfw *oxfw) 629int snd_oxfw_stream_discover(struct snd_oxfw *oxfw)
624{ 630{
625 u8 plugs[AVC_PLUG_INFO_BUF_BYTES]; 631 u8 plugs[AVC_PLUG_INFO_BUF_BYTES];
632 struct snd_oxfw_stream_formation formation;
633 u8 *format;
634 unsigned int i;
626 int err; 635 int err;
627 636
628 /* the number of plugs for isoc in/out, ext in/out */ 637 /* the number of plugs for isoc in/out, ext in/out */
@@ -642,12 +651,42 @@ int snd_oxfw_stream_discover(struct snd_oxfw *oxfw)
642 err = fill_stream_formats(oxfw, AVC_GENERAL_PLUG_DIR_OUT, 0); 651 err = fill_stream_formats(oxfw, AVC_GENERAL_PLUG_DIR_OUT, 0);
643 if (err < 0) 652 if (err < 0)
644 goto end; 653 goto end;
654
655 for (i = 0; i < SND_OXFW_STREAM_FORMAT_ENTRIES; i++) {
656 format = oxfw->tx_stream_formats[i];
657 if (format == NULL)
658 continue;
659 err = snd_oxfw_stream_parse_format(format, &formation);
660 if (err < 0)
661 continue;
662
663 /* Add one MIDI port. */
664 if (formation.midi > 0)
665 oxfw->midi_input_ports = 1;
666 }
667
645 oxfw->has_output = true; 668 oxfw->has_output = true;
646 } 669 }
647 670
648 /* use iPCR[0] if exists */ 671 /* use iPCR[0] if exists */
649 if (plugs[0] > 0) 672 if (plugs[0] > 0) {
650 err = fill_stream_formats(oxfw, AVC_GENERAL_PLUG_DIR_IN, 0); 673 err = fill_stream_formats(oxfw, AVC_GENERAL_PLUG_DIR_IN, 0);
674 if (err < 0)
675 goto end;
676
677 for (i = 0; i < SND_OXFW_STREAM_FORMAT_ENTRIES; i++) {
678 format = oxfw->rx_stream_formats[i];
679 if (format == NULL)
680 continue;
681 err = snd_oxfw_stream_parse_format(format, &formation);
682 if (err < 0)
683 continue;
684
685 /* Add one MIDI port. */
686 if (formation.midi > 0)
687 oxfw->midi_output_ports = 1;
688 }
689 }
651end: 690end:
652 return err; 691 return err;
653} 692}
diff --git a/sound/firewire/oxfw/oxfw.c b/sound/firewire/oxfw/oxfw.c
index 8c6ce019f437..588b93f20c2e 100644
--- a/sound/firewire/oxfw/oxfw.c
+++ b/sound/firewire/oxfw/oxfw.c
@@ -18,6 +18,9 @@
18#define VENDOR_GRIFFIN 0x001292 18#define VENDOR_GRIFFIN 0x001292
19#define VENDOR_BEHRINGER 0x001564 19#define VENDOR_BEHRINGER 0x001564
20#define VENDOR_LACIE 0x00d04b 20#define VENDOR_LACIE 0x00d04b
21#define VENDOR_TASCAM 0x00022e
22
23#define MODEL_SATELLITE 0x00200f
21 24
22#define SPECIFIER_1394TA 0x00a02d 25#define SPECIFIER_1394TA 0x00a02d
23#define VERSION_AVC 0x010001 26#define VERSION_AVC 0x010001
@@ -129,6 +132,40 @@ static void oxfw_card_free(struct snd_card *card)
129 mutex_destroy(&oxfw->mutex); 132 mutex_destroy(&oxfw->mutex);
130} 133}
131 134
135static void detect_quirks(struct snd_oxfw *oxfw)
136{
137 struct fw_device *fw_dev = fw_parent_device(oxfw->unit);
138 struct fw_csr_iterator it;
139 int key, val;
140 int vendor, model;
141
142 /* Seek from Root Directory of Config ROM. */
143 vendor = model = 0;
144 fw_csr_iterator_init(&it, fw_dev->config_rom + 5);
145 while (fw_csr_iterator_next(&it, &key, &val)) {
146 if (key == CSR_VENDOR)
147 vendor = val;
148 else if (key == CSR_MODEL)
149 model = val;
150 }
151
152 /*
153 * Mackie Onyx Satellite with base station has a quirk to report a wrong
154 * value in 'dbs' field of CIP header against its format information.
155 */
156 if (vendor == VENDOR_LOUD && model == MODEL_SATELLITE)
157 oxfw->wrong_dbs = true;
158
159 /*
160 * TASCAM FireOne has physical control and requires a pair of additional
161 * MIDI ports.
162 */
163 if (vendor == VENDOR_TASCAM) {
164 oxfw->midi_input_ports++;
165 oxfw->midi_output_ports++;
166 }
167}
168
132static int oxfw_probe(struct fw_unit *unit, 169static int oxfw_probe(struct fw_unit *unit,
133 const struct ieee1394_device_id *id) 170 const struct ieee1394_device_id *id)
134{ 171{
@@ -157,6 +194,8 @@ static int oxfw_probe(struct fw_unit *unit,
157 if (err < 0) 194 if (err < 0)
158 goto error; 195 goto error;
159 196
197 detect_quirks(oxfw);
198
160 err = name_card(oxfw); 199 err = name_card(oxfw);
161 if (err < 0) 200 if (err < 0)
162 goto error; 201 goto error;
@@ -294,6 +333,13 @@ static const struct ieee1394_device_id oxfw_id_table[] = {
294 .specifier_id = SPECIFIER_1394TA, 333 .specifier_id = SPECIFIER_1394TA,
295 .version = VERSION_AVC, 334 .version = VERSION_AVC,
296 }, 335 },
336 /* TASCAM, FireOne */
337 {
338 .match_flags = IEEE1394_MATCH_VENDOR_ID |
339 IEEE1394_MATCH_MODEL_ID,
340 .vendor_id = VENDOR_TASCAM,
341 .model_id = 0x800007,
342 },
297 { } 343 { }
298}; 344};
299MODULE_DEVICE_TABLE(ieee1394, oxfw_id_table); 345MODULE_DEVICE_TABLE(ieee1394, oxfw_id_table);
diff --git a/sound/firewire/oxfw/oxfw.h b/sound/firewire/oxfw/oxfw.h
index cace5ad4fe76..8392c424ad1d 100644
--- a/sound/firewire/oxfw/oxfw.h
+++ b/sound/firewire/oxfw/oxfw.h
@@ -28,7 +28,7 @@
28#include "../fcp.h" 28#include "../fcp.h"
29#include "../packets-buffer.h" 29#include "../packets-buffer.h"
30#include "../iso-resources.h" 30#include "../iso-resources.h"
31#include "../amdtp.h" 31#include "../amdtp-am824.h"
32#include "../cmp.h" 32#include "../cmp.h"
33 33
34struct device_info { 34struct device_info {
@@ -49,6 +49,7 @@ struct snd_oxfw {
49 struct mutex mutex; 49 struct mutex mutex;
50 spinlock_t lock; 50 spinlock_t lock;
51 51
52 bool wrong_dbs;
52 bool has_output; 53 bool has_output;
53 u8 *tx_stream_formats[SND_OXFW_STREAM_FORMAT_ENTRIES]; 54 u8 *tx_stream_formats[SND_OXFW_STREAM_FORMAT_ENTRIES];
54 u8 *rx_stream_formats[SND_OXFW_STREAM_FORMAT_ENTRIES]; 55 u8 *rx_stream_formats[SND_OXFW_STREAM_FORMAT_ENTRIES];
diff --git a/sound/firewire/tascam/Makefile b/sound/firewire/tascam/Makefile
new file mode 100644
index 000000000000..0fc955d5bd15
--- /dev/null
+++ b/sound/firewire/tascam/Makefile
@@ -0,0 +1,4 @@
1snd-firewire-tascam-objs := tascam-proc.o amdtp-tascam.o tascam-stream.o \
2 tascam-pcm.o tascam-hwdep.o tascam-transaction.o \
3 tascam-midi.o tascam.o
4obj-$(CONFIG_SND_FIREWIRE_TASCAM) += snd-firewire-tascam.o
diff --git a/sound/firewire/tascam/amdtp-tascam.c b/sound/firewire/tascam/amdtp-tascam.c
new file mode 100644
index 000000000000..9dd0fccd5ccc
--- /dev/null
+++ b/sound/firewire/tascam/amdtp-tascam.c
@@ -0,0 +1,243 @@
1/*
2 * amdtp-tascam.c - a part of driver for TASCAM FireWire series
3 *
4 * Copyright (c) 2015 Takashi Sakamoto
5 *
6 * Licensed under the terms of the GNU General Public License, version 2.
7 */
8
9#include <sound/pcm.h>
10#include "tascam.h"
11
12#define AMDTP_FMT_TSCM_TX 0x1e
13#define AMDTP_FMT_TSCM_RX 0x3e
14
15struct amdtp_tscm {
16 unsigned int pcm_channels;
17
18 void (*transfer_samples)(struct amdtp_stream *s,
19 struct snd_pcm_substream *pcm,
20 __be32 *buffer, unsigned int frames);
21};
22
23int amdtp_tscm_set_parameters(struct amdtp_stream *s, unsigned int rate)
24{
25 struct amdtp_tscm *p = s->protocol;
26 unsigned int data_channels;
27
28 if (amdtp_stream_running(s))
29 return -EBUSY;
30
31 data_channels = p->pcm_channels;
32
33 /* Packets in in-stream have extra 2 data channels. */
34 if (s->direction == AMDTP_IN_STREAM)
35 data_channels += 2;
36
37 return amdtp_stream_set_parameters(s, rate, data_channels);
38}
39
40static void write_pcm_s32(struct amdtp_stream *s,
41 struct snd_pcm_substream *pcm,
42 __be32 *buffer, unsigned int frames)
43{
44 struct amdtp_tscm *p = s->protocol;
45 struct snd_pcm_runtime *runtime = pcm->runtime;
46 unsigned int channels, remaining_frames, i, c;
47 const u32 *src;
48
49 channels = p->pcm_channels;
50 src = (void *)runtime->dma_area +
51 frames_to_bytes(runtime, s->pcm_buffer_pointer);
52 remaining_frames = runtime->buffer_size - s->pcm_buffer_pointer;
53
54 for (i = 0; i < frames; ++i) {
55 for (c = 0; c < channels; ++c) {
56 buffer[c] = cpu_to_be32(*src);
57 src++;
58 }
59 buffer += s->data_block_quadlets;
60 if (--remaining_frames == 0)
61 src = (void *)runtime->dma_area;
62 }
63}
64
65static void write_pcm_s16(struct amdtp_stream *s,
66 struct snd_pcm_substream *pcm,
67 __be32 *buffer, unsigned int frames)
68{
69 struct amdtp_tscm *p = s->protocol;
70 struct snd_pcm_runtime *runtime = pcm->runtime;
71 unsigned int channels, remaining_frames, i, c;
72 const u16 *src;
73
74 channels = p->pcm_channels;
75 src = (void *)runtime->dma_area +
76 frames_to_bytes(runtime, s->pcm_buffer_pointer);
77 remaining_frames = runtime->buffer_size - s->pcm_buffer_pointer;
78
79 for (i = 0; i < frames; ++i) {
80 for (c = 0; c < channels; ++c) {
81 buffer[c] = cpu_to_be32(*src << 16);
82 src++;
83 }
84 buffer += s->data_block_quadlets;
85 if (--remaining_frames == 0)
86 src = (void *)runtime->dma_area;
87 }
88}
89
90static void read_pcm_s32(struct amdtp_stream *s,
91 struct snd_pcm_substream *pcm,
92 __be32 *buffer, unsigned int frames)
93{
94 struct amdtp_tscm *p = s->protocol;
95 struct snd_pcm_runtime *runtime = pcm->runtime;
96 unsigned int channels, remaining_frames, i, c;
97 u32 *dst;
98
99 channels = p->pcm_channels;
100 dst = (void *)runtime->dma_area +
101 frames_to_bytes(runtime, s->pcm_buffer_pointer);
102 remaining_frames = runtime->buffer_size - s->pcm_buffer_pointer;
103
104 /* The first data channel is for event counter. */
105 buffer += 1;
106
107 for (i = 0; i < frames; ++i) {
108 for (c = 0; c < channels; ++c) {
109 *dst = be32_to_cpu(buffer[c]);
110 dst++;
111 }
112 buffer += s->data_block_quadlets;
113 if (--remaining_frames == 0)
114 dst = (void *)runtime->dma_area;
115 }
116}
117
118static void write_pcm_silence(struct amdtp_stream *s, __be32 *buffer,
119 unsigned int data_blocks)
120{
121 struct amdtp_tscm *p = s->protocol;
122 unsigned int channels, i, c;
123
124 channels = p->pcm_channels;
125
126 for (i = 0; i < data_blocks; ++i) {
127 for (c = 0; c < channels; ++c)
128 buffer[c] = 0x00000000;
129 buffer += s->data_block_quadlets;
130 }
131}
132
133int amdtp_tscm_add_pcm_hw_constraints(struct amdtp_stream *s,
134 struct snd_pcm_runtime *runtime)
135{
136 int err;
137
138 /*
139 * Our implementation allows this protocol to deliver 24 bit sample in
140 * 32bit data channel.
141 */
142 err = snd_pcm_hw_constraint_msbits(runtime, 0, 32, 24);
143 if (err < 0)
144 return err;
145
146 return amdtp_stream_add_pcm_hw_constraints(s, runtime);
147}
148
149void amdtp_tscm_set_pcm_format(struct amdtp_stream *s, snd_pcm_format_t format)
150{
151 struct amdtp_tscm *p = s->protocol;
152
153 if (WARN_ON(amdtp_stream_pcm_running(s)))
154 return;
155
156 switch (format) {
157 default:
158 WARN_ON(1);
159 /* fall through */
160 case SNDRV_PCM_FORMAT_S16:
161 if (s->direction == AMDTP_OUT_STREAM) {
162 p->transfer_samples = write_pcm_s16;
163 break;
164 }
165 WARN_ON(1);
166 /* fall through */
167 case SNDRV_PCM_FORMAT_S32:
168 if (s->direction == AMDTP_OUT_STREAM)
169 p->transfer_samples = write_pcm_s32;
170 else
171 p->transfer_samples = read_pcm_s32;
172 break;
173 }
174}
175
176static unsigned int process_tx_data_blocks(struct amdtp_stream *s,
177 __be32 *buffer,
178 unsigned int data_blocks,
179 unsigned int *syt)
180{
181 struct amdtp_tscm *p = (struct amdtp_tscm *)s->protocol;
182 struct snd_pcm_substream *pcm;
183
184 pcm = ACCESS_ONCE(s->pcm);
185 if (data_blocks > 0 && pcm)
186 p->transfer_samples(s, pcm, buffer, data_blocks);
187
188 /* A place holder for control messages. */
189
190 return data_blocks;
191}
192
193static unsigned int process_rx_data_blocks(struct amdtp_stream *s,
194 __be32 *buffer,
195 unsigned int data_blocks,
196 unsigned int *syt)
197{
198 struct amdtp_tscm *p = (struct amdtp_tscm *)s->protocol;
199 struct snd_pcm_substream *pcm;
200
201 /* This field is not used. */
202 *syt = 0x0000;
203
204 pcm = ACCESS_ONCE(s->pcm);
205 if (pcm)
206 p->transfer_samples(s, pcm, buffer, data_blocks);
207 else
208 write_pcm_silence(s, buffer, data_blocks);
209
210 return data_blocks;
211}
212
213int amdtp_tscm_init(struct amdtp_stream *s, struct fw_unit *unit,
214 enum amdtp_stream_direction dir, unsigned int pcm_channels)
215{
216 amdtp_stream_process_data_blocks_t process_data_blocks;
217 struct amdtp_tscm *p;
218 unsigned int fmt;
219 int err;
220
221 if (dir == AMDTP_IN_STREAM) {
222 fmt = AMDTP_FMT_TSCM_TX;
223 process_data_blocks = process_tx_data_blocks;
224 } else {
225 fmt = AMDTP_FMT_TSCM_RX;
226 process_data_blocks = process_rx_data_blocks;
227 }
228
229 err = amdtp_stream_init(s, unit, dir,
230 CIP_NONBLOCKING | CIP_SKIP_DBC_ZERO_CHECK, fmt,
231 process_data_blocks, sizeof(struct amdtp_tscm));
232 if (err < 0)
233 return 0;
234
235 /* Use fixed value for FDF field. */
236 s->fdf = 0x00;
237
238 /* This protocol uses fixed number of data channels for PCM samples. */
239 p = s->protocol;
240 p->pcm_channels = pcm_channels;
241
242 return 0;
243}
diff --git a/sound/firewire/tascam/tascam-hwdep.c b/sound/firewire/tascam/tascam-hwdep.c
new file mode 100644
index 000000000000..131267c3a042
--- /dev/null
+++ b/sound/firewire/tascam/tascam-hwdep.c
@@ -0,0 +1,201 @@
1/*
2 * tascam-hwdep.c - a part of driver for TASCAM FireWire series
3 *
4 * Copyright (c) 2015 Takashi Sakamoto
5 *
6 * Licensed under the terms of the GNU General Public License, version 2.
7 */
8
9/*
10 * This codes give three functionality.
11 *
12 * 1.get firewire node information
13 * 2.get notification about starting/stopping stream
14 * 3.lock/unlock stream
15 */
16
17#include "tascam.h"
18
19static long hwdep_read_locked(struct snd_tscm *tscm, char __user *buf,
20 long count)
21{
22 union snd_firewire_event event;
23
24 memset(&event, 0, sizeof(event));
25
26 event.lock_status.type = SNDRV_FIREWIRE_EVENT_LOCK_STATUS;
27 event.lock_status.status = (tscm->dev_lock_count > 0);
28 tscm->dev_lock_changed = false;
29
30 count = min_t(long, count, sizeof(event.lock_status));
31
32 if (copy_to_user(buf, &event, count))
33 return -EFAULT;
34
35 return count;
36}
37
38static long hwdep_read(struct snd_hwdep *hwdep, char __user *buf, long count,
39 loff_t *offset)
40{
41 struct snd_tscm *tscm = hwdep->private_data;
42 DEFINE_WAIT(wait);
43 union snd_firewire_event event;
44
45 spin_lock_irq(&tscm->lock);
46
47 while (!tscm->dev_lock_changed) {
48 prepare_to_wait(&tscm->hwdep_wait, &wait, TASK_INTERRUPTIBLE);
49 spin_unlock_irq(&tscm->lock);
50 schedule();
51 finish_wait(&tscm->hwdep_wait, &wait);
52 if (signal_pending(current))
53 return -ERESTARTSYS;
54 spin_lock_irq(&tscm->lock);
55 }
56
57 memset(&event, 0, sizeof(event));
58 count = hwdep_read_locked(tscm, buf, count);
59 spin_unlock_irq(&tscm->lock);
60
61 return count;
62}
63
64static unsigned int hwdep_poll(struct snd_hwdep *hwdep, struct file *file,
65 poll_table *wait)
66{
67 struct snd_tscm *tscm = hwdep->private_data;
68 unsigned int events;
69
70 poll_wait(file, &tscm->hwdep_wait, wait);
71
72 spin_lock_irq(&tscm->lock);
73 if (tscm->dev_lock_changed)
74 events = POLLIN | POLLRDNORM;
75 else
76 events = 0;
77 spin_unlock_irq(&tscm->lock);
78
79 return events;
80}
81
82static int hwdep_get_info(struct snd_tscm *tscm, void __user *arg)
83{
84 struct fw_device *dev = fw_parent_device(tscm->unit);
85 struct snd_firewire_get_info info;
86
87 memset(&info, 0, sizeof(info));
88 info.type = SNDRV_FIREWIRE_TYPE_TASCAM;
89 info.card = dev->card->index;
90 *(__be32 *)&info.guid[0] = cpu_to_be32(dev->config_rom[3]);
91 *(__be32 *)&info.guid[4] = cpu_to_be32(dev->config_rom[4]);
92 strlcpy(info.device_name, dev_name(&dev->device),
93 sizeof(info.device_name));
94
95 if (copy_to_user(arg, &info, sizeof(info)))
96 return -EFAULT;
97
98 return 0;
99}
100
101static int hwdep_lock(struct snd_tscm *tscm)
102{
103 int err;
104
105 spin_lock_irq(&tscm->lock);
106
107 if (tscm->dev_lock_count == 0) {
108 tscm->dev_lock_count = -1;
109 err = 0;
110 } else {
111 err = -EBUSY;
112 }
113
114 spin_unlock_irq(&tscm->lock);
115
116 return err;
117}
118
119static int hwdep_unlock(struct snd_tscm *tscm)
120{
121 int err;
122
123 spin_lock_irq(&tscm->lock);
124
125 if (tscm->dev_lock_count == -1) {
126 tscm->dev_lock_count = 0;
127 err = 0;
128 } else {
129 err = -EBADFD;
130 }
131
132 spin_unlock_irq(&tscm->lock);
133
134 return err;
135}
136
137static int hwdep_release(struct snd_hwdep *hwdep, struct file *file)
138{
139 struct snd_tscm *tscm = hwdep->private_data;
140
141 spin_lock_irq(&tscm->lock);
142 if (tscm->dev_lock_count == -1)
143 tscm->dev_lock_count = 0;
144 spin_unlock_irq(&tscm->lock);
145
146 return 0;
147}
148
149static int hwdep_ioctl(struct snd_hwdep *hwdep, struct file *file,
150 unsigned int cmd, unsigned long arg)
151{
152 struct snd_tscm *tscm = hwdep->private_data;
153
154 switch (cmd) {
155 case SNDRV_FIREWIRE_IOCTL_GET_INFO:
156 return hwdep_get_info(tscm, (void __user *)arg);
157 case SNDRV_FIREWIRE_IOCTL_LOCK:
158 return hwdep_lock(tscm);
159 case SNDRV_FIREWIRE_IOCTL_UNLOCK:
160 return hwdep_unlock(tscm);
161 default:
162 return -ENOIOCTLCMD;
163 }
164}
165
166#ifdef CONFIG_COMPAT
167static int hwdep_compat_ioctl(struct snd_hwdep *hwdep, struct file *file,
168 unsigned int cmd, unsigned long arg)
169{
170 return hwdep_ioctl(hwdep, file, cmd,
171 (unsigned long)compat_ptr(arg));
172}
173#else
174#define hwdep_compat_ioctl NULL
175#endif
176
177static const struct snd_hwdep_ops hwdep_ops = {
178 .read = hwdep_read,
179 .release = hwdep_release,
180 .poll = hwdep_poll,
181 .ioctl = hwdep_ioctl,
182 .ioctl_compat = hwdep_compat_ioctl,
183};
184
185int snd_tscm_create_hwdep_device(struct snd_tscm *tscm)
186{
187 struct snd_hwdep *hwdep;
188 int err;
189
190 err = snd_hwdep_new(tscm->card, "Tascam", 0, &hwdep);
191 if (err < 0)
192 return err;
193
194 strcpy(hwdep->name, "Tascam");
195 hwdep->iface = SNDRV_HWDEP_IFACE_FW_TASCAM;
196 hwdep->ops = hwdep_ops;
197 hwdep->private_data = tscm;
198 hwdep->exclusive = true;
199
200 return err;
201}
diff --git a/sound/firewire/tascam/tascam-midi.c b/sound/firewire/tascam/tascam-midi.c
new file mode 100644
index 000000000000..41f842079d9d
--- /dev/null
+++ b/sound/firewire/tascam/tascam-midi.c
@@ -0,0 +1,135 @@
1/*
2 * tascam-midi.c - a part of driver for TASCAM FireWire series
3 *
4 * Copyright (c) 2015 Takashi Sakamoto
5 *
6 * Licensed under the terms of the GNU General Public License, version 2.
7 */
8
9#include "tascam.h"
10
11static int midi_capture_open(struct snd_rawmidi_substream *substream)
12{
13 /* Do nothing. */
14 return 0;
15}
16
17static int midi_playback_open(struct snd_rawmidi_substream *substream)
18{
19 struct snd_tscm *tscm = substream->rmidi->private_data;
20
21 /* Initialize internal status. */
22 tscm->running_status[substream->number] = 0;
23 tscm->on_sysex[substream->number] = 0;
24 return 0;
25}
26
27static int midi_capture_close(struct snd_rawmidi_substream *substream)
28{
29 /* Do nothing. */
30 return 0;
31}
32
33static int midi_playback_close(struct snd_rawmidi_substream *substream)
34{
35 struct snd_tscm *tscm = substream->rmidi->private_data;
36
37 snd_fw_async_midi_port_finish(&tscm->out_ports[substream->number]);
38
39 return 0;
40}
41
42static void midi_capture_trigger(struct snd_rawmidi_substream *substrm, int up)
43{
44 struct snd_tscm *tscm = substrm->rmidi->private_data;
45 unsigned long flags;
46
47 spin_lock_irqsave(&tscm->lock, flags);
48
49 if (up)
50 tscm->tx_midi_substreams[substrm->number] = substrm;
51 else
52 tscm->tx_midi_substreams[substrm->number] = NULL;
53
54 spin_unlock_irqrestore(&tscm->lock, flags);
55}
56
57static void midi_playback_trigger(struct snd_rawmidi_substream *substrm, int up)
58{
59 struct snd_tscm *tscm = substrm->rmidi->private_data;
60 unsigned long flags;
61
62 spin_lock_irqsave(&tscm->lock, flags);
63
64 if (up)
65 snd_fw_async_midi_port_run(&tscm->out_ports[substrm->number],
66 substrm);
67
68 spin_unlock_irqrestore(&tscm->lock, flags);
69}
70
71static struct snd_rawmidi_ops midi_capture_ops = {
72 .open = midi_capture_open,
73 .close = midi_capture_close,
74 .trigger = midi_capture_trigger,
75};
76
77static struct snd_rawmidi_ops midi_playback_ops = {
78 .open = midi_playback_open,
79 .close = midi_playback_close,
80 .trigger = midi_playback_trigger,
81};
82
83int snd_tscm_create_midi_devices(struct snd_tscm *tscm)
84{
85 struct snd_rawmidi *rmidi;
86 struct snd_rawmidi_str *stream;
87 struct snd_rawmidi_substream *subs;
88 int err;
89
90 err = snd_rawmidi_new(tscm->card, tscm->card->driver, 0,
91 tscm->spec->midi_playback_ports,
92 tscm->spec->midi_capture_ports,
93 &rmidi);
94 if (err < 0)
95 return err;
96
97 snprintf(rmidi->name, sizeof(rmidi->name),
98 "%s MIDI", tscm->card->shortname);
99 rmidi->private_data = tscm;
100
101 rmidi->info_flags |= SNDRV_RAWMIDI_INFO_INPUT;
102 snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_INPUT,
103 &midi_capture_ops);
104 stream = &rmidi->streams[SNDRV_RAWMIDI_STREAM_INPUT];
105
106 /* Set port names for MIDI input. */
107 list_for_each_entry(subs, &stream->substreams, list) {
108 /* TODO: support virtual MIDI ports. */
109 if (subs->number < tscm->spec->midi_capture_ports) {
110 /* Hardware MIDI ports. */
111 snprintf(subs->name, sizeof(subs->name),
112 "%s MIDI %d",
113 tscm->card->shortname, subs->number + 1);
114 }
115 }
116
117 rmidi->info_flags |= SNDRV_RAWMIDI_INFO_OUTPUT;
118 snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_OUTPUT,
119 &midi_playback_ops);
120 stream = &rmidi->streams[SNDRV_RAWMIDI_STREAM_OUTPUT];
121
122 /* Set port names for MIDI ourput. */
123 list_for_each_entry(subs, &stream->substreams, list) {
124 if (subs->number < tscm->spec->midi_playback_ports) {
125 /* Hardware MIDI ports only. */
126 snprintf(subs->name, sizeof(subs->name),
127 "%s MIDI %d",
128 tscm->card->shortname, subs->number + 1);
129 }
130 }
131
132 rmidi->info_flags |= SNDRV_RAWMIDI_INFO_DUPLEX;
133
134 return 0;
135}
diff --git a/sound/firewire/tascam/tascam-pcm.c b/sound/firewire/tascam/tascam-pcm.c
new file mode 100644
index 000000000000..380d3db969a5
--- /dev/null
+++ b/sound/firewire/tascam/tascam-pcm.c
@@ -0,0 +1,312 @@
1/*
2 * tascam-pcm.c - a part of driver for TASCAM FireWire series
3 *
4 * Copyright (c) 2015 Takashi Sakamoto
5 *
6 * Licensed under the terms of the GNU General Public License, version 2.
7 */
8
9#include "tascam.h"
10
11static void set_buffer_params(struct snd_pcm_hardware *hw)
12{
13 hw->period_bytes_min = 4 * hw->channels_min;
14 hw->period_bytes_max = hw->period_bytes_min * 2048;
15 hw->buffer_bytes_max = hw->period_bytes_max * 2;
16
17 hw->periods_min = 2;
18 hw->periods_max = UINT_MAX;
19}
20
21static int pcm_init_hw_params(struct snd_tscm *tscm,
22 struct snd_pcm_substream *substream)
23{
24 static const struct snd_pcm_hardware hardware = {
25 .info = SNDRV_PCM_INFO_BATCH |
26 SNDRV_PCM_INFO_BLOCK_TRANSFER |
27 SNDRV_PCM_INFO_INTERLEAVED |
28 SNDRV_PCM_INFO_JOINT_DUPLEX |
29 SNDRV_PCM_INFO_MMAP |
30 SNDRV_PCM_INFO_MMAP_VALID,
31 .rates = SNDRV_PCM_RATE_44100 |
32 SNDRV_PCM_RATE_48000 |
33 SNDRV_PCM_RATE_88200 |
34 SNDRV_PCM_RATE_96000,
35 .rate_min = 44100,
36 .rate_max = 96000,
37 .channels_min = 10,
38 .channels_max = 18,
39 };
40 struct snd_pcm_runtime *runtime = substream->runtime;
41 struct amdtp_stream *stream;
42 unsigned int pcm_channels;
43
44 runtime->hw = hardware;
45
46 if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
47 runtime->hw.formats = SNDRV_PCM_FMTBIT_S32;
48 stream = &tscm->tx_stream;
49 pcm_channels = tscm->spec->pcm_capture_analog_channels;
50 } else {
51 runtime->hw.formats =
52 SNDRV_PCM_FMTBIT_S16 | SNDRV_PCM_FMTBIT_S32;
53 stream = &tscm->rx_stream;
54 pcm_channels = tscm->spec->pcm_playback_analog_channels;
55 }
56
57 if (tscm->spec->has_adat)
58 pcm_channels += 8;
59 if (tscm->spec->has_spdif)
60 pcm_channels += 2;
61 runtime->hw.channels_min = runtime->hw.channels_max = pcm_channels;
62
63 set_buffer_params(&runtime->hw);
64
65 return amdtp_tscm_add_pcm_hw_constraints(stream, runtime);
66}
67
68static int pcm_open(struct snd_pcm_substream *substream)
69{
70 struct snd_tscm *tscm = substream->private_data;
71 enum snd_tscm_clock clock;
72 unsigned int rate;
73 int err;
74
75 err = snd_tscm_stream_lock_try(tscm);
76 if (err < 0)
77 goto end;
78
79 err = pcm_init_hw_params(tscm, substream);
80 if (err < 0)
81 goto err_locked;
82
83 err = snd_tscm_stream_get_clock(tscm, &clock);
84 if (clock != SND_TSCM_CLOCK_INTERNAL ||
85 amdtp_stream_pcm_running(&tscm->rx_stream) ||
86 amdtp_stream_pcm_running(&tscm->tx_stream)) {
87 err = snd_tscm_stream_get_rate(tscm, &rate);
88 if (err < 0)
89 goto err_locked;
90 substream->runtime->hw.rate_min = rate;
91 substream->runtime->hw.rate_max = rate;
92 }
93
94 snd_pcm_set_sync(substream);
95end:
96 return err;
97err_locked:
98 snd_tscm_stream_lock_release(tscm);
99 return err;
100}
101
102static int pcm_close(struct snd_pcm_substream *substream)
103{
104 struct snd_tscm *tscm = substream->private_data;
105
106 snd_tscm_stream_lock_release(tscm);
107
108 return 0;
109}
110
111static int pcm_capture_hw_params(struct snd_pcm_substream *substream,
112 struct snd_pcm_hw_params *hw_params)
113{
114 struct snd_tscm *tscm = substream->private_data;
115 int err;
116
117 err = snd_pcm_lib_alloc_vmalloc_buffer(substream,
118 params_buffer_bytes(hw_params));
119 if (err < 0)
120 return err;
121
122 if (substream->runtime->status->state == SNDRV_PCM_STATE_OPEN) {
123 mutex_lock(&tscm->mutex);
124 tscm->substreams_counter++;
125 mutex_unlock(&tscm->mutex);
126 }
127
128 amdtp_tscm_set_pcm_format(&tscm->tx_stream, params_format(hw_params));
129
130 return 0;
131}
132
133static int pcm_playback_hw_params(struct snd_pcm_substream *substream,
134 struct snd_pcm_hw_params *hw_params)
135{
136 struct snd_tscm *tscm = substream->private_data;
137 int err;
138
139 err = snd_pcm_lib_alloc_vmalloc_buffer(substream,
140 params_buffer_bytes(hw_params));
141 if (err < 0)
142 return err;
143
144 if (substream->runtime->status->state == SNDRV_PCM_STATE_OPEN) {
145 mutex_lock(&tscm->mutex);
146 tscm->substreams_counter++;
147 mutex_unlock(&tscm->mutex);
148 }
149
150 amdtp_tscm_set_pcm_format(&tscm->rx_stream, params_format(hw_params));
151
152 return 0;
153}
154
155static int pcm_capture_hw_free(struct snd_pcm_substream *substream)
156{
157 struct snd_tscm *tscm = substream->private_data;
158
159 mutex_lock(&tscm->mutex);
160
161 if (substream->runtime->status->state != SNDRV_PCM_STATE_OPEN)
162 tscm->substreams_counter--;
163
164 snd_tscm_stream_stop_duplex(tscm);
165
166 mutex_unlock(&tscm->mutex);
167
168 return snd_pcm_lib_free_vmalloc_buffer(substream);
169}
170
171static int pcm_playback_hw_free(struct snd_pcm_substream *substream)
172{
173 struct snd_tscm *tscm = substream->private_data;
174
175 mutex_lock(&tscm->mutex);
176
177 if (substream->runtime->status->state != SNDRV_PCM_STATE_OPEN)
178 tscm->substreams_counter--;
179
180 snd_tscm_stream_stop_duplex(tscm);
181
182 mutex_unlock(&tscm->mutex);
183
184 return snd_pcm_lib_free_vmalloc_buffer(substream);
185}
186
187static int pcm_capture_prepare(struct snd_pcm_substream *substream)
188{
189 struct snd_tscm *tscm = substream->private_data;
190 struct snd_pcm_runtime *runtime = substream->runtime;
191 int err;
192
193 mutex_lock(&tscm->mutex);
194
195 err = snd_tscm_stream_start_duplex(tscm, runtime->rate);
196 if (err >= 0)
197 amdtp_stream_pcm_prepare(&tscm->tx_stream);
198
199 mutex_unlock(&tscm->mutex);
200
201 return err;
202}
203
204static int pcm_playback_prepare(struct snd_pcm_substream *substream)
205{
206 struct snd_tscm *tscm = substream->private_data;
207 struct snd_pcm_runtime *runtime = substream->runtime;
208 int err;
209
210 mutex_lock(&tscm->mutex);
211
212 err = snd_tscm_stream_start_duplex(tscm, runtime->rate);
213 if (err >= 0)
214 amdtp_stream_pcm_prepare(&tscm->rx_stream);
215
216 mutex_unlock(&tscm->mutex);
217
218 return err;
219}
220
221static int pcm_capture_trigger(struct snd_pcm_substream *substream, int cmd)
222{
223 struct snd_tscm *tscm = substream->private_data;
224
225 switch (cmd) {
226 case SNDRV_PCM_TRIGGER_START:
227 amdtp_stream_pcm_trigger(&tscm->tx_stream, substream);
228 break;
229 case SNDRV_PCM_TRIGGER_STOP:
230 amdtp_stream_pcm_trigger(&tscm->tx_stream, NULL);
231 break;
232 default:
233 return -EINVAL;
234 }
235
236 return 0;
237}
238
239static int pcm_playback_trigger(struct snd_pcm_substream *substream, int cmd)
240{
241 struct snd_tscm *tscm = substream->private_data;
242
243 switch (cmd) {
244 case SNDRV_PCM_TRIGGER_START:
245 amdtp_stream_pcm_trigger(&tscm->rx_stream, substream);
246 break;
247 case SNDRV_PCM_TRIGGER_STOP:
248 amdtp_stream_pcm_trigger(&tscm->rx_stream, NULL);
249 break;
250 default:
251 return -EINVAL;
252 }
253
254 return 0;
255}
256
257static snd_pcm_uframes_t pcm_capture_pointer(struct snd_pcm_substream *sbstrm)
258{
259 struct snd_tscm *tscm = sbstrm->private_data;
260
261 return amdtp_stream_pcm_pointer(&tscm->tx_stream);
262}
263
264static snd_pcm_uframes_t pcm_playback_pointer(struct snd_pcm_substream *sbstrm)
265{
266 struct snd_tscm *tscm = sbstrm->private_data;
267
268 return amdtp_stream_pcm_pointer(&tscm->rx_stream);
269}
270
271static struct snd_pcm_ops pcm_capture_ops = {
272 .open = pcm_open,
273 .close = pcm_close,
274 .ioctl = snd_pcm_lib_ioctl,
275 .hw_params = pcm_capture_hw_params,
276 .hw_free = pcm_capture_hw_free,
277 .prepare = pcm_capture_prepare,
278 .trigger = pcm_capture_trigger,
279 .pointer = pcm_capture_pointer,
280 .page = snd_pcm_lib_get_vmalloc_page,
281};
282
283static struct snd_pcm_ops pcm_playback_ops = {
284 .open = pcm_open,
285 .close = pcm_close,
286 .ioctl = snd_pcm_lib_ioctl,
287 .hw_params = pcm_playback_hw_params,
288 .hw_free = pcm_playback_hw_free,
289 .prepare = pcm_playback_prepare,
290 .trigger = pcm_playback_trigger,
291 .pointer = pcm_playback_pointer,
292 .page = snd_pcm_lib_get_vmalloc_page,
293 .mmap = snd_pcm_lib_mmap_vmalloc,
294};
295
296int snd_tscm_create_pcm_devices(struct snd_tscm *tscm)
297{
298 struct snd_pcm *pcm;
299 int err;
300
301 err = snd_pcm_new(tscm->card, tscm->card->driver, 0, 1, 1, &pcm);
302 if (err < 0)
303 return err;
304
305 pcm->private_data = tscm;
306 snprintf(pcm->name, sizeof(pcm->name),
307 "%s PCM", tscm->card->shortname);
308 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &pcm_playback_ops);
309 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &pcm_capture_ops);
310
311 return 0;
312}
diff --git a/sound/firewire/tascam/tascam-proc.c b/sound/firewire/tascam/tascam-proc.c
new file mode 100644
index 000000000000..bfd4a4c06914
--- /dev/null
+++ b/sound/firewire/tascam/tascam-proc.c
@@ -0,0 +1,88 @@
1/*
2 * tascam-proc.h - a part of driver for TASCAM FireWire series
3 *
4 * Copyright (c) 2015 Takashi Sakamoto
5 *
6 * Licensed under the terms of the GNU General Public License, version 2.
7 */
8
9#include "./tascam.h"
10
11static void proc_read_firmware(struct snd_info_entry *entry,
12 struct snd_info_buffer *buffer)
13{
14 struct snd_tscm *tscm = entry->private_data;
15 __be32 data;
16 unsigned int reg, fpga, arm, hw;
17 int err;
18
19 err = snd_fw_transaction(tscm->unit, TCODE_READ_QUADLET_REQUEST,
20 TSCM_ADDR_BASE + TSCM_OFFSET_FIRMWARE_REGISTER,
21 &data, sizeof(data), 0);
22 if (err < 0)
23 return;
24 reg = be32_to_cpu(data);
25
26 err = snd_fw_transaction(tscm->unit, TCODE_READ_QUADLET_REQUEST,
27 TSCM_ADDR_BASE + TSCM_OFFSET_FIRMWARE_FPGA,
28 &data, sizeof(data), 0);
29 if (err < 0)
30 return;
31 fpga = be32_to_cpu(data);
32
33 err = snd_fw_transaction(tscm->unit, TCODE_READ_QUADLET_REQUEST,
34 TSCM_ADDR_BASE + TSCM_OFFSET_FIRMWARE_ARM,
35 &data, sizeof(data), 0);
36 if (err < 0)
37 return;
38 arm = be32_to_cpu(data);
39
40 err = snd_fw_transaction(tscm->unit, TCODE_READ_QUADLET_REQUEST,
41 TSCM_ADDR_BASE + TSCM_OFFSET_FIRMWARE_HW,
42 &data, sizeof(data), 0);
43 if (err < 0)
44 return;
45 hw = be32_to_cpu(data);
46
47 snd_iprintf(buffer, "Register: %d (0x%08x)\n", reg & 0xffff, reg);
48 snd_iprintf(buffer, "FPGA: %d (0x%08x)\n", fpga & 0xffff, fpga);
49 snd_iprintf(buffer, "ARM: %d (0x%08x)\n", arm & 0xffff, arm);
50 snd_iprintf(buffer, "Hardware: %d (0x%08x)\n", hw >> 16, hw);
51}
52
53static void add_node(struct snd_tscm *tscm, struct snd_info_entry *root,
54 const char *name,
55 void (*op)(struct snd_info_entry *e,
56 struct snd_info_buffer *b))
57{
58 struct snd_info_entry *entry;
59
60 entry = snd_info_create_card_entry(tscm->card, name, root);
61 if (entry == NULL)
62 return;
63
64 snd_info_set_text_ops(entry, tscm, op);
65 if (snd_info_register(entry) < 0)
66 snd_info_free_entry(entry);
67}
68
69void snd_tscm_proc_init(struct snd_tscm *tscm)
70{
71 struct snd_info_entry *root;
72
73 /*
74 * All nodes are automatically removed at snd_card_disconnect(),
75 * by following to link list.
76 */
77 root = snd_info_create_card_entry(tscm->card, "firewire",
78 tscm->card->proc_root);
79 if (root == NULL)
80 return;
81 root->mode = S_IFDIR | S_IRUGO | S_IXUGO;
82 if (snd_info_register(root) < 0) {
83 snd_info_free_entry(root);
84 return;
85 }
86
87 add_node(tscm, root, "firmware", proc_read_firmware);
88}
diff --git a/sound/firewire/tascam/tascam-stream.c b/sound/firewire/tascam/tascam-stream.c
new file mode 100644
index 000000000000..0e6dd5c61f53
--- /dev/null
+++ b/sound/firewire/tascam/tascam-stream.c
@@ -0,0 +1,496 @@
1/*
2 * tascam-stream.c - a part of driver for TASCAM FireWire series
3 *
4 * Copyright (c) 2015 Takashi Sakamoto
5 *
6 * Licensed under the terms of the GNU General Public License, version 2.
7 */
8
9#include <linux/delay.h>
10#include "tascam.h"
11
12#define CALLBACK_TIMEOUT 500
13
14static int get_clock(struct snd_tscm *tscm, u32 *data)
15{
16 __be32 reg;
17 int err;
18
19 err = snd_fw_transaction(tscm->unit, TCODE_READ_QUADLET_REQUEST,
20 TSCM_ADDR_BASE + TSCM_OFFSET_CLOCK_STATUS,
21 &reg, sizeof(reg), 0);
22 if (err >= 0)
23 *data = be32_to_cpu(reg);
24
25 return err;
26}
27
28static int set_clock(struct snd_tscm *tscm, unsigned int rate,
29 enum snd_tscm_clock clock)
30{
31 u32 data;
32 __be32 reg;
33 int err;
34
35 err = get_clock(tscm, &data);
36 if (err < 0)
37 return err;
38 data &= 0x0000ffff;
39
40 if (rate > 0) {
41 data &= 0x000000ff;
42 /* Base rate. */
43 if ((rate % 44100) == 0) {
44 data |= 0x00000100;
45 /* Multiplier. */
46 if (rate / 44100 == 2)
47 data |= 0x00008000;
48 } else if ((rate % 48000) == 0) {
49 data |= 0x00000200;
50 /* Multiplier. */
51 if (rate / 48000 == 2)
52 data |= 0x00008000;
53 } else {
54 return -EAGAIN;
55 }
56 }
57
58 if (clock != INT_MAX) {
59 data &= 0x0000ff00;
60 data |= clock + 1;
61 }
62
63 reg = cpu_to_be32(data);
64
65 err = snd_fw_transaction(tscm->unit, TCODE_WRITE_QUADLET_REQUEST,
66 TSCM_ADDR_BASE + TSCM_OFFSET_CLOCK_STATUS,
67 &reg, sizeof(reg), 0);
68 if (err < 0)
69 return err;
70
71 if (data & 0x00008000)
72 reg = cpu_to_be32(0x0000001a);
73 else
74 reg = cpu_to_be32(0x0000000d);
75
76 return snd_fw_transaction(tscm->unit, TCODE_WRITE_QUADLET_REQUEST,
77 TSCM_ADDR_BASE + TSCM_OFFSET_MULTIPLEX_MODE,
78 &reg, sizeof(reg), 0);
79}
80
81int snd_tscm_stream_get_rate(struct snd_tscm *tscm, unsigned int *rate)
82{
83 u32 data = 0x0;
84 unsigned int trials = 0;
85 int err;
86
87 while (data == 0x0 || trials++ < 5) {
88 err = get_clock(tscm, &data);
89 if (err < 0)
90 return err;
91
92 data = (data & 0xff000000) >> 24;
93 }
94
95 /* Check base rate. */
96 if ((data & 0x0f) == 0x01)
97 *rate = 44100;
98 else if ((data & 0x0f) == 0x02)
99 *rate = 48000;
100 else
101 return -EAGAIN;
102
103 /* Check multiplier. */
104 if ((data & 0xf0) == 0x80)
105 *rate *= 2;
106 else if ((data & 0xf0) != 0x00)
107 return -EAGAIN;
108
109 return err;
110}
111
112int snd_tscm_stream_get_clock(struct snd_tscm *tscm, enum snd_tscm_clock *clock)
113{
114 u32 data;
115 int err;
116
117 err = get_clock(tscm, &data);
118 if (err < 0)
119 return err;
120
121 *clock = ((data & 0x00ff0000) >> 16) - 1;
122 if (*clock < 0 || *clock > SND_TSCM_CLOCK_ADAT)
123 return -EIO;
124
125 return 0;
126}
127
128static int enable_data_channels(struct snd_tscm *tscm)
129{
130 __be32 reg;
131 u32 data;
132 unsigned int i;
133 int err;
134
135 data = 0;
136 for (i = 0; i < tscm->spec->pcm_capture_analog_channels; ++i)
137 data |= BIT(i);
138 if (tscm->spec->has_adat)
139 data |= 0x0000ff00;
140 if (tscm->spec->has_spdif)
141 data |= 0x00030000;
142
143 reg = cpu_to_be32(data);
144 err = snd_fw_transaction(tscm->unit, TCODE_WRITE_QUADLET_REQUEST,
145 TSCM_ADDR_BASE + TSCM_OFFSET_TX_PCM_CHANNELS,
146 &reg, sizeof(reg), 0);
147 if (err < 0)
148 return err;
149
150 data = 0;
151 for (i = 0; i < tscm->spec->pcm_playback_analog_channels; ++i)
152 data |= BIT(i);
153 if (tscm->spec->has_adat)
154 data |= 0x0000ff00;
155 if (tscm->spec->has_spdif)
156 data |= 0x00030000;
157
158 reg = cpu_to_be32(data);
159 return snd_fw_transaction(tscm->unit, TCODE_WRITE_QUADLET_REQUEST,
160 TSCM_ADDR_BASE + TSCM_OFFSET_RX_PCM_CHANNELS,
161 &reg, sizeof(reg), 0);
162}
163
164static int set_stream_formats(struct snd_tscm *tscm, unsigned int rate)
165{
166 __be32 reg;
167 int err;
168
169 /* Set an option for unknown purpose. */
170 reg = cpu_to_be32(0x00200000);
171 err = snd_fw_transaction(tscm->unit, TCODE_WRITE_QUADLET_REQUEST,
172 TSCM_ADDR_BASE + TSCM_OFFSET_SET_OPTION,
173 &reg, sizeof(reg), 0);
174 if (err < 0)
175 return err;
176
177 err = enable_data_channels(tscm);
178 if (err < 0)
179 return err;
180
181 return set_clock(tscm, rate, INT_MAX);
182}
183
184static void finish_session(struct snd_tscm *tscm)
185{
186 __be32 reg;
187
188 reg = 0;
189 snd_fw_transaction(tscm->unit, TCODE_WRITE_QUADLET_REQUEST,
190 TSCM_ADDR_BASE + TSCM_OFFSET_START_STREAMING,
191 &reg, sizeof(reg), 0);
192
193 reg = 0;
194 snd_fw_transaction(tscm->unit, TCODE_WRITE_QUADLET_REQUEST,
195 TSCM_ADDR_BASE + TSCM_OFFSET_ISOC_RX_ON,
196 &reg, sizeof(reg), 0);
197
198}
199
200static int begin_session(struct snd_tscm *tscm)
201{
202 __be32 reg;
203 int err;
204
205 reg = cpu_to_be32(0x00000001);
206 err = snd_fw_transaction(tscm->unit, TCODE_WRITE_QUADLET_REQUEST,
207 TSCM_ADDR_BASE + TSCM_OFFSET_START_STREAMING,
208 &reg, sizeof(reg), 0);
209 if (err < 0)
210 return err;
211
212 reg = cpu_to_be32(0x00000001);
213 err = snd_fw_transaction(tscm->unit, TCODE_WRITE_QUADLET_REQUEST,
214 TSCM_ADDR_BASE + TSCM_OFFSET_ISOC_RX_ON,
215 &reg, sizeof(reg), 0);
216 if (err < 0)
217 return err;
218
219 /* Set an option for unknown purpose. */
220 reg = cpu_to_be32(0x00002000);
221 err = snd_fw_transaction(tscm->unit, TCODE_WRITE_QUADLET_REQUEST,
222 TSCM_ADDR_BASE + TSCM_OFFSET_SET_OPTION,
223 &reg, sizeof(reg), 0);
224 if (err < 0)
225 return err;
226
227 /* Start multiplexing PCM samples on packets. */
228 reg = cpu_to_be32(0x00000001);
229 return snd_fw_transaction(tscm->unit,
230 TCODE_WRITE_QUADLET_REQUEST,
231 TSCM_ADDR_BASE + TSCM_OFFSET_ISOC_TX_ON,
232 &reg, sizeof(reg), 0);
233}
234
235static void release_resources(struct snd_tscm *tscm)
236{
237 __be32 reg;
238
239 /* Unregister channels. */
240 reg = cpu_to_be32(0x00000000);
241 snd_fw_transaction(tscm->unit, TCODE_WRITE_QUADLET_REQUEST,
242 TSCM_ADDR_BASE + TSCM_OFFSET_ISOC_TX_CH,
243 &reg, sizeof(reg), 0);
244 reg = cpu_to_be32(0x00000000);
245 snd_fw_transaction(tscm->unit, TCODE_WRITE_QUADLET_REQUEST,
246 TSCM_ADDR_BASE + TSCM_OFFSET_UNKNOWN,
247 &reg, sizeof(reg), 0);
248 reg = cpu_to_be32(0x00000000);
249 snd_fw_transaction(tscm->unit, TCODE_WRITE_QUADLET_REQUEST,
250 TSCM_ADDR_BASE + TSCM_OFFSET_ISOC_RX_CH,
251 &reg, sizeof(reg), 0);
252
253 /* Release isochronous resources. */
254 fw_iso_resources_free(&tscm->tx_resources);
255 fw_iso_resources_free(&tscm->rx_resources);
256}
257
258static int keep_resources(struct snd_tscm *tscm, unsigned int rate)
259{
260 __be32 reg;
261 int err;
262
263 /* Keep resources for in-stream. */
264 err = amdtp_tscm_set_parameters(&tscm->tx_stream, rate);
265 if (err < 0)
266 return err;
267 err = fw_iso_resources_allocate(&tscm->tx_resources,
268 amdtp_stream_get_max_payload(&tscm->tx_stream),
269 fw_parent_device(tscm->unit)->max_speed);
270 if (err < 0)
271 goto error;
272
273 /* Keep resources for out-stream. */
274 err = amdtp_tscm_set_parameters(&tscm->rx_stream, rate);
275 if (err < 0)
276 return err;
277 err = fw_iso_resources_allocate(&tscm->rx_resources,
278 amdtp_stream_get_max_payload(&tscm->rx_stream),
279 fw_parent_device(tscm->unit)->max_speed);
280 if (err < 0)
281 return err;
282
283 /* Register the isochronous channel for transmitting stream. */
284 reg = cpu_to_be32(tscm->tx_resources.channel);
285 err = snd_fw_transaction(tscm->unit, TCODE_WRITE_QUADLET_REQUEST,
286 TSCM_ADDR_BASE + TSCM_OFFSET_ISOC_TX_CH,
287 &reg, sizeof(reg), 0);
288 if (err < 0)
289 goto error;
290
291 /* Unknown */
292 reg = cpu_to_be32(0x00000002);
293 err = snd_fw_transaction(tscm->unit, TCODE_WRITE_QUADLET_REQUEST,
294 TSCM_ADDR_BASE + TSCM_OFFSET_UNKNOWN,
295 &reg, sizeof(reg), 0);
296 if (err < 0)
297 goto error;
298
299 /* Register the isochronous channel for receiving stream. */
300 reg = cpu_to_be32(tscm->rx_resources.channel);
301 err = snd_fw_transaction(tscm->unit, TCODE_WRITE_QUADLET_REQUEST,
302 TSCM_ADDR_BASE + TSCM_OFFSET_ISOC_RX_CH,
303 &reg, sizeof(reg), 0);
304 if (err < 0)
305 goto error;
306
307 return 0;
308error:
309 release_resources(tscm);
310 return err;
311}
312
313int snd_tscm_stream_init_duplex(struct snd_tscm *tscm)
314{
315 unsigned int pcm_channels;
316 int err;
317
318 /* For out-stream. */
319 err = fw_iso_resources_init(&tscm->rx_resources, tscm->unit);
320 if (err < 0)
321 return err;
322 pcm_channels = tscm->spec->pcm_playback_analog_channels;
323 if (tscm->spec->has_adat)
324 pcm_channels += 8;
325 if (tscm->spec->has_spdif)
326 pcm_channels += 2;
327 err = amdtp_tscm_init(&tscm->rx_stream, tscm->unit, AMDTP_OUT_STREAM,
328 pcm_channels);
329 if (err < 0)
330 return err;
331
332 /* For in-stream. */
333 err = fw_iso_resources_init(&tscm->tx_resources, tscm->unit);
334 if (err < 0)
335 return err;
336 pcm_channels = tscm->spec->pcm_capture_analog_channels;
337 if (tscm->spec->has_adat)
338 pcm_channels += 8;
339 if (tscm->spec->has_spdif)
340 pcm_channels += 2;
341 err = amdtp_tscm_init(&tscm->tx_stream, tscm->unit, AMDTP_IN_STREAM,
342 pcm_channels);
343 if (err < 0)
344 amdtp_stream_destroy(&tscm->rx_stream);
345
346 return 0;
347}
348
349/* At bus reset, streaming is stopped and some registers are clear. */
350void snd_tscm_stream_update_duplex(struct snd_tscm *tscm)
351{
352 amdtp_stream_pcm_abort(&tscm->tx_stream);
353 amdtp_stream_stop(&tscm->tx_stream);
354
355 amdtp_stream_pcm_abort(&tscm->rx_stream);
356 amdtp_stream_stop(&tscm->rx_stream);
357}
358
359/*
360 * This function should be called before starting streams or after stopping
361 * streams.
362 */
363void snd_tscm_stream_destroy_duplex(struct snd_tscm *tscm)
364{
365 amdtp_stream_destroy(&tscm->rx_stream);
366 amdtp_stream_destroy(&tscm->tx_stream);
367
368 fw_iso_resources_destroy(&tscm->rx_resources);
369 fw_iso_resources_destroy(&tscm->tx_resources);
370}
371
372int snd_tscm_stream_start_duplex(struct snd_tscm *tscm, unsigned int rate)
373{
374 unsigned int curr_rate;
375 int err;
376
377 if (tscm->substreams_counter == 0)
378 return 0;
379
380 err = snd_tscm_stream_get_rate(tscm, &curr_rate);
381 if (err < 0)
382 return err;
383 if (curr_rate != rate ||
384 amdtp_streaming_error(&tscm->tx_stream) ||
385 amdtp_streaming_error(&tscm->rx_stream)) {
386 finish_session(tscm);
387
388 amdtp_stream_stop(&tscm->tx_stream);
389 amdtp_stream_stop(&tscm->rx_stream);
390
391 release_resources(tscm);
392 }
393
394 if (!amdtp_stream_running(&tscm->tx_stream)) {
395 amdtp_stream_set_sync(CIP_SYNC_TO_DEVICE,
396 &tscm->tx_stream, &tscm->rx_stream);
397 err = keep_resources(tscm, rate);
398 if (err < 0)
399 goto error;
400
401 err = set_stream_formats(tscm, rate);
402 if (err < 0)
403 goto error;
404
405 err = begin_session(tscm);
406 if (err < 0)
407 goto error;
408
409 err = amdtp_stream_start(&tscm->tx_stream,
410 tscm->tx_resources.channel,
411 fw_parent_device(tscm->unit)->max_speed);
412 if (err < 0)
413 goto error;
414
415 if (!amdtp_stream_wait_callback(&tscm->tx_stream,
416 CALLBACK_TIMEOUT)) {
417 err = -ETIMEDOUT;
418 goto error;
419 }
420 }
421
422 if (!amdtp_stream_running(&tscm->rx_stream)) {
423 err = amdtp_stream_start(&tscm->rx_stream,
424 tscm->rx_resources.channel,
425 fw_parent_device(tscm->unit)->max_speed);
426 if (err < 0)
427 goto error;
428
429 if (!amdtp_stream_wait_callback(&tscm->rx_stream,
430 CALLBACK_TIMEOUT)) {
431 err = -ETIMEDOUT;
432 goto error;
433 }
434 }
435
436 return 0;
437error:
438 amdtp_stream_stop(&tscm->tx_stream);
439 amdtp_stream_stop(&tscm->rx_stream);
440
441 finish_session(tscm);
442 release_resources(tscm);
443
444 return err;
445}
446
447void snd_tscm_stream_stop_duplex(struct snd_tscm *tscm)
448{
449 if (tscm->substreams_counter > 0)
450 return;
451
452 amdtp_stream_stop(&tscm->tx_stream);
453 amdtp_stream_stop(&tscm->rx_stream);
454
455 finish_session(tscm);
456 release_resources(tscm);
457}
458
459void snd_tscm_stream_lock_changed(struct snd_tscm *tscm)
460{
461 tscm->dev_lock_changed = true;
462 wake_up(&tscm->hwdep_wait);
463}
464
465int snd_tscm_stream_lock_try(struct snd_tscm *tscm)
466{
467 int err;
468
469 spin_lock_irq(&tscm->lock);
470
471 /* user land lock this */
472 if (tscm->dev_lock_count < 0) {
473 err = -EBUSY;
474 goto end;
475 }
476
477 /* this is the first time */
478 if (tscm->dev_lock_count++ == 0)
479 snd_tscm_stream_lock_changed(tscm);
480 err = 0;
481end:
482 spin_unlock_irq(&tscm->lock);
483 return err;
484}
485
486void snd_tscm_stream_lock_release(struct snd_tscm *tscm)
487{
488 spin_lock_irq(&tscm->lock);
489
490 if (WARN_ON(tscm->dev_lock_count <= 0))
491 goto end;
492 if (--tscm->dev_lock_count == 0)
493 snd_tscm_stream_lock_changed(tscm);
494end:
495 spin_unlock_irq(&tscm->lock);
496}
diff --git a/sound/firewire/tascam/tascam-transaction.c b/sound/firewire/tascam/tascam-transaction.c
new file mode 100644
index 000000000000..904ce0329fa1
--- /dev/null
+++ b/sound/firewire/tascam/tascam-transaction.c
@@ -0,0 +1,302 @@
1/*
2 * tascam-transaction.c - a part of driver for TASCAM FireWire series
3 *
4 * Copyright (c) 2015 Takashi Sakamoto
5 *
6 * Licensed under the terms of the GNU General Public License, version 2.
7 */
8
9#include "tascam.h"
10
11/*
12 * When return minus value, given argument is not MIDI status.
13 * When return 0, given argument is a beginning of system exclusive.
14 * When return the others, given argument is MIDI data.
15 */
16static inline int calculate_message_bytes(u8 status)
17{
18 switch (status) {
19 case 0xf6: /* Tune request. */
20 case 0xf8: /* Timing clock. */
21 case 0xfa: /* Start. */
22 case 0xfb: /* Continue. */
23 case 0xfc: /* Stop. */
24 case 0xfe: /* Active sensing. */
25 case 0xff: /* System reset. */
26 return 1;
27 case 0xf1: /* MIDI time code quarter frame. */
28 case 0xf3: /* Song select. */
29 return 2;
30 case 0xf2: /* Song position pointer. */
31 return 3;
32 case 0xf0: /* Exclusive. */
33 return 0;
34 case 0xf7: /* End of exclusive. */
35 break;
36 case 0xf4: /* Undefined. */
37 case 0xf5: /* Undefined. */
38 case 0xf9: /* Undefined. */
39 case 0xfd: /* Undefined. */
40 break;
41 default:
42 switch (status & 0xf0) {
43 case 0x80: /* Note on. */
44 case 0x90: /* Note off. */
45 case 0xa0: /* Polyphonic key pressure. */
46 case 0xb0: /* Control change and Mode change. */
47 case 0xe0: /* Pitch bend change. */
48 return 3;
49 case 0xc0: /* Program change. */
50 case 0xd0: /* Channel pressure. */
51 return 2;
52 default:
53 break;
54 }
55 break;
56 }
57
58 return -EINVAL;
59}
60
61static int fill_message(struct snd_rawmidi_substream *substream, u8 *buf)
62{
63 struct snd_tscm *tscm = substream->rmidi->private_data;
64 unsigned int port = substream->number;
65 int i, len, consume;
66 u8 *label, *msg;
67 u8 status;
68
69 /* The first byte is used for label, the rest for MIDI bytes. */
70 label = buf;
71 msg = buf + 1;
72
73 consume = snd_rawmidi_transmit_peek(substream, msg, 3);
74 if (consume == 0)
75 return 0;
76
77 /* On exclusive message. */
78 if (tscm->on_sysex[port]) {
79 /* Seek the end of exclusives. */
80 for (i = 0; i < consume; ++i) {
81 if (msg[i] == 0xf7) {
82 tscm->on_sysex[port] = false;
83 break;
84 }
85 }
86
87 /* At the end of exclusive message, use label 0x07. */
88 if (!tscm->on_sysex[port]) {
89 consume = i + 1;
90 *label = (port << 4) | 0x07;
91 /* During exclusive message, use label 0x04. */
92 } else if (consume == 3) {
93 *label = (port << 4) | 0x04;
94 /* We need to fill whole 3 bytes. Go to next change. */
95 } else {
96 return 0;
97 }
98
99 len = consume;
100 } else {
101 /* The beginning of exclusives. */
102 if (msg[0] == 0xf0) {
103 /* Transfer it in next chance in another condition. */
104 tscm->on_sysex[port] = true;
105 return 0;
106 } else {
107 /* On running-status. */
108 if ((msg[0] & 0x80) != 0x80)
109 status = tscm->running_status[port];
110 else
111 status = msg[0];
112
113 /* Calculate consume bytes. */
114 len = calculate_message_bytes(status);
115 if (len <= 0)
116 return 0;
117
118 /* On running-status. */
119 if ((msg[0] & 0x80) != 0x80) {
120 /* Enough MIDI bytes were not retrieved. */
121 if (consume < len - 1)
122 return 0;
123 consume = len - 1;
124
125 msg[2] = msg[1];
126 msg[1] = msg[0];
127 msg[0] = tscm->running_status[port];
128 } else {
129 /* Enough MIDI bytes were not retrieved. */
130 if (consume < len)
131 return 0;
132 consume = len;
133
134 tscm->running_status[port] = msg[0];
135 }
136 }
137
138 *label = (port << 4) | (msg[0] >> 4);
139 }
140
141 if (len > 0 && len < 3)
142 memset(msg + len, 0, 3 - len);
143
144 return consume;
145}
146
147static void handle_midi_tx(struct fw_card *card, struct fw_request *request,
148 int tcode, int destination, int source,
149 int generation, unsigned long long offset,
150 void *data, size_t length, void *callback_data)
151{
152 struct snd_tscm *tscm = callback_data;
153 u32 *buf = (u32 *)data;
154 unsigned int messages;
155 unsigned int i;
156 unsigned int port;
157 struct snd_rawmidi_substream *substream;
158 u8 *b;
159 int bytes;
160
161 if (offset != tscm->async_handler.offset)
162 goto end;
163
164 messages = length / 8;
165 for (i = 0; i < messages; i++) {
166 b = (u8 *)(buf + i * 2);
167
168 port = b[0] >> 4;
169 /* TODO: support virtual MIDI ports. */
170 if (port >= tscm->spec->midi_capture_ports)
171 goto end;
172
173 /* Assume the message length. */
174 bytes = calculate_message_bytes(b[1]);
175 /* On MIDI data or exclusives. */
176 if (bytes <= 0) {
177 /* Seek the end of exclusives. */
178 for (bytes = 1; bytes < 4; bytes++) {
179 if (b[bytes] == 0xf7)
180 break;
181 }
182 if (bytes == 4)
183 bytes = 3;
184 }
185
186 substream = ACCESS_ONCE(tscm->tx_midi_substreams[port]);
187 if (substream != NULL)
188 snd_rawmidi_receive(substream, b + 1, bytes);
189 }
190end:
191 fw_send_response(card, request, RCODE_COMPLETE);
192}
193
194int snd_tscm_transaction_register(struct snd_tscm *tscm)
195{
196 static const struct fw_address_region resp_register_region = {
197 .start = 0xffffe0000000ull,
198 .end = 0xffffe000ffffull,
199 };
200 unsigned int i;
201 int err;
202
203 /*
204 * Usually, two quadlets are transferred by one transaction. The first
205 * quadlet has MIDI messages, the rest includes timestamp.
206 * Sometimes, 8 set of the data is transferred by a block transaction.
207 */
208 tscm->async_handler.length = 8 * 8;
209 tscm->async_handler.address_callback = handle_midi_tx;
210 tscm->async_handler.callback_data = tscm;
211
212 err = fw_core_add_address_handler(&tscm->async_handler,
213 &resp_register_region);
214 if (err < 0)
215 return err;
216
217 err = snd_tscm_transaction_reregister(tscm);
218 if (err < 0)
219 goto error;
220
221 for (i = 0; i < TSCM_MIDI_OUT_PORT_MAX; i++) {
222 err = snd_fw_async_midi_port_init(
223 &tscm->out_ports[i], tscm->unit,
224 TSCM_ADDR_BASE + TSCM_OFFSET_MIDI_RX_QUAD,
225 4, fill_message);
226 if (err < 0)
227 goto error;
228 }
229
230 return err;
231error:
232 fw_core_remove_address_handler(&tscm->async_handler);
233 return err;
234}
235
236/* At bus reset, these registers are cleared. */
237int snd_tscm_transaction_reregister(struct snd_tscm *tscm)
238{
239 struct fw_device *device = fw_parent_device(tscm->unit);
240 __be32 reg;
241 int err;
242
243 /* Register messaging address. Block transaction is not allowed. */
244 reg = cpu_to_be32((device->card->node_id << 16) |
245 (tscm->async_handler.offset >> 32));
246 err = snd_fw_transaction(tscm->unit, TCODE_WRITE_QUADLET_REQUEST,
247 TSCM_ADDR_BASE + TSCM_OFFSET_MIDI_TX_ADDR_HI,
248 &reg, sizeof(reg), 0);
249 if (err < 0)
250 return err;
251
252 reg = cpu_to_be32(tscm->async_handler.offset);
253 err = snd_fw_transaction(tscm->unit, TCODE_WRITE_QUADLET_REQUEST,
254 TSCM_ADDR_BASE + TSCM_OFFSET_MIDI_TX_ADDR_LO,
255 &reg, sizeof(reg), 0);
256 if (err < 0)
257 return err;
258
259 /* Turn on messaging. */
260 reg = cpu_to_be32(0x00000001);
261 err = snd_fw_transaction(tscm->unit, TCODE_WRITE_QUADLET_REQUEST,
262 TSCM_ADDR_BASE + TSCM_OFFSET_MIDI_TX_ON,
263 &reg, sizeof(reg), 0);
264 if (err < 0)
265 return err;
266
267 /* Turn on FireWire LED. */
268 reg = cpu_to_be32(0x0001008e);
269 return snd_fw_transaction(tscm->unit, TCODE_WRITE_QUADLET_REQUEST,
270 TSCM_ADDR_BASE + TSCM_OFFSET_LED_POWER,
271 &reg, sizeof(reg), 0);
272}
273
274void snd_tscm_transaction_unregister(struct snd_tscm *tscm)
275{
276 __be32 reg;
277 unsigned int i;
278
279 /* Turn off FireWire LED. */
280 reg = cpu_to_be32(0x0000008e);
281 snd_fw_transaction(tscm->unit, TCODE_WRITE_QUADLET_REQUEST,
282 TSCM_ADDR_BASE + TSCM_OFFSET_LED_POWER,
283 &reg, sizeof(reg), 0);
284
285 /* Turn off messaging. */
286 reg = cpu_to_be32(0x00000000);
287 snd_fw_transaction(tscm->unit, TCODE_WRITE_QUADLET_REQUEST,
288 TSCM_ADDR_BASE + TSCM_OFFSET_MIDI_TX_ON,
289 &reg, sizeof(reg), 0);
290
291 /* Unregister the address. */
292 snd_fw_transaction(tscm->unit, TCODE_WRITE_QUADLET_REQUEST,
293 TSCM_ADDR_BASE + TSCM_OFFSET_MIDI_TX_ADDR_HI,
294 &reg, sizeof(reg), 0);
295 snd_fw_transaction(tscm->unit, TCODE_WRITE_QUADLET_REQUEST,
296 TSCM_ADDR_BASE + TSCM_OFFSET_MIDI_TX_ADDR_LO,
297 &reg, sizeof(reg), 0);
298
299 fw_core_remove_address_handler(&tscm->async_handler);
300 for (i = 0; i < TSCM_MIDI_OUT_PORT_MAX; i++)
301 snd_fw_async_midi_port_destroy(&tscm->out_ports[i]);
302}
diff --git a/sound/firewire/tascam/tascam.c b/sound/firewire/tascam/tascam.c
new file mode 100644
index 000000000000..ee0bc1839508
--- /dev/null
+++ b/sound/firewire/tascam/tascam.c
@@ -0,0 +1,209 @@
1/*
2 * tascam.c - a part of driver for TASCAM FireWire series
3 *
4 * Copyright (c) 2015 Takashi Sakamoto
5 *
6 * Licensed under the terms of the GNU General Public License, version 2.
7 */
8
9#include "tascam.h"
10
11MODULE_DESCRIPTION("TASCAM FireWire series Driver");
12MODULE_AUTHOR("Takashi Sakamoto <o-takashi@sakamocchi.jp>");
13MODULE_LICENSE("GPL v2");
14
15static struct snd_tscm_spec model_specs[] = {
16 {
17 .name = "FW-1884",
18 .has_adat = true,
19 .has_spdif = true,
20 .pcm_capture_analog_channels = 8,
21 .pcm_playback_analog_channels = 8,
22 .midi_capture_ports = 4,
23 .midi_playback_ports = 4,
24 .is_controller = true,
25 },
26 {
27 .name = "FW-1082",
28 .has_adat = false,
29 .has_spdif = true,
30 .pcm_capture_analog_channels = 8,
31 .pcm_playback_analog_channels = 2,
32 .midi_capture_ports = 2,
33 .midi_playback_ports = 2,
34 .is_controller = true,
35 },
36 /* FW-1804 may be supported. */
37};
38
39static int identify_model(struct snd_tscm *tscm)
40{
41 struct fw_device *fw_dev = fw_parent_device(tscm->unit);
42 const u32 *config_rom = fw_dev->config_rom;
43 char model[9];
44 unsigned int i;
45 u8 c;
46
47 if (fw_dev->config_rom_length < 30) {
48 dev_err(&tscm->unit->device,
49 "Configuration ROM is too short.\n");
50 return -ENODEV;
51 }
52
53 /* Pick up model name from certain addresses. */
54 for (i = 0; i < 8; i++) {
55 c = config_rom[28 + i / 4] >> (24 - 8 * (i % 4));
56 if (c == '\0')
57 break;
58 model[i] = c;
59 }
60 model[i] = '\0';
61
62 for (i = 0; i < ARRAY_SIZE(model_specs); i++) {
63 if (strcmp(model, model_specs[i].name) == 0) {
64 tscm->spec = &model_specs[i];
65 break;
66 }
67 }
68 if (tscm->spec == NULL)
69 return -ENODEV;
70
71 strcpy(tscm->card->driver, "FW-TASCAM");
72 strcpy(tscm->card->shortname, model);
73 strcpy(tscm->card->mixername, model);
74 snprintf(tscm->card->longname, sizeof(tscm->card->longname),
75 "TASCAM %s, GUID %08x%08x at %s, S%d", model,
76 fw_dev->config_rom[3], fw_dev->config_rom[4],
77 dev_name(&tscm->unit->device), 100 << fw_dev->max_speed);
78
79 return 0;
80}
81
82static void tscm_card_free(struct snd_card *card)
83{
84 struct snd_tscm *tscm = card->private_data;
85
86 snd_tscm_transaction_unregister(tscm);
87 snd_tscm_stream_destroy_duplex(tscm);
88
89 fw_unit_put(tscm->unit);
90
91 mutex_destroy(&tscm->mutex);
92}
93
94static int snd_tscm_probe(struct fw_unit *unit,
95 const struct ieee1394_device_id *entry)
96{
97 struct snd_card *card;
98 struct snd_tscm *tscm;
99 int err;
100
101 /* create card */
102 err = snd_card_new(&unit->device, -1, NULL, THIS_MODULE,
103 sizeof(struct snd_tscm), &card);
104 if (err < 0)
105 return err;
106 card->private_free = tscm_card_free;
107
108 /* initialize myself */
109 tscm = card->private_data;
110 tscm->card = card;
111 tscm->unit = fw_unit_get(unit);
112
113 mutex_init(&tscm->mutex);
114 spin_lock_init(&tscm->lock);
115 init_waitqueue_head(&tscm->hwdep_wait);
116
117 err = identify_model(tscm);
118 if (err < 0)
119 goto error;
120
121 snd_tscm_proc_init(tscm);
122
123 err = snd_tscm_stream_init_duplex(tscm);
124 if (err < 0)
125 goto error;
126
127 err = snd_tscm_create_pcm_devices(tscm);
128 if (err < 0)
129 goto error;
130
131 err = snd_tscm_transaction_register(tscm);
132 if (err < 0)
133 goto error;
134
135 err = snd_tscm_create_midi_devices(tscm);
136 if (err < 0)
137 goto error;
138
139 err = snd_tscm_create_hwdep_device(tscm);
140 if (err < 0)
141 goto error;
142
143 err = snd_card_register(card);
144 if (err < 0)
145 goto error;
146
147 dev_set_drvdata(&unit->device, tscm);
148
149 return err;
150error:
151 snd_card_free(card);
152 return err;
153}
154
155static void snd_tscm_update(struct fw_unit *unit)
156{
157 struct snd_tscm *tscm = dev_get_drvdata(&unit->device);
158
159 snd_tscm_transaction_reregister(tscm);
160
161 mutex_lock(&tscm->mutex);
162 snd_tscm_stream_update_duplex(tscm);
163 mutex_unlock(&tscm->mutex);
164}
165
166static void snd_tscm_remove(struct fw_unit *unit)
167{
168 struct snd_tscm *tscm = dev_get_drvdata(&unit->device);
169
170 /* No need to wait for releasing card object in this context. */
171 snd_card_free_when_closed(tscm->card);
172}
173
174static const struct ieee1394_device_id snd_tscm_id_table[] = {
175 {
176 .match_flags = IEEE1394_MATCH_VENDOR_ID |
177 IEEE1394_MATCH_SPECIFIER_ID,
178 .vendor_id = 0x00022e,
179 .specifier_id = 0x00022e,
180 },
181 /* FE-08 requires reverse-engineering because it just has faders. */
182 {}
183};
184MODULE_DEVICE_TABLE(ieee1394, snd_tscm_id_table);
185
186static struct fw_driver tscm_driver = {
187 .driver = {
188 .owner = THIS_MODULE,
189 .name = "snd-firewire-tascam",
190 .bus = &fw_bus_type,
191 },
192 .probe = snd_tscm_probe,
193 .update = snd_tscm_update,
194 .remove = snd_tscm_remove,
195 .id_table = snd_tscm_id_table,
196};
197
198static int __init snd_tscm_init(void)
199{
200 return driver_register(&tscm_driver.driver);
201}
202
203static void __exit snd_tscm_exit(void)
204{
205 driver_unregister(&tscm_driver.driver);
206}
207
208module_init(snd_tscm_init);
209module_exit(snd_tscm_exit);
diff --git a/sound/firewire/tascam/tascam.h b/sound/firewire/tascam/tascam.h
new file mode 100644
index 000000000000..2d028d2bd3bd
--- /dev/null
+++ b/sound/firewire/tascam/tascam.h
@@ -0,0 +1,147 @@
1/*
2 * tascam.h - a part of driver for TASCAM FireWire series
3 *
4 * Copyright (c) 2015 Takashi Sakamoto
5 *
6 * Licensed under the terms of the GNU General Public License, version 2.
7 */
8
9#ifndef SOUND_TASCAM_H_INCLUDED
10#define SOUND_TASCAM_H_INCLUDED
11
12#include <linux/device.h>
13#include <linux/firewire.h>
14#include <linux/firewire-constants.h>
15#include <linux/module.h>
16#include <linux/mod_devicetable.h>
17#include <linux/mutex.h>
18#include <linux/slab.h>
19#include <linux/compat.h>
20
21#include <sound/core.h>
22#include <sound/initval.h>
23#include <sound/info.h>
24#include <sound/pcm.h>
25#include <sound/pcm_params.h>
26#include <sound/firewire.h>
27#include <sound/hwdep.h>
28#include <sound/rawmidi.h>
29
30#include "../lib.h"
31#include "../amdtp-stream.h"
32#include "../iso-resources.h"
33
34struct snd_tscm_spec {
35 const char *const name;
36 bool has_adat;
37 bool has_spdif;
38 unsigned int pcm_capture_analog_channels;
39 unsigned int pcm_playback_analog_channels;
40 unsigned int midi_capture_ports;
41 unsigned int midi_playback_ports;
42 bool is_controller;
43};
44
45#define TSCM_MIDI_IN_PORT_MAX 4
46#define TSCM_MIDI_OUT_PORT_MAX 4
47
48struct snd_tscm {
49 struct snd_card *card;
50 struct fw_unit *unit;
51
52 struct mutex mutex;
53 spinlock_t lock;
54
55 const struct snd_tscm_spec *spec;
56
57 struct fw_iso_resources tx_resources;
58 struct fw_iso_resources rx_resources;
59 struct amdtp_stream tx_stream;
60 struct amdtp_stream rx_stream;
61 unsigned int substreams_counter;
62
63 int dev_lock_count;
64 bool dev_lock_changed;
65 wait_queue_head_t hwdep_wait;
66
67 /* For MIDI message incoming transactions. */
68 struct fw_address_handler async_handler;
69 struct snd_rawmidi_substream *tx_midi_substreams[TSCM_MIDI_IN_PORT_MAX];
70
71 /* For MIDI message outgoing transactions. */
72 struct snd_fw_async_midi_port out_ports[TSCM_MIDI_OUT_PORT_MAX];
73 u8 running_status[TSCM_MIDI_OUT_PORT_MAX];
74 bool on_sysex[TSCM_MIDI_OUT_PORT_MAX];
75
76 /* For control messages. */
77 struct snd_firewire_tascam_status *status;
78};
79
80#define TSCM_ADDR_BASE 0xffff00000000ull
81
82#define TSCM_OFFSET_FIRMWARE_REGISTER 0x0000
83#define TSCM_OFFSET_FIRMWARE_FPGA 0x0004
84#define TSCM_OFFSET_FIRMWARE_ARM 0x0008
85#define TSCM_OFFSET_FIRMWARE_HW 0x000c
86
87#define TSCM_OFFSET_ISOC_TX_CH 0x0200
88#define TSCM_OFFSET_UNKNOWN 0x0204
89#define TSCM_OFFSET_START_STREAMING 0x0208
90#define TSCM_OFFSET_ISOC_RX_CH 0x020c
91#define TSCM_OFFSET_ISOC_RX_ON 0x0210 /* Little conviction. */
92#define TSCM_OFFSET_TX_PCM_CHANNELS 0x0214
93#define TSCM_OFFSET_RX_PCM_CHANNELS 0x0218
94#define TSCM_OFFSET_MULTIPLEX_MODE 0x021c
95#define TSCM_OFFSET_ISOC_TX_ON 0x0220
96/* Unknown 0x0224 */
97#define TSCM_OFFSET_CLOCK_STATUS 0x0228
98#define TSCM_OFFSET_SET_OPTION 0x022c
99
100#define TSCM_OFFSET_MIDI_TX_ON 0x0300
101#define TSCM_OFFSET_MIDI_TX_ADDR_HI 0x0304
102#define TSCM_OFFSET_MIDI_TX_ADDR_LO 0x0308
103
104#define TSCM_OFFSET_LED_POWER 0x0404
105
106#define TSCM_OFFSET_MIDI_RX_QUAD 0x4000
107
108enum snd_tscm_clock {
109 SND_TSCM_CLOCK_INTERNAL = 0,
110 SND_TSCM_CLOCK_WORD = 1,
111 SND_TSCM_CLOCK_SPDIF = 2,
112 SND_TSCM_CLOCK_ADAT = 3,
113};
114
115int amdtp_tscm_init(struct amdtp_stream *s, struct fw_unit *unit,
116 enum amdtp_stream_direction dir, unsigned int pcm_channels);
117int amdtp_tscm_set_parameters(struct amdtp_stream *s, unsigned int rate);
118int amdtp_tscm_add_pcm_hw_constraints(struct amdtp_stream *s,
119 struct snd_pcm_runtime *runtime);
120void amdtp_tscm_set_pcm_format(struct amdtp_stream *s, snd_pcm_format_t format);
121
122int snd_tscm_stream_get_rate(struct snd_tscm *tscm, unsigned int *rate);
123int snd_tscm_stream_get_clock(struct snd_tscm *tscm,
124 enum snd_tscm_clock *clock);
125int snd_tscm_stream_init_duplex(struct snd_tscm *tscm);
126void snd_tscm_stream_update_duplex(struct snd_tscm *tscm);
127void snd_tscm_stream_destroy_duplex(struct snd_tscm *tscm);
128int snd_tscm_stream_start_duplex(struct snd_tscm *tscm, unsigned int rate);
129void snd_tscm_stream_stop_duplex(struct snd_tscm *tscm);
130
131void snd_tscm_stream_lock_changed(struct snd_tscm *tscm);
132int snd_tscm_stream_lock_try(struct snd_tscm *tscm);
133void snd_tscm_stream_lock_release(struct snd_tscm *tscm);
134
135int snd_tscm_transaction_register(struct snd_tscm *tscm);
136int snd_tscm_transaction_reregister(struct snd_tscm *tscm);
137void snd_tscm_transaction_unregister(struct snd_tscm *tscm);
138
139void snd_tscm_proc_init(struct snd_tscm *tscm);
140
141int snd_tscm_create_pcm_devices(struct snd_tscm *tscm);
142
143int snd_tscm_create_midi_devices(struct snd_tscm *tscm);
144
145int snd_tscm_create_hwdep_device(struct snd_tscm *tscm);
146
147#endif
diff --git a/sound/hda/ext/hdac_ext_stream.c b/sound/hda/ext/hdac_ext_stream.c
index 33ba77dd32f2..cb89ec7c8147 100644
--- a/sound/hda/ext/hdac_ext_stream.c
+++ b/sound/hda/ext/hdac_ext_stream.c
@@ -227,7 +227,7 @@ EXPORT_SYMBOL_GPL(snd_hdac_ext_link_stream_setup);
227void snd_hdac_ext_link_set_stream_id(struct hdac_ext_link *link, 227void snd_hdac_ext_link_set_stream_id(struct hdac_ext_link *link,
228 int stream) 228 int stream)
229{ 229{
230 snd_hdac_updatew(link->ml_addr, AZX_REG_ML_LOSIDV, (1 << stream), 0); 230 snd_hdac_updatew(link->ml_addr, AZX_REG_ML_LOSIDV, (1 << stream), 1 << stream);
231} 231}
232EXPORT_SYMBOL_GPL(snd_hdac_ext_link_set_stream_id); 232EXPORT_SYMBOL_GPL(snd_hdac_ext_link_set_stream_id);
233 233
@@ -385,14 +385,13 @@ void snd_hdac_ext_stream_release(struct hdac_ext_stream *stream, int type)
385 break; 385 break;
386 386
387 case HDAC_EXT_STREAM_TYPE_HOST: 387 case HDAC_EXT_STREAM_TYPE_HOST:
388 if (stream->decoupled) { 388 if (stream->decoupled && !stream->link_locked)
389 snd_hdac_ext_stream_decouple(ebus, stream, false); 389 snd_hdac_ext_stream_decouple(ebus, stream, false);
390 snd_hdac_stream_release(&stream->hstream); 390 snd_hdac_stream_release(&stream->hstream);
391 }
392 break; 391 break;
393 392
394 case HDAC_EXT_STREAM_TYPE_LINK: 393 case HDAC_EXT_STREAM_TYPE_LINK:
395 if (stream->decoupled) 394 if (stream->decoupled && !stream->hstream.opened)
396 snd_hdac_ext_stream_decouple(ebus, stream, false); 395 snd_hdac_ext_stream_decouple(ebus, stream, false);
397 spin_lock_irq(&bus->reg_lock); 396 spin_lock_irq(&bus->reg_lock);
398 stream->link_locked = 0; 397 stream->link_locked = 0;
diff --git a/sound/hda/hda_bus_type.c b/sound/hda/hda_bus_type.c
index 89c2711baaaf..3060e2aee36f 100644
--- a/sound/hda/hda_bus_type.c
+++ b/sound/hda/hda_bus_type.c
@@ -4,6 +4,7 @@
4#include <linux/init.h> 4#include <linux/init.h>
5#include <linux/device.h> 5#include <linux/device.h>
6#include <linux/module.h> 6#include <linux/module.h>
7#include <linux/mod_devicetable.h>
7#include <linux/export.h> 8#include <linux/export.h>
8#include <sound/hdaudio.h> 9#include <sound/hdaudio.h>
9 10
@@ -63,9 +64,21 @@ static int hda_bus_match(struct device *dev, struct device_driver *drv)
63 return 1; 64 return 1;
64} 65}
65 66
67static int hda_uevent(struct device *dev, struct kobj_uevent_env *env)
68{
69 char modalias[32];
70
71 snd_hdac_codec_modalias(dev_to_hdac_dev(dev), modalias,
72 sizeof(modalias));
73 if (add_uevent_var(env, "MODALIAS=%s", modalias))
74 return -ENOMEM;
75 return 0;
76}
77
66struct bus_type snd_hda_bus_type = { 78struct bus_type snd_hda_bus_type = {
67 .name = "hdaudio", 79 .name = "hdaudio",
68 .match = hda_bus_match, 80 .match = hda_bus_match,
81 .uevent = hda_uevent,
69}; 82};
70EXPORT_SYMBOL_GPL(snd_hda_bus_type); 83EXPORT_SYMBOL_GPL(snd_hda_bus_type);
71 84
diff --git a/sound/hda/hdac_bus.c b/sound/hda/hdac_bus.c
index 27c447e4fe5c..0e81ea89a596 100644
--- a/sound/hda/hdac_bus.c
+++ b/sound/hda/hdac_bus.c
@@ -172,6 +172,15 @@ static void process_unsol_events(struct work_struct *work)
172 } 172 }
173} 173}
174 174
175/**
176 * snd_hdac_bus_add_device - Add a codec to bus
177 * @bus: HDA core bus
178 * @codec: HDA core device to add
179 *
180 * Adds the given codec to the list in the bus. The caddr_tbl array
181 * and codec_powered bits are updated, as well.
182 * Returns zero if success, or a negative error code.
183 */
175int snd_hdac_bus_add_device(struct hdac_bus *bus, struct hdac_device *codec) 184int snd_hdac_bus_add_device(struct hdac_bus *bus, struct hdac_device *codec)
176{ 185{
177 if (bus->caddr_tbl[codec->addr]) { 186 if (bus->caddr_tbl[codec->addr]) {
@@ -188,6 +197,11 @@ int snd_hdac_bus_add_device(struct hdac_bus *bus, struct hdac_device *codec)
188} 197}
189EXPORT_SYMBOL_GPL(snd_hdac_bus_add_device); 198EXPORT_SYMBOL_GPL(snd_hdac_bus_add_device);
190 199
200/**
201 * snd_hdac_bus_remove_device - Remove a codec from bus
202 * @bus: HDA core bus
203 * @codec: HDA core device to remove
204 */
191void snd_hdac_bus_remove_device(struct hdac_bus *bus, 205void snd_hdac_bus_remove_device(struct hdac_bus *bus,
192 struct hdac_device *codec) 206 struct hdac_device *codec)
193{ 207{
diff --git a/sound/hda/hdac_device.c b/sound/hda/hdac_device.c
index db96042a497f..e361024eabb6 100644
--- a/sound/hda/hdac_device.c
+++ b/sound/hda/hdac_device.c
@@ -164,6 +164,43 @@ void snd_hdac_device_unregister(struct hdac_device *codec)
164EXPORT_SYMBOL_GPL(snd_hdac_device_unregister); 164EXPORT_SYMBOL_GPL(snd_hdac_device_unregister);
165 165
166/** 166/**
167 * snd_hdac_device_set_chip_name - set/update the codec name
168 * @codec: the HDAC device
169 * @name: name string to set
170 *
171 * Returns 0 if the name is set or updated, or a negative error code.
172 */
173int snd_hdac_device_set_chip_name(struct hdac_device *codec, const char *name)
174{
175 char *newname;
176
177 if (!name)
178 return 0;
179 newname = kstrdup(name, GFP_KERNEL);
180 if (!newname)
181 return -ENOMEM;
182 kfree(codec->chip_name);
183 codec->chip_name = newname;
184 return 0;
185}
186EXPORT_SYMBOL_GPL(snd_hdac_device_set_chip_name);
187
188/**
189 * snd_hdac_codec_modalias - give the module alias name
190 * @codec: HDAC device
191 * @buf: string buffer to store
192 * @size: string buffer size
193 *
194 * Returns the size of string, like snprintf(), or a negative error code.
195 */
196int snd_hdac_codec_modalias(struct hdac_device *codec, char *buf, size_t size)
197{
198 return snprintf(buf, size, "hdaudio:v%08Xr%08Xa%02X\n",
199 codec->vendor_id, codec->revision_id, codec->type);
200}
201EXPORT_SYMBOL_GPL(snd_hdac_codec_modalias);
202
203/**
167 * snd_hdac_make_cmd - compose a 32bit command word to be sent to the 204 * snd_hdac_make_cmd - compose a 32bit command word to be sent to the
168 * HD-audio controller 205 * HD-audio controller
169 * @codec: the codec object 206 * @codec: the codec object
@@ -592,8 +629,10 @@ int snd_hdac_power_down_pm(struct hdac_device *codec)
592EXPORT_SYMBOL_GPL(snd_hdac_power_down_pm); 629EXPORT_SYMBOL_GPL(snd_hdac_power_down_pm);
593#endif 630#endif
594 631
595/* 632/**
596 * Enable/disable the link power for a codec. 633 * snd_hdac_link_power - Enable/disable the link power for a codec
634 * @codec: the codec object
635 * @bool: enable or disable the link power
597 */ 636 */
598int snd_hdac_link_power(struct hdac_device *codec, bool enable) 637int snd_hdac_link_power(struct hdac_device *codec, bool enable)
599{ 638{
@@ -952,3 +991,84 @@ bool snd_hdac_is_supported_format(struct hdac_device *codec, hda_nid_t nid,
952 return true; 991 return true;
953} 992}
954EXPORT_SYMBOL_GPL(snd_hdac_is_supported_format); 993EXPORT_SYMBOL_GPL(snd_hdac_is_supported_format);
994
995static unsigned int codec_read(struct hdac_device *hdac, hda_nid_t nid,
996 int flags, unsigned int verb, unsigned int parm)
997{
998 unsigned int cmd = snd_hdac_make_cmd(hdac, nid, verb, parm);
999 unsigned int res;
1000
1001 if (snd_hdac_exec_verb(hdac, cmd, flags, &res))
1002 return -1;
1003
1004 return res;
1005}
1006
1007static int codec_write(struct hdac_device *hdac, hda_nid_t nid,
1008 int flags, unsigned int verb, unsigned int parm)
1009{
1010 unsigned int cmd = snd_hdac_make_cmd(hdac, nid, verb, parm);
1011
1012 return snd_hdac_exec_verb(hdac, cmd, flags, NULL);
1013}
1014
1015/**
1016 * snd_hdac_codec_read - send a command and get the response
1017 * @hdac: the HDAC device
1018 * @nid: NID to send the command
1019 * @flags: optional bit flags
1020 * @verb: the verb to send
1021 * @parm: the parameter for the verb
1022 *
1023 * Send a single command and read the corresponding response.
1024 *
1025 * Returns the obtained response value, or -1 for an error.
1026 */
1027int snd_hdac_codec_read(struct hdac_device *hdac, hda_nid_t nid,
1028 int flags, unsigned int verb, unsigned int parm)
1029{
1030 return codec_read(hdac, nid, flags, verb, parm);
1031}
1032EXPORT_SYMBOL_GPL(snd_hdac_codec_read);
1033
1034/**
1035 * snd_hdac_codec_write - send a single command without waiting for response
1036 * @hdac: the HDAC device
1037 * @nid: NID to send the command
1038 * @flags: optional bit flags
1039 * @verb: the verb to send
1040 * @parm: the parameter for the verb
1041 *
1042 * Send a single command without waiting for response.
1043 *
1044 * Returns 0 if successful, or a negative error code.
1045 */
1046int snd_hdac_codec_write(struct hdac_device *hdac, hda_nid_t nid,
1047 int flags, unsigned int verb, unsigned int parm)
1048{
1049 return codec_write(hdac, nid, flags, verb, parm);
1050}
1051EXPORT_SYMBOL_GPL(snd_hdac_codec_write);
1052
1053/**
1054 * snd_hdac_check_power_state - check whether the actual power state matches
1055 * with the target state
1056 *
1057 * @hdac: the HDAC device
1058 * @nid: NID to send the command
1059 * @target_state: target state to check for
1060 *
1061 * Return true if state matches, false if not
1062 */
1063bool snd_hdac_check_power_state(struct hdac_device *hdac,
1064 hda_nid_t nid, unsigned int target_state)
1065{
1066 unsigned int state = codec_read(hdac, nid, 0,
1067 AC_VERB_GET_POWER_STATE, 0);
1068
1069 if (state & AC_PWRST_ERROR)
1070 return true;
1071 state = (state >> 4) & 0x0f;
1072 return (state == target_state);
1073}
1074EXPORT_SYMBOL_GPL(snd_hdac_check_power_state);
diff --git a/sound/hda/hdac_i915.c b/sound/hda/hdac_i915.c
index 55c3df4458f7..8fef1b8d1fd8 100644
--- a/sound/hda/hdac_i915.c
+++ b/sound/hda/hdac_i915.c
@@ -23,6 +23,19 @@
23 23
24static struct i915_audio_component *hdac_acomp; 24static struct i915_audio_component *hdac_acomp;
25 25
26/**
27 * snd_hdac_set_codec_wakeup - Enable / disable HDMI/DP codec wakeup
28 * @bus: HDA core bus
29 * @enable: enable or disable the wakeup
30 *
31 * This function is supposed to be used only by a HD-audio controller
32 * driver that needs the interaction with i915 graphics.
33 *
34 * This function should be called during the chip reset, also called at
35 * resume for updating STATESTS register read.
36 *
37 * Returns zero for success or a negative error code.
38 */
26int snd_hdac_set_codec_wakeup(struct hdac_bus *bus, bool enable) 39int snd_hdac_set_codec_wakeup(struct hdac_bus *bus, bool enable)
27{ 40{
28 struct i915_audio_component *acomp = bus->audio_component; 41 struct i915_audio_component *acomp = bus->audio_component;
@@ -45,6 +58,19 @@ int snd_hdac_set_codec_wakeup(struct hdac_bus *bus, bool enable)
45} 58}
46EXPORT_SYMBOL_GPL(snd_hdac_set_codec_wakeup); 59EXPORT_SYMBOL_GPL(snd_hdac_set_codec_wakeup);
47 60
61/**
62 * snd_hdac_display_power - Power up / down the power refcount
63 * @bus: HDA core bus
64 * @enable: power up or down
65 *
66 * This function is supposed to be used only by a HD-audio controller
67 * driver that needs the interaction with i915 graphics.
68 *
69 * This function manages a refcount and calls the i915 get_power() and
70 * put_power() ops accordingly, toggling the codec wakeup, too.
71 *
72 * Returns zero for success or a negative error code.
73 */
48int snd_hdac_display_power(struct hdac_bus *bus, bool enable) 74int snd_hdac_display_power(struct hdac_bus *bus, bool enable)
49{ 75{
50 struct i915_audio_component *acomp = bus->audio_component; 76 struct i915_audio_component *acomp = bus->audio_component;
@@ -71,6 +97,16 @@ int snd_hdac_display_power(struct hdac_bus *bus, bool enable)
71} 97}
72EXPORT_SYMBOL_GPL(snd_hdac_display_power); 98EXPORT_SYMBOL_GPL(snd_hdac_display_power);
73 99
100/**
101 * snd_hdac_get_display_clk - Get CDCLK in kHz
102 * @bus: HDA core bus
103 *
104 * This function is supposed to be used only by a HD-audio controller
105 * driver that needs the interaction with i915 graphics.
106 *
107 * This function queries CDCLK value in kHz from the graphics driver and
108 * returns the value. A negative code is returned in error.
109 */
74int snd_hdac_get_display_clk(struct hdac_bus *bus) 110int snd_hdac_get_display_clk(struct hdac_bus *bus)
75{ 111{
76 struct i915_audio_component *acomp = bus->audio_component; 112 struct i915_audio_component *acomp = bus->audio_component;
@@ -134,6 +170,17 @@ static int hdac_component_master_match(struct device *dev, void *data)
134 return !strcmp(dev->driver->name, "i915"); 170 return !strcmp(dev->driver->name, "i915");
135} 171}
136 172
173/**
174 * snd_hdac_i915_register_notifier - Register i915 audio component ops
175 * @aops: i915 audio component ops
176 *
177 * This function is supposed to be used only by a HD-audio controller
178 * driver that needs the interaction with i915 graphics.
179 *
180 * This function sets the given ops to be called by the i915 graphics driver.
181 *
182 * Returns zero for success or a negative error code.
183 */
137int snd_hdac_i915_register_notifier(const struct i915_audio_component_audio_ops *aops) 184int snd_hdac_i915_register_notifier(const struct i915_audio_component_audio_ops *aops)
138{ 185{
139 if (WARN_ON(!hdac_acomp)) 186 if (WARN_ON(!hdac_acomp))
@@ -144,6 +191,18 @@ int snd_hdac_i915_register_notifier(const struct i915_audio_component_audio_ops
144} 191}
145EXPORT_SYMBOL_GPL(snd_hdac_i915_register_notifier); 192EXPORT_SYMBOL_GPL(snd_hdac_i915_register_notifier);
146 193
194/**
195 * snd_hdac_i915_init - Initialize i915 audio component
196 * @bus: HDA core bus
197 *
198 * This function is supposed to be used only by a HD-audio controller
199 * driver that needs the interaction with i915 graphics.
200 *
201 * This function initializes and sets up the audio component to communicate
202 * with i915 graphics driver.
203 *
204 * Returns zero for success or a negative error code.
205 */
147int snd_hdac_i915_init(struct hdac_bus *bus) 206int snd_hdac_i915_init(struct hdac_bus *bus)
148{ 207{
149 struct component_match *match = NULL; 208 struct component_match *match = NULL;
@@ -187,6 +246,17 @@ out_err:
187} 246}
188EXPORT_SYMBOL_GPL(snd_hdac_i915_init); 247EXPORT_SYMBOL_GPL(snd_hdac_i915_init);
189 248
249/**
250 * snd_hdac_i915_exit - Finalize i915 audio component
251 * @bus: HDA core bus
252 *
253 * This function is supposed to be used only by a HD-audio controller
254 * driver that needs the interaction with i915 graphics.
255 *
256 * This function releases the i915 audio component that has been used.
257 *
258 * Returns zero for success or a negative error code.
259 */
190int snd_hdac_i915_exit(struct hdac_bus *bus) 260int snd_hdac_i915_exit(struct hdac_bus *bus)
191{ 261{
192 struct device *dev = bus->dev; 262 struct device *dev = bus->dev;
diff --git a/sound/hda/hdac_regmap.c b/sound/hda/hdac_regmap.c
index b0ed870ffb88..eb8f7c30cb09 100644
--- a/sound/hda/hdac_regmap.c
+++ b/sound/hda/hdac_regmap.c
@@ -339,6 +339,12 @@ static const struct regmap_config hda_regmap_cfg = {
339 .use_single_rw = true, 339 .use_single_rw = true,
340}; 340};
341 341
342/**
343 * snd_hdac_regmap_init - Initialize regmap for HDA register accesses
344 * @codec: the codec object
345 *
346 * Returns zero for success or a negative error code.
347 */
342int snd_hdac_regmap_init(struct hdac_device *codec) 348int snd_hdac_regmap_init(struct hdac_device *codec)
343{ 349{
344 struct regmap *regmap; 350 struct regmap *regmap;
@@ -352,6 +358,10 @@ int snd_hdac_regmap_init(struct hdac_device *codec)
352} 358}
353EXPORT_SYMBOL_GPL(snd_hdac_regmap_init); 359EXPORT_SYMBOL_GPL(snd_hdac_regmap_init);
354 360
361/**
362 * snd_hdac_regmap_init - Release the regmap from HDA codec
363 * @codec: the codec object
364 */
355void snd_hdac_regmap_exit(struct hdac_device *codec) 365void snd_hdac_regmap_exit(struct hdac_device *codec)
356{ 366{
357 if (codec->regmap) { 367 if (codec->regmap) {
diff --git a/sound/hda/hdac_stream.c b/sound/hda/hdac_stream.c
index 8981159813ef..38990a77d7b7 100644
--- a/sound/hda/hdac_stream.c
+++ b/sound/hda/hdac_stream.c
@@ -426,7 +426,8 @@ int snd_hdac_stream_setup_periods(struct hdac_stream *azx_dev)
426} 426}
427EXPORT_SYMBOL_GPL(snd_hdac_stream_setup_periods); 427EXPORT_SYMBOL_GPL(snd_hdac_stream_setup_periods);
428 428
429/* snd_hdac_stream_set_params - set stream parameters 429/**
430 * snd_hdac_stream_set_params - set stream parameters
430 * @azx_dev: HD-audio core stream for which parameters are to be set 431 * @azx_dev: HD-audio core stream for which parameters are to be set
431 * @format_val: format value parameter 432 * @format_val: format value parameter
432 * 433 *
diff --git a/sound/hda/hdac_sysfs.c b/sound/hda/hdac_sysfs.c
index c71142dea98a..42d61bf41969 100644
--- a/sound/hda/hdac_sysfs.c
+++ b/sound/hda/hdac_sysfs.c
@@ -45,6 +45,13 @@ CODEC_ATTR(mfg);
45CODEC_ATTR_STR(vendor_name); 45CODEC_ATTR_STR(vendor_name);
46CODEC_ATTR_STR(chip_name); 46CODEC_ATTR_STR(chip_name);
47 47
48static ssize_t modalias_show(struct device *dev, struct device_attribute *attr,
49 char *buf)
50{
51 return snd_hdac_codec_modalias(dev_to_hdac_dev(dev), buf, 256);
52}
53static DEVICE_ATTR_RO(modalias);
54
48static struct attribute *hdac_dev_attrs[] = { 55static struct attribute *hdac_dev_attrs[] = {
49 &dev_attr_type.attr, 56 &dev_attr_type.attr,
50 &dev_attr_vendor_id.attr, 57 &dev_attr_vendor_id.attr,
@@ -54,6 +61,7 @@ static struct attribute *hdac_dev_attrs[] = {
54 &dev_attr_mfg.attr, 61 &dev_attr_mfg.attr,
55 &dev_attr_vendor_name.attr, 62 &dev_attr_vendor_name.attr,
56 &dev_attr_chip_name.attr, 63 &dev_attr_chip_name.attr,
64 &dev_attr_modalias.attr,
57 NULL 65 NULL
58}; 66};
59 67
diff --git a/sound/pci/cs46xx/cs46xx_lib.c b/sound/pci/cs46xx/cs46xx_lib.c
index 2a9f4a345171..2706f271a83b 100644
--- a/sound/pci/cs46xx/cs46xx_lib.c
+++ b/sound/pci/cs46xx/cs46xx_lib.c
@@ -1864,7 +1864,7 @@ int snd_cs46xx_pcm_iec958(struct snd_cs46xx *chip, int device)
1864 /* global setup */ 1864 /* global setup */
1865 pcm->info_flags = 0; 1865 pcm->info_flags = 0;
1866 strcpy(pcm->name, "CS46xx - IEC958"); 1866 strcpy(pcm->name, "CS46xx - IEC958");
1867 chip->pcm_rear = pcm; 1867 chip->pcm_iec958 = pcm;
1868 1868
1869 snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV, 1869 snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
1870 snd_dma_pci_data(chip->pci), 64*1024, 256*1024); 1870 snd_dma_pci_data(chip->pci), 64*1024, 256*1024);
@@ -2528,7 +2528,7 @@ int snd_cs46xx_mixer(struct snd_cs46xx *chip, int spdif_device)
2528#ifdef CONFIG_SND_CS46XX_NEW_DSP 2528#ifdef CONFIG_SND_CS46XX_NEW_DSP
2529 if (chip->nr_ac97_codecs == 1) { 2529 if (chip->nr_ac97_codecs == 1) {
2530 unsigned int id2 = chip->ac97[CS46XX_PRIMARY_CODEC_INDEX]->id & 0xffff; 2530 unsigned int id2 = chip->ac97[CS46XX_PRIMARY_CODEC_INDEX]->id & 0xffff;
2531 if (id2 == 0x592b || id2 == 0x592d) { 2531 if ((id2 & 0xfff0) == 0x5920) { /* CS4294 and CS4298 */
2532 err = snd_ctl_add(card, snd_ctl_new1(&snd_cs46xx_front_dup_ctl, chip)); 2532 err = snd_ctl_add(card, snd_ctl_new1(&snd_cs46xx_front_dup_ctl, chip));
2533 if (err < 0) 2533 if (err < 0)
2534 return err; 2534 return err;
@@ -3780,6 +3780,11 @@ static int snd_cs46xx_suspend(struct device *dev)
3780 snd_power_change_state(card, SNDRV_CTL_POWER_D3hot); 3780 snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
3781 chip->in_suspend = 1; 3781 chip->in_suspend = 1;
3782 snd_pcm_suspend_all(chip->pcm); 3782 snd_pcm_suspend_all(chip->pcm);
3783#ifdef CONFIG_SND_CS46XX_NEW_DSP
3784 snd_pcm_suspend_all(chip->pcm_rear);
3785 snd_pcm_suspend_all(chip->pcm_center_lfe);
3786 snd_pcm_suspend_all(chip->pcm_iec958);
3787#endif
3783 // chip->ac97_powerdown = snd_cs46xx_codec_read(chip, AC97_POWER_CONTROL); 3788 // chip->ac97_powerdown = snd_cs46xx_codec_read(chip, AC97_POWER_CONTROL);
3784 // chip->ac97_general_purpose = snd_cs46xx_codec_read(chip, BA0_AC97_GENERAL_PURPOSE); 3789 // chip->ac97_general_purpose = snd_cs46xx_codec_read(chip, BA0_AC97_GENERAL_PURPOSE);
3785 3790
diff --git a/sound/pci/hda/hda_bind.c b/sound/pci/hda/hda_bind.c
index d5ac25cc7fee..70671ad65d24 100644
--- a/sound/pci/hda/hda_bind.c
+++ b/sound/pci/hda/hda_bind.c
@@ -15,21 +15,22 @@
15#include "hda_local.h" 15#include "hda_local.h"
16 16
17/* 17/*
18 * find a matching codec preset 18 * find a matching codec id
19 */ 19 */
20static int hda_codec_match(struct hdac_device *dev, struct hdac_driver *drv) 20static int hda_codec_match(struct hdac_device *dev, struct hdac_driver *drv)
21{ 21{
22 struct hda_codec *codec = container_of(dev, struct hda_codec, core); 22 struct hda_codec *codec = container_of(dev, struct hda_codec, core);
23 struct hda_codec_driver *driver = 23 struct hda_codec_driver *driver =
24 container_of(drv, struct hda_codec_driver, core); 24 container_of(drv, struct hda_codec_driver, core);
25 const struct hda_codec_preset *preset; 25 const struct hda_device_id *list;
26 /* check probe_id instead of vendor_id if set */ 26 /* check probe_id instead of vendor_id if set */
27 u32 id = codec->probe_id ? codec->probe_id : codec->core.vendor_id; 27 u32 id = codec->probe_id ? codec->probe_id : codec->core.vendor_id;
28 u32 rev_id = codec->core.revision_id;
28 29
29 for (preset = driver->preset; preset->id; preset++) { 30 for (list = driver->id; list->vendor_id; list++) {
30 if (preset->id == id && 31 if (list->vendor_id == id &&
31 (!preset->rev || preset->rev == codec->core.revision_id)) { 32 (!list->rev_id || list->rev_id == rev_id)) {
32 codec->preset = preset; 33 codec->preset = list;
33 return 1; 34 return 1;
34 } 35 }
35 } 36 }
@@ -45,26 +46,45 @@ static void hda_codec_unsol_event(struct hdac_device *dev, unsigned int ev)
45 codec->patch_ops.unsol_event(codec, ev); 46 codec->patch_ops.unsol_event(codec, ev);
46} 47}
47 48
48/* reset the codec name from the preset */ 49/**
49static int codec_refresh_name(struct hda_codec *codec, const char *name) 50 * snd_hda_codec_set_name - set the codec name
51 * @codec: the HDA codec
52 * @name: name string to set
53 */
54int snd_hda_codec_set_name(struct hda_codec *codec, const char *name)
50{ 55{
51 if (name) { 56 int err;
52 kfree(codec->core.chip_name); 57
53 codec->core.chip_name = kstrdup(name, GFP_KERNEL); 58 if (!name)
59 return 0;
60 err = snd_hdac_device_set_chip_name(&codec->core, name);
61 if (err < 0)
62 return err;
63
64 /* update the mixer name */
65 if (!*codec->card->mixername ||
66 codec->bus->mixer_assigned >= codec->core.addr) {
67 snprintf(codec->card->mixername,
68 sizeof(codec->card->mixername), "%s %s",
69 codec->core.vendor_name, codec->core.chip_name);
70 codec->bus->mixer_assigned = codec->core.addr;
54 } 71 }
55 return codec->core.chip_name ? 0 : -ENOMEM; 72
73 return 0;
56} 74}
75EXPORT_SYMBOL_GPL(snd_hda_codec_set_name);
57 76
58static int hda_codec_driver_probe(struct device *dev) 77static int hda_codec_driver_probe(struct device *dev)
59{ 78{
60 struct hda_codec *codec = dev_to_hda_codec(dev); 79 struct hda_codec *codec = dev_to_hda_codec(dev);
61 struct module *owner = dev->driver->owner; 80 struct module *owner = dev->driver->owner;
81 hda_codec_patch_t patch;
62 int err; 82 int err;
63 83
64 if (WARN_ON(!codec->preset)) 84 if (WARN_ON(!codec->preset))
65 return -EINVAL; 85 return -EINVAL;
66 86
67 err = codec_refresh_name(codec, codec->preset->name); 87 err = snd_hda_codec_set_name(codec, codec->preset->name);
68 if (err < 0) 88 if (err < 0)
69 goto error; 89 goto error;
70 err = snd_hdac_regmap_init(&codec->core); 90 err = snd_hdac_regmap_init(&codec->core);
@@ -76,9 +96,12 @@ static int hda_codec_driver_probe(struct device *dev)
76 goto error; 96 goto error;
77 } 97 }
78 98
79 err = codec->preset->patch(codec); 99 patch = (hda_codec_patch_t)codec->preset->driver_data;
80 if (err < 0) 100 if (patch) {
81 goto error_module; 101 err = patch(codec);
102 if (err < 0)
103 goto error_module;
104 }
82 105
83 err = snd_hda_codec_build_pcms(codec); 106 err = snd_hda_codec_build_pcms(codec);
84 if (err < 0) 107 if (err < 0)
@@ -155,11 +178,10 @@ static inline bool codec_probed(struct hda_codec *codec)
155static void codec_bind_module(struct hda_codec *codec) 178static void codec_bind_module(struct hda_codec *codec)
156{ 179{
157#ifdef MODULE 180#ifdef MODULE
158 request_module("snd-hda-codec-id:%08x", codec->core.vendor_id); 181 char modalias[32];
159 if (codec_probed(codec)) 182
160 return; 183 snd_hdac_codec_modalias(&codec->core, modalias, sizeof(modalias));
161 request_module("snd-hda-codec-id:%04x*", 184 request_module(modalias);
162 (codec->core.vendor_id >> 16) & 0xffff);
163 if (codec_probed(codec)) 185 if (codec_probed(codec))
164 return; 186 return;
165#endif 187#endif
@@ -251,11 +273,6 @@ int snd_hda_codec_configure(struct hda_codec *codec)
251 } 273 }
252 } 274 }
253 275
254 /* audio codec should override the mixer name */
255 if (codec->core.afg || !*codec->card->mixername)
256 snprintf(codec->card->mixername,
257 sizeof(codec->card->mixername), "%s %s",
258 codec->core.vendor_name, codec->core.chip_name);
259 return 0; 276 return 0;
260 277
261 error: 278 error:
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c
index a249d5486889..83741887faa1 100644
--- a/sound/pci/hda/hda_codec.c
+++ b/sound/pci/hda/hda_codec.c
@@ -91,50 +91,6 @@ static int codec_exec_verb(struct hdac_device *dev, unsigned int cmd,
91} 91}
92 92
93/** 93/**
94 * snd_hda_codec_read - send a command and get the response
95 * @codec: the HDA codec
96 * @nid: NID to send the command
97 * @flags: optional bit flags
98 * @verb: the verb to send
99 * @parm: the parameter for the verb
100 *
101 * Send a single command and read the corresponding response.
102 *
103 * Returns the obtained response value, or -1 for an error.
104 */
105unsigned int snd_hda_codec_read(struct hda_codec *codec, hda_nid_t nid,
106 int flags,
107 unsigned int verb, unsigned int parm)
108{
109 unsigned int cmd = snd_hdac_make_cmd(&codec->core, nid, verb, parm);
110 unsigned int res;
111 if (snd_hdac_exec_verb(&codec->core, cmd, flags, &res))
112 return -1;
113 return res;
114}
115EXPORT_SYMBOL_GPL(snd_hda_codec_read);
116
117/**
118 * snd_hda_codec_write - send a single command without waiting for response
119 * @codec: the HDA codec
120 * @nid: NID to send the command
121 * @flags: optional bit flags
122 * @verb: the verb to send
123 * @parm: the parameter for the verb
124 *
125 * Send a single command without waiting for response.
126 *
127 * Returns 0 if successful, or a negative error code.
128 */
129int snd_hda_codec_write(struct hda_codec *codec, hda_nid_t nid, int flags,
130 unsigned int verb, unsigned int parm)
131{
132 unsigned int cmd = snd_hdac_make_cmd(&codec->core, nid, verb, parm);
133 return snd_hdac_exec_verb(&codec->core, cmd, flags, NULL);
134}
135EXPORT_SYMBOL_GPL(snd_hda_codec_write);
136
137/**
138 * snd_hda_sequence_write - sequence writes 94 * snd_hda_sequence_write - sequence writes
139 * @codec: the HDA codec 95 * @codec: the HDA codec
140 * @seq: VERB array to send 96 * @seq: VERB array to send
diff --git a/sound/pci/hda/hda_codec.h b/sound/pci/hda/hda_codec.h
index 2970413f18a0..373fcad840ea 100644
--- a/sound/pci/hda/hda_codec.h
+++ b/sound/pci/hda/hda_codec.h
@@ -22,6 +22,7 @@
22#define __SOUND_HDA_CODEC_H 22#define __SOUND_HDA_CODEC_H
23 23
24#include <linux/kref.h> 24#include <linux/kref.h>
25#include <linux/mod_devicetable.h>
25#include <sound/info.h> 26#include <sound/info.h>
26#include <sound/control.h> 27#include <sound/control.h>
27#include <sound/pcm.h> 28#include <sound/pcm.h>
@@ -69,6 +70,7 @@ struct hda_bus {
69 unsigned int no_response_fallback:1; /* don't fallback at RIRB error */ 70 unsigned int no_response_fallback:1; /* don't fallback at RIRB error */
70 71
71 int primary_dig_out_type; /* primary digital out PCM type */ 72 int primary_dig_out_type; /* primary digital out PCM type */
73 unsigned int mixer_assigned; /* codec addr for mixer name */
72}; 74};
73 75
74/* from hdac_bus to hda_bus */ 76/* from hdac_bus to hda_bus */
@@ -80,19 +82,21 @@ struct hda_bus {
80 * Known codecs have the patch to build and set up the controls/PCMs 82 * Known codecs have the patch to build and set up the controls/PCMs
81 * better than the generic parser. 83 * better than the generic parser.
82 */ 84 */
83struct hda_codec_preset { 85typedef int (*hda_codec_patch_t)(struct hda_codec *);
84 unsigned int id;
85 unsigned int rev;
86 const char *name;
87 int (*patch)(struct hda_codec *codec);
88};
89 86
90#define HDA_CODEC_ID_GENERIC_HDMI 0x00000101 87#define HDA_CODEC_ID_GENERIC_HDMI 0x00000101
91#define HDA_CODEC_ID_GENERIC 0x00000201 88#define HDA_CODEC_ID_GENERIC 0x00000201
92 89
90#define HDA_CODEC_REV_ENTRY(_vid, _rev, _name, _patch) \
91 { .vendor_id = (_vid), .rev_id = (_rev), .name = (_name), \
92 .api_version = HDA_DEV_LEGACY, \
93 .driver_data = (unsigned long)(_patch) }
94#define HDA_CODEC_ENTRY(_vid, _name, _patch) \
95 HDA_CODEC_REV_ENTRY(_vid, 0, _name, _patch)
96
93struct hda_codec_driver { 97struct hda_codec_driver {
94 struct hdac_driver core; 98 struct hdac_driver core;
95 const struct hda_codec_preset *preset; 99 const struct hda_device_id *id;
96}; 100};
97 101
98int __hda_codec_driver_register(struct hda_codec_driver *drv, const char *name, 102int __hda_codec_driver_register(struct hda_codec_driver *drv, const char *name,
@@ -183,7 +187,7 @@ struct hda_codec {
183 u32 probe_id; /* overridden id for probing */ 187 u32 probe_id; /* overridden id for probing */
184 188
185 /* detected preset */ 189 /* detected preset */
186 const struct hda_codec_preset *preset; 190 const struct hda_device_id *preset;
187 const char *modelname; /* model name for preset */ 191 const char *modelname; /* model name for preset */
188 192
189 /* set by patch */ 193 /* set by patch */
@@ -297,10 +301,6 @@ struct hda_codec {
297/* 301/*
298 * constructors 302 * constructors
299 */ 303 */
300int snd_hda_bus_new(struct snd_card *card,
301 const struct hdac_bus_ops *ops,
302 const struct hdac_io_ops *io_ops,
303 struct hda_bus **busp);
304int snd_hda_codec_new(struct hda_bus *bus, struct snd_card *card, 304int snd_hda_codec_new(struct hda_bus *bus, struct snd_card *card,
305 unsigned int codec_addr, struct hda_codec **codecp); 305 unsigned int codec_addr, struct hda_codec **codecp);
306int snd_hda_codec_configure(struct hda_codec *codec); 306int snd_hda_codec_configure(struct hda_codec *codec);
@@ -309,11 +309,21 @@ int snd_hda_codec_update_widgets(struct hda_codec *codec);
309/* 309/*
310 * low level functions 310 * low level functions
311 */ 311 */
312unsigned int snd_hda_codec_read(struct hda_codec *codec, hda_nid_t nid, 312static inline unsigned int
313snd_hda_codec_read(struct hda_codec *codec, hda_nid_t nid,
313 int flags, 314 int flags,
314 unsigned int verb, unsigned int parm); 315 unsigned int verb, unsigned int parm)
315int snd_hda_codec_write(struct hda_codec *codec, hda_nid_t nid, int flags, 316{
316 unsigned int verb, unsigned int parm); 317 return snd_hdac_codec_read(&codec->core, nid, flags, verb, parm);
318}
319
320static inline int
321snd_hda_codec_write(struct hda_codec *codec, hda_nid_t nid, int flags,
322 unsigned int verb, unsigned int parm)
323{
324 return snd_hdac_codec_write(&codec->core, nid, flags, verb, parm);
325}
326
317#define snd_hda_param_read(codec, nid, param) \ 327#define snd_hda_param_read(codec, nid, param) \
318 snd_hdac_read_parm(&(codec)->core, nid, param) 328 snd_hdac_read_parm(&(codec)->core, nid, param)
319#define snd_hda_get_sub_nodes(codec, nid, start_nid) \ 329#define snd_hda_get_sub_nodes(codec, nid, start_nid) \
@@ -453,6 +463,8 @@ void snd_hda_unlock_devices(struct hda_bus *bus);
453void snd_hda_bus_reset(struct hda_bus *bus); 463void snd_hda_bus_reset(struct hda_bus *bus);
454void snd_hda_bus_reset_codecs(struct hda_bus *bus); 464void snd_hda_bus_reset_codecs(struct hda_bus *bus);
455 465
466int snd_hda_codec_set_name(struct hda_codec *codec, const char *name);
467
456/* 468/*
457 * power management 469 * power management
458 */ 470 */
diff --git a/sound/pci/hda/hda_controller.c b/sound/pci/hda/hda_controller.c
index 944455997fdc..22dbfa563919 100644
--- a/sound/pci/hda/hda_controller.c
+++ b/sound/pci/hda/hda_controller.c
@@ -1045,6 +1045,7 @@ int azx_bus_init(struct azx *chip, const char *model,
1045 mutex_init(&bus->prepare_mutex); 1045 mutex_init(&bus->prepare_mutex);
1046 bus->pci = chip->pci; 1046 bus->pci = chip->pci;
1047 bus->modelname = model; 1047 bus->modelname = model;
1048 bus->mixer_assigned = -1;
1048 bus->core.snoop = azx_snoop(chip); 1049 bus->core.snoop = azx_snoop(chip);
1049 if (chip->get_position[0] != azx_get_pos_lpib || 1050 if (chip->get_position[0] != azx_get_pos_lpib ||
1050 chip->get_position[1] != azx_get_pos_lpib) 1051 chip->get_position[1] != azx_get_pos_lpib)
@@ -1059,6 +1060,9 @@ int azx_bus_init(struct azx *chip, const char *model,
1059 bus->needs_damn_long_delay = 1; 1060 bus->needs_damn_long_delay = 1;
1060 } 1061 }
1061 1062
1063 if (chip->driver_caps & AZX_DCAPS_4K_BDLE_BOUNDARY)
1064 bus->core.align_bdle_4k = true;
1065
1062 /* AMD chipsets often cause the communication stalls upon certain 1066 /* AMD chipsets often cause the communication stalls upon certain
1063 * sequence like the pin-detection. It seems that forcing the synced 1067 * sequence like the pin-detection. It seems that forcing the synced
1064 * access works around the stall. Grrr... 1068 * access works around the stall. Grrr...
diff --git a/sound/pci/hda/hda_generic.c b/sound/pci/hda/hda_generic.c
index 24f91114a32c..c6e8a651cea1 100644
--- a/sound/pci/hda/hda_generic.c
+++ b/sound/pci/hda/hda_generic.c
@@ -5877,13 +5877,14 @@ error:
5877 return err; 5877 return err;
5878} 5878}
5879 5879
5880static const struct hda_codec_preset snd_hda_preset_generic[] = { 5880static const struct hda_device_id snd_hda_id_generic[] = {
5881 { .id = HDA_CODEC_ID_GENERIC, .patch = snd_hda_parse_generic_codec }, 5881 HDA_CODEC_ENTRY(HDA_CODEC_ID_GENERIC, "Generic", snd_hda_parse_generic_codec),
5882 {} /* terminator */ 5882 {} /* terminator */
5883}; 5883};
5884MODULE_DEVICE_TABLE(hdaudio, snd_hda_id_generic);
5884 5885
5885static struct hda_codec_driver generic_driver = { 5886static struct hda_codec_driver generic_driver = {
5886 .preset = snd_hda_preset_generic, 5887 .id = snd_hda_id_generic,
5887}; 5888};
5888 5889
5889module_hda_codec_driver(generic_driver); 5890module_hda_codec_driver(generic_driver);
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c
index c38c68f57938..4d2cbe2ca141 100644
--- a/sound/pci/hda/hda_intel.c
+++ b/sound/pci/hda/hda_intel.c
@@ -334,6 +334,7 @@ enum {
334 334
335#define AZX_DCAPS_PRESET_CTHDA \ 335#define AZX_DCAPS_PRESET_CTHDA \
336 (AZX_DCAPS_NO_MSI | AZX_DCAPS_POSFIX_LPIB |\ 336 (AZX_DCAPS_NO_MSI | AZX_DCAPS_POSFIX_LPIB |\
337 AZX_DCAPS_NO_64BIT |\
337 AZX_DCAPS_4K_BDLE_BOUNDARY | AZX_DCAPS_SNOOP_OFF) 338 AZX_DCAPS_4K_BDLE_BOUNDARY | AZX_DCAPS_SNOOP_OFF)
338 339
339/* 340/*
@@ -2104,6 +2105,11 @@ static const struct pci_device_id azx_ids[] = {
2104 .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_PCH }, 2105 .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_PCH },
2105 { PCI_DEVICE(0x8086, 0x8d21), 2106 { PCI_DEVICE(0x8086, 0x8d21),
2106 .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_PCH }, 2107 .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_PCH },
2108 /* Lewisburg */
2109 { PCI_DEVICE(0x8086, 0xa1f0),
2110 .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_PCH },
2111 { PCI_DEVICE(0x8086, 0xa270),
2112 .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_PCH },
2107 /* Lynx Point-LP */ 2113 /* Lynx Point-LP */
2108 { PCI_DEVICE(0x8086, 0x9c20), 2114 { PCI_DEVICE(0x8086, 0x9c20),
2109 .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_PCH }, 2115 .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_PCH },
@@ -2284,11 +2290,13 @@ static const struct pci_device_id azx_ids[] = {
2284 .class = PCI_CLASS_MULTIMEDIA_HD_AUDIO << 8, 2290 .class = PCI_CLASS_MULTIMEDIA_HD_AUDIO << 8,
2285 .class_mask = 0xffffff, 2291 .class_mask = 0xffffff,
2286 .driver_data = AZX_DRIVER_CTX | AZX_DCAPS_CTX_WORKAROUND | 2292 .driver_data = AZX_DRIVER_CTX | AZX_DCAPS_CTX_WORKAROUND |
2293 AZX_DCAPS_NO_64BIT |
2287 AZX_DCAPS_RIRB_PRE_DELAY | AZX_DCAPS_POSFIX_LPIB }, 2294 AZX_DCAPS_RIRB_PRE_DELAY | AZX_DCAPS_POSFIX_LPIB },
2288#else 2295#else
2289 /* this entry seems still valid -- i.e. without emu20kx chip */ 2296 /* this entry seems still valid -- i.e. without emu20kx chip */
2290 { PCI_DEVICE(0x1102, 0x0009), 2297 { PCI_DEVICE(0x1102, 0x0009),
2291 .driver_data = AZX_DRIVER_CTX | AZX_DCAPS_CTX_WORKAROUND | 2298 .driver_data = AZX_DRIVER_CTX | AZX_DCAPS_CTX_WORKAROUND |
2299 AZX_DCAPS_NO_64BIT |
2292 AZX_DCAPS_RIRB_PRE_DELAY | AZX_DCAPS_POSFIX_LPIB }, 2300 AZX_DCAPS_RIRB_PRE_DELAY | AZX_DCAPS_POSFIX_LPIB },
2293#endif 2301#endif
2294 /* CM8888 */ 2302 /* CM8888 */
diff --git a/sound/pci/hda/hda_local.h b/sound/pci/hda/hda_local.h
index 4a21c2199e02..d0e066e4c985 100644
--- a/sound/pci/hda/hda_local.h
+++ b/sound/pci/hda/hda_local.h
@@ -681,12 +681,7 @@ static inline bool
681snd_hda_check_power_state(struct hda_codec *codec, hda_nid_t nid, 681snd_hda_check_power_state(struct hda_codec *codec, hda_nid_t nid,
682 unsigned int target_state) 682 unsigned int target_state)
683{ 683{
684 unsigned int state = snd_hda_codec_read(codec, nid, 0, 684 return snd_hdac_check_power_state(&codec->core, nid, target_state);
685 AC_VERB_GET_POWER_STATE, 0);
686 if (state & AC_PWRST_ERROR)
687 return true;
688 state = (state >> 4) & 0x0f;
689 return (state == target_state);
690} 685}
691 686
692unsigned int snd_hda_codec_eapd_power_filter(struct hda_codec *codec, 687unsigned int snd_hda_codec_eapd_power_filter(struct hda_codec *codec,
diff --git a/sound/pci/hda/hda_sysfs.c b/sound/pci/hda/hda_sysfs.c
index a6e3d9b511ab..64e0d1d81ca5 100644
--- a/sound/pci/hda/hda_sysfs.c
+++ b/sound/pci/hda/hda_sysfs.c
@@ -595,8 +595,7 @@ static void parse_model_mode(char *buf, struct hda_bus *bus,
595static void parse_chip_name_mode(char *buf, struct hda_bus *bus, 595static void parse_chip_name_mode(char *buf, struct hda_bus *bus,
596 struct hda_codec **codecp) 596 struct hda_codec **codecp)
597{ 597{
598 kfree((*codecp)->core.chip_name); 598 snd_hda_codec_set_name(*codecp, buf);
599 (*codecp)->core.chip_name = kstrdup(buf, GFP_KERNEL);
600} 599}
601 600
602#define DEFINE_PARSE_ID_MODE(name) \ 601#define DEFINE_PARSE_ID_MODE(name) \
diff --git a/sound/pci/hda/patch_analog.c b/sound/pci/hda/patch_analog.c
index c033a4ee6547..e0fb8c6d1bc2 100644
--- a/sound/pci/hda/patch_analog.c
+++ b/sound/pci/hda/patch_analog.c
@@ -1165,32 +1165,31 @@ static int patch_ad1882(struct hda_codec *codec)
1165/* 1165/*
1166 * patch entries 1166 * patch entries
1167 */ 1167 */
1168static const struct hda_codec_preset snd_hda_preset_analog[] = { 1168static const struct hda_device_id snd_hda_id_analog[] = {
1169 { .id = 0x11d4184a, .name = "AD1884A", .patch = patch_ad1884 }, 1169 HDA_CODEC_ENTRY(0x11d4184a, "AD1884A", patch_ad1884),
1170 { .id = 0x11d41882, .name = "AD1882", .patch = patch_ad1882 }, 1170 HDA_CODEC_ENTRY(0x11d41882, "AD1882", patch_ad1882),
1171 { .id = 0x11d41883, .name = "AD1883", .patch = patch_ad1884 }, 1171 HDA_CODEC_ENTRY(0x11d41883, "AD1883", patch_ad1884),
1172 { .id = 0x11d41884, .name = "AD1884", .patch = patch_ad1884 }, 1172 HDA_CODEC_ENTRY(0x11d41884, "AD1884", patch_ad1884),
1173 { .id = 0x11d4194a, .name = "AD1984A", .patch = patch_ad1884 }, 1173 HDA_CODEC_ENTRY(0x11d4194a, "AD1984A", patch_ad1884),
1174 { .id = 0x11d4194b, .name = "AD1984B", .patch = patch_ad1884 }, 1174 HDA_CODEC_ENTRY(0x11d4194b, "AD1984B", patch_ad1884),
1175 { .id = 0x11d41981, .name = "AD1981", .patch = patch_ad1981 }, 1175 HDA_CODEC_ENTRY(0x11d41981, "AD1981", patch_ad1981),
1176 { .id = 0x11d41983, .name = "AD1983", .patch = patch_ad1983 }, 1176 HDA_CODEC_ENTRY(0x11d41983, "AD1983", patch_ad1983),
1177 { .id = 0x11d41984, .name = "AD1984", .patch = patch_ad1884 }, 1177 HDA_CODEC_ENTRY(0x11d41984, "AD1984", patch_ad1884),
1178 { .id = 0x11d41986, .name = "AD1986A", .patch = patch_ad1986a }, 1178 HDA_CODEC_ENTRY(0x11d41986, "AD1986A", patch_ad1986a),
1179 { .id = 0x11d41988, .name = "AD1988", .patch = patch_ad1988 }, 1179 HDA_CODEC_ENTRY(0x11d41988, "AD1988", patch_ad1988),
1180 { .id = 0x11d4198b, .name = "AD1988B", .patch = patch_ad1988 }, 1180 HDA_CODEC_ENTRY(0x11d4198b, "AD1988B", patch_ad1988),
1181 { .id = 0x11d4882a, .name = "AD1882A", .patch = patch_ad1882 }, 1181 HDA_CODEC_ENTRY(0x11d4882a, "AD1882A", patch_ad1882),
1182 { .id = 0x11d4989a, .name = "AD1989A", .patch = patch_ad1988 }, 1182 HDA_CODEC_ENTRY(0x11d4989a, "AD1989A", patch_ad1988),
1183 { .id = 0x11d4989b, .name = "AD1989B", .patch = patch_ad1988 }, 1183 HDA_CODEC_ENTRY(0x11d4989b, "AD1989B", patch_ad1988),
1184 {} /* terminator */ 1184 {} /* terminator */
1185}; 1185};
1186 1186MODULE_DEVICE_TABLE(hdaudio, snd_hda_id_analog);
1187MODULE_ALIAS("snd-hda-codec-id:11d4*");
1188 1187
1189MODULE_LICENSE("GPL"); 1188MODULE_LICENSE("GPL");
1190MODULE_DESCRIPTION("Analog Devices HD-audio codec"); 1189MODULE_DESCRIPTION("Analog Devices HD-audio codec");
1191 1190
1192static struct hda_codec_driver analog_driver = { 1191static struct hda_codec_driver analog_driver = {
1193 .preset = snd_hda_preset_analog, 1192 .id = snd_hda_id_analog,
1194}; 1193};
1195 1194
1196module_hda_codec_driver(analog_driver); 1195module_hda_codec_driver(analog_driver);
diff --git a/sound/pci/hda/patch_ca0110.c b/sound/pci/hda/patch_ca0110.c
index 484bbf4134cd..c2d9ee9cfdc0 100644
--- a/sound/pci/hda/patch_ca0110.c
+++ b/sound/pci/hda/patch_ca0110.c
@@ -83,22 +83,19 @@ static int patch_ca0110(struct hda_codec *codec)
83/* 83/*
84 * patch entries 84 * patch entries
85 */ 85 */
86static const struct hda_codec_preset snd_hda_preset_ca0110[] = { 86static const struct hda_device_id snd_hda_id_ca0110[] = {
87 { .id = 0x1102000a, .name = "CA0110-IBG", .patch = patch_ca0110 }, 87 HDA_CODEC_ENTRY(0x1102000a, "CA0110-IBG", patch_ca0110),
88 { .id = 0x1102000b, .name = "CA0110-IBG", .patch = patch_ca0110 }, 88 HDA_CODEC_ENTRY(0x1102000b, "CA0110-IBG", patch_ca0110),
89 { .id = 0x1102000d, .name = "SB0880 X-Fi", .patch = patch_ca0110 }, 89 HDA_CODEC_ENTRY(0x1102000d, "SB0880 X-Fi", patch_ca0110),
90 {} /* terminator */ 90 {} /* terminator */
91}; 91};
92 92MODULE_DEVICE_TABLE(hdaudio, snd_hda_id_ca0110);
93MODULE_ALIAS("snd-hda-codec-id:1102000a");
94MODULE_ALIAS("snd-hda-codec-id:1102000b");
95MODULE_ALIAS("snd-hda-codec-id:1102000d");
96 93
97MODULE_LICENSE("GPL"); 94MODULE_LICENSE("GPL");
98MODULE_DESCRIPTION("Creative CA0110-IBG HD-audio codec"); 95MODULE_DESCRIPTION("Creative CA0110-IBG HD-audio codec");
99 96
100static struct hda_codec_driver ca0110_driver = { 97static struct hda_codec_driver ca0110_driver = {
101 .preset = snd_hda_preset_ca0110, 98 .id = snd_hda_id_ca0110,
102}; 99};
103 100
104module_hda_codec_driver(ca0110_driver); 101module_hda_codec_driver(ca0110_driver);
diff --git a/sound/pci/hda/patch_ca0132.c b/sound/pci/hda/patch_ca0132.c
index 186792fe226e..f8a12ca477f1 100644
--- a/sound/pci/hda/patch_ca0132.c
+++ b/sound/pci/hda/patch_ca0132.c
@@ -2673,13 +2673,13 @@ static bool dspload_wait_loaded(struct hda_codec *codec)
2673 2673
2674 do { 2674 do {
2675 if (dspload_is_loaded(codec)) { 2675 if (dspload_is_loaded(codec)) {
2676 pr_info("ca0132 DOWNLOAD OK :-) DSP IS RUNNING.\n"); 2676 codec_info(codec, "ca0132 DSP downloaded and running\n");
2677 return true; 2677 return true;
2678 } 2678 }
2679 msleep(20); 2679 msleep(20);
2680 } while (time_before(jiffies, timeout)); 2680 } while (time_before(jiffies, timeout));
2681 2681
2682 pr_err("ca0132 DOWNLOAD FAILED!!! DSP IS NOT RUNNING.\n"); 2682 codec_err(codec, "ca0132 failed to download DSP\n");
2683 return false; 2683 return false;
2684} 2684}
2685 2685
@@ -4375,7 +4375,7 @@ static bool ca0132_download_dsp_images(struct hda_codec *codec)
4375 4375
4376 dsp_os_image = (struct dsp_image_seg *)(fw_entry->data); 4376 dsp_os_image = (struct dsp_image_seg *)(fw_entry->data);
4377 if (dspload_image(codec, dsp_os_image, 0, 0, true, 0)) { 4377 if (dspload_image(codec, dsp_os_image, 0, 0, true, 0)) {
4378 pr_err("ca0132 dspload_image failed.\n"); 4378 codec_err(codec, "ca0132 DSP load image failed\n");
4379 goto exit_download; 4379 goto exit_download;
4380 } 4380 }
4381 4381
@@ -4778,18 +4778,17 @@ static int patch_ca0132(struct hda_codec *codec)
4778/* 4778/*
4779 * patch entries 4779 * patch entries
4780 */ 4780 */
4781static struct hda_codec_preset snd_hda_preset_ca0132[] = { 4781static struct hda_device_id snd_hda_id_ca0132[] = {
4782 { .id = 0x11020011, .name = "CA0132", .patch = patch_ca0132 }, 4782 HDA_CODEC_ENTRY(0x11020011, "CA0132", patch_ca0132),
4783 {} /* terminator */ 4783 {} /* terminator */
4784}; 4784};
4785 4785MODULE_DEVICE_TABLE(hdaudio, snd_hda_id_ca0132);
4786MODULE_ALIAS("snd-hda-codec-id:11020011");
4787 4786
4788MODULE_LICENSE("GPL"); 4787MODULE_LICENSE("GPL");
4789MODULE_DESCRIPTION("Creative Sound Core3D codec"); 4788MODULE_DESCRIPTION("Creative Sound Core3D codec");
4790 4789
4791static struct hda_codec_driver ca0132_driver = { 4790static struct hda_codec_driver ca0132_driver = {
4792 .preset = snd_hda_preset_ca0132, 4791 .id = snd_hda_id_ca0132,
4793}; 4792};
4794 4793
4795module_hda_codec_driver(ca0132_driver); 4794module_hda_codec_driver(ca0132_driver);
diff --git a/sound/pci/hda/patch_cirrus.c b/sound/pci/hda/patch_cirrus.c
index 85813de26da8..a12ae8ac0914 100644
--- a/sound/pci/hda/patch_cirrus.c
+++ b/sound/pci/hda/patch_cirrus.c
@@ -570,6 +570,7 @@ static struct cs_spec *cs_alloc_spec(struct hda_codec *codec, int vendor_nid)
570 return NULL; 570 return NULL;
571 codec->spec = spec; 571 codec->spec = spec;
572 spec->vendor_nid = vendor_nid; 572 spec->vendor_nid = vendor_nid;
573 codec->power_save_node = 1;
573 snd_hda_gen_spec_init(&spec->gen); 574 snd_hda_gen_spec_init(&spec->gen);
574 575
575 return spec; 576 return spec;
@@ -1200,26 +1201,21 @@ static int patch_cs4213(struct hda_codec *codec)
1200/* 1201/*
1201 * patch entries 1202 * patch entries
1202 */ 1203 */
1203static const struct hda_codec_preset snd_hda_preset_cirrus[] = { 1204static const struct hda_device_id snd_hda_id_cirrus[] = {
1204 { .id = 0x10134206, .name = "CS4206", .patch = patch_cs420x }, 1205 HDA_CODEC_ENTRY(0x10134206, "CS4206", patch_cs420x),
1205 { .id = 0x10134207, .name = "CS4207", .patch = patch_cs420x }, 1206 HDA_CODEC_ENTRY(0x10134207, "CS4207", patch_cs420x),
1206 { .id = 0x10134208, .name = "CS4208", .patch = patch_cs4208 }, 1207 HDA_CODEC_ENTRY(0x10134208, "CS4208", patch_cs4208),
1207 { .id = 0x10134210, .name = "CS4210", .patch = patch_cs4210 }, 1208 HDA_CODEC_ENTRY(0x10134210, "CS4210", patch_cs4210),
1208 { .id = 0x10134213, .name = "CS4213", .patch = patch_cs4213 }, 1209 HDA_CODEC_ENTRY(0x10134213, "CS4213", patch_cs4213),
1209 {} /* terminator */ 1210 {} /* terminator */
1210}; 1211};
1211 1212MODULE_DEVICE_TABLE(hdaudio, snd_hda_id_cirrus);
1212MODULE_ALIAS("snd-hda-codec-id:10134206");
1213MODULE_ALIAS("snd-hda-codec-id:10134207");
1214MODULE_ALIAS("snd-hda-codec-id:10134208");
1215MODULE_ALIAS("snd-hda-codec-id:10134210");
1216MODULE_ALIAS("snd-hda-codec-id:10134213");
1217 1213
1218MODULE_LICENSE("GPL"); 1214MODULE_LICENSE("GPL");
1219MODULE_DESCRIPTION("Cirrus Logic HD-audio codec"); 1215MODULE_DESCRIPTION("Cirrus Logic HD-audio codec");
1220 1216
1221static struct hda_codec_driver cirrus_driver = { 1217static struct hda_codec_driver cirrus_driver = {
1222 .preset = snd_hda_preset_cirrus, 1218 .id = snd_hda_id_cirrus,
1223}; 1219};
1224 1220
1225module_hda_codec_driver(cirrus_driver); 1221module_hda_codec_driver(cirrus_driver);
diff --git a/sound/pci/hda/patch_cmedia.c b/sound/pci/hda/patch_cmedia.c
index f5ed078710f8..1b2195dd2b26 100644
--- a/sound/pci/hda/patch_cmedia.c
+++ b/sound/pci/hda/patch_cmedia.c
@@ -123,22 +123,19 @@ static int patch_cmi8888(struct hda_codec *codec)
123/* 123/*
124 * patch entries 124 * patch entries
125 */ 125 */
126static const struct hda_codec_preset snd_hda_preset_cmedia[] = { 126static const struct hda_device_id snd_hda_id_cmedia[] = {
127 { .id = 0x13f68888, .name = "CMI8888", .patch = patch_cmi8888 }, 127 HDA_CODEC_ENTRY(0x13f68888, "CMI8888", patch_cmi8888),
128 { .id = 0x13f69880, .name = "CMI9880", .patch = patch_cmi9880 }, 128 HDA_CODEC_ENTRY(0x13f69880, "CMI9880", patch_cmi9880),
129 { .id = 0x434d4980, .name = "CMI9880", .patch = patch_cmi9880 }, 129 HDA_CODEC_ENTRY(0x434d4980, "CMI9880", patch_cmi9880),
130 {} /* terminator */ 130 {} /* terminator */
131}; 131};
132 132MODULE_DEVICE_TABLE(hdaudio, snd_hda_id_cmedia);
133MODULE_ALIAS("snd-hda-codec-id:13f68888");
134MODULE_ALIAS("snd-hda-codec-id:13f69880");
135MODULE_ALIAS("snd-hda-codec-id:434d4980");
136 133
137MODULE_LICENSE("GPL"); 134MODULE_LICENSE("GPL");
138MODULE_DESCRIPTION("C-Media HD-audio codec"); 135MODULE_DESCRIPTION("C-Media HD-audio codec");
139 136
140static struct hda_codec_driver cmedia_driver = { 137static struct hda_codec_driver cmedia_driver = {
141 .preset = snd_hda_preset_cmedia, 138 .id = snd_hda_id_cmedia,
142}; 139};
143 140
144module_hda_codec_driver(cmedia_driver); 141module_hda_codec_driver(cmedia_driver);
diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c
index 2f0ec7c45fc7..c8b8ef5246a6 100644
--- a/sound/pci/hda/patch_conexant.c
+++ b/sound/pci/hda/patch_conexant.c
@@ -954,100 +954,44 @@ static int patch_conexant_auto(struct hda_codec *codec)
954/* 954/*
955 */ 955 */
956 956
957static const struct hda_codec_preset snd_hda_preset_conexant[] = { 957static const struct hda_device_id snd_hda_id_conexant[] = {
958 { .id = 0x14f15045, .name = "CX20549 (Venice)", 958 HDA_CODEC_ENTRY(0x14f15045, "CX20549 (Venice)", patch_conexant_auto),
959 .patch = patch_conexant_auto }, 959 HDA_CODEC_ENTRY(0x14f15047, "CX20551 (Waikiki)", patch_conexant_auto),
960 { .id = 0x14f15047, .name = "CX20551 (Waikiki)", 960 HDA_CODEC_ENTRY(0x14f15051, "CX20561 (Hermosa)", patch_conexant_auto),
961 .patch = patch_conexant_auto }, 961 HDA_CODEC_ENTRY(0x14f15066, "CX20582 (Pebble)", patch_conexant_auto),
962 { .id = 0x14f15051, .name = "CX20561 (Hermosa)", 962 HDA_CODEC_ENTRY(0x14f15067, "CX20583 (Pebble HSF)", patch_conexant_auto),
963 .patch = patch_conexant_auto }, 963 HDA_CODEC_ENTRY(0x14f15068, "CX20584", patch_conexant_auto),
964 { .id = 0x14f15066, .name = "CX20582 (Pebble)", 964 HDA_CODEC_ENTRY(0x14f15069, "CX20585", patch_conexant_auto),
965 .patch = patch_conexant_auto }, 965 HDA_CODEC_ENTRY(0x14f1506c, "CX20588", patch_conexant_auto),
966 { .id = 0x14f15067, .name = "CX20583 (Pebble HSF)", 966 HDA_CODEC_ENTRY(0x14f1506e, "CX20590", patch_conexant_auto),
967 .patch = patch_conexant_auto }, 967 HDA_CODEC_ENTRY(0x14f15097, "CX20631", patch_conexant_auto),
968 { .id = 0x14f15068, .name = "CX20584", 968 HDA_CODEC_ENTRY(0x14f15098, "CX20632", patch_conexant_auto),
969 .patch = patch_conexant_auto }, 969 HDA_CODEC_ENTRY(0x14f150a1, "CX20641", patch_conexant_auto),
970 { .id = 0x14f15069, .name = "CX20585", 970 HDA_CODEC_ENTRY(0x14f150a2, "CX20642", patch_conexant_auto),
971 .patch = patch_conexant_auto }, 971 HDA_CODEC_ENTRY(0x14f150ab, "CX20651", patch_conexant_auto),
972 { .id = 0x14f1506c, .name = "CX20588", 972 HDA_CODEC_ENTRY(0x14f150ac, "CX20652", patch_conexant_auto),
973 .patch = patch_conexant_auto }, 973 HDA_CODEC_ENTRY(0x14f150b8, "CX20664", patch_conexant_auto),
974 { .id = 0x14f1506e, .name = "CX20590", 974 HDA_CODEC_ENTRY(0x14f150b9, "CX20665", patch_conexant_auto),
975 .patch = patch_conexant_auto }, 975 HDA_CODEC_ENTRY(0x14f150f1, "CX20721", patch_conexant_auto),
976 { .id = 0x14f15097, .name = "CX20631", 976 HDA_CODEC_ENTRY(0x14f150f2, "CX20722", patch_conexant_auto),
977 .patch = patch_conexant_auto }, 977 HDA_CODEC_ENTRY(0x14f150f3, "CX20723", patch_conexant_auto),
978 { .id = 0x14f15098, .name = "CX20632", 978 HDA_CODEC_ENTRY(0x14f150f4, "CX20724", patch_conexant_auto),
979 .patch = patch_conexant_auto }, 979 HDA_CODEC_ENTRY(0x14f1510f, "CX20751/2", patch_conexant_auto),
980 { .id = 0x14f150a1, .name = "CX20641", 980 HDA_CODEC_ENTRY(0x14f15110, "CX20751/2", patch_conexant_auto),
981 .patch = patch_conexant_auto }, 981 HDA_CODEC_ENTRY(0x14f15111, "CX20753/4", patch_conexant_auto),
982 { .id = 0x14f150a2, .name = "CX20642", 982 HDA_CODEC_ENTRY(0x14f15113, "CX20755", patch_conexant_auto),
983 .patch = patch_conexant_auto }, 983 HDA_CODEC_ENTRY(0x14f15114, "CX20756", patch_conexant_auto),
984 { .id = 0x14f150ab, .name = "CX20651", 984 HDA_CODEC_ENTRY(0x14f15115, "CX20757", patch_conexant_auto),
985 .patch = patch_conexant_auto }, 985 HDA_CODEC_ENTRY(0x14f151d7, "CX20952", patch_conexant_auto),
986 { .id = 0x14f150ac, .name = "CX20652",
987 .patch = patch_conexant_auto },
988 { .id = 0x14f150b8, .name = "CX20664",
989 .patch = patch_conexant_auto },
990 { .id = 0x14f150b9, .name = "CX20665",
991 .patch = patch_conexant_auto },
992 { .id = 0x14f150f1, .name = "CX20721",
993 .patch = patch_conexant_auto },
994 { .id = 0x14f150f2, .name = "CX20722",
995 .patch = patch_conexant_auto },
996 { .id = 0x14f150f3, .name = "CX20723",
997 .patch = patch_conexant_auto },
998 { .id = 0x14f150f4, .name = "CX20724",
999 .patch = patch_conexant_auto },
1000 { .id = 0x14f1510f, .name = "CX20751/2",
1001 .patch = patch_conexant_auto },
1002 { .id = 0x14f15110, .name = "CX20751/2",
1003 .patch = patch_conexant_auto },
1004 { .id = 0x14f15111, .name = "CX20753/4",
1005 .patch = patch_conexant_auto },
1006 { .id = 0x14f15113, .name = "CX20755",
1007 .patch = patch_conexant_auto },
1008 { .id = 0x14f15114, .name = "CX20756",
1009 .patch = patch_conexant_auto },
1010 { .id = 0x14f15115, .name = "CX20757",
1011 .patch = patch_conexant_auto },
1012 { .id = 0x14f151d7, .name = "CX20952",
1013 .patch = patch_conexant_auto },
1014 {} /* terminator */ 986 {} /* terminator */
1015}; 987};
1016 988MODULE_DEVICE_TABLE(hdaudio, snd_hda_id_conexant);
1017MODULE_ALIAS("snd-hda-codec-id:14f15045");
1018MODULE_ALIAS("snd-hda-codec-id:14f15047");
1019MODULE_ALIAS("snd-hda-codec-id:14f15051");
1020MODULE_ALIAS("snd-hda-codec-id:14f15066");
1021MODULE_ALIAS("snd-hda-codec-id:14f15067");
1022MODULE_ALIAS("snd-hda-codec-id:14f15068");
1023MODULE_ALIAS("snd-hda-codec-id:14f15069");
1024MODULE_ALIAS("snd-hda-codec-id:14f1506c");
1025MODULE_ALIAS("snd-hda-codec-id:14f1506e");
1026MODULE_ALIAS("snd-hda-codec-id:14f15097");
1027MODULE_ALIAS("snd-hda-codec-id:14f15098");
1028MODULE_ALIAS("snd-hda-codec-id:14f150a1");
1029MODULE_ALIAS("snd-hda-codec-id:14f150a2");
1030MODULE_ALIAS("snd-hda-codec-id:14f150ab");
1031MODULE_ALIAS("snd-hda-codec-id:14f150ac");
1032MODULE_ALIAS("snd-hda-codec-id:14f150b8");
1033MODULE_ALIAS("snd-hda-codec-id:14f150b9");
1034MODULE_ALIAS("snd-hda-codec-id:14f150f1");
1035MODULE_ALIAS("snd-hda-codec-id:14f150f2");
1036MODULE_ALIAS("snd-hda-codec-id:14f150f3");
1037MODULE_ALIAS("snd-hda-codec-id:14f150f4");
1038MODULE_ALIAS("snd-hda-codec-id:14f1510f");
1039MODULE_ALIAS("snd-hda-codec-id:14f15110");
1040MODULE_ALIAS("snd-hda-codec-id:14f15111");
1041MODULE_ALIAS("snd-hda-codec-id:14f15113");
1042MODULE_ALIAS("snd-hda-codec-id:14f15114");
1043MODULE_ALIAS("snd-hda-codec-id:14f15115");
1044MODULE_ALIAS("snd-hda-codec-id:14f151d7");
1045 989
1046MODULE_LICENSE("GPL"); 990MODULE_LICENSE("GPL");
1047MODULE_DESCRIPTION("Conexant HD-audio codec"); 991MODULE_DESCRIPTION("Conexant HD-audio codec");
1048 992
1049static struct hda_codec_driver conexant_driver = { 993static struct hda_codec_driver conexant_driver = {
1050 .preset = snd_hda_preset_conexant, 994 .id = snd_hda_id_conexant,
1051}; 995};
1052 996
1053module_hda_codec_driver(conexant_driver); 997module_hda_codec_driver(conexant_driver);
diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c
index acbfbe087ee8..f503a883bef3 100644
--- a/sound/pci/hda/patch_hdmi.c
+++ b/sound/pci/hda/patch_hdmi.c
@@ -1775,6 +1775,16 @@ static bool check_non_pcm_per_cvt(struct hda_codec *codec, hda_nid_t cvt_nid)
1775 return non_pcm; 1775 return non_pcm;
1776} 1776}
1777 1777
1778/* There is a fixed mapping between audio pin node and display port
1779 * on current Intel platforms:
1780 * Pin Widget 5 - PORT B (port = 1 in i915 driver)
1781 * Pin Widget 6 - PORT C (port = 2 in i915 driver)
1782 * Pin Widget 7 - PORT D (port = 3 in i915 driver)
1783 */
1784static int intel_pin2port(hda_nid_t pin_nid)
1785{
1786 return pin_nid - 4;
1787}
1778 1788
1779/* 1789/*
1780 * HDMI callbacks 1790 * HDMI callbacks
@@ -1791,6 +1801,8 @@ static int generic_hdmi_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
1791 int pin_idx = hinfo_to_pin_index(codec, hinfo); 1801 int pin_idx = hinfo_to_pin_index(codec, hinfo);
1792 struct hdmi_spec_per_pin *per_pin = get_pin(spec, pin_idx); 1802 struct hdmi_spec_per_pin *per_pin = get_pin(spec, pin_idx);
1793 hda_nid_t pin_nid = per_pin->pin_nid; 1803 hda_nid_t pin_nid = per_pin->pin_nid;
1804 struct snd_pcm_runtime *runtime = substream->runtime;
1805 struct i915_audio_component *acomp = codec->bus->core.audio_component;
1794 bool non_pcm; 1806 bool non_pcm;
1795 int pinctl; 1807 int pinctl;
1796 1808
@@ -1807,6 +1819,13 @@ static int generic_hdmi_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
1807 intel_not_share_assigned_cvt(codec, pin_nid, per_pin->mux_idx); 1819 intel_not_share_assigned_cvt(codec, pin_nid, per_pin->mux_idx);
1808 } 1820 }
1809 1821
1822 /* Call sync_audio_rate to set the N/CTS/M manually if necessary */
1823 /* Todo: add DP1.2 MST audio support later */
1824 if (acomp && acomp->ops && acomp->ops->sync_audio_rate)
1825 acomp->ops->sync_audio_rate(acomp->dev,
1826 intel_pin2port(pin_nid),
1827 runtime->rate);
1828
1810 non_pcm = check_non_pcm_per_cvt(codec, cvt_nid); 1829 non_pcm = check_non_pcm_per_cvt(codec, cvt_nid);
1811 mutex_lock(&per_pin->lock); 1830 mutex_lock(&per_pin->lock);
1812 per_pin->channels = substream->runtime->channels; 1831 per_pin->channels = substream->runtime->channels;
@@ -2561,7 +2580,7 @@ static int simple_playback_pcm_open(struct hda_pcm_stream *hinfo,
2561 struct hdmi_spec *spec = codec->spec; 2580 struct hdmi_spec *spec = codec->spec;
2562 struct snd_pcm_hw_constraint_list *hw_constraints_channels = NULL; 2581 struct snd_pcm_hw_constraint_list *hw_constraints_channels = NULL;
2563 2582
2564 switch (codec->preset->id) { 2583 switch (codec->preset->vendor_id) {
2565 case 0x10de0002: 2584 case 0x10de0002:
2566 case 0x10de0003: 2585 case 0x10de0003:
2567 case 0x10de0005: 2586 case 0x10de0005:
@@ -2879,7 +2898,7 @@ static int nvhdmi_7x_8ch_build_controls(struct hda_codec *codec)
2879 snd_pcm_alt_chmaps, 8, 0, &chmap); 2898 snd_pcm_alt_chmaps, 8, 0, &chmap);
2880 if (err < 0) 2899 if (err < 0)
2881 return err; 2900 return err;
2882 switch (codec->preset->id) { 2901 switch (codec->preset->vendor_id) {
2883 case 0x10de0002: 2902 case 0x10de0002:
2884 case 0x10de0003: 2903 case 0x10de0003:
2885 case 0x10de0005: 2904 case 0x10de0005:
@@ -3487,138 +3506,77 @@ static int patch_via_hdmi(struct hda_codec *codec)
3487/* 3506/*
3488 * patch entries 3507 * patch entries
3489 */ 3508 */
3490static const struct hda_codec_preset snd_hda_preset_hdmi[] = { 3509static const struct hda_device_id snd_hda_id_hdmi[] = {
3491{ .id = 0x1002793c, .name = "RS600 HDMI", .patch = patch_atihdmi }, 3510HDA_CODEC_ENTRY(0x1002793c, "RS600 HDMI", patch_atihdmi),
3492{ .id = 0x10027919, .name = "RS600 HDMI", .patch = patch_atihdmi }, 3511HDA_CODEC_ENTRY(0x10027919, "RS600 HDMI", patch_atihdmi),
3493{ .id = 0x1002791a, .name = "RS690/780 HDMI", .patch = patch_atihdmi }, 3512HDA_CODEC_ENTRY(0x1002791a, "RS690/780 HDMI", patch_atihdmi),
3494{ .id = 0x1002aa01, .name = "R6xx HDMI", .patch = patch_atihdmi }, 3513HDA_CODEC_ENTRY(0x1002aa01, "R6xx HDMI", patch_atihdmi),
3495{ .id = 0x10951390, .name = "SiI1390 HDMI", .patch = patch_generic_hdmi }, 3514HDA_CODEC_ENTRY(0x10951390, "SiI1390 HDMI", patch_generic_hdmi),
3496{ .id = 0x10951392, .name = "SiI1392 HDMI", .patch = patch_generic_hdmi }, 3515HDA_CODEC_ENTRY(0x10951392, "SiI1392 HDMI", patch_generic_hdmi),
3497{ .id = 0x17e80047, .name = "Chrontel HDMI", .patch = patch_generic_hdmi }, 3516HDA_CODEC_ENTRY(0x17e80047, "Chrontel HDMI", patch_generic_hdmi),
3498{ .id = 0x10de0002, .name = "MCP77/78 HDMI", .patch = patch_nvhdmi_8ch_7x }, 3517HDA_CODEC_ENTRY(0x10de0002, "MCP77/78 HDMI", patch_nvhdmi_8ch_7x),
3499{ .id = 0x10de0003, .name = "MCP77/78 HDMI", .patch = patch_nvhdmi_8ch_7x }, 3518HDA_CODEC_ENTRY(0x10de0003, "MCP77/78 HDMI", patch_nvhdmi_8ch_7x),
3500{ .id = 0x10de0005, .name = "MCP77/78 HDMI", .patch = patch_nvhdmi_8ch_7x }, 3519HDA_CODEC_ENTRY(0x10de0005, "MCP77/78 HDMI", patch_nvhdmi_8ch_7x),
3501{ .id = 0x10de0006, .name = "MCP77/78 HDMI", .patch = patch_nvhdmi_8ch_7x }, 3520HDA_CODEC_ENTRY(0x10de0006, "MCP77/78 HDMI", patch_nvhdmi_8ch_7x),
3502{ .id = 0x10de0007, .name = "MCP79/7A HDMI", .patch = patch_nvhdmi_8ch_7x }, 3521HDA_CODEC_ENTRY(0x10de0007, "MCP79/7A HDMI", patch_nvhdmi_8ch_7x),
3503{ .id = 0x10de000a, .name = "GPU 0a HDMI/DP", .patch = patch_nvhdmi }, 3522HDA_CODEC_ENTRY(0x10de000a, "GPU 0a HDMI/DP", patch_nvhdmi),
3504{ .id = 0x10de000b, .name = "GPU 0b HDMI/DP", .patch = patch_nvhdmi }, 3523HDA_CODEC_ENTRY(0x10de000b, "GPU 0b HDMI/DP", patch_nvhdmi),
3505{ .id = 0x10de000c, .name = "MCP89 HDMI", .patch = patch_nvhdmi }, 3524HDA_CODEC_ENTRY(0x10de000c, "MCP89 HDMI", patch_nvhdmi),
3506{ .id = 0x10de000d, .name = "GPU 0d HDMI/DP", .patch = patch_nvhdmi }, 3525HDA_CODEC_ENTRY(0x10de000d, "GPU 0d HDMI/DP", patch_nvhdmi),
3507{ .id = 0x10de0010, .name = "GPU 10 HDMI/DP", .patch = patch_nvhdmi }, 3526HDA_CODEC_ENTRY(0x10de0010, "GPU 10 HDMI/DP", patch_nvhdmi),
3508{ .id = 0x10de0011, .name = "GPU 11 HDMI/DP", .patch = patch_nvhdmi }, 3527HDA_CODEC_ENTRY(0x10de0011, "GPU 11 HDMI/DP", patch_nvhdmi),
3509{ .id = 0x10de0012, .name = "GPU 12 HDMI/DP", .patch = patch_nvhdmi }, 3528HDA_CODEC_ENTRY(0x10de0012, "GPU 12 HDMI/DP", patch_nvhdmi),
3510{ .id = 0x10de0013, .name = "GPU 13 HDMI/DP", .patch = patch_nvhdmi }, 3529HDA_CODEC_ENTRY(0x10de0013, "GPU 13 HDMI/DP", patch_nvhdmi),
3511{ .id = 0x10de0014, .name = "GPU 14 HDMI/DP", .patch = patch_nvhdmi }, 3530HDA_CODEC_ENTRY(0x10de0014, "GPU 14 HDMI/DP", patch_nvhdmi),
3512{ .id = 0x10de0015, .name = "GPU 15 HDMI/DP", .patch = patch_nvhdmi }, 3531HDA_CODEC_ENTRY(0x10de0015, "GPU 15 HDMI/DP", patch_nvhdmi),
3513{ .id = 0x10de0016, .name = "GPU 16 HDMI/DP", .patch = patch_nvhdmi }, 3532HDA_CODEC_ENTRY(0x10de0016, "GPU 16 HDMI/DP", patch_nvhdmi),
3514/* 17 is known to be absent */ 3533/* 17 is known to be absent */
3515{ .id = 0x10de0018, .name = "GPU 18 HDMI/DP", .patch = patch_nvhdmi }, 3534HDA_CODEC_ENTRY(0x10de0018, "GPU 18 HDMI/DP", patch_nvhdmi),
3516{ .id = 0x10de0019, .name = "GPU 19 HDMI/DP", .patch = patch_nvhdmi }, 3535HDA_CODEC_ENTRY(0x10de0019, "GPU 19 HDMI/DP", patch_nvhdmi),
3517{ .id = 0x10de001a, .name = "GPU 1a HDMI/DP", .patch = patch_nvhdmi }, 3536HDA_CODEC_ENTRY(0x10de001a, "GPU 1a HDMI/DP", patch_nvhdmi),
3518{ .id = 0x10de001b, .name = "GPU 1b HDMI/DP", .patch = patch_nvhdmi }, 3537HDA_CODEC_ENTRY(0x10de001b, "GPU 1b HDMI/DP", patch_nvhdmi),
3519{ .id = 0x10de001c, .name = "GPU 1c HDMI/DP", .patch = patch_nvhdmi }, 3538HDA_CODEC_ENTRY(0x10de001c, "GPU 1c HDMI/DP", patch_nvhdmi),
3520{ .id = 0x10de0020, .name = "Tegra30 HDMI", .patch = patch_tegra_hdmi }, 3539HDA_CODEC_ENTRY(0x10de0020, "Tegra30 HDMI", patch_tegra_hdmi),
3521{ .id = 0x10de0022, .name = "Tegra114 HDMI", .patch = patch_tegra_hdmi }, 3540HDA_CODEC_ENTRY(0x10de0022, "Tegra114 HDMI", patch_tegra_hdmi),
3522{ .id = 0x10de0028, .name = "Tegra124 HDMI", .patch = patch_tegra_hdmi }, 3541HDA_CODEC_ENTRY(0x10de0028, "Tegra124 HDMI", patch_tegra_hdmi),
3523{ .id = 0x10de0029, .name = "Tegra210 HDMI/DP", .patch = patch_tegra_hdmi }, 3542HDA_CODEC_ENTRY(0x10de0029, "Tegra210 HDMI/DP", patch_tegra_hdmi),
3524{ .id = 0x10de0040, .name = "GPU 40 HDMI/DP", .patch = patch_nvhdmi }, 3543HDA_CODEC_ENTRY(0x10de0040, "GPU 40 HDMI/DP", patch_nvhdmi),
3525{ .id = 0x10de0041, .name = "GPU 41 HDMI/DP", .patch = patch_nvhdmi }, 3544HDA_CODEC_ENTRY(0x10de0041, "GPU 41 HDMI/DP", patch_nvhdmi),
3526{ .id = 0x10de0042, .name = "GPU 42 HDMI/DP", .patch = patch_nvhdmi }, 3545HDA_CODEC_ENTRY(0x10de0042, "GPU 42 HDMI/DP", patch_nvhdmi),
3527{ .id = 0x10de0043, .name = "GPU 43 HDMI/DP", .patch = patch_nvhdmi }, 3546HDA_CODEC_ENTRY(0x10de0043, "GPU 43 HDMI/DP", patch_nvhdmi),
3528{ .id = 0x10de0044, .name = "GPU 44 HDMI/DP", .patch = patch_nvhdmi }, 3547HDA_CODEC_ENTRY(0x10de0044, "GPU 44 HDMI/DP", patch_nvhdmi),
3529{ .id = 0x10de0051, .name = "GPU 51 HDMI/DP", .patch = patch_nvhdmi }, 3548HDA_CODEC_ENTRY(0x10de0051, "GPU 51 HDMI/DP", patch_nvhdmi),
3530{ .id = 0x10de0060, .name = "GPU 60 HDMI/DP", .patch = patch_nvhdmi }, 3549HDA_CODEC_ENTRY(0x10de0060, "GPU 60 HDMI/DP", patch_nvhdmi),
3531{ .id = 0x10de0067, .name = "MCP67 HDMI", .patch = patch_nvhdmi_2ch }, 3550HDA_CODEC_ENTRY(0x10de0067, "MCP67 HDMI", patch_nvhdmi_2ch),
3532{ .id = 0x10de0070, .name = "GPU 70 HDMI/DP", .patch = patch_nvhdmi }, 3551HDA_CODEC_ENTRY(0x10de0070, "GPU 70 HDMI/DP", patch_nvhdmi),
3533{ .id = 0x10de0071, .name = "GPU 71 HDMI/DP", .patch = patch_nvhdmi }, 3552HDA_CODEC_ENTRY(0x10de0071, "GPU 71 HDMI/DP", patch_nvhdmi),
3534{ .id = 0x10de0072, .name = "GPU 72 HDMI/DP", .patch = patch_nvhdmi }, 3553HDA_CODEC_ENTRY(0x10de0072, "GPU 72 HDMI/DP", patch_nvhdmi),
3535{ .id = 0x10de007d, .name = "GPU 7d HDMI/DP", .patch = patch_nvhdmi }, 3554HDA_CODEC_ENTRY(0x10de007d, "GPU 7d HDMI/DP", patch_nvhdmi),
3536{ .id = 0x10de8001, .name = "MCP73 HDMI", .patch = patch_nvhdmi_2ch }, 3555HDA_CODEC_ENTRY(0x10de8001, "MCP73 HDMI", patch_nvhdmi_2ch),
3537{ .id = 0x11069f80, .name = "VX900 HDMI/DP", .patch = patch_via_hdmi }, 3556HDA_CODEC_ENTRY(0x11069f80, "VX900 HDMI/DP", patch_via_hdmi),
3538{ .id = 0x11069f81, .name = "VX900 HDMI/DP", .patch = patch_via_hdmi }, 3557HDA_CODEC_ENTRY(0x11069f81, "VX900 HDMI/DP", patch_via_hdmi),
3539{ .id = 0x11069f84, .name = "VX11 HDMI/DP", .patch = patch_generic_hdmi }, 3558HDA_CODEC_ENTRY(0x11069f84, "VX11 HDMI/DP", patch_generic_hdmi),
3540{ .id = 0x11069f85, .name = "VX11 HDMI/DP", .patch = patch_generic_hdmi }, 3559HDA_CODEC_ENTRY(0x11069f85, "VX11 HDMI/DP", patch_generic_hdmi),
3541{ .id = 0x80860054, .name = "IbexPeak HDMI", .patch = patch_generic_hdmi }, 3560HDA_CODEC_ENTRY(0x80860054, "IbexPeak HDMI", patch_generic_hdmi),
3542{ .id = 0x80862801, .name = "Bearlake HDMI", .patch = patch_generic_hdmi }, 3561HDA_CODEC_ENTRY(0x80862801, "Bearlake HDMI", patch_generic_hdmi),
3543{ .id = 0x80862802, .name = "Cantiga HDMI", .patch = patch_generic_hdmi }, 3562HDA_CODEC_ENTRY(0x80862802, "Cantiga HDMI", patch_generic_hdmi),
3544{ .id = 0x80862803, .name = "Eaglelake HDMI", .patch = patch_generic_hdmi }, 3563HDA_CODEC_ENTRY(0x80862803, "Eaglelake HDMI", patch_generic_hdmi),
3545{ .id = 0x80862804, .name = "IbexPeak HDMI", .patch = patch_generic_hdmi }, 3564HDA_CODEC_ENTRY(0x80862804, "IbexPeak HDMI", patch_generic_hdmi),
3546{ .id = 0x80862805, .name = "CougarPoint HDMI", .patch = patch_generic_hdmi }, 3565HDA_CODEC_ENTRY(0x80862805, "CougarPoint HDMI", patch_generic_hdmi),
3547{ .id = 0x80862806, .name = "PantherPoint HDMI", .patch = patch_generic_hdmi }, 3566HDA_CODEC_ENTRY(0x80862806, "PantherPoint HDMI", patch_generic_hdmi),
3548{ .id = 0x80862807, .name = "Haswell HDMI", .patch = patch_generic_hdmi }, 3567HDA_CODEC_ENTRY(0x80862807, "Haswell HDMI", patch_generic_hdmi),
3549{ .id = 0x80862808, .name = "Broadwell HDMI", .patch = patch_generic_hdmi }, 3568HDA_CODEC_ENTRY(0x80862808, "Broadwell HDMI", patch_generic_hdmi),
3550{ .id = 0x80862809, .name = "Skylake HDMI", .patch = patch_generic_hdmi }, 3569HDA_CODEC_ENTRY(0x80862809, "Skylake HDMI", patch_generic_hdmi),
3551{ .id = 0x8086280a, .name = "Broxton HDMI", .patch = patch_generic_hdmi }, 3570HDA_CODEC_ENTRY(0x8086280a, "Broxton HDMI", patch_generic_hdmi),
3552{ .id = 0x80862880, .name = "CedarTrail HDMI", .patch = patch_generic_hdmi }, 3571HDA_CODEC_ENTRY(0x80862880, "CedarTrail HDMI", patch_generic_hdmi),
3553{ .id = 0x80862882, .name = "Valleyview2 HDMI", .patch = patch_generic_hdmi }, 3572HDA_CODEC_ENTRY(0x80862882, "Valleyview2 HDMI", patch_generic_hdmi),
3554{ .id = 0x80862883, .name = "Braswell HDMI", .patch = patch_generic_hdmi }, 3573HDA_CODEC_ENTRY(0x80862883, "Braswell HDMI", patch_generic_hdmi),
3555{ .id = 0x808629fb, .name = "Crestline HDMI", .patch = patch_generic_hdmi }, 3574HDA_CODEC_ENTRY(0x808629fb, "Crestline HDMI", patch_generic_hdmi),
3556/* special ID for generic HDMI */ 3575/* special ID for generic HDMI */
3557{ .id = HDA_CODEC_ID_GENERIC_HDMI, .patch = patch_generic_hdmi }, 3576HDA_CODEC_ENTRY(HDA_CODEC_ID_GENERIC_HDMI, "Generic HDMI", patch_generic_hdmi),
3558{} /* terminator */ 3577{} /* terminator */
3559}; 3578};
3560 3579MODULE_DEVICE_TABLE(hdaudio, snd_hda_id_hdmi);
3561MODULE_ALIAS("snd-hda-codec-id:1002793c");
3562MODULE_ALIAS("snd-hda-codec-id:10027919");
3563MODULE_ALIAS("snd-hda-codec-id:1002791a");
3564MODULE_ALIAS("snd-hda-codec-id:1002aa01");
3565MODULE_ALIAS("snd-hda-codec-id:10951390");
3566MODULE_ALIAS("snd-hda-codec-id:10951392");
3567MODULE_ALIAS("snd-hda-codec-id:10de0002");
3568MODULE_ALIAS("snd-hda-codec-id:10de0003");
3569MODULE_ALIAS("snd-hda-codec-id:10de0005");
3570MODULE_ALIAS("snd-hda-codec-id:10de0006");
3571MODULE_ALIAS("snd-hda-codec-id:10de0007");
3572MODULE_ALIAS("snd-hda-codec-id:10de000a");
3573MODULE_ALIAS("snd-hda-codec-id:10de000b");
3574MODULE_ALIAS("snd-hda-codec-id:10de000c");
3575MODULE_ALIAS("snd-hda-codec-id:10de000d");
3576MODULE_ALIAS("snd-hda-codec-id:10de0010");
3577MODULE_ALIAS("snd-hda-codec-id:10de0011");
3578MODULE_ALIAS("snd-hda-codec-id:10de0012");
3579MODULE_ALIAS("snd-hda-codec-id:10de0013");
3580MODULE_ALIAS("snd-hda-codec-id:10de0014");
3581MODULE_ALIAS("snd-hda-codec-id:10de0015");
3582MODULE_ALIAS("snd-hda-codec-id:10de0016");
3583MODULE_ALIAS("snd-hda-codec-id:10de0018");
3584MODULE_ALIAS("snd-hda-codec-id:10de0019");
3585MODULE_ALIAS("snd-hda-codec-id:10de001a");
3586MODULE_ALIAS("snd-hda-codec-id:10de001b");
3587MODULE_ALIAS("snd-hda-codec-id:10de001c");
3588MODULE_ALIAS("snd-hda-codec-id:10de0028");
3589MODULE_ALIAS("snd-hda-codec-id:10de0040");
3590MODULE_ALIAS("snd-hda-codec-id:10de0041");
3591MODULE_ALIAS("snd-hda-codec-id:10de0042");
3592MODULE_ALIAS("snd-hda-codec-id:10de0043");
3593MODULE_ALIAS("snd-hda-codec-id:10de0044");
3594MODULE_ALIAS("snd-hda-codec-id:10de0051");
3595MODULE_ALIAS("snd-hda-codec-id:10de0060");
3596MODULE_ALIAS("snd-hda-codec-id:10de0067");
3597MODULE_ALIAS("snd-hda-codec-id:10de0070");
3598MODULE_ALIAS("snd-hda-codec-id:10de0071");
3599MODULE_ALIAS("snd-hda-codec-id:10de0072");
3600MODULE_ALIAS("snd-hda-codec-id:10de007d");
3601MODULE_ALIAS("snd-hda-codec-id:10de8001");
3602MODULE_ALIAS("snd-hda-codec-id:11069f80");
3603MODULE_ALIAS("snd-hda-codec-id:11069f81");
3604MODULE_ALIAS("snd-hda-codec-id:11069f84");
3605MODULE_ALIAS("snd-hda-codec-id:11069f85");
3606MODULE_ALIAS("snd-hda-codec-id:17e80047");
3607MODULE_ALIAS("snd-hda-codec-id:80860054");
3608MODULE_ALIAS("snd-hda-codec-id:80862801");
3609MODULE_ALIAS("snd-hda-codec-id:80862802");
3610MODULE_ALIAS("snd-hda-codec-id:80862803");
3611MODULE_ALIAS("snd-hda-codec-id:80862804");
3612MODULE_ALIAS("snd-hda-codec-id:80862805");
3613MODULE_ALIAS("snd-hda-codec-id:80862806");
3614MODULE_ALIAS("snd-hda-codec-id:80862807");
3615MODULE_ALIAS("snd-hda-codec-id:80862808");
3616MODULE_ALIAS("snd-hda-codec-id:80862809");
3617MODULE_ALIAS("snd-hda-codec-id:8086280a");
3618MODULE_ALIAS("snd-hda-codec-id:80862880");
3619MODULE_ALIAS("snd-hda-codec-id:80862882");
3620MODULE_ALIAS("snd-hda-codec-id:80862883");
3621MODULE_ALIAS("snd-hda-codec-id:808629fb");
3622 3580
3623MODULE_LICENSE("GPL"); 3581MODULE_LICENSE("GPL");
3624MODULE_DESCRIPTION("HDMI HD-audio codec"); 3582MODULE_DESCRIPTION("HDMI HD-audio codec");
@@ -3627,7 +3585,7 @@ MODULE_ALIAS("snd-hda-codec-nvhdmi");
3627MODULE_ALIAS("snd-hda-codec-atihdmi"); 3585MODULE_ALIAS("snd-hda-codec-atihdmi");
3628 3586
3629static struct hda_codec_driver hdmi_driver = { 3587static struct hda_codec_driver hdmi_driver = {
3630 .preset = snd_hda_preset_hdmi, 3588 .id = snd_hda_id_hdmi,
3631}; 3589};
3632 3590
3633module_hda_codec_driver(hdmi_driver); 3591module_hda_codec_driver(hdmi_driver);
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index 16b8dcba5c12..2f7b065f9ac4 100644
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -822,17 +822,7 @@ static const struct hda_codec_ops alc_patch_ops = {
822}; 822};
823 823
824 824
825/* replace the codec chip_name with the given string */ 825#define alc_codec_rename(codec, name) snd_hda_codec_set_name(codec, name)
826static int alc_codec_rename(struct hda_codec *codec, const char *name)
827{
828 kfree(codec->core.chip_name);
829 codec->core.chip_name = kstrdup(name, GFP_KERNEL);
830 if (!codec->core.chip_name) {
831 alc_free(codec);
832 return -ENOMEM;
833 }
834 return 0;
835}
836 826
837/* 827/*
838 * Rename codecs appropriately from COEF value or subvendor id 828 * Rename codecs appropriately from COEF value or subvendor id
@@ -4596,6 +4586,7 @@ enum {
4596 ALC292_FIXUP_DELL_E7X, 4586 ALC292_FIXUP_DELL_E7X,
4597 ALC292_FIXUP_DISABLE_AAMIX, 4587 ALC292_FIXUP_DISABLE_AAMIX,
4598 ALC298_FIXUP_DELL1_MIC_NO_PRESENCE, 4588 ALC298_FIXUP_DELL1_MIC_NO_PRESENCE,
4589 ALC275_FIXUP_DELL_XPS,
4599}; 4590};
4600 4591
4601static const struct hda_fixup alc269_fixups[] = { 4592static const struct hda_fixup alc269_fixups[] = {
@@ -5165,6 +5156,17 @@ static const struct hda_fixup alc269_fixups[] = {
5165 .chained = true, 5156 .chained = true,
5166 .chain_id = ALC269_FIXUP_HEADSET_MODE 5157 .chain_id = ALC269_FIXUP_HEADSET_MODE
5167 }, 5158 },
5159 [ALC275_FIXUP_DELL_XPS] = {
5160 .type = HDA_FIXUP_VERBS,
5161 .v.verbs = (const struct hda_verb[]) {
5162 /* Enables internal speaker */
5163 {0x20, AC_VERB_SET_COEF_INDEX, 0x1f},
5164 {0x20, AC_VERB_SET_PROC_COEF, 0x00c0},
5165 {0x20, AC_VERB_SET_COEF_INDEX, 0x30},
5166 {0x20, AC_VERB_SET_PROC_COEF, 0x00b1},
5167 {}
5168 }
5169 },
5168}; 5170};
5169 5171
5170static const struct snd_pci_quirk alc269_fixup_tbl[] = { 5172static const struct snd_pci_quirk alc269_fixup_tbl[] = {
@@ -5179,6 +5181,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
5179 SND_PCI_QUIRK(0x1025, 0x0775, "Acer Aspire E1-572", ALC271_FIXUP_HP_GATE_MIC_JACK_E1_572), 5181 SND_PCI_QUIRK(0x1025, 0x0775, "Acer Aspire E1-572", ALC271_FIXUP_HP_GATE_MIC_JACK_E1_572),
5180 SND_PCI_QUIRK(0x1025, 0x079b, "Acer Aspire V5-573G", ALC282_FIXUP_ASPIRE_V5_PINS), 5182 SND_PCI_QUIRK(0x1025, 0x079b, "Acer Aspire V5-573G", ALC282_FIXUP_ASPIRE_V5_PINS),
5181 SND_PCI_QUIRK(0x1028, 0x0470, "Dell M101z", ALC269_FIXUP_DELL_M101Z), 5183 SND_PCI_QUIRK(0x1028, 0x0470, "Dell M101z", ALC269_FIXUP_DELL_M101Z),
5184 SND_PCI_QUIRK(0x1028, 0x054b, "Dell XPS one 2710", ALC275_FIXUP_DELL_XPS),
5182 SND_PCI_QUIRK(0x1028, 0x05ca, "Dell Latitude E7240", ALC292_FIXUP_DELL_E7X), 5185 SND_PCI_QUIRK(0x1028, 0x05ca, "Dell Latitude E7240", ALC292_FIXUP_DELL_E7X),
5183 SND_PCI_QUIRK(0x1028, 0x05cb, "Dell Latitude E7440", ALC292_FIXUP_DELL_E7X), 5186 SND_PCI_QUIRK(0x1028, 0x05cb, "Dell Latitude E7440", ALC292_FIXUP_DELL_E7X),
5184 SND_PCI_QUIRK(0x1028, 0x05da, "Dell Vostro 5460", ALC290_FIXUP_SUBWOOFER), 5187 SND_PCI_QUIRK(0x1028, 0x05da, "Dell Vostro 5460", ALC290_FIXUP_SUBWOOFER),
@@ -6627,78 +6630,70 @@ static int patch_alc680(struct hda_codec *codec)
6627/* 6630/*
6628 * patch entries 6631 * patch entries
6629 */ 6632 */
6630static const struct hda_codec_preset snd_hda_preset_realtek[] = { 6633static const struct hda_device_id snd_hda_id_realtek[] = {
6631 { .id = 0x10ec0221, .name = "ALC221", .patch = patch_alc269 }, 6634 HDA_CODEC_ENTRY(0x10ec0221, "ALC221", patch_alc269),
6632 { .id = 0x10ec0231, .name = "ALC231", .patch = patch_alc269 }, 6635 HDA_CODEC_ENTRY(0x10ec0231, "ALC231", patch_alc269),
6633 { .id = 0x10ec0233, .name = "ALC233", .patch = patch_alc269 }, 6636 HDA_CODEC_ENTRY(0x10ec0233, "ALC233", patch_alc269),
6634 { .id = 0x10ec0235, .name = "ALC233", .patch = patch_alc269 }, 6637 HDA_CODEC_ENTRY(0x10ec0235, "ALC233", patch_alc269),
6635 { .id = 0x10ec0255, .name = "ALC255", .patch = patch_alc269 }, 6638 HDA_CODEC_ENTRY(0x10ec0255, "ALC255", patch_alc269),
6636 { .id = 0x10ec0256, .name = "ALC256", .patch = patch_alc269 }, 6639 HDA_CODEC_ENTRY(0x10ec0256, "ALC256", patch_alc269),
6637 { .id = 0x10ec0260, .name = "ALC260", .patch = patch_alc260 }, 6640 HDA_CODEC_ENTRY(0x10ec0260, "ALC260", patch_alc260),
6638 { .id = 0x10ec0262, .name = "ALC262", .patch = patch_alc262 }, 6641 HDA_CODEC_ENTRY(0x10ec0262, "ALC262", patch_alc262),
6639 { .id = 0x10ec0267, .name = "ALC267", .patch = patch_alc268 }, 6642 HDA_CODEC_ENTRY(0x10ec0267, "ALC267", patch_alc268),
6640 { .id = 0x10ec0268, .name = "ALC268", .patch = patch_alc268 }, 6643 HDA_CODEC_ENTRY(0x10ec0268, "ALC268", patch_alc268),
6641 { .id = 0x10ec0269, .name = "ALC269", .patch = patch_alc269 }, 6644 HDA_CODEC_ENTRY(0x10ec0269, "ALC269", patch_alc269),
6642 { .id = 0x10ec0270, .name = "ALC270", .patch = patch_alc269 }, 6645 HDA_CODEC_ENTRY(0x10ec0270, "ALC270", patch_alc269),
6643 { .id = 0x10ec0272, .name = "ALC272", .patch = patch_alc662 }, 6646 HDA_CODEC_ENTRY(0x10ec0272, "ALC272", patch_alc662),
6644 { .id = 0x10ec0275, .name = "ALC275", .patch = patch_alc269 }, 6647 HDA_CODEC_ENTRY(0x10ec0275, "ALC275", patch_alc269),
6645 { .id = 0x10ec0276, .name = "ALC276", .patch = patch_alc269 }, 6648 HDA_CODEC_ENTRY(0x10ec0276, "ALC276", patch_alc269),
6646 { .id = 0x10ec0280, .name = "ALC280", .patch = patch_alc269 }, 6649 HDA_CODEC_ENTRY(0x10ec0280, "ALC280", patch_alc269),
6647 { .id = 0x10ec0282, .name = "ALC282", .patch = patch_alc269 }, 6650 HDA_CODEC_ENTRY(0x10ec0282, "ALC282", patch_alc269),
6648 { .id = 0x10ec0283, .name = "ALC283", .patch = patch_alc269 }, 6651 HDA_CODEC_ENTRY(0x10ec0283, "ALC283", patch_alc269),
6649 { .id = 0x10ec0284, .name = "ALC284", .patch = patch_alc269 }, 6652 HDA_CODEC_ENTRY(0x10ec0284, "ALC284", patch_alc269),
6650 { .id = 0x10ec0285, .name = "ALC285", .patch = patch_alc269 }, 6653 HDA_CODEC_ENTRY(0x10ec0285, "ALC285", patch_alc269),
6651 { .id = 0x10ec0286, .name = "ALC286", .patch = patch_alc269 }, 6654 HDA_CODEC_ENTRY(0x10ec0286, "ALC286", patch_alc269),
6652 { .id = 0x10ec0288, .name = "ALC288", .patch = patch_alc269 }, 6655 HDA_CODEC_ENTRY(0x10ec0288, "ALC288", patch_alc269),
6653 { .id = 0x10ec0290, .name = "ALC290", .patch = patch_alc269 }, 6656 HDA_CODEC_ENTRY(0x10ec0290, "ALC290", patch_alc269),
6654 { .id = 0x10ec0292, .name = "ALC292", .patch = patch_alc269 }, 6657 HDA_CODEC_ENTRY(0x10ec0292, "ALC292", patch_alc269),
6655 { .id = 0x10ec0293, .name = "ALC293", .patch = patch_alc269 }, 6658 HDA_CODEC_ENTRY(0x10ec0293, "ALC293", patch_alc269),
6656 { .id = 0x10ec0298, .name = "ALC298", .patch = patch_alc269 }, 6659 HDA_CODEC_ENTRY(0x10ec0298, "ALC298", patch_alc269),
6657 { .id = 0x10ec0861, .rev = 0x100340, .name = "ALC660", 6660 HDA_CODEC_REV_ENTRY(0x10ec0861, 0x100340, "ALC660", patch_alc861),
6658 .patch = patch_alc861 }, 6661 HDA_CODEC_ENTRY(0x10ec0660, "ALC660-VD", patch_alc861vd),
6659 { .id = 0x10ec0660, .name = "ALC660-VD", .patch = patch_alc861vd }, 6662 HDA_CODEC_ENTRY(0x10ec0861, "ALC861", patch_alc861),
6660 { .id = 0x10ec0861, .name = "ALC861", .patch = patch_alc861 }, 6663 HDA_CODEC_ENTRY(0x10ec0862, "ALC861-VD", patch_alc861vd),
6661 { .id = 0x10ec0862, .name = "ALC861-VD", .patch = patch_alc861vd }, 6664 HDA_CODEC_REV_ENTRY(0x10ec0662, 0x100002, "ALC662 rev2", patch_alc882),
6662 { .id = 0x10ec0662, .rev = 0x100002, .name = "ALC662 rev2", 6665 HDA_CODEC_REV_ENTRY(0x10ec0662, 0x100101, "ALC662 rev1", patch_alc662),
6663 .patch = patch_alc882 }, 6666 HDA_CODEC_REV_ENTRY(0x10ec0662, 0x100300, "ALC662 rev3", patch_alc662),
6664 { .id = 0x10ec0662, .rev = 0x100101, .name = "ALC662 rev1", 6667 HDA_CODEC_ENTRY(0x10ec0663, "ALC663", patch_alc662),
6665 .patch = patch_alc662 }, 6668 HDA_CODEC_ENTRY(0x10ec0665, "ALC665", patch_alc662),
6666 { .id = 0x10ec0662, .rev = 0x100300, .name = "ALC662 rev3", 6669 HDA_CODEC_ENTRY(0x10ec0667, "ALC667", patch_alc662),
6667 .patch = patch_alc662 }, 6670 HDA_CODEC_ENTRY(0x10ec0668, "ALC668", patch_alc662),
6668 { .id = 0x10ec0663, .name = "ALC663", .patch = patch_alc662 }, 6671 HDA_CODEC_ENTRY(0x10ec0670, "ALC670", patch_alc662),
6669 { .id = 0x10ec0665, .name = "ALC665", .patch = patch_alc662 }, 6672 HDA_CODEC_ENTRY(0x10ec0671, "ALC671", patch_alc662),
6670 { .id = 0x10ec0667, .name = "ALC667", .patch = patch_alc662 }, 6673 HDA_CODEC_ENTRY(0x10ec0680, "ALC680", patch_alc680),
6671 { .id = 0x10ec0668, .name = "ALC668", .patch = patch_alc662 }, 6674 HDA_CODEC_ENTRY(0x10ec0867, "ALC891", patch_alc882),
6672 { .id = 0x10ec0670, .name = "ALC670", .patch = patch_alc662 }, 6675 HDA_CODEC_ENTRY(0x10ec0880, "ALC880", patch_alc880),
6673 { .id = 0x10ec0671, .name = "ALC671", .patch = patch_alc662 }, 6676 HDA_CODEC_ENTRY(0x10ec0882, "ALC882", patch_alc882),
6674 { .id = 0x10ec0680, .name = "ALC680", .patch = patch_alc680 }, 6677 HDA_CODEC_ENTRY(0x10ec0883, "ALC883", patch_alc882),
6675 { .id = 0x10ec0867, .name = "ALC891", .patch = patch_alc882 }, 6678 HDA_CODEC_REV_ENTRY(0x10ec0885, 0x100101, "ALC889A", patch_alc882),
6676 { .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 }, 6679 HDA_CODEC_REV_ENTRY(0x10ec0885, 0x100103, "ALC889A", patch_alc882),
6677 { .id = 0x10ec0882, .name = "ALC882", .patch = patch_alc882 }, 6680 HDA_CODEC_ENTRY(0x10ec0885, "ALC885", patch_alc882),
6678 { .id = 0x10ec0883, .name = "ALC883", .patch = patch_alc882 }, 6681 HDA_CODEC_ENTRY(0x10ec0887, "ALC887", patch_alc882),
6679 { .id = 0x10ec0885, .rev = 0x100101, .name = "ALC889A", 6682 HDA_CODEC_REV_ENTRY(0x10ec0888, 0x100101, "ALC1200", patch_alc882),
6680 .patch = patch_alc882 }, 6683 HDA_CODEC_ENTRY(0x10ec0888, "ALC888", patch_alc882),
6681 { .id = 0x10ec0885, .rev = 0x100103, .name = "ALC889A", 6684 HDA_CODEC_ENTRY(0x10ec0889, "ALC889", patch_alc882),
6682 .patch = patch_alc882 }, 6685 HDA_CODEC_ENTRY(0x10ec0892, "ALC892", patch_alc662),
6683 { .id = 0x10ec0885, .name = "ALC885", .patch = patch_alc882 }, 6686 HDA_CODEC_ENTRY(0x10ec0899, "ALC898", patch_alc882),
6684 { .id = 0x10ec0887, .name = "ALC887", .patch = patch_alc882 }, 6687 HDA_CODEC_ENTRY(0x10ec0900, "ALC1150", patch_alc882),
6685 { .id = 0x10ec0888, .rev = 0x100101, .name = "ALC1200",
6686 .patch = patch_alc882 },
6687 { .id = 0x10ec0888, .name = "ALC888", .patch = patch_alc882 },
6688 { .id = 0x10ec0889, .name = "ALC889", .patch = patch_alc882 },
6689 { .id = 0x10ec0892, .name = "ALC892", .patch = patch_alc662 },
6690 { .id = 0x10ec0899, .name = "ALC898", .patch = patch_alc882 },
6691 { .id = 0x10ec0900, .name = "ALC1150", .patch = patch_alc882 },
6692 {} /* terminator */ 6688 {} /* terminator */
6693}; 6689};
6694 6690MODULE_DEVICE_TABLE(hdaudio, snd_hda_id_realtek);
6695MODULE_ALIAS("snd-hda-codec-id:10ec*");
6696 6691
6697MODULE_LICENSE("GPL"); 6692MODULE_LICENSE("GPL");
6698MODULE_DESCRIPTION("Realtek HD-audio codec"); 6693MODULE_DESCRIPTION("Realtek HD-audio codec");
6699 6694
6700static struct hda_codec_driver realtek_driver = { 6695static struct hda_codec_driver realtek_driver = {
6701 .preset = snd_hda_preset_realtek, 6696 .id = snd_hda_id_realtek,
6702}; 6697};
6703 6698
6704module_hda_codec_driver(realtek_driver); 6699module_hda_codec_driver(realtek_driver);
diff --git a/sound/pci/hda/patch_si3054.c b/sound/pci/hda/patch_si3054.c
index 5104bebb2286..ffda38c45509 100644
--- a/sound/pci/hda/patch_si3054.c
+++ b/sound/pci/hda/patch_si3054.c
@@ -289,41 +289,30 @@ static int patch_si3054(struct hda_codec *codec)
289/* 289/*
290 * patch entries 290 * patch entries
291 */ 291 */
292static const struct hda_codec_preset snd_hda_preset_si3054[] = { 292static const struct hda_device_id snd_hda_id_si3054[] = {
293 { .id = 0x163c3055, .name = "Si3054", .patch = patch_si3054 }, 293 HDA_CODEC_ENTRY(0x163c3055, "Si3054", patch_si3054),
294 { .id = 0x163c3155, .name = "Si3054", .patch = patch_si3054 }, 294 HDA_CODEC_ENTRY(0x163c3155, "Si3054", patch_si3054),
295 { .id = 0x11c13026, .name = "Si3054", .patch = patch_si3054 }, 295 HDA_CODEC_ENTRY(0x11c13026, "Si3054", patch_si3054),
296 { .id = 0x11c13055, .name = "Si3054", .patch = patch_si3054 }, 296 HDA_CODEC_ENTRY(0x11c13055, "Si3054", patch_si3054),
297 { .id = 0x11c13155, .name = "Si3054", .patch = patch_si3054 }, 297 HDA_CODEC_ENTRY(0x11c13155, "Si3054", patch_si3054),
298 { .id = 0x10573055, .name = "Si3054", .patch = patch_si3054 }, 298 HDA_CODEC_ENTRY(0x10573055, "Si3054", patch_si3054),
299 { .id = 0x10573057, .name = "Si3054", .patch = patch_si3054 }, 299 HDA_CODEC_ENTRY(0x10573057, "Si3054", patch_si3054),
300 { .id = 0x10573155, .name = "Si3054", .patch = patch_si3054 }, 300 HDA_CODEC_ENTRY(0x10573155, "Si3054", patch_si3054),
301 /* VIA HDA on Clevo m540 */ 301 /* VIA HDA on Clevo m540 */
302 { .id = 0x11063288, .name = "Si3054", .patch = patch_si3054 }, 302 HDA_CODEC_ENTRY(0x11063288, "Si3054", patch_si3054),
303 /* Asus A8J Modem (SM56) */ 303 /* Asus A8J Modem (SM56) */
304 { .id = 0x15433155, .name = "Si3054", .patch = patch_si3054 }, 304 HDA_CODEC_ENTRY(0x15433155, "Si3054", patch_si3054),
305 /* LG LW20 modem */ 305 /* LG LW20 modem */
306 { .id = 0x18540018, .name = "Si3054", .patch = patch_si3054 }, 306 HDA_CODEC_ENTRY(0x18540018, "Si3054", patch_si3054),
307 {} 307 {}
308}; 308};
309 309MODULE_DEVICE_TABLE(hdaudio, snd_hda_id_si3054);
310MODULE_ALIAS("snd-hda-codec-id:163c3055");
311MODULE_ALIAS("snd-hda-codec-id:163c3155");
312MODULE_ALIAS("snd-hda-codec-id:11c13026");
313MODULE_ALIAS("snd-hda-codec-id:11c13055");
314MODULE_ALIAS("snd-hda-codec-id:11c13155");
315MODULE_ALIAS("snd-hda-codec-id:10573055");
316MODULE_ALIAS("snd-hda-codec-id:10573057");
317MODULE_ALIAS("snd-hda-codec-id:10573155");
318MODULE_ALIAS("snd-hda-codec-id:11063288");
319MODULE_ALIAS("snd-hda-codec-id:15433155");
320MODULE_ALIAS("snd-hda-codec-id:18540018");
321 310
322MODULE_LICENSE("GPL"); 311MODULE_LICENSE("GPL");
323MODULE_DESCRIPTION("Si3054 HD-audio modem codec"); 312MODULE_DESCRIPTION("Si3054 HD-audio modem codec");
324 313
325static struct hda_codec_driver si3054_driver = { 314static struct hda_codec_driver si3054_driver = {
326 .preset = snd_hda_preset_si3054, 315 .id = snd_hda_id_si3054,
327}; 316};
328 317
329module_hda_codec_driver(si3054_driver); 318module_hda_codec_driver(si3054_driver);
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c
index def5cc8dff02..826122d8acee 100644
--- a/sound/pci/hda/patch_sigmatel.c
+++ b/sound/pci/hda/patch_sigmatel.c
@@ -702,6 +702,7 @@ static bool hp_bnb2011_with_dock(struct hda_codec *codec)
702static bool hp_blike_system(u32 subsystem_id) 702static bool hp_blike_system(u32 subsystem_id)
703{ 703{
704 switch (subsystem_id) { 704 switch (subsystem_id) {
705 case 0x103c1473: /* HP ProBook 6550b */
705 case 0x103c1520: 706 case 0x103c1520:
706 case 0x103c1521: 707 case 0x103c1521:
707 case 0x103c1523: 708 case 0x103c1523:
@@ -5012,121 +5013,119 @@ static int patch_stac9872(struct hda_codec *codec)
5012/* 5013/*
5013 * patch entries 5014 * patch entries
5014 */ 5015 */
5015static const struct hda_codec_preset snd_hda_preset_sigmatel[] = { 5016static const struct hda_device_id snd_hda_id_sigmatel[] = {
5016 { .id = 0x83847690, .name = "STAC9200", .patch = patch_stac9200 }, 5017 HDA_CODEC_ENTRY(0x83847690, "STAC9200", patch_stac9200),
5017 { .id = 0x83847882, .name = "STAC9220 A1", .patch = patch_stac922x }, 5018 HDA_CODEC_ENTRY(0x83847882, "STAC9220 A1", patch_stac922x),
5018 { .id = 0x83847680, .name = "STAC9221 A1", .patch = patch_stac922x }, 5019 HDA_CODEC_ENTRY(0x83847680, "STAC9221 A1", patch_stac922x),
5019 { .id = 0x83847880, .name = "STAC9220 A2", .patch = patch_stac922x }, 5020 HDA_CODEC_ENTRY(0x83847880, "STAC9220 A2", patch_stac922x),
5020 { .id = 0x83847681, .name = "STAC9220D/9223D A2", .patch = patch_stac922x }, 5021 HDA_CODEC_ENTRY(0x83847681, "STAC9220D/9223D A2", patch_stac922x),
5021 { .id = 0x83847682, .name = "STAC9221 A2", .patch = patch_stac922x }, 5022 HDA_CODEC_ENTRY(0x83847682, "STAC9221 A2", patch_stac922x),
5022 { .id = 0x83847683, .name = "STAC9221D A2", .patch = patch_stac922x }, 5023 HDA_CODEC_ENTRY(0x83847683, "STAC9221D A2", patch_stac922x),
5023 { .id = 0x83847618, .name = "STAC9227", .patch = patch_stac927x }, 5024 HDA_CODEC_ENTRY(0x83847618, "STAC9227", patch_stac927x),
5024 { .id = 0x83847619, .name = "STAC9227", .patch = patch_stac927x }, 5025 HDA_CODEC_ENTRY(0x83847619, "STAC9227", patch_stac927x),
5025 { .id = 0x83847616, .name = "STAC9228", .patch = patch_stac927x }, 5026 HDA_CODEC_ENTRY(0x83847616, "STAC9228", patch_stac927x),
5026 { .id = 0x83847617, .name = "STAC9228", .patch = patch_stac927x }, 5027 HDA_CODEC_ENTRY(0x83847617, "STAC9228", patch_stac927x),
5027 { .id = 0x83847614, .name = "STAC9229", .patch = patch_stac927x }, 5028 HDA_CODEC_ENTRY(0x83847614, "STAC9229", patch_stac927x),
5028 { .id = 0x83847615, .name = "STAC9229", .patch = patch_stac927x }, 5029 HDA_CODEC_ENTRY(0x83847615, "STAC9229", patch_stac927x),
5029 { .id = 0x83847620, .name = "STAC9274", .patch = patch_stac927x }, 5030 HDA_CODEC_ENTRY(0x83847620, "STAC9274", patch_stac927x),
5030 { .id = 0x83847621, .name = "STAC9274D", .patch = patch_stac927x }, 5031 HDA_CODEC_ENTRY(0x83847621, "STAC9274D", patch_stac927x),
5031 { .id = 0x83847622, .name = "STAC9273X", .patch = patch_stac927x }, 5032 HDA_CODEC_ENTRY(0x83847622, "STAC9273X", patch_stac927x),
5032 { .id = 0x83847623, .name = "STAC9273D", .patch = patch_stac927x }, 5033 HDA_CODEC_ENTRY(0x83847623, "STAC9273D", patch_stac927x),
5033 { .id = 0x83847624, .name = "STAC9272X", .patch = patch_stac927x }, 5034 HDA_CODEC_ENTRY(0x83847624, "STAC9272X", patch_stac927x),
5034 { .id = 0x83847625, .name = "STAC9272D", .patch = patch_stac927x }, 5035 HDA_CODEC_ENTRY(0x83847625, "STAC9272D", patch_stac927x),
5035 { .id = 0x83847626, .name = "STAC9271X", .patch = patch_stac927x }, 5036 HDA_CODEC_ENTRY(0x83847626, "STAC9271X", patch_stac927x),
5036 { .id = 0x83847627, .name = "STAC9271D", .patch = patch_stac927x }, 5037 HDA_CODEC_ENTRY(0x83847627, "STAC9271D", patch_stac927x),
5037 { .id = 0x83847628, .name = "STAC9274X5NH", .patch = patch_stac927x }, 5038 HDA_CODEC_ENTRY(0x83847628, "STAC9274X5NH", patch_stac927x),
5038 { .id = 0x83847629, .name = "STAC9274D5NH", .patch = patch_stac927x }, 5039 HDA_CODEC_ENTRY(0x83847629, "STAC9274D5NH", patch_stac927x),
5039 { .id = 0x83847632, .name = "STAC9202", .patch = patch_stac925x }, 5040 HDA_CODEC_ENTRY(0x83847632, "STAC9202", patch_stac925x),
5040 { .id = 0x83847633, .name = "STAC9202D", .patch = patch_stac925x }, 5041 HDA_CODEC_ENTRY(0x83847633, "STAC9202D", patch_stac925x),
5041 { .id = 0x83847634, .name = "STAC9250", .patch = patch_stac925x }, 5042 HDA_CODEC_ENTRY(0x83847634, "STAC9250", patch_stac925x),
5042 { .id = 0x83847635, .name = "STAC9250D", .patch = patch_stac925x }, 5043 HDA_CODEC_ENTRY(0x83847635, "STAC9250D", patch_stac925x),
5043 { .id = 0x83847636, .name = "STAC9251", .patch = patch_stac925x }, 5044 HDA_CODEC_ENTRY(0x83847636, "STAC9251", patch_stac925x),
5044 { .id = 0x83847637, .name = "STAC9250D", .patch = patch_stac925x }, 5045 HDA_CODEC_ENTRY(0x83847637, "STAC9250D", patch_stac925x),
5045 { .id = 0x83847645, .name = "92HD206X", .patch = patch_stac927x }, 5046 HDA_CODEC_ENTRY(0x83847645, "92HD206X", patch_stac927x),
5046 { .id = 0x83847646, .name = "92HD206D", .patch = patch_stac927x }, 5047 HDA_CODEC_ENTRY(0x83847646, "92HD206D", patch_stac927x),
5047 /* The following does not take into account .id=0x83847661 when subsys = 5048 /* The following does not take into account .id=0x83847661 when subsys =
5048 * 104D0C00 which is STAC9225s. Because of this, some SZ Notebooks are 5049 * 104D0C00 which is STAC9225s. Because of this, some SZ Notebooks are
5049 * currently not fully supported. 5050 * currently not fully supported.
5050 */ 5051 */
5051 { .id = 0x83847661, .name = "CXD9872RD/K", .patch = patch_stac9872 }, 5052 HDA_CODEC_ENTRY(0x83847661, "CXD9872RD/K", patch_stac9872),
5052 { .id = 0x83847662, .name = "STAC9872AK", .patch = patch_stac9872 }, 5053 HDA_CODEC_ENTRY(0x83847662, "STAC9872AK", patch_stac9872),
5053 { .id = 0x83847664, .name = "CXD9872AKD", .patch = patch_stac9872 }, 5054 HDA_CODEC_ENTRY(0x83847664, "CXD9872AKD", patch_stac9872),
5054 { .id = 0x83847698, .name = "STAC9205", .patch = patch_stac9205 }, 5055 HDA_CODEC_ENTRY(0x83847698, "STAC9205", patch_stac9205),
5055 { .id = 0x838476a0, .name = "STAC9205", .patch = patch_stac9205 }, 5056 HDA_CODEC_ENTRY(0x838476a0, "STAC9205", patch_stac9205),
5056 { .id = 0x838476a1, .name = "STAC9205D", .patch = patch_stac9205 }, 5057 HDA_CODEC_ENTRY(0x838476a1, "STAC9205D", patch_stac9205),
5057 { .id = 0x838476a2, .name = "STAC9204", .patch = patch_stac9205 }, 5058 HDA_CODEC_ENTRY(0x838476a2, "STAC9204", patch_stac9205),
5058 { .id = 0x838476a3, .name = "STAC9204D", .patch = patch_stac9205 }, 5059 HDA_CODEC_ENTRY(0x838476a3, "STAC9204D", patch_stac9205),
5059 { .id = 0x838476a4, .name = "STAC9255", .patch = patch_stac9205 }, 5060 HDA_CODEC_ENTRY(0x838476a4, "STAC9255", patch_stac9205),
5060 { .id = 0x838476a5, .name = "STAC9255D", .patch = patch_stac9205 }, 5061 HDA_CODEC_ENTRY(0x838476a5, "STAC9255D", patch_stac9205),
5061 { .id = 0x838476a6, .name = "STAC9254", .patch = patch_stac9205 }, 5062 HDA_CODEC_ENTRY(0x838476a6, "STAC9254", patch_stac9205),
5062 { .id = 0x838476a7, .name = "STAC9254D", .patch = patch_stac9205 }, 5063 HDA_CODEC_ENTRY(0x838476a7, "STAC9254D", patch_stac9205),
5063 { .id = 0x111d7603, .name = "92HD75B3X5", .patch = patch_stac92hd71bxx}, 5064 HDA_CODEC_ENTRY(0x111d7603, "92HD75B3X5", patch_stac92hd71bxx),
5064 { .id = 0x111d7604, .name = "92HD83C1X5", .patch = patch_stac92hd83xxx}, 5065 HDA_CODEC_ENTRY(0x111d7604, "92HD83C1X5", patch_stac92hd83xxx),
5065 { .id = 0x111d76d4, .name = "92HD83C1C5", .patch = patch_stac92hd83xxx}, 5066 HDA_CODEC_ENTRY(0x111d76d4, "92HD83C1C5", patch_stac92hd83xxx),
5066 { .id = 0x111d7605, .name = "92HD81B1X5", .patch = patch_stac92hd83xxx}, 5067 HDA_CODEC_ENTRY(0x111d7605, "92HD81B1X5", patch_stac92hd83xxx),
5067 { .id = 0x111d76d5, .name = "92HD81B1C5", .patch = patch_stac92hd83xxx}, 5068 HDA_CODEC_ENTRY(0x111d76d5, "92HD81B1C5", patch_stac92hd83xxx),
5068 { .id = 0x111d76d1, .name = "92HD87B1/3", .patch = patch_stac92hd83xxx}, 5069 HDA_CODEC_ENTRY(0x111d76d1, "92HD87B1/3", patch_stac92hd83xxx),
5069 { .id = 0x111d76d9, .name = "92HD87B2/4", .patch = patch_stac92hd83xxx}, 5070 HDA_CODEC_ENTRY(0x111d76d9, "92HD87B2/4", patch_stac92hd83xxx),
5070 { .id = 0x111d7666, .name = "92HD88B3", .patch = patch_stac92hd83xxx}, 5071 HDA_CODEC_ENTRY(0x111d7666, "92HD88B3", patch_stac92hd83xxx),
5071 { .id = 0x111d7667, .name = "92HD88B1", .patch = patch_stac92hd83xxx}, 5072 HDA_CODEC_ENTRY(0x111d7667, "92HD88B1", patch_stac92hd83xxx),
5072 { .id = 0x111d7668, .name = "92HD88B2", .patch = patch_stac92hd83xxx}, 5073 HDA_CODEC_ENTRY(0x111d7668, "92HD88B2", patch_stac92hd83xxx),
5073 { .id = 0x111d7669, .name = "92HD88B4", .patch = patch_stac92hd83xxx}, 5074 HDA_CODEC_ENTRY(0x111d7669, "92HD88B4", patch_stac92hd83xxx),
5074 { .id = 0x111d7608, .name = "92HD75B2X5", .patch = patch_stac92hd71bxx}, 5075 HDA_CODEC_ENTRY(0x111d7608, "92HD75B2X5", patch_stac92hd71bxx),
5075 { .id = 0x111d7674, .name = "92HD73D1X5", .patch = patch_stac92hd73xx }, 5076 HDA_CODEC_ENTRY(0x111d7674, "92HD73D1X5", patch_stac92hd73xx),
5076 { .id = 0x111d7675, .name = "92HD73C1X5", .patch = patch_stac92hd73xx }, 5077 HDA_CODEC_ENTRY(0x111d7675, "92HD73C1X5", patch_stac92hd73xx),
5077 { .id = 0x111d7676, .name = "92HD73E1X5", .patch = patch_stac92hd73xx }, 5078 HDA_CODEC_ENTRY(0x111d7676, "92HD73E1X5", patch_stac92hd73xx),
5078 { .id = 0x111d7695, .name = "92HD95", .patch = patch_stac92hd95 }, 5079 HDA_CODEC_ENTRY(0x111d7695, "92HD95", patch_stac92hd95),
5079 { .id = 0x111d76b0, .name = "92HD71B8X", .patch = patch_stac92hd71bxx }, 5080 HDA_CODEC_ENTRY(0x111d76b0, "92HD71B8X", patch_stac92hd71bxx),
5080 { .id = 0x111d76b1, .name = "92HD71B8X", .patch = patch_stac92hd71bxx }, 5081 HDA_CODEC_ENTRY(0x111d76b1, "92HD71B8X", patch_stac92hd71bxx),
5081 { .id = 0x111d76b2, .name = "92HD71B7X", .patch = patch_stac92hd71bxx }, 5082 HDA_CODEC_ENTRY(0x111d76b2, "92HD71B7X", patch_stac92hd71bxx),
5082 { .id = 0x111d76b3, .name = "92HD71B7X", .patch = patch_stac92hd71bxx }, 5083 HDA_CODEC_ENTRY(0x111d76b3, "92HD71B7X", patch_stac92hd71bxx),
5083 { .id = 0x111d76b4, .name = "92HD71B6X", .patch = patch_stac92hd71bxx }, 5084 HDA_CODEC_ENTRY(0x111d76b4, "92HD71B6X", patch_stac92hd71bxx),
5084 { .id = 0x111d76b5, .name = "92HD71B6X", .patch = patch_stac92hd71bxx }, 5085 HDA_CODEC_ENTRY(0x111d76b5, "92HD71B6X", patch_stac92hd71bxx),
5085 { .id = 0x111d76b6, .name = "92HD71B5X", .patch = patch_stac92hd71bxx }, 5086 HDA_CODEC_ENTRY(0x111d76b6, "92HD71B5X", patch_stac92hd71bxx),
5086 { .id = 0x111d76b7, .name = "92HD71B5X", .patch = patch_stac92hd71bxx }, 5087 HDA_CODEC_ENTRY(0x111d76b7, "92HD71B5X", patch_stac92hd71bxx),
5087 { .id = 0x111d76c0, .name = "92HD89C3", .patch = patch_stac92hd73xx }, 5088 HDA_CODEC_ENTRY(0x111d76c0, "92HD89C3", patch_stac92hd73xx),
5088 { .id = 0x111d76c1, .name = "92HD89C2", .patch = patch_stac92hd73xx }, 5089 HDA_CODEC_ENTRY(0x111d76c1, "92HD89C2", patch_stac92hd73xx),
5089 { .id = 0x111d76c2, .name = "92HD89C1", .patch = patch_stac92hd73xx }, 5090 HDA_CODEC_ENTRY(0x111d76c2, "92HD89C1", patch_stac92hd73xx),
5090 { .id = 0x111d76c3, .name = "92HD89B3", .patch = patch_stac92hd73xx }, 5091 HDA_CODEC_ENTRY(0x111d76c3, "92HD89B3", patch_stac92hd73xx),
5091 { .id = 0x111d76c4, .name = "92HD89B2", .patch = patch_stac92hd73xx }, 5092 HDA_CODEC_ENTRY(0x111d76c4, "92HD89B2", patch_stac92hd73xx),
5092 { .id = 0x111d76c5, .name = "92HD89B1", .patch = patch_stac92hd73xx }, 5093 HDA_CODEC_ENTRY(0x111d76c5, "92HD89B1", patch_stac92hd73xx),
5093 { .id = 0x111d76c6, .name = "92HD89E3", .patch = patch_stac92hd73xx }, 5094 HDA_CODEC_ENTRY(0x111d76c6, "92HD89E3", patch_stac92hd73xx),
5094 { .id = 0x111d76c7, .name = "92HD89E2", .patch = patch_stac92hd73xx }, 5095 HDA_CODEC_ENTRY(0x111d76c7, "92HD89E2", patch_stac92hd73xx),
5095 { .id = 0x111d76c8, .name = "92HD89E1", .patch = patch_stac92hd73xx }, 5096 HDA_CODEC_ENTRY(0x111d76c8, "92HD89E1", patch_stac92hd73xx),
5096 { .id = 0x111d76c9, .name = "92HD89D3", .patch = patch_stac92hd73xx }, 5097 HDA_CODEC_ENTRY(0x111d76c9, "92HD89D3", patch_stac92hd73xx),
5097 { .id = 0x111d76ca, .name = "92HD89D2", .patch = patch_stac92hd73xx }, 5098 HDA_CODEC_ENTRY(0x111d76ca, "92HD89D2", patch_stac92hd73xx),
5098 { .id = 0x111d76cb, .name = "92HD89D1", .patch = patch_stac92hd73xx }, 5099 HDA_CODEC_ENTRY(0x111d76cb, "92HD89D1", patch_stac92hd73xx),
5099 { .id = 0x111d76cc, .name = "92HD89F3", .patch = patch_stac92hd73xx }, 5100 HDA_CODEC_ENTRY(0x111d76cc, "92HD89F3", patch_stac92hd73xx),
5100 { .id = 0x111d76cd, .name = "92HD89F2", .patch = patch_stac92hd73xx }, 5101 HDA_CODEC_ENTRY(0x111d76cd, "92HD89F2", patch_stac92hd73xx),
5101 { .id = 0x111d76ce, .name = "92HD89F1", .patch = patch_stac92hd73xx }, 5102 HDA_CODEC_ENTRY(0x111d76ce, "92HD89F1", patch_stac92hd73xx),
5102 { .id = 0x111d76df, .name = "92HD93BXX", .patch = patch_stac92hd83xxx}, 5103 HDA_CODEC_ENTRY(0x111d76df, "92HD93BXX", patch_stac92hd83xxx),
5103 { .id = 0x111d76e0, .name = "92HD91BXX", .patch = patch_stac92hd83xxx}, 5104 HDA_CODEC_ENTRY(0x111d76e0, "92HD91BXX", patch_stac92hd83xxx),
5104 { .id = 0x111d76e3, .name = "92HD98BXX", .patch = patch_stac92hd83xxx}, 5105 HDA_CODEC_ENTRY(0x111d76e3, "92HD98BXX", patch_stac92hd83xxx),
5105 { .id = 0x111d76e5, .name = "92HD99BXX", .patch = patch_stac92hd83xxx}, 5106 HDA_CODEC_ENTRY(0x111d76e5, "92HD99BXX", patch_stac92hd83xxx),
5106 { .id = 0x111d76e7, .name = "92HD90BXX", .patch = patch_stac92hd83xxx}, 5107 HDA_CODEC_ENTRY(0x111d76e7, "92HD90BXX", patch_stac92hd83xxx),
5107 { .id = 0x111d76e8, .name = "92HD66B1X5", .patch = patch_stac92hd83xxx}, 5108 HDA_CODEC_ENTRY(0x111d76e8, "92HD66B1X5", patch_stac92hd83xxx),
5108 { .id = 0x111d76e9, .name = "92HD66B2X5", .patch = patch_stac92hd83xxx}, 5109 HDA_CODEC_ENTRY(0x111d76e9, "92HD66B2X5", patch_stac92hd83xxx),
5109 { .id = 0x111d76ea, .name = "92HD66B3X5", .patch = patch_stac92hd83xxx}, 5110 HDA_CODEC_ENTRY(0x111d76ea, "92HD66B3X5", patch_stac92hd83xxx),
5110 { .id = 0x111d76eb, .name = "92HD66C1X5", .patch = patch_stac92hd83xxx}, 5111 HDA_CODEC_ENTRY(0x111d76eb, "92HD66C1X5", patch_stac92hd83xxx),
5111 { .id = 0x111d76ec, .name = "92HD66C2X5", .patch = patch_stac92hd83xxx}, 5112 HDA_CODEC_ENTRY(0x111d76ec, "92HD66C2X5", patch_stac92hd83xxx),
5112 { .id = 0x111d76ed, .name = "92HD66C3X5", .patch = patch_stac92hd83xxx}, 5113 HDA_CODEC_ENTRY(0x111d76ed, "92HD66C3X5", patch_stac92hd83xxx),
5113 { .id = 0x111d76ee, .name = "92HD66B1X3", .patch = patch_stac92hd83xxx}, 5114 HDA_CODEC_ENTRY(0x111d76ee, "92HD66B1X3", patch_stac92hd83xxx),
5114 { .id = 0x111d76ef, .name = "92HD66B2X3", .patch = patch_stac92hd83xxx}, 5115 HDA_CODEC_ENTRY(0x111d76ef, "92HD66B2X3", patch_stac92hd83xxx),
5115 { .id = 0x111d76f0, .name = "92HD66B3X3", .patch = patch_stac92hd83xxx}, 5116 HDA_CODEC_ENTRY(0x111d76f0, "92HD66B3X3", patch_stac92hd83xxx),
5116 { .id = 0x111d76f1, .name = "92HD66C1X3", .patch = patch_stac92hd83xxx}, 5117 HDA_CODEC_ENTRY(0x111d76f1, "92HD66C1X3", patch_stac92hd83xxx),
5117 { .id = 0x111d76f2, .name = "92HD66C2X3", .patch = patch_stac92hd83xxx}, 5118 HDA_CODEC_ENTRY(0x111d76f2, "92HD66C2X3", patch_stac92hd83xxx),
5118 { .id = 0x111d76f3, .name = "92HD66C3/65", .patch = patch_stac92hd83xxx}, 5119 HDA_CODEC_ENTRY(0x111d76f3, "92HD66C3/65", patch_stac92hd83xxx),
5119 {} /* terminator */ 5120 {} /* terminator */
5120}; 5121};
5121 5122MODULE_DEVICE_TABLE(hdaudio, snd_hda_id_sigmatel);
5122MODULE_ALIAS("snd-hda-codec-id:8384*");
5123MODULE_ALIAS("snd-hda-codec-id:111d*");
5124 5123
5125MODULE_LICENSE("GPL"); 5124MODULE_LICENSE("GPL");
5126MODULE_DESCRIPTION("IDT/Sigmatel HD-audio codec"); 5125MODULE_DESCRIPTION("IDT/Sigmatel HD-audio codec");
5127 5126
5128static struct hda_codec_driver sigmatel_driver = { 5127static struct hda_codec_driver sigmatel_driver = {
5129 .preset = snd_hda_preset_sigmatel, 5128 .id = snd_hda_id_sigmatel,
5130}; 5129};
5131 5130
5132module_hda_codec_driver(sigmatel_driver); 5131module_hda_codec_driver(sigmatel_driver);
diff --git a/sound/pci/hda/patch_via.c b/sound/pci/hda/patch_via.c
index da5366405eda..fc30d1e8aa76 100644
--- a/sound/pci/hda/patch_via.c
+++ b/sound/pci/hda/patch_via.c
@@ -785,21 +785,11 @@ static int patch_vt1708S(struct hda_codec *codec)
785 override_mic_boost(codec, 0x1e, 0, 3, 40); 785 override_mic_boost(codec, 0x1e, 0, 3, 40);
786 786
787 /* correct names for VT1708BCE */ 787 /* correct names for VT1708BCE */
788 if (get_codec_type(codec) == VT1708BCE) { 788 if (get_codec_type(codec) == VT1708BCE)
789 kfree(codec->core.chip_name); 789 snd_hda_codec_set_name(codec, "VT1708BCE");
790 codec->core.chip_name = kstrdup("VT1708BCE", GFP_KERNEL);
791 snprintf(codec->card->mixername,
792 sizeof(codec->card->mixername),
793 "%s %s", codec->core.vendor_name, codec->core.chip_name);
794 }
795 /* correct names for VT1705 */ 790 /* correct names for VT1705 */
796 if (codec->core.vendor_id == 0x11064397) { 791 if (codec->core.vendor_id == 0x11064397)
797 kfree(codec->core.chip_name); 792 snd_hda_codec_set_name(codec, "VT1705");
798 codec->core.chip_name = kstrdup("VT1705", GFP_KERNEL);
799 snprintf(codec->card->mixername,
800 sizeof(codec->card->mixername),
801 "%s %s", codec->core.vendor_name, codec->core.chip_name);
802 }
803 793
804 /* automatic parse from the BIOS config */ 794 /* automatic parse from the BIOS config */
805 err = via_parse_auto_config(codec); 795 err = via_parse_auto_config(codec);
@@ -1210,109 +1200,64 @@ static int patch_vt3476(struct hda_codec *codec)
1210/* 1200/*
1211 * patch entries 1201 * patch entries
1212 */ 1202 */
1213static const struct hda_codec_preset snd_hda_preset_via[] = { 1203static const struct hda_device_id snd_hda_id_via[] = {
1214 { .id = 0x11061708, .name = "VT1708", .patch = patch_vt1708}, 1204 HDA_CODEC_ENTRY(0x11061708, "VT1708", patch_vt1708),
1215 { .id = 0x11061709, .name = "VT1708", .patch = patch_vt1708}, 1205 HDA_CODEC_ENTRY(0x11061709, "VT1708", patch_vt1708),
1216 { .id = 0x1106170a, .name = "VT1708", .patch = patch_vt1708}, 1206 HDA_CODEC_ENTRY(0x1106170a, "VT1708", patch_vt1708),
1217 { .id = 0x1106170b, .name = "VT1708", .patch = patch_vt1708}, 1207 HDA_CODEC_ENTRY(0x1106170b, "VT1708", patch_vt1708),
1218 { .id = 0x1106e710, .name = "VT1709 10-Ch", 1208 HDA_CODEC_ENTRY(0x1106e710, "VT1709 10-Ch", patch_vt1709),
1219 .patch = patch_vt1709}, 1209 HDA_CODEC_ENTRY(0x1106e711, "VT1709 10-Ch", patch_vt1709),
1220 { .id = 0x1106e711, .name = "VT1709 10-Ch", 1210 HDA_CODEC_ENTRY(0x1106e712, "VT1709 10-Ch", patch_vt1709),
1221 .patch = patch_vt1709}, 1211 HDA_CODEC_ENTRY(0x1106e713, "VT1709 10-Ch", patch_vt1709),
1222 { .id = 0x1106e712, .name = "VT1709 10-Ch", 1212 HDA_CODEC_ENTRY(0x1106e714, "VT1709 6-Ch", patch_vt1709),
1223 .patch = patch_vt1709}, 1213 HDA_CODEC_ENTRY(0x1106e715, "VT1709 6-Ch", patch_vt1709),
1224 { .id = 0x1106e713, .name = "VT1709 10-Ch", 1214 HDA_CODEC_ENTRY(0x1106e716, "VT1709 6-Ch", patch_vt1709),
1225 .patch = patch_vt1709}, 1215 HDA_CODEC_ENTRY(0x1106e717, "VT1709 6-Ch", patch_vt1709),
1226 { .id = 0x1106e714, .name = "VT1709 6-Ch", 1216 HDA_CODEC_ENTRY(0x1106e720, "VT1708B 8-Ch", patch_vt1708B),
1227 .patch = patch_vt1709}, 1217 HDA_CODEC_ENTRY(0x1106e721, "VT1708B 8-Ch", patch_vt1708B),
1228 { .id = 0x1106e715, .name = "VT1709 6-Ch", 1218 HDA_CODEC_ENTRY(0x1106e722, "VT1708B 8-Ch", patch_vt1708B),
1229 .patch = patch_vt1709}, 1219 HDA_CODEC_ENTRY(0x1106e723, "VT1708B 8-Ch", patch_vt1708B),
1230 { .id = 0x1106e716, .name = "VT1709 6-Ch", 1220 HDA_CODEC_ENTRY(0x1106e724, "VT1708B 4-Ch", patch_vt1708B),
1231 .patch = patch_vt1709}, 1221 HDA_CODEC_ENTRY(0x1106e725, "VT1708B 4-Ch", patch_vt1708B),
1232 { .id = 0x1106e717, .name = "VT1709 6-Ch", 1222 HDA_CODEC_ENTRY(0x1106e726, "VT1708B 4-Ch", patch_vt1708B),
1233 .patch = patch_vt1709}, 1223 HDA_CODEC_ENTRY(0x1106e727, "VT1708B 4-Ch", patch_vt1708B),
1234 { .id = 0x1106e720, .name = "VT1708B 8-Ch", 1224 HDA_CODEC_ENTRY(0x11060397, "VT1708S", patch_vt1708S),
1235 .patch = patch_vt1708B}, 1225 HDA_CODEC_ENTRY(0x11061397, "VT1708S", patch_vt1708S),
1236 { .id = 0x1106e721, .name = "VT1708B 8-Ch", 1226 HDA_CODEC_ENTRY(0x11062397, "VT1708S", patch_vt1708S),
1237 .patch = patch_vt1708B}, 1227 HDA_CODEC_ENTRY(0x11063397, "VT1708S", patch_vt1708S),
1238 { .id = 0x1106e722, .name = "VT1708B 8-Ch", 1228 HDA_CODEC_ENTRY(0x11064397, "VT1705", patch_vt1708S),
1239 .patch = patch_vt1708B}, 1229 HDA_CODEC_ENTRY(0x11065397, "VT1708S", patch_vt1708S),
1240 { .id = 0x1106e723, .name = "VT1708B 8-Ch", 1230 HDA_CODEC_ENTRY(0x11066397, "VT1708S", patch_vt1708S),
1241 .patch = patch_vt1708B}, 1231 HDA_CODEC_ENTRY(0x11067397, "VT1708S", patch_vt1708S),
1242 { .id = 0x1106e724, .name = "VT1708B 4-Ch", 1232 HDA_CODEC_ENTRY(0x11060398, "VT1702", patch_vt1702),
1243 .patch = patch_vt1708B}, 1233 HDA_CODEC_ENTRY(0x11061398, "VT1702", patch_vt1702),
1244 { .id = 0x1106e725, .name = "VT1708B 4-Ch", 1234 HDA_CODEC_ENTRY(0x11062398, "VT1702", patch_vt1702),
1245 .patch = patch_vt1708B}, 1235 HDA_CODEC_ENTRY(0x11063398, "VT1702", patch_vt1702),
1246 { .id = 0x1106e726, .name = "VT1708B 4-Ch", 1236 HDA_CODEC_ENTRY(0x11064398, "VT1702", patch_vt1702),
1247 .patch = patch_vt1708B}, 1237 HDA_CODEC_ENTRY(0x11065398, "VT1702", patch_vt1702),
1248 { .id = 0x1106e727, .name = "VT1708B 4-Ch", 1238 HDA_CODEC_ENTRY(0x11066398, "VT1702", patch_vt1702),
1249 .patch = patch_vt1708B}, 1239 HDA_CODEC_ENTRY(0x11067398, "VT1702", patch_vt1702),
1250 { .id = 0x11060397, .name = "VT1708S", 1240 HDA_CODEC_ENTRY(0x11060428, "VT1718S", patch_vt1718S),
1251 .patch = patch_vt1708S}, 1241 HDA_CODEC_ENTRY(0x11064428, "VT1718S", patch_vt1718S),
1252 { .id = 0x11061397, .name = "VT1708S", 1242 HDA_CODEC_ENTRY(0x11060441, "VT2020", patch_vt1718S),
1253 .patch = patch_vt1708S}, 1243 HDA_CODEC_ENTRY(0x11064441, "VT1828S", patch_vt1718S),
1254 { .id = 0x11062397, .name = "VT1708S", 1244 HDA_CODEC_ENTRY(0x11060433, "VT1716S", patch_vt1716S),
1255 .patch = patch_vt1708S}, 1245 HDA_CODEC_ENTRY(0x1106a721, "VT1716S", patch_vt1716S),
1256 { .id = 0x11063397, .name = "VT1708S", 1246 HDA_CODEC_ENTRY(0x11060438, "VT2002P", patch_vt2002P),
1257 .patch = patch_vt1708S}, 1247 HDA_CODEC_ENTRY(0x11064438, "VT2002P", patch_vt2002P),
1258 { .id = 0x11064397, .name = "VT1705", 1248 HDA_CODEC_ENTRY(0x11060448, "VT1812", patch_vt1812),
1259 .patch = patch_vt1708S}, 1249 HDA_CODEC_ENTRY(0x11060440, "VT1818S", patch_vt1708S),
1260 { .id = 0x11065397, .name = "VT1708S", 1250 HDA_CODEC_ENTRY(0x11060446, "VT1802", patch_vt2002P),
1261 .patch = patch_vt1708S}, 1251 HDA_CODEC_ENTRY(0x11068446, "VT1802", patch_vt2002P),
1262 { .id = 0x11066397, .name = "VT1708S", 1252 HDA_CODEC_ENTRY(0x11064760, "VT1705CF", patch_vt3476),
1263 .patch = patch_vt1708S}, 1253 HDA_CODEC_ENTRY(0x11064761, "VT1708SCE", patch_vt3476),
1264 { .id = 0x11067397, .name = "VT1708S", 1254 HDA_CODEC_ENTRY(0x11064762, "VT1808", patch_vt3476),
1265 .patch = patch_vt1708S},
1266 { .id = 0x11060398, .name = "VT1702",
1267 .patch = patch_vt1702},
1268 { .id = 0x11061398, .name = "VT1702",
1269 .patch = patch_vt1702},
1270 { .id = 0x11062398, .name = "VT1702",
1271 .patch = patch_vt1702},
1272 { .id = 0x11063398, .name = "VT1702",
1273 .patch = patch_vt1702},
1274 { .id = 0x11064398, .name = "VT1702",
1275 .patch = patch_vt1702},
1276 { .id = 0x11065398, .name = "VT1702",
1277 .patch = patch_vt1702},
1278 { .id = 0x11066398, .name = "VT1702",
1279 .patch = patch_vt1702},
1280 { .id = 0x11067398, .name = "VT1702",
1281 .patch = patch_vt1702},
1282 { .id = 0x11060428, .name = "VT1718S",
1283 .patch = patch_vt1718S},
1284 { .id = 0x11064428, .name = "VT1718S",
1285 .patch = patch_vt1718S},
1286 { .id = 0x11060441, .name = "VT2020",
1287 .patch = patch_vt1718S},
1288 { .id = 0x11064441, .name = "VT1828S",
1289 .patch = patch_vt1718S},
1290 { .id = 0x11060433, .name = "VT1716S",
1291 .patch = patch_vt1716S},
1292 { .id = 0x1106a721, .name = "VT1716S",
1293 .patch = patch_vt1716S},
1294 { .id = 0x11060438, .name = "VT2002P", .patch = patch_vt2002P},
1295 { .id = 0x11064438, .name = "VT2002P", .patch = patch_vt2002P},
1296 { .id = 0x11060448, .name = "VT1812", .patch = patch_vt1812},
1297 { .id = 0x11060440, .name = "VT1818S",
1298 .patch = patch_vt1708S},
1299 { .id = 0x11060446, .name = "VT1802",
1300 .patch = patch_vt2002P},
1301 { .id = 0x11068446, .name = "VT1802",
1302 .patch = patch_vt2002P},
1303 { .id = 0x11064760, .name = "VT1705CF",
1304 .patch = patch_vt3476},
1305 { .id = 0x11064761, .name = "VT1708SCE",
1306 .patch = patch_vt3476},
1307 { .id = 0x11064762, .name = "VT1808",
1308 .patch = patch_vt3476},
1309 {} /* terminator */ 1255 {} /* terminator */
1310}; 1256};
1311 1257MODULE_DEVICE_TABLE(hdaudio, snd_hda_id_via);
1312MODULE_ALIAS("snd-hda-codec-id:1106*");
1313 1258
1314static struct hda_codec_driver via_driver = { 1259static struct hda_codec_driver via_driver = {
1315 .preset = snd_hda_preset_via, 1260 .id = snd_hda_id_via,
1316}; 1261};
1317 1262
1318MODULE_LICENSE("GPL"); 1263MODULE_LICENSE("GPL");
diff --git a/sound/pci/korg1212/korg1212.c b/sound/pci/korg1212/korg1212.c
index 7acbc21d642a..9e1ad119a3ce 100644
--- a/sound/pci/korg1212/korg1212.c
+++ b/sound/pci/korg1212/korg1212.c
@@ -1394,7 +1394,9 @@ static int snd_korg1212_playback_open(struct snd_pcm_substream *substream)
1394 1394
1395 spin_unlock_irqrestore(&korg1212->lock, flags); 1395 spin_unlock_irqrestore(&korg1212->lock, flags);
1396 1396
1397 snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_PERIOD_SIZE, kPlayBufferFrames, kPlayBufferFrames); 1397 snd_pcm_hw_constraint_single(runtime, SNDRV_PCM_HW_PARAM_PERIOD_SIZE,
1398 kPlayBufferFrames);
1399
1398 return 0; 1400 return 0;
1399} 1401}
1400 1402
@@ -1422,8 +1424,8 @@ static int snd_korg1212_capture_open(struct snd_pcm_substream *substream)
1422 1424
1423 spin_unlock_irqrestore(&korg1212->lock, flags); 1425 spin_unlock_irqrestore(&korg1212->lock, flags);
1424 1426
1425 snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_PERIOD_SIZE, 1427 snd_pcm_hw_constraint_single(runtime, SNDRV_PCM_HW_PARAM_PERIOD_SIZE,
1426 kPlayBufferFrames, kPlayBufferFrames); 1428 kPlayBufferFrames);
1427 return 0; 1429 return 0;
1428} 1430}
1429 1431
diff --git a/sound/pci/lx6464es/lx6464es.c b/sound/pci/lx6464es/lx6464es.c
index cba89beb2b38..8b8e2e54fba3 100644
--- a/sound/pci/lx6464es/lx6464es.c
+++ b/sound/pci/lx6464es/lx6464es.c
@@ -234,8 +234,8 @@ static int lx_pcm_open(struct snd_pcm_substream *substream)
234 234
235 /* the clock rate cannot be changed */ 235 /* the clock rate cannot be changed */
236 board_rate = chip->board_sample_rate; 236 board_rate = chip->board_sample_rate;
237 err = snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_RATE, 237 err = snd_pcm_hw_constraint_single(runtime, SNDRV_PCM_HW_PARAM_RATE,
238 board_rate, board_rate); 238 board_rate);
239 239
240 if (err < 0) { 240 if (err < 0) {
241 dev_warn(chip->card->dev, "could not constrain periods\n"); 241 dev_warn(chip->card->dev, "could not constrain periods\n");
diff --git a/sound/pci/maestro3.c b/sound/pci/maestro3.c
index 72e89cedc52d..17ae92613de4 100644
--- a/sound/pci/maestro3.c
+++ b/sound/pci/maestro3.c
@@ -1929,15 +1929,32 @@ snd_m3_ac97_write(struct snd_ac97 *ac97, unsigned short reg, unsigned short val)
1929 return; 1929 return;
1930 snd_m3_outw(chip, val, CODEC_DATA); 1930 snd_m3_outw(chip, val, CODEC_DATA);
1931 snd_m3_outb(chip, reg & 0x7f, CODEC_COMMAND); 1931 snd_m3_outb(chip, reg & 0x7f, CODEC_COMMAND);
1932 /*
1933 * Workaround for buggy ES1988 integrated AC'97 codec. It remains silent
1934 * until the MASTER volume or mute is touched (alsactl restore does not
1935 * work).
1936 */
1937 if (ac97->id == 0x45838308 && reg == AC97_MASTER) {
1938 snd_m3_ac97_wait(chip);
1939 snd_m3_outw(chip, val, CODEC_DATA);
1940 snd_m3_outb(chip, reg & 0x7f, CODEC_COMMAND);
1941 }
1932} 1942}
1933 1943
1934 1944
1935static void snd_m3_remote_codec_config(int io, int isremote) 1945static void snd_m3_remote_codec_config(struct snd_m3 *chip, int isremote)
1936{ 1946{
1947 int io = chip->iobase;
1948 u16 tmp;
1949
1937 isremote = isremote ? 1 : 0; 1950 isremote = isremote ? 1 : 0;
1938 1951
1939 outw((inw(io + RING_BUS_CTRL_B) & ~SECOND_CODEC_ID_MASK) | isremote, 1952 tmp = inw(io + RING_BUS_CTRL_B) & ~SECOND_CODEC_ID_MASK;
1940 io + RING_BUS_CTRL_B); 1953 /* enable dock on Dell Latitude C810 */
1954 if (chip->pci->subsystem_vendor == 0x1028 &&
1955 chip->pci->subsystem_device == 0x00e5)
1956 tmp |= M3I_DOCK_ENABLE;
1957 outw(tmp | isremote, io + RING_BUS_CTRL_B);
1941 outw((inw(io + SDO_OUT_DEST_CTRL) & ~COMMAND_ADDR_OUT) | isremote, 1958 outw((inw(io + SDO_OUT_DEST_CTRL) & ~COMMAND_ADDR_OUT) | isremote,
1942 io + SDO_OUT_DEST_CTRL); 1959 io + SDO_OUT_DEST_CTRL);
1943 outw((inw(io + SDO_IN_DEST_CTRL) & ~STATUS_ADDR_IN) | isremote, 1960 outw((inw(io + SDO_IN_DEST_CTRL) & ~STATUS_ADDR_IN) | isremote,
@@ -1989,7 +2006,7 @@ static void snd_m3_ac97_reset(struct snd_m3 *chip)
1989 if (!chip->irda_workaround) 2006 if (!chip->irda_workaround)
1990 dir |= 0x10; /* assuming pci bus master? */ 2007 dir |= 0x10; /* assuming pci bus master? */
1991 2008
1992 snd_m3_remote_codec_config(io, 0); 2009 snd_m3_remote_codec_config(chip, 0);
1993 2010
1994 outw(IO_SRAM_ENABLE, io + RING_BUS_CTRL_A); 2011 outw(IO_SRAM_ENABLE, io + RING_BUS_CTRL_A);
1995 udelay(20); 2012 udelay(20);
diff --git a/sound/pci/rme32.c b/sound/pci/rme32.c
index 23d7f5d30c41..cd94ac548ba3 100644
--- a/sound/pci/rme32.c
+++ b/sound/pci/rme32.c
@@ -831,9 +831,9 @@ static struct snd_pcm_hw_constraint_list hw_constraints_period_bytes = {
831static void snd_rme32_set_buffer_constraint(struct rme32 *rme32, struct snd_pcm_runtime *runtime) 831static void snd_rme32_set_buffer_constraint(struct rme32 *rme32, struct snd_pcm_runtime *runtime)
832{ 832{
833 if (! rme32->fullduplex_mode) { 833 if (! rme32->fullduplex_mode) {
834 snd_pcm_hw_constraint_minmax(runtime, 834 snd_pcm_hw_constraint_single(runtime,
835 SNDRV_PCM_HW_PARAM_BUFFER_BYTES, 835 SNDRV_PCM_HW_PARAM_BUFFER_BYTES,
836 RME32_BUFFER_SIZE, RME32_BUFFER_SIZE); 836 RME32_BUFFER_SIZE);
837 snd_pcm_hw_constraint_list(runtime, 0, 837 snd_pcm_hw_constraint_list(runtime, 0,
838 SNDRV_PCM_HW_PARAM_PERIOD_BYTES, 838 SNDRV_PCM_HW_PARAM_PERIOD_BYTES,
839 &hw_constraints_period_bytes); 839 &hw_constraints_period_bytes);
diff --git a/sound/pci/rme96.c b/sound/pci/rme96.c
index 2306ccf7281e..714df906249e 100644
--- a/sound/pci/rme96.c
+++ b/sound/pci/rme96.c
@@ -1152,13 +1152,13 @@ rme96_set_buffer_size_constraint(struct rme96 *rme96,
1152{ 1152{
1153 unsigned int size; 1153 unsigned int size;
1154 1154
1155 snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_BUFFER_BYTES, 1155 snd_pcm_hw_constraint_single(runtime, SNDRV_PCM_HW_PARAM_BUFFER_BYTES,
1156 RME96_BUFFER_SIZE, RME96_BUFFER_SIZE); 1156 RME96_BUFFER_SIZE);
1157 if ((size = rme96->playback_periodsize) != 0 || 1157 if ((size = rme96->playback_periodsize) != 0 ||
1158 (size = rme96->capture_periodsize) != 0) 1158 (size = rme96->capture_periodsize) != 0)
1159 snd_pcm_hw_constraint_minmax(runtime, 1159 snd_pcm_hw_constraint_single(runtime,
1160 SNDRV_PCM_HW_PARAM_PERIOD_BYTES, 1160 SNDRV_PCM_HW_PARAM_PERIOD_BYTES,
1161 size, size); 1161 size);
1162 else 1162 else
1163 snd_pcm_hw_constraint_list(runtime, 0, 1163 snd_pcm_hw_constraint_list(runtime, 0,
1164 SNDRV_PCM_HW_PARAM_PERIOD_BYTES, 1164 SNDRV_PCM_HW_PARAM_PERIOD_BYTES,
diff --git a/sound/pci/rme9652/hdsp.c b/sound/pci/rme9652/hdsp.c
index 9bba275b4c9b..2875b4f6d8c9 100644
--- a/sound/pci/rme9652/hdsp.c
+++ b/sound/pci/rme9652/hdsp.c
@@ -5112,6 +5112,7 @@ static int hdsp_request_fw_loader(struct hdsp *hdsp)
5112 dev_err(hdsp->card->dev, 5112 dev_err(hdsp->card->dev,
5113 "too short firmware size %d (expected %d)\n", 5113 "too short firmware size %d (expected %d)\n",
5114 (int)fw->size, HDSP_FIRMWARE_SIZE); 5114 (int)fw->size, HDSP_FIRMWARE_SIZE);
5115 release_firmware(fw);
5115 return -EINVAL; 5116 return -EINVAL;
5116 } 5117 }
5117 5118
diff --git a/sound/pci/rme9652/hdspm.c b/sound/pci/rme9652/hdspm.c
index cb666c73712d..8bc8016c173d 100644
--- a/sound/pci/rme9652/hdspm.c
+++ b/sound/pci/rme9652/hdspm.c
@@ -6080,18 +6080,17 @@ static int snd_hdspm_open(struct snd_pcm_substream *substream)
6080 SNDRV_PCM_HW_PARAM_PERIOD_SIZE, 6080 SNDRV_PCM_HW_PARAM_PERIOD_SIZE,
6081 32, 4096); 6081 32, 4096);
6082 /* RayDAT & AIO have a fixed buffer of 16384 samples per channel */ 6082 /* RayDAT & AIO have a fixed buffer of 16384 samples per channel */
6083 snd_pcm_hw_constraint_minmax(runtime, 6083 snd_pcm_hw_constraint_single(runtime,
6084 SNDRV_PCM_HW_PARAM_BUFFER_SIZE, 6084 SNDRV_PCM_HW_PARAM_BUFFER_SIZE,
6085 16384, 16384); 6085 16384);
6086 break; 6086 break;
6087 6087
6088 default: 6088 default:
6089 snd_pcm_hw_constraint_minmax(runtime, 6089 snd_pcm_hw_constraint_minmax(runtime,
6090 SNDRV_PCM_HW_PARAM_PERIOD_SIZE, 6090 SNDRV_PCM_HW_PARAM_PERIOD_SIZE,
6091 64, 8192); 6091 64, 8192);
6092 snd_pcm_hw_constraint_minmax(runtime, 6092 snd_pcm_hw_constraint_single(runtime,
6093 SNDRV_PCM_HW_PARAM_PERIODS, 6093 SNDRV_PCM_HW_PARAM_PERIODS, 2);
6094 2, 2);
6095 break; 6094 break;
6096 } 6095 }
6097 6096
diff --git a/sound/soc/Kconfig b/sound/soc/Kconfig
index 225bfda414e9..7ff7d88e46dd 100644
--- a/sound/soc/Kconfig
+++ b/sound/soc/Kconfig
@@ -9,7 +9,6 @@ menuconfig SND_SOC
9 select SND_JACK if INPUT=y || INPUT=SND 9 select SND_JACK if INPUT=y || INPUT=SND
10 select REGMAP_I2C if I2C 10 select REGMAP_I2C if I2C
11 select REGMAP_SPI if SPI_MASTER 11 select REGMAP_SPI if SPI_MASTER
12 select SND_COMPRESS_OFFLOAD
13 ---help--- 12 ---help---
14 13
15 If you want ASoC support, you should say Y here and also to the 14 If you want ASoC support, you should say Y here and also to the
@@ -30,6 +29,10 @@ config SND_SOC_GENERIC_DMAENGINE_PCM
30 bool 29 bool
31 select SND_DMAENGINE_PCM 30 select SND_DMAENGINE_PCM
32 31
32config SND_SOC_COMPRESS
33 bool
34 select SND_COMPRESS_OFFLOAD
35
33config SND_SOC_TOPOLOGY 36config SND_SOC_TOPOLOGY
34 bool 37 bool
35 38
@@ -58,6 +61,7 @@ source "sound/soc/sh/Kconfig"
58source "sound/soc/sirf/Kconfig" 61source "sound/soc/sirf/Kconfig"
59source "sound/soc/spear/Kconfig" 62source "sound/soc/spear/Kconfig"
60source "sound/soc/sti/Kconfig" 63source "sound/soc/sti/Kconfig"
64source "sound/soc/sunxi/Kconfig"
61source "sound/soc/tegra/Kconfig" 65source "sound/soc/tegra/Kconfig"
62source "sound/soc/txx9/Kconfig" 66source "sound/soc/txx9/Kconfig"
63source "sound/soc/ux500/Kconfig" 67source "sound/soc/ux500/Kconfig"
diff --git a/sound/soc/Makefile b/sound/soc/Makefile
index 134aca150a50..8eb06db32fa0 100644
--- a/sound/soc/Makefile
+++ b/sound/soc/Makefile
@@ -1,5 +1,6 @@
1snd-soc-core-objs := soc-core.o soc-dapm.o soc-jack.o soc-cache.o soc-utils.o 1snd-soc-core-objs := soc-core.o soc-dapm.o soc-jack.o soc-cache.o soc-utils.o
2snd-soc-core-objs += soc-pcm.o soc-compress.o soc-io.o soc-devres.o soc-ops.o 2snd-soc-core-objs += soc-pcm.o soc-io.o soc-devres.o soc-ops.o
3snd-soc-core-$(CONFIG_SND_SOC_COMPRESS) += soc-compress.o
3 4
4ifneq ($(CONFIG_SND_SOC_TOPOLOGY),) 5ifneq ($(CONFIG_SND_SOC_TOPOLOGY),)
5snd-soc-core-objs += soc-topology.o 6snd-soc-core-objs += soc-topology.o
@@ -40,6 +41,7 @@ obj-$(CONFIG_SND_SOC) += sh/
40obj-$(CONFIG_SND_SOC) += sirf/ 41obj-$(CONFIG_SND_SOC) += sirf/
41obj-$(CONFIG_SND_SOC) += spear/ 42obj-$(CONFIG_SND_SOC) += spear/
42obj-$(CONFIG_SND_SOC) += sti/ 43obj-$(CONFIG_SND_SOC) += sti/
44obj-$(CONFIG_SND_SOC) += sunxi/
43obj-$(CONFIG_SND_SOC) += tegra/ 45obj-$(CONFIG_SND_SOC) += tegra/
44obj-$(CONFIG_SND_SOC) += txx9/ 46obj-$(CONFIG_SND_SOC) += txx9/
45obj-$(CONFIG_SND_SOC) += ux500/ 47obj-$(CONFIG_SND_SOC) += ux500/
diff --git a/sound/soc/atmel/Kconfig b/sound/soc/atmel/Kconfig
index 1489cd461aec..2d30464b81ce 100644
--- a/sound/soc/atmel/Kconfig
+++ b/sound/soc/atmel/Kconfig
@@ -59,4 +59,13 @@ config SND_AT91_SOC_SAM9X5_WM8731
59 help 59 help
60 Say Y if you want to add support for audio SoC on an 60 Say Y if you want to add support for audio SoC on an
61 at91sam9x5 based board that is using WM8731 codec. 61 at91sam9x5 based board that is using WM8731 codec.
62
63config SND_ATMEL_SOC_CLASSD
64 tristate "Atmel ASoC driver for boards using CLASSD"
65 depends on ARCH_AT91 || COMPILE_TEST
66 select SND_ATMEL_SOC_DMA
67 select REGMAP_MMIO
68 help
69 Say Y if you want to add support for Atmel ASoC driver for boards using
70 CLASSD.
62endif 71endif
diff --git a/sound/soc/atmel/Makefile b/sound/soc/atmel/Makefile
index b327e5cc8de3..f6f7db428216 100644
--- a/sound/soc/atmel/Makefile
+++ b/sound/soc/atmel/Makefile
@@ -11,7 +11,9 @@ obj-$(CONFIG_SND_ATMEL_SOC_SSC) += snd-soc-atmel_ssc_dai.o
11snd-soc-sam9g20-wm8731-objs := sam9g20_wm8731.o 11snd-soc-sam9g20-wm8731-objs := sam9g20_wm8731.o
12snd-atmel-soc-wm8904-objs := atmel_wm8904.o 12snd-atmel-soc-wm8904-objs := atmel_wm8904.o
13snd-soc-sam9x5-wm8731-objs := sam9x5_wm8731.o 13snd-soc-sam9x5-wm8731-objs := sam9x5_wm8731.o
14snd-atmel-soc-classd-objs := atmel-classd.o
14 15
15obj-$(CONFIG_SND_AT91_SOC_SAM9G20_WM8731) += snd-soc-sam9g20-wm8731.o 16obj-$(CONFIG_SND_AT91_SOC_SAM9G20_WM8731) += snd-soc-sam9g20-wm8731.o
16obj-$(CONFIG_SND_ATMEL_SOC_WM8904) += snd-atmel-soc-wm8904.o 17obj-$(CONFIG_SND_ATMEL_SOC_WM8904) += snd-atmel-soc-wm8904.o
17obj-$(CONFIG_SND_AT91_SOC_SAM9X5_WM8731) += snd-soc-sam9x5-wm8731.o 18obj-$(CONFIG_SND_AT91_SOC_SAM9X5_WM8731) += snd-soc-sam9x5-wm8731.o
19obj-$(CONFIG_SND_ATMEL_SOC_CLASSD) += snd-atmel-soc-classd.o
diff --git a/sound/soc/atmel/atmel-classd.c b/sound/soc/atmel/atmel-classd.c
new file mode 100644
index 000000000000..8276675730ef
--- /dev/null
+++ b/sound/soc/atmel/atmel-classd.c
@@ -0,0 +1,679 @@
1/* Atmel ALSA SoC Audio Class D Amplifier (CLASSD) driver
2 *
3 * Copyright (C) 2015 Atmel
4 *
5 * Author: Songjun Wu <songjun.wu@atmel.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 or later
9 * as published by the Free Software Foundation.
10 */
11
12#include <linux/of.h>
13#include <linux/clk.h>
14#include <linux/module.h>
15#include <linux/platform_device.h>
16#include <linux/regmap.h>
17#include <sound/core.h>
18#include <sound/dmaengine_pcm.h>
19#include <sound/pcm_params.h>
20#include <sound/tlv.h>
21#include "atmel-classd.h"
22
23struct atmel_classd_pdata {
24 bool non_overlap_enable;
25 int non_overlap_time;
26 int pwm_type;
27 const char *card_name;
28};
29
30struct atmel_classd {
31 dma_addr_t phy_base;
32 struct regmap *regmap;
33 struct clk *pclk;
34 struct clk *gclk;
35 struct clk *aclk;
36 int irq;
37 const struct atmel_classd_pdata *pdata;
38};
39
40#ifdef CONFIG_OF
41static const struct of_device_id atmel_classd_of_match[] = {
42 {
43 .compatible = "atmel,sama5d2-classd",
44 }, {
45 /* sentinel */
46 }
47};
48MODULE_DEVICE_TABLE(of, atmel_classd_of_match);
49
50static struct atmel_classd_pdata *atmel_classd_dt_init(struct device *dev)
51{
52 struct device_node *np = dev->of_node;
53 struct atmel_classd_pdata *pdata;
54 const char *pwm_type;
55 int ret;
56
57 if (!np) {
58 dev_err(dev, "device node not found\n");
59 return ERR_PTR(-EINVAL);
60 }
61
62 pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL);
63 if (!pdata)
64 return ERR_PTR(-ENOMEM);
65
66 ret = of_property_read_string(np, "atmel,pwm-type", &pwm_type);
67 if ((ret == 0) && (strcmp(pwm_type, "diff") == 0))
68 pdata->pwm_type = CLASSD_MR_PWMTYP_DIFF;
69 else
70 pdata->pwm_type = CLASSD_MR_PWMTYP_SINGLE;
71
72 ret = of_property_read_u32(np,
73 "atmel,non-overlap-time", &pdata->non_overlap_time);
74 if (ret)
75 pdata->non_overlap_enable = false;
76 else
77 pdata->non_overlap_enable = true;
78
79 ret = of_property_read_string(np, "atmel,model", &pdata->card_name);
80 if (ret)
81 pdata->card_name = "CLASSD";
82
83 return pdata;
84}
85#else
86static inline struct atmel_classd_pdata *
87atmel_classd_dt_init(struct device *dev)
88{
89 return ERR_PTR(-EINVAL);
90}
91#endif
92
93#define ATMEL_CLASSD_RATES (SNDRV_PCM_RATE_8000 \
94 | SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 \
95 | SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 \
96 | SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 \
97 | SNDRV_PCM_RATE_96000)
98
99static const struct snd_pcm_hardware atmel_classd_hw = {
100 .info = SNDRV_PCM_INFO_MMAP
101 | SNDRV_PCM_INFO_MMAP_VALID
102 | SNDRV_PCM_INFO_INTERLEAVED
103 | SNDRV_PCM_INFO_RESUME
104 | SNDRV_PCM_INFO_PAUSE,
105 .formats = (SNDRV_PCM_FMTBIT_S16_LE),
106 .rates = ATMEL_CLASSD_RATES,
107 .rate_min = 8000,
108 .rate_max = 96000,
109 .channels_min = 2,
110 .channels_max = 2,
111 .buffer_bytes_max = 64 * 1024,
112 .period_bytes_min = 256,
113 .period_bytes_max = 32 * 1024,
114 .periods_min = 2,
115 .periods_max = 256,
116};
117
118#define ATMEL_CLASSD_PREALLOC_BUF_SIZE (64 * 1024)
119
120/* cpu dai component */
121static int atmel_classd_cpu_dai_startup(struct snd_pcm_substream *substream,
122 struct snd_soc_dai *cpu_dai)
123{
124 struct snd_soc_pcm_runtime *rtd = substream->private_data;
125 struct atmel_classd *dd = snd_soc_card_get_drvdata(rtd->card);
126
127 regmap_write(dd->regmap, CLASSD_THR, 0x0);
128
129 return clk_prepare_enable(dd->pclk);
130}
131
132static void atmel_classd_cpu_dai_shutdown(struct snd_pcm_substream *substream,
133 struct snd_soc_dai *cpu_dai)
134{
135 struct snd_soc_pcm_runtime *rtd = substream->private_data;
136 struct atmel_classd *dd = snd_soc_card_get_drvdata(rtd->card);
137
138 clk_disable_unprepare(dd->pclk);
139}
140
141static const struct snd_soc_dai_ops atmel_classd_cpu_dai_ops = {
142 .startup = atmel_classd_cpu_dai_startup,
143 .shutdown = atmel_classd_cpu_dai_shutdown,
144};
145
146static struct snd_soc_dai_driver atmel_classd_cpu_dai = {
147 .playback = {
148 .channels_min = 2,
149 .channels_max = 2,
150 .rates = ATMEL_CLASSD_RATES,
151 .formats = SNDRV_PCM_FMTBIT_S16_LE,},
152 .ops = &atmel_classd_cpu_dai_ops,
153};
154
155static const struct snd_soc_component_driver atmel_classd_cpu_dai_component = {
156 .name = "atmel-classd",
157};
158
159/* platform */
160static int
161atmel_classd_platform_configure_dma(struct snd_pcm_substream *substream,
162 struct snd_pcm_hw_params *params,
163 struct dma_slave_config *slave_config)
164{
165 struct snd_soc_pcm_runtime *rtd = substream->private_data;
166 struct atmel_classd *dd = snd_soc_card_get_drvdata(rtd->card);
167
168 if (params_physical_width(params) != 16) {
169 dev_err(rtd->platform->dev,
170 "only supports 16-bit audio data\n");
171 return -EINVAL;
172 }
173
174 slave_config->direction = DMA_MEM_TO_DEV;
175 slave_config->dst_addr = dd->phy_base + CLASSD_THR;
176 slave_config->dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
177 slave_config->dst_maxburst = 1;
178 slave_config->src_maxburst = 1;
179 slave_config->device_fc = false;
180
181 return 0;
182}
183
184static const struct snd_dmaengine_pcm_config
185atmel_classd_dmaengine_pcm_config = {
186 .prepare_slave_config = atmel_classd_platform_configure_dma,
187 .pcm_hardware = &atmel_classd_hw,
188 .prealloc_buffer_size = ATMEL_CLASSD_PREALLOC_BUF_SIZE,
189};
190
191/* codec */
192static const char * const mono_mode_text[] = {
193 "mix", "sat", "left", "right"
194};
195
196static SOC_ENUM_SINGLE_DECL(classd_mono_mode_enum,
197 CLASSD_INTPMR, CLASSD_INTPMR_MONO_MODE_SHIFT,
198 mono_mode_text);
199
200static const char * const eqcfg_text[] = {
201 "Treble-12dB", "Treble-6dB",
202 "Medium-8dB", "Medium-3dB",
203 "Bass-12dB", "Bass-6dB",
204 "0 dB",
205 "Bass+6dB", "Bass+12dB",
206 "Medium+3dB", "Medium+8dB",
207 "Treble+6dB", "Treble+12dB",
208};
209
210static const unsigned int eqcfg_value[] = {
211 CLASSD_INTPMR_EQCFG_T_CUT_12, CLASSD_INTPMR_EQCFG_T_CUT_6,
212 CLASSD_INTPMR_EQCFG_M_CUT_8, CLASSD_INTPMR_EQCFG_M_CUT_3,
213 CLASSD_INTPMR_EQCFG_B_CUT_12, CLASSD_INTPMR_EQCFG_B_CUT_6,
214 CLASSD_INTPMR_EQCFG_FLAT,
215 CLASSD_INTPMR_EQCFG_B_BOOST_6, CLASSD_INTPMR_EQCFG_B_BOOST_12,
216 CLASSD_INTPMR_EQCFG_M_BOOST_3, CLASSD_INTPMR_EQCFG_M_BOOST_8,
217 CLASSD_INTPMR_EQCFG_T_BOOST_6, CLASSD_INTPMR_EQCFG_T_BOOST_12,
218};
219
220static SOC_VALUE_ENUM_SINGLE_DECL(classd_eqcfg_enum,
221 CLASSD_INTPMR, CLASSD_INTPMR_EQCFG_SHIFT, 0xf,
222 eqcfg_text, eqcfg_value);
223
224static const DECLARE_TLV_DB_SCALE(classd_digital_tlv, -7800, 100, 1);
225
226static const struct snd_kcontrol_new atmel_classd_snd_controls[] = {
227SOC_DOUBLE_TLV("Playback Volume", CLASSD_INTPMR,
228 CLASSD_INTPMR_ATTL_SHIFT, CLASSD_INTPMR_ATTR_SHIFT,
229 78, 1, classd_digital_tlv),
230
231SOC_SINGLE("Deemphasis Switch", CLASSD_INTPMR,
232 CLASSD_INTPMR_DEEMP_SHIFT, 1, 0),
233
234SOC_SINGLE("Mono Switch", CLASSD_INTPMR, CLASSD_INTPMR_MONO_SHIFT, 1, 0),
235
236SOC_SINGLE("Swap Switch", CLASSD_INTPMR, CLASSD_INTPMR_SWAP_SHIFT, 1, 0),
237
238SOC_ENUM("Mono Mode", classd_mono_mode_enum),
239
240SOC_ENUM("EQ", classd_eqcfg_enum),
241};
242
243static const char * const pwm_type[] = {
244 "Single ended", "Differential"
245};
246
247static int atmel_classd_codec_probe(struct snd_soc_codec *codec)
248{
249 struct snd_soc_card *card = snd_soc_codec_get_drvdata(codec);
250 struct atmel_classd *dd = snd_soc_card_get_drvdata(card);
251 const struct atmel_classd_pdata *pdata = dd->pdata;
252 u32 mask, val;
253
254 mask = CLASSD_MR_PWMTYP_MASK;
255 val = pdata->pwm_type << CLASSD_MR_PWMTYP_SHIFT;
256
257 mask |= CLASSD_MR_NON_OVERLAP_MASK;
258 if (pdata->non_overlap_enable) {
259 val |= (CLASSD_MR_NON_OVERLAP_EN
260 << CLASSD_MR_NON_OVERLAP_SHIFT);
261
262 mask |= CLASSD_MR_NOVR_VAL_MASK;
263 switch (pdata->non_overlap_time) {
264 case 5:
265 val |= (CLASSD_MR_NOVR_VAL_5NS
266 << CLASSD_MR_NOVR_VAL_SHIFT);
267 break;
268 case 10:
269 val |= (CLASSD_MR_NOVR_VAL_10NS
270 << CLASSD_MR_NOVR_VAL_SHIFT);
271 break;
272 case 15:
273 val |= (CLASSD_MR_NOVR_VAL_15NS
274 << CLASSD_MR_NOVR_VAL_SHIFT);
275 break;
276 case 20:
277 val |= (CLASSD_MR_NOVR_VAL_20NS
278 << CLASSD_MR_NOVR_VAL_SHIFT);
279 break;
280 default:
281 val |= (CLASSD_MR_NOVR_VAL_10NS
282 << CLASSD_MR_NOVR_VAL_SHIFT);
283 dev_warn(codec->dev,
284 "non-overlapping value %d is invalid, the default value 10 is specified\n",
285 pdata->non_overlap_time);
286 break;
287 }
288 }
289
290 snd_soc_update_bits(codec, CLASSD_MR, mask, val);
291
292 dev_info(codec->dev,
293 "PWM modulation type is %s, non-overlapping is %s\n",
294 pwm_type[pdata->pwm_type],
295 pdata->non_overlap_enable?"enabled":"disabled");
296
297 return 0;
298}
299
300static struct regmap *atmel_classd_codec_get_remap(struct device *dev)
301{
302 return dev_get_regmap(dev, NULL);
303}
304
305static struct snd_soc_codec_driver soc_codec_dev_classd = {
306 .probe = atmel_classd_codec_probe,
307 .controls = atmel_classd_snd_controls,
308 .num_controls = ARRAY_SIZE(atmel_classd_snd_controls),
309 .get_regmap = atmel_classd_codec_get_remap,
310};
311
312/* codec dai component */
313static int atmel_classd_codec_dai_startup(struct snd_pcm_substream *substream,
314 struct snd_soc_dai *codec_dai)
315{
316 struct snd_soc_pcm_runtime *rtd = substream->private_data;
317 struct atmel_classd *dd = snd_soc_card_get_drvdata(rtd->card);
318 int ret;
319
320 ret = clk_prepare_enable(dd->aclk);
321 if (ret)
322 return ret;
323
324 return clk_prepare_enable(dd->gclk);
325}
326
327static int atmel_classd_codec_dai_digital_mute(struct snd_soc_dai *codec_dai,
328 int mute)
329{
330 struct snd_soc_codec *codec = codec_dai->codec;
331 u32 mask, val;
332
333 mask = CLASSD_MR_LMUTE_MASK | CLASSD_MR_RMUTE_MASK;
334
335 if (mute)
336 val = mask;
337 else
338 val = 0;
339
340 snd_soc_update_bits(codec, CLASSD_MR, mask, val);
341
342 return 0;
343}
344
345#define CLASSD_ACLK_RATE_11M2896_MPY_8 (112896 * 100 * 8)
346#define CLASSD_ACLK_RATE_12M288_MPY_8 (12228 * 1000 * 8)
347
348static struct {
349 int rate;
350 int sample_rate;
351 int dsp_clk;
352 unsigned long aclk_rate;
353} const sample_rates[] = {
354 { 8000, CLASSD_INTPMR_FRAME_8K,
355 CLASSD_INTPMR_DSP_CLK_FREQ_12M288, CLASSD_ACLK_RATE_12M288_MPY_8 },
356 { 16000, CLASSD_INTPMR_FRAME_16K,
357 CLASSD_INTPMR_DSP_CLK_FREQ_12M288, CLASSD_ACLK_RATE_12M288_MPY_8 },
358 { 32000, CLASSD_INTPMR_FRAME_32K,
359 CLASSD_INTPMR_DSP_CLK_FREQ_12M288, CLASSD_ACLK_RATE_12M288_MPY_8 },
360 { 48000, CLASSD_INTPMR_FRAME_48K,
361 CLASSD_INTPMR_DSP_CLK_FREQ_12M288, CLASSD_ACLK_RATE_12M288_MPY_8 },
362 { 96000, CLASSD_INTPMR_FRAME_96K,
363 CLASSD_INTPMR_DSP_CLK_FREQ_12M288, CLASSD_ACLK_RATE_12M288_MPY_8 },
364 { 22050, CLASSD_INTPMR_FRAME_22K,
365 CLASSD_INTPMR_DSP_CLK_FREQ_11M2896, CLASSD_ACLK_RATE_11M2896_MPY_8 },
366 { 44100, CLASSD_INTPMR_FRAME_44K,
367 CLASSD_INTPMR_DSP_CLK_FREQ_11M2896, CLASSD_ACLK_RATE_11M2896_MPY_8 },
368 { 88200, CLASSD_INTPMR_FRAME_88K,
369 CLASSD_INTPMR_DSP_CLK_FREQ_11M2896, CLASSD_ACLK_RATE_11M2896_MPY_8 },
370};
371
372static int
373atmel_classd_codec_dai_hw_params(struct snd_pcm_substream *substream,
374 struct snd_pcm_hw_params *params,
375 struct snd_soc_dai *codec_dai)
376{
377 struct snd_soc_pcm_runtime *rtd = substream->private_data;
378 struct atmel_classd *dd = snd_soc_card_get_drvdata(rtd->card);
379 struct snd_soc_codec *codec = codec_dai->codec;
380 int fs;
381 int i, best, best_val, cur_val, ret;
382 u32 mask, val;
383
384 fs = params_rate(params);
385
386 best = 0;
387 best_val = abs(fs - sample_rates[0].rate);
388 for (i = 1; i < ARRAY_SIZE(sample_rates); i++) {
389 /* Closest match */
390 cur_val = abs(fs - sample_rates[i].rate);
391 if (cur_val < best_val) {
392 best = i;
393 best_val = cur_val;
394 }
395 }
396
397 dev_dbg(codec->dev,
398 "Selected SAMPLE_RATE of %dHz, ACLK_RATE of %ldHz\n",
399 sample_rates[best].rate, sample_rates[best].aclk_rate);
400
401 clk_disable_unprepare(dd->gclk);
402 clk_disable_unprepare(dd->aclk);
403
404 ret = clk_set_rate(dd->aclk, sample_rates[best].aclk_rate);
405 if (ret)
406 return ret;
407
408 mask = CLASSD_INTPMR_DSP_CLK_FREQ_MASK | CLASSD_INTPMR_FRAME_MASK;
409 val = (sample_rates[best].dsp_clk << CLASSD_INTPMR_DSP_CLK_FREQ_SHIFT)
410 | (sample_rates[best].sample_rate << CLASSD_INTPMR_FRAME_SHIFT);
411
412 snd_soc_update_bits(codec, CLASSD_INTPMR, mask, val);
413
414 ret = clk_prepare_enable(dd->aclk);
415 if (ret)
416 return ret;
417
418 return clk_prepare_enable(dd->gclk);
419}
420
421static void
422atmel_classd_codec_dai_shutdown(struct snd_pcm_substream *substream,
423 struct snd_soc_dai *codec_dai)
424{
425 struct snd_soc_pcm_runtime *rtd = substream->private_data;
426 struct atmel_classd *dd = snd_soc_card_get_drvdata(rtd->card);
427
428 clk_disable_unprepare(dd->gclk);
429 clk_disable_unprepare(dd->aclk);
430}
431
432static int atmel_classd_codec_dai_prepare(struct snd_pcm_substream *substream,
433 struct snd_soc_dai *codec_dai)
434{
435 struct snd_soc_codec *codec = codec_dai->codec;
436
437 snd_soc_update_bits(codec, CLASSD_MR,
438 CLASSD_MR_LEN_MASK | CLASSD_MR_REN_MASK,
439 (CLASSD_MR_LEN_DIS << CLASSD_MR_LEN_SHIFT)
440 |(CLASSD_MR_REN_DIS << CLASSD_MR_REN_SHIFT));
441
442 return 0;
443}
444
445static int atmel_classd_codec_dai_trigger(struct snd_pcm_substream *substream,
446 int cmd, struct snd_soc_dai *codec_dai)
447{
448 struct snd_soc_codec *codec = codec_dai->codec;
449 u32 mask, val;
450
451 mask = CLASSD_MR_LEN_MASK | CLASSD_MR_REN_MASK;
452
453 switch (cmd) {
454 case SNDRV_PCM_TRIGGER_START:
455 case SNDRV_PCM_TRIGGER_RESUME:
456 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
457 val = mask;
458 break;
459 case SNDRV_PCM_TRIGGER_STOP:
460 case SNDRV_PCM_TRIGGER_SUSPEND:
461 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
462 val = (CLASSD_MR_LEN_DIS << CLASSD_MR_LEN_SHIFT)
463 | (CLASSD_MR_REN_DIS << CLASSD_MR_REN_SHIFT);
464 break;
465 default:
466 return -EINVAL;
467 }
468
469 snd_soc_update_bits(codec, CLASSD_MR, mask, val);
470
471 return 0;
472}
473
474static const struct snd_soc_dai_ops atmel_classd_codec_dai_ops = {
475 .digital_mute = atmel_classd_codec_dai_digital_mute,
476 .startup = atmel_classd_codec_dai_startup,
477 .shutdown = atmel_classd_codec_dai_shutdown,
478 .hw_params = atmel_classd_codec_dai_hw_params,
479 .prepare = atmel_classd_codec_dai_prepare,
480 .trigger = atmel_classd_codec_dai_trigger,
481};
482
483#define ATMEL_CLASSD_CODEC_DAI_NAME "atmel-classd-hifi"
484
485static struct snd_soc_dai_driver atmel_classd_codec_dai = {
486 .name = ATMEL_CLASSD_CODEC_DAI_NAME,
487 .playback = {
488 .stream_name = "Playback",
489 .channels_min = 2,
490 .channels_max = 2,
491 .rates = ATMEL_CLASSD_RATES,
492 .formats = SNDRV_PCM_FMTBIT_S16_LE,
493 },
494 .ops = &atmel_classd_codec_dai_ops,
495};
496
497/* ASoC sound card */
498static int atmel_classd_asoc_card_init(struct device *dev,
499 struct snd_soc_card *card)
500{
501 struct snd_soc_dai_link *dai_link;
502 struct atmel_classd *dd = snd_soc_card_get_drvdata(card);
503
504 dai_link = devm_kzalloc(dev, sizeof(*dai_link), GFP_KERNEL);
505 if (!dai_link)
506 return -ENOMEM;
507
508 dai_link->name = "CLASSD";
509 dai_link->stream_name = "CLASSD PCM";
510 dai_link->codec_dai_name = ATMEL_CLASSD_CODEC_DAI_NAME;
511 dai_link->cpu_dai_name = dev_name(dev);
512 dai_link->codec_name = dev_name(dev);
513 dai_link->platform_name = dev_name(dev);
514
515 card->dai_link = dai_link;
516 card->num_links = 1;
517 card->name = dd->pdata->card_name;
518 card->dev = dev;
519
520 return 0;
521};
522
523/* regmap configuration */
524static const struct reg_default atmel_classd_reg_defaults[] = {
525 { CLASSD_INTPMR, 0x00301212 },
526};
527
528#define ATMEL_CLASSD_REG_MAX 0xE4
529static const struct regmap_config atmel_classd_regmap_config = {
530 .reg_bits = 32,
531 .reg_stride = 4,
532 .val_bits = 32,
533 .max_register = ATMEL_CLASSD_REG_MAX,
534
535 .cache_type = REGCACHE_FLAT,
536 .reg_defaults = atmel_classd_reg_defaults,
537 .num_reg_defaults = ARRAY_SIZE(atmel_classd_reg_defaults),
538};
539
540static int atmel_classd_probe(struct platform_device *pdev)
541{
542 struct device *dev = &pdev->dev;
543 struct atmel_classd *dd;
544 struct resource *res;
545 void __iomem *io_base;
546 const struct atmel_classd_pdata *pdata;
547 struct snd_soc_card *card;
548 int ret;
549
550 pdata = dev_get_platdata(dev);
551 if (!pdata) {
552 pdata = atmel_classd_dt_init(dev);
553 if (IS_ERR(pdata))
554 return PTR_ERR(pdata);
555 }
556
557 dd = devm_kzalloc(dev, sizeof(*dd), GFP_KERNEL);
558 if (!dd)
559 return -ENOMEM;
560
561 dd->pdata = pdata;
562
563 dd->irq = platform_get_irq(pdev, 0);
564 if (dd->irq < 0) {
565 ret = dd->irq;
566 dev_err(dev, "failed to could not get irq: %d\n", ret);
567 return ret;
568 }
569
570 dd->pclk = devm_clk_get(dev, "pclk");
571 if (IS_ERR(dd->pclk)) {
572 ret = PTR_ERR(dd->pclk);
573 dev_err(dev, "failed to get peripheral clock: %d\n", ret);
574 return ret;
575 }
576
577 dd->gclk = devm_clk_get(dev, "gclk");
578 if (IS_ERR(dd->gclk)) {
579 ret = PTR_ERR(dd->gclk);
580 dev_err(dev, "failed to get GCK clock: %d\n", ret);
581 return ret;
582 }
583
584 dd->aclk = devm_clk_get(dev, "aclk");
585 if (IS_ERR(dd->aclk)) {
586 ret = PTR_ERR(dd->aclk);
587 dev_err(dev, "failed to get audio clock: %d\n", ret);
588 return ret;
589 }
590
591 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
592 if (!res) {
593 dev_err(dev, "no memory resource\n");
594 return -ENXIO;
595 }
596
597 io_base = devm_ioremap_resource(dev, res);
598 if (IS_ERR(io_base)) {
599 ret = PTR_ERR(io_base);
600 dev_err(dev, "failed to remap register memory: %d\n", ret);
601 return ret;
602 }
603
604 dd->phy_base = res->start;
605
606 dd->regmap = devm_regmap_init_mmio(dev, io_base,
607 &atmel_classd_regmap_config);
608 if (IS_ERR(dd->regmap)) {
609 ret = PTR_ERR(dd->regmap);
610 dev_err(dev, "failed to init register map: %d\n", ret);
611 return ret;
612 }
613
614 ret = devm_snd_soc_register_component(dev,
615 &atmel_classd_cpu_dai_component,
616 &atmel_classd_cpu_dai, 1);
617 if (ret) {
618 dev_err(dev, "could not register CPU DAI: %d\n", ret);
619 return ret;
620 }
621
622 ret = devm_snd_dmaengine_pcm_register(dev,
623 &atmel_classd_dmaengine_pcm_config,
624 0);
625 if (ret) {
626 dev_err(dev, "could not register platform: %d\n", ret);
627 return ret;
628 }
629
630 ret = snd_soc_register_codec(dev, &soc_codec_dev_classd,
631 &atmel_classd_codec_dai, 1);
632 if (ret) {
633 dev_err(dev, "could not register codec: %d\n", ret);
634 return ret;
635 }
636
637 /* register sound card */
638 card = devm_kzalloc(dev, sizeof(*card), GFP_KERNEL);
639 if (!card)
640 return -ENOMEM;
641
642 snd_soc_card_set_drvdata(card, dd);
643 platform_set_drvdata(pdev, card);
644
645 ret = atmel_classd_asoc_card_init(dev, card);
646 if (ret) {
647 dev_err(dev, "failed to init sound card\n");
648 return ret;
649 }
650
651 ret = devm_snd_soc_register_card(dev, card);
652 if (ret) {
653 dev_err(dev, "failed to register sound card: %d\n", ret);
654 return ret;
655 }
656
657 return 0;
658}
659
660static int atmel_classd_remove(struct platform_device *pdev)
661{
662 snd_soc_unregister_codec(&pdev->dev);
663 return 0;
664}
665
666static struct platform_driver atmel_classd_driver = {
667 .driver = {
668 .name = "atmel-classd",
669 .of_match_table = of_match_ptr(atmel_classd_of_match),
670 .pm = &snd_soc_pm_ops,
671 },
672 .probe = atmel_classd_probe,
673 .remove = atmel_classd_remove,
674};
675module_platform_driver(atmel_classd_driver);
676
677MODULE_DESCRIPTION("Atmel ClassD driver under ALSA SoC architecture");
678MODULE_AUTHOR("Songjun Wu <songjun.wu@atmel.com>");
679MODULE_LICENSE("GPL");
diff --git a/sound/soc/atmel/atmel-classd.h b/sound/soc/atmel/atmel-classd.h
new file mode 100644
index 000000000000..73f8fdd1ca83
--- /dev/null
+++ b/sound/soc/atmel/atmel-classd.h
@@ -0,0 +1,120 @@
1#ifndef __ATMEL_CLASSD_H_
2#define __ATMEL_CLASSD_H_
3
4#define CLASSD_CR 0x00000000
5#define CLASSD_CR_RESET 0x1
6
7#define CLASSD_MR 0x00000004
8
9#define CLASSD_MR_LEN_DIS 0x0
10#define CLASSD_MR_LEN_EN 0x1
11#define CLASSD_MR_LEN_MASK (0x1 << 0)
12#define CLASSD_MR_LEN_SHIFT (0)
13
14#define CLASSD_MR_LMUTE_DIS 0x0
15#define CLASSD_MR_LMUTE_EN 0x1
16#define CLASSD_MR_LMUTE_SHIFT (0x1)
17#define CLASSD_MR_LMUTE_MASK (0x1 << 1)
18
19#define CLASSD_MR_REN_DIS 0x0
20#define CLASSD_MR_REN_EN 0x1
21#define CLASSD_MR_REN_MASK (0x1 << 4)
22#define CLASSD_MR_REN_SHIFT (4)
23
24#define CLASSD_MR_RMUTE_DIS 0x0
25#define CLASSD_MR_RMUTE_EN 0x1
26#define CLASSD_MR_RMUTE_SHIFT (0x5)
27#define CLASSD_MR_RMUTE_MASK (0x1 << 5)
28
29#define CLASSD_MR_PWMTYP_SINGLE 0x0
30#define CLASSD_MR_PWMTYP_DIFF 0x1
31#define CLASSD_MR_PWMTYP_MASK (0x1 << 8)
32#define CLASSD_MR_PWMTYP_SHIFT (8)
33
34#define CLASSD_MR_NON_OVERLAP_DIS 0x0
35#define CLASSD_MR_NON_OVERLAP_EN 0x1
36#define CLASSD_MR_NON_OVERLAP_MASK (0x1 << 16)
37#define CLASSD_MR_NON_OVERLAP_SHIFT (16)
38
39#define CLASSD_MR_NOVR_VAL_5NS 0x0
40#define CLASSD_MR_NOVR_VAL_10NS 0x1
41#define CLASSD_MR_NOVR_VAL_15NS 0x2
42#define CLASSD_MR_NOVR_VAL_20NS 0x3
43#define CLASSD_MR_NOVR_VAL_MASK (0x3 << 20)
44#define CLASSD_MR_NOVR_VAL_SHIFT (20)
45
46#define CLASSD_INTPMR 0x00000008
47
48#define CLASSD_INTPMR_ATTL_MASK (0x3f << 0)
49#define CLASSD_INTPMR_ATTL_SHIFT (0)
50#define CLASSD_INTPMR_ATTR_MASK (0x3f << 8)
51#define CLASSD_INTPMR_ATTR_SHIFT (8)
52
53#define CLASSD_INTPMR_DSP_CLK_FREQ_12M288 0x0
54#define CLASSD_INTPMR_DSP_CLK_FREQ_11M2896 0x1
55#define CLASSD_INTPMR_DSP_CLK_FREQ_MASK (0x1 << 16)
56#define CLASSD_INTPMR_DSP_CLK_FREQ_SHIFT (16)
57
58#define CLASSD_INTPMR_DEEMP_DIS 0x0
59#define CLASSD_INTPMR_DEEMP_EN 0x1
60#define CLASSD_INTPMR_DEEMP_MASK (0x1 << 18)
61#define CLASSD_INTPMR_DEEMP_SHIFT (18)
62
63#define CLASSD_INTPMR_SWAP_LEFT_ON_LSB 0x0
64#define CLASSD_INTPMR_SWAP_RIGHT_ON_LSB 0x1
65#define CLASSD_INTPMR_SWAP_MASK (0x1 << 19)
66#define CLASSD_INTPMR_SWAP_SHIFT (19)
67
68#define CLASSD_INTPMR_FRAME_8K 0x0
69#define CLASSD_INTPMR_FRAME_16K 0x1
70#define CLASSD_INTPMR_FRAME_32K 0x2
71#define CLASSD_INTPMR_FRAME_48K 0x3
72#define CLASSD_INTPMR_FRAME_96K 0x4
73#define CLASSD_INTPMR_FRAME_22K 0x5
74#define CLASSD_INTPMR_FRAME_44K 0x6
75#define CLASSD_INTPMR_FRAME_88K 0x7
76#define CLASSD_INTPMR_FRAME_MASK (0x7 << 20)
77#define CLASSD_INTPMR_FRAME_SHIFT (20)
78
79#define CLASSD_INTPMR_EQCFG_FLAT 0x0
80#define CLASSD_INTPMR_EQCFG_B_BOOST_12 0x1
81#define CLASSD_INTPMR_EQCFG_B_BOOST_6 0x2
82#define CLASSD_INTPMR_EQCFG_B_CUT_12 0x3
83#define CLASSD_INTPMR_EQCFG_B_CUT_6 0x4
84#define CLASSD_INTPMR_EQCFG_M_BOOST_3 0x5
85#define CLASSD_INTPMR_EQCFG_M_BOOST_8 0x6
86#define CLASSD_INTPMR_EQCFG_M_CUT_3 0x7
87#define CLASSD_INTPMR_EQCFG_M_CUT_8 0x8
88#define CLASSD_INTPMR_EQCFG_T_BOOST_12 0x9
89#define CLASSD_INTPMR_EQCFG_T_BOOST_6 0xa
90#define CLASSD_INTPMR_EQCFG_T_CUT_12 0xb
91#define CLASSD_INTPMR_EQCFG_T_CUT_6 0xc
92#define CLASSD_INTPMR_EQCFG_SHIFT (24)
93
94#define CLASSD_INTPMR_MONO_DIS 0x0
95#define CLASSD_INTPMR_MONO_EN 0x1
96#define CLASSD_INTPMR_MONO_MASK (0x1 << 28)
97#define CLASSD_INTPMR_MONO_SHIFT (28)
98
99#define CLASSD_INTPMR_MONO_MODE_MIX 0x0
100#define CLASSD_INTPMR_MONO_MODE_SAT 0x1
101#define CLASSD_INTPMR_MONO_MODE_LEFT 0x2
102#define CLASSD_INTPMR_MONO_MODE_RIGHT 0x3
103#define CLASSD_INTPMR_MONO_MODE_MASK (0x3 << 29)
104#define CLASSD_INTPMR_MONO_MODE_SHIFT (29)
105
106#define CLASSD_INTSR 0x0000000c
107
108#define CLASSD_THR 0x00000010
109
110#define CLASSD_IER 0x00000014
111
112#define CLASSD_IDR 0x00000018
113
114#define CLASSD_IMR 0x0000001c
115
116#define CLASSD_ISR 0x00000020
117
118#define CLASSD_WPMR 0x000000e4
119
120#endif
diff --git a/sound/soc/atmel/atmel_wm8904.c b/sound/soc/atmel/atmel_wm8904.c
index aa354e1c6ff7..1933bcd46cca 100644
--- a/sound/soc/atmel/atmel_wm8904.c
+++ b/sound/soc/atmel/atmel_wm8904.c
@@ -176,6 +176,7 @@ static const struct of_device_id atmel_asoc_wm8904_dt_ids[] = {
176 { .compatible = "atmel,asoc-wm8904", }, 176 { .compatible = "atmel,asoc-wm8904", },
177 { } 177 { }
178}; 178};
179MODULE_DEVICE_TABLE(of, atmel_asoc_wm8904_dt_ids);
179#endif 180#endif
180 181
181static struct platform_driver atmel_asoc_wm8904_driver = { 182static struct platform_driver atmel_asoc_wm8904_driver = {
diff --git a/sound/soc/au1x/db1000.c b/sound/soc/au1x/db1000.c
index 452f404abfd2..e97c32798e98 100644
--- a/sound/soc/au1x/db1000.c
+++ b/sound/soc/au1x/db1000.c
@@ -38,14 +38,7 @@ static int db1000_audio_probe(struct platform_device *pdev)
38{ 38{
39 struct snd_soc_card *card = &db1000_ac97; 39 struct snd_soc_card *card = &db1000_ac97;
40 card->dev = &pdev->dev; 40 card->dev = &pdev->dev;
41 return snd_soc_register_card(card); 41 return devm_snd_soc_register_card(&pdev->dev, card);
42}
43
44static int db1000_audio_remove(struct platform_device *pdev)
45{
46 struct snd_soc_card *card = platform_get_drvdata(pdev);
47 snd_soc_unregister_card(card);
48 return 0;
49} 42}
50 43
51static struct platform_driver db1000_audio_driver = { 44static struct platform_driver db1000_audio_driver = {
@@ -54,7 +47,6 @@ static struct platform_driver db1000_audio_driver = {
54 .pm = &snd_soc_pm_ops, 47 .pm = &snd_soc_pm_ops,
55 }, 48 },
56 .probe = db1000_audio_probe, 49 .probe = db1000_audio_probe,
57 .remove = db1000_audio_remove,
58}; 50};
59 51
60module_platform_driver(db1000_audio_driver); 52module_platform_driver(db1000_audio_driver);
diff --git a/sound/soc/au1x/db1200.c b/sound/soc/au1x/db1200.c
index 8c907ebea189..5c73061d912a 100644
--- a/sound/soc/au1x/db1200.c
+++ b/sound/soc/au1x/db1200.c
@@ -178,14 +178,7 @@ static int db1200_audio_probe(struct platform_device *pdev)
178 178
179 card = db1200_cards[pid->driver_data]; 179 card = db1200_cards[pid->driver_data];
180 card->dev = &pdev->dev; 180 card->dev = &pdev->dev;
181 return snd_soc_register_card(card); 181 return devm_snd_soc_register_card(&pdev->dev, card);
182}
183
184static int db1200_audio_remove(struct platform_device *pdev)
185{
186 struct snd_soc_card *card = platform_get_drvdata(pdev);
187 snd_soc_unregister_card(card);
188 return 0;
189} 182}
190 183
191static struct platform_driver db1200_audio_driver = { 184static struct platform_driver db1200_audio_driver = {
@@ -195,7 +188,6 @@ static struct platform_driver db1200_audio_driver = {
195 }, 188 },
196 .id_table = db1200_pids, 189 .id_table = db1200_pids,
197 .probe = db1200_audio_probe, 190 .probe = db1200_audio_probe,
198 .remove = db1200_audio_remove,
199}; 191};
200 192
201module_platform_driver(db1200_audio_driver); 193module_platform_driver(db1200_audio_driver);
diff --git a/sound/soc/blackfin/bf5xx-ad1836.c b/sound/soc/blackfin/bf5xx-ad1836.c
index 5bf1501e5e3c..864df2616e10 100644
--- a/sound/soc/blackfin/bf5xx-ad1836.c
+++ b/sound/soc/blackfin/bf5xx-ad1836.c
@@ -87,27 +87,18 @@ static int bf5xx_ad1836_driver_probe(struct platform_device *pdev)
87 card->dev = &pdev->dev; 87 card->dev = &pdev->dev;
88 platform_set_drvdata(pdev, card); 88 platform_set_drvdata(pdev, card);
89 89
90 ret = snd_soc_register_card(card); 90 ret = devm_snd_soc_register_card(&pdev->dev, card);
91 if (ret) 91 if (ret)
92 dev_err(&pdev->dev, "Failed to register card\n"); 92 dev_err(&pdev->dev, "Failed to register card\n");
93 return ret; 93 return ret;
94} 94}
95 95
96static int bf5xx_ad1836_driver_remove(struct platform_device *pdev)
97{
98 struct snd_soc_card *card = platform_get_drvdata(pdev);
99
100 snd_soc_unregister_card(card);
101 return 0;
102}
103
104static struct platform_driver bf5xx_ad1836_driver = { 96static struct platform_driver bf5xx_ad1836_driver = {
105 .driver = { 97 .driver = {
106 .name = "bfin-snd-ad1836", 98 .name = "bfin-snd-ad1836",
107 .pm = &snd_soc_pm_ops, 99 .pm = &snd_soc_pm_ops,
108 }, 100 },
109 .probe = bf5xx_ad1836_driver_probe, 101 .probe = bf5xx_ad1836_driver_probe,
110 .remove = bf5xx_ad1836_driver_remove,
111}; 102};
112module_platform_driver(bf5xx_ad1836_driver); 103module_platform_driver(bf5xx_ad1836_driver);
113 104
diff --git a/sound/soc/blackfin/bfin-eval-adau1373.c b/sound/soc/blackfin/bfin-eval-adau1373.c
index 523baf5820d7..72ac78988426 100644
--- a/sound/soc/blackfin/bfin-eval-adau1373.c
+++ b/sound/soc/blackfin/bfin-eval-adau1373.c
@@ -154,16 +154,7 @@ static int bfin_eval_adau1373_probe(struct platform_device *pdev)
154 154
155 card->dev = &pdev->dev; 155 card->dev = &pdev->dev;
156 156
157 return snd_soc_register_card(&bfin_eval_adau1373); 157 return devm_snd_soc_register_card(&pdev->dev, &bfin_eval_adau1373);
158}
159
160static int bfin_eval_adau1373_remove(struct platform_device *pdev)
161{
162 struct snd_soc_card *card = platform_get_drvdata(pdev);
163
164 snd_soc_unregister_card(card);
165
166 return 0;
167} 158}
168 159
169static struct platform_driver bfin_eval_adau1373_driver = { 160static struct platform_driver bfin_eval_adau1373_driver = {
@@ -172,7 +163,6 @@ static struct platform_driver bfin_eval_adau1373_driver = {
172 .pm = &snd_soc_pm_ops, 163 .pm = &snd_soc_pm_ops,
173 }, 164 },
174 .probe = bfin_eval_adau1373_probe, 165 .probe = bfin_eval_adau1373_probe,
175 .remove = bfin_eval_adau1373_remove,
176}; 166};
177 167
178module_platform_driver(bfin_eval_adau1373_driver); 168module_platform_driver(bfin_eval_adau1373_driver);
diff --git a/sound/soc/blackfin/bfin-eval-adau1701.c b/sound/soc/blackfin/bfin-eval-adau1701.c
index f9e926dfd4ef..5c67f72cf9a9 100644
--- a/sound/soc/blackfin/bfin-eval-adau1701.c
+++ b/sound/soc/blackfin/bfin-eval-adau1701.c
@@ -94,16 +94,7 @@ static int bfin_eval_adau1701_probe(struct platform_device *pdev)
94 94
95 card->dev = &pdev->dev; 95 card->dev = &pdev->dev;
96 96
97 return snd_soc_register_card(&bfin_eval_adau1701); 97 return devm_snd_soc_register_card(&pdev->dev, &bfin_eval_adau1701);
98}
99
100static int bfin_eval_adau1701_remove(struct platform_device *pdev)
101{
102 struct snd_soc_card *card = platform_get_drvdata(pdev);
103
104 snd_soc_unregister_card(card);
105
106 return 0;
107} 98}
108 99
109static struct platform_driver bfin_eval_adau1701_driver = { 100static struct platform_driver bfin_eval_adau1701_driver = {
@@ -112,7 +103,6 @@ static struct platform_driver bfin_eval_adau1701_driver = {
112 .pm = &snd_soc_pm_ops, 103 .pm = &snd_soc_pm_ops,
113 }, 104 },
114 .probe = bfin_eval_adau1701_probe, 105 .probe = bfin_eval_adau1701_probe,
115 .remove = bfin_eval_adau1701_remove,
116}; 106};
117 107
118module_platform_driver(bfin_eval_adau1701_driver); 108module_platform_driver(bfin_eval_adau1701_driver);
diff --git a/sound/soc/blackfin/bfin-eval-adav80x.c b/sound/soc/blackfin/bfin-eval-adav80x.c
index 27eee66afdb2..1037477d10b2 100644
--- a/sound/soc/blackfin/bfin-eval-adav80x.c
+++ b/sound/soc/blackfin/bfin-eval-adav80x.c
@@ -119,16 +119,7 @@ static int bfin_eval_adav80x_probe(struct platform_device *pdev)
119 119
120 card->dev = &pdev->dev; 120 card->dev = &pdev->dev;
121 121
122 return snd_soc_register_card(&bfin_eval_adav80x); 122 return devm_snd_soc_register_card(&pdev->dev, &bfin_eval_adav80x);
123}
124
125static int bfin_eval_adav80x_remove(struct platform_device *pdev)
126{
127 struct snd_soc_card *card = platform_get_drvdata(pdev);
128
129 snd_soc_unregister_card(card);
130
131 return 0;
132} 123}
133 124
134static const struct platform_device_id bfin_eval_adav80x_ids[] = { 125static const struct platform_device_id bfin_eval_adav80x_ids[] = {
@@ -144,7 +135,6 @@ static struct platform_driver bfin_eval_adav80x_driver = {
144 .pm = &snd_soc_pm_ops, 135 .pm = &snd_soc_pm_ops,
145 }, 136 },
146 .probe = bfin_eval_adav80x_probe, 137 .probe = bfin_eval_adav80x_probe,
147 .remove = bfin_eval_adav80x_remove,
148 .id_table = bfin_eval_adav80x_ids, 138 .id_table = bfin_eval_adav80x_ids,
149}; 139};
150 140
diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig
index 0c9733ecd17f..cfdafc4c11ea 100644
--- a/sound/soc/codecs/Kconfig
+++ b/sound/soc/codecs/Kconfig
@@ -36,6 +36,7 @@ config SND_SOC_ALL_CODECS
36 select SND_SOC_AK4104 if SPI_MASTER 36 select SND_SOC_AK4104 if SPI_MASTER
37 select SND_SOC_AK4535 if I2C 37 select SND_SOC_AK4535 if I2C
38 select SND_SOC_AK4554 38 select SND_SOC_AK4554
39 select SND_SOC_AK4613 if I2C
39 select SND_SOC_AK4641 if I2C 40 select SND_SOC_AK4641 if I2C
40 select SND_SOC_AK4642 if I2C 41 select SND_SOC_AK4642 if I2C
41 select SND_SOC_AK4671 if I2C 42 select SND_SOC_AK4671 if I2C
@@ -57,6 +58,7 @@ config SND_SOC_ALL_CODECS
57 select SND_SOC_CX20442 if TTY 58 select SND_SOC_CX20442 if TTY
58 select SND_SOC_DA7210 if SND_SOC_I2C_AND_SPI 59 select SND_SOC_DA7210 if SND_SOC_I2C_AND_SPI
59 select SND_SOC_DA7213 if I2C 60 select SND_SOC_DA7213 if I2C
61 select SND_SOC_DA7219 if I2C
60 select SND_SOC_DA732X if I2C 62 select SND_SOC_DA732X if I2C
61 select SND_SOC_DA9055 if I2C 63 select SND_SOC_DA9055 if I2C
62 select SND_SOC_DMIC 64 select SND_SOC_DMIC
@@ -79,7 +81,7 @@ config SND_SOC_ALL_CODECS
79 select SND_SOC_MAX9877 if I2C 81 select SND_SOC_MAX9877 if I2C
80 select SND_SOC_MC13783 if MFD_MC13XXX 82 select SND_SOC_MC13783 if MFD_MC13XXX
81 select SND_SOC_ML26124 if I2C 83 select SND_SOC_ML26124 if I2C
82 select SND_SOC_HDMI_CODEC 84 select SND_SOC_NAU8825 if I2C
83 select SND_SOC_PCM1681 if I2C 85 select SND_SOC_PCM1681 if I2C
84 select SND_SOC_PCM1792A if SPI_MASTER 86 select SND_SOC_PCM1792A if SPI_MASTER
85 select SND_SOC_PCM3008 87 select SND_SOC_PCM3008
@@ -171,6 +173,7 @@ config SND_SOC_ALL_CODECS
171 select SND_SOC_WM8995 if SND_SOC_I2C_AND_SPI 173 select SND_SOC_WM8995 if SND_SOC_I2C_AND_SPI
172 select SND_SOC_WM8996 if I2C 174 select SND_SOC_WM8996 if I2C
173 select SND_SOC_WM8997 if MFD_WM8997 175 select SND_SOC_WM8997 if MFD_WM8997
176 select SND_SOC_WM8998 if MFD_WM8998
174 select SND_SOC_WM9081 if I2C 177 select SND_SOC_WM9081 if I2C
175 select SND_SOC_WM9090 if I2C 178 select SND_SOC_WM9090 if I2C
176 select SND_SOC_WM9705 if SND_SOC_AC97_BUS 179 select SND_SOC_WM9705 if SND_SOC_AC97_BUS
@@ -195,9 +198,11 @@ config SND_SOC_ARIZONA
195 default y if SND_SOC_WM5102=y 198 default y if SND_SOC_WM5102=y
196 default y if SND_SOC_WM5110=y 199 default y if SND_SOC_WM5110=y
197 default y if SND_SOC_WM8997=y 200 default y if SND_SOC_WM8997=y
201 default y if SND_SOC_WM8998=y
198 default m if SND_SOC_WM5102=m 202 default m if SND_SOC_WM5102=m
199 default m if SND_SOC_WM5110=m 203 default m if SND_SOC_WM5110=m
200 default m if SND_SOC_WM8997=m 204 default m if SND_SOC_WM8997=m
205 default m if SND_SOC_WM8998=m
201 206
202config SND_SOC_WM_HUBS 207config SND_SOC_WM_HUBS
203 tristate 208 tristate
@@ -319,6 +324,10 @@ config SND_SOC_AK4535
319config SND_SOC_AK4554 324config SND_SOC_AK4554
320 tristate "AKM AK4554 CODEC" 325 tristate "AKM AK4554 CODEC"
321 326
327config SND_SOC_AK4613
328 tristate "AKM AK4613 CODEC"
329 depends on I2C
330
322config SND_SOC_AK4641 331config SND_SOC_AK4641
323 tristate 332 tristate
324 333
@@ -430,6 +439,9 @@ config SND_SOC_DA7210
430config SND_SOC_DA7213 439config SND_SOC_DA7213
431 tristate 440 tristate
432 441
442config SND_SOC_DA7219
443 tristate
444
433config SND_SOC_DA732X 445config SND_SOC_DA732X
434 tristate 446 tristate
435 447
@@ -442,9 +454,6 @@ config SND_SOC_BT_SCO
442config SND_SOC_DMIC 454config SND_SOC_DMIC
443 tristate 455 tristate
444 456
445config SND_SOC_HDMI_CODEC
446 tristate "HDMI stub CODEC"
447
448config SND_SOC_ES8328 457config SND_SOC_ES8328
449 tristate "Everest Semi ES8328 CODEC" 458 tristate "Everest Semi ES8328 CODEC"
450 459
@@ -865,6 +874,9 @@ config SND_SOC_WM8996
865config SND_SOC_WM8997 874config SND_SOC_WM8997
866 tristate 875 tristate
867 876
877config SND_SOC_WM8998
878 tristate
879
868config SND_SOC_WM9081 880config SND_SOC_WM9081
869 tristate 881 tristate
870 882
@@ -896,6 +908,9 @@ config SND_SOC_MC13783
896config SND_SOC_ML26124 908config SND_SOC_ML26124
897 tristate 909 tristate
898 910
911config SND_SOC_NAU8825
912 tristate
913
899config SND_SOC_TPA6130A2 914config SND_SOC_TPA6130A2
900 tristate "Texas Instruments TPA6130A2 headphone amplifier" 915 tristate "Texas Instruments TPA6130A2 headphone amplifier"
901 depends on I2C 916 depends on I2C
diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile
index 4a32077954ae..f632fc42f59f 100644
--- a/sound/soc/codecs/Makefile
+++ b/sound/soc/codecs/Makefile
@@ -26,6 +26,7 @@ snd-soc-ads117x-objs := ads117x.o
26snd-soc-ak4104-objs := ak4104.o 26snd-soc-ak4104-objs := ak4104.o
27snd-soc-ak4535-objs := ak4535.o 27snd-soc-ak4535-objs := ak4535.o
28snd-soc-ak4554-objs := ak4554.o 28snd-soc-ak4554-objs := ak4554.o
29snd-soc-ak4613-objs := ak4613.o
29snd-soc-ak4641-objs := ak4641.o 30snd-soc-ak4641-objs := ak4641.o
30snd-soc-ak4642-objs := ak4642.o 31snd-soc-ak4642-objs := ak4642.o
31snd-soc-ak4671-objs := ak4671.o 32snd-soc-ak4671-objs := ak4671.o
@@ -49,6 +50,7 @@ snd-soc-cs4349-objs := cs4349.o
49snd-soc-cx20442-objs := cx20442.o 50snd-soc-cx20442-objs := cx20442.o
50snd-soc-da7210-objs := da7210.o 51snd-soc-da7210-objs := da7210.o
51snd-soc-da7213-objs := da7213.o 52snd-soc-da7213-objs := da7213.o
53snd-soc-da7219-objs := da7219.o da7219-aad.o
52snd-soc-da732x-objs := da732x.o 54snd-soc-da732x-objs := da732x.o
53snd-soc-da9055-objs := da9055.o 55snd-soc-da9055-objs := da9055.o
54snd-soc-bt-sco-objs := bt-sco.o 56snd-soc-bt-sco-objs := bt-sco.o
@@ -72,7 +74,7 @@ snd-soc-max98925-objs := max98925.o
72snd-soc-max9850-objs := max9850.o 74snd-soc-max9850-objs := max9850.o
73snd-soc-mc13783-objs := mc13783.o 75snd-soc-mc13783-objs := mc13783.o
74snd-soc-ml26124-objs := ml26124.o 76snd-soc-ml26124-objs := ml26124.o
75snd-soc-hdmi-codec-objs := hdmi.o 77snd-soc-nau8825-objs := nau8825.o
76snd-soc-pcm1681-objs := pcm1681.o 78snd-soc-pcm1681-objs := pcm1681.o
77snd-soc-pcm1792a-codec-objs := pcm1792a.o 79snd-soc-pcm1792a-codec-objs := pcm1792a.o
78snd-soc-pcm3008-objs := pcm3008.o 80snd-soc-pcm3008-objs := pcm3008.o
@@ -176,6 +178,7 @@ snd-soc-wm8993-objs := wm8993.o
176snd-soc-wm8994-objs := wm8994.o wm8958-dsp2.o 178snd-soc-wm8994-objs := wm8994.o wm8958-dsp2.o
177snd-soc-wm8995-objs := wm8995.o 179snd-soc-wm8995-objs := wm8995.o
178snd-soc-wm8997-objs := wm8997.o 180snd-soc-wm8997-objs := wm8997.o
181snd-soc-wm8998-objs := wm8998.o
179snd-soc-wm9081-objs := wm9081.o 182snd-soc-wm9081-objs := wm9081.o
180snd-soc-wm9090-objs := wm9090.o 183snd-soc-wm9090-objs := wm9090.o
181snd-soc-wm9705-objs := wm9705.o 184snd-soc-wm9705-objs := wm9705.o
@@ -216,6 +219,7 @@ obj-$(CONFIG_SND_SOC_ADS117X) += snd-soc-ads117x.o
216obj-$(CONFIG_SND_SOC_AK4104) += snd-soc-ak4104.o 219obj-$(CONFIG_SND_SOC_AK4104) += snd-soc-ak4104.o
217obj-$(CONFIG_SND_SOC_AK4535) += snd-soc-ak4535.o 220obj-$(CONFIG_SND_SOC_AK4535) += snd-soc-ak4535.o
218obj-$(CONFIG_SND_SOC_AK4554) += snd-soc-ak4554.o 221obj-$(CONFIG_SND_SOC_AK4554) += snd-soc-ak4554.o
222obj-$(CONFIG_SND_SOC_AK4613) += snd-soc-ak4613.o
219obj-$(CONFIG_SND_SOC_AK4641) += snd-soc-ak4641.o 223obj-$(CONFIG_SND_SOC_AK4641) += snd-soc-ak4641.o
220obj-$(CONFIG_SND_SOC_AK4642) += snd-soc-ak4642.o 224obj-$(CONFIG_SND_SOC_AK4642) += snd-soc-ak4642.o
221obj-$(CONFIG_SND_SOC_AK4671) += snd-soc-ak4671.o 225obj-$(CONFIG_SND_SOC_AK4671) += snd-soc-ak4671.o
@@ -241,6 +245,7 @@ obj-$(CONFIG_SND_SOC_CS4349) += snd-soc-cs4349.o
241obj-$(CONFIG_SND_SOC_CX20442) += snd-soc-cx20442.o 245obj-$(CONFIG_SND_SOC_CX20442) += snd-soc-cx20442.o
242obj-$(CONFIG_SND_SOC_DA7210) += snd-soc-da7210.o 246obj-$(CONFIG_SND_SOC_DA7210) += snd-soc-da7210.o
243obj-$(CONFIG_SND_SOC_DA7213) += snd-soc-da7213.o 247obj-$(CONFIG_SND_SOC_DA7213) += snd-soc-da7213.o
248obj-$(CONFIG_SND_SOC_DA7219) += snd-soc-da7219.o
244obj-$(CONFIG_SND_SOC_DA732X) += snd-soc-da732x.o 249obj-$(CONFIG_SND_SOC_DA732X) += snd-soc-da732x.o
245obj-$(CONFIG_SND_SOC_DA9055) += snd-soc-da9055.o 250obj-$(CONFIG_SND_SOC_DA9055) += snd-soc-da9055.o
246obj-$(CONFIG_SND_SOC_BT_SCO) += snd-soc-bt-sco.o 251obj-$(CONFIG_SND_SOC_BT_SCO) += snd-soc-bt-sco.o
@@ -264,7 +269,7 @@ obj-$(CONFIG_SND_SOC_MAX98925) += snd-soc-max98925.o
264obj-$(CONFIG_SND_SOC_MAX9850) += snd-soc-max9850.o 269obj-$(CONFIG_SND_SOC_MAX9850) += snd-soc-max9850.o
265obj-$(CONFIG_SND_SOC_MC13783) += snd-soc-mc13783.o 270obj-$(CONFIG_SND_SOC_MC13783) += snd-soc-mc13783.o
266obj-$(CONFIG_SND_SOC_ML26124) += snd-soc-ml26124.o 271obj-$(CONFIG_SND_SOC_ML26124) += snd-soc-ml26124.o
267obj-$(CONFIG_SND_SOC_HDMI_CODEC) += snd-soc-hdmi-codec.o 272obj-$(CONFIG_SND_SOC_NAU8825) += snd-soc-nau8825.o
268obj-$(CONFIG_SND_SOC_PCM1681) += snd-soc-pcm1681.o 273obj-$(CONFIG_SND_SOC_PCM1681) += snd-soc-pcm1681.o
269obj-$(CONFIG_SND_SOC_PCM1792A) += snd-soc-pcm1792a-codec.o 274obj-$(CONFIG_SND_SOC_PCM1792A) += snd-soc-pcm1792a-codec.o
270obj-$(CONFIG_SND_SOC_PCM3008) += snd-soc-pcm3008.o 275obj-$(CONFIG_SND_SOC_PCM3008) += snd-soc-pcm3008.o
@@ -364,6 +369,7 @@ obj-$(CONFIG_SND_SOC_WM8993) += snd-soc-wm8993.o
364obj-$(CONFIG_SND_SOC_WM8994) += snd-soc-wm8994.o 369obj-$(CONFIG_SND_SOC_WM8994) += snd-soc-wm8994.o
365obj-$(CONFIG_SND_SOC_WM8995) += snd-soc-wm8995.o 370obj-$(CONFIG_SND_SOC_WM8995) += snd-soc-wm8995.o
366obj-$(CONFIG_SND_SOC_WM8997) += snd-soc-wm8997.o 371obj-$(CONFIG_SND_SOC_WM8997) += snd-soc-wm8997.o
372obj-$(CONFIG_SND_SOC_WM8998) += snd-soc-wm8998.o
367obj-$(CONFIG_SND_SOC_WM9081) += snd-soc-wm9081.o 373obj-$(CONFIG_SND_SOC_WM9081) += snd-soc-wm9081.o
368obj-$(CONFIG_SND_SOC_WM9090) += snd-soc-wm9090.o 374obj-$(CONFIG_SND_SOC_WM9090) += snd-soc-wm9090.o
369obj-$(CONFIG_SND_SOC_WM9705) += snd-soc-wm9705.o 375obj-$(CONFIG_SND_SOC_WM9705) += snd-soc-wm9705.o
diff --git a/sound/soc/codecs/ad193x-i2c.c b/sound/soc/codecs/ad193x-i2c.c
index df3a1a415825..171313664bc8 100644
--- a/sound/soc/codecs/ad193x-i2c.c
+++ b/sound/soc/codecs/ad193x-i2c.c
@@ -15,8 +15,8 @@
15#include "ad193x.h" 15#include "ad193x.h"
16 16
17static const struct i2c_device_id ad193x_id[] = { 17static const struct i2c_device_id ad193x_id[] = {
18 { "ad1936", 0 }, 18 { "ad1936", AD193X },
19 { "ad1937", 0 }, 19 { "ad1937", AD193X },
20 { } 20 { }
21}; 21};
22MODULE_DEVICE_TABLE(i2c, ad193x_id); 22MODULE_DEVICE_TABLE(i2c, ad193x_id);
@@ -30,7 +30,9 @@ static int ad193x_i2c_probe(struct i2c_client *client,
30 config.val_bits = 8; 30 config.val_bits = 8;
31 config.reg_bits = 8; 31 config.reg_bits = 8;
32 32
33 return ad193x_probe(&client->dev, devm_regmap_init_i2c(client, &config)); 33 return ad193x_probe(&client->dev,
34 devm_regmap_init_i2c(client, &config),
35 (enum ad193x_type)id->driver_data);
34} 36}
35 37
36static int ad193x_i2c_remove(struct i2c_client *client) 38static int ad193x_i2c_remove(struct i2c_client *client)
diff --git a/sound/soc/codecs/ad193x-spi.c b/sound/soc/codecs/ad193x-spi.c
index 8199a3de0024..23c28573bdb7 100644
--- a/sound/soc/codecs/ad193x-spi.c
+++ b/sound/soc/codecs/ad193x-spi.c
@@ -16,6 +16,7 @@
16 16
17static int ad193x_spi_probe(struct spi_device *spi) 17static int ad193x_spi_probe(struct spi_device *spi)
18{ 18{
19 const struct spi_device_id *id = spi_get_device_id(spi);
19 struct regmap_config config; 20 struct regmap_config config;
20 21
21 config = ad193x_regmap_config; 22 config = ad193x_regmap_config;
@@ -24,7 +25,8 @@ static int ad193x_spi_probe(struct spi_device *spi)
24 config.read_flag_mask = 0x09; 25 config.read_flag_mask = 0x09;
25 config.write_flag_mask = 0x08; 26 config.write_flag_mask = 0x08;
26 27
27 return ad193x_probe(&spi->dev, devm_regmap_init_spi(spi, &config)); 28 return ad193x_probe(&spi->dev, devm_regmap_init_spi(spi, &config),
29 (enum ad193x_type)id->driver_data);
28} 30}
29 31
30static int ad193x_spi_remove(struct spi_device *spi) 32static int ad193x_spi_remove(struct spi_device *spi)
@@ -33,12 +35,24 @@ static int ad193x_spi_remove(struct spi_device *spi)
33 return 0; 35 return 0;
34} 36}
35 37
38static const struct spi_device_id ad193x_spi_id[] = {
39 { "ad193x", AD193X },
40 { "ad1933", AD1933 },
41 { "ad1934", AD1934 },
42 { "ad1938", AD193X },
43 { "ad1939", AD193X },
44 { "adau1328", AD193X },
45 { }
46};
47MODULE_DEVICE_TABLE(spi, ad193x_spi_id);
48
36static struct spi_driver ad193x_spi_driver = { 49static struct spi_driver ad193x_spi_driver = {
37 .driver = { 50 .driver = {
38 .name = "ad193x", 51 .name = "ad193x",
39 }, 52 },
40 .probe = ad193x_spi_probe, 53 .probe = ad193x_spi_probe,
41 .remove = ad193x_spi_remove, 54 .remove = ad193x_spi_remove,
55 .id_table = ad193x_spi_id,
42}; 56};
43module_spi_driver(ad193x_spi_driver); 57module_spi_driver(ad193x_spi_driver);
44 58
diff --git a/sound/soc/codecs/ad193x.c b/sound/soc/codecs/ad193x.c
index 17c953595660..3a3f3f2343d7 100644
--- a/sound/soc/codecs/ad193x.c
+++ b/sound/soc/codecs/ad193x.c
@@ -23,6 +23,7 @@
23/* codec private data */ 23/* codec private data */
24struct ad193x_priv { 24struct ad193x_priv {
25 struct regmap *regmap; 25 struct regmap *regmap;
26 enum ad193x_type type;
26 int sysclk; 27 int sysclk;
27}; 28};
28 29
@@ -47,12 +48,6 @@ static const struct snd_kcontrol_new ad193x_snd_controls[] = {
47 SOC_DOUBLE_R_TLV("DAC4 Volume", AD193X_DAC_L4_VOL, 48 SOC_DOUBLE_R_TLV("DAC4 Volume", AD193X_DAC_L4_VOL,
48 AD193X_DAC_R4_VOL, 0, 0xFF, 1, adau193x_tlv), 49 AD193X_DAC_R4_VOL, 0, 0xFF, 1, adau193x_tlv),
49 50
50 /* ADC switch control */
51 SOC_DOUBLE("ADC1 Switch", AD193X_ADC_CTRL0, AD193X_ADCL1_MUTE,
52 AD193X_ADCR1_MUTE, 1, 1),
53 SOC_DOUBLE("ADC2 Switch", AD193X_ADC_CTRL0, AD193X_ADCL2_MUTE,
54 AD193X_ADCR2_MUTE, 1, 1),
55
56 /* DAC switch control */ 51 /* DAC switch control */
57 SOC_DOUBLE("DAC1 Switch", AD193X_DAC_CHNL_MUTE, AD193X_DACL1_MUTE, 52 SOC_DOUBLE("DAC1 Switch", AD193X_DAC_CHNL_MUTE, AD193X_DACL1_MUTE,
58 AD193X_DACR1_MUTE, 1, 1), 53 AD193X_DACR1_MUTE, 1, 1),
@@ -63,26 +58,37 @@ static const struct snd_kcontrol_new ad193x_snd_controls[] = {
63 SOC_DOUBLE("DAC4 Switch", AD193X_DAC_CHNL_MUTE, AD193X_DACL4_MUTE, 58 SOC_DOUBLE("DAC4 Switch", AD193X_DAC_CHNL_MUTE, AD193X_DACL4_MUTE,
64 AD193X_DACR4_MUTE, 1, 1), 59 AD193X_DACR4_MUTE, 1, 1),
65 60
61 /* DAC de-emphasis */
62 SOC_ENUM("Playback Deemphasis", ad193x_deemp_enum),
63};
64
65static const struct snd_kcontrol_new ad193x_adc_snd_controls[] = {
66 /* ADC switch control */
67 SOC_DOUBLE("ADC1 Switch", AD193X_ADC_CTRL0, AD193X_ADCL1_MUTE,
68 AD193X_ADCR1_MUTE, 1, 1),
69 SOC_DOUBLE("ADC2 Switch", AD193X_ADC_CTRL0, AD193X_ADCL2_MUTE,
70 AD193X_ADCR2_MUTE, 1, 1),
71
66 /* ADC high-pass filter */ 72 /* ADC high-pass filter */
67 SOC_SINGLE("ADC High Pass Filter Switch", AD193X_ADC_CTRL0, 73 SOC_SINGLE("ADC High Pass Filter Switch", AD193X_ADC_CTRL0,
68 AD193X_ADC_HIGHPASS_FILTER, 1, 0), 74 AD193X_ADC_HIGHPASS_FILTER, 1, 0),
69
70 /* DAC de-emphasis */
71 SOC_ENUM("Playback Deemphasis", ad193x_deemp_enum),
72}; 75};
73 76
74static const struct snd_soc_dapm_widget ad193x_dapm_widgets[] = { 77static const struct snd_soc_dapm_widget ad193x_dapm_widgets[] = {
75 SND_SOC_DAPM_DAC("DAC", "Playback", SND_SOC_NOPM, 0, 0), 78 SND_SOC_DAPM_DAC("DAC", "Playback", SND_SOC_NOPM, 0, 0),
76 SND_SOC_DAPM_PGA("DAC Output", AD193X_DAC_CTRL0, 0, 1, NULL, 0), 79 SND_SOC_DAPM_PGA("DAC Output", AD193X_DAC_CTRL0, 0, 1, NULL, 0),
77 SND_SOC_DAPM_ADC("ADC", "Capture", SND_SOC_NOPM, 0, 0),
78 SND_SOC_DAPM_SUPPLY("PLL_PWR", AD193X_PLL_CLK_CTRL0, 0, 1, NULL, 0), 80 SND_SOC_DAPM_SUPPLY("PLL_PWR", AD193X_PLL_CLK_CTRL0, 0, 1, NULL, 0),
79 SND_SOC_DAPM_SUPPLY("ADC_PWR", AD193X_ADC_CTRL0, 0, 1, NULL, 0),
80 SND_SOC_DAPM_SUPPLY("SYSCLK", AD193X_PLL_CLK_CTRL0, 7, 0, NULL, 0), 81 SND_SOC_DAPM_SUPPLY("SYSCLK", AD193X_PLL_CLK_CTRL0, 7, 0, NULL, 0),
81 SND_SOC_DAPM_VMID("VMID"), 82 SND_SOC_DAPM_VMID("VMID"),
82 SND_SOC_DAPM_OUTPUT("DAC1OUT"), 83 SND_SOC_DAPM_OUTPUT("DAC1OUT"),
83 SND_SOC_DAPM_OUTPUT("DAC2OUT"), 84 SND_SOC_DAPM_OUTPUT("DAC2OUT"),
84 SND_SOC_DAPM_OUTPUT("DAC3OUT"), 85 SND_SOC_DAPM_OUTPUT("DAC3OUT"),
85 SND_SOC_DAPM_OUTPUT("DAC4OUT"), 86 SND_SOC_DAPM_OUTPUT("DAC4OUT"),
87};
88
89static const struct snd_soc_dapm_widget ad193x_adc_widgets[] = {
90 SND_SOC_DAPM_ADC("ADC", "Capture", SND_SOC_NOPM, 0, 0),
91 SND_SOC_DAPM_SUPPLY("ADC_PWR", AD193X_ADC_CTRL0, 0, 1, NULL, 0),
86 SND_SOC_DAPM_INPUT("ADC1IN"), 92 SND_SOC_DAPM_INPUT("ADC1IN"),
87 SND_SOC_DAPM_INPUT("ADC2IN"), 93 SND_SOC_DAPM_INPUT("ADC2IN"),
88}; 94};
@@ -91,18 +97,33 @@ static const struct snd_soc_dapm_route audio_paths[] = {
91 { "DAC", NULL, "SYSCLK" }, 97 { "DAC", NULL, "SYSCLK" },
92 { "DAC Output", NULL, "DAC" }, 98 { "DAC Output", NULL, "DAC" },
93 { "DAC Output", NULL, "VMID" }, 99 { "DAC Output", NULL, "VMID" },
94 { "ADC", NULL, "SYSCLK" },
95 { "DAC", NULL, "ADC_PWR" },
96 { "ADC", NULL, "ADC_PWR" },
97 { "DAC1OUT", NULL, "DAC Output" }, 100 { "DAC1OUT", NULL, "DAC Output" },
98 { "DAC2OUT", NULL, "DAC Output" }, 101 { "DAC2OUT", NULL, "DAC Output" },
99 { "DAC3OUT", NULL, "DAC Output" }, 102 { "DAC3OUT", NULL, "DAC Output" },
100 { "DAC4OUT", NULL, "DAC Output" }, 103 { "DAC4OUT", NULL, "DAC Output" },
104 { "SYSCLK", NULL, "PLL_PWR" },
105};
106
107static const struct snd_soc_dapm_route ad193x_adc_audio_paths[] = {
108 { "ADC", NULL, "SYSCLK" },
109 { "ADC", NULL, "ADC_PWR" },
101 { "ADC", NULL, "ADC1IN" }, 110 { "ADC", NULL, "ADC1IN" },
102 { "ADC", NULL, "ADC2IN" }, 111 { "ADC", NULL, "ADC2IN" },
103 { "SYSCLK", NULL, "PLL_PWR" },
104}; 112};
105 113
114static inline bool ad193x_has_adc(const struct ad193x_priv *ad193x)
115{
116 switch (ad193x->type) {
117 case AD1933:
118 case AD1934:
119 return false;
120 default:
121 break;
122 }
123
124 return true;
125}
126
106/* 127/*
107 * DAI ops entries 128 * DAI ops entries
108 */ 129 */
@@ -147,8 +168,10 @@ static int ad193x_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
147 168
148 regmap_update_bits(ad193x->regmap, AD193X_DAC_CTRL1, 169 regmap_update_bits(ad193x->regmap, AD193X_DAC_CTRL1,
149 AD193X_DAC_CHAN_MASK, channels << AD193X_DAC_CHAN_SHFT); 170 AD193X_DAC_CHAN_MASK, channels << AD193X_DAC_CHAN_SHFT);
150 regmap_update_bits(ad193x->regmap, AD193X_ADC_CTRL2, 171 if (ad193x_has_adc(ad193x))
151 AD193X_ADC_CHAN_MASK, channels << AD193X_ADC_CHAN_SHFT); 172 regmap_update_bits(ad193x->regmap, AD193X_ADC_CTRL2,
173 AD193X_ADC_CHAN_MASK,
174 channels << AD193X_ADC_CHAN_SHFT);
152 175
153 return 0; 176 return 0;
154} 177}
@@ -172,7 +195,9 @@ static int ad193x_set_dai_fmt(struct snd_soc_dai *codec_dai,
172 adc_serfmt |= AD193X_ADC_SERFMT_AUX; 195 adc_serfmt |= AD193X_ADC_SERFMT_AUX;
173 break; 196 break;
174 default: 197 default:
175 return -EINVAL; 198 if (ad193x_has_adc(ad193x))
199 return -EINVAL;
200 break;
176 } 201 }
177 202
178 switch (fmt & SND_SOC_DAIFMT_INV_MASK) { 203 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
@@ -217,10 +242,12 @@ static int ad193x_set_dai_fmt(struct snd_soc_dai *codec_dai,
217 return -EINVAL; 242 return -EINVAL;
218 } 243 }
219 244
220 regmap_update_bits(ad193x->regmap, AD193X_ADC_CTRL1, 245 if (ad193x_has_adc(ad193x)) {
221 AD193X_ADC_SERFMT_MASK, adc_serfmt); 246 regmap_update_bits(ad193x->regmap, AD193X_ADC_CTRL1,
222 regmap_update_bits(ad193x->regmap, AD193X_ADC_CTRL2, 247 AD193X_ADC_SERFMT_MASK, adc_serfmt);
223 AD193X_ADC_FMT_MASK, adc_fmt); 248 regmap_update_bits(ad193x->regmap, AD193X_ADC_CTRL2,
249 AD193X_ADC_FMT_MASK, adc_fmt);
250 }
224 regmap_update_bits(ad193x->regmap, AD193X_DAC_CTRL1, 251 regmap_update_bits(ad193x->regmap, AD193X_DAC_CTRL1,
225 AD193X_DAC_FMT_MASK, dac_fmt); 252 AD193X_DAC_FMT_MASK, dac_fmt);
226 253
@@ -287,8 +314,9 @@ static int ad193x_hw_params(struct snd_pcm_substream *substream,
287 AD193X_DAC_WORD_LEN_MASK, 314 AD193X_DAC_WORD_LEN_MASK,
288 word_len << AD193X_DAC_WORD_LEN_SHFT); 315 word_len << AD193X_DAC_WORD_LEN_SHFT);
289 316
290 regmap_update_bits(ad193x->regmap, AD193X_ADC_CTRL1, 317 if (ad193x_has_adc(ad193x))
291 AD193X_ADC_WORD_LEN_MASK, word_len); 318 regmap_update_bits(ad193x->regmap, AD193X_ADC_CTRL1,
319 AD193X_ADC_WORD_LEN_MASK, word_len);
292 320
293 return 0; 321 return 0;
294} 322}
@@ -326,6 +354,8 @@ static struct snd_soc_dai_driver ad193x_dai = {
326static int ad193x_codec_probe(struct snd_soc_codec *codec) 354static int ad193x_codec_probe(struct snd_soc_codec *codec)
327{ 355{
328 struct ad193x_priv *ad193x = snd_soc_codec_get_drvdata(codec); 356 struct ad193x_priv *ad193x = snd_soc_codec_get_drvdata(codec);
357 struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
358 int num, ret;
329 359
330 /* default setting for ad193x */ 360 /* default setting for ad193x */
331 361
@@ -335,14 +365,46 @@ static int ad193x_codec_probe(struct snd_soc_codec *codec)
335 regmap_write(ad193x->regmap, AD193X_DAC_CTRL2, 0x1A); 365 regmap_write(ad193x->regmap, AD193X_DAC_CTRL2, 0x1A);
336 /* dac in tdm mode */ 366 /* dac in tdm mode */
337 regmap_write(ad193x->regmap, AD193X_DAC_CTRL0, 0x40); 367 regmap_write(ad193x->regmap, AD193X_DAC_CTRL0, 0x40);
338 /* high-pass filter enable */ 368
339 regmap_write(ad193x->regmap, AD193X_ADC_CTRL0, 0x3); 369 /* adc only */
340 /* sata delay=1, adc aux mode */ 370 if (ad193x_has_adc(ad193x)) {
341 regmap_write(ad193x->regmap, AD193X_ADC_CTRL1, 0x43); 371 /* high-pass filter enable */
372 regmap_write(ad193x->regmap, AD193X_ADC_CTRL0, 0x3);
373 /* sata delay=1, adc aux mode */
374 regmap_write(ad193x->regmap, AD193X_ADC_CTRL1, 0x43);
375 }
376
342 /* pll input: mclki/xi */ 377 /* pll input: mclki/xi */
343 regmap_write(ad193x->regmap, AD193X_PLL_CLK_CTRL0, 0x99); /* mclk=24.576Mhz: 0x9D; mclk=12.288Mhz: 0x99 */ 378 regmap_write(ad193x->regmap, AD193X_PLL_CLK_CTRL0, 0x99); /* mclk=24.576Mhz: 0x9D; mclk=12.288Mhz: 0x99 */
344 regmap_write(ad193x->regmap, AD193X_PLL_CLK_CTRL1, 0x04); 379 regmap_write(ad193x->regmap, AD193X_PLL_CLK_CTRL1, 0x04);
345 380
381 /* adc only */
382 if (ad193x_has_adc(ad193x)) {
383 /* add adc controls */
384 num = ARRAY_SIZE(ad193x_adc_snd_controls);
385 ret = snd_soc_add_codec_controls(codec,
386 ad193x_adc_snd_controls,
387 num);
388 if (ret)
389 return ret;
390
391 /* add adc widgets */
392 num = ARRAY_SIZE(ad193x_adc_widgets);
393 ret = snd_soc_dapm_new_controls(dapm,
394 ad193x_adc_widgets,
395 num);
396 if (ret)
397 return ret;
398
399 /* add adc routes */
400 num = ARRAY_SIZE(ad193x_adc_audio_paths);
401 ret = snd_soc_dapm_add_routes(dapm,
402 ad193x_adc_audio_paths,
403 num);
404 if (ret)
405 return ret;
406 }
407
346 return 0; 408 return 0;
347} 409}
348 410
@@ -356,18 +418,13 @@ static struct snd_soc_codec_driver soc_codec_dev_ad193x = {
356 .num_dapm_routes = ARRAY_SIZE(audio_paths), 418 .num_dapm_routes = ARRAY_SIZE(audio_paths),
357}; 419};
358 420
359static bool adau193x_reg_volatile(struct device *dev, unsigned int reg)
360{
361 return false;
362}
363
364const struct regmap_config ad193x_regmap_config = { 421const struct regmap_config ad193x_regmap_config = {
365 .max_register = AD193X_NUM_REGS - 1, 422 .max_register = AD193X_NUM_REGS - 1,
366 .volatile_reg = adau193x_reg_volatile,
367}; 423};
368EXPORT_SYMBOL_GPL(ad193x_regmap_config); 424EXPORT_SYMBOL_GPL(ad193x_regmap_config);
369 425
370int ad193x_probe(struct device *dev, struct regmap *regmap) 426int ad193x_probe(struct device *dev, struct regmap *regmap,
427 enum ad193x_type type)
371{ 428{
372 struct ad193x_priv *ad193x; 429 struct ad193x_priv *ad193x;
373 430
@@ -379,6 +436,7 @@ int ad193x_probe(struct device *dev, struct regmap *regmap)
379 return -ENOMEM; 436 return -ENOMEM;
380 437
381 ad193x->regmap = regmap; 438 ad193x->regmap = regmap;
439 ad193x->type = type;
382 440
383 dev_set_drvdata(dev, ad193x); 441 dev_set_drvdata(dev, ad193x);
384 442
diff --git a/sound/soc/codecs/ad193x.h b/sound/soc/codecs/ad193x.h
index ab9a998f15be..8b1e65f928d2 100644
--- a/sound/soc/codecs/ad193x.h
+++ b/sound/soc/codecs/ad193x.h
@@ -13,8 +13,15 @@
13 13
14struct device; 14struct device;
15 15
16enum ad193x_type {
17 AD193X,
18 AD1933,
19 AD1934,
20};
21
16extern const struct regmap_config ad193x_regmap_config; 22extern const struct regmap_config ad193x_regmap_config;
17int ad193x_probe(struct device *dev, struct regmap *regmap); 23int ad193x_probe(struct device *dev, struct regmap *regmap,
24 enum ad193x_type type);
18 25
19#define AD193X_PLL_CLK_CTRL0 0x00 26#define AD193X_PLL_CLK_CTRL0 0x00
20#define AD193X_PLL_POWERDOWN 0x01 27#define AD193X_PLL_POWERDOWN 0x01
diff --git a/sound/soc/codecs/adav80x.c b/sound/soc/codecs/adav80x.c
index 198c924551b7..acff8d62059c 100644
--- a/sound/soc/codecs/adav80x.c
+++ b/sound/soc/codecs/adav80x.c
@@ -728,8 +728,8 @@ static int adav80x_dai_startup(struct snd_pcm_substream *substream,
728 if (!snd_soc_codec_is_active(codec) || !adav80x->rate) 728 if (!snd_soc_codec_is_active(codec) || !adav80x->rate)
729 return 0; 729 return 0;
730 730
731 return snd_pcm_hw_constraint_minmax(substream->runtime, 731 return snd_pcm_hw_constraint_single(substream->runtime,
732 SNDRV_PCM_HW_PARAM_RATE, adav80x->rate, adav80x->rate); 732 SNDRV_PCM_HW_PARAM_RATE, adav80x->rate);
733} 733}
734 734
735static void adav80x_dai_shutdown(struct snd_pcm_substream *substream, 735static void adav80x_dai_shutdown(struct snd_pcm_substream *substream,
diff --git a/sound/soc/codecs/ak4613.c b/sound/soc/codecs/ak4613.c
new file mode 100644
index 000000000000..07a266460ec3
--- /dev/null
+++ b/sound/soc/codecs/ak4613.c
@@ -0,0 +1,497 @@
1/*
2 * ak4613.c -- Asahi Kasei ALSA Soc Audio driver
3 *
4 * Copyright (C) 2015 Renesas Electronics Corporation
5 * Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
6 *
7 * Based on ak4642.c by Kuninori Morimoto
8 * Based on wm8731.c by Richard Purdie
9 * Based on ak4535.c by Richard Purdie
10 * Based on wm8753.c by Liam Girdwood
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License version 2 as
14 * published by the Free Software Foundation.
15 */
16
17#include <linux/clk.h>
18#include <linux/i2c.h>
19#include <linux/slab.h>
20#include <linux/of_device.h>
21#include <linux/module.h>
22#include <linux/regmap.h>
23#include <sound/soc.h>
24#include <sound/pcm_params.h>
25#include <sound/tlv.h>
26
27#define PW_MGMT1 0x00 /* Power Management 1 */
28#define PW_MGMT2 0x01 /* Power Management 2 */
29#define PW_MGMT3 0x02 /* Power Management 3 */
30#define CTRL1 0x03 /* Control 1 */
31#define CTRL2 0x04 /* Control 2 */
32#define DEMP1 0x05 /* De-emphasis1 */
33#define DEMP2 0x06 /* De-emphasis2 */
34#define OFD 0x07 /* Overflow Detect */
35#define ZRD 0x08 /* Zero Detect */
36#define ICTRL 0x09 /* Input Control */
37#define OCTRL 0x0a /* Output Control */
38#define LOUT1 0x0b /* LOUT1 Volume Control */
39#define ROUT1 0x0c /* ROUT1 Volume Control */
40#define LOUT2 0x0d /* LOUT2 Volume Control */
41#define ROUT2 0x0e /* ROUT2 Volume Control */
42#define LOUT3 0x0f /* LOUT3 Volume Control */
43#define ROUT3 0x10 /* ROUT3 Volume Control */
44#define LOUT4 0x11 /* LOUT4 Volume Control */
45#define ROUT4 0x12 /* ROUT4 Volume Control */
46#define LOUT5 0x13 /* LOUT5 Volume Control */
47#define ROUT5 0x14 /* ROUT5 Volume Control */
48#define LOUT6 0x15 /* LOUT6 Volume Control */
49#define ROUT6 0x16 /* ROUT6 Volume Control */
50
51/* PW_MGMT1 */
52#define RSTN BIT(0)
53#define PMDAC BIT(1)
54#define PMADC BIT(2)
55#define PMVR BIT(3)
56
57/* PW_MGMT2 */
58#define PMAD_ALL 0x7
59
60/* PW_MGMT3 */
61#define PMDA_ALL 0x3f
62
63/* CTRL1 */
64#define DIF0 BIT(3)
65#define DIF1 BIT(4)
66#define DIF2 BIT(5)
67#define TDM0 BIT(6)
68#define TDM1 BIT(7)
69#define NO_FMT (0xff)
70#define FMT_MASK (0xf8)
71
72/* CTRL2 */
73#define DFS_NORMAL_SPEED (0 << 2)
74#define DFS_DOUBLE_SPEED (1 << 2)
75#define DFS_QUAD_SPEED (2 << 2)
76
77struct ak4613_priv {
78 struct mutex lock;
79
80 unsigned int fmt;
81 u8 fmt_ctrl;
82 int cnt;
83};
84
85struct ak4613_formats {
86 unsigned int width;
87 unsigned int fmt;
88};
89
90struct ak4613_interface {
91 struct ak4613_formats capture;
92 struct ak4613_formats playback;
93};
94
95/*
96 * Playback Volume
97 *
98 * max : 0x00 : 0 dB
99 * ( 0.5 dB step )
100 * min : 0xFE : -127.0 dB
101 * mute: 0xFF
102 */
103static const DECLARE_TLV_DB_SCALE(out_tlv, -12750, 50, 1);
104
105static const struct snd_kcontrol_new ak4613_snd_controls[] = {
106 SOC_DOUBLE_R_TLV("Digital Playback Volume1", LOUT1, ROUT1,
107 0, 0xFF, 1, out_tlv),
108 SOC_DOUBLE_R_TLV("Digital Playback Volume2", LOUT2, ROUT2,
109 0, 0xFF, 1, out_tlv),
110 SOC_DOUBLE_R_TLV("Digital Playback Volume3", LOUT3, ROUT3,
111 0, 0xFF, 1, out_tlv),
112 SOC_DOUBLE_R_TLV("Digital Playback Volume4", LOUT4, ROUT4,
113 0, 0xFF, 1, out_tlv),
114 SOC_DOUBLE_R_TLV("Digital Playback Volume5", LOUT5, ROUT5,
115 0, 0xFF, 1, out_tlv),
116 SOC_DOUBLE_R_TLV("Digital Playback Volume6", LOUT6, ROUT6,
117 0, 0xFF, 1, out_tlv),
118};
119
120static const struct reg_default ak4613_reg[] = {
121 { 0x0, 0x0f }, { 0x1, 0x07 }, { 0x2, 0x3f }, { 0x3, 0x20 },
122 { 0x4, 0x20 }, { 0x5, 0x55 }, { 0x6, 0x05 }, { 0x7, 0x07 },
123 { 0x8, 0x0f }, { 0x9, 0x07 }, { 0xa, 0x3f }, { 0xb, 0x00 },
124 { 0xc, 0x00 }, { 0xd, 0x00 }, { 0xe, 0x00 }, { 0xf, 0x00 },
125 { 0x10, 0x00 }, { 0x11, 0x00 }, { 0x12, 0x00 }, { 0x13, 0x00 },
126 { 0x14, 0x00 }, { 0x15, 0x00 }, { 0x16, 0x00 },
127};
128
129#define AUDIO_IFACE_IDX_TO_VAL(i) (i << 3)
130#define AUDIO_IFACE(b, fmt) { b, SND_SOC_DAIFMT_##fmt }
131static const struct ak4613_interface ak4613_iface[] = {
132 /* capture */ /* playback */
133 [0] = { AUDIO_IFACE(24, LEFT_J), AUDIO_IFACE(16, RIGHT_J) },
134 [1] = { AUDIO_IFACE(24, LEFT_J), AUDIO_IFACE(20, RIGHT_J) },
135 [2] = { AUDIO_IFACE(24, LEFT_J), AUDIO_IFACE(24, RIGHT_J) },
136 [3] = { AUDIO_IFACE(24, LEFT_J), AUDIO_IFACE(24, LEFT_J) },
137 [4] = { AUDIO_IFACE(24, I2S), AUDIO_IFACE(24, I2S) },
138};
139
140static const struct regmap_config ak4613_regmap_cfg = {
141 .reg_bits = 8,
142 .val_bits = 8,
143 .max_register = 0x16,
144 .reg_defaults = ak4613_reg,
145 .num_reg_defaults = ARRAY_SIZE(ak4613_reg),
146};
147
148static const struct of_device_id ak4613_of_match[] = {
149 { .compatible = "asahi-kasei,ak4613", .data = &ak4613_regmap_cfg },
150 {},
151};
152MODULE_DEVICE_TABLE(of, ak4613_of_match);
153
154static const struct i2c_device_id ak4613_i2c_id[] = {
155 { "ak4613", (kernel_ulong_t)&ak4613_regmap_cfg },
156 { }
157};
158MODULE_DEVICE_TABLE(i2c, ak4613_i2c_id);
159
160static const struct snd_soc_dapm_widget ak4613_dapm_widgets[] = {
161
162 /* Outputs */
163 SND_SOC_DAPM_OUTPUT("LOUT1"),
164 SND_SOC_DAPM_OUTPUT("LOUT2"),
165 SND_SOC_DAPM_OUTPUT("LOUT3"),
166 SND_SOC_DAPM_OUTPUT("LOUT4"),
167 SND_SOC_DAPM_OUTPUT("LOUT5"),
168 SND_SOC_DAPM_OUTPUT("LOUT6"),
169
170 SND_SOC_DAPM_OUTPUT("ROUT1"),
171 SND_SOC_DAPM_OUTPUT("ROUT2"),
172 SND_SOC_DAPM_OUTPUT("ROUT3"),
173 SND_SOC_DAPM_OUTPUT("ROUT4"),
174 SND_SOC_DAPM_OUTPUT("ROUT5"),
175 SND_SOC_DAPM_OUTPUT("ROUT6"),
176
177 /* Inputs */
178 SND_SOC_DAPM_INPUT("LIN1"),
179 SND_SOC_DAPM_INPUT("LIN2"),
180
181 SND_SOC_DAPM_INPUT("RIN1"),
182 SND_SOC_DAPM_INPUT("RIN2"),
183
184 /* DAC */
185 SND_SOC_DAPM_DAC("DAC1", NULL, PW_MGMT3, 0, 0),
186 SND_SOC_DAPM_DAC("DAC2", NULL, PW_MGMT3, 1, 0),
187 SND_SOC_DAPM_DAC("DAC3", NULL, PW_MGMT3, 2, 0),
188 SND_SOC_DAPM_DAC("DAC4", NULL, PW_MGMT3, 3, 0),
189 SND_SOC_DAPM_DAC("DAC5", NULL, PW_MGMT3, 4, 0),
190 SND_SOC_DAPM_DAC("DAC6", NULL, PW_MGMT3, 5, 0),
191
192 /* ADC */
193 SND_SOC_DAPM_ADC("ADC1", NULL, PW_MGMT2, 0, 0),
194 SND_SOC_DAPM_ADC("ADC2", NULL, PW_MGMT2, 1, 0),
195};
196
197static const struct snd_soc_dapm_route ak4613_intercon[] = {
198 {"LOUT1", NULL, "DAC1"},
199 {"LOUT2", NULL, "DAC2"},
200 {"LOUT3", NULL, "DAC3"},
201 {"LOUT4", NULL, "DAC4"},
202 {"LOUT5", NULL, "DAC5"},
203 {"LOUT6", NULL, "DAC6"},
204
205 {"ROUT1", NULL, "DAC1"},
206 {"ROUT2", NULL, "DAC2"},
207 {"ROUT3", NULL, "DAC3"},
208 {"ROUT4", NULL, "DAC4"},
209 {"ROUT5", NULL, "DAC5"},
210 {"ROUT6", NULL, "DAC6"},
211
212 {"DAC1", NULL, "Playback"},
213 {"DAC2", NULL, "Playback"},
214 {"DAC3", NULL, "Playback"},
215 {"DAC4", NULL, "Playback"},
216 {"DAC5", NULL, "Playback"},
217 {"DAC6", NULL, "Playback"},
218
219 {"Capture", NULL, "ADC1"},
220 {"Capture", NULL, "ADC2"},
221
222 {"ADC1", NULL, "LIN1"},
223 {"ADC2", NULL, "LIN2"},
224
225 {"ADC1", NULL, "RIN1"},
226 {"ADC2", NULL, "RIN2"},
227};
228
229static void ak4613_dai_shutdown(struct snd_pcm_substream *substream,
230 struct snd_soc_dai *dai)
231{
232 struct snd_soc_codec *codec = dai->codec;
233 struct ak4613_priv *priv = snd_soc_codec_get_drvdata(codec);
234 struct device *dev = codec->dev;
235
236 mutex_lock(&priv->lock);
237 priv->cnt--;
238 if (priv->cnt < 0) {
239 dev_err(dev, "unexpected counter error\n");
240 priv->cnt = 0;
241 }
242 if (!priv->cnt)
243 priv->fmt_ctrl = NO_FMT;
244 mutex_unlock(&priv->lock);
245}
246
247static int ak4613_dai_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
248{
249 struct snd_soc_codec *codec = dai->codec;
250 struct ak4613_priv *priv = snd_soc_codec_get_drvdata(codec);
251
252 fmt &= SND_SOC_DAIFMT_FORMAT_MASK;
253
254 switch (fmt) {
255 case SND_SOC_DAIFMT_RIGHT_J:
256 case SND_SOC_DAIFMT_LEFT_J:
257 case SND_SOC_DAIFMT_I2S:
258 priv->fmt = fmt;
259
260 break;
261 default:
262 return -EINVAL;
263 }
264
265 return 0;
266}
267
268static int ak4613_dai_hw_params(struct snd_pcm_substream *substream,
269 struct snd_pcm_hw_params *params,
270 struct snd_soc_dai *dai)
271{
272 struct snd_soc_codec *codec = dai->codec;
273 struct ak4613_priv *priv = snd_soc_codec_get_drvdata(codec);
274 const struct ak4613_formats *fmts;
275 struct device *dev = codec->dev;
276 unsigned int width = params_width(params);
277 unsigned int fmt = priv->fmt;
278 unsigned int rate;
279 int is_play = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
280 int i, ret;
281 u8 fmt_ctrl, ctrl2;
282
283 rate = params_rate(params);
284 switch (rate) {
285 case 32000:
286 case 44100:
287 case 48000:
288 ctrl2 = DFS_NORMAL_SPEED;
289 break;
290 case 88200:
291 case 96000:
292 ctrl2 = DFS_DOUBLE_SPEED;
293 break;
294 case 176400:
295 case 192000:
296 ctrl2 = DFS_QUAD_SPEED;
297 break;
298 default:
299 return -EINVAL;
300 }
301
302 /*
303 * FIXME
304 *
305 * It doesn't support TDM at this point
306 */
307 fmt_ctrl = NO_FMT;
308 for (i = 0; i < ARRAY_SIZE(ak4613_iface); i++) {
309 fmts = (is_play) ? &ak4613_iface[i].playback :
310 &ak4613_iface[i].capture;
311
312 if (fmts->fmt != fmt)
313 continue;
314
315 if (fmt == SND_SOC_DAIFMT_RIGHT_J) {
316 if (fmts->width != width)
317 continue;
318 } else {
319 if (fmts->width < width)
320 continue;
321 }
322
323 fmt_ctrl = AUDIO_IFACE_IDX_TO_VAL(i);
324 break;
325 }
326
327 ret = -EINVAL;
328 if (fmt_ctrl == NO_FMT)
329 goto hw_params_end;
330
331 mutex_lock(&priv->lock);
332 if ((priv->fmt_ctrl == NO_FMT) ||
333 (priv->fmt_ctrl == fmt_ctrl)) {
334 priv->fmt_ctrl = fmt_ctrl;
335 priv->cnt++;
336 ret = 0;
337 }
338 mutex_unlock(&priv->lock);
339
340 if (ret < 0)
341 goto hw_params_end;
342
343 snd_soc_update_bits(codec, CTRL1, FMT_MASK, fmt_ctrl);
344 snd_soc_write(codec, CTRL2, ctrl2);
345
346hw_params_end:
347 if (ret < 0)
348 dev_warn(dev, "unsupported data width/format combination\n");
349
350 return ret;
351}
352
353static int ak4613_set_bias_level(struct snd_soc_codec *codec,
354 enum snd_soc_bias_level level)
355{
356 u8 mgmt1 = 0;
357
358 switch (level) {
359 case SND_SOC_BIAS_ON:
360 mgmt1 |= RSTN;
361 /* fall through */
362 case SND_SOC_BIAS_PREPARE:
363 mgmt1 |= PMADC | PMDAC;
364 /* fall through */
365 case SND_SOC_BIAS_STANDBY:
366 mgmt1 |= PMVR;
367 /* fall through */
368 case SND_SOC_BIAS_OFF:
369 default:
370 break;
371 }
372
373 snd_soc_write(codec, PW_MGMT1, mgmt1);
374
375 return 0;
376}
377
378static const struct snd_soc_dai_ops ak4613_dai_ops = {
379 .shutdown = ak4613_dai_shutdown,
380 .set_fmt = ak4613_dai_set_fmt,
381 .hw_params = ak4613_dai_hw_params,
382};
383
384#define AK4613_PCM_RATE (SNDRV_PCM_RATE_32000 |\
385 SNDRV_PCM_RATE_44100 |\
386 SNDRV_PCM_RATE_48000 |\
387 SNDRV_PCM_RATE_64000 |\
388 SNDRV_PCM_RATE_88200 |\
389 SNDRV_PCM_RATE_96000 |\
390 SNDRV_PCM_RATE_176400 |\
391 SNDRV_PCM_RATE_192000)
392#define AK4613_PCM_FMTBIT (SNDRV_PCM_FMTBIT_S16_LE |\
393 SNDRV_PCM_FMTBIT_S24_LE)
394
395static struct snd_soc_dai_driver ak4613_dai = {
396 .name = "ak4613-hifi",
397 .playback = {
398 .stream_name = "Playback",
399 .channels_min = 2,
400 .channels_max = 2,
401 .rates = AK4613_PCM_RATE,
402 .formats = AK4613_PCM_FMTBIT,
403 },
404 .capture = {
405 .stream_name = "Capture",
406 .channels_min = 2,
407 .channels_max = 2,
408 .rates = AK4613_PCM_RATE,
409 .formats = AK4613_PCM_FMTBIT,
410 },
411 .ops = &ak4613_dai_ops,
412 .symmetric_rates = 1,
413};
414
415static int ak4613_resume(struct snd_soc_codec *codec)
416{
417 struct regmap *regmap = dev_get_regmap(codec->dev, NULL);
418
419 regcache_mark_dirty(regmap);
420 return regcache_sync(regmap);
421}
422
423static struct snd_soc_codec_driver soc_codec_dev_ak4613 = {
424 .resume = ak4613_resume,
425 .set_bias_level = ak4613_set_bias_level,
426 .controls = ak4613_snd_controls,
427 .num_controls = ARRAY_SIZE(ak4613_snd_controls),
428 .dapm_widgets = ak4613_dapm_widgets,
429 .num_dapm_widgets = ARRAY_SIZE(ak4613_dapm_widgets),
430 .dapm_routes = ak4613_intercon,
431 .num_dapm_routes = ARRAY_SIZE(ak4613_intercon),
432};
433
434static int ak4613_i2c_probe(struct i2c_client *i2c,
435 const struct i2c_device_id *id)
436{
437 struct device *dev = &i2c->dev;
438 struct device_node *np = dev->of_node;
439 const struct regmap_config *regmap_cfg;
440 struct regmap *regmap;
441 struct ak4613_priv *priv;
442
443 regmap_cfg = NULL;
444 if (np) {
445 const struct of_device_id *of_id;
446
447 of_id = of_match_device(ak4613_of_match, dev);
448 if (of_id)
449 regmap_cfg = of_id->data;
450 } else {
451 regmap_cfg = (const struct regmap_config *)id->driver_data;
452 }
453
454 if (!regmap_cfg)
455 return -EINVAL;
456
457 priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
458 if (!priv)
459 return -ENOMEM;
460
461 priv->fmt_ctrl = NO_FMT;
462 priv->cnt = 0;
463
464 mutex_init(&priv->lock);
465
466 i2c_set_clientdata(i2c, priv);
467
468 regmap = devm_regmap_init_i2c(i2c, regmap_cfg);
469 if (IS_ERR(regmap))
470 return PTR_ERR(regmap);
471
472 return snd_soc_register_codec(dev, &soc_codec_dev_ak4613,
473 &ak4613_dai, 1);
474}
475
476static int ak4613_i2c_remove(struct i2c_client *client)
477{
478 snd_soc_unregister_codec(&client->dev);
479 return 0;
480}
481
482static struct i2c_driver ak4613_i2c_driver = {
483 .driver = {
484 .name = "ak4613-codec",
485 .owner = THIS_MODULE,
486 .of_match_table = ak4613_of_match,
487 },
488 .probe = ak4613_i2c_probe,
489 .remove = ak4613_i2c_remove,
490 .id_table = ak4613_i2c_id,
491};
492
493module_i2c_driver(ak4613_i2c_driver);
494
495MODULE_DESCRIPTION("Soc AK4613 driver");
496MODULE_AUTHOR("Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>");
497MODULE_LICENSE("GPL v2");
diff --git a/sound/soc/codecs/ak4642.c b/sound/soc/codecs/ak4642.c
index 4a90143d0e90..cda27c22812a 100644
--- a/sound/soc/codecs/ak4642.c
+++ b/sound/soc/codecs/ak4642.c
@@ -23,6 +23,8 @@
23 * AK4648 is tested. 23 * AK4648 is tested.
24 */ 24 */
25 25
26#include <linux/clk.h>
27#include <linux/clk-provider.h>
26#include <linux/delay.h> 28#include <linux/delay.h>
27#include <linux/i2c.h> 29#include <linux/i2c.h>
28#include <linux/slab.h> 30#include <linux/slab.h>
@@ -128,11 +130,8 @@
128#define I2S (3 << 0) 130#define I2S (3 << 0)
129 131
130/* MD_CTL2 */ 132/* MD_CTL2 */
131#define FS0 (1 << 0) 133#define FSs(val) (((val & 0x7) << 0) | ((val & 0x8) << 2))
132#define FS1 (1 << 1) 134#define PSs(val) ((val & 0x3) << 6)
133#define FS2 (1 << 2)
134#define FS3 (1 << 5)
135#define FS_MASK (FS0 | FS1 | FS2 | FS3)
136 135
137/* MD_CTL3 */ 136/* MD_CTL3 */
138#define BST1 (1 << 3) 137#define BST1 (1 << 3)
@@ -147,6 +146,7 @@ struct ak4642_drvdata {
147 146
148struct ak4642_priv { 147struct ak4642_priv {
149 const struct ak4642_drvdata *drvdata; 148 const struct ak4642_drvdata *drvdata;
149 struct clk *mcko;
150}; 150};
151 151
152/* 152/*
@@ -430,56 +430,56 @@ static int ak4642_dai_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
430 return 0; 430 return 0;
431} 431}
432 432
433static int ak4642_set_mcko(struct snd_soc_codec *codec,
434 u32 frequency)
435{
436 u32 fs_list[] = {
437 [0] = 8000,
438 [1] = 12000,
439 [2] = 16000,
440 [3] = 24000,
441 [4] = 7350,
442 [5] = 11025,
443 [6] = 14700,
444 [7] = 22050,
445 [10] = 32000,
446 [11] = 48000,
447 [14] = 29400,
448 [15] = 44100,
449 };
450 u32 ps_list[] = {
451 [0] = 256,
452 [1] = 128,
453 [2] = 64,
454 [3] = 32
455 };
456 int ps, fs;
457
458 for (ps = 0; ps < ARRAY_SIZE(ps_list); ps++) {
459 for (fs = 0; fs < ARRAY_SIZE(fs_list); fs++) {
460 if (frequency == ps_list[ps] * fs_list[fs]) {
461 snd_soc_write(codec, MD_CTL2,
462 PSs(ps) | FSs(fs));
463 return 0;
464 }
465 }
466 }
467
468 return 0;
469}
470
433static int ak4642_dai_hw_params(struct snd_pcm_substream *substream, 471static int ak4642_dai_hw_params(struct snd_pcm_substream *substream,
434 struct snd_pcm_hw_params *params, 472 struct snd_pcm_hw_params *params,
435 struct snd_soc_dai *dai) 473 struct snd_soc_dai *dai)
436{ 474{
437 struct snd_soc_codec *codec = dai->codec; 475 struct snd_soc_codec *codec = dai->codec;
438 u8 rate; 476 struct ak4642_priv *priv = snd_soc_codec_get_drvdata(codec);
477 u32 rate = clk_get_rate(priv->mcko);
439 478
440 switch (params_rate(params)) { 479 if (!rate)
441 case 7350: 480 rate = params_rate(params) * 256;
442 rate = FS2;
443 break;
444 case 8000:
445 rate = 0;
446 break;
447 case 11025:
448 rate = FS2 | FS0;
449 break;
450 case 12000:
451 rate = FS0;
452 break;
453 case 14700:
454 rate = FS2 | FS1;
455 break;
456 case 16000:
457 rate = FS1;
458 break;
459 case 22050:
460 rate = FS2 | FS1 | FS0;
461 break;
462 case 24000:
463 rate = FS1 | FS0;
464 break;
465 case 29400:
466 rate = FS3 | FS2 | FS1;
467 break;
468 case 32000:
469 rate = FS3 | FS1;
470 break;
471 case 44100:
472 rate = FS3 | FS2 | FS1 | FS0;
473 break;
474 case 48000:
475 rate = FS3 | FS1 | FS0;
476 break;
477 default:
478 return -EINVAL;
479 }
480 snd_soc_update_bits(codec, MD_CTL2, FS_MASK, rate);
481 481
482 return 0; 482 return ak4642_set_mcko(codec, rate);
483} 483}
484 484
485static int ak4642_set_bias_level(struct snd_soc_codec *codec, 485static int ak4642_set_bias_level(struct snd_soc_codec *codec,
@@ -532,7 +532,18 @@ static int ak4642_resume(struct snd_soc_codec *codec)
532 return 0; 532 return 0;
533} 533}
534 534
535static int ak4642_probe(struct snd_soc_codec *codec)
536{
537 struct ak4642_priv *priv = snd_soc_codec_get_drvdata(codec);
538
539 if (priv->mcko)
540 ak4642_set_mcko(codec, clk_get_rate(priv->mcko));
541
542 return 0;
543}
544
535static struct snd_soc_codec_driver soc_codec_dev_ak4642 = { 545static struct snd_soc_codec_driver soc_codec_dev_ak4642 = {
546 .probe = ak4642_probe,
536 .resume = ak4642_resume, 547 .resume = ak4642_resume,
537 .set_bias_level = ak4642_set_bias_level, 548 .set_bias_level = ak4642_set_bias_level,
538 .controls = ak4642_snd_controls, 549 .controls = ak4642_snd_controls,
@@ -580,19 +591,54 @@ static const struct ak4642_drvdata ak4648_drvdata = {
580 .extended_frequencies = 1, 591 .extended_frequencies = 1,
581}; 592};
582 593
594#ifdef CONFIG_COMMON_CLK
595static struct clk *ak4642_of_parse_mcko(struct device *dev)
596{
597 struct device_node *np = dev->of_node;
598 struct clk *clk;
599 const char *clk_name = np->name;
600 const char *parent_clk_name = NULL;
601 u32 rate;
602
603 if (of_property_read_u32(np, "clock-frequency", &rate))
604 return NULL;
605
606 if (of_property_read_bool(np, "clocks"))
607 parent_clk_name = of_clk_get_parent_name(np, 0);
608
609 of_property_read_string(np, "clock-output-names", &clk_name);
610
611 clk = clk_register_fixed_rate(dev, clk_name, parent_clk_name,
612 (parent_clk_name) ? 0 : CLK_IS_ROOT,
613 rate);
614 if (!IS_ERR(clk))
615 of_clk_add_provider(np, of_clk_src_simple_get, clk);
616
617 return clk;
618}
619#else
620#define ak4642_of_parse_mcko(d) 0
621#endif
622
583static const struct of_device_id ak4642_of_match[]; 623static const struct of_device_id ak4642_of_match[];
584static int ak4642_i2c_probe(struct i2c_client *i2c, 624static int ak4642_i2c_probe(struct i2c_client *i2c,
585 const struct i2c_device_id *id) 625 const struct i2c_device_id *id)
586{ 626{
587 struct device_node *np = i2c->dev.of_node; 627 struct device *dev = &i2c->dev;
628 struct device_node *np = dev->of_node;
588 const struct ak4642_drvdata *drvdata = NULL; 629 const struct ak4642_drvdata *drvdata = NULL;
589 struct regmap *regmap; 630 struct regmap *regmap;
590 struct ak4642_priv *priv; 631 struct ak4642_priv *priv;
632 struct clk *mcko = NULL;
591 633
592 if (np) { 634 if (np) {
593 const struct of_device_id *of_id; 635 const struct of_device_id *of_id;
594 636
595 of_id = of_match_device(ak4642_of_match, &i2c->dev); 637 mcko = ak4642_of_parse_mcko(dev);
638 if (IS_ERR(mcko))
639 mcko = NULL;
640
641 of_id = of_match_device(ak4642_of_match, dev);
596 if (of_id) 642 if (of_id)
597 drvdata = of_id->data; 643 drvdata = of_id->data;
598 } else { 644 } else {
@@ -600,15 +646,16 @@ static int ak4642_i2c_probe(struct i2c_client *i2c,
600 } 646 }
601 647
602 if (!drvdata) { 648 if (!drvdata) {
603 dev_err(&i2c->dev, "Unknown device type\n"); 649 dev_err(dev, "Unknown device type\n");
604 return -EINVAL; 650 return -EINVAL;
605 } 651 }
606 652
607 priv = devm_kzalloc(&i2c->dev, sizeof(*priv), GFP_KERNEL); 653 priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
608 if (!priv) 654 if (!priv)
609 return -ENOMEM; 655 return -ENOMEM;
610 656
611 priv->drvdata = drvdata; 657 priv->drvdata = drvdata;
658 priv->mcko = mcko;
612 659
613 i2c_set_clientdata(i2c, priv); 660 i2c_set_clientdata(i2c, priv);
614 661
@@ -616,7 +663,7 @@ static int ak4642_i2c_probe(struct i2c_client *i2c,
616 if (IS_ERR(regmap)) 663 if (IS_ERR(regmap))
617 return PTR_ERR(regmap); 664 return PTR_ERR(regmap);
618 665
619 return snd_soc_register_codec(&i2c->dev, 666 return snd_soc_register_codec(dev,
620 &soc_codec_dev_ak4642, &ak4642_dai, 1); 667 &soc_codec_dev_ak4642, &ak4642_dai, 1);
621} 668}
622 669
diff --git a/sound/soc/codecs/arizona.c b/sound/soc/codecs/arizona.c
index 8a2221ab3d10..9929efc6b9aa 100644
--- a/sound/soc/codecs/arizona.c
+++ b/sound/soc/codecs/arizona.c
@@ -147,6 +147,8 @@ static int arizona_spk_ev(struct snd_soc_dapm_widget *w,
147 0x4f5, 0x0da); 147 0x4f5, 0x0da);
148 } 148 }
149 break; 149 break;
150 default:
151 break;
150 } 152 }
151 153
152 return 0; 154 return 0;
@@ -314,6 +316,7 @@ const char *arizona_mixer_texts[ARIZONA_NUM_MIXER_INPUTS] = {
314 "Tone Generator 2", 316 "Tone Generator 2",
315 "Haptics", 317 "Haptics",
316 "AEC", 318 "AEC",
319 "AEC2",
317 "Mic Mute Mixer", 320 "Mic Mute Mixer",
318 "Noise Generator", 321 "Noise Generator",
319 "IN1L", 322 "IN1L",
@@ -421,6 +424,7 @@ int arizona_mixer_values[ARIZONA_NUM_MIXER_INPUTS] = {
421 0x05, 424 0x05,
422 0x06, /* Haptics */ 425 0x06, /* Haptics */
423 0x08, /* AEC */ 426 0x08, /* AEC */
427 0x09, /* AEC2 */
424 0x0c, /* Noise mixer */ 428 0x0c, /* Noise mixer */
425 0x0d, /* Comfort noise */ 429 0x0d, /* Comfort noise */
426 0x10, /* IN1L */ 430 0x10, /* IN1L */
@@ -525,6 +529,32 @@ EXPORT_SYMBOL_GPL(arizona_mixer_values);
525const DECLARE_TLV_DB_SCALE(arizona_mixer_tlv, -3200, 100, 0); 529const DECLARE_TLV_DB_SCALE(arizona_mixer_tlv, -3200, 100, 0);
526EXPORT_SYMBOL_GPL(arizona_mixer_tlv); 530EXPORT_SYMBOL_GPL(arizona_mixer_tlv);
527 531
532const char * const arizona_sample_rate_text[ARIZONA_SAMPLE_RATE_ENUM_SIZE] = {
533 "12kHz", "24kHz", "48kHz", "96kHz", "192kHz",
534 "11.025kHz", "22.05kHz", "44.1kHz", "88.2kHz", "176.4kHz",
535 "4kHz", "8kHz", "16kHz", "32kHz",
536};
537EXPORT_SYMBOL_GPL(arizona_sample_rate_text);
538
539const unsigned int arizona_sample_rate_val[ARIZONA_SAMPLE_RATE_ENUM_SIZE] = {
540 0x01, 0x02, 0x03, 0x04, 0x05, 0x09, 0x0A, 0x0B, 0x0C, 0x0D,
541 0x10, 0x11, 0x12, 0x13,
542};
543EXPORT_SYMBOL_GPL(arizona_sample_rate_val);
544
545const char *arizona_sample_rate_val_to_name(unsigned int rate_val)
546{
547 int i;
548
549 for (i = 0; i < ARRAY_SIZE(arizona_sample_rate_val); ++i) {
550 if (arizona_sample_rate_val[i] == rate_val)
551 return arizona_sample_rate_text[i];
552 }
553
554 return "Illegal";
555}
556EXPORT_SYMBOL_GPL(arizona_sample_rate_val_to_name);
557
528const char *arizona_rate_text[ARIZONA_RATE_ENUM_SIZE] = { 558const char *arizona_rate_text[ARIZONA_RATE_ENUM_SIZE] = {
529 "SYNCCLK rate", "8kHz", "16kHz", "ASYNCCLK rate", 559 "SYNCCLK rate", "8kHz", "16kHz", "ASYNCCLK rate",
530}; 560};
@@ -689,6 +719,15 @@ static void arizona_in_set_vu(struct snd_soc_codec *codec, int ena)
689 ARIZONA_IN_VU, val); 719 ARIZONA_IN_VU, val);
690} 720}
691 721
722bool arizona_input_analog(struct snd_soc_codec *codec, int shift)
723{
724 unsigned int reg = ARIZONA_IN1L_CONTROL + ((shift / 2) * 8);
725 unsigned int val = snd_soc_read(codec, reg);
726
727 return !(val & ARIZONA_IN1_MODE_MASK);
728}
729EXPORT_SYMBOL_GPL(arizona_input_analog);
730
692int arizona_in_ev(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, 731int arizona_in_ev(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol,
693 int event) 732 int event)
694{ 733{
@@ -725,6 +764,9 @@ int arizona_in_ev(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol,
725 reg = snd_soc_read(codec, ARIZONA_INPUT_ENABLES); 764 reg = snd_soc_read(codec, ARIZONA_INPUT_ENABLES);
726 if (reg == 0) 765 if (reg == 0)
727 arizona_in_set_vu(codec, 0); 766 arizona_in_set_vu(codec, 0);
767 break;
768 default:
769 break;
728 } 770 }
729 771
730 return 0; 772 return 0;
@@ -806,6 +848,8 @@ int arizona_out_ev(struct snd_soc_dapm_widget *w,
806 break; 848 break;
807 } 849 }
808 break; 850 break;
851 default:
852 break;
809 } 853 }
810 854
811 return 0; 855 return 0;
@@ -1868,6 +1912,11 @@ static int arizona_calc_fratio(struct arizona_fll *fll,
1868 if (fll->arizona->rev < 3 || sync) 1912 if (fll->arizona->rev < 3 || sync)
1869 return init_ratio; 1913 return init_ratio;
1870 break; 1914 break;
1915 case WM8998:
1916 case WM1814:
1917 if (sync)
1918 return init_ratio;
1919 break;
1871 default: 1920 default:
1872 return init_ratio; 1921 return init_ratio;
1873 } 1922 }
diff --git a/sound/soc/codecs/arizona.h b/sound/soc/codecs/arizona.h
index ada0a418ff4b..fea8b8ae8e1a 100644
--- a/sound/soc/codecs/arizona.h
+++ b/sound/soc/codecs/arizona.h
@@ -93,12 +93,17 @@ struct arizona_priv {
93 bool dvfs_cached; 93 bool dvfs_cached;
94}; 94};
95 95
96#define ARIZONA_NUM_MIXER_INPUTS 103 96#define ARIZONA_NUM_MIXER_INPUTS 104
97 97
98extern const unsigned int arizona_mixer_tlv[]; 98extern const unsigned int arizona_mixer_tlv[];
99extern const char *arizona_mixer_texts[ARIZONA_NUM_MIXER_INPUTS]; 99extern const char *arizona_mixer_texts[ARIZONA_NUM_MIXER_INPUTS];
100extern int arizona_mixer_values[ARIZONA_NUM_MIXER_INPUTS]; 100extern int arizona_mixer_values[ARIZONA_NUM_MIXER_INPUTS];
101 101
102#define ARIZONA_GAINMUX_CONTROLS(name, base) \
103 SOC_SINGLE_RANGE_TLV(name " Input Volume", base + 1, \
104 ARIZONA_MIXER_VOL_SHIFT, 0x20, 0x50, 0, \
105 arizona_mixer_tlv)
106
102#define ARIZONA_MIXER_CONTROLS(name, base) \ 107#define ARIZONA_MIXER_CONTROLS(name, base) \
103 SOC_SINGLE_RANGE_TLV(name " Input 1 Volume", base + 1, \ 108 SOC_SINGLE_RANGE_TLV(name " Input 1 Volume", base + 1, \
104 ARIZONA_MIXER_VOL_SHIFT, 0x20, 0x50, 0, \ 109 ARIZONA_MIXER_VOL_SHIFT, 0x20, 0x50, 0, \
@@ -209,8 +214,12 @@ extern int arizona_mixer_values[ARIZONA_NUM_MIXER_INPUTS];
209 .num_regs = 1 }) } 214 .num_regs = 1 }) }
210 215
211#define ARIZONA_RATE_ENUM_SIZE 4 216#define ARIZONA_RATE_ENUM_SIZE 4
217#define ARIZONA_SAMPLE_RATE_ENUM_SIZE 14
218
212extern const char *arizona_rate_text[ARIZONA_RATE_ENUM_SIZE]; 219extern const char *arizona_rate_text[ARIZONA_RATE_ENUM_SIZE];
213extern const int arizona_rate_val[ARIZONA_RATE_ENUM_SIZE]; 220extern const int arizona_rate_val[ARIZONA_RATE_ENUM_SIZE];
221extern const char * const arizona_sample_rate_text[ARIZONA_SAMPLE_RATE_ENUM_SIZE];
222extern const unsigned int arizona_sample_rate_val[ARIZONA_SAMPLE_RATE_ENUM_SIZE];
214 223
215extern const struct soc_enum arizona_isrc_fsl[]; 224extern const struct soc_enum arizona_isrc_fsl[];
216extern const struct soc_enum arizona_isrc_fsh[]; 225extern const struct soc_enum arizona_isrc_fsh[];
@@ -294,4 +303,7 @@ extern int arizona_init_dai(struct arizona_priv *priv, int dai);
294int arizona_set_output_mode(struct snd_soc_codec *codec, int output, 303int arizona_set_output_mode(struct snd_soc_codec *codec, int output,
295 bool diff); 304 bool diff);
296 305
306extern bool arizona_input_analog(struct snd_soc_codec *codec, int shift);
307
308extern const char *arizona_sample_rate_val_to_name(unsigned int rate_val);
297#endif 309#endif
diff --git a/sound/soc/codecs/da7213.c b/sound/soc/codecs/da7213.c
index a9c86efb3187..7278f93460c1 100644
--- a/sound/soc/codecs/da7213.c
+++ b/sound/soc/codecs/da7213.c
@@ -12,6 +12,7 @@
12 * option) any later version. 12 * option) any later version.
13 */ 13 */
14 14
15#include <linux/clk.h>
15#include <linux/delay.h> 16#include <linux/delay.h>
16#include <linux/i2c.h> 17#include <linux/i2c.h>
17#include <linux/regmap.h> 18#include <linux/regmap.h>
@@ -1222,23 +1223,44 @@ static int da7213_set_dai_sysclk(struct snd_soc_dai *codec_dai,
1222{ 1223{
1223 struct snd_soc_codec *codec = codec_dai->codec; 1224 struct snd_soc_codec *codec = codec_dai->codec;
1224 struct da7213_priv *da7213 = snd_soc_codec_get_drvdata(codec); 1225 struct da7213_priv *da7213 = snd_soc_codec_get_drvdata(codec);
1226 int ret = 0;
1227
1228 if ((da7213->clk_src == clk_id) && (da7213->mclk_rate == freq))
1229 return 0;
1230
1231 if (((freq < 5000000) && (freq != 32768)) || (freq > 54000000)) {
1232 dev_err(codec_dai->dev, "Unsupported MCLK value %d\n",
1233 freq);
1234 return -EINVAL;
1235 }
1225 1236
1226 switch (clk_id) { 1237 switch (clk_id) {
1227 case DA7213_CLKSRC_MCLK: 1238 case DA7213_CLKSRC_MCLK:
1228 if ((freq == 32768) || 1239 da7213->mclk_squarer_en = false;
1229 ((freq >= 5000000) && (freq <= 54000000))) { 1240 break;
1230 da7213->mclk_rate = freq; 1241 case DA7213_CLKSRC_MCLK_SQR:
1231 return 0; 1242 da7213->mclk_squarer_en = true;
1232 } else {
1233 dev_err(codec_dai->dev, "Unsupported MCLK value %d\n",
1234 freq);
1235 return -EINVAL;
1236 }
1237 break; 1243 break;
1238 default: 1244 default:
1239 dev_err(codec_dai->dev, "Unknown clock source %d\n", clk_id); 1245 dev_err(codec_dai->dev, "Unknown clock source %d\n", clk_id);
1240 return -EINVAL; 1246 return -EINVAL;
1241 } 1247 }
1248
1249 da7213->clk_src = clk_id;
1250
1251 if (da7213->mclk) {
1252 freq = clk_round_rate(da7213->mclk, freq);
1253 ret = clk_set_rate(da7213->mclk, freq);
1254 if (ret) {
1255 dev_err(codec_dai->dev, "Failed to set clock rate %d\n",
1256 freq);
1257 return ret;
1258 }
1259 }
1260
1261 da7213->mclk_rate = freq;
1262
1263 return 0;
1242} 1264}
1243 1265
1244/* Supported PLL input frequencies are 5MHz - 54MHz. */ 1266/* Supported PLL input frequencies are 5MHz - 54MHz. */
@@ -1366,12 +1388,25 @@ static struct snd_soc_dai_driver da7213_dai = {
1366static int da7213_set_bias_level(struct snd_soc_codec *codec, 1388static int da7213_set_bias_level(struct snd_soc_codec *codec,
1367 enum snd_soc_bias_level level) 1389 enum snd_soc_bias_level level)
1368{ 1390{
1391 struct da7213_priv *da7213 = snd_soc_codec_get_drvdata(codec);
1392 int ret;
1393
1369 switch (level) { 1394 switch (level) {
1370 case SND_SOC_BIAS_ON: 1395 case SND_SOC_BIAS_ON:
1371 case SND_SOC_BIAS_PREPARE: 1396 case SND_SOC_BIAS_PREPARE:
1372 break; 1397 break;
1373 case SND_SOC_BIAS_STANDBY: 1398 case SND_SOC_BIAS_STANDBY:
1374 if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF) { 1399 if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF) {
1400 /* MCLK */
1401 if (da7213->mclk) {
1402 ret = clk_prepare_enable(da7213->mclk);
1403 if (ret) {
1404 dev_err(codec->dev,
1405 "Failed to enable mclk\n");
1406 return ret;
1407 }
1408 }
1409
1375 /* Enable VMID reference & master bias */ 1410 /* Enable VMID reference & master bias */
1376 snd_soc_update_bits(codec, DA7213_REFERENCES, 1411 snd_soc_update_bits(codec, DA7213_REFERENCES,
1377 DA7213_VMID_EN | DA7213_BIAS_EN, 1412 DA7213_VMID_EN | DA7213_BIAS_EN,
@@ -1382,15 +1417,127 @@ static int da7213_set_bias_level(struct snd_soc_codec *codec,
1382 /* Disable VMID reference & master bias */ 1417 /* Disable VMID reference & master bias */
1383 snd_soc_update_bits(codec, DA7213_REFERENCES, 1418 snd_soc_update_bits(codec, DA7213_REFERENCES,
1384 DA7213_VMID_EN | DA7213_BIAS_EN, 0); 1419 DA7213_VMID_EN | DA7213_BIAS_EN, 0);
1420
1421 /* MCLK */
1422 if (da7213->mclk)
1423 clk_disable_unprepare(da7213->mclk);
1385 break; 1424 break;
1386 } 1425 }
1387 return 0; 1426 return 0;
1388} 1427}
1389 1428
1429/* DT */
1430static const struct of_device_id da7213_of_match[] = {
1431 { .compatible = "dlg,da7213", },
1432 { }
1433};
1434MODULE_DEVICE_TABLE(of, da7213_of_match);
1435
1436static enum da7213_micbias_voltage
1437 da7213_of_micbias_lvl(struct snd_soc_codec *codec, u32 val)
1438{
1439 switch (val) {
1440 case 1600:
1441 return DA7213_MICBIAS_1_6V;
1442 case 2200:
1443 return DA7213_MICBIAS_2_2V;
1444 case 2500:
1445 return DA7213_MICBIAS_2_5V;
1446 case 3000:
1447 return DA7213_MICBIAS_3_0V;
1448 default:
1449 dev_warn(codec->dev, "Invalid micbias level\n");
1450 return DA7213_MICBIAS_2_2V;
1451 }
1452}
1453
1454static enum da7213_dmic_data_sel
1455 da7213_of_dmic_data_sel(struct snd_soc_codec *codec, const char *str)
1456{
1457 if (!strcmp(str, "lrise_rfall")) {
1458 return DA7213_DMIC_DATA_LRISE_RFALL;
1459 } else if (!strcmp(str, "lfall_rrise")) {
1460 return DA7213_DMIC_DATA_LFALL_RRISE;
1461 } else {
1462 dev_warn(codec->dev, "Invalid DMIC data select type\n");
1463 return DA7213_DMIC_DATA_LRISE_RFALL;
1464 }
1465}
1466
1467static enum da7213_dmic_samplephase
1468 da7213_of_dmic_samplephase(struct snd_soc_codec *codec, const char *str)
1469{
1470 if (!strcmp(str, "on_clkedge")) {
1471 return DA7213_DMIC_SAMPLE_ON_CLKEDGE;
1472 } else if (!strcmp(str, "between_clkedge")) {
1473 return DA7213_DMIC_SAMPLE_BETWEEN_CLKEDGE;
1474 } else {
1475 dev_warn(codec->dev, "Invalid DMIC sample phase\n");
1476 return DA7213_DMIC_SAMPLE_ON_CLKEDGE;
1477 }
1478}
1479
1480static enum da7213_dmic_clk_rate
1481 da7213_of_dmic_clkrate(struct snd_soc_codec *codec, u32 val)
1482{
1483 switch (val) {
1484 case 1500000:
1485 return DA7213_DMIC_CLK_1_5MHZ;
1486 case 3000000:
1487 return DA7213_DMIC_CLK_3_0MHZ;
1488 default:
1489 dev_warn(codec->dev, "Invalid DMIC clock rate\n");
1490 return DA7213_DMIC_CLK_1_5MHZ;
1491 }
1492}
1493
1494static struct da7213_platform_data
1495 *da7213_of_to_pdata(struct snd_soc_codec *codec)
1496{
1497 struct device_node *np = codec->dev->of_node;
1498 struct da7213_platform_data *pdata;
1499 const char *of_str;
1500 u32 of_val32;
1501
1502 pdata = devm_kzalloc(codec->dev, sizeof(*pdata), GFP_KERNEL);
1503 if (!pdata) {
1504 dev_warn(codec->dev, "Failed to allocate memory for pdata\n");
1505 return NULL;
1506 }
1507
1508 if (of_property_read_u32(np, "dlg,micbias1-lvl", &of_val32) >= 0)
1509 pdata->micbias1_lvl = da7213_of_micbias_lvl(codec, of_val32);
1510 else
1511 pdata->micbias1_lvl = DA7213_MICBIAS_2_2V;
1512
1513 if (of_property_read_u32(np, "dlg,micbias2-lvl", &of_val32) >= 0)
1514 pdata->micbias2_lvl = da7213_of_micbias_lvl(codec, of_val32);
1515 else
1516 pdata->micbias2_lvl = DA7213_MICBIAS_2_2V;
1517
1518 if (!of_property_read_string(np, "dlg,dmic-data-sel", &of_str))
1519 pdata->dmic_data_sel = da7213_of_dmic_data_sel(codec, of_str);
1520 else
1521 pdata->dmic_data_sel = DA7213_DMIC_DATA_LRISE_RFALL;
1522
1523 if (!of_property_read_string(np, "dlg,dmic-samplephase", &of_str))
1524 pdata->dmic_samplephase =
1525 da7213_of_dmic_samplephase(codec, of_str);
1526 else
1527 pdata->dmic_samplephase = DA7213_DMIC_SAMPLE_ON_CLKEDGE;
1528
1529 if (of_property_read_u32(np, "dlg,dmic-clkrate", &of_val32) >= 0)
1530 pdata->dmic_clk_rate = da7213_of_dmic_clkrate(codec, of_val32);
1531 else
1532 pdata->dmic_clk_rate = DA7213_DMIC_CLK_3_0MHZ;
1533
1534 return pdata;
1535}
1536
1537
1390static int da7213_probe(struct snd_soc_codec *codec) 1538static int da7213_probe(struct snd_soc_codec *codec)
1391{ 1539{
1392 struct da7213_priv *da7213 = snd_soc_codec_get_drvdata(codec); 1540 struct da7213_priv *da7213 = snd_soc_codec_get_drvdata(codec);
1393 struct da7213_platform_data *pdata = da7213->pdata;
1394 1541
1395 /* Default to using ALC auto offset calibration mode. */ 1542 /* Default to using ALC auto offset calibration mode. */
1396 snd_soc_update_bits(codec, DA7213_ALC_CTRL1, 1543 snd_soc_update_bits(codec, DA7213_ALC_CTRL1,
@@ -1450,8 +1597,15 @@ static int da7213_probe(struct snd_soc_codec *codec)
1450 snd_soc_update_bits(codec, DA7213_LINE_CTRL, 1597 snd_soc_update_bits(codec, DA7213_LINE_CTRL,
1451 DA7213_LINE_AMP_OE, DA7213_LINE_AMP_OE); 1598 DA7213_LINE_AMP_OE, DA7213_LINE_AMP_OE);
1452 1599
1600 /* Handle DT/Platform data */
1601 if (codec->dev->of_node)
1602 da7213->pdata = da7213_of_to_pdata(codec);
1603 else
1604 da7213->pdata = dev_get_platdata(codec->dev);
1605
1453 /* Set platform data values */ 1606 /* Set platform data values */
1454 if (da7213->pdata) { 1607 if (da7213->pdata) {
1608 struct da7213_platform_data *pdata = da7213->pdata;
1455 u8 micbias_lvl = 0, dmic_cfg = 0; 1609 u8 micbias_lvl = 0, dmic_cfg = 0;
1456 1610
1457 /* Set Mic Bias voltages */ 1611 /* Set Mic Bias voltages */
@@ -1503,10 +1657,17 @@ static int da7213_probe(struct snd_soc_codec *codec)
1503 DA7213_DMIC_DATA_SEL_MASK | 1657 DA7213_DMIC_DATA_SEL_MASK |
1504 DA7213_DMIC_SAMPLEPHASE_MASK | 1658 DA7213_DMIC_SAMPLEPHASE_MASK |
1505 DA7213_DMIC_CLK_RATE_MASK, dmic_cfg); 1659 DA7213_DMIC_CLK_RATE_MASK, dmic_cfg);
1660 }
1506 1661
1507 /* Set MCLK squaring */ 1662 /* Check if MCLK provided */
1508 da7213->mclk_squarer_en = pdata->mclk_squaring; 1663 da7213->mclk = devm_clk_get(codec->dev, "mclk");
1664 if (IS_ERR(da7213->mclk)) {
1665 if (PTR_ERR(da7213->mclk) != -ENOENT)
1666 return PTR_ERR(da7213->mclk);
1667 else
1668 da7213->mclk = NULL;
1509 } 1669 }
1670
1510 return 0; 1671 return 0;
1511} 1672}
1512 1673
@@ -1537,7 +1698,6 @@ static int da7213_i2c_probe(struct i2c_client *i2c,
1537 const struct i2c_device_id *id) 1698 const struct i2c_device_id *id)
1538{ 1699{
1539 struct da7213_priv *da7213; 1700 struct da7213_priv *da7213;
1540 struct da7213_platform_data *pdata = dev_get_platdata(&i2c->dev);
1541 int ret; 1701 int ret;
1542 1702
1543 da7213 = devm_kzalloc(&i2c->dev, sizeof(struct da7213_priv), 1703 da7213 = devm_kzalloc(&i2c->dev, sizeof(struct da7213_priv),
@@ -1545,9 +1705,6 @@ static int da7213_i2c_probe(struct i2c_client *i2c,
1545 if (!da7213) 1705 if (!da7213)
1546 return -ENOMEM; 1706 return -ENOMEM;
1547 1707
1548 if (pdata)
1549 da7213->pdata = pdata;
1550
1551 i2c_set_clientdata(i2c, da7213); 1708 i2c_set_clientdata(i2c, da7213);
1552 1709
1553 da7213->regmap = devm_regmap_init_i2c(i2c, &da7213_regmap_config); 1710 da7213->regmap = devm_regmap_init_i2c(i2c, &da7213_regmap_config);
@@ -1582,6 +1739,7 @@ MODULE_DEVICE_TABLE(i2c, da7213_i2c_id);
1582static struct i2c_driver da7213_i2c_driver = { 1739static struct i2c_driver da7213_i2c_driver = {
1583 .driver = { 1740 .driver = {
1584 .name = "da7213", 1741 .name = "da7213",
1742 .of_match_table = of_match_ptr(da7213_of_match),
1585 }, 1743 },
1586 .probe = da7213_i2c_probe, 1744 .probe = da7213_i2c_probe,
1587 .remove = da7213_remove, 1745 .remove = da7213_remove,
diff --git a/sound/soc/codecs/da7213.h b/sound/soc/codecs/da7213.h
index 9cb9ddd01282..030fd691b076 100644
--- a/sound/soc/codecs/da7213.h
+++ b/sound/soc/codecs/da7213.h
@@ -13,6 +13,7 @@
13#ifndef _DA7213_H 13#ifndef _DA7213_H
14#define _DA7213_H 14#define _DA7213_H
15 15
16#include <linux/clk.h>
16#include <linux/regmap.h> 17#include <linux/regmap.h>
17#include <sound/da7213.h> 18#include <sound/da7213.h>
18 19
@@ -504,14 +505,17 @@
504#define DA7213_PLL_INDIV_20_40_MHZ_VAL 8 505#define DA7213_PLL_INDIV_20_40_MHZ_VAL 8
505#define DA7213_PLL_INDIV_40_54_MHZ_VAL 16 506#define DA7213_PLL_INDIV_40_54_MHZ_VAL 16
506 507
507enum clk_src { 508enum da7213_clk_src {
508 DA7213_CLKSRC_MCLK 509 DA7213_CLKSRC_MCLK = 0,
510 DA7213_CLKSRC_MCLK_SQR,
509}; 511};
510 512
511/* Codec private data */ 513/* Codec private data */
512struct da7213_priv { 514struct da7213_priv {
513 struct regmap *regmap; 515 struct regmap *regmap;
516 struct clk *mclk;
514 unsigned int mclk_rate; 517 unsigned int mclk_rate;
518 int clk_src;
515 bool master; 519 bool master;
516 bool mclk_squarer_en; 520 bool mclk_squarer_en;
517 bool srm_en; 521 bool srm_en;
diff --git a/sound/soc/codecs/da7219-aad.c b/sound/soc/codecs/da7219-aad.c
new file mode 100644
index 000000000000..9459593eef13
--- /dev/null
+++ b/sound/soc/codecs/da7219-aad.c
@@ -0,0 +1,823 @@
1/*
2 * da7219-aad.c - Dialog DA7219 ALSA SoC AAD Driver
3 *
4 * Copyright (c) 2015 Dialog Semiconductor Ltd.
5 *
6 * Author: Adam Thomson <Adam.Thomson.Opensource@diasemi.com>
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the
10 * Free Software Foundation; either version 2 of the License, or (at your
11 * option) any later version.
12 */
13
14#include <linux/module.h>
15#include <linux/platform_device.h>
16#include <linux/of_device.h>
17#include <linux/of_irq.h>
18#include <linux/pm_wakeirq.h>
19#include <linux/slab.h>
20#include <linux/delay.h>
21#include <linux/workqueue.h>
22#include <sound/soc.h>
23#include <sound/jack.h>
24#include <sound/da7219.h>
25
26#include "da7219.h"
27#include "da7219-aad.h"
28
29
30/*
31 * Detection control
32 */
33
34void da7219_aad_jack_det(struct snd_soc_codec *codec, struct snd_soc_jack *jack)
35{
36 struct da7219_priv *da7219 = snd_soc_codec_get_drvdata(codec);
37
38 da7219->aad->jack = jack;
39 da7219->aad->jack_inserted = false;
40
41 /* Send an initial empty report */
42 snd_soc_jack_report(jack, 0, DA7219_AAD_REPORT_ALL_MASK);
43
44 /* Enable/Disable jack detection */
45 snd_soc_update_bits(codec, DA7219_ACCDET_CONFIG_1,
46 DA7219_ACCDET_EN_MASK,
47 (jack ? DA7219_ACCDET_EN_MASK : 0));
48}
49EXPORT_SYMBOL_GPL(da7219_aad_jack_det);
50
51/*
52 * Button/HPTest work
53 */
54
55static void da7219_aad_btn_det_work(struct work_struct *work)
56{
57 struct da7219_aad_priv *da7219_aad =
58 container_of(work, struct da7219_aad_priv, btn_det_work);
59 struct snd_soc_codec *codec = da7219_aad->codec;
60 struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
61 u8 statusa, micbias_ctrl;
62 bool micbias_up = false;
63 int retries = 0;
64
65 /* Drive headphones/lineout */
66 snd_soc_update_bits(codec, DA7219_HP_L_CTRL,
67 DA7219_HP_L_AMP_OE_MASK,
68 DA7219_HP_L_AMP_OE_MASK);
69 snd_soc_update_bits(codec, DA7219_HP_R_CTRL,
70 DA7219_HP_R_AMP_OE_MASK,
71 DA7219_HP_R_AMP_OE_MASK);
72
73 /* Make sure mic bias is up */
74 snd_soc_dapm_force_enable_pin(dapm, "Mic Bias");
75 snd_soc_dapm_sync(dapm);
76
77 do {
78 statusa = snd_soc_read(codec, DA7219_ACCDET_STATUS_A);
79 if (statusa & DA7219_MICBIAS_UP_STS_MASK)
80 micbias_up = true;
81 else if (retries++ < DA7219_AAD_MICBIAS_CHK_RETRIES)
82 msleep(DA7219_AAD_MICBIAS_CHK_DELAY);
83 } while ((!micbias_up) && (retries < DA7219_AAD_MICBIAS_CHK_RETRIES));
84
85 if (retries >= DA7219_AAD_MICBIAS_CHK_RETRIES)
86 dev_warn(codec->dev, "Mic bias status check timed out");
87
88 /*
89 * Mic bias pulse required to enable mic, must be done before enabling
90 * button detection to prevent erroneous button readings.
91 */
92 if (da7219_aad->micbias_pulse_lvl && da7219_aad->micbias_pulse_time) {
93 /* Pulse higher level voltage */
94 micbias_ctrl = snd_soc_read(codec, DA7219_MICBIAS_CTRL);
95 snd_soc_update_bits(codec, DA7219_MICBIAS_CTRL,
96 DA7219_MICBIAS1_LEVEL_MASK,
97 da7219_aad->micbias_pulse_lvl);
98 msleep(da7219_aad->micbias_pulse_time);
99 snd_soc_write(codec, DA7219_MICBIAS_CTRL, micbias_ctrl);
100
101 }
102
103 snd_soc_update_bits(codec, DA7219_ACCDET_CONFIG_1,
104 DA7219_BUTTON_CONFIG_MASK,
105 da7219_aad->btn_cfg);
106}
107
108static void da7219_aad_hptest_work(struct work_struct *work)
109{
110 struct da7219_aad_priv *da7219_aad =
111 container_of(work, struct da7219_aad_priv, hptest_work);
112 struct snd_soc_codec *codec = da7219_aad->codec;
113 struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
114 struct da7219_priv *da7219 = snd_soc_codec_get_drvdata(codec);
115
116 u16 tonegen_freq_hptest;
117 u8 accdet_cfg8;
118 int report = 0;
119
120 /* Lock DAPM and any Kcontrols that are affected by this test */
121 snd_soc_dapm_mutex_lock(dapm);
122 mutex_lock(&da7219->lock);
123
124 /* Bypass cache so it saves current settings */
125 regcache_cache_bypass(da7219->regmap, true);
126
127 /* Make sure Tone Generator is disabled */
128 snd_soc_write(codec, DA7219_TONE_GEN_CFG1, 0);
129
130 /* Enable HPTest block, 1KOhms check */
131 snd_soc_update_bits(codec, DA7219_ACCDET_CONFIG_8,
132 DA7219_HPTEST_EN_MASK | DA7219_HPTEST_RES_SEL_MASK,
133 DA7219_HPTEST_EN_MASK |
134 DA7219_HPTEST_RES_SEL_1KOHMS);
135
136 /* Set gains to 0db */
137 snd_soc_write(codec, DA7219_DAC_L_GAIN, DA7219_DAC_DIGITAL_GAIN_0DB);
138 snd_soc_write(codec, DA7219_DAC_R_GAIN, DA7219_DAC_DIGITAL_GAIN_0DB);
139 snd_soc_write(codec, DA7219_HP_L_GAIN, DA7219_HP_AMP_GAIN_0DB);
140 snd_soc_write(codec, DA7219_HP_R_GAIN, DA7219_HP_AMP_GAIN_0DB);
141
142 /* Disable DAC filters, EQs and soft mute */
143 snd_soc_update_bits(codec, DA7219_DAC_FILTERS1, DA7219_HPF_MODE_MASK,
144 0);
145 snd_soc_update_bits(codec, DA7219_DAC_FILTERS4, DA7219_DAC_EQ_EN_MASK,
146 0);
147 snd_soc_update_bits(codec, DA7219_DAC_FILTERS5,
148 DA7219_DAC_SOFTMUTE_EN_MASK, 0);
149
150 /* Enable HP left & right paths */
151 snd_soc_update_bits(codec, DA7219_CP_CTRL, DA7219_CP_EN_MASK,
152 DA7219_CP_EN_MASK);
153 snd_soc_update_bits(codec, DA7219_DIG_ROUTING_DAC,
154 DA7219_DAC_L_SRC_MASK | DA7219_DAC_R_SRC_MASK,
155 DA7219_DAC_L_SRC_TONEGEN |
156 DA7219_DAC_R_SRC_TONEGEN);
157 snd_soc_update_bits(codec, DA7219_DAC_L_CTRL,
158 DA7219_DAC_L_EN_MASK | DA7219_DAC_L_MUTE_EN_MASK,
159 DA7219_DAC_L_EN_MASK);
160 snd_soc_update_bits(codec, DA7219_DAC_R_CTRL,
161 DA7219_DAC_R_EN_MASK | DA7219_DAC_R_MUTE_EN_MASK,
162 DA7219_DAC_R_EN_MASK);
163 snd_soc_update_bits(codec, DA7219_MIXOUT_L_SELECT,
164 DA7219_MIXOUT_L_MIX_SELECT_MASK,
165 DA7219_MIXOUT_L_MIX_SELECT_MASK);
166 snd_soc_update_bits(codec, DA7219_MIXOUT_R_SELECT,
167 DA7219_MIXOUT_R_MIX_SELECT_MASK,
168 DA7219_MIXOUT_R_MIX_SELECT_MASK);
169 snd_soc_update_bits(codec, DA7219_DROUTING_ST_OUTFILT_1L,
170 DA7219_OUTFILT_ST_1L_SRC_MASK,
171 DA7219_DMIX_ST_SRC_OUTFILT1L);
172 snd_soc_update_bits(codec, DA7219_DROUTING_ST_OUTFILT_1R,
173 DA7219_OUTFILT_ST_1R_SRC_MASK,
174 DA7219_DMIX_ST_SRC_OUTFILT1R);
175 snd_soc_update_bits(codec, DA7219_MIXOUT_L_CTRL,
176 DA7219_MIXOUT_L_AMP_EN_MASK,
177 DA7219_MIXOUT_L_AMP_EN_MASK);
178 snd_soc_update_bits(codec, DA7219_MIXOUT_R_CTRL,
179 DA7219_MIXOUT_R_AMP_EN_MASK,
180 DA7219_MIXOUT_R_AMP_EN_MASK);
181 snd_soc_write(codec, DA7219_HP_L_CTRL,
182 DA7219_HP_L_AMP_OE_MASK | DA7219_HP_L_AMP_EN_MASK);
183 snd_soc_write(codec, DA7219_HP_R_CTRL,
184 DA7219_HP_R_AMP_OE_MASK | DA7219_HP_R_AMP_EN_MASK);
185
186 /* Configure & start Tone Generator */
187 snd_soc_write(codec, DA7219_TONE_GEN_ON_PER, DA7219_BEEP_ON_PER_MASK);
188 tonegen_freq_hptest = cpu_to_le16(DA7219_AAD_HPTEST_RAMP_FREQ);
189 regmap_raw_write(da7219->regmap, DA7219_TONE_GEN_FREQ1_L,
190 &tonegen_freq_hptest, sizeof(tonegen_freq_hptest));
191 snd_soc_update_bits(codec, DA7219_TONE_GEN_CFG2,
192 DA7219_SWG_SEL_MASK | DA7219_TONE_GEN_GAIN_MASK,
193 DA7219_SWG_SEL_SRAMP |
194 DA7219_TONE_GEN_GAIN_MINUS_15DB);
195 snd_soc_write(codec, DA7219_TONE_GEN_CFG1, DA7219_START_STOPN_MASK);
196
197 msleep(DA7219_AAD_HPTEST_PERIOD);
198
199 /* Grab comparator reading */
200 accdet_cfg8 = snd_soc_read(codec, DA7219_ACCDET_CONFIG_8);
201 if (accdet_cfg8 & DA7219_HPTEST_COMP_MASK)
202 report |= SND_JACK_HEADPHONE;
203 else
204 report |= SND_JACK_LINEOUT;
205
206 /* Stop tone generator */
207 snd_soc_write(codec, DA7219_TONE_GEN_CFG1, 0);
208
209 msleep(DA7219_AAD_HPTEST_PERIOD);
210
211 /* Restore original settings from cache */
212 regcache_mark_dirty(da7219->regmap);
213 regcache_sync_region(da7219->regmap, DA7219_HP_L_CTRL,
214 DA7219_HP_R_CTRL);
215 regcache_sync_region(da7219->regmap, DA7219_MIXOUT_L_CTRL,
216 DA7219_MIXOUT_R_CTRL);
217 regcache_sync_region(da7219->regmap, DA7219_DROUTING_ST_OUTFILT_1L,
218 DA7219_DROUTING_ST_OUTFILT_1R);
219 regcache_sync_region(da7219->regmap, DA7219_MIXOUT_L_SELECT,
220 DA7219_MIXOUT_R_SELECT);
221 regcache_sync_region(da7219->regmap, DA7219_DAC_L_CTRL,
222 DA7219_DAC_R_CTRL);
223 regcache_sync_region(da7219->regmap, DA7219_DIG_ROUTING_DAC,
224 DA7219_DIG_ROUTING_DAC);
225 regcache_sync_region(da7219->regmap, DA7219_CP_CTRL, DA7219_CP_CTRL);
226 regcache_sync_region(da7219->regmap, DA7219_DAC_FILTERS5,
227 DA7219_DAC_FILTERS5);
228 regcache_sync_region(da7219->regmap, DA7219_DAC_FILTERS4,
229 DA7219_DAC_FILTERS1);
230 regcache_sync_region(da7219->regmap, DA7219_HP_L_GAIN,
231 DA7219_HP_R_GAIN);
232 regcache_sync_region(da7219->regmap, DA7219_DAC_L_GAIN,
233 DA7219_DAC_R_GAIN);
234 regcache_sync_region(da7219->regmap, DA7219_TONE_GEN_ON_PER,
235 DA7219_TONE_GEN_ON_PER);
236 regcache_sync_region(da7219->regmap, DA7219_TONE_GEN_FREQ1_L,
237 DA7219_TONE_GEN_FREQ1_U);
238 regcache_sync_region(da7219->regmap, DA7219_TONE_GEN_CFG1,
239 DA7219_TONE_GEN_CFG2);
240
241 regcache_cache_bypass(da7219->regmap, false);
242
243 /* Disable HPTest block */
244 snd_soc_update_bits(codec, DA7219_ACCDET_CONFIG_8,
245 DA7219_HPTEST_EN_MASK, 0);
246
247 /* Drive Headphones/lineout */
248 snd_soc_update_bits(codec, DA7219_HP_L_CTRL, DA7219_HP_L_AMP_OE_MASK,
249 DA7219_HP_L_AMP_OE_MASK);
250 snd_soc_update_bits(codec, DA7219_HP_R_CTRL, DA7219_HP_R_AMP_OE_MASK,
251 DA7219_HP_R_AMP_OE_MASK);
252
253 mutex_unlock(&da7219->lock);
254 snd_soc_dapm_mutex_unlock(dapm);
255
256 /*
257 * Only send report if jack hasn't been removed during process,
258 * otherwise it's invalid and we drop it.
259 */
260 if (da7219_aad->jack_inserted)
261 snd_soc_jack_report(da7219_aad->jack, report,
262 SND_JACK_HEADSET | SND_JACK_LINEOUT);
263}
264
265
266/*
267 * IRQ
268 */
269
270static irqreturn_t da7219_aad_irq_thread(int irq, void *data)
271{
272 struct da7219_aad_priv *da7219_aad = data;
273 struct snd_soc_codec *codec = da7219_aad->codec;
274 struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
275 struct da7219_priv *da7219 = snd_soc_codec_get_drvdata(codec);
276 u8 events[DA7219_AAD_IRQ_REG_MAX];
277 u8 statusa;
278 int i, report = 0, mask = 0;
279
280 /* Read current IRQ events */
281 regmap_bulk_read(da7219->regmap, DA7219_ACCDET_IRQ_EVENT_A,
282 events, DA7219_AAD_IRQ_REG_MAX);
283
284 if (!events[DA7219_AAD_IRQ_REG_A] && !events[DA7219_AAD_IRQ_REG_B])
285 return IRQ_NONE;
286
287 /* Read status register for jack insertion & type status */
288 statusa = snd_soc_read(codec, DA7219_ACCDET_STATUS_A);
289
290 /* Clear events */
291 regmap_bulk_write(da7219->regmap, DA7219_ACCDET_IRQ_EVENT_A,
292 events, DA7219_AAD_IRQ_REG_MAX);
293
294 dev_dbg(codec->dev, "IRQ events = 0x%x|0x%x, status = 0x%x\n",
295 events[DA7219_AAD_IRQ_REG_A], events[DA7219_AAD_IRQ_REG_B],
296 statusa);
297
298 if (statusa & DA7219_JACK_INSERTION_STS_MASK) {
299 /* Jack Insertion */
300 if (events[DA7219_AAD_IRQ_REG_A] &
301 DA7219_E_JACK_INSERTED_MASK) {
302 report |= SND_JACK_MECHANICAL;
303 mask |= SND_JACK_MECHANICAL;
304 da7219_aad->jack_inserted = true;
305 }
306
307 /* Jack type detection */
308 if (events[DA7219_AAD_IRQ_REG_A] &
309 DA7219_E_JACK_DETECT_COMPLETE_MASK) {
310 /*
311 * If 4-pole, then enable button detection, else perform
312 * HP impedance test to determine output type to report.
313 *
314 * We schedule work here as the tasks themselves can
315 * take time to complete, and in particular for hptest
316 * we want to be able to check if the jack was removed
317 * during the procedure as this will invalidate the
318 * result. By doing this as work, the IRQ thread can
319 * handle a removal, and we can check at the end of
320 * hptest if we have a valid result or not.
321 */
322 if (statusa & DA7219_JACK_TYPE_STS_MASK) {
323 report |= SND_JACK_HEADSET;
324 mask |= SND_JACK_HEADSET | SND_JACK_LINEOUT;
325 schedule_work(&da7219_aad->btn_det_work);
326 } else {
327 schedule_work(&da7219_aad->hptest_work);
328 }
329 }
330
331 /* Button support for 4-pole jack */
332 if (statusa & DA7219_JACK_TYPE_STS_MASK) {
333 for (i = 0; i < DA7219_AAD_MAX_BUTTONS; ++i) {
334 /* Button Press */
335 if (events[DA7219_AAD_IRQ_REG_B] &
336 (DA7219_E_BUTTON_A_PRESSED_MASK << i)) {
337 report |= SND_JACK_BTN_0 >> i;
338 mask |= SND_JACK_BTN_0 >> i;
339 }
340 }
341 snd_soc_jack_report(da7219_aad->jack, report, mask);
342
343 for (i = 0; i < DA7219_AAD_MAX_BUTTONS; ++i) {
344 /* Button Release */
345 if (events[DA7219_AAD_IRQ_REG_B] &
346 (DA7219_E_BUTTON_A_RELEASED_MASK >> i)) {
347 report &= ~(SND_JACK_BTN_0 >> i);
348 mask |= SND_JACK_BTN_0 >> i;
349 }
350 }
351 }
352 } else {
353 /* Jack removal */
354 if (events[DA7219_AAD_IRQ_REG_A] & DA7219_E_JACK_REMOVED_MASK) {
355 report = 0;
356 mask |= DA7219_AAD_REPORT_ALL_MASK;
357 da7219_aad->jack_inserted = false;
358
359 /* Un-drive headphones/lineout */
360 snd_soc_update_bits(codec, DA7219_HP_R_CTRL,
361 DA7219_HP_R_AMP_OE_MASK, 0);
362 snd_soc_update_bits(codec, DA7219_HP_L_CTRL,
363 DA7219_HP_L_AMP_OE_MASK, 0);
364
365 /* Ensure button detection disabled */
366 snd_soc_update_bits(codec, DA7219_ACCDET_CONFIG_1,
367 DA7219_BUTTON_CONFIG_MASK, 0);
368
369 /* Disable mic bias */
370 snd_soc_dapm_disable_pin(dapm, "Mic Bias");
371 snd_soc_dapm_sync(dapm);
372
373 /* Cancel any pending work */
374 cancel_work_sync(&da7219_aad->btn_det_work);
375 cancel_work_sync(&da7219_aad->hptest_work);
376 }
377 }
378
379 snd_soc_jack_report(da7219_aad->jack, report, mask);
380
381 return IRQ_HANDLED;
382}
383
384/*
385 * DT to pdata conversion
386 */
387
388static enum da7219_aad_micbias_pulse_lvl
389 da7219_aad_of_micbias_pulse_lvl(struct snd_soc_codec *codec, u32 val)
390{
391 switch (val) {
392 case 2800:
393 return DA7219_AAD_MICBIAS_PULSE_LVL_2_8V;
394 case 2900:
395 return DA7219_AAD_MICBIAS_PULSE_LVL_2_9V;
396 default:
397 dev_warn(codec->dev, "Invalid micbias pulse level");
398 return DA7219_AAD_MICBIAS_PULSE_LVL_OFF;
399 }
400}
401
402static enum da7219_aad_btn_cfg
403 da7219_aad_of_btn_cfg(struct snd_soc_codec *codec, u32 val)
404{
405 switch (val) {
406 case 2:
407 return DA7219_AAD_BTN_CFG_2MS;
408 case 5:
409 return DA7219_AAD_BTN_CFG_5MS;
410 case 10:
411 return DA7219_AAD_BTN_CFG_10MS;
412 case 50:
413 return DA7219_AAD_BTN_CFG_50MS;
414 case 100:
415 return DA7219_AAD_BTN_CFG_100MS;
416 case 200:
417 return DA7219_AAD_BTN_CFG_200MS;
418 case 500:
419 return DA7219_AAD_BTN_CFG_500MS;
420 default:
421 dev_warn(codec->dev, "Invalid button config");
422 return DA7219_AAD_BTN_CFG_10MS;
423 }
424}
425
426static enum da7219_aad_mic_det_thr
427 da7219_aad_of_mic_det_thr(struct snd_soc_codec *codec, u32 val)
428{
429 switch (val) {
430 case 200:
431 return DA7219_AAD_MIC_DET_THR_200_OHMS;
432 case 500:
433 return DA7219_AAD_MIC_DET_THR_500_OHMS;
434 case 750:
435 return DA7219_AAD_MIC_DET_THR_750_OHMS;
436 case 1000:
437 return DA7219_AAD_MIC_DET_THR_1000_OHMS;
438 default:
439 dev_warn(codec->dev, "Invalid mic detect threshold");
440 return DA7219_AAD_MIC_DET_THR_500_OHMS;
441 }
442}
443
444static enum da7219_aad_jack_ins_deb
445 da7219_aad_of_jack_ins_deb(struct snd_soc_codec *codec, u32 val)
446{
447 switch (val) {
448 case 5:
449 return DA7219_AAD_JACK_INS_DEB_5MS;
450 case 10:
451 return DA7219_AAD_JACK_INS_DEB_10MS;
452 case 20:
453 return DA7219_AAD_JACK_INS_DEB_20MS;
454 case 50:
455 return DA7219_AAD_JACK_INS_DEB_50MS;
456 case 100:
457 return DA7219_AAD_JACK_INS_DEB_100MS;
458 case 200:
459 return DA7219_AAD_JACK_INS_DEB_200MS;
460 case 500:
461 return DA7219_AAD_JACK_INS_DEB_500MS;
462 case 1000:
463 return DA7219_AAD_JACK_INS_DEB_1S;
464 default:
465 dev_warn(codec->dev, "Invalid jack insert debounce");
466 return DA7219_AAD_JACK_INS_DEB_20MS;
467 }
468}
469
470static enum da7219_aad_jack_det_rate
471 da7219_aad_of_jack_det_rate(struct snd_soc_codec *codec, const char *str)
472{
473 if (!strcmp(str, "32ms_64ms")) {
474 return DA7219_AAD_JACK_DET_RATE_32_64MS;
475 } else if (!strcmp(str, "64ms_128ms")) {
476 return DA7219_AAD_JACK_DET_RATE_64_128MS;
477 } else if (!strcmp(str, "128ms_256ms")) {
478 return DA7219_AAD_JACK_DET_RATE_128_256MS;
479 } else if (!strcmp(str, "256ms_512ms")) {
480 return DA7219_AAD_JACK_DET_RATE_256_512MS;
481 } else {
482 dev_warn(codec->dev, "Invalid jack detect rate");
483 return DA7219_AAD_JACK_DET_RATE_256_512MS;
484 }
485}
486
487static enum da7219_aad_jack_rem_deb
488 da7219_aad_of_jack_rem_deb(struct snd_soc_codec *codec, u32 val)
489{
490 switch (val) {
491 case 1:
492 return DA7219_AAD_JACK_REM_DEB_1MS;
493 case 5:
494 return DA7219_AAD_JACK_REM_DEB_5MS;
495 case 10:
496 return DA7219_AAD_JACK_REM_DEB_10MS;
497 case 20:
498 return DA7219_AAD_JACK_REM_DEB_20MS;
499 default:
500 dev_warn(codec->dev, "Invalid jack removal debounce");
501 return DA7219_AAD_JACK_REM_DEB_1MS;
502 }
503}
504
505static enum da7219_aad_btn_avg
506 da7219_aad_of_btn_avg(struct snd_soc_codec *codec, u32 val)
507{
508 switch (val) {
509 case 1:
510 return DA7219_AAD_BTN_AVG_1;
511 case 2:
512 return DA7219_AAD_BTN_AVG_2;
513 case 4:
514 return DA7219_AAD_BTN_AVG_4;
515 case 8:
516 return DA7219_AAD_BTN_AVG_8;
517 default:
518 dev_warn(codec->dev, "Invalid button average value");
519 return DA7219_AAD_BTN_AVG_2;
520 }
521}
522
523static enum da7219_aad_adc_1bit_rpt
524 da7219_aad_of_adc_1bit_rpt(struct snd_soc_codec *codec, u32 val)
525{
526 switch (val) {
527 case 1:
528 return DA7219_AAD_ADC_1BIT_RPT_1;
529 case 2:
530 return DA7219_AAD_ADC_1BIT_RPT_2;
531 case 4:
532 return DA7219_AAD_ADC_1BIT_RPT_4;
533 case 8:
534 return DA7219_AAD_ADC_1BIT_RPT_8;
535 default:
536 dev_warn(codec->dev, "Invalid ADC 1-bit repeat value");
537 return DA7219_AAD_ADC_1BIT_RPT_1;
538 }
539}
540
541static struct da7219_aad_pdata *da7219_aad_of_to_pdata(struct snd_soc_codec *codec)
542{
543 struct device_node *np = codec->dev->of_node;
544 struct device_node *aad_np = of_find_node_by_name(np, "da7219_aad");
545 struct da7219_aad_pdata *aad_pdata;
546 const char *of_str;
547 u32 of_val32;
548
549 if (!aad_np)
550 return NULL;
551
552 aad_pdata = devm_kzalloc(codec->dev, sizeof(*aad_pdata), GFP_KERNEL);
553 if (!aad_pdata)
554 goto out;
555
556 aad_pdata->irq = irq_of_parse_and_map(np, 0);
557
558 if (of_property_read_u32(aad_np, "dlg,micbias-pulse-lvl",
559 &of_val32) >= 0)
560 aad_pdata->micbias_pulse_lvl =
561 da7219_aad_of_micbias_pulse_lvl(codec, of_val32);
562 else
563 aad_pdata->micbias_pulse_lvl = DA7219_AAD_MICBIAS_PULSE_LVL_OFF;
564
565 if (of_property_read_u32(aad_np, "dlg,micbias-pulse-time",
566 &of_val32) >= 0)
567 aad_pdata->micbias_pulse_time = of_val32;
568
569 if (of_property_read_u32(aad_np, "dlg,btn-cfg", &of_val32) >= 0)
570 aad_pdata->btn_cfg = da7219_aad_of_btn_cfg(codec, of_val32);
571 else
572 aad_pdata->btn_cfg = DA7219_AAD_BTN_CFG_10MS;
573
574 if (of_property_read_u32(aad_np, "dlg,mic-det-thr", &of_val32) >= 0)
575 aad_pdata->mic_det_thr =
576 da7219_aad_of_mic_det_thr(codec, of_val32);
577 else
578 aad_pdata->mic_det_thr = DA7219_AAD_MIC_DET_THR_500_OHMS;
579
580 if (of_property_read_u32(aad_np, "dlg,jack-ins-deb", &of_val32) >= 0)
581 aad_pdata->jack_ins_deb =
582 da7219_aad_of_jack_ins_deb(codec, of_val32);
583 else
584 aad_pdata->jack_ins_deb = DA7219_AAD_JACK_INS_DEB_20MS;
585
586 if (!of_property_read_string(aad_np, "dlg,jack-det-rate", &of_str))
587 aad_pdata->jack_det_rate =
588 da7219_aad_of_jack_det_rate(codec, of_str);
589 else
590 aad_pdata->jack_det_rate = DA7219_AAD_JACK_DET_RATE_256_512MS;
591
592 if (of_property_read_u32(aad_np, "dlg,jack-rem-deb", &of_val32) >= 0)
593 aad_pdata->jack_rem_deb =
594 da7219_aad_of_jack_rem_deb(codec, of_val32);
595 else
596 aad_pdata->jack_rem_deb = DA7219_AAD_JACK_REM_DEB_1MS;
597
598 if (of_property_read_u32(aad_np, "dlg,a-d-btn-thr", &of_val32) >= 0)
599 aad_pdata->a_d_btn_thr = (u8) of_val32;
600 else
601 aad_pdata->a_d_btn_thr = 0xA;
602
603 if (of_property_read_u32(aad_np, "dlg,d-b-btn-thr", &of_val32) >= 0)
604 aad_pdata->d_b_btn_thr = (u8) of_val32;
605 else
606 aad_pdata->d_b_btn_thr = 0x16;
607
608 if (of_property_read_u32(aad_np, "dlg,b-c-btn-thr", &of_val32) >= 0)
609 aad_pdata->b_c_btn_thr = (u8) of_val32;
610 else
611 aad_pdata->b_c_btn_thr = 0x21;
612
613 if (of_property_read_u32(aad_np, "dlg,c-mic-btn-thr", &of_val32) >= 0)
614 aad_pdata->c_mic_btn_thr = (u8) of_val32;
615 else
616 aad_pdata->c_mic_btn_thr = 0x3E;
617
618 if (of_property_read_u32(aad_np, "dlg,btn-avg", &of_val32) >= 0)
619 aad_pdata->btn_avg = da7219_aad_of_btn_avg(codec, of_val32);
620 else
621 aad_pdata->btn_avg = DA7219_AAD_BTN_AVG_2;
622
623 if (of_property_read_u32(aad_np, "dlg,adc-1bit-rpt", &of_val32) >= 0)
624 aad_pdata->adc_1bit_rpt =
625 da7219_aad_of_adc_1bit_rpt(codec, of_val32);
626 else
627 aad_pdata->adc_1bit_rpt = DA7219_AAD_ADC_1BIT_RPT_1;
628
629out:
630 of_node_put(aad_np);
631
632 return aad_pdata;
633}
634
635static void da7219_aad_handle_pdata(struct snd_soc_codec *codec)
636{
637 struct da7219_priv *da7219 = snd_soc_codec_get_drvdata(codec);
638 struct da7219_aad_priv *da7219_aad = da7219->aad;
639 struct da7219_pdata *pdata = da7219->pdata;
640
641 if ((pdata) && (pdata->aad_pdata)) {
642 struct da7219_aad_pdata *aad_pdata = pdata->aad_pdata;
643 u8 cfg, mask;
644
645 da7219_aad->irq = aad_pdata->irq;
646
647 switch (aad_pdata->micbias_pulse_lvl) {
648 case DA7219_AAD_MICBIAS_PULSE_LVL_2_8V:
649 case DA7219_AAD_MICBIAS_PULSE_LVL_2_9V:
650 da7219_aad->micbias_pulse_lvl =
651 (aad_pdata->micbias_pulse_lvl <<
652 DA7219_MICBIAS1_LEVEL_SHIFT);
653 break;
654 default:
655 break;
656 }
657
658 da7219_aad->micbias_pulse_time = aad_pdata->micbias_pulse_time;
659
660 switch (aad_pdata->btn_cfg) {
661 case DA7219_AAD_BTN_CFG_2MS:
662 case DA7219_AAD_BTN_CFG_5MS:
663 case DA7219_AAD_BTN_CFG_10MS:
664 case DA7219_AAD_BTN_CFG_50MS:
665 case DA7219_AAD_BTN_CFG_100MS:
666 case DA7219_AAD_BTN_CFG_200MS:
667 case DA7219_AAD_BTN_CFG_500MS:
668 da7219_aad->btn_cfg = (aad_pdata->btn_cfg <<
669 DA7219_BUTTON_CONFIG_SHIFT);
670 }
671
672 cfg = 0;
673 mask = 0;
674 switch (aad_pdata->mic_det_thr) {
675 case DA7219_AAD_MIC_DET_THR_200_OHMS:
676 case DA7219_AAD_MIC_DET_THR_500_OHMS:
677 case DA7219_AAD_MIC_DET_THR_750_OHMS:
678 case DA7219_AAD_MIC_DET_THR_1000_OHMS:
679 cfg |= (aad_pdata->mic_det_thr <<
680 DA7219_MIC_DET_THRESH_SHIFT);
681 mask |= DA7219_MIC_DET_THRESH_MASK;
682 }
683 snd_soc_update_bits(codec, DA7219_ACCDET_CONFIG_1, mask, cfg);
684
685 cfg = 0;
686 mask = 0;
687 switch (aad_pdata->jack_ins_deb) {
688 case DA7219_AAD_JACK_INS_DEB_5MS:
689 case DA7219_AAD_JACK_INS_DEB_10MS:
690 case DA7219_AAD_JACK_INS_DEB_20MS:
691 case DA7219_AAD_JACK_INS_DEB_50MS:
692 case DA7219_AAD_JACK_INS_DEB_100MS:
693 case DA7219_AAD_JACK_INS_DEB_200MS:
694 case DA7219_AAD_JACK_INS_DEB_500MS:
695 case DA7219_AAD_JACK_INS_DEB_1S:
696 cfg |= (aad_pdata->jack_ins_deb <<
697 DA7219_JACKDET_DEBOUNCE_SHIFT);
698 mask |= DA7219_JACKDET_DEBOUNCE_MASK;
699 }
700 switch (aad_pdata->jack_det_rate) {
701 case DA7219_AAD_JACK_DET_RATE_32_64MS:
702 case DA7219_AAD_JACK_DET_RATE_64_128MS:
703 case DA7219_AAD_JACK_DET_RATE_128_256MS:
704 case DA7219_AAD_JACK_DET_RATE_256_512MS:
705 cfg |= (aad_pdata->jack_det_rate <<
706 DA7219_JACK_DETECT_RATE_SHIFT);
707 mask |= DA7219_JACK_DETECT_RATE_MASK;
708 }
709 switch (aad_pdata->jack_rem_deb) {
710 case DA7219_AAD_JACK_REM_DEB_1MS:
711 case DA7219_AAD_JACK_REM_DEB_5MS:
712 case DA7219_AAD_JACK_REM_DEB_10MS:
713 case DA7219_AAD_JACK_REM_DEB_20MS:
714 cfg |= (aad_pdata->jack_rem_deb <<
715 DA7219_JACKDET_REM_DEB_SHIFT);
716 mask |= DA7219_JACKDET_REM_DEB_MASK;
717 }
718 snd_soc_update_bits(codec, DA7219_ACCDET_CONFIG_2, mask, cfg);
719
720 snd_soc_write(codec, DA7219_ACCDET_CONFIG_3,
721 aad_pdata->a_d_btn_thr);
722 snd_soc_write(codec, DA7219_ACCDET_CONFIG_4,
723 aad_pdata->d_b_btn_thr);
724 snd_soc_write(codec, DA7219_ACCDET_CONFIG_5,
725 aad_pdata->b_c_btn_thr);
726 snd_soc_write(codec, DA7219_ACCDET_CONFIG_6,
727 aad_pdata->c_mic_btn_thr);
728
729 cfg = 0;
730 mask = 0;
731 switch (aad_pdata->btn_avg) {
732 case DA7219_AAD_BTN_AVG_1:
733 case DA7219_AAD_BTN_AVG_2:
734 case DA7219_AAD_BTN_AVG_4:
735 case DA7219_AAD_BTN_AVG_8:
736 cfg |= (aad_pdata->btn_avg <<
737 DA7219_BUTTON_AVERAGE_SHIFT);
738 mask |= DA7219_BUTTON_AVERAGE_MASK;
739 }
740 switch (aad_pdata->adc_1bit_rpt) {
741 case DA7219_AAD_ADC_1BIT_RPT_1:
742 case DA7219_AAD_ADC_1BIT_RPT_2:
743 case DA7219_AAD_ADC_1BIT_RPT_4:
744 case DA7219_AAD_ADC_1BIT_RPT_8:
745 cfg |= (aad_pdata->adc_1bit_rpt <<
746 DA7219_ADC_1_BIT_REPEAT_SHIFT);
747 mask |= DA7219_ADC_1_BIT_REPEAT_MASK;
748 }
749 snd_soc_update_bits(codec, DA7219_ACCDET_CONFIG_7, mask, cfg);
750 }
751}
752
753
754/*
755 * Init/Exit
756 */
757
758int da7219_aad_init(struct snd_soc_codec *codec)
759{
760 struct da7219_priv *da7219 = snd_soc_codec_get_drvdata(codec);
761 struct da7219_aad_priv *da7219_aad;
762 u8 mask[DA7219_AAD_IRQ_REG_MAX];
763 int ret;
764
765 da7219_aad = devm_kzalloc(codec->dev, sizeof(*da7219_aad), GFP_KERNEL);
766 if (!da7219_aad)
767 return -ENOMEM;
768
769 da7219->aad = da7219_aad;
770 da7219_aad->codec = codec;
771
772 /* Handle any DT/platform data */
773 if ((codec->dev->of_node) && (da7219->pdata))
774 da7219->pdata->aad_pdata = da7219_aad_of_to_pdata(codec);
775
776 da7219_aad_handle_pdata(codec);
777
778 /* Disable button detection */
779 snd_soc_update_bits(codec, DA7219_ACCDET_CONFIG_1,
780 DA7219_BUTTON_CONFIG_MASK, 0);
781
782 INIT_WORK(&da7219_aad->btn_det_work, da7219_aad_btn_det_work);
783 INIT_WORK(&da7219_aad->hptest_work, da7219_aad_hptest_work);
784
785 ret = request_threaded_irq(da7219_aad->irq, NULL,
786 da7219_aad_irq_thread,
787 IRQF_TRIGGER_LOW | IRQF_ONESHOT,
788 "da7219-aad", da7219_aad);
789 if (ret) {
790 dev_err(codec->dev, "Failed to request IRQ: %d\n", ret);
791 return ret;
792 }
793
794 /* Unmask AAD IRQs */
795 memset(mask, 0, DA7219_AAD_IRQ_REG_MAX);
796 regmap_bulk_write(da7219->regmap, DA7219_ACCDET_IRQ_MASK_A,
797 &mask, DA7219_AAD_IRQ_REG_MAX);
798
799 return 0;
800}
801EXPORT_SYMBOL_GPL(da7219_aad_init);
802
803void da7219_aad_exit(struct snd_soc_codec *codec)
804{
805 struct da7219_priv *da7219 = snd_soc_codec_get_drvdata(codec);
806 struct da7219_aad_priv *da7219_aad = da7219->aad;
807 u8 mask[DA7219_AAD_IRQ_REG_MAX];
808
809 /* Mask off AAD IRQs */
810 memset(mask, DA7219_BYTE_MASK, DA7219_AAD_IRQ_REG_MAX);
811 regmap_bulk_write(da7219->regmap, DA7219_ACCDET_IRQ_MASK_A,
812 mask, DA7219_AAD_IRQ_REG_MAX);
813
814 free_irq(da7219_aad->irq, da7219_aad);
815
816 cancel_work_sync(&da7219_aad->btn_det_work);
817 cancel_work_sync(&da7219_aad->hptest_work);
818}
819EXPORT_SYMBOL_GPL(da7219_aad_exit);
820
821MODULE_DESCRIPTION("ASoC DA7219 AAD Driver");
822MODULE_AUTHOR("Adam Thomson <Adam.Thomson.Opensource@diasemi.com>");
823MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/da7219-aad.h b/sound/soc/codecs/da7219-aad.h
new file mode 100644
index 000000000000..4fccf677cd06
--- /dev/null
+++ b/sound/soc/codecs/da7219-aad.h
@@ -0,0 +1,212 @@
1/*
2 * da7219-aad.h - DA7322 ASoC AAD Driver
3 *
4 * Copyright (c) 2015 Dialog Semiconductor Ltd.
5 *
6 * Author: Adam Thomson <Adam.Thomson.Opensource@diasemi.com>
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the
10 * Free Software Foundation; either version 2 of the License, or (at your
11 * option) any later version.
12 */
13
14#ifndef __DA7219_AAD_H
15#define __DA7219_AAD_H
16
17#include <linux/timer.h>
18#include <sound/soc.h>
19#include <sound/jack.h>
20#include <sound/da7219-aad.h>
21
22/*
23 * Registers
24 */
25
26#define DA7219_ACCDET_STATUS_A 0xC0
27#define DA7219_ACCDET_STATUS_B 0xC1
28#define DA7219_ACCDET_IRQ_EVENT_A 0xC2
29#define DA7219_ACCDET_IRQ_EVENT_B 0xC3
30#define DA7219_ACCDET_IRQ_MASK_A 0xC4
31#define DA7219_ACCDET_IRQ_MASK_B 0xC5
32#define DA7219_ACCDET_CONFIG_1 0xC6
33#define DA7219_ACCDET_CONFIG_2 0xC7
34#define DA7219_ACCDET_CONFIG_3 0xC8
35#define DA7219_ACCDET_CONFIG_4 0xC9
36#define DA7219_ACCDET_CONFIG_5 0xCA
37#define DA7219_ACCDET_CONFIG_6 0xCB
38#define DA7219_ACCDET_CONFIG_7 0xCC
39#define DA7219_ACCDET_CONFIG_8 0xCD
40
41
42/*
43 * Bit Fields
44 */
45
46/* DA7219_ACCDET_STATUS_A = 0xC0 */
47#define DA7219_JACK_INSERTION_STS_SHIFT 0
48#define DA7219_JACK_INSERTION_STS_MASK (0x1 << 0)
49#define DA7219_JACK_TYPE_STS_SHIFT 1
50#define DA7219_JACK_TYPE_STS_MASK (0x1 << 1)
51#define DA7219_JACK_PIN_ORDER_STS_SHIFT 2
52#define DA7219_JACK_PIN_ORDER_STS_MASK (0x1 << 2)
53#define DA7219_MICBIAS_UP_STS_SHIFT 3
54#define DA7219_MICBIAS_UP_STS_MASK (0x1 << 3)
55
56/* DA7219_ACCDET_STATUS_B = 0xC1 */
57#define DA7219_BUTTON_TYPE_STS_SHIFT 0
58#define DA7219_BUTTON_TYPE_STS_MASK (0xFF << 0)
59
60/* DA7219_ACCDET_IRQ_EVENT_A = 0xC2 */
61#define DA7219_E_JACK_INSERTED_SHIFT 0
62#define DA7219_E_JACK_INSERTED_MASK (0x1 << 0)
63#define DA7219_E_JACK_REMOVED_SHIFT 1
64#define DA7219_E_JACK_REMOVED_MASK (0x1 << 1)
65#define DA7219_E_JACK_DETECT_COMPLETE_SHIFT 2
66#define DA7219_E_JACK_DETECT_COMPLETE_MASK (0x1 << 2)
67
68/* DA7219_ACCDET_IRQ_EVENT_B = 0xC3 */
69#define DA7219_E_BUTTON_A_PRESSED_SHIFT 0
70#define DA7219_E_BUTTON_A_PRESSED_MASK (0x1 << 0)
71#define DA7219_E_BUTTON_B_PRESSED_SHIFT 1
72#define DA7219_E_BUTTON_B_PRESSED_MASK (0x1 << 1)
73#define DA7219_E_BUTTON_C_PRESSED_SHIFT 2
74#define DA7219_E_BUTTON_C_PRESSED_MASK (0x1 << 2)
75#define DA7219_E_BUTTON_D_PRESSED_SHIFT 3
76#define DA7219_E_BUTTON_D_PRESSED_MASK (0x1 << 3)
77#define DA7219_E_BUTTON_D_RELEASED_SHIFT 4
78#define DA7219_E_BUTTON_D_RELEASED_MASK (0x1 << 4)
79#define DA7219_E_BUTTON_C_RELEASED_SHIFT 5
80#define DA7219_E_BUTTON_C_RELEASED_MASK (0x1 << 5)
81#define DA7219_E_BUTTON_B_RELEASED_SHIFT 6
82#define DA7219_E_BUTTON_B_RELEASED_MASK (0x1 << 6)
83#define DA7219_E_BUTTON_A_RELEASED_SHIFT 7
84#define DA7219_E_BUTTON_A_RELEASED_MASK (0x1 << 7)
85
86/* DA7219_ACCDET_IRQ_MASK_A = 0xC4 */
87#define DA7219_M_JACK_INSERTED_SHIFT 0
88#define DA7219_M_JACK_INSERTED_MASK (0x1 << 0)
89#define DA7219_M_JACK_REMOVED_SHIFT 1
90#define DA7219_M_JACK_REMOVED_MASK (0x1 << 1)
91#define DA7219_M_JACK_DETECT_COMPLETE_SHIFT 2
92#define DA7219_M_JACK_DETECT_COMPLETE_MASK (0x1 << 2)
93
94/* DA7219_ACCDET_IRQ_MASK_B = 0xC5 */
95#define DA7219_M_BUTTON_A_PRESSED_SHIFT 0
96#define DA7219_M_BUTTON_A_PRESSED_MASK (0x1 << 0)
97#define DA7219_M_BUTTON_B_PRESSED_SHIFT 1
98#define DA7219_M_BUTTON_B_PRESSED_MASK (0x1 << 1)
99#define DA7219_M_BUTTON_C_PRESSED_SHIFT 2
100#define DA7219_M_BUTTON_C_PRESSED_MASK (0x1 << 2)
101#define DA7219_M_BUTTON_D_PRESSED_SHIFT 3
102#define DA7219_M_BUTTON_D_PRESSED_MASK (0x1 << 3)
103#define DA7219_M_BUTTON_D_RELEASED_SHIFT 4
104#define DA7219_M_BUTTON_D_RELEASED_MASK (0x1 << 4)
105#define DA7219_M_BUTTON_C_RELEASED_SHIFT 5
106#define DA7219_M_BUTTON_C_RELEASED_MASK (0x1 << 5)
107#define DA7219_M_BUTTON_B_RELEASED_SHIFT 6
108#define DA7219_M_BUTTON_B_RELEASED_MASK (0x1 << 6)
109#define DA7219_M_BUTTON_A_RELEASED_SHIFT 7
110#define DA7219_M_BUTTON_A_RELEASED_MASK (0x1 << 7)
111
112/* DA7219_ACCDET_CONFIG_1 = 0xC6 */
113#define DA7219_ACCDET_EN_SHIFT 0
114#define DA7219_ACCDET_EN_MASK (0x1 << 0)
115#define DA7219_BUTTON_CONFIG_SHIFT 1
116#define DA7219_BUTTON_CONFIG_MASK (0x7 << 1)
117#define DA7219_MIC_DET_THRESH_SHIFT 4
118#define DA7219_MIC_DET_THRESH_MASK (0x3 << 4)
119#define DA7219_JACK_TYPE_DET_EN_SHIFT 6
120#define DA7219_JACK_TYPE_DET_EN_MASK (0x1 << 6)
121#define DA7219_PIN_ORDER_DET_EN_SHIFT 7
122#define DA7219_PIN_ORDER_DET_EN_MASK (0x1 << 7)
123
124/* DA7219_ACCDET_CONFIG_2 = 0xC7 */
125#define DA7219_ACCDET_PAUSE_SHIFT 0
126#define DA7219_ACCDET_PAUSE_MASK (0x1 << 0)
127#define DA7219_JACKDET_DEBOUNCE_SHIFT 1
128#define DA7219_JACKDET_DEBOUNCE_MASK (0x7 << 1)
129#define DA7219_JACK_DETECT_RATE_SHIFT 4
130#define DA7219_JACK_DETECT_RATE_MASK (0x3 << 4)
131#define DA7219_JACKDET_REM_DEB_SHIFT 6
132#define DA7219_JACKDET_REM_DEB_MASK (0x3 << 6)
133
134/* DA7219_ACCDET_CONFIG_3 = 0xC8 */
135#define DA7219_A_D_BUTTON_THRESH_SHIFT 0
136#define DA7219_A_D_BUTTON_THRESH_MASK (0xFF << 0)
137
138/* DA7219_ACCDET_CONFIG_4 = 0xC9 */
139#define DA7219_D_B_BUTTON_THRESH_SHIFT 0
140#define DA7219_D_B_BUTTON_THRESH_MASK (0xFF << 0)
141
142/* DA7219_ACCDET_CONFIG_5 = 0xCA */
143#define DA7219_B_C_BUTTON_THRESH_SHIFT 0
144#define DA7219_B_C_BUTTON_THRESH_MASK (0xFF << 0)
145
146/* DA7219_ACCDET_CONFIG_6 = 0xCB */
147#define DA7219_C_MIC_BUTTON_THRESH_SHIFT 0
148#define DA7219_C_MIC_BUTTON_THRESH_MASK (0xFF << 0)
149
150/* DA7219_ACCDET_CONFIG_7 = 0xCC */
151#define DA7219_BUTTON_AVERAGE_SHIFT 0
152#define DA7219_BUTTON_AVERAGE_MASK (0x3 << 0)
153#define DA7219_ADC_1_BIT_REPEAT_SHIFT 2
154#define DA7219_ADC_1_BIT_REPEAT_MASK (0x3 << 2)
155#define DA7219_PIN_ORDER_FORCE_SHIFT 4
156#define DA7219_PIN_ORDER_FORCE_MASK (0x1 << 4)
157#define DA7219_JACK_TYPE_FORCE_SHIFT 5
158#define DA7219_JACK_TYPE_FORCE_MASK (0x1 << 5)
159
160/* DA7219_ACCDET_CONFIG_8 = 0xCD */
161#define DA7219_HPTEST_EN_SHIFT 0
162#define DA7219_HPTEST_EN_MASK (0x1 << 0)
163#define DA7219_HPTEST_RES_SEL_SHIFT 1
164#define DA7219_HPTEST_RES_SEL_MASK (0x3 << 1)
165#define DA7219_HPTEST_RES_SEL_1KOHMS (0x0 << 1)
166#define DA7219_HPTEST_COMP_SHIFT 4
167#define DA7219_HPTEST_COMP_MASK (0x1 << 4)
168
169
170#define DA7219_AAD_MAX_BUTTONS 4
171#define DA7219_AAD_REPORT_ALL_MASK (SND_JACK_MECHANICAL | \
172 SND_JACK_HEADSET | SND_JACK_LINEOUT | \
173 SND_JACK_BTN_0 | SND_JACK_BTN_1 | \
174 SND_JACK_BTN_2 | SND_JACK_BTN_3)
175
176#define DA7219_AAD_MICBIAS_CHK_DELAY 10
177#define DA7219_AAD_MICBIAS_CHK_RETRIES 5
178
179#define DA7219_AAD_HPTEST_RAMP_FREQ 0x28
180#define DA7219_AAD_HPTEST_PERIOD 65
181
182enum da7219_aad_event_regs {
183 DA7219_AAD_IRQ_REG_A = 0,
184 DA7219_AAD_IRQ_REG_B,
185 DA7219_AAD_IRQ_REG_MAX,
186};
187
188/* Private data */
189struct da7219_aad_priv {
190 struct snd_soc_codec *codec;
191 int irq;
192
193 u8 micbias_pulse_lvl;
194 u32 micbias_pulse_time;
195
196 u8 btn_cfg;
197
198 struct work_struct btn_det_work;
199 struct work_struct hptest_work;
200
201 struct snd_soc_jack *jack;
202 bool jack_inserted;
203};
204
205/* AAD control */
206void da7219_aad_jack_det(struct snd_soc_codec *codec, struct snd_soc_jack *jack);
207
208/* Init/Exit */
209int da7219_aad_init(struct snd_soc_codec *codec);
210void da7219_aad_exit(struct snd_soc_codec *codec);
211
212#endif /* __DA7219_AAD_H */
diff --git a/sound/soc/codecs/da7219.c b/sound/soc/codecs/da7219.c
new file mode 100644
index 000000000000..f238c1e8a69c
--- /dev/null
+++ b/sound/soc/codecs/da7219.c
@@ -0,0 +1,1955 @@
1/*
2 * da7219.c - DA7219 ALSA SoC Codec Driver
3 *
4 * Copyright (c) 2015 Dialog Semiconductor
5 *
6 * Author: Adam Thomson <Adam.Thomson.Opensource@diasemi.com>
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the
10 * Free Software Foundation; either version 2 of the License, or (at your
11 * option) any later version.
12 */
13
14#include <linux/clk.h>
15#include <linux/i2c.h>
16#include <linux/of_device.h>
17#include <linux/regmap.h>
18#include <linux/slab.h>
19#include <linux/pm.h>
20#include <linux/module.h>
21#include <linux/delay.h>
22#include <linux/regulator/consumer.h>
23#include <sound/pcm.h>
24#include <sound/pcm_params.h>
25#include <sound/soc.h>
26#include <sound/soc-dapm.h>
27#include <sound/initval.h>
28#include <sound/tlv.h>
29#include <asm/div64.h>
30
31#include <sound/da7219.h>
32#include "da7219.h"
33#include "da7219-aad.h"
34
35
36/*
37 * TLVs and Enums
38 */
39
40/* Input TLVs */
41static const DECLARE_TLV_DB_SCALE(da7219_mic_gain_tlv, -600, 600, 0);
42static const DECLARE_TLV_DB_SCALE(da7219_mixin_gain_tlv, -450, 150, 0);
43static const DECLARE_TLV_DB_SCALE(da7219_adc_dig_gain_tlv, -8325, 75, 0);
44static const DECLARE_TLV_DB_SCALE(da7219_alc_threshold_tlv, -9450, 150, 0);
45static const DECLARE_TLV_DB_SCALE(da7219_alc_gain_tlv, 0, 600, 0);
46static const DECLARE_TLV_DB_SCALE(da7219_alc_ana_gain_tlv, 0, 600, 0);
47static const DECLARE_TLV_DB_SCALE(da7219_sidetone_gain_tlv, -4200, 300, 0);
48static const DECLARE_TLV_DB_SCALE(da7219_tonegen_gain_tlv, -4500, 300, 0);
49
50/* Output TLVs */
51static const DECLARE_TLV_DB_SCALE(da7219_dac_eq_band_tlv, -1050, 150, 0);
52
53static const DECLARE_TLV_DB_RANGE(da7219_dac_dig_gain_tlv,
54 0x0, 0x07, TLV_DB_SCALE_ITEM(TLV_DB_GAIN_MUTE, 0, 1),
55 /* -77.25dB to 12dB */
56 0x08, 0x7f, TLV_DB_SCALE_ITEM(-7725, 75, 0)
57);
58
59static const DECLARE_TLV_DB_SCALE(da7219_dac_ng_threshold_tlv, -10200, 600, 0);
60static const DECLARE_TLV_DB_SCALE(da7219_hp_gain_tlv, -5700, 100, 0);
61
62/* Input Enums */
63static const char * const da7219_alc_attack_rate_txt[] = {
64 "7.33/fs", "14.66/fs", "29.32/fs", "58.64/fs", "117.3/fs", "234.6/fs",
65 "469.1/fs", "938.2/fs", "1876/fs", "3753/fs", "7506/fs", "15012/fs",
66 "30024/fs"
67};
68
69static const struct soc_enum da7219_alc_attack_rate =
70 SOC_ENUM_SINGLE(DA7219_ALC_CTRL2, DA7219_ALC_ATTACK_SHIFT,
71 DA7219_ALC_ATTACK_MAX, da7219_alc_attack_rate_txt);
72
73static const char * const da7219_alc_release_rate_txt[] = {
74 "28.66/fs", "57.33/fs", "114.6/fs", "229.3/fs", "458.6/fs", "917.1/fs",
75 "1834/fs", "3668/fs", "7337/fs", "14674/fs", "29348/fs"
76};
77
78static const struct soc_enum da7219_alc_release_rate =
79 SOC_ENUM_SINGLE(DA7219_ALC_CTRL2, DA7219_ALC_RELEASE_SHIFT,
80 DA7219_ALC_RELEASE_MAX, da7219_alc_release_rate_txt);
81
82static const char * const da7219_alc_hold_time_txt[] = {
83 "62/fs", "124/fs", "248/fs", "496/fs", "992/fs", "1984/fs", "3968/fs",
84 "7936/fs", "15872/fs", "31744/fs", "63488/fs", "126976/fs",
85 "253952/fs", "507904/fs", "1015808/fs", "2031616/fs"
86};
87
88static const struct soc_enum da7219_alc_hold_time =
89 SOC_ENUM_SINGLE(DA7219_ALC_CTRL3, DA7219_ALC_HOLD_SHIFT,
90 DA7219_ALC_HOLD_MAX, da7219_alc_hold_time_txt);
91
92static const char * const da7219_alc_env_rate_txt[] = {
93 "1/4", "1/16", "1/256", "1/65536"
94};
95
96static const struct soc_enum da7219_alc_env_attack_rate =
97 SOC_ENUM_SINGLE(DA7219_ALC_CTRL3, DA7219_ALC_INTEG_ATTACK_SHIFT,
98 DA7219_ALC_INTEG_MAX, da7219_alc_env_rate_txt);
99
100static const struct soc_enum da7219_alc_env_release_rate =
101 SOC_ENUM_SINGLE(DA7219_ALC_CTRL3, DA7219_ALC_INTEG_RELEASE_SHIFT,
102 DA7219_ALC_INTEG_MAX, da7219_alc_env_rate_txt);
103
104static const char * const da7219_alc_anticlip_step_txt[] = {
105 "0.034dB/fs", "0.068dB/fs", "0.136dB/fs", "0.272dB/fs"
106};
107
108static const struct soc_enum da7219_alc_anticlip_step =
109 SOC_ENUM_SINGLE(DA7219_ALC_ANTICLIP_CTRL,
110 DA7219_ALC_ANTICLIP_STEP_SHIFT,
111 DA7219_ALC_ANTICLIP_STEP_MAX,
112 da7219_alc_anticlip_step_txt);
113
114/* Input/Output Enums */
115static const char * const da7219_gain_ramp_rate_txt[] = {
116 "Nominal Rate * 8", "Nominal Rate", "Nominal Rate / 8",
117 "Nominal Rate / 16"
118};
119
120static const struct soc_enum da7219_gain_ramp_rate =
121 SOC_ENUM_SINGLE(DA7219_GAIN_RAMP_CTRL, DA7219_GAIN_RAMP_RATE_SHIFT,
122 DA7219_GAIN_RAMP_RATE_MAX, da7219_gain_ramp_rate_txt);
123
124static const char * const da7219_hpf_mode_txt[] = {
125 "Disabled", "Audio", "Voice"
126};
127
128static const unsigned int da7219_hpf_mode_val[] = {
129 DA7219_HPF_DISABLED, DA7219_HPF_AUDIO_EN, DA7219_HPF_VOICE_EN,
130};
131
132static const struct soc_enum da7219_adc_hpf_mode =
133 SOC_VALUE_ENUM_SINGLE(DA7219_ADC_FILTERS1, DA7219_HPF_MODE_SHIFT,
134 DA7219_HPF_MODE_MASK, DA7219_HPF_MODE_MAX,
135 da7219_hpf_mode_txt, da7219_hpf_mode_val);
136
137static const struct soc_enum da7219_dac_hpf_mode =
138 SOC_VALUE_ENUM_SINGLE(DA7219_DAC_FILTERS1, DA7219_HPF_MODE_SHIFT,
139 DA7219_HPF_MODE_MASK, DA7219_HPF_MODE_MAX,
140 da7219_hpf_mode_txt, da7219_hpf_mode_val);
141
142static const char * const da7219_audio_hpf_corner_txt[] = {
143 "2Hz", "4Hz", "8Hz", "16Hz"
144};
145
146static const struct soc_enum da7219_adc_audio_hpf_corner =
147 SOC_ENUM_SINGLE(DA7219_ADC_FILTERS1,
148 DA7219_ADC_AUDIO_HPF_CORNER_SHIFT,
149 DA7219_AUDIO_HPF_CORNER_MAX,
150 da7219_audio_hpf_corner_txt);
151
152static const struct soc_enum da7219_dac_audio_hpf_corner =
153 SOC_ENUM_SINGLE(DA7219_DAC_FILTERS1,
154 DA7219_DAC_AUDIO_HPF_CORNER_SHIFT,
155 DA7219_AUDIO_HPF_CORNER_MAX,
156 da7219_audio_hpf_corner_txt);
157
158static const char * const da7219_voice_hpf_corner_txt[] = {
159 "2.5Hz", "25Hz", "50Hz", "100Hz", "150Hz", "200Hz", "300Hz", "400Hz"
160};
161
162static const struct soc_enum da7219_adc_voice_hpf_corner =
163 SOC_ENUM_SINGLE(DA7219_ADC_FILTERS1,
164 DA7219_ADC_VOICE_HPF_CORNER_SHIFT,
165 DA7219_VOICE_HPF_CORNER_MAX,
166 da7219_voice_hpf_corner_txt);
167
168static const struct soc_enum da7219_dac_voice_hpf_corner =
169 SOC_ENUM_SINGLE(DA7219_DAC_FILTERS1,
170 DA7219_DAC_VOICE_HPF_CORNER_SHIFT,
171 DA7219_VOICE_HPF_CORNER_MAX,
172 da7219_voice_hpf_corner_txt);
173
174static const char * const da7219_tonegen_dtmf_key_txt[] = {
175 "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D",
176 "*", "#"
177};
178
179static const struct soc_enum da7219_tonegen_dtmf_key =
180 SOC_ENUM_SINGLE(DA7219_TONE_GEN_CFG1, DA7219_DTMF_REG_SHIFT,
181 DA7219_DTMF_REG_MAX, da7219_tonegen_dtmf_key_txt);
182
183static const char * const da7219_tonegen_swg_sel_txt[] = {
184 "Sum", "SWG1", "SWG2", "SWG1_1-Cos"
185};
186
187static const struct soc_enum da7219_tonegen_swg_sel =
188 SOC_ENUM_SINGLE(DA7219_TONE_GEN_CFG2, DA7219_SWG_SEL_SHIFT,
189 DA7219_SWG_SEL_MAX, da7219_tonegen_swg_sel_txt);
190
191/* Output Enums */
192static const char * const da7219_dac_softmute_rate_txt[] = {
193 "1 Sample", "2 Samples", "4 Samples", "8 Samples", "16 Samples",
194 "32 Samples", "64 Samples"
195};
196
197static const struct soc_enum da7219_dac_softmute_rate =
198 SOC_ENUM_SINGLE(DA7219_DAC_FILTERS5, DA7219_DAC_SOFTMUTE_RATE_SHIFT,
199 DA7219_DAC_SOFTMUTE_RATE_MAX,
200 da7219_dac_softmute_rate_txt);
201
202static const char * const da7219_dac_ng_setup_time_txt[] = {
203 "256 Samples", "512 Samples", "1024 Samples", "2048 Samples"
204};
205
206static const struct soc_enum da7219_dac_ng_setup_time =
207 SOC_ENUM_SINGLE(DA7219_DAC_NG_SETUP_TIME,
208 DA7219_DAC_NG_SETUP_TIME_SHIFT,
209 DA7219_DAC_NG_SETUP_TIME_MAX,
210 da7219_dac_ng_setup_time_txt);
211
212static const char * const da7219_dac_ng_rampup_txt[] = {
213 "0.22ms/dB", "0.0138ms/dB"
214};
215
216static const struct soc_enum da7219_dac_ng_rampup_rate =
217 SOC_ENUM_SINGLE(DA7219_DAC_NG_SETUP_TIME,
218 DA7219_DAC_NG_RAMPUP_RATE_SHIFT,
219 DA7219_DAC_NG_RAMP_RATE_MAX,
220 da7219_dac_ng_rampup_txt);
221
222static const char * const da7219_dac_ng_rampdown_txt[] = {
223 "0.88ms/dB", "14.08ms/dB"
224};
225
226static const struct soc_enum da7219_dac_ng_rampdown_rate =
227 SOC_ENUM_SINGLE(DA7219_DAC_NG_SETUP_TIME,
228 DA7219_DAC_NG_RAMPDN_RATE_SHIFT,
229 DA7219_DAC_NG_RAMP_RATE_MAX,
230 da7219_dac_ng_rampdown_txt);
231
232
233static const char * const da7219_cp_track_mode_txt[] = {
234 "Largest Volume", "DAC Volume", "Signal Magnitude"
235};
236
237static const unsigned int da7219_cp_track_mode_val[] = {
238 DA7219_CP_MCHANGE_LARGEST_VOL, DA7219_CP_MCHANGE_DAC_VOL,
239 DA7219_CP_MCHANGE_SIG_MAG
240};
241
242static const struct soc_enum da7219_cp_track_mode =
243 SOC_VALUE_ENUM_SINGLE(DA7219_CP_CTRL, DA7219_CP_MCHANGE_SHIFT,
244 DA7219_CP_MCHANGE_REL_MASK, DA7219_CP_MCHANGE_MAX,
245 da7219_cp_track_mode_txt,
246 da7219_cp_track_mode_val);
247
248
249/*
250 * Control Functions
251 */
252
253/* Locked Kcontrol calls */
254static int da7219_volsw_locked_get(struct snd_kcontrol *kcontrol,
255 struct snd_ctl_elem_value *ucontrol)
256{
257 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
258 struct da7219_priv *da7219 = snd_soc_codec_get_drvdata(codec);
259 int ret;
260
261 mutex_lock(&da7219->lock);
262 ret = snd_soc_get_volsw(kcontrol, ucontrol);
263 mutex_unlock(&da7219->lock);
264
265 return ret;
266}
267
268static int da7219_volsw_locked_put(struct snd_kcontrol *kcontrol,
269 struct snd_ctl_elem_value *ucontrol)
270{
271 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
272 struct da7219_priv *da7219 = snd_soc_codec_get_drvdata(codec);
273 int ret;
274
275 mutex_lock(&da7219->lock);
276 ret = snd_soc_put_volsw(kcontrol, ucontrol);
277 mutex_unlock(&da7219->lock);
278
279 return ret;
280}
281
282static int da7219_enum_locked_get(struct snd_kcontrol *kcontrol,
283 struct snd_ctl_elem_value *ucontrol)
284{
285 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
286 struct da7219_priv *da7219 = snd_soc_codec_get_drvdata(codec);
287 int ret;
288
289 mutex_lock(&da7219->lock);
290 ret = snd_soc_get_enum_double(kcontrol, ucontrol);
291 mutex_unlock(&da7219->lock);
292
293 return ret;
294}
295
296static int da7219_enum_locked_put(struct snd_kcontrol *kcontrol,
297 struct snd_ctl_elem_value *ucontrol)
298{
299 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
300 struct da7219_priv *da7219 = snd_soc_codec_get_drvdata(codec);
301 int ret;
302
303 mutex_lock(&da7219->lock);
304 ret = snd_soc_put_enum_double(kcontrol, ucontrol);
305 mutex_unlock(&da7219->lock);
306
307 return ret;
308}
309
310/* ALC */
311static void da7219_alc_calib(struct snd_soc_codec *codec)
312{
313 u8 mic_ctrl, mixin_ctrl, adc_ctrl, calib_ctrl;
314
315 /* Save current state of mic control register */
316 mic_ctrl = snd_soc_read(codec, DA7219_MIC_1_CTRL);
317
318 /* Save current state of input mixer control register */
319 mixin_ctrl = snd_soc_read(codec, DA7219_MIXIN_L_CTRL);
320
321 /* Save current state of input ADC control register */
322 adc_ctrl = snd_soc_read(codec, DA7219_ADC_L_CTRL);
323
324 /* Enable then Mute MIC PGAs */
325 snd_soc_update_bits(codec, DA7219_MIC_1_CTRL, DA7219_MIC_1_AMP_EN_MASK,
326 DA7219_MIC_1_AMP_EN_MASK);
327 snd_soc_update_bits(codec, DA7219_MIC_1_CTRL,
328 DA7219_MIC_1_AMP_MUTE_EN_MASK,
329 DA7219_MIC_1_AMP_MUTE_EN_MASK);
330
331 /* Enable input mixers unmuted */
332 snd_soc_update_bits(codec, DA7219_MIXIN_L_CTRL,
333 DA7219_MIXIN_L_AMP_EN_MASK |
334 DA7219_MIXIN_L_AMP_MUTE_EN_MASK,
335 DA7219_MIXIN_L_AMP_EN_MASK);
336
337 /* Enable input filters unmuted */
338 snd_soc_update_bits(codec, DA7219_ADC_L_CTRL,
339 DA7219_ADC_L_MUTE_EN_MASK | DA7219_ADC_L_EN_MASK,
340 DA7219_ADC_L_EN_MASK);
341
342 /* Perform auto calibration */
343 snd_soc_update_bits(codec, DA7219_ALC_CTRL1,
344 DA7219_ALC_AUTO_CALIB_EN_MASK,
345 DA7219_ALC_AUTO_CALIB_EN_MASK);
346 do {
347 calib_ctrl = snd_soc_read(codec, DA7219_ALC_CTRL1);
348 } while (calib_ctrl & DA7219_ALC_AUTO_CALIB_EN_MASK);
349
350 /* If auto calibration fails, disable DC offset, hybrid ALC */
351 if (calib_ctrl & DA7219_ALC_CALIB_OVERFLOW_MASK) {
352 dev_warn(codec->dev,
353 "ALC auto calibration failed with overflow\n");
354 snd_soc_update_bits(codec, DA7219_ALC_CTRL1,
355 DA7219_ALC_OFFSET_EN_MASK |
356 DA7219_ALC_SYNC_MODE_MASK, 0);
357 } else {
358 /* Enable DC offset cancellation, hybrid mode */
359 snd_soc_update_bits(codec, DA7219_ALC_CTRL1,
360 DA7219_ALC_OFFSET_EN_MASK |
361 DA7219_ALC_SYNC_MODE_MASK,
362 DA7219_ALC_OFFSET_EN_MASK |
363 DA7219_ALC_SYNC_MODE_MASK);
364 }
365
366 /* Restore input filter control register to original state */
367 snd_soc_write(codec, DA7219_ADC_L_CTRL, adc_ctrl);
368
369 /* Restore input mixer control registers to original state */
370 snd_soc_write(codec, DA7219_MIXIN_L_CTRL, mixin_ctrl);
371
372 /* Restore MIC control registers to original states */
373 snd_soc_write(codec, DA7219_MIC_1_CTRL, mic_ctrl);
374}
375
376static int da7219_mixin_gain_put(struct snd_kcontrol *kcontrol,
377 struct snd_ctl_elem_value *ucontrol)
378{
379 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
380 struct da7219_priv *da7219 = snd_soc_codec_get_drvdata(codec);
381 int ret;
382
383 ret = snd_soc_put_volsw(kcontrol, ucontrol);
384
385 /*
386 * If ALC in operation and value of control has been updated,
387 * make sure calibrated offsets are updated.
388 */
389 if ((ret == 1) && (da7219->alc_en))
390 da7219_alc_calib(codec);
391
392 return ret;
393}
394
395static int da7219_alc_sw_put(struct snd_kcontrol *kcontrol,
396 struct snd_ctl_elem_value *ucontrol)
397{
398 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
399 struct da7219_priv *da7219 = snd_soc_codec_get_drvdata(codec);
400
401
402 /* Force ALC offset calibration if enabling ALC */
403 if ((ucontrol->value.integer.value[0]) && (!da7219->alc_en)) {
404 da7219_alc_calib(codec);
405 da7219->alc_en = true;
406 } else {
407 da7219->alc_en = false;
408 }
409
410 return snd_soc_put_volsw(kcontrol, ucontrol);
411}
412
413/* ToneGen */
414static int da7219_tonegen_freq_get(struct snd_kcontrol *kcontrol,
415 struct snd_ctl_elem_value *ucontrol)
416{
417 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
418 struct da7219_priv *da7219 = snd_soc_codec_get_drvdata(codec);
419 struct soc_mixer_control *mixer_ctrl =
420 (struct soc_mixer_control *) kcontrol->private_value;
421 unsigned int reg = mixer_ctrl->reg;
422 u16 val;
423 int ret;
424
425 mutex_lock(&da7219->lock);
426 ret = regmap_raw_read(da7219->regmap, reg, &val, sizeof(val));
427 mutex_unlock(&da7219->lock);
428
429 if (ret)
430 return ret;
431
432 /*
433 * Frequency value spans two 8-bit registers, lower then upper byte.
434 * Therefore we need to convert to host endianness here.
435 */
436 ucontrol->value.integer.value[0] = le16_to_cpu(val);
437
438 return 0;
439}
440
441static int da7219_tonegen_freq_put(struct snd_kcontrol *kcontrol,
442 struct snd_ctl_elem_value *ucontrol)
443{
444 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
445 struct da7219_priv *da7219 = snd_soc_codec_get_drvdata(codec);
446 struct soc_mixer_control *mixer_ctrl =
447 (struct soc_mixer_control *) kcontrol->private_value;
448 unsigned int reg = mixer_ctrl->reg;
449 u16 val;
450 int ret;
451
452 /*
453 * Frequency value spans two 8-bit registers, lower then upper byte.
454 * Therefore we need to convert to little endian here to align with
455 * HW registers.
456 */
457 val = cpu_to_le16(ucontrol->value.integer.value[0]);
458
459 mutex_lock(&da7219->lock);
460 ret = regmap_raw_write(da7219->regmap, reg, &val, sizeof(val));
461 mutex_unlock(&da7219->lock);
462
463 return ret;
464}
465
466
467/*
468 * KControls
469 */
470
471static const struct snd_kcontrol_new da7219_snd_controls[] = {
472 /* Mics */
473 SOC_SINGLE_TLV("Mic Volume", DA7219_MIC_1_GAIN,
474 DA7219_MIC_1_AMP_GAIN_SHIFT, DA7219_MIC_1_AMP_GAIN_MAX,
475 DA7219_NO_INVERT, da7219_mic_gain_tlv),
476 SOC_SINGLE("Mic Switch", DA7219_MIC_1_CTRL,
477 DA7219_MIC_1_AMP_MUTE_EN_SHIFT, DA7219_SWITCH_EN_MAX,
478 DA7219_INVERT),
479
480 /* Mixer Input */
481 SOC_SINGLE_EXT_TLV("Mixin Volume", DA7219_MIXIN_L_GAIN,
482 DA7219_MIXIN_L_AMP_GAIN_SHIFT,
483 DA7219_MIXIN_L_AMP_GAIN_MAX, DA7219_NO_INVERT,
484 snd_soc_get_volsw, da7219_mixin_gain_put,
485 da7219_mixin_gain_tlv),
486 SOC_SINGLE("Mixin Switch", DA7219_MIXIN_L_CTRL,
487 DA7219_MIXIN_L_AMP_MUTE_EN_SHIFT, DA7219_SWITCH_EN_MAX,
488 DA7219_INVERT),
489 SOC_SINGLE("Mixin Gain Ramp Switch", DA7219_MIXIN_L_CTRL,
490 DA7219_MIXIN_L_AMP_RAMP_EN_SHIFT, DA7219_SWITCH_EN_MAX,
491 DA7219_NO_INVERT),
492 SOC_SINGLE("Mixin ZC Gain Switch", DA7219_MIXIN_L_CTRL,
493 DA7219_MIXIN_L_AMP_ZC_EN_SHIFT, DA7219_SWITCH_EN_MAX,
494 DA7219_NO_INVERT),
495
496 /* ADC */
497 SOC_SINGLE_TLV("Capture Digital Volume", DA7219_ADC_L_GAIN,
498 DA7219_ADC_L_DIGITAL_GAIN_SHIFT,
499 DA7219_ADC_L_DIGITAL_GAIN_MAX, DA7219_NO_INVERT,
500 da7219_adc_dig_gain_tlv),
501 SOC_SINGLE("Capture Digital Switch", DA7219_ADC_L_CTRL,
502 DA7219_ADC_L_MUTE_EN_SHIFT, DA7219_SWITCH_EN_MAX,
503 DA7219_INVERT),
504 SOC_SINGLE("Capture Digital Gain Ramp Switch", DA7219_ADC_L_CTRL,
505 DA7219_ADC_L_RAMP_EN_SHIFT, DA7219_SWITCH_EN_MAX,
506 DA7219_NO_INVERT),
507
508 /* ALC */
509 SOC_ENUM("ALC Attack Rate", da7219_alc_attack_rate),
510 SOC_ENUM("ALC Release Rate", da7219_alc_release_rate),
511 SOC_ENUM("ALC Hold Time", da7219_alc_hold_time),
512 SOC_ENUM("ALC Envelope Attack Rate", da7219_alc_env_attack_rate),
513 SOC_ENUM("ALC Envelope Release Rate", da7219_alc_env_release_rate),
514 SOC_SINGLE_TLV("ALC Noise Threshold", DA7219_ALC_NOISE,
515 DA7219_ALC_NOISE_SHIFT, DA7219_ALC_THRESHOLD_MAX,
516 DA7219_INVERT, da7219_alc_threshold_tlv),
517 SOC_SINGLE_TLV("ALC Min Threshold", DA7219_ALC_TARGET_MIN,
518 DA7219_ALC_THRESHOLD_MIN_SHIFT, DA7219_ALC_THRESHOLD_MAX,
519 DA7219_INVERT, da7219_alc_threshold_tlv),
520 SOC_SINGLE_TLV("ALC Max Threshold", DA7219_ALC_TARGET_MAX,
521 DA7219_ALC_THRESHOLD_MAX_SHIFT, DA7219_ALC_THRESHOLD_MAX,
522 DA7219_INVERT, da7219_alc_threshold_tlv),
523 SOC_SINGLE_TLV("ALC Max Attenuation", DA7219_ALC_GAIN_LIMITS,
524 DA7219_ALC_ATTEN_MAX_SHIFT, DA7219_ALC_ATTEN_GAIN_MAX,
525 DA7219_NO_INVERT, da7219_alc_gain_tlv),
526 SOC_SINGLE_TLV("ALC Max Volume", DA7219_ALC_GAIN_LIMITS,
527 DA7219_ALC_GAIN_MAX_SHIFT, DA7219_ALC_ATTEN_GAIN_MAX,
528 DA7219_NO_INVERT, da7219_alc_gain_tlv),
529 SOC_SINGLE_RANGE_TLV("ALC Min Analog Volume", DA7219_ALC_ANA_GAIN_LIMITS,
530 DA7219_ALC_ANA_GAIN_MIN_SHIFT,
531 DA7219_ALC_ANA_GAIN_MIN, DA7219_ALC_ANA_GAIN_MAX,
532 DA7219_NO_INVERT, da7219_alc_ana_gain_tlv),
533 SOC_SINGLE_RANGE_TLV("ALC Max Analog Volume", DA7219_ALC_ANA_GAIN_LIMITS,
534 DA7219_ALC_ANA_GAIN_MAX_SHIFT,
535 DA7219_ALC_ANA_GAIN_MIN, DA7219_ALC_ANA_GAIN_MAX,
536 DA7219_NO_INVERT, da7219_alc_ana_gain_tlv),
537 SOC_ENUM("ALC Anticlip Step", da7219_alc_anticlip_step),
538 SOC_SINGLE("ALC Anticlip Switch", DA7219_ALC_ANTICLIP_CTRL,
539 DA7219_ALC_ANTIPCLIP_EN_SHIFT, DA7219_SWITCH_EN_MAX,
540 DA7219_NO_INVERT),
541 SOC_SINGLE_EXT("ALC Switch", DA7219_ALC_CTRL1, DA7219_ALC_EN_SHIFT,
542 DA7219_SWITCH_EN_MAX, DA7219_NO_INVERT,
543 snd_soc_get_volsw, da7219_alc_sw_put),
544
545 /* Input High-Pass Filters */
546 SOC_ENUM("ADC HPF Mode", da7219_adc_hpf_mode),
547 SOC_ENUM("ADC HPF Corner Audio", da7219_adc_audio_hpf_corner),
548 SOC_ENUM("ADC HPF Corner Voice", da7219_adc_voice_hpf_corner),
549
550 /* Sidetone Filter */
551 SOC_SINGLE_TLV("Sidetone Volume", DA7219_SIDETONE_GAIN,
552 DA7219_SIDETONE_GAIN_SHIFT, DA7219_SIDETONE_GAIN_MAX,
553 DA7219_NO_INVERT, da7219_sidetone_gain_tlv),
554 SOC_SINGLE("Sidetone Switch", DA7219_SIDETONE_CTRL,
555 DA7219_SIDETONE_MUTE_EN_SHIFT, DA7219_SWITCH_EN_MAX,
556 DA7219_INVERT),
557
558 /* Tone Generator */
559 SOC_SINGLE_EXT_TLV("ToneGen Volume", DA7219_TONE_GEN_CFG2,
560 DA7219_TONE_GEN_GAIN_SHIFT, DA7219_TONE_GEN_GAIN_MAX,
561 DA7219_NO_INVERT, da7219_volsw_locked_get,
562 da7219_volsw_locked_put, da7219_tonegen_gain_tlv),
563 SOC_ENUM_EXT("ToneGen DTMF Key", da7219_tonegen_dtmf_key,
564 da7219_enum_locked_get, da7219_enum_locked_put),
565 SOC_SINGLE_EXT("ToneGen DTMF Switch", DA7219_TONE_GEN_CFG1,
566 DA7219_DTMF_EN_SHIFT, DA7219_SWITCH_EN_MAX,
567 DA7219_NO_INVERT, da7219_volsw_locked_get,
568 da7219_volsw_locked_put),
569 SOC_ENUM_EXT("ToneGen Sinewave Gen Type", da7219_tonegen_swg_sel,
570 da7219_enum_locked_get, da7219_enum_locked_put),
571 SOC_SINGLE_EXT("ToneGen Sinewave1 Freq", DA7219_TONE_GEN_FREQ1_L,
572 DA7219_FREQ1_L_SHIFT, DA7219_FREQ_MAX, DA7219_NO_INVERT,
573 da7219_tonegen_freq_get, da7219_tonegen_freq_put),
574 SOC_SINGLE_EXT("ToneGen Sinewave2 Freq", DA7219_TONE_GEN_FREQ2_L,
575 DA7219_FREQ2_L_SHIFT, DA7219_FREQ_MAX, DA7219_NO_INVERT,
576 da7219_tonegen_freq_get, da7219_tonegen_freq_put),
577 SOC_SINGLE_EXT("ToneGen On Time", DA7219_TONE_GEN_ON_PER,
578 DA7219_BEEP_ON_PER_SHIFT, DA7219_BEEP_ON_OFF_MAX,
579 DA7219_NO_INVERT, da7219_volsw_locked_get,
580 da7219_volsw_locked_put),
581 SOC_SINGLE("ToneGen Off Time", DA7219_TONE_GEN_OFF_PER,
582 DA7219_BEEP_OFF_PER_SHIFT, DA7219_BEEP_ON_OFF_MAX,
583 DA7219_NO_INVERT),
584
585 /* Gain ramping */
586 SOC_ENUM("Gain Ramp Rate", da7219_gain_ramp_rate),
587
588 /* DAC High-Pass Filter */
589 SOC_ENUM_EXT("DAC HPF Mode", da7219_dac_hpf_mode,
590 da7219_enum_locked_get, da7219_enum_locked_put),
591 SOC_ENUM("DAC HPF Corner Audio", da7219_dac_audio_hpf_corner),
592 SOC_ENUM("DAC HPF Corner Voice", da7219_dac_voice_hpf_corner),
593
594 /* DAC 5-Band Equaliser */
595 SOC_SINGLE_TLV("DAC EQ Band1 Volume", DA7219_DAC_FILTERS2,
596 DA7219_DAC_EQ_BAND1_SHIFT, DA7219_DAC_EQ_BAND_MAX,
597 DA7219_NO_INVERT, da7219_dac_eq_band_tlv),
598 SOC_SINGLE_TLV("DAC EQ Band2 Volume", DA7219_DAC_FILTERS2,
599 DA7219_DAC_EQ_BAND2_SHIFT, DA7219_DAC_EQ_BAND_MAX,
600 DA7219_NO_INVERT, da7219_dac_eq_band_tlv),
601 SOC_SINGLE_TLV("DAC EQ Band3 Volume", DA7219_DAC_FILTERS3,
602 DA7219_DAC_EQ_BAND3_SHIFT, DA7219_DAC_EQ_BAND_MAX,
603 DA7219_NO_INVERT, da7219_dac_eq_band_tlv),
604 SOC_SINGLE_TLV("DAC EQ Band4 Volume", DA7219_DAC_FILTERS3,
605 DA7219_DAC_EQ_BAND4_SHIFT, DA7219_DAC_EQ_BAND_MAX,
606 DA7219_NO_INVERT, da7219_dac_eq_band_tlv),
607 SOC_SINGLE_TLV("DAC EQ Band5 Volume", DA7219_DAC_FILTERS4,
608 DA7219_DAC_EQ_BAND5_SHIFT, DA7219_DAC_EQ_BAND_MAX,
609 DA7219_NO_INVERT, da7219_dac_eq_band_tlv),
610 SOC_SINGLE_EXT("DAC EQ Switch", DA7219_DAC_FILTERS4,
611 DA7219_DAC_EQ_EN_SHIFT, DA7219_SWITCH_EN_MAX,
612 DA7219_NO_INVERT, da7219_volsw_locked_get,
613 da7219_volsw_locked_put),
614
615 /* DAC Softmute */
616 SOC_ENUM("DAC Soft Mute Rate", da7219_dac_softmute_rate),
617 SOC_SINGLE_EXT("DAC Soft Mute Switch", DA7219_DAC_FILTERS5,
618 DA7219_DAC_SOFTMUTE_EN_SHIFT, DA7219_SWITCH_EN_MAX,
619 DA7219_NO_INVERT, da7219_volsw_locked_get,
620 da7219_volsw_locked_put),
621
622 /* DAC Noise Gate */
623 SOC_ENUM("DAC NG Setup Time", da7219_dac_ng_setup_time),
624 SOC_ENUM("DAC NG Rampup Rate", da7219_dac_ng_rampup_rate),
625 SOC_ENUM("DAC NG Rampdown Rate", da7219_dac_ng_rampdown_rate),
626 SOC_SINGLE_TLV("DAC NG Off Threshold", DA7219_DAC_NG_OFF_THRESH,
627 DA7219_DAC_NG_OFF_THRESHOLD_SHIFT,
628 DA7219_DAC_NG_THRESHOLD_MAX, DA7219_NO_INVERT,
629 da7219_dac_ng_threshold_tlv),
630 SOC_SINGLE_TLV("DAC NG On Threshold", DA7219_DAC_NG_ON_THRESH,
631 DA7219_DAC_NG_ON_THRESHOLD_SHIFT,
632 DA7219_DAC_NG_THRESHOLD_MAX, DA7219_NO_INVERT,
633 da7219_dac_ng_threshold_tlv),
634 SOC_SINGLE("DAC NG Switch", DA7219_DAC_NG_CTRL, DA7219_DAC_NG_EN_SHIFT,
635 DA7219_SWITCH_EN_MAX, DA7219_NO_INVERT),
636
637 /* DACs */
638 SOC_DOUBLE_R_EXT_TLV("Playback Digital Volume", DA7219_DAC_L_GAIN,
639 DA7219_DAC_R_GAIN, DA7219_DAC_L_DIGITAL_GAIN_SHIFT,
640 DA7219_DAC_DIGITAL_GAIN_MAX, DA7219_NO_INVERT,
641 da7219_volsw_locked_get, da7219_volsw_locked_put,
642 da7219_dac_dig_gain_tlv),
643 SOC_DOUBLE_R_EXT("Playback Digital Switch", DA7219_DAC_L_CTRL,
644 DA7219_DAC_R_CTRL, DA7219_DAC_L_MUTE_EN_SHIFT,
645 DA7219_SWITCH_EN_MAX, DA7219_INVERT,
646 da7219_volsw_locked_get, da7219_volsw_locked_put),
647 SOC_DOUBLE_R("Playback Digital Gain Ramp Switch", DA7219_DAC_L_CTRL,
648 DA7219_DAC_R_CTRL, DA7219_DAC_L_RAMP_EN_SHIFT,
649 DA7219_SWITCH_EN_MAX, DA7219_NO_INVERT),
650
651 /* CP */
652 SOC_ENUM("Charge Pump Track Mode", da7219_cp_track_mode),
653 SOC_SINGLE("Charge Pump Threshold", DA7219_CP_VOL_THRESHOLD1,
654 DA7219_CP_THRESH_VDD2_SHIFT, DA7219_CP_THRESH_VDD2_MAX,
655 DA7219_NO_INVERT),
656
657 /* Headphones */
658 SOC_DOUBLE_R_EXT_TLV("Headphone Volume", DA7219_HP_L_GAIN,
659 DA7219_HP_R_GAIN, DA7219_HP_L_AMP_GAIN_SHIFT,
660 DA7219_HP_AMP_GAIN_MAX, DA7219_NO_INVERT,
661 da7219_volsw_locked_get, da7219_volsw_locked_put,
662 da7219_hp_gain_tlv),
663 SOC_DOUBLE_R_EXT("Headphone Switch", DA7219_HP_L_CTRL, DA7219_HP_R_CTRL,
664 DA7219_HP_L_AMP_MUTE_EN_SHIFT, DA7219_SWITCH_EN_MAX,
665 DA7219_INVERT, da7219_volsw_locked_get,
666 da7219_volsw_locked_put),
667 SOC_DOUBLE_R("Headphone Gain Ramp Switch", DA7219_HP_L_CTRL,
668 DA7219_HP_R_CTRL, DA7219_HP_L_AMP_RAMP_EN_SHIFT,
669 DA7219_SWITCH_EN_MAX, DA7219_NO_INVERT),
670 SOC_DOUBLE_R("Headphone ZC Gain Switch", DA7219_HP_L_CTRL,
671 DA7219_HP_R_CTRL, DA7219_HP_L_AMP_ZC_EN_SHIFT,
672 DA7219_SWITCH_EN_MAX, DA7219_NO_INVERT),
673};
674
675
676/*
677 * DAPM Mux Controls
678 */
679
680static const char * const da7219_out_sel_txt[] = {
681 "ADC", "Tone Generator", "DAIL", "DAIR"
682};
683
684static const struct soc_enum da7219_out_dail_sel =
685 SOC_ENUM_SINGLE(DA7219_DIG_ROUTING_DAI,
686 DA7219_DAI_L_SRC_SHIFT,
687 DA7219_OUT_SRC_MAX,
688 da7219_out_sel_txt);
689
690static const struct snd_kcontrol_new da7219_out_dail_sel_mux =
691 SOC_DAPM_ENUM("Out DAIL Mux", da7219_out_dail_sel);
692
693static const struct soc_enum da7219_out_dair_sel =
694 SOC_ENUM_SINGLE(DA7219_DIG_ROUTING_DAI,
695 DA7219_DAI_R_SRC_SHIFT,
696 DA7219_OUT_SRC_MAX,
697 da7219_out_sel_txt);
698
699static const struct snd_kcontrol_new da7219_out_dair_sel_mux =
700 SOC_DAPM_ENUM("Out DAIR Mux", da7219_out_dair_sel);
701
702static const struct soc_enum da7219_out_dacl_sel =
703 SOC_ENUM_SINGLE(DA7219_DIG_ROUTING_DAC,
704 DA7219_DAC_L_SRC_SHIFT,
705 DA7219_OUT_SRC_MAX,
706 da7219_out_sel_txt);
707
708static const struct snd_kcontrol_new da7219_out_dacl_sel_mux =
709 SOC_DAPM_ENUM("Out DACL Mux", da7219_out_dacl_sel);
710
711static const struct soc_enum da7219_out_dacr_sel =
712 SOC_ENUM_SINGLE(DA7219_DIG_ROUTING_DAC,
713 DA7219_DAC_R_SRC_SHIFT,
714 DA7219_OUT_SRC_MAX,
715 da7219_out_sel_txt);
716
717static const struct snd_kcontrol_new da7219_out_dacr_sel_mux =
718 SOC_DAPM_ENUM("Out DACR Mux", da7219_out_dacr_sel);
719
720
721/*
722 * DAPM Mixer Controls
723 */
724
725static const struct snd_kcontrol_new da7219_mixin_controls[] = {
726 SOC_DAPM_SINGLE("Mic Switch", DA7219_MIXIN_L_SELECT,
727 DA7219_MIXIN_L_MIX_SELECT_SHIFT,
728 DA7219_SWITCH_EN_MAX, DA7219_NO_INVERT),
729};
730
731static const struct snd_kcontrol_new da7219_mixout_l_controls[] = {
732 SOC_DAPM_SINGLE("DACL Switch", DA7219_MIXOUT_L_SELECT,
733 DA7219_MIXOUT_L_MIX_SELECT_SHIFT,
734 DA7219_SWITCH_EN_MAX, DA7219_NO_INVERT),
735};
736
737static const struct snd_kcontrol_new da7219_mixout_r_controls[] = {
738 SOC_DAPM_SINGLE("DACR Switch", DA7219_MIXOUT_R_SELECT,
739 DA7219_MIXOUT_R_MIX_SELECT_SHIFT,
740 DA7219_SWITCH_EN_MAX, DA7219_NO_INVERT),
741};
742
743#define DA7219_DMIX_ST_CTRLS(reg) \
744 SOC_DAPM_SINGLE("Out FilterL Switch", reg, \
745 DA7219_DMIX_ST_SRC_OUTFILT1L_SHIFT, \
746 DA7219_SWITCH_EN_MAX, DA7219_NO_INVERT), \
747 SOC_DAPM_SINGLE("Out FilterR Switch", reg, \
748 DA7219_DMIX_ST_SRC_OUTFILT1R_SHIFT, \
749 DA7219_SWITCH_EN_MAX, DA7219_NO_INVERT), \
750 SOC_DAPM_SINGLE("Sidetone Switch", reg, \
751 DA7219_DMIX_ST_SRC_SIDETONE_SHIFT, \
752 DA7219_SWITCH_EN_MAX, DA7219_NO_INVERT) \
753
754static const struct snd_kcontrol_new da7219_st_out_filtl_mix_controls[] = {
755 DA7219_DMIX_ST_CTRLS(DA7219_DROUTING_ST_OUTFILT_1L),
756};
757
758static const struct snd_kcontrol_new da7219_st_out_filtr_mix_controls[] = {
759 DA7219_DMIX_ST_CTRLS(DA7219_DROUTING_ST_OUTFILT_1R),
760};
761
762
763/*
764 * DAPM Events
765 */
766
767static int da7219_dai_event(struct snd_soc_dapm_widget *w,
768 struct snd_kcontrol *kcontrol, int event)
769{
770 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
771 struct da7219_priv *da7219 = snd_soc_codec_get_drvdata(codec);
772 u8 pll_ctrl, pll_status;
773 int i = 0;
774 bool srm_lock = false;
775
776 switch (event) {
777 case SND_SOC_DAPM_PRE_PMU:
778 if (da7219->master)
779 /* Enable DAI clks for master mode */
780 snd_soc_update_bits(codec, DA7219_DAI_CLK_MODE,
781 DA7219_DAI_CLK_EN_MASK,
782 DA7219_DAI_CLK_EN_MASK);
783
784 /* PC synchronised to DAI */
785 snd_soc_update_bits(codec, DA7219_PC_COUNT,
786 DA7219_PC_FREERUN_MASK, 0);
787
788 /* Slave mode, if SRM not enabled no need for status checks */
789 pll_ctrl = snd_soc_read(codec, DA7219_PLL_CTRL);
790 if ((pll_ctrl & DA7219_PLL_MODE_MASK) != DA7219_PLL_MODE_SRM)
791 return 0;
792
793 /* Check SRM has locked */
794 do {
795 pll_status = snd_soc_read(codec, DA7219_PLL_SRM_STS);
796 if (pll_status & DA7219_PLL_SRM_STS_SRM_LOCK) {
797 srm_lock = true;
798 } else {
799 ++i;
800 msleep(50);
801 }
802 } while ((i < DA7219_SRM_CHECK_RETRIES) & (!srm_lock));
803
804 if (!srm_lock)
805 dev_warn(codec->dev, "SRM failed to lock\n");
806
807 return 0;
808 case SND_SOC_DAPM_POST_PMD:
809 /* PC free-running */
810 snd_soc_update_bits(codec, DA7219_PC_COUNT,
811 DA7219_PC_FREERUN_MASK,
812 DA7219_PC_FREERUN_MASK);
813
814 /* Disable DAI clks if in master mode */
815 if (da7219->master)
816 snd_soc_update_bits(codec, DA7219_DAI_CLK_MODE,
817 DA7219_DAI_CLK_EN_MASK, 0);
818 return 0;
819 default:
820 return -EINVAL;
821 }
822}
823
824
825/*
826 * DAPM Widgets
827 */
828
829static const struct snd_soc_dapm_widget da7219_dapm_widgets[] = {
830 /* Input Supplies */
831 SND_SOC_DAPM_SUPPLY("Mic Bias", DA7219_MICBIAS_CTRL,
832 DA7219_MICBIAS1_EN_SHIFT, DA7219_NO_INVERT,
833 NULL, 0),
834
835 /* Inputs */
836 SND_SOC_DAPM_INPUT("MIC"),
837
838 /* Input PGAs */
839 SND_SOC_DAPM_PGA("Mic PGA", DA7219_MIC_1_CTRL,
840 DA7219_MIC_1_AMP_EN_SHIFT, DA7219_NO_INVERT,
841 NULL, 0),
842 SND_SOC_DAPM_PGA("Mixin PGA", DA7219_MIXIN_L_CTRL,
843 DA7219_MIXIN_L_AMP_EN_SHIFT, DA7219_NO_INVERT,
844 NULL, 0),
845
846 /* Input Filters */
847 SND_SOC_DAPM_ADC("ADC", NULL, DA7219_ADC_L_CTRL, DA7219_ADC_L_EN_SHIFT,
848 DA7219_NO_INVERT),
849
850 /* Tone Generator */
851 SND_SOC_DAPM_SIGGEN("TONE"),
852 SND_SOC_DAPM_PGA("Tone Generator", DA7219_TONE_GEN_CFG1,
853 DA7219_START_STOPN_SHIFT, DA7219_NO_INVERT, NULL, 0),
854
855 /* Sidetone Input */
856 SND_SOC_DAPM_ADC("Sidetone Filter", NULL, DA7219_SIDETONE_CTRL,
857 DA7219_SIDETONE_EN_SHIFT, DA7219_NO_INVERT),
858
859 /* Input Mixer Supply */
860 SND_SOC_DAPM_SUPPLY("Mixer In Supply", DA7219_MIXIN_L_CTRL,
861 DA7219_MIXIN_L_MIX_EN_SHIFT, DA7219_NO_INVERT,
862 NULL, 0),
863
864 /* Input Mixer */
865 SND_SOC_DAPM_MIXER("Mixer In", SND_SOC_NOPM, 0, 0,
866 da7219_mixin_controls,
867 ARRAY_SIZE(da7219_mixin_controls)),
868
869 /* Input Muxes */
870 SND_SOC_DAPM_MUX("Out DAIL Mux", SND_SOC_NOPM, 0, 0,
871 &da7219_out_dail_sel_mux),
872 SND_SOC_DAPM_MUX("Out DAIR Mux", SND_SOC_NOPM, 0, 0,
873 &da7219_out_dair_sel_mux),
874
875 /* DAI Supply */
876 SND_SOC_DAPM_SUPPLY("DAI", DA7219_DAI_CTRL, DA7219_DAI_EN_SHIFT,
877 DA7219_NO_INVERT, da7219_dai_event,
878 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
879
880 /* DAI */
881 SND_SOC_DAPM_AIF_OUT("DAIOUT", "Capture", 0, SND_SOC_NOPM, 0, 0),
882 SND_SOC_DAPM_AIF_IN("DAIIN", "Playback", 0, SND_SOC_NOPM, 0, 0),
883
884 /* Output Muxes */
885 SND_SOC_DAPM_MUX("Out DACL Mux", SND_SOC_NOPM, 0, 0,
886 &da7219_out_dacl_sel_mux),
887 SND_SOC_DAPM_MUX("Out DACR Mux", SND_SOC_NOPM, 0, 0,
888 &da7219_out_dacr_sel_mux),
889
890 /* Output Mixers */
891 SND_SOC_DAPM_MIXER("Mixer Out FilterL", SND_SOC_NOPM, 0, 0,
892 da7219_mixout_l_controls,
893 ARRAY_SIZE(da7219_mixout_l_controls)),
894 SND_SOC_DAPM_MIXER("Mixer Out FilterR", SND_SOC_NOPM, 0, 0,
895 da7219_mixout_r_controls,
896 ARRAY_SIZE(da7219_mixout_r_controls)),
897
898 /* Sidetone Mixers */
899 SND_SOC_DAPM_MIXER("ST Mixer Out FilterL", SND_SOC_NOPM, 0, 0,
900 da7219_st_out_filtl_mix_controls,
901 ARRAY_SIZE(da7219_st_out_filtl_mix_controls)),
902 SND_SOC_DAPM_MIXER("ST Mixer Out FilterR", SND_SOC_NOPM, 0,
903 0, da7219_st_out_filtr_mix_controls,
904 ARRAY_SIZE(da7219_st_out_filtr_mix_controls)),
905
906 /* DACs */
907 SND_SOC_DAPM_DAC("DACL", NULL, DA7219_DAC_L_CTRL, DA7219_DAC_L_EN_SHIFT,
908 DA7219_NO_INVERT),
909 SND_SOC_DAPM_DAC("DACR", NULL, DA7219_DAC_R_CTRL, DA7219_DAC_R_EN_SHIFT,
910 DA7219_NO_INVERT),
911
912 /* Output PGAs */
913 SND_SOC_DAPM_PGA("Mixout Left PGA", DA7219_MIXOUT_L_CTRL,
914 DA7219_MIXOUT_L_AMP_EN_SHIFT, DA7219_NO_INVERT,
915 NULL, 0),
916 SND_SOC_DAPM_PGA("Mixout Right PGA", DA7219_MIXOUT_R_CTRL,
917 DA7219_MIXOUT_R_AMP_EN_SHIFT, DA7219_NO_INVERT,
918 NULL, 0),
919 SND_SOC_DAPM_PGA("Headphone Left PGA", DA7219_HP_L_CTRL,
920 DA7219_HP_L_AMP_EN_SHIFT, DA7219_NO_INVERT, NULL, 0),
921 SND_SOC_DAPM_PGA("Headphone Right PGA", DA7219_HP_R_CTRL,
922 DA7219_HP_R_AMP_EN_SHIFT, DA7219_NO_INVERT, NULL, 0),
923
924 /* Output Supplies */
925 SND_SOC_DAPM_SUPPLY("Charge Pump", DA7219_CP_CTRL, DA7219_CP_EN_SHIFT,
926 DA7219_NO_INVERT, NULL, 0),
927
928 /* Outputs */
929 SND_SOC_DAPM_OUTPUT("HPL"),
930 SND_SOC_DAPM_OUTPUT("HPR"),
931};
932
933
934/*
935 * DAPM Mux Routes
936 */
937
938#define DA7219_OUT_DAI_MUX_ROUTES(name) \
939 {name, "ADC", "Mixer In"}, \
940 {name, "Tone Generator", "Tone Generator"}, \
941 {name, "DAIL", "DAIOUT"}, \
942 {name, "DAIR", "DAIOUT"}
943
944#define DA7219_OUT_DAC_MUX_ROUTES(name) \
945 {name, "ADC", "Mixer In"}, \
946 {name, "Tone Generator", "Tone Generator"}, \
947 {name, "DAIL", "DAIIN"}, \
948 {name, "DAIR", "DAIIN"}
949
950/*
951 * DAPM Mixer Routes
952 */
953
954#define DA7219_DMIX_ST_ROUTES(name) \
955 {name, "Out FilterL Switch", "Mixer Out FilterL"}, \
956 {name, "Out FilterR Switch", "Mixer Out FilterR"}, \
957 {name, "Sidetone Switch", "Sidetone Filter"}
958
959
960/*
961 * DAPM audio route definition
962 */
963
964static const struct snd_soc_dapm_route da7219_audio_map[] = {
965 /* Input paths */
966 {"MIC", NULL, "Mic Bias"},
967 {"Mic PGA", NULL, "MIC"},
968 {"Mixin PGA", NULL, "Mic PGA"},
969 {"ADC", NULL, "Mixin PGA"},
970
971 {"Sidetone Filter", NULL, "ADC"},
972 {"Mixer In", NULL, "Mixer In Supply"},
973 {"Mixer In", "Mic Switch", "ADC"},
974
975 {"Tone Generator", NULL, "TONE"},
976
977 DA7219_OUT_DAI_MUX_ROUTES("Out DAIL Mux"),
978 DA7219_OUT_DAI_MUX_ROUTES("Out DAIR Mux"),
979
980 {"DAIOUT", NULL, "Out DAIL Mux"},
981 {"DAIOUT", NULL, "Out DAIR Mux"},
982 {"DAIOUT", NULL, "DAI"},
983
984 /* Output paths */
985 {"DAIIN", NULL, "DAI"},
986
987 DA7219_OUT_DAC_MUX_ROUTES("Out DACL Mux"),
988 DA7219_OUT_DAC_MUX_ROUTES("Out DACR Mux"),
989
990 {"Mixer Out FilterL", "DACL Switch", "Out DACL Mux"},
991 {"Mixer Out FilterR", "DACR Switch", "Out DACR Mux"},
992
993 DA7219_DMIX_ST_ROUTES("ST Mixer Out FilterL"),
994 DA7219_DMIX_ST_ROUTES("ST Mixer Out FilterR"),
995
996 {"DACL", NULL, "ST Mixer Out FilterL"},
997 {"DACR", NULL, "ST Mixer Out FilterR"},
998
999 {"Mixout Left PGA", NULL, "DACL"},
1000 {"Mixout Right PGA", NULL, "DACR"},
1001
1002 {"Headphone Left PGA", NULL, "Mixout Left PGA"},
1003 {"Headphone Right PGA", NULL, "Mixout Right PGA"},
1004
1005 {"HPL", NULL, "Headphone Left PGA"},
1006 {"HPR", NULL, "Headphone Right PGA"},
1007
1008 {"HPL", NULL, "Charge Pump"},
1009 {"HPR", NULL, "Charge Pump"},
1010};
1011
1012
1013/*
1014 * DAI operations
1015 */
1016
1017static int da7219_set_dai_sysclk(struct snd_soc_dai *codec_dai,
1018 int clk_id, unsigned int freq, int dir)
1019{
1020 struct snd_soc_codec *codec = codec_dai->codec;
1021 struct da7219_priv *da7219 = snd_soc_codec_get_drvdata(codec);
1022 int ret = 0;
1023
1024 if ((da7219->clk_src == clk_id) && (da7219->mclk_rate == freq))
1025 return 0;
1026
1027 if (((freq < 2000000) && (freq != 32768)) || (freq > 54000000)) {
1028 dev_err(codec_dai->dev, "Unsupported MCLK value %d\n",
1029 freq);
1030 return -EINVAL;
1031 }
1032
1033 switch (clk_id) {
1034 case DA7219_CLKSRC_MCLK_SQR:
1035 snd_soc_update_bits(codec, DA7219_PLL_CTRL,
1036 DA7219_PLL_MCLK_SQR_EN_MASK,
1037 DA7219_PLL_MCLK_SQR_EN_MASK);
1038 break;
1039 case DA7219_CLKSRC_MCLK:
1040 snd_soc_update_bits(codec, DA7219_PLL_CTRL,
1041 DA7219_PLL_MCLK_SQR_EN_MASK, 0);
1042 break;
1043 default:
1044 dev_err(codec_dai->dev, "Unknown clock source %d\n", clk_id);
1045 return -EINVAL;
1046 }
1047
1048 da7219->clk_src = clk_id;
1049
1050 if (da7219->mclk) {
1051 freq = clk_round_rate(da7219->mclk, freq);
1052 ret = clk_set_rate(da7219->mclk, freq);
1053 if (ret) {
1054 dev_err(codec_dai->dev, "Failed to set clock rate %d\n",
1055 freq);
1056 return ret;
1057 }
1058 }
1059
1060 da7219->mclk_rate = freq;
1061
1062 return 0;
1063}
1064
1065static int da7219_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
1066 int source, unsigned int fref, unsigned int fout)
1067{
1068 struct snd_soc_codec *codec = codec_dai->codec;
1069 struct da7219_priv *da7219 = snd_soc_codec_get_drvdata(codec);
1070
1071 u8 pll_ctrl, indiv_bits, indiv;
1072 u8 pll_frac_top, pll_frac_bot, pll_integer;
1073 u32 freq_ref;
1074 u64 frac_div;
1075
1076 /* Verify 32KHz, 2MHz - 54MHz MCLK provided, and set input divider */
1077 if (da7219->mclk_rate == 32768) {
1078 indiv_bits = DA7219_PLL_INDIV_2_5_MHZ;
1079 indiv = DA7219_PLL_INDIV_2_5_MHZ_VAL;
1080 } else if (da7219->mclk_rate < 2000000) {
1081 dev_err(codec->dev, "PLL input clock %d below valid range\n",
1082 da7219->mclk_rate);
1083 return -EINVAL;
1084 } else if (da7219->mclk_rate <= 5000000) {
1085 indiv_bits = DA7219_PLL_INDIV_2_5_MHZ;
1086 indiv = DA7219_PLL_INDIV_2_5_MHZ_VAL;
1087 } else if (da7219->mclk_rate <= 10000000) {
1088 indiv_bits = DA7219_PLL_INDIV_5_10_MHZ;
1089 indiv = DA7219_PLL_INDIV_5_10_MHZ_VAL;
1090 } else if (da7219->mclk_rate <= 20000000) {
1091 indiv_bits = DA7219_PLL_INDIV_10_20_MHZ;
1092 indiv = DA7219_PLL_INDIV_10_20_MHZ_VAL;
1093 } else if (da7219->mclk_rate <= 40000000) {
1094 indiv_bits = DA7219_PLL_INDIV_20_40_MHZ;
1095 indiv = DA7219_PLL_INDIV_20_40_MHZ_VAL;
1096 } else if (da7219->mclk_rate <= 54000000) {
1097 indiv_bits = DA7219_PLL_INDIV_40_54_MHZ;
1098 indiv = DA7219_PLL_INDIV_40_54_MHZ_VAL;
1099 } else {
1100 dev_err(codec->dev, "PLL input clock %d above valid range\n",
1101 da7219->mclk_rate);
1102 return -EINVAL;
1103 }
1104 freq_ref = (da7219->mclk_rate / indiv);
1105 pll_ctrl = indiv_bits;
1106
1107 /* Configure PLL */
1108 switch (source) {
1109 case DA7219_SYSCLK_MCLK:
1110 pll_ctrl |= DA7219_PLL_MODE_BYPASS;
1111 snd_soc_update_bits(codec, DA7219_PLL_CTRL,
1112 DA7219_PLL_INDIV_MASK |
1113 DA7219_PLL_MODE_MASK, pll_ctrl);
1114 return 0;
1115 case DA7219_SYSCLK_PLL:
1116 pll_ctrl |= DA7219_PLL_MODE_NORMAL;
1117 break;
1118 case DA7219_SYSCLK_PLL_SRM:
1119 pll_ctrl |= DA7219_PLL_MODE_SRM;
1120 break;
1121 case DA7219_SYSCLK_PLL_32KHZ:
1122 pll_ctrl |= DA7219_PLL_MODE_32KHZ;
1123 break;
1124 default:
1125 dev_err(codec->dev, "Invalid PLL config\n");
1126 return -EINVAL;
1127 }
1128
1129 /* Calculate dividers for PLL */
1130 pll_integer = fout / freq_ref;
1131 frac_div = (u64)(fout % freq_ref) * 8192ULL;
1132 do_div(frac_div, freq_ref);
1133 pll_frac_top = (frac_div >> DA7219_BYTE_SHIFT) & DA7219_BYTE_MASK;
1134 pll_frac_bot = (frac_div) & DA7219_BYTE_MASK;
1135
1136 /* Write PLL config & dividers */
1137 snd_soc_write(codec, DA7219_PLL_FRAC_TOP, pll_frac_top);
1138 snd_soc_write(codec, DA7219_PLL_FRAC_BOT, pll_frac_bot);
1139 snd_soc_write(codec, DA7219_PLL_INTEGER, pll_integer);
1140 snd_soc_update_bits(codec, DA7219_PLL_CTRL,
1141 DA7219_PLL_INDIV_MASK | DA7219_PLL_MODE_MASK,
1142 pll_ctrl);
1143
1144 return 0;
1145}
1146
1147static int da7219_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
1148{
1149 struct snd_soc_codec *codec = codec_dai->codec;
1150 struct da7219_priv *da7219 = snd_soc_codec_get_drvdata(codec);
1151 u8 dai_clk_mode = 0, dai_ctrl = 0;
1152
1153 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
1154 case SND_SOC_DAIFMT_CBM_CFM:
1155 da7219->master = true;
1156 break;
1157 case SND_SOC_DAIFMT_CBS_CFS:
1158 da7219->master = false;
1159 break;
1160 default:
1161 return -EINVAL;
1162 }
1163
1164 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
1165 case SND_SOC_DAIFMT_NB_NF:
1166 break;
1167 case SND_SOC_DAIFMT_NB_IF:
1168 dai_clk_mode |= DA7219_DAI_WCLK_POL_INV;
1169 break;
1170 case SND_SOC_DAIFMT_IB_NF:
1171 dai_clk_mode |= DA7219_DAI_CLK_POL_INV;
1172 break;
1173 case SND_SOC_DAIFMT_IB_IF:
1174 dai_clk_mode |= DA7219_DAI_WCLK_POL_INV |
1175 DA7219_DAI_CLK_POL_INV;
1176 break;
1177 default:
1178 return -EINVAL;
1179 }
1180
1181 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
1182 case SND_SOC_DAIFMT_I2S:
1183 dai_ctrl |= DA7219_DAI_FORMAT_I2S;
1184 break;
1185 case SND_SOC_DAIFMT_LEFT_J:
1186 dai_ctrl |= DA7219_DAI_FORMAT_LEFT_J;
1187 break;
1188 case SND_SOC_DAIFMT_RIGHT_J:
1189 dai_ctrl |= DA7219_DAI_FORMAT_RIGHT_J;
1190 break;
1191 case SND_SOC_DAIFMT_DSP_B:
1192 dai_ctrl |= DA7219_DAI_FORMAT_DSP;
1193 break;
1194 default:
1195 return -EINVAL;
1196 }
1197
1198 /* By default 64 BCLKs per WCLK is supported */
1199 dai_clk_mode |= DA7219_DAI_BCLKS_PER_WCLK_64;
1200
1201 snd_soc_update_bits(codec, DA7219_DAI_CLK_MODE,
1202 DA7219_DAI_BCLKS_PER_WCLK_MASK |
1203 DA7219_DAI_CLK_POL_MASK | DA7219_DAI_WCLK_POL_MASK,
1204 dai_clk_mode);
1205 snd_soc_update_bits(codec, DA7219_DAI_CTRL, DA7219_DAI_FORMAT_MASK,
1206 dai_ctrl);
1207
1208 return 0;
1209}
1210
1211static int da7219_set_dai_tdm_slot(struct snd_soc_dai *dai,
1212 unsigned int tx_mask, unsigned int rx_mask,
1213 int slots, int slot_width)
1214{
1215 struct snd_soc_codec *codec = dai->codec;
1216 struct da7219_priv *da7219 = snd_soc_codec_get_drvdata(codec);
1217 u8 dai_bclks_per_wclk;
1218 u16 offset;
1219 u32 frame_size;
1220
1221 /* No channels enabled so disable TDM, revert to 64-bit frames */
1222 if (!tx_mask) {
1223 snd_soc_update_bits(codec, DA7219_DAI_TDM_CTRL,
1224 DA7219_DAI_TDM_CH_EN_MASK |
1225 DA7219_DAI_TDM_MODE_EN_MASK, 0);
1226 snd_soc_update_bits(codec, DA7219_DAI_CLK_MODE,
1227 DA7219_DAI_BCLKS_PER_WCLK_MASK,
1228 DA7219_DAI_BCLKS_PER_WCLK_64);
1229 return 0;
1230 }
1231
1232 /* Check we have valid slots */
1233 if (fls(tx_mask) > DA7219_DAI_TDM_MAX_SLOTS) {
1234 dev_err(codec->dev, "Invalid number of slots, max = %d\n",
1235 DA7219_DAI_TDM_MAX_SLOTS);
1236 return -EINVAL;
1237 }
1238
1239 /* Check we have a valid offset given */
1240 if (rx_mask > DA7219_DAI_OFFSET_MAX) {
1241 dev_err(codec->dev, "Invalid slot offset, max = %d\n",
1242 DA7219_DAI_OFFSET_MAX);
1243 return -EINVAL;
1244 }
1245
1246 /* Calculate & validate frame size based on slot info provided. */
1247 frame_size = slots * slot_width;
1248 switch (frame_size) {
1249 case 32:
1250 dai_bclks_per_wclk = DA7219_DAI_BCLKS_PER_WCLK_32;
1251 break;
1252 case 64:
1253 dai_bclks_per_wclk = DA7219_DAI_BCLKS_PER_WCLK_64;
1254 break;
1255 case 128:
1256 dai_bclks_per_wclk = DA7219_DAI_BCLKS_PER_WCLK_128;
1257 break;
1258 case 256:
1259 dai_bclks_per_wclk = DA7219_DAI_BCLKS_PER_WCLK_256;
1260 break;
1261 default:
1262 dev_err(codec->dev, "Invalid frame size %d\n", frame_size);
1263 return -EINVAL;
1264 }
1265
1266 snd_soc_update_bits(codec, DA7219_DAI_CLK_MODE,
1267 DA7219_DAI_BCLKS_PER_WCLK_MASK,
1268 dai_bclks_per_wclk);
1269
1270 offset = cpu_to_le16(rx_mask);
1271 regmap_bulk_write(da7219->regmap, DA7219_DAI_OFFSET_LOWER,
1272 &offset, sizeof(offset));
1273
1274 snd_soc_update_bits(codec, DA7219_DAI_TDM_CTRL,
1275 DA7219_DAI_TDM_CH_EN_MASK |
1276 DA7219_DAI_TDM_MODE_EN_MASK,
1277 (tx_mask << DA7219_DAI_TDM_CH_EN_SHIFT) |
1278 DA7219_DAI_TDM_MODE_EN_MASK);
1279
1280 return 0;
1281}
1282
1283static int da7219_hw_params(struct snd_pcm_substream *substream,
1284 struct snd_pcm_hw_params *params,
1285 struct snd_soc_dai *dai)
1286{
1287 struct snd_soc_codec *codec = dai->codec;
1288 u8 dai_ctrl = 0, fs;
1289 unsigned int channels;
1290
1291 switch (params_width(params)) {
1292 case 16:
1293 dai_ctrl |= DA7219_DAI_WORD_LENGTH_S16_LE;
1294 break;
1295 case 20:
1296 dai_ctrl |= DA7219_DAI_WORD_LENGTH_S20_LE;
1297 break;
1298 case 24:
1299 dai_ctrl |= DA7219_DAI_WORD_LENGTH_S24_LE;
1300 break;
1301 case 32:
1302 dai_ctrl |= DA7219_DAI_WORD_LENGTH_S32_LE;
1303 break;
1304 default:
1305 return -EINVAL;
1306 }
1307
1308 channels = params_channels(params);
1309 if ((channels < 1) | (channels > DA7219_DAI_CH_NUM_MAX)) {
1310 dev_err(codec->dev,
1311 "Invalid number of channels, only 1 to %d supported\n",
1312 DA7219_DAI_CH_NUM_MAX);
1313 return -EINVAL;
1314 }
1315 dai_ctrl |= channels << DA7219_DAI_CH_NUM_SHIFT;
1316
1317 switch (params_rate(params)) {
1318 case 8000:
1319 fs = DA7219_SR_8000;
1320 break;
1321 case 11025:
1322 fs = DA7219_SR_11025;
1323 break;
1324 case 12000:
1325 fs = DA7219_SR_12000;
1326 break;
1327 case 16000:
1328 fs = DA7219_SR_16000;
1329 break;
1330 case 22050:
1331 fs = DA7219_SR_22050;
1332 break;
1333 case 24000:
1334 fs = DA7219_SR_24000;
1335 break;
1336 case 32000:
1337 fs = DA7219_SR_32000;
1338 break;
1339 case 44100:
1340 fs = DA7219_SR_44100;
1341 break;
1342 case 48000:
1343 fs = DA7219_SR_48000;
1344 break;
1345 case 88200:
1346 fs = DA7219_SR_88200;
1347 break;
1348 case 96000:
1349 fs = DA7219_SR_96000;
1350 break;
1351 default:
1352 return -EINVAL;
1353 }
1354
1355 snd_soc_update_bits(codec, DA7219_DAI_CTRL,
1356 DA7219_DAI_WORD_LENGTH_MASK |
1357 DA7219_DAI_CH_NUM_MASK,
1358 dai_ctrl);
1359 snd_soc_write(codec, DA7219_SR, fs);
1360
1361 return 0;
1362}
1363
1364static const struct snd_soc_dai_ops da7219_dai_ops = {
1365 .hw_params = da7219_hw_params,
1366 .set_sysclk = da7219_set_dai_sysclk,
1367 .set_pll = da7219_set_dai_pll,
1368 .set_fmt = da7219_set_dai_fmt,
1369 .set_tdm_slot = da7219_set_dai_tdm_slot,
1370};
1371
1372#define DA7219_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
1373 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
1374
1375static struct snd_soc_dai_driver da7219_dai = {
1376 .name = "da7219-hifi",
1377 .playback = {
1378 .stream_name = "Playback",
1379 .channels_min = 1,
1380 .channels_max = DA7219_DAI_CH_NUM_MAX,
1381 .rates = SNDRV_PCM_RATE_8000_96000,
1382 .formats = DA7219_FORMATS,
1383 },
1384 .capture = {
1385 .stream_name = "Capture",
1386 .channels_min = 1,
1387 .channels_max = DA7219_DAI_CH_NUM_MAX,
1388 .rates = SNDRV_PCM_RATE_8000_96000,
1389 .formats = DA7219_FORMATS,
1390 },
1391 .ops = &da7219_dai_ops,
1392 .symmetric_rates = 1,
1393 .symmetric_channels = 1,
1394 .symmetric_samplebits = 1,
1395};
1396
1397
1398/*
1399 * DT
1400 */
1401
1402static const struct of_device_id da7219_of_match[] = {
1403 { .compatible = "dlg,da7219", },
1404 { }
1405};
1406MODULE_DEVICE_TABLE(of, da7219_of_match);
1407
1408static enum da7219_ldo_lvl_sel da7219_of_ldo_lvl(struct snd_soc_codec *codec,
1409 u32 val)
1410{
1411 switch (val) {
1412 case 1050:
1413 return DA7219_LDO_LVL_SEL_1_05V;
1414 case 1100:
1415 return DA7219_LDO_LVL_SEL_1_10V;
1416 case 1200:
1417 return DA7219_LDO_LVL_SEL_1_20V;
1418 case 1400:
1419 return DA7219_LDO_LVL_SEL_1_40V;
1420 default:
1421 dev_warn(codec->dev, "Invalid LDO level");
1422 return DA7219_LDO_LVL_SEL_1_05V;
1423 }
1424}
1425
1426static enum da7219_micbias_voltage
1427 da7219_of_micbias_lvl(struct snd_soc_codec *codec, u32 val)
1428{
1429 switch (val) {
1430 case 1800:
1431 return DA7219_MICBIAS_1_8V;
1432 case 2000:
1433 return DA7219_MICBIAS_2_0V;
1434 case 2200:
1435 return DA7219_MICBIAS_2_2V;
1436 case 2400:
1437 return DA7219_MICBIAS_2_4V;
1438 case 2600:
1439 return DA7219_MICBIAS_2_6V;
1440 default:
1441 dev_warn(codec->dev, "Invalid micbias level");
1442 return DA7219_MICBIAS_2_2V;
1443 }
1444}
1445
1446static enum da7219_mic_amp_in_sel
1447 da7219_of_mic_amp_in_sel(struct snd_soc_codec *codec, const char *str)
1448{
1449 if (!strcmp(str, "diff")) {
1450 return DA7219_MIC_AMP_IN_SEL_DIFF;
1451 } else if (!strcmp(str, "se_p")) {
1452 return DA7219_MIC_AMP_IN_SEL_SE_P;
1453 } else if (!strcmp(str, "se_n")) {
1454 return DA7219_MIC_AMP_IN_SEL_SE_N;
1455 } else {
1456 dev_warn(codec->dev, "Invalid mic input type selection");
1457 return DA7219_MIC_AMP_IN_SEL_DIFF;
1458 }
1459}
1460
1461static struct da7219_pdata *da7219_of_to_pdata(struct snd_soc_codec *codec)
1462{
1463 struct device_node *np = codec->dev->of_node;
1464 struct da7219_pdata *pdata;
1465 const char *of_str;
1466 u32 of_val32;
1467
1468 pdata = devm_kzalloc(codec->dev, sizeof(*pdata), GFP_KERNEL);
1469 if (!pdata)
1470 return NULL;
1471
1472 if (of_property_read_u32(np, "dlg,ldo-lvl", &of_val32) >= 0)
1473 pdata->ldo_lvl_sel = da7219_of_ldo_lvl(codec, of_val32);
1474
1475 if (of_property_read_u32(np, "dlg,micbias-lvl", &of_val32) >= 0)
1476 pdata->micbias_lvl = da7219_of_micbias_lvl(codec, of_val32);
1477 else
1478 pdata->micbias_lvl = DA7219_MICBIAS_2_2V;
1479
1480 if (!of_property_read_string(np, "dlg,mic-amp-in-sel", &of_str))
1481 pdata->mic_amp_in_sel = da7219_of_mic_amp_in_sel(codec, of_str);
1482 else
1483 pdata->mic_amp_in_sel = DA7219_MIC_AMP_IN_SEL_DIFF;
1484
1485 return pdata;
1486}
1487
1488
1489/*
1490 * Codec driver functions
1491 */
1492
1493static int da7219_set_bias_level(struct snd_soc_codec *codec,
1494 enum snd_soc_bias_level level)
1495{
1496 struct da7219_priv *da7219 = snd_soc_codec_get_drvdata(codec);
1497 int ret;
1498
1499 switch (level) {
1500 case SND_SOC_BIAS_ON:
1501 case SND_SOC_BIAS_PREPARE:
1502 break;
1503 case SND_SOC_BIAS_STANDBY:
1504 if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF) {
1505 /* MCLK */
1506 if (da7219->mclk) {
1507 ret = clk_prepare_enable(da7219->mclk);
1508 if (ret) {
1509 dev_err(codec->dev,
1510 "Failed to enable mclk\n");
1511 return ret;
1512 }
1513 }
1514
1515 /* Master bias */
1516 snd_soc_update_bits(codec, DA7219_REFERENCES,
1517 DA7219_BIAS_EN_MASK,
1518 DA7219_BIAS_EN_MASK);
1519
1520 /* Enable Internal Digital LDO */
1521 snd_soc_update_bits(codec, DA7219_LDO_CTRL,
1522 DA7219_LDO_EN_MASK,
1523 DA7219_LDO_EN_MASK);
1524 }
1525 break;
1526 case SND_SOC_BIAS_OFF:
1527 /* Only disable if jack detection not active */
1528 if (!da7219->aad->jack) {
1529 /* Bypass Internal Digital LDO */
1530 snd_soc_update_bits(codec, DA7219_LDO_CTRL,
1531 DA7219_LDO_EN_MASK, 0);
1532
1533 /* Master bias */
1534 snd_soc_update_bits(codec, DA7219_REFERENCES,
1535 DA7219_BIAS_EN_MASK, 0);
1536 }
1537
1538 /* MCLK */
1539 if (da7219->mclk)
1540 clk_disable_unprepare(da7219->mclk);
1541 break;
1542 }
1543
1544 return 0;
1545}
1546
1547static const char *da7219_supply_names[DA7219_NUM_SUPPLIES] = {
1548 [DA7219_SUPPLY_VDD] = "VDD",
1549 [DA7219_SUPPLY_VDDMIC] = "VDDMIC",
1550 [DA7219_SUPPLY_VDDIO] = "VDDIO",
1551};
1552
1553static int da7219_handle_supplies(struct snd_soc_codec *codec)
1554{
1555 struct da7219_priv *da7219 = snd_soc_codec_get_drvdata(codec);
1556 struct regulator *vddio;
1557 u8 io_voltage_lvl = DA7219_IO_VOLTAGE_LEVEL_2_5V_3_6V;
1558 int i, ret;
1559
1560 /* Get required supplies */
1561 for (i = 0; i < DA7219_NUM_SUPPLIES; ++i)
1562 da7219->supplies[i].supply = da7219_supply_names[i];
1563
1564 ret = devm_regulator_bulk_get(codec->dev, DA7219_NUM_SUPPLIES,
1565 da7219->supplies);
1566 if (ret) {
1567 dev_err(codec->dev, "Failed to get supplies");
1568 return ret;
1569 }
1570
1571 /* Determine VDDIO voltage provided */
1572 vddio = da7219->supplies[DA7219_SUPPLY_VDDIO].consumer;
1573 ret = regulator_get_voltage(vddio);
1574 if (ret < 1200000)
1575 dev_warn(codec->dev, "Invalid VDDIO voltage\n");
1576 else if (ret < 2800000)
1577 io_voltage_lvl = DA7219_IO_VOLTAGE_LEVEL_1_2V_2_8V;
1578
1579 /* Enable main supplies */
1580 ret = regulator_bulk_enable(DA7219_NUM_SUPPLIES, da7219->supplies);
1581 if (ret) {
1582 dev_err(codec->dev, "Failed to enable supplies");
1583 return ret;
1584 }
1585
1586 /* Ensure device in active mode */
1587 snd_soc_write(codec, DA7219_SYSTEM_ACTIVE, DA7219_SYSTEM_ACTIVE_MASK);
1588
1589 /* Update IO voltage level range */
1590 snd_soc_write(codec, DA7219_IO_CTRL, io_voltage_lvl);
1591
1592 return 0;
1593}
1594
1595static void da7219_handle_pdata(struct snd_soc_codec *codec)
1596{
1597 struct da7219_priv *da7219 = snd_soc_codec_get_drvdata(codec);
1598 struct da7219_pdata *pdata = da7219->pdata;
1599
1600 if (pdata) {
1601 u8 micbias_lvl = 0;
1602
1603 /* Internal LDO */
1604 switch (pdata->ldo_lvl_sel) {
1605 case DA7219_LDO_LVL_SEL_1_05V:
1606 case DA7219_LDO_LVL_SEL_1_10V:
1607 case DA7219_LDO_LVL_SEL_1_20V:
1608 case DA7219_LDO_LVL_SEL_1_40V:
1609 snd_soc_update_bits(codec, DA7219_LDO_CTRL,
1610 DA7219_LDO_LEVEL_SELECT_MASK,
1611 (pdata->ldo_lvl_sel <<
1612 DA7219_LDO_LEVEL_SELECT_SHIFT));
1613 break;
1614 }
1615
1616 /* Mic Bias voltages */
1617 switch (pdata->micbias_lvl) {
1618 case DA7219_MICBIAS_1_8V:
1619 case DA7219_MICBIAS_2_0V:
1620 case DA7219_MICBIAS_2_2V:
1621 case DA7219_MICBIAS_2_4V:
1622 case DA7219_MICBIAS_2_6V:
1623 micbias_lvl |= (pdata->micbias_lvl <<
1624 DA7219_MICBIAS1_LEVEL_SHIFT);
1625 break;
1626 }
1627
1628 snd_soc_write(codec, DA7219_MICBIAS_CTRL, micbias_lvl);
1629
1630 /* Mic */
1631 switch (pdata->mic_amp_in_sel) {
1632 case DA7219_MIC_AMP_IN_SEL_DIFF:
1633 case DA7219_MIC_AMP_IN_SEL_SE_P:
1634 case DA7219_MIC_AMP_IN_SEL_SE_N:
1635 snd_soc_write(codec, DA7219_MIC_1_SELECT,
1636 pdata->mic_amp_in_sel);
1637 break;
1638 }
1639 }
1640}
1641
1642static int da7219_probe(struct snd_soc_codec *codec)
1643{
1644 struct da7219_priv *da7219 = snd_soc_codec_get_drvdata(codec);
1645 int ret;
1646
1647 mutex_init(&da7219->lock);
1648
1649 /* Regulator configuration */
1650 ret = da7219_handle_supplies(codec);
1651 if (ret)
1652 return ret;
1653
1654 /* Handle DT/Platform data */
1655 if (codec->dev->of_node)
1656 da7219->pdata = da7219_of_to_pdata(codec);
1657 else
1658 da7219->pdata = dev_get_platdata(codec->dev);
1659
1660 da7219_handle_pdata(codec);
1661
1662 /* Check if MCLK provided */
1663 da7219->mclk = devm_clk_get(codec->dev, "mclk");
1664 if (IS_ERR(da7219->mclk)) {
1665 if (PTR_ERR(da7219->mclk) != -ENOENT)
1666 return PTR_ERR(da7219->mclk);
1667 else
1668 da7219->mclk = NULL;
1669 }
1670
1671 /* Default PC counter to free-running */
1672 snd_soc_update_bits(codec, DA7219_PC_COUNT, DA7219_PC_FREERUN_MASK,
1673 DA7219_PC_FREERUN_MASK);
1674
1675 /* Default gain ramping */
1676 snd_soc_update_bits(codec, DA7219_MIXIN_L_CTRL,
1677 DA7219_MIXIN_L_AMP_RAMP_EN_MASK,
1678 DA7219_MIXIN_L_AMP_RAMP_EN_MASK);
1679 snd_soc_update_bits(codec, DA7219_ADC_L_CTRL, DA7219_ADC_L_RAMP_EN_MASK,
1680 DA7219_ADC_L_RAMP_EN_MASK);
1681 snd_soc_update_bits(codec, DA7219_DAC_L_CTRL, DA7219_DAC_L_RAMP_EN_MASK,
1682 DA7219_DAC_L_RAMP_EN_MASK);
1683 snd_soc_update_bits(codec, DA7219_DAC_R_CTRL, DA7219_DAC_R_RAMP_EN_MASK,
1684 DA7219_DAC_R_RAMP_EN_MASK);
1685 snd_soc_update_bits(codec, DA7219_HP_L_CTRL,
1686 DA7219_HP_L_AMP_RAMP_EN_MASK,
1687 DA7219_HP_L_AMP_RAMP_EN_MASK);
1688 snd_soc_update_bits(codec, DA7219_HP_R_CTRL,
1689 DA7219_HP_R_AMP_RAMP_EN_MASK,
1690 DA7219_HP_R_AMP_RAMP_EN_MASK);
1691
1692 /* Default infinite tone gen, start/stop by Kcontrol */
1693 snd_soc_write(codec, DA7219_TONE_GEN_CYCLES, DA7219_BEEP_CYCLES_MASK);
1694
1695 /* Initialise AAD block */
1696 return da7219_aad_init(codec);
1697}
1698
1699static int da7219_remove(struct snd_soc_codec *codec)
1700{
1701 struct da7219_priv *da7219 = snd_soc_codec_get_drvdata(codec);
1702
1703 da7219_aad_exit(codec);
1704
1705 /* Supplies */
1706 return regulator_bulk_disable(DA7219_NUM_SUPPLIES, da7219->supplies);
1707}
1708
1709#ifdef CONFIG_PM
1710static int da7219_suspend(struct snd_soc_codec *codec)
1711{
1712 struct da7219_priv *da7219 = snd_soc_codec_get_drvdata(codec);
1713
1714 snd_soc_codec_force_bias_level(codec, SND_SOC_BIAS_OFF);
1715
1716 /* Put device into standby mode if jack detection disabled */
1717 if (!da7219->aad->jack)
1718 snd_soc_write(codec, DA7219_SYSTEM_ACTIVE, 0);
1719
1720 return 0;
1721}
1722
1723static int da7219_resume(struct snd_soc_codec *codec)
1724{
1725 struct da7219_priv *da7219 = snd_soc_codec_get_drvdata(codec);
1726
1727 /* Put device into active mode if previously pushed to standby */
1728 if (!da7219->aad->jack)
1729 snd_soc_write(codec, DA7219_SYSTEM_ACTIVE,
1730 DA7219_SYSTEM_ACTIVE_MASK);
1731
1732 snd_soc_codec_force_bias_level(codec, SND_SOC_BIAS_STANDBY);
1733
1734 return 0;
1735}
1736#else
1737#define da7219_suspend NULL
1738#define da7219_resume NULL
1739#endif
1740
1741static struct snd_soc_codec_driver soc_codec_dev_da7219 = {
1742 .probe = da7219_probe,
1743 .remove = da7219_remove,
1744 .suspend = da7219_suspend,
1745 .resume = da7219_resume,
1746 .set_bias_level = da7219_set_bias_level,
1747
1748 .controls = da7219_snd_controls,
1749 .num_controls = ARRAY_SIZE(da7219_snd_controls),
1750
1751 .dapm_widgets = da7219_dapm_widgets,
1752 .num_dapm_widgets = ARRAY_SIZE(da7219_dapm_widgets),
1753 .dapm_routes = da7219_audio_map,
1754 .num_dapm_routes = ARRAY_SIZE(da7219_audio_map),
1755};
1756
1757
1758/*
1759 * Regmap configs
1760 */
1761
1762static struct reg_default da7219_reg_defaults[] = {
1763 { DA7219_MIC_1_SELECT, 0x00 },
1764 { DA7219_CIF_TIMEOUT_CTRL, 0x01 },
1765 { DA7219_SR_24_48, 0x00 },
1766 { DA7219_SR, 0x0A },
1767 { DA7219_CIF_I2C_ADDR_CFG, 0x02 },
1768 { DA7219_PLL_CTRL, 0x10 },
1769 { DA7219_PLL_FRAC_TOP, 0x00 },
1770 { DA7219_PLL_FRAC_BOT, 0x00 },
1771 { DA7219_PLL_INTEGER, 0x20 },
1772 { DA7219_DIG_ROUTING_DAI, 0x10 },
1773 { DA7219_DAI_CLK_MODE, 0x01 },
1774 { DA7219_DAI_CTRL, 0x28 },
1775 { DA7219_DAI_TDM_CTRL, 0x40 },
1776 { DA7219_DIG_ROUTING_DAC, 0x32 },
1777 { DA7219_DAI_OFFSET_LOWER, 0x00 },
1778 { DA7219_DAI_OFFSET_UPPER, 0x00 },
1779 { DA7219_REFERENCES, 0x00 },
1780 { DA7219_MIXIN_L_SELECT, 0x00 },
1781 { DA7219_MIXIN_L_GAIN, 0x03 },
1782 { DA7219_ADC_L_GAIN, 0x6F },
1783 { DA7219_ADC_FILTERS1, 0x80 },
1784 { DA7219_MIC_1_GAIN, 0x01 },
1785 { DA7219_SIDETONE_CTRL, 0x40 },
1786 { DA7219_SIDETONE_GAIN, 0x0E },
1787 { DA7219_DROUTING_ST_OUTFILT_1L, 0x01 },
1788 { DA7219_DROUTING_ST_OUTFILT_1R, 0x02 },
1789 { DA7219_DAC_FILTERS5, 0x00 },
1790 { DA7219_DAC_FILTERS2, 0x88 },
1791 { DA7219_DAC_FILTERS3, 0x88 },
1792 { DA7219_DAC_FILTERS4, 0x08 },
1793 { DA7219_DAC_FILTERS1, 0x80 },
1794 { DA7219_DAC_L_GAIN, 0x6F },
1795 { DA7219_DAC_R_GAIN, 0x6F },
1796 { DA7219_CP_CTRL, 0x20 },
1797 { DA7219_HP_L_GAIN, 0x39 },
1798 { DA7219_HP_R_GAIN, 0x39 },
1799 { DA7219_MIXOUT_L_SELECT, 0x00 },
1800 { DA7219_MIXOUT_R_SELECT, 0x00 },
1801 { DA7219_MICBIAS_CTRL, 0x03 },
1802 { DA7219_MIC_1_CTRL, 0x40 },
1803 { DA7219_MIXIN_L_CTRL, 0x40 },
1804 { DA7219_ADC_L_CTRL, 0x40 },
1805 { DA7219_DAC_L_CTRL, 0x40 },
1806 { DA7219_DAC_R_CTRL, 0x40 },
1807 { DA7219_HP_L_CTRL, 0x40 },
1808 { DA7219_HP_R_CTRL, 0x40 },
1809 { DA7219_MIXOUT_L_CTRL, 0x10 },
1810 { DA7219_MIXOUT_R_CTRL, 0x10 },
1811 { DA7219_CHIP_ID1, 0x23 },
1812 { DA7219_CHIP_ID2, 0x93 },
1813 { DA7219_CHIP_REVISION, 0x00 },
1814 { DA7219_LDO_CTRL, 0x00 },
1815 { DA7219_IO_CTRL, 0x00 },
1816 { DA7219_GAIN_RAMP_CTRL, 0x00 },
1817 { DA7219_PC_COUNT, 0x02 },
1818 { DA7219_CP_VOL_THRESHOLD1, 0x0E },
1819 { DA7219_DIG_CTRL, 0x00 },
1820 { DA7219_ALC_CTRL2, 0x00 },
1821 { DA7219_ALC_CTRL3, 0x00 },
1822 { DA7219_ALC_NOISE, 0x3F },
1823 { DA7219_ALC_TARGET_MIN, 0x3F },
1824 { DA7219_ALC_TARGET_MAX, 0x00 },
1825 { DA7219_ALC_GAIN_LIMITS, 0xFF },
1826 { DA7219_ALC_ANA_GAIN_LIMITS, 0x71 },
1827 { DA7219_ALC_ANTICLIP_CTRL, 0x00 },
1828 { DA7219_ALC_ANTICLIP_LEVEL, 0x00 },
1829 { DA7219_DAC_NG_SETUP_TIME, 0x00 },
1830 { DA7219_DAC_NG_OFF_THRESH, 0x00 },
1831 { DA7219_DAC_NG_ON_THRESH, 0x00 },
1832 { DA7219_DAC_NG_CTRL, 0x00 },
1833 { DA7219_TONE_GEN_CFG1, 0x00 },
1834 { DA7219_TONE_GEN_CFG2, 0x00 },
1835 { DA7219_TONE_GEN_CYCLES, 0x00 },
1836 { DA7219_TONE_GEN_FREQ1_L, 0x55 },
1837 { DA7219_TONE_GEN_FREQ1_U, 0x15 },
1838 { DA7219_TONE_GEN_FREQ2_L, 0x00 },
1839 { DA7219_TONE_GEN_FREQ2_U, 0x40 },
1840 { DA7219_TONE_GEN_ON_PER, 0x02 },
1841 { DA7219_TONE_GEN_OFF_PER, 0x01 },
1842 { DA7219_ACCDET_IRQ_MASK_A, 0x00 },
1843 { DA7219_ACCDET_IRQ_MASK_B, 0x00 },
1844 { DA7219_ACCDET_CONFIG_1, 0xD6 },
1845 { DA7219_ACCDET_CONFIG_2, 0x34 },
1846 { DA7219_ACCDET_CONFIG_3, 0x0A },
1847 { DA7219_ACCDET_CONFIG_4, 0x16 },
1848 { DA7219_ACCDET_CONFIG_5, 0x21 },
1849 { DA7219_ACCDET_CONFIG_6, 0x3E },
1850 { DA7219_ACCDET_CONFIG_7, 0x01 },
1851 { DA7219_SYSTEM_ACTIVE, 0x00 },
1852};
1853
1854static bool da7219_volatile_register(struct device *dev, unsigned int reg)
1855{
1856 switch (reg) {
1857 case DA7219_MIC_1_GAIN_STATUS:
1858 case DA7219_MIXIN_L_GAIN_STATUS:
1859 case DA7219_ADC_L_GAIN_STATUS:
1860 case DA7219_DAC_L_GAIN_STATUS:
1861 case DA7219_DAC_R_GAIN_STATUS:
1862 case DA7219_HP_L_GAIN_STATUS:
1863 case DA7219_HP_R_GAIN_STATUS:
1864 case DA7219_CIF_CTRL:
1865 case DA7219_PLL_SRM_STS:
1866 case DA7219_ALC_CTRL1:
1867 case DA7219_SYSTEM_MODES_INPUT:
1868 case DA7219_SYSTEM_MODES_OUTPUT:
1869 case DA7219_ALC_OFFSET_AUTO_M_L:
1870 case DA7219_ALC_OFFSET_AUTO_U_L:
1871 case DA7219_TONE_GEN_CFG1:
1872 case DA7219_ACCDET_STATUS_A:
1873 case DA7219_ACCDET_STATUS_B:
1874 case DA7219_ACCDET_IRQ_EVENT_A:
1875 case DA7219_ACCDET_IRQ_EVENT_B:
1876 case DA7219_ACCDET_CONFIG_8:
1877 case DA7219_SYSTEM_STATUS:
1878 return 1;
1879 default:
1880 return 0;
1881 }
1882}
1883
1884static const struct regmap_config da7219_regmap_config = {
1885 .reg_bits = 8,
1886 .val_bits = 8,
1887
1888 .max_register = DA7219_SYSTEM_ACTIVE,
1889 .reg_defaults = da7219_reg_defaults,
1890 .num_reg_defaults = ARRAY_SIZE(da7219_reg_defaults),
1891 .volatile_reg = da7219_volatile_register,
1892 .cache_type = REGCACHE_RBTREE,
1893};
1894
1895
1896/*
1897 * I2C layer
1898 */
1899
1900static int da7219_i2c_probe(struct i2c_client *i2c,
1901 const struct i2c_device_id *id)
1902{
1903 struct da7219_priv *da7219;
1904 int ret;
1905
1906 da7219 = devm_kzalloc(&i2c->dev, sizeof(struct da7219_priv),
1907 GFP_KERNEL);
1908 if (!da7219)
1909 return -ENOMEM;
1910
1911 i2c_set_clientdata(i2c, da7219);
1912
1913 da7219->regmap = devm_regmap_init_i2c(i2c, &da7219_regmap_config);
1914 if (IS_ERR(da7219->regmap)) {
1915 ret = PTR_ERR(da7219->regmap);
1916 dev_err(&i2c->dev, "regmap_init() failed: %d\n", ret);
1917 return ret;
1918 }
1919
1920 ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_da7219,
1921 &da7219_dai, 1);
1922 if (ret < 0) {
1923 dev_err(&i2c->dev, "Failed to register da7219 codec: %d\n",
1924 ret);
1925 }
1926 return ret;
1927}
1928
1929static int da7219_i2c_remove(struct i2c_client *client)
1930{
1931 snd_soc_unregister_codec(&client->dev);
1932 return 0;
1933}
1934
1935static const struct i2c_device_id da7219_i2c_id[] = {
1936 { "da7219", },
1937 { }
1938};
1939MODULE_DEVICE_TABLE(i2c, da7219_i2c_id);
1940
1941static struct i2c_driver da7219_i2c_driver = {
1942 .driver = {
1943 .name = "da7219",
1944 .of_match_table = of_match_ptr(da7219_of_match),
1945 },
1946 .probe = da7219_i2c_probe,
1947 .remove = da7219_i2c_remove,
1948 .id_table = da7219_i2c_id,
1949};
1950
1951module_i2c_driver(da7219_i2c_driver);
1952
1953MODULE_DESCRIPTION("ASoC DA7219 Codec Driver");
1954MODULE_AUTHOR("Adam Thomson <Adam.Thomson.Opensource@diasemi.com>");
1955MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/da7219.h b/sound/soc/codecs/da7219.h
new file mode 100644
index 000000000000..b514268c6c56
--- /dev/null
+++ b/sound/soc/codecs/da7219.h
@@ -0,0 +1,820 @@
1/*
2 * da7219.h - DA7219 ALSA SoC Codec Driver
3 *
4 * Copyright (c) 2015 Dialog Semiconductor
5 *
6 * Author: Adam Thomson <Adam.Thomson.Opensource@diasemi.com>
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the
10 * Free Software Foundation; either version 2 of the License, or (at your
11 * option) any later version.
12 */
13
14#ifndef __DA7219_H
15#define __DA7219_H
16
17#include <linux/regmap.h>
18#include <linux/regulator/consumer.h>
19#include <sound/da7219.h>
20
21/*
22 * Registers
23 */
24
25#define DA7219_MIC_1_GAIN_STATUS 0x6
26#define DA7219_MIXIN_L_GAIN_STATUS 0x8
27#define DA7219_ADC_L_GAIN_STATUS 0xA
28#define DA7219_DAC_L_GAIN_STATUS 0xC
29#define DA7219_DAC_R_GAIN_STATUS 0xD
30#define DA7219_HP_L_GAIN_STATUS 0xE
31#define DA7219_HP_R_GAIN_STATUS 0xF
32#define DA7219_MIC_1_SELECT 0x10
33#define DA7219_CIF_TIMEOUT_CTRL 0x12
34#define DA7219_CIF_CTRL 0x13
35#define DA7219_SR_24_48 0x16
36#define DA7219_SR 0x17
37#define DA7219_CIF_I2C_ADDR_CFG 0x1B
38#define DA7219_PLL_CTRL 0x20
39#define DA7219_PLL_FRAC_TOP 0x22
40#define DA7219_PLL_FRAC_BOT 0x23
41#define DA7219_PLL_INTEGER 0x24
42#define DA7219_PLL_SRM_STS 0x25
43#define DA7219_DIG_ROUTING_DAI 0x2A
44#define DA7219_DAI_CLK_MODE 0x2B
45#define DA7219_DAI_CTRL 0x2C
46#define DA7219_DAI_TDM_CTRL 0x2D
47#define DA7219_DIG_ROUTING_DAC 0x2E
48#define DA7219_ALC_CTRL1 0x2F
49#define DA7219_DAI_OFFSET_LOWER 0x30
50#define DA7219_DAI_OFFSET_UPPER 0x31
51#define DA7219_REFERENCES 0x32
52#define DA7219_MIXIN_L_SELECT 0x33
53#define DA7219_MIXIN_L_GAIN 0x34
54#define DA7219_ADC_L_GAIN 0x36
55#define DA7219_ADC_FILTERS1 0x38
56#define DA7219_MIC_1_GAIN 0x39
57#define DA7219_SIDETONE_CTRL 0x3A
58#define DA7219_SIDETONE_GAIN 0x3B
59#define DA7219_DROUTING_ST_OUTFILT_1L 0x3C
60#define DA7219_DROUTING_ST_OUTFILT_1R 0x3D
61#define DA7219_DAC_FILTERS5 0x40
62#define DA7219_DAC_FILTERS2 0x41
63#define DA7219_DAC_FILTERS3 0x42
64#define DA7219_DAC_FILTERS4 0x43
65#define DA7219_DAC_FILTERS1 0x44
66#define DA7219_DAC_L_GAIN 0x45
67#define DA7219_DAC_R_GAIN 0x46
68#define DA7219_CP_CTRL 0x47
69#define DA7219_HP_L_GAIN 0x48
70#define DA7219_HP_R_GAIN 0x49
71#define DA7219_MIXOUT_L_SELECT 0x4B
72#define DA7219_MIXOUT_R_SELECT 0x4C
73#define DA7219_SYSTEM_MODES_INPUT 0x50
74#define DA7219_SYSTEM_MODES_OUTPUT 0x51
75#define DA7219_MICBIAS_CTRL 0x62
76#define DA7219_MIC_1_CTRL 0x63
77#define DA7219_MIXIN_L_CTRL 0x65
78#define DA7219_ADC_L_CTRL 0x67
79#define DA7219_DAC_L_CTRL 0x69
80#define DA7219_DAC_R_CTRL 0x6A
81#define DA7219_HP_L_CTRL 0x6B
82#define DA7219_HP_R_CTRL 0x6C
83#define DA7219_MIXOUT_L_CTRL 0x6E
84#define DA7219_MIXOUT_R_CTRL 0x6F
85#define DA7219_CHIP_ID1 0x81
86#define DA7219_CHIP_ID2 0x82
87#define DA7219_CHIP_REVISION 0x83
88#define DA7219_LDO_CTRL 0x90
89#define DA7219_IO_CTRL 0x91
90#define DA7219_GAIN_RAMP_CTRL 0x92
91#define DA7219_PC_COUNT 0x94
92#define DA7219_CP_VOL_THRESHOLD1 0x95
93#define DA7219_CP_DELAY 0x96
94#define DA7219_DIG_CTRL 0x99
95#define DA7219_ALC_CTRL2 0x9A
96#define DA7219_ALC_CTRL3 0x9B
97#define DA7219_ALC_NOISE 0x9C
98#define DA7219_ALC_TARGET_MIN 0x9D
99#define DA7219_ALC_TARGET_MAX 0x9E
100#define DA7219_ALC_GAIN_LIMITS 0x9F
101#define DA7219_ALC_ANA_GAIN_LIMITS 0xA0
102#define DA7219_ALC_ANTICLIP_CTRL 0xA1
103#define DA7219_ALC_ANTICLIP_LEVEL 0xA2
104#define DA7219_ALC_OFFSET_AUTO_M_L 0xA3
105#define DA7219_ALC_OFFSET_AUTO_U_L 0xA4
106#define DA7219_DAC_NG_SETUP_TIME 0xAF
107#define DA7219_DAC_NG_OFF_THRESH 0xB0
108#define DA7219_DAC_NG_ON_THRESH 0xB1
109#define DA7219_DAC_NG_CTRL 0xB2
110#define DA7219_TONE_GEN_CFG1 0xB4
111#define DA7219_TONE_GEN_CFG2 0xB5
112#define DA7219_TONE_GEN_CYCLES 0xB6
113#define DA7219_TONE_GEN_FREQ1_L 0xB7
114#define DA7219_TONE_GEN_FREQ1_U 0xB8
115#define DA7219_TONE_GEN_FREQ2_L 0xB9
116#define DA7219_TONE_GEN_FREQ2_U 0xBA
117#define DA7219_TONE_GEN_ON_PER 0xBB
118#define DA7219_TONE_GEN_OFF_PER 0xBC
119#define DA7219_SYSTEM_STATUS 0xE0
120#define DA7219_SYSTEM_ACTIVE 0xFD
121
122
123/*
124 * Bit Fields
125 */
126
127#define DA7219_SWITCH_EN_MAX 0x1
128
129/* DA7219_MIC_1_GAIN_STATUS = 0x6 */
130#define DA7219_MIC_1_AMP_GAIN_STATUS_SHIFT 0
131#define DA7219_MIC_1_AMP_GAIN_STATUS_MASK (0x7 << 0)
132#define DA7219_MIC_1_AMP_GAIN_MAX 0x7
133
134/* DA7219_MIXIN_L_GAIN_STATUS = 0x8 */
135#define DA7219_MIXIN_L_AMP_GAIN_STATUS_SHIFT 0
136#define DA7219_MIXIN_L_AMP_GAIN_STATUS_MASK (0xF << 0)
137
138/* DA7219_ADC_L_GAIN_STATUS = 0xA */
139#define DA7219_ADC_L_DIGITAL_GAIN_STATUS_SHIFT 0
140#define DA7219_ADC_L_DIGITAL_GAIN_STATUS_MASK (0x7F << 0)
141
142/* DA7219_DAC_L_GAIN_STATUS = 0xC */
143#define DA7219_DAC_L_DIGITAL_GAIN_STATUS_SHIFT 0
144#define DA7219_DAC_L_DIGITAL_GAIN_STATUS_MASK (0x7F << 0)
145
146/* DA7219_DAC_R_GAIN_STATUS = 0xD */
147#define DA7219_DAC_R_DIGITAL_GAIN_STATUS_SHIFT 0
148#define DA7219_DAC_R_DIGITAL_GAIN_STATUS_MASK (0x7F << 0)
149
150/* DA7219_HP_L_GAIN_STATUS = 0xE */
151#define DA7219_HP_L_AMP_GAIN_STATUS_SHIFT 0
152#define DA7219_HP_L_AMP_GAIN_STATUS_MASK (0x3F << 0)
153
154/* DA7219_HP_R_GAIN_STATUS = 0xF */
155#define DA7219_HP_R_AMP_GAIN_STATUS_SHIFT 0
156#define DA7219_HP_R_AMP_GAIN_STATUS_MASK (0x3F << 0)
157
158/* DA7219_MIC_1_SELECT = 0x10 */
159#define DA7219_MIC_1_AMP_IN_SEL_SHIFT 0
160#define DA7219_MIC_1_AMP_IN_SEL_MASK (0x3 << 0)
161
162/* DA7219_CIF_TIMEOUT_CTRL = 0x12 */
163#define DA7219_I2C_TIMEOUT_EN_SHIFT 0
164#define DA7219_I2C_TIMEOUT_EN_MASK (0x1 << 0)
165
166/* DA7219_CIF_CTRL = 0x13 */
167#define DA7219_CIF_I2C_WRITE_MODE_SHIFT 0
168#define DA7219_CIF_I2C_WRITE_MODE_MASK (0x1 << 0)
169#define DA7219_CIF_REG_SOFT_RESET_SHIFT 7
170#define DA7219_CIF_REG_SOFT_RESET_MASK (0x1 << 7)
171
172/* DA7219_SR_24_48 = 0x16 */
173#define DA7219_SR_24_48_SHIFT 0
174#define DA7219_SR_24_48_MASK (0x1 << 0)
175
176/* DA7219_SR = 0x17 */
177#define DA7219_SR_SHIFT 0
178#define DA7219_SR_MASK (0xF << 0)
179#define DA7219_SR_8000 (0x01 << 0)
180#define DA7219_SR_11025 (0x02 << 0)
181#define DA7219_SR_12000 (0x03 << 0)
182#define DA7219_SR_16000 (0x05 << 0)
183#define DA7219_SR_22050 (0x06 << 0)
184#define DA7219_SR_24000 (0x07 << 0)
185#define DA7219_SR_32000 (0x09 << 0)
186#define DA7219_SR_44100 (0x0A << 0)
187#define DA7219_SR_48000 (0x0B << 0)
188#define DA7219_SR_88200 (0x0E << 0)
189#define DA7219_SR_96000 (0x0F << 0)
190
191/* DA7219_CIF_I2C_ADDR_CFG = 0x1B */
192#define DA7219_CIF_I2C_ADDR_CFG_SHIFT 0
193#define DA7219_CIF_I2C_ADDR_CFG_MASK (0x3 << 0)
194
195/* DA7219_PLL_CTRL = 0x20 */
196#define DA7219_PLL_INDIV_SHIFT 2
197#define DA7219_PLL_INDIV_MASK (0x7 << 2)
198#define DA7219_PLL_INDIV_2_5_MHZ (0x0 << 2)
199#define DA7219_PLL_INDIV_5_10_MHZ (0x1 << 2)
200#define DA7219_PLL_INDIV_10_20_MHZ (0x2 << 2)
201#define DA7219_PLL_INDIV_20_40_MHZ (0x3 << 2)
202#define DA7219_PLL_INDIV_40_54_MHZ (0x4 << 2)
203#define DA7219_PLL_MCLK_SQR_EN_SHIFT 5
204#define DA7219_PLL_MCLK_SQR_EN_MASK (0x1 << 5)
205#define DA7219_PLL_MODE_SHIFT 6
206#define DA7219_PLL_MODE_MASK (0x3 << 6)
207#define DA7219_PLL_MODE_BYPASS (0x0 << 6)
208#define DA7219_PLL_MODE_NORMAL (0x1 << 6)
209#define DA7219_PLL_MODE_SRM (0x2 << 6)
210#define DA7219_PLL_MODE_32KHZ (0x3 << 6)
211
212/* DA7219_PLL_FRAC_TOP = 0x22 */
213#define DA7219_PLL_FBDIV_FRAC_TOP_SHIFT 0
214#define DA7219_PLL_FBDIV_FRAC_TOP_MASK (0x1F << 0)
215
216/* DA7219_PLL_FRAC_BOT = 0x23 */
217#define DA7219_PLL_FBDIV_FRAC_BOT_SHIFT 0
218#define DA7219_PLL_FBDIV_FRAC_BOT_MASK (0xFF << 0)
219
220/* DA7219_PLL_INTEGER = 0x24 */
221#define DA7219_PLL_FBDIV_INTEGER_SHIFT 0
222#define DA7219_PLL_FBDIV_INTEGER_MASK (0x7F << 0)
223
224/* DA7219_PLL_SRM_STS = 0x25 */
225#define DA7219_PLL_SRM_STATE_SHIFT 0
226#define DA7219_PLL_SRM_STATE_MASK (0xF << 0)
227#define DA7219_PLL_SRM_STATUS_SHIFT 4
228#define DA7219_PLL_SRM_STATUS_MASK (0xF << 4)
229#define DA7219_PLL_SRM_STS_SRM_LOCK (0x1 << 7)
230
231/* DA7219_DIG_ROUTING_DAI = 0x2A */
232#define DA7219_DAI_L_SRC_SHIFT 0
233#define DA7219_DAI_L_SRC_MASK (0x3 << 0)
234#define DA7219_DAI_R_SRC_SHIFT 4
235#define DA7219_DAI_R_SRC_MASK (0x3 << 4)
236#define DA7219_OUT_SRC_MAX 4
237
238/* DA7219_DAI_CLK_MODE = 0x2B */
239#define DA7219_DAI_BCLKS_PER_WCLK_SHIFT 0
240#define DA7219_DAI_BCLKS_PER_WCLK_MASK (0x3 << 0)
241#define DA7219_DAI_BCLKS_PER_WCLK_32 (0x0 << 0)
242#define DA7219_DAI_BCLKS_PER_WCLK_64 (0x1 << 0)
243#define DA7219_DAI_BCLKS_PER_WCLK_128 (0x2 << 0)
244#define DA7219_DAI_BCLKS_PER_WCLK_256 (0x3 << 0)
245#define DA7219_DAI_CLK_POL_SHIFT 2
246#define DA7219_DAI_CLK_POL_MASK (0x1 << 2)
247#define DA7219_DAI_CLK_POL_INV (0x1 << 2)
248#define DA7219_DAI_WCLK_POL_SHIFT 3
249#define DA7219_DAI_WCLK_POL_MASK (0x1 << 3)
250#define DA7219_DAI_WCLK_POL_INV (0x1 << 3)
251#define DA7219_DAI_WCLK_TRI_STATE_SHIFT 4
252#define DA7219_DAI_WCLK_TRI_STATE_MASK (0x1 << 4)
253#define DA7219_DAI_CLK_EN_SHIFT 7
254#define DA7219_DAI_CLK_EN_MASK (0x1 << 7)
255
256/* DA7219_DAI_CTRL = 0x2C */
257#define DA7219_DAI_FORMAT_SHIFT 0
258#define DA7219_DAI_FORMAT_MASK (0x3 << 0)
259#define DA7219_DAI_FORMAT_I2S (0x0 << 0)
260#define DA7219_DAI_FORMAT_LEFT_J (0x1 << 0)
261#define DA7219_DAI_FORMAT_RIGHT_J (0x2 << 0)
262#define DA7219_DAI_FORMAT_DSP (0x3 << 0)
263#define DA7219_DAI_WORD_LENGTH_SHIFT 2
264#define DA7219_DAI_WORD_LENGTH_MASK (0x3 << 2)
265#define DA7219_DAI_WORD_LENGTH_S16_LE (0x0 << 2)
266#define DA7219_DAI_WORD_LENGTH_S20_LE (0x1 << 2)
267#define DA7219_DAI_WORD_LENGTH_S24_LE (0x2 << 2)
268#define DA7219_DAI_WORD_LENGTH_S32_LE (0x3 << 2)
269#define DA7219_DAI_CH_NUM_SHIFT 4
270#define DA7219_DAI_CH_NUM_MASK (0x3 << 4)
271#define DA7219_DAI_CH_NUM_MAX 2
272#define DA7219_DAI_EN_SHIFT 7
273#define DA7219_DAI_EN_MASK (0x1 << 7)
274
275/* DA7219_DAI_TDM_CTRL = 0x2D */
276#define DA7219_DAI_TDM_CH_EN_SHIFT 0
277#define DA7219_DAI_TDM_CH_EN_MASK (0x3 << 0)
278#define DA7219_DAI_OE_SHIFT 6
279#define DA7219_DAI_OE_MASK (0x1 << 6)
280#define DA7219_DAI_TDM_MODE_EN_SHIFT 7
281#define DA7219_DAI_TDM_MODE_EN_MASK (0x1 << 7)
282#define DA7219_DAI_TDM_MAX_SLOTS 2
283
284/* DA7219_DIG_ROUTING_DAC = 0x2E */
285#define DA7219_DAC_L_SRC_SHIFT 0
286#define DA7219_DAC_L_SRC_MASK (0x3 << 0)
287#define DA7219_DAC_L_SRC_TONEGEN (0x1 << 0)
288#define DA7219_DAC_L_MONO_SHIFT 3
289#define DA7219_DAC_L_MONO_MASK (0x1 << 3)
290#define DA7219_DAC_R_SRC_SHIFT 4
291#define DA7219_DAC_R_SRC_MASK (0x3 << 4)
292#define DA7219_DAC_R_SRC_TONEGEN (0x1 << 4)
293#define DA7219_DAC_R_MONO_SHIFT 7
294#define DA7219_DAC_R_MONO_MASK (0x1 << 7)
295
296/* DA7219_ALC_CTRL1 = 0x2F */
297#define DA7219_ALC_OFFSET_EN_SHIFT 0
298#define DA7219_ALC_OFFSET_EN_MASK (0x1 << 0)
299#define DA7219_ALC_SYNC_MODE_SHIFT 1
300#define DA7219_ALC_SYNC_MODE_MASK (0x1 << 1)
301#define DA7219_ALC_EN_SHIFT 3
302#define DA7219_ALC_EN_MASK (0x1 << 3)
303#define DA7219_ALC_AUTO_CALIB_EN_SHIFT 4
304#define DA7219_ALC_AUTO_CALIB_EN_MASK (0x1 << 4)
305#define DA7219_ALC_CALIB_OVERFLOW_SHIFT 5
306#define DA7219_ALC_CALIB_OVERFLOW_MASK (0x1 << 5)
307
308/* DA7219_DAI_OFFSET_LOWER = 0x30 */
309#define DA7219_DAI_OFFSET_LOWER_SHIFT 0
310#define DA7219_DAI_OFFSET_LOWER_MASK (0xFF << 0)
311
312/* DA7219_DAI_OFFSET_UPPER = 0x31 */
313#define DA7219_DAI_OFFSET_UPPER_SHIFT 0
314#define DA7219_DAI_OFFSET_UPPER_MASK (0x7 << 0)
315#define DA7219_DAI_OFFSET_MAX 0x2FF
316
317/* DA7219_REFERENCES = 0x32 */
318#define DA7219_BIAS_EN_SHIFT 3
319#define DA7219_BIAS_EN_MASK (0x1 << 3)
320#define DA7219_VMID_FAST_CHARGE_SHIFT 4
321#define DA7219_VMID_FAST_CHARGE_MASK (0x1 << 4)
322
323/* DA7219_MIXIN_L_SELECT = 0x33 */
324#define DA7219_MIXIN_L_MIX_SELECT_SHIFT 0
325#define DA7219_MIXIN_L_MIX_SELECT_MASK (0x1 << 0)
326
327/* DA7219_MIXIN_L_GAIN = 0x34 */
328#define DA7219_MIXIN_L_AMP_GAIN_SHIFT 0
329#define DA7219_MIXIN_L_AMP_GAIN_MASK (0xF << 0)
330#define DA7219_MIXIN_L_AMP_GAIN_MAX 0xF
331
332/* DA7219_ADC_L_GAIN = 0x36 */
333#define DA7219_ADC_L_DIGITAL_GAIN_SHIFT 0
334#define DA7219_ADC_L_DIGITAL_GAIN_MASK (0x7F << 0)
335#define DA7219_ADC_L_DIGITAL_GAIN_MAX 0x7F
336
337/* DA7219_ADC_FILTERS1 = 0x38 */
338#define DA7219_ADC_VOICE_HPF_CORNER_SHIFT 0
339#define DA7219_ADC_VOICE_HPF_CORNER_MASK (0x7 << 0)
340#define DA7219_VOICE_HPF_CORNER_MAX 8
341#define DA7219_ADC_VOICE_EN_SHIFT 3
342#define DA7219_ADC_VOICE_EN_MASK (0x1 << 3)
343#define DA7219_ADC_AUDIO_HPF_CORNER_SHIFT 4
344#define DA7219_ADC_AUDIO_HPF_CORNER_MASK (0x3 << 4)
345#define DA7219_AUDIO_HPF_CORNER_MAX 4
346#define DA7219_ADC_HPF_EN_SHIFT 7
347#define DA7219_ADC_HPF_EN_MASK (0x1 << 7)
348#define DA7219_HPF_MODE_SHIFT 0
349#define DA7219_HPF_DISABLED ((0x0 << 3) | (0x0 << 7))
350#define DA7219_HPF_AUDIO_EN ((0x0 << 3) | (0x1 << 7))
351#define DA7219_HPF_VOICE_EN ((0x1 << 3) | (0x1 << 7))
352#define DA7219_HPF_MODE_MASK ((0x1 << 3) | (0x1 << 7))
353#define DA7219_HPF_MODE_MAX 3
354
355/* DA7219_MIC_1_GAIN = 0x39 */
356#define DA7219_MIC_1_AMP_GAIN_SHIFT 0
357#define DA7219_MIC_1_AMP_GAIN_MASK (0x7 << 0)
358
359/* DA7219_SIDETONE_CTRL = 0x3A */
360#define DA7219_SIDETONE_MUTE_EN_SHIFT 6
361#define DA7219_SIDETONE_MUTE_EN_MASK (0x1 << 6)
362#define DA7219_SIDETONE_EN_SHIFT 7
363#define DA7219_SIDETONE_EN_MASK (0x1 << 7)
364
365/* DA7219_SIDETONE_GAIN = 0x3B */
366#define DA7219_SIDETONE_GAIN_SHIFT 0
367#define DA7219_SIDETONE_GAIN_MASK (0xF << 0)
368#define DA7219_SIDETONE_GAIN_MAX 0xE
369
370/* DA7219_DROUTING_ST_OUTFILT_1L = 0x3C */
371#define DA7219_OUTFILT_ST_1L_SRC_SHIFT 0
372#define DA7219_OUTFILT_ST_1L_SRC_MASK (0x7 << 0)
373#define DA7219_DMIX_ST_SRC_OUTFILT1L_SHIFT 0
374#define DA7219_DMIX_ST_SRC_OUTFILT1R_SHIFT 1
375#define DA7219_DMIX_ST_SRC_SIDETONE_SHIFT 2
376#define DA7219_DMIX_ST_SRC_OUTFILT1L (0x1 << 0)
377#define DA7219_DMIX_ST_SRC_OUTFILT1R (0x1 << 1)
378
379/* DA7219_DROUTING_ST_OUTFILT_1R = 0x3D */
380#define DA7219_OUTFILT_ST_1R_SRC_SHIFT 0
381#define DA7219_OUTFILT_ST_1R_SRC_MASK (0x7 << 0)
382
383/* DA7219_DAC_FILTERS5 = 0x40 */
384#define DA7219_DAC_SOFTMUTE_RATE_SHIFT 4
385#define DA7219_DAC_SOFTMUTE_RATE_MASK (0x7 << 4)
386#define DA7219_DAC_SOFTMUTE_RATE_MAX 7
387#define DA7219_DAC_SOFTMUTE_EN_SHIFT 7
388#define DA7219_DAC_SOFTMUTE_EN_MASK (0x1 << 7)
389
390/* DA7219_DAC_FILTERS2 = 0x41 */
391#define DA7219_DAC_EQ_BAND1_SHIFT 0
392#define DA7219_DAC_EQ_BAND1_MASK (0xF << 0)
393#define DA7219_DAC_EQ_BAND2_SHIFT 4
394#define DA7219_DAC_EQ_BAND2_MASK (0xF << 4)
395#define DA7219_DAC_EQ_BAND_MAX 0xF
396
397/* DA7219_DAC_FILTERS3 = 0x42 */
398#define DA7219_DAC_EQ_BAND3_SHIFT 0
399#define DA7219_DAC_EQ_BAND3_MASK (0xF << 0)
400#define DA7219_DAC_EQ_BAND4_SHIFT 4
401#define DA7219_DAC_EQ_BAND4_MASK (0xF << 4)
402
403/* DA7219_DAC_FILTERS4 = 0x43 */
404#define DA7219_DAC_EQ_BAND5_SHIFT 0
405#define DA7219_DAC_EQ_BAND5_MASK (0xF << 0)
406#define DA7219_DAC_EQ_EN_SHIFT 7
407#define DA7219_DAC_EQ_EN_MASK (0x1 << 7)
408
409/* DA7219_DAC_FILTERS1 = 0x44 */
410#define DA7219_DAC_VOICE_HPF_CORNER_SHIFT 0
411#define DA7219_DAC_VOICE_HPF_CORNER_MASK (0x7 << 0)
412#define DA7219_DAC_VOICE_EN_SHIFT 3
413#define DA7219_DAC_VOICE_EN_MASK (0x1 << 3)
414#define DA7219_DAC_AUDIO_HPF_CORNER_SHIFT 4
415#define DA7219_DAC_AUDIO_HPF_CORNER_MASK (0x3 << 4)
416#define DA7219_DAC_HPF_EN_SHIFT 7
417#define DA7219_DAC_HPF_EN_MASK (0x1 << 7)
418
419/* DA7219_DAC_L_GAIN = 0x45 */
420#define DA7219_DAC_L_DIGITAL_GAIN_SHIFT 0
421#define DA7219_DAC_L_DIGITAL_GAIN_MASK (0x7F << 0)
422#define DA7219_DAC_DIGITAL_GAIN_MAX 0x7F
423#define DA7219_DAC_DIGITAL_GAIN_0DB (0x6F << 0)
424
425/* DA7219_DAC_R_GAIN = 0x46 */
426#define DA7219_DAC_R_DIGITAL_GAIN_SHIFT 0
427#define DA7219_DAC_R_DIGITAL_GAIN_MASK (0x7F << 0)
428
429/* DA7219_CP_CTRL = 0x47 */
430#define DA7219_CP_MCHANGE_SHIFT 4
431#define DA7219_CP_MCHANGE_MASK (0x3 << 4)
432#define DA7219_CP_MCHANGE_REL_MASK 0x3
433#define DA7219_CP_MCHANGE_MAX 3
434#define DA7219_CP_MCHANGE_LARGEST_VOL 0x1
435#define DA7219_CP_MCHANGE_DAC_VOL 0x2
436#define DA7219_CP_MCHANGE_SIG_MAG 0x3
437#define DA7219_CP_EN_SHIFT 7
438#define DA7219_CP_EN_MASK (0x1 << 7)
439
440/* DA7219_HP_L_GAIN = 0x48 */
441#define DA7219_HP_L_AMP_GAIN_SHIFT 0
442#define DA7219_HP_L_AMP_GAIN_MASK (0x3F << 0)
443#define DA7219_HP_AMP_GAIN_MAX 0x3F
444#define DA7219_HP_AMP_GAIN_0DB (0x39 << 0)
445
446/* DA7219_HP_R_GAIN = 0x49 */
447#define DA7219_HP_R_AMP_GAIN_SHIFT 0
448#define DA7219_HP_R_AMP_GAIN_MASK (0x3F << 0)
449
450/* DA7219_MIXOUT_L_SELECT = 0x4B */
451#define DA7219_MIXOUT_L_MIX_SELECT_SHIFT 0
452#define DA7219_MIXOUT_L_MIX_SELECT_MASK (0x1 << 0)
453
454/* DA7219_MIXOUT_R_SELECT = 0x4C */
455#define DA7219_MIXOUT_R_MIX_SELECT_SHIFT 0
456#define DA7219_MIXOUT_R_MIX_SELECT_MASK (0x1 << 0)
457
458/* DA7219_SYSTEM_MODES_INPUT = 0x50 */
459#define DA7219_MODE_SUBMIT_SHIFT 0
460#define DA7219_MODE_SUBMIT_MASK (0x1 << 0)
461#define DA7219_ADC_MODE_SHIFT 1
462#define DA7219_ADC_MODE_MASK (0x7F << 1)
463
464/* DA7219_SYSTEM_MODES_OUTPUT = 0x51 */
465#define DA7219_MODE_SUBMIT_SHIFT 0
466#define DA7219_MODE_SUBMIT_MASK (0x1 << 0)
467#define DA7219_DAC_MODE_SHIFT 1
468#define DA7219_DAC_MODE_MASK (0x7F << 1)
469
470/* DA7219_MICBIAS_CTRL = 0x62 */
471#define DA7219_MICBIAS1_LEVEL_SHIFT 0
472#define DA7219_MICBIAS1_LEVEL_MASK (0x7 << 0)
473#define DA7219_MICBIAS1_EN_SHIFT 3
474#define DA7219_MICBIAS1_EN_MASK (0x1 << 3)
475
476/* DA7219_MIC_1_CTRL = 0x63 */
477#define DA7219_MIC_1_AMP_RAMP_EN_SHIFT 5
478#define DA7219_MIC_1_AMP_RAMP_EN_MASK (0x1 << 5)
479#define DA7219_MIC_1_AMP_MUTE_EN_SHIFT 6
480#define DA7219_MIC_1_AMP_MUTE_EN_MASK (0x1 << 6)
481#define DA7219_MIC_1_AMP_EN_SHIFT 7
482#define DA7219_MIC_1_AMP_EN_MASK (0x1 << 7)
483
484/* DA7219_MIXIN_L_CTRL = 0x65 */
485#define DA7219_MIXIN_L_MIX_EN_SHIFT 3
486#define DA7219_MIXIN_L_MIX_EN_MASK (0x1 << 3)
487#define DA7219_MIXIN_L_AMP_ZC_EN_SHIFT 4
488#define DA7219_MIXIN_L_AMP_ZC_EN_MASK (0x1 << 4)
489#define DA7219_MIXIN_L_AMP_RAMP_EN_SHIFT 5
490#define DA7219_MIXIN_L_AMP_RAMP_EN_MASK (0x1 << 5)
491#define DA7219_MIXIN_L_AMP_MUTE_EN_SHIFT 6
492#define DA7219_MIXIN_L_AMP_MUTE_EN_MASK (0x1 << 6)
493#define DA7219_MIXIN_L_AMP_EN_SHIFT 7
494#define DA7219_MIXIN_L_AMP_EN_MASK (0x1 << 7)
495
496/* DA7219_ADC_L_CTRL = 0x67 */
497#define DA7219_ADC_L_BIAS_SHIFT 0
498#define DA7219_ADC_L_BIAS_MASK (0x3 << 0)
499#define DA7219_ADC_L_RAMP_EN_SHIFT 5
500#define DA7219_ADC_L_RAMP_EN_MASK (0x1 << 5)
501#define DA7219_ADC_L_MUTE_EN_SHIFT 6
502#define DA7219_ADC_L_MUTE_EN_MASK (0x1 << 6)
503#define DA7219_ADC_L_EN_SHIFT 7
504#define DA7219_ADC_L_EN_MASK (0x1 << 7)
505
506/* DA7219_DAC_L_CTRL = 0x69 */
507#define DA7219_DAC_L_RAMP_EN_SHIFT 5
508#define DA7219_DAC_L_RAMP_EN_MASK (0x1 << 5)
509#define DA7219_DAC_L_MUTE_EN_SHIFT 6
510#define DA7219_DAC_L_MUTE_EN_MASK (0x1 << 6)
511#define DA7219_DAC_L_EN_SHIFT 7
512#define DA7219_DAC_L_EN_MASK (0x1 << 7)
513
514/* DA7219_DAC_R_CTRL = 0x6A */
515#define DA7219_DAC_R_RAMP_EN_SHIFT 5
516#define DA7219_DAC_R_RAMP_EN_MASK (0x1 << 5)
517#define DA7219_DAC_R_MUTE_EN_SHIFT 6
518#define DA7219_DAC_R_MUTE_EN_MASK (0x1 << 6)
519#define DA7219_DAC_R_EN_SHIFT 7
520#define DA7219_DAC_R_EN_MASK (0x1 << 7)
521
522/* DA7219_HP_L_CTRL = 0x6B */
523#define DA7219_HP_L_AMP_MIN_GAIN_EN_SHIFT 2
524#define DA7219_HP_L_AMP_MIN_GAIN_EN_MASK (0x1 << 2)
525#define DA7219_HP_L_AMP_OE_SHIFT 3
526#define DA7219_HP_L_AMP_OE_MASK (0x1 << 3)
527#define DA7219_HP_L_AMP_ZC_EN_SHIFT 4
528#define DA7219_HP_L_AMP_ZC_EN_MASK (0x1 << 4)
529#define DA7219_HP_L_AMP_RAMP_EN_SHIFT 5
530#define DA7219_HP_L_AMP_RAMP_EN_MASK (0x1 << 5)
531#define DA7219_HP_L_AMP_MUTE_EN_SHIFT 6
532#define DA7219_HP_L_AMP_MUTE_EN_MASK (0x1 << 6)
533#define DA7219_HP_L_AMP_EN_SHIFT 7
534#define DA7219_HP_L_AMP_EN_MASK (0x1 << 7)
535
536/* DA7219_HP_R_CTRL = 0x6C */
537#define DA7219_HP_R_AMP_MIN_GAIN_EN_SHIFT 2
538#define DA7219_HP_R_AMP_MIN_GAIN_EN_MASK (0x1 << 2)
539#define DA7219_HP_R_AMP_OE_SHIFT 3
540#define DA7219_HP_R_AMP_OE_MASK (0x1 << 3)
541#define DA7219_HP_R_AMP_ZC_EN_SHIFT 4
542#define DA7219_HP_R_AMP_ZC_EN_MASK (0x1 << 4)
543#define DA7219_HP_R_AMP_RAMP_EN_SHIFT 5
544#define DA7219_HP_R_AMP_RAMP_EN_MASK (0x1 << 5)
545#define DA7219_HP_R_AMP_MUTE_EN_SHIFT 6
546#define DA7219_HP_R_AMP_MUTE_EN_MASK (0x1 << 6)
547#define DA7219_HP_R_AMP_EN_SHIFT 7
548#define DA7219_HP_R_AMP_EN_MASK (0x1 << 7)
549
550/* DA7219_MIXOUT_L_CTRL = 0x6E */
551#define DA7219_MIXOUT_L_AMP_EN_SHIFT 7
552#define DA7219_MIXOUT_L_AMP_EN_MASK (0x1 << 7)
553
554/* DA7219_MIXOUT_R_CTRL = 0x6F */
555#define DA7219_MIXOUT_R_AMP_EN_SHIFT 7
556#define DA7219_MIXOUT_R_AMP_EN_MASK (0x1 << 7)
557
558/* DA7219_CHIP_ID1 = 0x81 */
559#define DA7219_CHIP_ID1_SHIFT 0
560#define DA7219_CHIP_ID1_MASK (0xFF << 0)
561
562/* DA7219_CHIP_ID2 = 0x82 */
563#define DA7219_CHIP_ID2_SHIFT 0
564#define DA7219_CHIP_ID2_MASK (0xFF << 0)
565
566/* DA7219_CHIP_REVISION = 0x83 */
567#define DA7219_CHIP_MINOR_SHIFT 0
568#define DA7219_CHIP_MINOR_MASK (0xF << 0)
569#define DA7219_CHIP_MAJOR_SHIFT 4
570#define DA7219_CHIP_MAJOR_MASK (0xF << 4)
571
572/* DA7219_LDO_CTRL = 0x90 */
573#define DA7219_LDO_LEVEL_SELECT_SHIFT 4
574#define DA7219_LDO_LEVEL_SELECT_MASK (0x3 << 4)
575#define DA7219_LDO_EN_SHIFT 7
576#define DA7219_LDO_EN_MASK (0x1 << 7)
577
578/* DA7219_IO_CTRL = 0x91 */
579#define DA7219_IO_VOLTAGE_LEVEL_SHIFT 0
580#define DA7219_IO_VOLTAGE_LEVEL_MASK (0x1 << 0)
581#define DA7219_IO_VOLTAGE_LEVEL_2_5V_3_6V 0
582#define DA7219_IO_VOLTAGE_LEVEL_1_2V_2_8V 1
583
584/* DA7219_GAIN_RAMP_CTRL = 0x92 */
585#define DA7219_GAIN_RAMP_RATE_SHIFT 0
586#define DA7219_GAIN_RAMP_RATE_MASK (0x3 << 0)
587#define DA7219_GAIN_RAMP_RATE_MAX 4
588
589/* DA7219_PC_COUNT = 0x94 */
590#define DA7219_PC_FREERUN_SHIFT 0
591#define DA7219_PC_FREERUN_MASK (0x1 << 0)
592#define DA7219_PC_RESYNC_AUTO_SHIFT 1
593#define DA7219_PC_RESYNC_AUTO_MASK (0x1 << 1)
594
595/* DA7219_CP_VOL_THRESHOLD1 = 0x95 */
596#define DA7219_CP_THRESH_VDD2_SHIFT 0
597#define DA7219_CP_THRESH_VDD2_MASK (0x3F << 0)
598#define DA7219_CP_THRESH_VDD2_MAX 0x3F
599
600/* DA7219_DIG_CTRL = 0x99 */
601#define DA7219_DAC_L_INV_SHIFT 3
602#define DA7219_DAC_L_INV_MASK (0x1 << 3)
603#define DA7219_DAC_R_INV_SHIFT 7
604#define DA7219_DAC_R_INV_MASK (0x1 << 7)
605
606/* DA7219_ALC_CTRL2 = 0x9A */
607#define DA7219_ALC_ATTACK_SHIFT 0
608#define DA7219_ALC_ATTACK_MASK (0xF << 0)
609#define DA7219_ALC_ATTACK_MAX 13
610#define DA7219_ALC_RELEASE_SHIFT 4
611#define DA7219_ALC_RELEASE_MASK (0xF << 4)
612#define DA7219_ALC_RELEASE_MAX 11
613
614/* DA7219_ALC_CTRL3 = 0x9B */
615#define DA7219_ALC_HOLD_SHIFT 0
616#define DA7219_ALC_HOLD_MASK (0xF << 0)
617#define DA7219_ALC_HOLD_MAX 16
618#define DA7219_ALC_INTEG_ATTACK_SHIFT 4
619#define DA7219_ALC_INTEG_ATTACK_MASK (0x3 << 4)
620#define DA7219_ALC_INTEG_RELEASE_SHIFT 6
621#define DA7219_ALC_INTEG_RELEASE_MASK (0x3 << 6)
622#define DA7219_ALC_INTEG_MAX 4
623
624/* DA7219_ALC_NOISE = 0x9C */
625#define DA7219_ALC_NOISE_SHIFT 0
626#define DA7219_ALC_NOISE_MASK (0x3F << 0)
627#define DA7219_ALC_THRESHOLD_MAX 0x3F
628
629/* DA7219_ALC_TARGET_MIN = 0x9D */
630#define DA7219_ALC_THRESHOLD_MIN_SHIFT 0
631#define DA7219_ALC_THRESHOLD_MIN_MASK (0x3F << 0)
632
633/* DA7219_ALC_TARGET_MAX = 0x9E */
634#define DA7219_ALC_THRESHOLD_MAX_SHIFT 0
635#define DA7219_ALC_THRESHOLD_MAX_MASK (0x3F << 0)
636
637/* DA7219_ALC_GAIN_LIMITS = 0x9F */
638#define DA7219_ALC_ATTEN_MAX_SHIFT 0
639#define DA7219_ALC_ATTEN_MAX_MASK (0xF << 0)
640#define DA7219_ALC_GAIN_MAX_SHIFT 4
641#define DA7219_ALC_GAIN_MAX_MASK (0xF << 4)
642#define DA7219_ALC_ATTEN_GAIN_MAX 0xF
643
644/* DA7219_ALC_ANA_GAIN_LIMITS = 0xA0 */
645#define DA7219_ALC_ANA_GAIN_MIN_SHIFT 0
646#define DA7219_ALC_ANA_GAIN_MIN_MASK (0x7 << 0)
647#define DA7219_ALC_ANA_GAIN_MIN 0x1
648#define DA7219_ALC_ANA_GAIN_MAX_SHIFT 4
649#define DA7219_ALC_ANA_GAIN_MAX_MASK (0x7 << 4)
650#define DA7219_ALC_ANA_GAIN_MAX 0x7
651
652/* DA7219_ALC_ANTICLIP_CTRL = 0xA1 */
653#define DA7219_ALC_ANTICLIP_STEP_SHIFT 0
654#define DA7219_ALC_ANTICLIP_STEP_MASK (0x3 << 0)
655#define DA7219_ALC_ANTICLIP_STEP_MAX 4
656#define DA7219_ALC_ANTIPCLIP_EN_SHIFT 7
657#define DA7219_ALC_ANTIPCLIP_EN_MASK (0x1 << 7)
658
659/* DA7219_ALC_ANTICLIP_LEVEL = 0xA2 */
660#define DA7219_ALC_ANTICLIP_LEVEL_SHIFT 0
661#define DA7219_ALC_ANTICLIP_LEVEL_MASK (0x7F << 0)
662
663/* DA7219_ALC_OFFSET_AUTO_M_L = 0xA3 */
664#define DA7219_ALC_OFFSET_AUTO_M_L_SHIFT 0
665#define DA7219_ALC_OFFSET_AUTO_M_L_MASK (0xFF << 0)
666
667/* DA7219_ALC_OFFSET_AUTO_U_L = 0xA4 */
668#define DA7219_ALC_OFFSET_AUTO_U_L_SHIFT 0
669#define DA7219_ALC_OFFSET_AUTO_U_L_MASK (0xF << 0)
670
671/* DA7219_DAC_NG_SETUP_TIME = 0xAF */
672#define DA7219_DAC_NG_SETUP_TIME_SHIFT 0
673#define DA7219_DAC_NG_SETUP_TIME_MASK (0x3 << 0)
674#define DA7219_DAC_NG_SETUP_TIME_MAX 4
675#define DA7219_DAC_NG_RAMPUP_RATE_SHIFT 2
676#define DA7219_DAC_NG_RAMPUP_RATE_MASK (0x1 << 2)
677#define DA7219_DAC_NG_RAMPDN_RATE_SHIFT 3
678#define DA7219_DAC_NG_RAMPDN_RATE_MASK (0x1 << 3)
679#define DA7219_DAC_NG_RAMP_RATE_MAX 2
680
681/* DA7219_DAC_NG_OFF_THRESH = 0xB0 */
682#define DA7219_DAC_NG_OFF_THRESHOLD_SHIFT 0
683#define DA7219_DAC_NG_OFF_THRESHOLD_MASK (0x7 << 0)
684#define DA7219_DAC_NG_THRESHOLD_MAX 0x7
685
686/* DA7219_DAC_NG_ON_THRESH = 0xB1 */
687#define DA7219_DAC_NG_ON_THRESHOLD_SHIFT 0
688#define DA7219_DAC_NG_ON_THRESHOLD_MASK (0x7 << 0)
689
690/* DA7219_DAC_NG_CTRL = 0xB2 */
691#define DA7219_DAC_NG_EN_SHIFT 7
692#define DA7219_DAC_NG_EN_MASK (0x1 << 7)
693
694/* DA7219_TONE_GEN_CFG1 = 0xB4 */
695#define DA7219_DTMF_REG_SHIFT 0
696#define DA7219_DTMF_REG_MASK (0xF << 0)
697#define DA7219_DTMF_REG_MAX 16
698#define DA7219_DTMF_EN_SHIFT 4
699#define DA7219_DTMF_EN_MASK (0x1 << 4)
700#define DA7219_START_STOPN_SHIFT 7
701#define DA7219_START_STOPN_MASK (0x1 << 7)
702
703/* DA7219_TONE_GEN_CFG2 = 0xB5 */
704#define DA7219_SWG_SEL_SHIFT 0
705#define DA7219_SWG_SEL_MASK (0x3 << 0)
706#define DA7219_SWG_SEL_MAX 4
707#define DA7219_SWG_SEL_SRAMP (0x3 << 0)
708#define DA7219_TONE_GEN_GAIN_SHIFT 4
709#define DA7219_TONE_GEN_GAIN_MASK (0xF << 4)
710#define DA7219_TONE_GEN_GAIN_MAX 0xF
711#define DA7219_TONE_GEN_GAIN_MINUS_9DB (0x3 << 4)
712#define DA7219_TONE_GEN_GAIN_MINUS_15DB (0x5 << 4)
713
714/* DA7219_TONE_GEN_CYCLES = 0xB6 */
715#define DA7219_BEEP_CYCLES_SHIFT 0
716#define DA7219_BEEP_CYCLES_MASK (0x7 << 0)
717
718/* DA7219_TONE_GEN_FREQ1_L = 0xB7 */
719#define DA7219_FREQ1_L_SHIFT 0
720#define DA7219_FREQ1_L_MASK (0xFF << 0)
721#define DA7219_FREQ_MAX 0xFFFF
722
723/* DA7219_TONE_GEN_FREQ1_U = 0xB8 */
724#define DA7219_FREQ1_U_SHIFT 0
725#define DA7219_FREQ1_U_MASK (0xFF << 0)
726
727/* DA7219_TONE_GEN_FREQ2_L = 0xB9 */
728#define DA7219_FREQ2_L_SHIFT 0
729#define DA7219_FREQ2_L_MASK (0xFF << 0)
730
731/* DA7219_TONE_GEN_FREQ2_U = 0xBA */
732#define DA7219_FREQ2_U_SHIFT 0
733#define DA7219_FREQ2_U_MASK (0xFF << 0)
734
735/* DA7219_TONE_GEN_ON_PER = 0xBB */
736#define DA7219_BEEP_ON_PER_SHIFT 0
737#define DA7219_BEEP_ON_PER_MASK (0x3F << 0)
738#define DA7219_BEEP_ON_OFF_MAX 0x3F
739
740/* DA7219_TONE_GEN_OFF_PER = 0xBC */
741#define DA7219_BEEP_OFF_PER_SHIFT 0
742#define DA7219_BEEP_OFF_PER_MASK (0x3F << 0)
743
744/* DA7219_SYSTEM_STATUS = 0xE0 */
745#define DA7219_SC1_BUSY_SHIFT 0
746#define DA7219_SC1_BUSY_MASK (0x1 << 0)
747#define DA7219_SC2_BUSY_SHIFT 1
748#define DA7219_SC2_BUSY_MASK (0x1 << 1)
749
750/* DA7219_SYSTEM_ACTIVE = 0xFD */
751#define DA7219_SYSTEM_ACTIVE_SHIFT 0
752#define DA7219_SYSTEM_ACTIVE_MASK (0x1 << 0)
753
754
755/*
756 * General defines & data
757 */
758
759/* Register inversion */
760#define DA7219_NO_INVERT 0
761#define DA7219_INVERT 1
762
763/* Byte related defines */
764#define DA7219_BYTE_SHIFT 8
765#define DA7219_BYTE_MASK 0xFF
766
767/* PLL Output Frequencies */
768#define DA7219_PLL_FREQ_OUT_90316 90316800
769#define DA7219_PLL_FREQ_OUT_98304 98304000
770
771/* PLL Frequency Dividers */
772#define DA7219_PLL_INDIV_2_5_MHZ_VAL 1
773#define DA7219_PLL_INDIV_5_10_MHZ_VAL 2
774#define DA7219_PLL_INDIV_10_20_MHZ_VAL 4
775#define DA7219_PLL_INDIV_20_40_MHZ_VAL 8
776#define DA7219_PLL_INDIV_40_54_MHZ_VAL 16
777
778/* SRM */
779#define DA7219_SRM_CHECK_RETRIES 8
780
781enum da7219_clk_src {
782 DA7219_CLKSRC_MCLK = 0,
783 DA7219_CLKSRC_MCLK_SQR,
784};
785
786enum da7219_sys_clk {
787 DA7219_SYSCLK_MCLK = 0,
788 DA7219_SYSCLK_PLL,
789 DA7219_SYSCLK_PLL_SRM,
790 DA7219_SYSCLK_PLL_32KHZ
791};
792
793/* Regulators */
794enum da7219_supplies {
795 DA7219_SUPPLY_VDD = 0,
796 DA7219_SUPPLY_VDDMIC,
797 DA7219_SUPPLY_VDDIO,
798 DA7219_NUM_SUPPLIES,
799};
800
801struct da7219_aad_priv;
802
803/* Private data */
804struct da7219_priv {
805 struct da7219_aad_priv *aad;
806 struct da7219_pdata *pdata;
807
808 struct regulator_bulk_data supplies[DA7219_NUM_SUPPLIES];
809 struct regmap *regmap;
810 struct mutex lock;
811
812 struct clk *mclk;
813 unsigned int mclk_rate;
814 int clk_src;
815
816 bool master;
817 bool alc_en;
818};
819
820#endif /* __DA7219_H */
diff --git a/sound/soc/codecs/es8328.c b/sound/soc/codecs/es8328.c
index 6a091016e0fc..969e337dc17c 100644
--- a/sound/soc/codecs/es8328.c
+++ b/sound/soc/codecs/es8328.c
@@ -129,7 +129,7 @@ static int es8328_put_deemph(struct snd_kcontrol *kcontrol,
129{ 129{
130 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); 130 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
131 struct es8328_priv *es8328 = snd_soc_codec_get_drvdata(codec); 131 struct es8328_priv *es8328 = snd_soc_codec_get_drvdata(codec);
132 int deemph = ucontrol->value.integer.value[0]; 132 unsigned int deemph = ucontrol->value.integer.value[0];
133 int ret; 133 int ret;
134 134
135 if (deemph > 1) 135 if (deemph > 1)
diff --git a/sound/soc/codecs/hdmi.c b/sound/soc/codecs/hdmi.c
deleted file mode 100644
index bd42ad34e004..000000000000
--- a/sound/soc/codecs/hdmi.c
+++ /dev/null
@@ -1,109 +0,0 @@
1/*
2 * ALSA SoC codec driver for HDMI audio codecs.
3 * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/
4 * Author: Ricardo Neri <ricardo.neri@ti.com>
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms 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 that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
18 * 02110-1301 USA
19 *
20 */
21#include <linux/module.h>
22#include <sound/soc.h>
23#include <linux/of.h>
24#include <linux/of_device.h>
25
26#define DRV_NAME "hdmi-audio-codec"
27
28static const struct snd_soc_dapm_widget hdmi_widgets[] = {
29 SND_SOC_DAPM_INPUT("RX"),
30 SND_SOC_DAPM_OUTPUT("TX"),
31};
32
33static const struct snd_soc_dapm_route hdmi_routes[] = {
34 { "Capture", NULL, "RX" },
35 { "TX", NULL, "Playback" },
36};
37
38static struct snd_soc_dai_driver hdmi_codec_dai = {
39 .name = "hdmi-hifi",
40 .playback = {
41 .stream_name = "Playback",
42 .channels_min = 2,
43 .channels_max = 8,
44 .rates = SNDRV_PCM_RATE_32000 |
45 SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 |
46 SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000 |
47 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_192000,
48 .formats = SNDRV_PCM_FMTBIT_S16_LE |
49 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE,
50 .sig_bits = 24,
51 },
52 .capture = {
53 .stream_name = "Capture",
54 .channels_min = 2,
55 .channels_max = 2,
56 .rates = SNDRV_PCM_RATE_32000 |
57 SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 |
58 SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000 |
59 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_192000,
60 .formats = SNDRV_PCM_FMTBIT_S16_LE |
61 SNDRV_PCM_FMTBIT_S24_LE,
62 },
63
64};
65
66#ifdef CONFIG_OF
67static const struct of_device_id hdmi_audio_codec_ids[] = {
68 { .compatible = "linux,hdmi-audio", },
69 { }
70};
71MODULE_DEVICE_TABLE(of, hdmi_audio_codec_ids);
72#endif
73
74static struct snd_soc_codec_driver hdmi_codec = {
75 .dapm_widgets = hdmi_widgets,
76 .num_dapm_widgets = ARRAY_SIZE(hdmi_widgets),
77 .dapm_routes = hdmi_routes,
78 .num_dapm_routes = ARRAY_SIZE(hdmi_routes),
79 .ignore_pmdown_time = true,
80};
81
82static int hdmi_codec_probe(struct platform_device *pdev)
83{
84 return snd_soc_register_codec(&pdev->dev, &hdmi_codec,
85 &hdmi_codec_dai, 1);
86}
87
88static int hdmi_codec_remove(struct platform_device *pdev)
89{
90 snd_soc_unregister_codec(&pdev->dev);
91 return 0;
92}
93
94static struct platform_driver hdmi_codec_driver = {
95 .driver = {
96 .name = DRV_NAME,
97 .of_match_table = of_match_ptr(hdmi_audio_codec_ids),
98 },
99
100 .probe = hdmi_codec_probe,
101 .remove = hdmi_codec_remove,
102};
103
104module_platform_driver(hdmi_codec_driver);
105
106MODULE_AUTHOR("Ricardo Neri <ricardo.neri@ti.com>");
107MODULE_DESCRIPTION("ASoC generic HDMI codec driver");
108MODULE_LICENSE("GPL");
109MODULE_ALIAS("platform:" DRV_NAME);
diff --git a/sound/soc/codecs/nau8825.c b/sound/soc/codecs/nau8825.c
new file mode 100644
index 000000000000..7fc7b4e3f444
--- /dev/null
+++ b/sound/soc/codecs/nau8825.c
@@ -0,0 +1,1309 @@
1/*
2 * Nuvoton NAU8825 audio codec driver
3 *
4 * Copyright 2015 Google Chromium project.
5 * Author: Anatol Pomozov <anatol@chromium.org>
6 * Copyright 2015 Nuvoton Technology Corp.
7 * Co-author: Meng-Huang Kuo <mhkuo@nuvoton.com>
8 *
9 * Licensed under the GPL-2.
10 */
11
12#include <linux/module.h>
13#include <linux/delay.h>
14#include <linux/init.h>
15#include <linux/i2c.h>
16#include <linux/regmap.h>
17#include <linux/slab.h>
18#include <linux/clk.h>
19#include <linux/acpi.h>
20#include <linux/math64.h>
21
22#include <sound/initval.h>
23#include <sound/tlv.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/jack.h>
29
30
31#include "nau8825.h"
32
33#define NAU_FREF_MAX 13500000
34#define NAU_FVCO_MAX 100000000
35#define NAU_FVCO_MIN 90000000
36
37struct nau8825_fll {
38 int mclk_src;
39 int ratio;
40 int fll_frac;
41 int fll_int;
42 int clk_ref_div;
43};
44
45struct nau8825_fll_attr {
46 unsigned int param;
47 unsigned int val;
48};
49
50/* scaling for mclk from sysclk_src output */
51static const struct nau8825_fll_attr mclk_src_scaling[] = {
52 { 1, 0x0 },
53 { 2, 0x2 },
54 { 4, 0x3 },
55 { 8, 0x4 },
56 { 16, 0x5 },
57 { 32, 0x6 },
58 { 3, 0x7 },
59 { 6, 0xa },
60 { 12, 0xb },
61 { 24, 0xc },
62 { 48, 0xd },
63 { 96, 0xe },
64 { 5, 0xf },
65};
66
67/* ratio for input clk freq */
68static const struct nau8825_fll_attr fll_ratio[] = {
69 { 512000, 0x01 },
70 { 256000, 0x02 },
71 { 128000, 0x04 },
72 { 64000, 0x08 },
73 { 32000, 0x10 },
74 { 8000, 0x20 },
75 { 4000, 0x40 },
76};
77
78static const struct nau8825_fll_attr fll_pre_scalar[] = {
79 { 1, 0x0 },
80 { 2, 0x1 },
81 { 4, 0x2 },
82 { 8, 0x3 },
83};
84
85static const struct reg_default nau8825_reg_defaults[] = {
86 { NAU8825_REG_ENA_CTRL, 0x00ff },
87 { NAU8825_REG_CLK_DIVIDER, 0x0050 },
88 { NAU8825_REG_FLL1, 0x0 },
89 { NAU8825_REG_FLL2, 0x3126 },
90 { NAU8825_REG_FLL3, 0x0008 },
91 { NAU8825_REG_FLL4, 0x0010 },
92 { NAU8825_REG_FLL5, 0x0 },
93 { NAU8825_REG_FLL6, 0x6000 },
94 { NAU8825_REG_FLL_VCO_RSV, 0xf13c },
95 { NAU8825_REG_HSD_CTRL, 0x000c },
96 { NAU8825_REG_JACK_DET_CTRL, 0x0 },
97 { NAU8825_REG_INTERRUPT_MASK, 0x0 },
98 { NAU8825_REG_INTERRUPT_DIS_CTRL, 0xffff },
99 { NAU8825_REG_SAR_CTRL, 0x0015 },
100 { NAU8825_REG_KEYDET_CTRL, 0x0110 },
101 { NAU8825_REG_VDET_THRESHOLD_1, 0x0 },
102 { NAU8825_REG_VDET_THRESHOLD_2, 0x0 },
103 { NAU8825_REG_VDET_THRESHOLD_3, 0x0 },
104 { NAU8825_REG_VDET_THRESHOLD_4, 0x0 },
105 { NAU8825_REG_GPIO34_CTRL, 0x0 },
106 { NAU8825_REG_GPIO12_CTRL, 0x0 },
107 { NAU8825_REG_TDM_CTRL, 0x0 },
108 { NAU8825_REG_I2S_PCM_CTRL1, 0x000b },
109 { NAU8825_REG_I2S_PCM_CTRL2, 0x8010 },
110 { NAU8825_REG_LEFT_TIME_SLOT, 0x0 },
111 { NAU8825_REG_RIGHT_TIME_SLOT, 0x0 },
112 { NAU8825_REG_BIQ_CTRL, 0x0 },
113 { NAU8825_REG_BIQ_COF1, 0x0 },
114 { NAU8825_REG_BIQ_COF2, 0x0 },
115 { NAU8825_REG_BIQ_COF3, 0x0 },
116 { NAU8825_REG_BIQ_COF4, 0x0 },
117 { NAU8825_REG_BIQ_COF5, 0x0 },
118 { NAU8825_REG_BIQ_COF6, 0x0 },
119 { NAU8825_REG_BIQ_COF7, 0x0 },
120 { NAU8825_REG_BIQ_COF8, 0x0 },
121 { NAU8825_REG_BIQ_COF9, 0x0 },
122 { NAU8825_REG_BIQ_COF10, 0x0 },
123 { NAU8825_REG_ADC_RATE, 0x0010 },
124 { NAU8825_REG_DAC_CTRL1, 0x0001 },
125 { NAU8825_REG_DAC_CTRL2, 0x0 },
126 { NAU8825_REG_DAC_DGAIN_CTRL, 0x0 },
127 { NAU8825_REG_ADC_DGAIN_CTRL, 0x00cf },
128 { NAU8825_REG_MUTE_CTRL, 0x0 },
129 { NAU8825_REG_HSVOL_CTRL, 0x0 },
130 { NAU8825_REG_DACL_CTRL, 0x02cf },
131 { NAU8825_REG_DACR_CTRL, 0x00cf },
132 { NAU8825_REG_ADC_DRC_KNEE_IP12, 0x1486 },
133 { NAU8825_REG_ADC_DRC_KNEE_IP34, 0x0f12 },
134 { NAU8825_REG_ADC_DRC_SLOPES, 0x25ff },
135 { NAU8825_REG_ADC_DRC_ATKDCY, 0x3457 },
136 { NAU8825_REG_DAC_DRC_KNEE_IP12, 0x1486 },
137 { NAU8825_REG_DAC_DRC_KNEE_IP34, 0x0f12 },
138 { NAU8825_REG_DAC_DRC_SLOPES, 0x25f9 },
139 { NAU8825_REG_DAC_DRC_ATKDCY, 0x3457 },
140 { NAU8825_REG_IMM_MODE_CTRL, 0x0 },
141 { NAU8825_REG_CLASSG_CTRL, 0x0 },
142 { NAU8825_REG_OPT_EFUSE_CTRL, 0x0 },
143 { NAU8825_REG_MISC_CTRL, 0x0 },
144 { NAU8825_REG_BIAS_ADJ, 0x0 },
145 { NAU8825_REG_TRIM_SETTINGS, 0x0 },
146 { NAU8825_REG_ANALOG_CONTROL_1, 0x0 },
147 { NAU8825_REG_ANALOG_CONTROL_2, 0x0 },
148 { NAU8825_REG_ANALOG_ADC_1, 0x0011 },
149 { NAU8825_REG_ANALOG_ADC_2, 0x0020 },
150 { NAU8825_REG_RDAC, 0x0008 },
151 { NAU8825_REG_MIC_BIAS, 0x0006 },
152 { NAU8825_REG_BOOST, 0x0 },
153 { NAU8825_REG_FEPGA, 0x0 },
154 { NAU8825_REG_POWER_UP_CONTROL, 0x0 },
155 { NAU8825_REG_CHARGE_PUMP, 0x0 },
156};
157
158static bool nau8825_readable_reg(struct device *dev, unsigned int reg)
159{
160 switch (reg) {
161 case NAU8825_REG_ENA_CTRL:
162 case NAU8825_REG_CLK_DIVIDER ... NAU8825_REG_FLL_VCO_RSV:
163 case NAU8825_REG_HSD_CTRL ... NAU8825_REG_JACK_DET_CTRL:
164 case NAU8825_REG_INTERRUPT_MASK ... NAU8825_REG_KEYDET_CTRL:
165 case NAU8825_REG_VDET_THRESHOLD_1 ... NAU8825_REG_DACR_CTRL:
166 case NAU8825_REG_ADC_DRC_KNEE_IP12 ... NAU8825_REG_ADC_DRC_ATKDCY:
167 case NAU8825_REG_DAC_DRC_KNEE_IP12 ... NAU8825_REG_DAC_DRC_ATKDCY:
168 case NAU8825_REG_IMM_MODE_CTRL ... NAU8825_REG_IMM_RMS_R:
169 case NAU8825_REG_CLASSG_CTRL ... NAU8825_REG_OPT_EFUSE_CTRL:
170 case NAU8825_REG_MISC_CTRL:
171 case NAU8825_REG_I2C_DEVICE_ID ... NAU8825_REG_SARDOUT_RAM_STATUS:
172 case NAU8825_REG_BIAS_ADJ:
173 case NAU8825_REG_TRIM_SETTINGS ... NAU8825_REG_ANALOG_CONTROL_2:
174 case NAU8825_REG_ANALOG_ADC_1 ... NAU8825_REG_MIC_BIAS:
175 case NAU8825_REG_BOOST ... NAU8825_REG_FEPGA:
176 case NAU8825_REG_POWER_UP_CONTROL ... NAU8825_REG_GENERAL_STATUS:
177 return true;
178 default:
179 return false;
180 }
181
182}
183
184static bool nau8825_writeable_reg(struct device *dev, unsigned int reg)
185{
186 switch (reg) {
187 case NAU8825_REG_RESET ... NAU8825_REG_ENA_CTRL:
188 case NAU8825_REG_CLK_DIVIDER ... NAU8825_REG_FLL_VCO_RSV:
189 case NAU8825_REG_HSD_CTRL ... NAU8825_REG_JACK_DET_CTRL:
190 case NAU8825_REG_INTERRUPT_MASK:
191 case NAU8825_REG_INT_CLR_KEY_STATUS ... NAU8825_REG_KEYDET_CTRL:
192 case NAU8825_REG_VDET_THRESHOLD_1 ... NAU8825_REG_DACR_CTRL:
193 case NAU8825_REG_ADC_DRC_KNEE_IP12 ... NAU8825_REG_ADC_DRC_ATKDCY:
194 case NAU8825_REG_DAC_DRC_KNEE_IP12 ... NAU8825_REG_DAC_DRC_ATKDCY:
195 case NAU8825_REG_IMM_MODE_CTRL:
196 case NAU8825_REG_CLASSG_CTRL ... NAU8825_REG_OPT_EFUSE_CTRL:
197 case NAU8825_REG_MISC_CTRL:
198 case NAU8825_REG_BIAS_ADJ:
199 case NAU8825_REG_TRIM_SETTINGS ... NAU8825_REG_ANALOG_CONTROL_2:
200 case NAU8825_REG_ANALOG_ADC_1 ... NAU8825_REG_MIC_BIAS:
201 case NAU8825_REG_BOOST ... NAU8825_REG_FEPGA:
202 case NAU8825_REG_POWER_UP_CONTROL ... NAU8825_REG_CHARGE_PUMP:
203 return true;
204 default:
205 return false;
206 }
207}
208
209static bool nau8825_volatile_reg(struct device *dev, unsigned int reg)
210{
211 switch (reg) {
212 case NAU8825_REG_RESET:
213 case NAU8825_REG_IRQ_STATUS:
214 case NAU8825_REG_INT_CLR_KEY_STATUS:
215 case NAU8825_REG_IMM_RMS_L:
216 case NAU8825_REG_IMM_RMS_R:
217 case NAU8825_REG_I2C_DEVICE_ID:
218 case NAU8825_REG_SARDOUT_RAM_STATUS:
219 case NAU8825_REG_CHARGE_PUMP_INPUT_READ:
220 case NAU8825_REG_GENERAL_STATUS:
221 return true;
222 default:
223 return false;
224 }
225}
226
227static int nau8825_pump_event(struct snd_soc_dapm_widget *w,
228 struct snd_kcontrol *kcontrol, int event)
229{
230 switch (event) {
231 case SND_SOC_DAPM_POST_PMU:
232 /* Prevent startup click by letting charge pump to ramp up */
233 msleep(10);
234 break;
235 default:
236 return -EINVAL;
237 }
238
239 return 0;
240}
241
242static const char * const nau8825_adc_decimation[] = {
243 "32", "64", "128", "256"
244};
245
246static const struct soc_enum nau8825_adc_decimation_enum =
247 SOC_ENUM_SINGLE(NAU8825_REG_ADC_RATE, NAU8825_ADC_SYNC_DOWN_SFT,
248 ARRAY_SIZE(nau8825_adc_decimation), nau8825_adc_decimation);
249
250static const char * const nau8825_dac_oversampl[] = {
251 "64", "256", "128", "", "32"
252};
253
254static const struct soc_enum nau8825_dac_oversampl_enum =
255 SOC_ENUM_SINGLE(NAU8825_REG_DAC_CTRL1, NAU8825_DAC_OVERSAMPLE_SFT,
256 ARRAY_SIZE(nau8825_dac_oversampl), nau8825_dac_oversampl);
257
258static const DECLARE_TLV_DB_MINMAX_MUTE(adc_vol_tlv, -10300, 2400);
259static const DECLARE_TLV_DB_MINMAX_MUTE(sidetone_vol_tlv, -4200, 0);
260static const DECLARE_TLV_DB_MINMAX(dac_vol_tlv, -5400, 0);
261static const DECLARE_TLV_DB_MINMAX(fepga_gain_tlv, -100, 3600);
262static const DECLARE_TLV_DB_MINMAX_MUTE(crosstalk_vol_tlv, -9600, 2400);
263
264static const struct snd_kcontrol_new nau8825_controls[] = {
265 SOC_SINGLE_TLV("Mic Volume", NAU8825_REG_ADC_DGAIN_CTRL,
266 0, 0xff, 0, adc_vol_tlv),
267 SOC_DOUBLE_TLV("Headphone Bypass Volume", NAU8825_REG_ADC_DGAIN_CTRL,
268 12, 8, 0x0f, 0, sidetone_vol_tlv),
269 SOC_DOUBLE_TLV("Headphone Volume", NAU8825_REG_HSVOL_CTRL,
270 6, 0, 0x3f, 1, dac_vol_tlv),
271 SOC_SINGLE_TLV("Frontend PGA Volume", NAU8825_REG_POWER_UP_CONTROL,
272 8, 37, 0, fepga_gain_tlv),
273 SOC_DOUBLE_TLV("Headphone Crosstalk Volume", NAU8825_REG_DAC_DGAIN_CTRL,
274 0, 8, 0xff, 0, crosstalk_vol_tlv),
275
276 SOC_ENUM("ADC Decimation Rate", nau8825_adc_decimation_enum),
277 SOC_ENUM("DAC Oversampling Rate", nau8825_dac_oversampl_enum),
278};
279
280/* DAC Mux 0x33[9] and 0x34[9] */
281static const char * const nau8825_dac_src[] = {
282 "DACL", "DACR",
283};
284
285static SOC_ENUM_SINGLE_DECL(
286 nau8825_dacl_enum, NAU8825_REG_DACL_CTRL,
287 NAU8825_DACL_CH_SEL_SFT, nau8825_dac_src);
288
289static SOC_ENUM_SINGLE_DECL(
290 nau8825_dacr_enum, NAU8825_REG_DACR_CTRL,
291 NAU8825_DACR_CH_SEL_SFT, nau8825_dac_src);
292
293static const struct snd_kcontrol_new nau8825_dacl_mux =
294 SOC_DAPM_ENUM("DACL Source", nau8825_dacl_enum);
295
296static const struct snd_kcontrol_new nau8825_dacr_mux =
297 SOC_DAPM_ENUM("DACR Source", nau8825_dacr_enum);
298
299
300static const struct snd_soc_dapm_widget nau8825_dapm_widgets[] = {
301 SND_SOC_DAPM_AIF_OUT("AIFTX", "Capture", 0, NAU8825_REG_I2S_PCM_CTRL2,
302 15, 1),
303
304 SND_SOC_DAPM_INPUT("MIC"),
305 SND_SOC_DAPM_MICBIAS("MICBIAS", NAU8825_REG_MIC_BIAS, 8, 0),
306
307 SND_SOC_DAPM_PGA("Frontend PGA", NAU8825_REG_POWER_UP_CONTROL, 14, 0,
308 NULL, 0),
309
310 SND_SOC_DAPM_ADC("ADC", NULL, NAU8825_REG_ENA_CTRL, 8, 0),
311 SND_SOC_DAPM_SUPPLY("ADC Clock", NAU8825_REG_ENA_CTRL, 7, 0, NULL, 0),
312 SND_SOC_DAPM_SUPPLY("ADC Power", NAU8825_REG_ANALOG_ADC_2, 6, 0, NULL,
313 0),
314
315 /* ADC for button press detection */
316 SND_SOC_DAPM_ADC("SAR", NULL, NAU8825_REG_SAR_CTRL,
317 NAU8825_SAR_ADC_EN_SFT, 0),
318
319 SND_SOC_DAPM_DAC("ADACL", NULL, NAU8825_REG_RDAC, 12, 0),
320 SND_SOC_DAPM_DAC("ADACR", NULL, NAU8825_REG_RDAC, 13, 0),
321 SND_SOC_DAPM_SUPPLY("ADACL Clock", NAU8825_REG_RDAC, 8, 0, NULL, 0),
322 SND_SOC_DAPM_SUPPLY("ADACR Clock", NAU8825_REG_RDAC, 9, 0, NULL, 0),
323
324 SND_SOC_DAPM_DAC("DDACR", NULL, NAU8825_REG_ENA_CTRL,
325 NAU8825_ENABLE_DACR_SFT, 0),
326 SND_SOC_DAPM_DAC("DDACL", NULL, NAU8825_REG_ENA_CTRL,
327 NAU8825_ENABLE_DACL_SFT, 0),
328 SND_SOC_DAPM_SUPPLY("DDAC Clock", NAU8825_REG_ENA_CTRL, 6, 0, NULL, 0),
329
330 SND_SOC_DAPM_MUX("DACL Mux", SND_SOC_NOPM, 0, 0, &nau8825_dacl_mux),
331 SND_SOC_DAPM_MUX("DACR Mux", SND_SOC_NOPM, 0, 0, &nau8825_dacr_mux),
332
333 SND_SOC_DAPM_PGA("HP amp L", NAU8825_REG_CLASSG_CTRL, 1, 0, NULL, 0),
334 SND_SOC_DAPM_PGA("HP amp R", NAU8825_REG_CLASSG_CTRL, 2, 0, NULL, 0),
335 SND_SOC_DAPM_SUPPLY("HP amp power", NAU8825_REG_CLASSG_CTRL, 0, 0, NULL,
336 0),
337
338 SND_SOC_DAPM_SUPPLY("Charge Pump", NAU8825_REG_CHARGE_PUMP, 5, 0,
339 nau8825_pump_event, SND_SOC_DAPM_POST_PMU),
340
341 SND_SOC_DAPM_PGA("Output Driver R Stage 1",
342 NAU8825_REG_POWER_UP_CONTROL, 5, 0, NULL, 0),
343 SND_SOC_DAPM_PGA("Output Driver L Stage 1",
344 NAU8825_REG_POWER_UP_CONTROL, 4, 0, NULL, 0),
345 SND_SOC_DAPM_PGA("Output Driver R Stage 2",
346 NAU8825_REG_POWER_UP_CONTROL, 3, 0, NULL, 0),
347 SND_SOC_DAPM_PGA("Output Driver L Stage 2",
348 NAU8825_REG_POWER_UP_CONTROL, 2, 0, NULL, 0),
349 SND_SOC_DAPM_PGA_S("Output Driver R Stage 3", 1,
350 NAU8825_REG_POWER_UP_CONTROL, 1, 0, NULL, 0),
351 SND_SOC_DAPM_PGA_S("Output Driver L Stage 3", 1,
352 NAU8825_REG_POWER_UP_CONTROL, 0, 0, NULL, 0),
353
354 SND_SOC_DAPM_PGA_S("Output DACL", 2, NAU8825_REG_CHARGE_PUMP, 8, 1, NULL, 0),
355 SND_SOC_DAPM_PGA_S("Output DACR", 2, NAU8825_REG_CHARGE_PUMP, 9, 1, NULL, 0),
356
357 SND_SOC_DAPM_OUTPUT("HPOL"),
358 SND_SOC_DAPM_OUTPUT("HPOR"),
359};
360
361static const struct snd_soc_dapm_route nau8825_dapm_routes[] = {
362 {"Frontend PGA", NULL, "MIC"},
363 {"ADC", NULL, "Frontend PGA"},
364 {"ADC", NULL, "ADC Clock"},
365 {"ADC", NULL, "ADC Power"},
366 {"AIFTX", NULL, "ADC"},
367
368 {"DDACL", NULL, "Playback"},
369 {"DDACR", NULL, "Playback"},
370 {"DDACL", NULL, "DDAC Clock"},
371 {"DDACR", NULL, "DDAC Clock"},
372 {"DACL Mux", "DACL", "DDACL"},
373 {"DACL Mux", "DACR", "DDACR"},
374 {"DACR Mux", "DACL", "DDACL"},
375 {"DACR Mux", "DACR", "DDACR"},
376 {"HP amp L", NULL, "DACL Mux"},
377 {"HP amp R", NULL, "DACR Mux"},
378 {"HP amp L", NULL, "HP amp power"},
379 {"HP amp R", NULL, "HP amp power"},
380 {"ADACL", NULL, "HP amp L"},
381 {"ADACR", NULL, "HP amp R"},
382 {"ADACL", NULL, "ADACL Clock"},
383 {"ADACR", NULL, "ADACR Clock"},
384 {"Output Driver L Stage 1", NULL, "ADACL"},
385 {"Output Driver R Stage 1", NULL, "ADACR"},
386 {"Output Driver L Stage 2", NULL, "Output Driver L Stage 1"},
387 {"Output Driver R Stage 2", NULL, "Output Driver R Stage 1"},
388 {"Output Driver L Stage 3", NULL, "Output Driver L Stage 2"},
389 {"Output Driver R Stage 3", NULL, "Output Driver R Stage 2"},
390 {"Output DACL", NULL, "Output Driver L Stage 3"},
391 {"Output DACR", NULL, "Output Driver R Stage 3"},
392 {"HPOL", NULL, "Output DACL"},
393 {"HPOR", NULL, "Output DACR"},
394 {"HPOL", NULL, "Charge Pump"},
395 {"HPOR", NULL, "Charge Pump"},
396};
397
398static int nau8825_hw_params(struct snd_pcm_substream *substream,
399 struct snd_pcm_hw_params *params,
400 struct snd_soc_dai *dai)
401{
402 struct snd_soc_codec *codec = dai->codec;
403 struct nau8825 *nau8825 = snd_soc_codec_get_drvdata(codec);
404 unsigned int val_len = 0;
405
406 switch (params_width(params)) {
407 case 16:
408 val_len |= NAU8825_I2S_DL_16;
409 break;
410 case 20:
411 val_len |= NAU8825_I2S_DL_20;
412 break;
413 case 24:
414 val_len |= NAU8825_I2S_DL_24;
415 break;
416 case 32:
417 val_len |= NAU8825_I2S_DL_32;
418 break;
419 default:
420 return -EINVAL;
421 }
422
423 regmap_update_bits(nau8825->regmap, NAU8825_REG_I2S_PCM_CTRL1,
424 NAU8825_I2S_DL_MASK, val_len);
425
426 return 0;
427}
428
429static int nau8825_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
430{
431 struct snd_soc_codec *codec = codec_dai->codec;
432 struct nau8825 *nau8825 = snd_soc_codec_get_drvdata(codec);
433 unsigned int ctrl1_val = 0, ctrl2_val = 0;
434
435 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
436 case SND_SOC_DAIFMT_CBM_CFM:
437 ctrl2_val |= NAU8825_I2S_MS_MASTER;
438 break;
439 case SND_SOC_DAIFMT_CBS_CFS:
440 break;
441 default:
442 return -EINVAL;
443 }
444
445 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
446 case SND_SOC_DAIFMT_NB_NF:
447 break;
448 case SND_SOC_DAIFMT_IB_NF:
449 ctrl1_val |= NAU8825_I2S_BP_INV;
450 break;
451 default:
452 return -EINVAL;
453 }
454
455 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
456 case SND_SOC_DAIFMT_I2S:
457 ctrl1_val |= NAU8825_I2S_DF_I2S;
458 break;
459 case SND_SOC_DAIFMT_LEFT_J:
460 ctrl1_val |= NAU8825_I2S_DF_LEFT;
461 break;
462 case SND_SOC_DAIFMT_RIGHT_J:
463 ctrl1_val |= NAU8825_I2S_DF_RIGTH;
464 break;
465 case SND_SOC_DAIFMT_DSP_A:
466 ctrl1_val |= NAU8825_I2S_DF_PCM_AB;
467 break;
468 case SND_SOC_DAIFMT_DSP_B:
469 ctrl1_val |= NAU8825_I2S_DF_PCM_AB;
470 ctrl1_val |= NAU8825_I2S_PCMB_EN;
471 break;
472 default:
473 return -EINVAL;
474 }
475
476 regmap_update_bits(nau8825->regmap, NAU8825_REG_I2S_PCM_CTRL1,
477 NAU8825_I2S_DL_MASK | NAU8825_I2S_DF_MASK |
478 NAU8825_I2S_BP_MASK | NAU8825_I2S_PCMB_MASK,
479 ctrl1_val);
480 regmap_update_bits(nau8825->regmap, NAU8825_REG_I2S_PCM_CTRL2,
481 NAU8825_I2S_MS_MASK, ctrl2_val);
482
483 return 0;
484}
485
486static const struct snd_soc_dai_ops nau8825_dai_ops = {
487 .hw_params = nau8825_hw_params,
488 .set_fmt = nau8825_set_dai_fmt,
489};
490
491#define NAU8825_RATES SNDRV_PCM_RATE_8000_192000
492#define NAU8825_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE \
493 | SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S32_LE)
494
495static struct snd_soc_dai_driver nau8825_dai = {
496 .name = "nau8825-hifi",
497 .playback = {
498 .stream_name = "Playback",
499 .channels_min = 1,
500 .channels_max = 2,
501 .rates = NAU8825_RATES,
502 .formats = NAU8825_FORMATS,
503 },
504 .capture = {
505 .stream_name = "Capture",
506 .channels_min = 1,
507 .channels_max = 1,
508 .rates = NAU8825_RATES,
509 .formats = NAU8825_FORMATS,
510 },
511 .ops = &nau8825_dai_ops,
512};
513
514/**
515 * nau8825_enable_jack_detect - Specify a jack for event reporting
516 *
517 * @component: component to register the jack with
518 * @jack: jack to use to report headset and button events on
519 *
520 * After this function has been called the headset insert/remove and button
521 * events will be routed to the given jack. Jack can be null to stop
522 * reporting.
523 */
524int nau8825_enable_jack_detect(struct snd_soc_codec *codec,
525 struct snd_soc_jack *jack)
526{
527 struct nau8825 *nau8825 = snd_soc_codec_get_drvdata(codec);
528 struct regmap *regmap = nau8825->regmap;
529
530 nau8825->jack = jack;
531
532 /* Ground HP Outputs[1:0], needed for headset auto detection
533 * Enable Automatic Mic/Gnd switching reading on insert interrupt[6]
534 */
535 regmap_update_bits(regmap, NAU8825_REG_HSD_CTRL,
536 NAU8825_HSD_AUTO_MODE | NAU8825_SPKR_DWN1R | NAU8825_SPKR_DWN1L,
537 NAU8825_HSD_AUTO_MODE | NAU8825_SPKR_DWN1R | NAU8825_SPKR_DWN1L);
538
539 regmap_update_bits(regmap, NAU8825_REG_INTERRUPT_MASK,
540 NAU8825_IRQ_HEADSET_COMPLETE_EN | NAU8825_IRQ_EJECT_EN, 0);
541
542 return 0;
543}
544EXPORT_SYMBOL_GPL(nau8825_enable_jack_detect);
545
546
547static bool nau8825_is_jack_inserted(struct regmap *regmap)
548{
549 int status;
550
551 regmap_read(regmap, NAU8825_REG_I2C_DEVICE_ID, &status);
552 return !(status & NAU8825_GPIO2JD1);
553}
554
555static void nau8825_restart_jack_detection(struct regmap *regmap)
556{
557 /* this will restart the entire jack detection process including MIC/GND
558 * switching and create interrupts. We have to go from 0 to 1 and back
559 * to 0 to restart.
560 */
561 regmap_update_bits(regmap, NAU8825_REG_JACK_DET_CTRL,
562 NAU8825_JACK_DET_RESTART, NAU8825_JACK_DET_RESTART);
563 regmap_update_bits(regmap, NAU8825_REG_JACK_DET_CTRL,
564 NAU8825_JACK_DET_RESTART, 0);
565}
566
567static void nau8825_eject_jack(struct nau8825 *nau8825)
568{
569 struct snd_soc_dapm_context *dapm = nau8825->dapm;
570 struct regmap *regmap = nau8825->regmap;
571
572 snd_soc_dapm_disable_pin(dapm, "SAR");
573 snd_soc_dapm_disable_pin(dapm, "MICBIAS");
574 /* Detach 2kOhm Resistors from MICBIAS to MICGND1/2 */
575 regmap_update_bits(regmap, NAU8825_REG_MIC_BIAS,
576 NAU8825_MICBIAS_JKSLV | NAU8825_MICBIAS_JKR2, 0);
577 /* ground HPL/HPR, MICGRND1/2 */
578 regmap_update_bits(regmap, NAU8825_REG_HSD_CTRL, 0xf, 0xf);
579
580 snd_soc_dapm_sync(dapm);
581}
582
583static int nau8825_button_decode(int value)
584{
585 int buttons = 0;
586
587 /* The chip supports up to 8 buttons, but ALSA defines only 6 buttons */
588 if (value & BIT(0))
589 buttons |= SND_JACK_BTN_0;
590 if (value & BIT(1))
591 buttons |= SND_JACK_BTN_1;
592 if (value & BIT(2))
593 buttons |= SND_JACK_BTN_2;
594 if (value & BIT(3))
595 buttons |= SND_JACK_BTN_3;
596 if (value & BIT(4))
597 buttons |= SND_JACK_BTN_4;
598 if (value & BIT(5))
599 buttons |= SND_JACK_BTN_5;
600
601 return buttons;
602}
603
604static int nau8825_jack_insert(struct nau8825 *nau8825)
605{
606 struct regmap *regmap = nau8825->regmap;
607 struct snd_soc_dapm_context *dapm = nau8825->dapm;
608 int jack_status_reg, mic_detected;
609 int type = 0;
610
611 regmap_read(regmap, NAU8825_REG_GENERAL_STATUS, &jack_status_reg);
612 mic_detected = (jack_status_reg >> 10) & 3;
613
614 switch (mic_detected) {
615 case 0:
616 /* no mic */
617 type = SND_JACK_HEADPHONE;
618 break;
619 case 1:
620 dev_dbg(nau8825->dev, "OMTP (micgnd1) mic connected\n");
621 type = SND_JACK_HEADSET;
622
623 /* Unground MICGND1 */
624 regmap_update_bits(regmap, NAU8825_REG_HSD_CTRL, 3 << 2,
625 1 << 2);
626 /* Attach 2kOhm Resistor from MICBIAS to MICGND1 */
627 regmap_update_bits(regmap, NAU8825_REG_MIC_BIAS,
628 NAU8825_MICBIAS_JKSLV | NAU8825_MICBIAS_JKR2,
629 NAU8825_MICBIAS_JKR2);
630 /* Attach SARADC to MICGND1 */
631 regmap_update_bits(regmap, NAU8825_REG_SAR_CTRL,
632 NAU8825_SAR_INPUT_MASK,
633 NAU8825_SAR_INPUT_JKR2);
634
635 snd_soc_dapm_force_enable_pin(dapm, "MICBIAS");
636 snd_soc_dapm_force_enable_pin(dapm, "SAR");
637 snd_soc_dapm_sync(dapm);
638 break;
639 case 2:
640 case 3:
641 dev_dbg(nau8825->dev, "CTIA (micgnd2) mic connected\n");
642 type = SND_JACK_HEADSET;
643
644 /* Unground MICGND2 */
645 regmap_update_bits(regmap, NAU8825_REG_HSD_CTRL, 3 << 2,
646 2 << 2);
647 /* Attach 2kOhm Resistor from MICBIAS to MICGND2 */
648 regmap_update_bits(regmap, NAU8825_REG_MIC_BIAS,
649 NAU8825_MICBIAS_JKSLV | NAU8825_MICBIAS_JKR2,
650 NAU8825_MICBIAS_JKSLV);
651 /* Attach SARADC to MICGND2 */
652 regmap_update_bits(regmap, NAU8825_REG_SAR_CTRL,
653 NAU8825_SAR_INPUT_MASK,
654 NAU8825_SAR_INPUT_JKSLV);
655
656 snd_soc_dapm_force_enable_pin(dapm, "MICBIAS");
657 snd_soc_dapm_force_enable_pin(dapm, "SAR");
658 snd_soc_dapm_sync(dapm);
659 break;
660 }
661
662 if (type & SND_JACK_HEADPHONE) {
663 /* Unground HPL/R */
664 regmap_update_bits(regmap, NAU8825_REG_HSD_CTRL, 0x3, 0);
665 }
666
667 return type;
668}
669
670#define NAU8825_BUTTONS (SND_JACK_BTN_0 | SND_JACK_BTN_1 | \
671 SND_JACK_BTN_2 | SND_JACK_BTN_3)
672
673static irqreturn_t nau8825_interrupt(int irq, void *data)
674{
675 struct nau8825 *nau8825 = (struct nau8825 *)data;
676 struct regmap *regmap = nau8825->regmap;
677 int active_irq, clear_irq = 0, event = 0, event_mask = 0;
678
679 regmap_read(regmap, NAU8825_REG_IRQ_STATUS, &active_irq);
680
681 if ((active_irq & NAU8825_JACK_EJECTION_IRQ_MASK) ==
682 NAU8825_JACK_EJECTION_DETECTED) {
683
684 nau8825_eject_jack(nau8825);
685 event_mask |= SND_JACK_HEADSET;
686 clear_irq = NAU8825_JACK_EJECTION_IRQ_MASK;
687 } else if (active_irq & NAU8825_KEY_SHORT_PRESS_IRQ) {
688 int key_status;
689
690 regmap_read(regmap, NAU8825_REG_INT_CLR_KEY_STATUS,
691 &key_status);
692
693 /* upper 8 bits of the register are for short pressed keys,
694 * lower 8 bits - for long pressed buttons
695 */
696 nau8825->button_pressed = nau8825_button_decode(
697 key_status >> 8);
698
699 event |= nau8825->button_pressed;
700 event_mask |= NAU8825_BUTTONS;
701 clear_irq = NAU8825_KEY_SHORT_PRESS_IRQ;
702 } else if (active_irq & NAU8825_KEY_RELEASE_IRQ) {
703 event_mask = NAU8825_BUTTONS;
704 clear_irq = NAU8825_KEY_RELEASE_IRQ;
705 } else if (active_irq & NAU8825_HEADSET_COMPLETION_IRQ) {
706 if (nau8825_is_jack_inserted(regmap)) {
707 event |= nau8825_jack_insert(nau8825);
708 } else {
709 dev_warn(nau8825->dev, "Headset completion IRQ fired but no headset connected\n");
710 nau8825_eject_jack(nau8825);
711 }
712
713 event_mask |= SND_JACK_HEADSET;
714 clear_irq = NAU8825_HEADSET_COMPLETION_IRQ;
715 }
716
717 if (!clear_irq)
718 clear_irq = active_irq;
719 /* clears the rightmost interruption */
720 regmap_write(regmap, NAU8825_REG_INT_CLR_KEY_STATUS, clear_irq);
721
722 if (event_mask)
723 snd_soc_jack_report(nau8825->jack, event, event_mask);
724
725 return IRQ_HANDLED;
726}
727
728static void nau8825_setup_buttons(struct nau8825 *nau8825)
729{
730 struct regmap *regmap = nau8825->regmap;
731
732 regmap_update_bits(regmap, NAU8825_REG_SAR_CTRL,
733 NAU8825_SAR_TRACKING_GAIN_MASK,
734 nau8825->sar_voltage << NAU8825_SAR_TRACKING_GAIN_SFT);
735 regmap_update_bits(regmap, NAU8825_REG_SAR_CTRL,
736 NAU8825_SAR_COMPARE_TIME_MASK,
737 nau8825->sar_compare_time << NAU8825_SAR_COMPARE_TIME_SFT);
738 regmap_update_bits(regmap, NAU8825_REG_SAR_CTRL,
739 NAU8825_SAR_SAMPLING_TIME_MASK,
740 nau8825->sar_sampling_time << NAU8825_SAR_SAMPLING_TIME_SFT);
741
742 regmap_update_bits(regmap, NAU8825_REG_KEYDET_CTRL,
743 NAU8825_KEYDET_LEVELS_NR_MASK,
744 (nau8825->sar_threshold_num - 1) << NAU8825_KEYDET_LEVELS_NR_SFT);
745 regmap_update_bits(regmap, NAU8825_REG_KEYDET_CTRL,
746 NAU8825_KEYDET_HYSTERESIS_MASK,
747 nau8825->sar_hysteresis << NAU8825_KEYDET_HYSTERESIS_SFT);
748 regmap_update_bits(regmap, NAU8825_REG_KEYDET_CTRL,
749 NAU8825_KEYDET_SHORTKEY_DEBOUNCE_MASK,
750 nau8825->key_debounce << NAU8825_KEYDET_SHORTKEY_DEBOUNCE_SFT);
751
752 regmap_write(regmap, NAU8825_REG_VDET_THRESHOLD_1,
753 (nau8825->sar_threshold[0] << 8) | nau8825->sar_threshold[1]);
754 regmap_write(regmap, NAU8825_REG_VDET_THRESHOLD_2,
755 (nau8825->sar_threshold[2] << 8) | nau8825->sar_threshold[3]);
756 regmap_write(regmap, NAU8825_REG_VDET_THRESHOLD_3,
757 (nau8825->sar_threshold[4] << 8) | nau8825->sar_threshold[5]);
758 regmap_write(regmap, NAU8825_REG_VDET_THRESHOLD_4,
759 (nau8825->sar_threshold[6] << 8) | nau8825->sar_threshold[7]);
760
761 /* Enable short press and release interruptions */
762 regmap_update_bits(regmap, NAU8825_REG_INTERRUPT_MASK,
763 NAU8825_IRQ_KEY_SHORT_PRESS_EN | NAU8825_IRQ_KEY_RELEASE_EN,
764 0);
765}
766
767static void nau8825_init_regs(struct nau8825 *nau8825)
768{
769 struct regmap *regmap = nau8825->regmap;
770
771 /* Enable Bias/Vmid */
772 regmap_update_bits(nau8825->regmap, NAU8825_REG_BIAS_ADJ,
773 NAU8825_BIAS_VMID, NAU8825_BIAS_VMID);
774 regmap_update_bits(nau8825->regmap, NAU8825_REG_BOOST,
775 NAU8825_GLOBAL_BIAS_EN, NAU8825_GLOBAL_BIAS_EN);
776
777 /* VMID Tieoff */
778 regmap_update_bits(regmap, NAU8825_REG_BIAS_ADJ,
779 NAU8825_BIAS_VMID_SEL_MASK,
780 nau8825->vref_impedance << NAU8825_BIAS_VMID_SEL_SFT);
781 /* Disable Boost Driver, Automatic Short circuit protection enable */
782 regmap_update_bits(regmap, NAU8825_REG_BOOST,
783 NAU8825_PRECHARGE_DIS | NAU8825_HP_BOOST_G_DIS |
784 NAU8825_SHORT_SHUTDOWN_EN,
785 NAU8825_PRECHARGE_DIS | NAU8825_HP_BOOST_G_DIS |
786 NAU8825_SHORT_SHUTDOWN_EN);
787
788 regmap_update_bits(regmap, NAU8825_REG_GPIO12_CTRL,
789 NAU8825_JKDET_OUTPUT_EN,
790 nau8825->jkdet_enable ? 0 : NAU8825_JKDET_OUTPUT_EN);
791 regmap_update_bits(regmap, NAU8825_REG_GPIO12_CTRL,
792 NAU8825_JKDET_PULL_EN,
793 nau8825->jkdet_pull_enable ? 0 : NAU8825_JKDET_PULL_EN);
794 regmap_update_bits(regmap, NAU8825_REG_GPIO12_CTRL,
795 NAU8825_JKDET_PULL_UP,
796 nau8825->jkdet_pull_up ? NAU8825_JKDET_PULL_UP : 0);
797 regmap_update_bits(regmap, NAU8825_REG_JACK_DET_CTRL,
798 NAU8825_JACK_POLARITY,
799 /* jkdet_polarity - 1 is for active-low */
800 nau8825->jkdet_polarity ? 0 : NAU8825_JACK_POLARITY);
801
802 regmap_update_bits(regmap, NAU8825_REG_JACK_DET_CTRL,
803 NAU8825_JACK_INSERT_DEBOUNCE_MASK,
804 nau8825->jack_insert_debounce << NAU8825_JACK_INSERT_DEBOUNCE_SFT);
805 regmap_update_bits(regmap, NAU8825_REG_JACK_DET_CTRL,
806 NAU8825_JACK_EJECT_DEBOUNCE_MASK,
807 nau8825->jack_eject_debounce << NAU8825_JACK_EJECT_DEBOUNCE_SFT);
808
809 /* Mask unneeded IRQs: 1 - disable, 0 - enable */
810 regmap_update_bits(regmap, NAU8825_REG_INTERRUPT_MASK, 0x7ff, 0x7ff);
811
812 regmap_update_bits(regmap, NAU8825_REG_MIC_BIAS,
813 NAU8825_MICBIAS_VOLTAGE_MASK, nau8825->micbias_voltage);
814
815 if (nau8825->sar_threshold_num)
816 nau8825_setup_buttons(nau8825);
817
818 /* Default oversampling/decimations settings are unusable
819 * (audible hiss). Set it to something better.
820 */
821 regmap_update_bits(regmap, NAU8825_REG_ADC_RATE,
822 NAU8825_ADC_SYNC_DOWN_MASK, NAU8825_ADC_SYNC_DOWN_128);
823 regmap_update_bits(regmap, NAU8825_REG_DAC_CTRL1,
824 NAU8825_DAC_OVERSAMPLE_MASK, NAU8825_DAC_OVERSAMPLE_128);
825}
826
827static const struct regmap_config nau8825_regmap_config = {
828 .val_bits = 16,
829 .reg_bits = 16,
830
831 .max_register = NAU8825_REG_MAX,
832 .readable_reg = nau8825_readable_reg,
833 .writeable_reg = nau8825_writeable_reg,
834 .volatile_reg = nau8825_volatile_reg,
835
836 .cache_type = REGCACHE_RBTREE,
837 .reg_defaults = nau8825_reg_defaults,
838 .num_reg_defaults = ARRAY_SIZE(nau8825_reg_defaults),
839};
840
841static int nau8825_codec_probe(struct snd_soc_codec *codec)
842{
843 struct nau8825 *nau8825 = snd_soc_codec_get_drvdata(codec);
844 struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
845
846 nau8825->dapm = dapm;
847
848 /* The interrupt clock is gated by x1[10:8],
849 * one of them needs to be enabled all the time for
850 * interrupts to happen.
851 */
852 snd_soc_dapm_force_enable_pin(dapm, "DDACR");
853 snd_soc_dapm_sync(dapm);
854
855 /* Unmask interruptions. Handler uses dapm object so we can enable
856 * interruptions only after dapm is fully initialized.
857 */
858 regmap_write(nau8825->regmap, NAU8825_REG_INTERRUPT_DIS_CTRL, 0);
859 nau8825_restart_jack_detection(nau8825->regmap);
860
861 return 0;
862}
863
864/**
865 * nau8825_calc_fll_param - Calculate FLL parameters.
866 * @fll_in: external clock provided to codec.
867 * @fs: sampling rate.
868 * @fll_param: Pointer to structure of FLL parameters.
869 *
870 * Calculate FLL parameters to configure codec.
871 *
872 * Returns 0 for success or negative error code.
873 */
874static int nau8825_calc_fll_param(unsigned int fll_in, unsigned int fs,
875 struct nau8825_fll *fll_param)
876{
877 u64 fvco;
878 unsigned int fref, i;
879
880 /* Ensure the reference clock frequency (FREF) is <= 13.5MHz by dividing
881 * freq_in by 1, 2, 4, or 8 using FLL pre-scalar.
882 * FREF = freq_in / NAU8825_FLL_REF_DIV_MASK
883 */
884 for (i = 0; i < ARRAY_SIZE(fll_pre_scalar); i++) {
885 fref = fll_in / fll_pre_scalar[i].param;
886 if (fref <= NAU_FREF_MAX)
887 break;
888 }
889 if (i == ARRAY_SIZE(fll_pre_scalar))
890 return -EINVAL;
891 fll_param->clk_ref_div = fll_pre_scalar[i].val;
892
893 /* Choose the FLL ratio based on FREF */
894 for (i = 0; i < ARRAY_SIZE(fll_ratio); i++) {
895 if (fref >= fll_ratio[i].param)
896 break;
897 }
898 if (i == ARRAY_SIZE(fll_ratio))
899 return -EINVAL;
900 fll_param->ratio = fll_ratio[i].val;
901
902 /* Calculate the frequency of DCO (FDCO) given freq_out = 256 * Fs.
903 * FDCO must be within the 90MHz - 100MHz or the FFL cannot be
904 * guaranteed across the full range of operation.
905 * FDCO = freq_out * 2 * mclk_src_scaling
906 */
907 for (i = 0; i < ARRAY_SIZE(mclk_src_scaling); i++) {
908 fvco = 256 * fs * 2 * mclk_src_scaling[i].param;
909 if (NAU_FVCO_MIN < fvco && fvco < NAU_FVCO_MAX)
910 break;
911 }
912 if (i == ARRAY_SIZE(mclk_src_scaling))
913 return -EINVAL;
914 fll_param->mclk_src = mclk_src_scaling[i].val;
915
916 /* Calculate the FLL 10-bit integer input and the FLL 16-bit fractional
917 * input based on FDCO, FREF and FLL ratio.
918 */
919 fvco = div_u64(fvco << 16, fref * fll_param->ratio);
920 fll_param->fll_int = (fvco >> 16) & 0x3FF;
921 fll_param->fll_frac = fvco & 0xFFFF;
922 return 0;
923}
924
925static void nau8825_fll_apply(struct nau8825 *nau8825,
926 struct nau8825_fll *fll_param)
927{
928 regmap_update_bits(nau8825->regmap, NAU8825_REG_CLK_DIVIDER,
929 NAU8825_CLK_MCLK_SRC_MASK, fll_param->mclk_src);
930 regmap_update_bits(nau8825->regmap, NAU8825_REG_FLL1,
931 NAU8825_FLL_RATIO_MASK, fll_param->ratio);
932 /* FLL 16-bit fractional input */
933 regmap_write(nau8825->regmap, NAU8825_REG_FLL2, fll_param->fll_frac);
934 /* FLL 10-bit integer input */
935 regmap_update_bits(nau8825->regmap, NAU8825_REG_FLL3,
936 NAU8825_FLL_INTEGER_MASK, fll_param->fll_int);
937 /* FLL pre-scaler */
938 regmap_update_bits(nau8825->regmap, NAU8825_REG_FLL4,
939 NAU8825_FLL_REF_DIV_MASK, fll_param->clk_ref_div);
940 /* select divided VCO input */
941 regmap_update_bits(nau8825->regmap, NAU8825_REG_FLL5,
942 NAU8825_FLL_FILTER_SW_MASK, 0x0000);
943 /* FLL sigma delta modulator enable */
944 regmap_update_bits(nau8825->regmap, NAU8825_REG_FLL6,
945 NAU8825_SDM_EN_MASK, NAU8825_SDM_EN);
946}
947
948/* freq_out must be 256*Fs in order to achieve the best performance */
949static int nau8825_set_pll(struct snd_soc_codec *codec, int pll_id, int source,
950 unsigned int freq_in, unsigned int freq_out)
951{
952 struct nau8825 *nau8825 = snd_soc_codec_get_drvdata(codec);
953 struct nau8825_fll fll_param;
954 int ret, fs;
955
956 fs = freq_out / 256;
957 ret = nau8825_calc_fll_param(freq_in, fs, &fll_param);
958 if (ret < 0) {
959 dev_err(codec->dev, "Unsupported input clock %d\n", freq_in);
960 return ret;
961 }
962 dev_dbg(codec->dev, "mclk_src=%x ratio=%x fll_frac=%x fll_int=%x clk_ref_div=%x\n",
963 fll_param.mclk_src, fll_param.ratio, fll_param.fll_frac,
964 fll_param.fll_int, fll_param.clk_ref_div);
965
966 nau8825_fll_apply(nau8825, &fll_param);
967 mdelay(2);
968 regmap_update_bits(nau8825->regmap, NAU8825_REG_CLK_DIVIDER,
969 NAU8825_CLK_SRC_MASK, NAU8825_CLK_SRC_VCO);
970 return 0;
971}
972
973static int nau8825_configure_sysclk(struct nau8825 *nau8825, int clk_id,
974 unsigned int freq)
975{
976 struct regmap *regmap = nau8825->regmap;
977 int ret;
978
979 switch (clk_id) {
980 case NAU8825_CLK_MCLK:
981 regmap_update_bits(regmap, NAU8825_REG_CLK_DIVIDER,
982 NAU8825_CLK_SRC_MASK, NAU8825_CLK_SRC_MCLK);
983 regmap_update_bits(regmap, NAU8825_REG_FLL6, NAU8825_DCO_EN, 0);
984
985 /* We selected MCLK source but the clock itself managed externally */
986 if (!nau8825->mclk)
987 break;
988
989 if (!nau8825->mclk_freq) {
990 ret = clk_prepare_enable(nau8825->mclk);
991 if (ret) {
992 dev_err(nau8825->dev, "Unable to prepare codec mclk\n");
993 return ret;
994 }
995 }
996
997 if (nau8825->mclk_freq != freq) {
998 nau8825->mclk_freq = freq;
999
1000 freq = clk_round_rate(nau8825->mclk, freq);
1001 ret = clk_set_rate(nau8825->mclk, freq);
1002 if (ret) {
1003 dev_err(nau8825->dev, "Unable to set mclk rate\n");
1004 return ret;
1005 }
1006 }
1007
1008 break;
1009 case NAU8825_CLK_INTERNAL:
1010 regmap_update_bits(regmap, NAU8825_REG_FLL6, NAU8825_DCO_EN,
1011 NAU8825_DCO_EN);
1012 regmap_update_bits(regmap, NAU8825_REG_CLK_DIVIDER,
1013 NAU8825_CLK_SRC_MASK, NAU8825_CLK_SRC_VCO);
1014
1015 if (nau8825->mclk_freq) {
1016 clk_disable_unprepare(nau8825->mclk);
1017 nau8825->mclk_freq = 0;
1018 }
1019
1020 break;
1021 default:
1022 dev_err(nau8825->dev, "Invalid clock id (%d)\n", clk_id);
1023 return -EINVAL;
1024 }
1025
1026 dev_dbg(nau8825->dev, "Sysclk is %dHz and clock id is %d\n", freq,
1027 clk_id);
1028 return 0;
1029}
1030
1031static int nau8825_set_sysclk(struct snd_soc_codec *codec, int clk_id,
1032 int source, unsigned int freq, int dir)
1033{
1034 struct nau8825 *nau8825 = snd_soc_codec_get_drvdata(codec);
1035
1036 return nau8825_configure_sysclk(nau8825, clk_id, freq);
1037}
1038
1039static int nau8825_set_bias_level(struct snd_soc_codec *codec,
1040 enum snd_soc_bias_level level)
1041{
1042 struct nau8825 *nau8825 = snd_soc_codec_get_drvdata(codec);
1043 int ret;
1044
1045 switch (level) {
1046 case SND_SOC_BIAS_ON:
1047 break;
1048
1049 case SND_SOC_BIAS_PREPARE:
1050 break;
1051
1052 case SND_SOC_BIAS_STANDBY:
1053 if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF) {
1054 if (nau8825->mclk_freq) {
1055 ret = clk_prepare_enable(nau8825->mclk);
1056 if (ret) {
1057 dev_err(nau8825->dev, "Unable to prepare codec mclk\n");
1058 return ret;
1059 }
1060 }
1061
1062 ret = regcache_sync(nau8825->regmap);
1063 if (ret) {
1064 dev_err(codec->dev,
1065 "Failed to sync cache: %d\n", ret);
1066 return ret;
1067 }
1068 }
1069
1070 break;
1071
1072 case SND_SOC_BIAS_OFF:
1073 if (nau8825->mclk_freq)
1074 clk_disable_unprepare(nau8825->mclk);
1075
1076 regcache_mark_dirty(nau8825->regmap);
1077 break;
1078 }
1079 return 0;
1080}
1081
1082static struct snd_soc_codec_driver nau8825_codec_driver = {
1083 .probe = nau8825_codec_probe,
1084 .set_sysclk = nau8825_set_sysclk,
1085 .set_pll = nau8825_set_pll,
1086 .set_bias_level = nau8825_set_bias_level,
1087 .suspend_bias_off = true,
1088
1089 .controls = nau8825_controls,
1090 .num_controls = ARRAY_SIZE(nau8825_controls),
1091 .dapm_widgets = nau8825_dapm_widgets,
1092 .num_dapm_widgets = ARRAY_SIZE(nau8825_dapm_widgets),
1093 .dapm_routes = nau8825_dapm_routes,
1094 .num_dapm_routes = ARRAY_SIZE(nau8825_dapm_routes),
1095};
1096
1097static void nau8825_reset_chip(struct regmap *regmap)
1098{
1099 regmap_write(regmap, NAU8825_REG_RESET, 0x00);
1100 regmap_write(regmap, NAU8825_REG_RESET, 0x00);
1101}
1102
1103static void nau8825_print_device_properties(struct nau8825 *nau8825)
1104{
1105 int i;
1106 struct device *dev = nau8825->dev;
1107
1108 dev_dbg(dev, "jkdet-enable: %d\n", nau8825->jkdet_enable);
1109 dev_dbg(dev, "jkdet-pull-enable: %d\n", nau8825->jkdet_pull_enable);
1110 dev_dbg(dev, "jkdet-pull-up: %d\n", nau8825->jkdet_pull_up);
1111 dev_dbg(dev, "jkdet-polarity: %d\n", nau8825->jkdet_polarity);
1112 dev_dbg(dev, "micbias-voltage: %d\n", nau8825->micbias_voltage);
1113 dev_dbg(dev, "vref-impedance: %d\n", nau8825->vref_impedance);
1114
1115 dev_dbg(dev, "sar-threshold-num: %d\n", nau8825->sar_threshold_num);
1116 for (i = 0; i < nau8825->sar_threshold_num; i++)
1117 dev_dbg(dev, "sar-threshold[%d]=%d\n", i,
1118 nau8825->sar_threshold[i]);
1119
1120 dev_dbg(dev, "sar-hysteresis: %d\n", nau8825->sar_hysteresis);
1121 dev_dbg(dev, "sar-voltage: %d\n", nau8825->sar_voltage);
1122 dev_dbg(dev, "sar-compare-time: %d\n", nau8825->sar_compare_time);
1123 dev_dbg(dev, "sar-sampling-time: %d\n", nau8825->sar_sampling_time);
1124 dev_dbg(dev, "short-key-debounce: %d\n", nau8825->key_debounce);
1125 dev_dbg(dev, "jack-insert-debounce: %d\n",
1126 nau8825->jack_insert_debounce);
1127 dev_dbg(dev, "jack-eject-debounce: %d\n",
1128 nau8825->jack_eject_debounce);
1129}
1130
1131static int nau8825_read_device_properties(struct device *dev,
1132 struct nau8825 *nau8825) {
1133
1134 nau8825->jkdet_enable = device_property_read_bool(dev,
1135 "nuvoton,jkdet-enable");
1136 nau8825->jkdet_pull_enable = device_property_read_bool(dev,
1137 "nuvoton,jkdet-pull-enable");
1138 nau8825->jkdet_pull_up = device_property_read_bool(dev,
1139 "nuvoton,jkdet-pull-up");
1140 device_property_read_u32(dev, "nuvoton,jkdet-polarity",
1141 &nau8825->jkdet_polarity);
1142 device_property_read_u32(dev, "nuvoton,micbias-voltage",
1143 &nau8825->micbias_voltage);
1144 device_property_read_u32(dev, "nuvoton,vref-impedance",
1145 &nau8825->vref_impedance);
1146 device_property_read_u32(dev, "nuvoton,sar-threshold-num",
1147 &nau8825->sar_threshold_num);
1148 device_property_read_u32_array(dev, "nuvoton,sar-threshold",
1149 nau8825->sar_threshold, nau8825->sar_threshold_num);
1150 device_property_read_u32(dev, "nuvoton,sar-hysteresis",
1151 &nau8825->sar_hysteresis);
1152 device_property_read_u32(dev, "nuvoton,sar-voltage",
1153 &nau8825->sar_voltage);
1154 device_property_read_u32(dev, "nuvoton,sar-compare-time",
1155 &nau8825->sar_compare_time);
1156 device_property_read_u32(dev, "nuvoton,sar-sampling-time",
1157 &nau8825->sar_sampling_time);
1158 device_property_read_u32(dev, "nuvoton,short-key-debounce",
1159 &nau8825->key_debounce);
1160 device_property_read_u32(dev, "nuvoton,jack-insert-debounce",
1161 &nau8825->jack_insert_debounce);
1162 device_property_read_u32(dev, "nuvoton,jack-eject-debounce",
1163 &nau8825->jack_eject_debounce);
1164
1165 nau8825->mclk = devm_clk_get(dev, "mclk");
1166 if (PTR_ERR(nau8825->mclk) == -EPROBE_DEFER) {
1167 return -EPROBE_DEFER;
1168 } else if (PTR_ERR(nau8825->mclk) == -ENOENT) {
1169 /* The MCLK is managed externally or not used at all */
1170 nau8825->mclk = NULL;
1171 dev_info(dev, "No 'mclk' clock found, assume MCLK is managed externally");
1172 } else if (IS_ERR(nau8825->mclk)) {
1173 return -EINVAL;
1174 }
1175
1176 return 0;
1177}
1178
1179static int nau8825_setup_irq(struct nau8825 *nau8825)
1180{
1181 struct regmap *regmap = nau8825->regmap;
1182 int ret;
1183
1184 /* IRQ Output Enable */
1185 regmap_update_bits(regmap, NAU8825_REG_INTERRUPT_MASK,
1186 NAU8825_IRQ_OUTPUT_EN, NAU8825_IRQ_OUTPUT_EN);
1187
1188 /* Enable internal VCO needed for interruptions */
1189 nau8825_configure_sysclk(nau8825, NAU8825_CLK_INTERNAL, 0);
1190
1191 /* Enable DDACR needed for interrupts
1192 * It is the same as force_enable_pin("DDACR") we do later
1193 */
1194 regmap_update_bits(regmap, NAU8825_REG_ENA_CTRL,
1195 NAU8825_ENABLE_DACR, NAU8825_ENABLE_DACR);
1196
1197 /* Chip needs one FSCLK cycle in order to generate interrupts,
1198 * as we cannot guarantee one will be provided by the system. Turning
1199 * master mode on then off enables us to generate that FSCLK cycle
1200 * with a minimum of contention on the clock bus.
1201 */
1202 regmap_update_bits(regmap, NAU8825_REG_I2S_PCM_CTRL2,
1203 NAU8825_I2S_MS_MASK, NAU8825_I2S_MS_MASTER);
1204 regmap_update_bits(regmap, NAU8825_REG_I2S_PCM_CTRL2,
1205 NAU8825_I2S_MS_MASK, NAU8825_I2S_MS_SLAVE);
1206
1207 ret = devm_request_threaded_irq(nau8825->dev, nau8825->irq, NULL,
1208 nau8825_interrupt, IRQF_TRIGGER_LOW | IRQF_ONESHOT,
1209 "nau8825", nau8825);
1210
1211 if (ret) {
1212 dev_err(nau8825->dev, "Cannot request irq %d (%d)\n",
1213 nau8825->irq, ret);
1214 return ret;
1215 }
1216
1217 return 0;
1218}
1219
1220static int nau8825_i2c_probe(struct i2c_client *i2c,
1221 const struct i2c_device_id *id)
1222{
1223 struct device *dev = &i2c->dev;
1224 struct nau8825 *nau8825 = dev_get_platdata(&i2c->dev);
1225 int ret, value;
1226
1227 if (!nau8825) {
1228 nau8825 = devm_kzalloc(dev, sizeof(*nau8825), GFP_KERNEL);
1229 if (!nau8825)
1230 return -ENOMEM;
1231 ret = nau8825_read_device_properties(dev, nau8825);
1232 if (ret)
1233 return ret;
1234 }
1235
1236 i2c_set_clientdata(i2c, nau8825);
1237
1238 nau8825->regmap = devm_regmap_init_i2c(i2c, &nau8825_regmap_config);
1239 if (IS_ERR(nau8825->regmap))
1240 return PTR_ERR(nau8825->regmap);
1241 nau8825->dev = dev;
1242 nau8825->irq = i2c->irq;
1243
1244 nau8825_print_device_properties(nau8825);
1245
1246 nau8825_reset_chip(nau8825->regmap);
1247 ret = regmap_read(nau8825->regmap, NAU8825_REG_I2C_DEVICE_ID, &value);
1248 if (ret < 0) {
1249 dev_err(dev, "Failed to read device id from the NAU8825: %d\n",
1250 ret);
1251 return ret;
1252 }
1253 if ((value & NAU8825_SOFTWARE_ID_MASK) !=
1254 NAU8825_SOFTWARE_ID_NAU8825) {
1255 dev_err(dev, "Not a NAU8825 chip\n");
1256 return -ENODEV;
1257 }
1258
1259 nau8825_init_regs(nau8825);
1260
1261 if (i2c->irq)
1262 nau8825_setup_irq(nau8825);
1263
1264 return snd_soc_register_codec(&i2c->dev, &nau8825_codec_driver,
1265 &nau8825_dai, 1);
1266}
1267
1268static int nau8825_i2c_remove(struct i2c_client *client)
1269{
1270 snd_soc_unregister_codec(&client->dev);
1271 return 0;
1272}
1273
1274static const struct i2c_device_id nau8825_i2c_ids[] = {
1275 { "nau8825", 0 },
1276 { }
1277};
1278
1279#ifdef CONFIG_OF
1280static const struct of_device_id nau8825_of_ids[] = {
1281 { .compatible = "nuvoton,nau8825", },
1282 {}
1283};
1284MODULE_DEVICE_TABLE(of, nau8825_of_ids);
1285#endif
1286
1287#ifdef CONFIG_ACPI
1288static const struct acpi_device_id nau8825_acpi_match[] = {
1289 { "10508825", 0 },
1290 {},
1291};
1292MODULE_DEVICE_TABLE(acpi, nau8825_acpi_match);
1293#endif
1294
1295static struct i2c_driver nau8825_driver = {
1296 .driver = {
1297 .name = "nau8825",
1298 .of_match_table = of_match_ptr(nau8825_of_ids),
1299 .acpi_match_table = ACPI_PTR(nau8825_acpi_match),
1300 },
1301 .probe = nau8825_i2c_probe,
1302 .remove = nau8825_i2c_remove,
1303 .id_table = nau8825_i2c_ids,
1304};
1305module_i2c_driver(nau8825_driver);
1306
1307MODULE_DESCRIPTION("ASoC nau8825 driver");
1308MODULE_AUTHOR("Anatol Pomozov <anatol@chromium.org>");
1309MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/nau8825.h b/sound/soc/codecs/nau8825.h
new file mode 100644
index 000000000000..dff8edb83bfd
--- /dev/null
+++ b/sound/soc/codecs/nau8825.h
@@ -0,0 +1,341 @@
1/*
2 * NAU8825 ALSA SoC audio driver
3 *
4 * Copyright 2015 Google Inc.
5 * Author: Anatol Pomozov <anatol.pomozov@chrominium.org>
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 __NAU8825_H__
13#define __NAU8825_H__
14
15#define NAU8825_REG_RESET 0x00
16#define NAU8825_REG_ENA_CTRL 0x01
17#define NAU8825_REG_CLK_DIVIDER 0x03
18#define NAU8825_REG_FLL1 0x04
19#define NAU8825_REG_FLL2 0x05
20#define NAU8825_REG_FLL3 0x06
21#define NAU8825_REG_FLL4 0x07
22#define NAU8825_REG_FLL5 0x08
23#define NAU8825_REG_FLL6 0x09
24#define NAU8825_REG_FLL_VCO_RSV 0x0a
25#define NAU8825_REG_HSD_CTRL 0x0c
26#define NAU8825_REG_JACK_DET_CTRL 0x0d
27#define NAU8825_REG_INTERRUPT_MASK 0x0f
28#define NAU8825_REG_IRQ_STATUS 0x10
29#define NAU8825_REG_INT_CLR_KEY_STATUS 0x11
30#define NAU8825_REG_INTERRUPT_DIS_CTRL 0x12
31#define NAU8825_REG_SAR_CTRL 0x13
32#define NAU8825_REG_KEYDET_CTRL 0x14
33#define NAU8825_REG_VDET_THRESHOLD_1 0x15
34#define NAU8825_REG_VDET_THRESHOLD_2 0x16
35#define NAU8825_REG_VDET_THRESHOLD_3 0x17
36#define NAU8825_REG_VDET_THRESHOLD_4 0x18
37#define NAU8825_REG_GPIO34_CTRL 0x19
38#define NAU8825_REG_GPIO12_CTRL 0x1a
39#define NAU8825_REG_TDM_CTRL 0x1b
40#define NAU8825_REG_I2S_PCM_CTRL1 0x1c
41#define NAU8825_REG_I2S_PCM_CTRL2 0x1d
42#define NAU8825_REG_LEFT_TIME_SLOT 0x1e
43#define NAU8825_REG_RIGHT_TIME_SLOT 0x1f
44#define NAU8825_REG_BIQ_CTRL 0x20
45#define NAU8825_REG_BIQ_COF1 0x21
46#define NAU8825_REG_BIQ_COF2 0x22
47#define NAU8825_REG_BIQ_COF3 0x23
48#define NAU8825_REG_BIQ_COF4 0x24
49#define NAU8825_REG_BIQ_COF5 0x25
50#define NAU8825_REG_BIQ_COF6 0x26
51#define NAU8825_REG_BIQ_COF7 0x27
52#define NAU8825_REG_BIQ_COF8 0x28
53#define NAU8825_REG_BIQ_COF9 0x29
54#define NAU8825_REG_BIQ_COF10 0x2a
55#define NAU8825_REG_ADC_RATE 0x2b
56#define NAU8825_REG_DAC_CTRL1 0x2c
57#define NAU8825_REG_DAC_CTRL2 0x2d
58#define NAU8825_REG_DAC_DGAIN_CTRL 0x2f
59#define NAU8825_REG_ADC_DGAIN_CTRL 0x30
60#define NAU8825_REG_MUTE_CTRL 0x31
61#define NAU8825_REG_HSVOL_CTRL 0x32
62#define NAU8825_REG_DACL_CTRL 0x33
63#define NAU8825_REG_DACR_CTRL 0x34
64#define NAU8825_REG_ADC_DRC_KNEE_IP12 0x38
65#define NAU8825_REG_ADC_DRC_KNEE_IP34 0x39
66#define NAU8825_REG_ADC_DRC_SLOPES 0x3a
67#define NAU8825_REG_ADC_DRC_ATKDCY 0x3b
68#define NAU8825_REG_DAC_DRC_KNEE_IP12 0x45
69#define NAU8825_REG_DAC_DRC_KNEE_IP34 0x46
70#define NAU8825_REG_DAC_DRC_SLOPES 0x47
71#define NAU8825_REG_DAC_DRC_ATKDCY 0x48
72#define NAU8825_REG_IMM_MODE_CTRL 0x4c
73#define NAU8825_REG_IMM_RMS_L 0x4d
74#define NAU8825_REG_IMM_RMS_R 0x4e
75#define NAU8825_REG_CLASSG_CTRL 0x50
76#define NAU8825_REG_OPT_EFUSE_CTRL 0x51
77#define NAU8825_REG_MISC_CTRL 0x55
78#define NAU8825_REG_I2C_DEVICE_ID 0x58
79#define NAU8825_REG_SARDOUT_RAM_STATUS 0x59
80#define NAU8825_REG_BIAS_ADJ 0x66
81#define NAU8825_REG_TRIM_SETTINGS 0x68
82#define NAU8825_REG_ANALOG_CONTROL_1 0x69
83#define NAU8825_REG_ANALOG_CONTROL_2 0x6a
84#define NAU8825_REG_ANALOG_ADC_1 0x71
85#define NAU8825_REG_ANALOG_ADC_2 0x72
86#define NAU8825_REG_RDAC 0x73
87#define NAU8825_REG_MIC_BIAS 0x74
88#define NAU8825_REG_BOOST 0x76
89#define NAU8825_REG_FEPGA 0x77
90#define NAU8825_REG_POWER_UP_CONTROL 0x7f
91#define NAU8825_REG_CHARGE_PUMP 0x80
92#define NAU8825_REG_CHARGE_PUMP_INPUT_READ 0x81
93#define NAU8825_REG_GENERAL_STATUS 0x82
94#define NAU8825_REG_MAX NAU8825_REG_GENERAL_STATUS
95
96/* ENA_CTRL (0x1) */
97#define NAU8825_ENABLE_DACR_SFT 10
98#define NAU8825_ENABLE_DACR (1 << NAU8825_ENABLE_DACR_SFT)
99#define NAU8825_ENABLE_DACL_SFT 9
100#define NAU8825_ENABLE_ADC_SFT 8
101#define NAU8825_ENABLE_SAR_SFT 1
102
103/* CLK_DIVIDER (0x3) */
104#define NAU8825_CLK_SRC_SFT 15
105#define NAU8825_CLK_SRC_MASK (1 << NAU8825_CLK_SRC_SFT)
106#define NAU8825_CLK_SRC_VCO (1 << NAU8825_CLK_SRC_SFT)
107#define NAU8825_CLK_SRC_MCLK (0 << NAU8825_CLK_SRC_SFT)
108#define NAU8825_CLK_MCLK_SRC_MASK (0xf << 0)
109
110/* FLL1 (0x04) */
111#define NAU8825_FLL_RATIO_MASK (0x7f << 0)
112
113/* FLL3 (0x06) */
114#define NAU8825_FLL_INTEGER_MASK (0x3ff << 0)
115
116/* FLL4 (0x07) */
117#define NAU8825_FLL_REF_DIV_MASK (0x3 << 10)
118
119/* FLL5 (0x08) */
120#define NAU8825_FLL_FILTER_SW_MASK (0x1 << 14)
121
122/* FLL6 (0x9) */
123#define NAU8825_DCO_EN_MASK (0x1 << 15)
124#define NAU8825_DCO_EN (0x1 << 15)
125#define NAU8825_DCO_DIS (0x0 << 15)
126#define NAU8825_SDM_EN_MASK (0x1 << 14)
127#define NAU8825_SDM_EN (0x1 << 14)
128#define NAU8825_SDM_DIS (0x0 << 14)
129
130/* HSD_CTRL (0xc) */
131#define NAU8825_HSD_AUTO_MODE (1 << 6)
132/* 0 - short to GND, 1 - open */
133#define NAU8825_SPKR_DWN1R (1 << 1)
134#define NAU8825_SPKR_DWN1L (1 << 0)
135
136/* JACK_DET_CTRL (0xd) */
137#define NAU8825_JACK_DET_RESTART (1 << 9)
138#define NAU8825_JACK_INSERT_DEBOUNCE_SFT 5
139#define NAU8825_JACK_INSERT_DEBOUNCE_MASK (0x7 << NAU8825_JACK_INSERT_DEBOUNCE_SFT)
140#define NAU8825_JACK_EJECT_DEBOUNCE_SFT 2
141#define NAU8825_JACK_EJECT_DEBOUNCE_MASK (0x7 << NAU8825_JACK_EJECT_DEBOUNCE_SFT)
142#define NAU8825_JACK_POLARITY (1 << 1) /* 0 - active low, 1 - active high */
143
144/* INTERRUPT_MASK (0xf) */
145#define NAU8825_IRQ_OUTPUT_EN (1 << 11)
146#define NAU8825_IRQ_HEADSET_COMPLETE_EN (1 << 10)
147#define NAU8825_IRQ_KEY_RELEASE_EN (1 << 7)
148#define NAU8825_IRQ_KEY_SHORT_PRESS_EN (1 << 5)
149#define NAU8825_IRQ_EJECT_EN (1 << 2)
150
151/* IRQ_STATUS (0x10) */
152#define NAU8825_HEADSET_COMPLETION_IRQ (1 << 10)
153#define NAU8825_SHORT_CIRCUIT_IRQ (1 << 9)
154#define NAU8825_IMPEDANCE_MEAS_IRQ (1 << 8)
155#define NAU8825_KEY_IRQ_MASK (0x7 << 5)
156#define NAU8825_KEY_RELEASE_IRQ (1 << 7)
157#define NAU8825_KEY_LONG_PRESS_IRQ (1 << 6)
158#define NAU8825_KEY_SHORT_PRESS_IRQ (1 << 5)
159#define NAU8825_MIC_DETECTION_IRQ (1 << 4)
160#define NAU8825_JACK_EJECTION_IRQ_MASK (3 << 2)
161#define NAU8825_JACK_EJECTION_DETECTED (1 << 2)
162#define NAU8825_JACK_INSERTION_IRQ_MASK (3 << 0)
163#define NAU8825_JACK_INSERTION_DETECTED (1 << 0)
164
165/* INTERRUPT_DIS_CTRL (0x12) */
166#define NAU8825_IRQ_HEADSET_COMPLETE_DIS (1 << 10)
167#define NAU8825_IRQ_KEY_RELEASE_DIS (1 << 7)
168#define NAU8825_IRQ_KEY_SHORT_PRESS_DIS (1 << 5)
169#define NAU8825_IRQ_EJECT_DIS (1 << 2)
170
171/* SAR_CTRL (0x13) */
172#define NAU8825_SAR_ADC_EN_SFT 12
173#define NAU8825_SAR_ADC_EN (1 << NAU8825_SAR_ADC_EN_SFT)
174#define NAU8825_SAR_INPUT_MASK (1 << 11)
175#define NAU8825_SAR_INPUT_JKSLV (1 << 11)
176#define NAU8825_SAR_INPUT_JKR2 (0 << 11)
177#define NAU8825_SAR_TRACKING_GAIN_SFT 8
178#define NAU8825_SAR_TRACKING_GAIN_MASK (0x7 << NAU8825_SAR_TRACKING_GAIN_SFT)
179#define NAU8825_SAR_COMPARE_TIME_SFT 2
180#define NAU8825_SAR_COMPARE_TIME_MASK (3 << 2)
181#define NAU8825_SAR_SAMPLING_TIME_SFT 0
182#define NAU8825_SAR_SAMPLING_TIME_MASK (3 << 0)
183
184/* KEYDET_CTRL (0x14) */
185#define NAU8825_KEYDET_SHORTKEY_DEBOUNCE_SFT 12
186#define NAU8825_KEYDET_SHORTKEY_DEBOUNCE_MASK (0x3 << NAU8825_KEYDET_SHORTKEY_DEBOUNCE_SFT)
187#define NAU8825_KEYDET_LEVELS_NR_SFT 8
188#define NAU8825_KEYDET_LEVELS_NR_MASK (0x7 << 8)
189#define NAU8825_KEYDET_HYSTERESIS_SFT 0
190#define NAU8825_KEYDET_HYSTERESIS_MASK 0xf
191
192/* GPIO12_CTRL (0x1a) */
193#define NAU8825_JKDET_PULL_UP (1 << 11) /* 0 - pull down, 1 - pull up */
194#define NAU8825_JKDET_PULL_EN (1 << 9) /* 0 - enable pull, 1 - disable */
195#define NAU8825_JKDET_OUTPUT_EN (1 << 8) /* 0 - enable input, 1 - enable output */
196
197/* I2S_PCM_CTRL1 (0x1c) */
198#define NAU8825_I2S_BP_SFT 7
199#define NAU8825_I2S_BP_MASK (1 << NAU8825_I2S_BP_SFT)
200#define NAU8825_I2S_BP_INV (1 << NAU8825_I2S_BP_SFT)
201#define NAU8825_I2S_PCMB_SFT 6
202#define NAU8825_I2S_PCMB_MASK (1 << NAU8825_I2S_PCMB_SFT)
203#define NAU8825_I2S_PCMB_EN (1 << NAU8825_I2S_PCMB_SFT)
204#define NAU8825_I2S_DL_SFT 2
205#define NAU8825_I2S_DL_MASK (0x3 << NAU8825_I2S_DL_SFT)
206#define NAU8825_I2S_DL_16 (0 << NAU8825_I2S_DL_SFT)
207#define NAU8825_I2S_DL_20 (1 << NAU8825_I2S_DL_SFT)
208#define NAU8825_I2S_DL_24 (2 << NAU8825_I2S_DL_SFT)
209#define NAU8825_I2S_DL_32 (3 << NAU8825_I2S_DL_SFT)
210#define NAU8825_I2S_DF_SFT 0
211#define NAU8825_I2S_DF_MASK (0x3 << NAU8825_I2S_DF_SFT)
212#define NAU8825_I2S_DF_RIGTH (0 << NAU8825_I2S_DF_SFT)
213#define NAU8825_I2S_DF_LEFT (1 << NAU8825_I2S_DF_SFT)
214#define NAU8825_I2S_DF_I2S (2 << NAU8825_I2S_DF_SFT)
215#define NAU8825_I2S_DF_PCM_AB (3 << NAU8825_I2S_DF_SFT)
216
217/* I2S_PCM_CTRL2 (0x1d) */
218#define NAU8825_I2S_TRISTATE (1 << 15) /* 0 - normal mode, 1 - Hi-Z output */
219#define NAU8825_I2S_MS_SFT 3
220#define NAU8825_I2S_MS_MASK (1 << NAU8825_I2S_MS_SFT)
221#define NAU8825_I2S_MS_MASTER (1 << NAU8825_I2S_MS_SFT)
222#define NAU8825_I2S_MS_SLAVE (0 << NAU8825_I2S_MS_SFT)
223
224/* ADC_RATE (0x2b) */
225#define NAU8825_ADC_SYNC_DOWN_SFT 0
226#define NAU8825_ADC_SYNC_DOWN_MASK 0x3
227#define NAU8825_ADC_SYNC_DOWN_32 0
228#define NAU8825_ADC_SYNC_DOWN_64 1
229#define NAU8825_ADC_SYNC_DOWN_128 2
230#define NAU8825_ADC_SYNC_DOWN_256 3
231
232/* DAC_CTRL1 (0x2c) */
233#define NAU8825_DAC_CLIP_OFF (1 << 7)
234#define NAU8825_DAC_OVERSAMPLE_SFT 0
235#define NAU8825_DAC_OVERSAMPLE_MASK 0x7
236#define NAU8825_DAC_OVERSAMPLE_64 0
237#define NAU8825_DAC_OVERSAMPLE_256 1
238#define NAU8825_DAC_OVERSAMPLE_128 2
239#define NAU8825_DAC_OVERSAMPLE_32 4
240
241/* MUTE_CTRL (0x31) */
242#define NAU8825_DAC_ZERO_CROSSING_EN (1 << 9)
243#define NAU8825_DAC_SOFT_MUTE (1 << 9)
244
245/* HSVOL_CTRL (0x32) */
246#define NAU8825_HP_MUTE (1 << 15)
247
248/* DACL_CTRL (0x33) */
249#define NAU8825_DACL_CH_SEL_SFT 9
250
251/* DACR_CTRL (0x34) */
252#define NAU8825_DACR_CH_SEL_SFT 9
253
254/* I2C_DEVICE_ID (0x58) */
255#define NAU8825_GPIO2JD1 (1 << 7)
256#define NAU8825_SOFTWARE_ID_MASK 0x3
257#define NAU8825_SOFTWARE_ID_NAU8825 0x0
258
259/* BIAS_ADJ (0x66) */
260#define NAU8825_BIAS_VMID (1 << 6)
261#define NAU8825_BIAS_VMID_SEL_SFT 4
262#define NAU8825_BIAS_VMID_SEL_MASK (3 << NAU8825_BIAS_VMID_SEL_SFT)
263
264/* ANALOG_CONTROL_2 (0x6a) */
265#define NAU8825_HP_NON_CLASSG_CURRENT_2xADJ (1 << 12)
266#define NAU8825_DAC_CAPACITOR_MSB (1 << 1)
267#define NAU8825_DAC_CAPACITOR_LSB (1 << 0)
268
269/* ANALOG_ADC_2 (0x72) */
270#define NAU8825_ADC_VREFSEL_MASK (0x3 << 8)
271#define NAU8825_ADC_VREFSEL_ANALOG (0 << 8)
272#define NAU8825_ADC_VREFSEL_VMID (1 << 8)
273#define NAU8825_ADC_VREFSEL_VMID_PLUS_0_5DB (2 << 8)
274#define NAU8825_ADC_VREFSEL_VMID_PLUS_1DB (3 << 8)
275#define NAU8825_POWERUP_ADCL (1 << 6)
276
277/* MIC_BIAS (0x74) */
278#define NAU8825_MICBIAS_JKSLV (1 << 14)
279#define NAU8825_MICBIAS_JKR2 (1 << 12)
280#define NAU8825_MICBIAS_POWERUP_SFT 8
281#define NAU8825_MICBIAS_VOLTAGE_SFT 0
282#define NAU8825_MICBIAS_VOLTAGE_MASK 0x7
283
284/* BOOST (0x76) */
285#define NAU8825_PRECHARGE_DIS (1 << 13)
286#define NAU8825_GLOBAL_BIAS_EN (1 << 12)
287#define NAU8825_HP_BOOST_G_DIS (1 << 8)
288#define NAU8825_SHORT_SHUTDOWN_EN (1 << 6)
289
290/* POWER_UP_CONTROL (0x7f) */
291#define NAU8825_POWERUP_INTEGR_R (1 << 5)
292#define NAU8825_POWERUP_INTEGR_L (1 << 4)
293#define NAU8825_POWERUP_DRV_IN_R (1 << 3)
294#define NAU8825_POWERUP_DRV_IN_L (1 << 2)
295#define NAU8825_POWERUP_HP_DRV_R (1 << 1)
296#define NAU8825_POWERUP_HP_DRV_L (1 << 0)
297
298/* CHARGE_PUMP (0x80) */
299#define NAU8825_JAMNODCLOW (1 << 10)
300#define NAU8825_POWER_DOWN_DACR (1 << 9)
301#define NAU8825_POWER_DOWN_DACL (1 << 8)
302#define NAU8825_CHANRGE_PUMP_EN (1 << 5)
303
304
305/* System Clock Source */
306enum {
307 NAU8825_CLK_MCLK = 0,
308 NAU8825_CLK_INTERNAL,
309};
310
311struct nau8825 {
312 struct device *dev;
313 struct regmap *regmap;
314 struct snd_soc_dapm_context *dapm;
315 struct snd_soc_jack *jack;
316 struct clk *mclk;
317 int irq;
318 int mclk_freq; /* 0 - mclk is disabled */
319 int button_pressed;
320 int micbias_voltage;
321 int vref_impedance;
322 bool jkdet_enable;
323 bool jkdet_pull_enable;
324 bool jkdet_pull_up;
325 int jkdet_polarity;
326 int sar_threshold_num;
327 int sar_threshold[8];
328 int sar_hysteresis;
329 int sar_voltage;
330 int sar_compare_time;
331 int sar_sampling_time;
332 int key_debounce;
333 int jack_insert_debounce;
334 int jack_eject_debounce;
335};
336
337int nau8825_enable_jack_detect(struct snd_soc_codec *codec,
338 struct snd_soc_jack *jack);
339
340
341#endif /* __NAU8825_H__ */
diff --git a/sound/soc/codecs/rl6347a.c b/sound/soc/codecs/rl6347a.c
index 91d5166bd3a1..a4b910efbd45 100644
--- a/sound/soc/codecs/rl6347a.c
+++ b/sound/soc/codecs/rl6347a.c
@@ -11,25 +11,8 @@
11 */ 11 */
12 12
13#include <linux/module.h> 13#include <linux/module.h>
14#include <linux/moduleparam.h>
15#include <linux/init.h>
16#include <linux/delay.h>
17#include <linux/pm.h>
18#include <linux/i2c.h> 14#include <linux/i2c.h>
19#include <linux/platform_device.h> 15#include <linux/regmap.h>
20#include <linux/spi/spi.h>
21#include <linux/dmi.h>
22#include <linux/acpi.h>
23#include <sound/core.h>
24#include <sound/pcm.h>
25#include <sound/pcm_params.h>
26#include <sound/soc.h>
27#include <sound/soc-dapm.h>
28#include <sound/initval.h>
29#include <sound/tlv.h>
30#include <sound/jack.h>
31#include <linux/workqueue.h>
32#include <sound/hda_verbs.h>
33 16
34#include "rl6347a.h" 17#include "rl6347a.h"
35 18
diff --git a/sound/soc/codecs/rl6347a.h b/sound/soc/codecs/rl6347a.h
index 1cb56e50b7f3..e127919cb36b 100644
--- a/sound/soc/codecs/rl6347a.h
+++ b/sound/soc/codecs/rl6347a.h
@@ -12,6 +12,8 @@
12#ifndef __RL6347A_H__ 12#ifndef __RL6347A_H__
13#define __RL6347A_H__ 13#define __RL6347A_H__
14 14
15#include <sound/hda_verbs.h>
16
15#define VERB_CMD(V, N, D) ((N << 20) | (V << 8) | D) 17#define VERB_CMD(V, N, D) ((N << 20) | (V << 8) | D)
16 18
17#define RL6347A_VENDOR_REGISTERS 0x20 19#define RL6347A_VENDOR_REGISTERS 0x20
diff --git a/sound/soc/codecs/rt286.c b/sound/soc/codecs/rt286.c
index bd9365885f73..af2ed774b552 100644
--- a/sound/soc/codecs/rt286.c
+++ b/sound/soc/codecs/rt286.c
@@ -29,7 +29,6 @@
29#include <sound/jack.h> 29#include <sound/jack.h>
30#include <linux/workqueue.h> 30#include <linux/workqueue.h>
31#include <sound/rt286.h> 31#include <sound/rt286.h>
32#include <sound/hda_verbs.h>
33 32
34#include "rl6347a.h" 33#include "rl6347a.h"
35#include "rt286.h" 34#include "rt286.h"
@@ -38,7 +37,7 @@
38#define RT288_VENDOR_ID 0x10ec0288 37#define RT288_VENDOR_ID 0x10ec0288
39 38
40struct rt286_priv { 39struct rt286_priv {
41 const struct reg_default *index_cache; 40 struct reg_default *index_cache;
42 int index_cache_size; 41 int index_cache_size;
43 struct regmap *regmap; 42 struct regmap *regmap;
44 struct snd_soc_codec *codec; 43 struct snd_soc_codec *codec;
@@ -1161,7 +1160,11 @@ static int rt286_i2c_probe(struct i2c_client *i2c,
1161 return -ENODEV; 1160 return -ENODEV;
1162 } 1161 }
1163 1162
1164 rt286->index_cache = rt286_index_def; 1163 rt286->index_cache = devm_kmemdup(&i2c->dev, rt286_index_def,
1164 sizeof(rt286_index_def), GFP_KERNEL);
1165 if (!rt286->index_cache)
1166 return -ENOMEM;
1167
1165 rt286->index_cache_size = INDEX_CACHE_SIZE; 1168 rt286->index_cache_size = INDEX_CACHE_SIZE;
1166 rt286->i2c = i2c; 1169 rt286->i2c = i2c;
1167 i2c_set_clientdata(i2c, rt286); 1170 i2c_set_clientdata(i2c, rt286);
diff --git a/sound/soc/codecs/rt298.c b/sound/soc/codecs/rt298.c
index f823eb502367..b3f795c60749 100644
--- a/sound/soc/codecs/rt298.c
+++ b/sound/soc/codecs/rt298.c
@@ -28,7 +28,6 @@
28#include <sound/jack.h> 28#include <sound/jack.h>
29#include <linux/workqueue.h> 29#include <linux/workqueue.h>
30#include <sound/rt298.h> 30#include <sound/rt298.h>
31#include <sound/hda_verbs.h>
32 31
33#include "rl6347a.h" 32#include "rl6347a.h"
34#include "rt298.h" 33#include "rt298.h"
@@ -49,7 +48,7 @@ struct rt298_priv {
49 int is_hp_in; 48 int is_hp_in;
50}; 49};
51 50
52static struct reg_default rt298_index_def[] = { 51static const struct reg_default rt298_index_def[] = {
53 { 0x01, 0xa5a8 }, 52 { 0x01, 0xa5a8 },
54 { 0x02, 0x8e95 }, 53 { 0x02, 0x8e95 },
55 { 0x03, 0x0002 }, 54 { 0x03, 0x0002 },
@@ -129,7 +128,7 @@ static bool rt298_volatile_register(struct device *dev, unsigned int reg)
129 case VERB_CMD(AC_VERB_GET_EAPD_BTLENABLE, RT298_HP_OUT, 0): 128 case VERB_CMD(AC_VERB_GET_EAPD_BTLENABLE, RT298_HP_OUT, 0):
130 return true; 129 return true;
131 default: 130 default:
132 return true; 131 return false;
133 } 132 }
134 133
135 134
@@ -1165,7 +1164,11 @@ static int rt298_i2c_probe(struct i2c_client *i2c,
1165 return -ENODEV; 1164 return -ENODEV;
1166 } 1165 }
1167 1166
1168 rt298->index_cache = rt298_index_def; 1167 rt298->index_cache = devm_kmemdup(&i2c->dev, rt298_index_def,
1168 sizeof(rt298_index_def), GFP_KERNEL);
1169 if (!rt298->index_cache)
1170 return -ENOMEM;
1171
1169 rt298->index_cache_size = INDEX_CACHE_SIZE; 1172 rt298->index_cache_size = INDEX_CACHE_SIZE;
1170 rt298->i2c = i2c; 1173 rt298->i2c = i2c;
1171 i2c_set_clientdata(i2c, rt298); 1174 i2c_set_clientdata(i2c, rt298);
diff --git a/sound/soc/codecs/rt5640.c b/sound/soc/codecs/rt5640.c
index e1ceeb885f7d..f2beb1aa5763 100644
--- a/sound/soc/codecs/rt5640.c
+++ b/sound/soc/codecs/rt5640.c
@@ -405,11 +405,14 @@ static const struct snd_kcontrol_new rt5640_snd_controls[] = {
405 SOC_DOUBLE_TLV("DAC1 Playback Volume", RT5640_DAC1_DIG_VOL, 405 SOC_DOUBLE_TLV("DAC1 Playback Volume", RT5640_DAC1_DIG_VOL,
406 RT5640_L_VOL_SFT, RT5640_R_VOL_SFT, 406 RT5640_L_VOL_SFT, RT5640_R_VOL_SFT,
407 175, 0, dac_vol_tlv), 407 175, 0, dac_vol_tlv),
408 /* IN1/IN2 Control */ 408 /* IN1/IN2/IN3 Control */
409 SOC_SINGLE_TLV("IN1 Boost", RT5640_IN1_IN2, 409 SOC_SINGLE_TLV("IN1 Boost", RT5640_IN1_IN2,
410 RT5640_BST_SFT1, 8, 0, bst_tlv), 410 RT5640_BST_SFT1, 8, 0, bst_tlv),
411 SOC_SINGLE_TLV("IN2 Boost", RT5640_IN3_IN4, 411 SOC_SINGLE_TLV("IN2 Boost", RT5640_IN3_IN4,
412 RT5640_BST_SFT2, 8, 0, bst_tlv), 412 RT5640_BST_SFT2, 8, 0, bst_tlv),
413 SOC_SINGLE_TLV("IN3 Boost", RT5640_IN1_IN2,
414 RT5640_BST_SFT2, 8, 0, bst_tlv),
415
413 /* INL/INR Volume Control */ 416 /* INL/INR Volume Control */
414 SOC_DOUBLE_TLV("IN Capture Volume", RT5640_INL_INR_VOL, 417 SOC_DOUBLE_TLV("IN Capture Volume", RT5640_INL_INR_VOL,
415 RT5640_INL_VOL_SFT, RT5640_INR_VOL_SFT, 418 RT5640_INL_VOL_SFT, RT5640_INR_VOL_SFT,
@@ -598,6 +601,8 @@ static const struct snd_kcontrol_new rt5640_rec_l_mix[] = {
598 RT5640_M_HP_L_RM_L_SFT, 1, 1), 601 RT5640_M_HP_L_RM_L_SFT, 1, 1),
599 SOC_DAPM_SINGLE("INL Switch", RT5640_REC_L2_MIXER, 602 SOC_DAPM_SINGLE("INL Switch", RT5640_REC_L2_MIXER,
600 RT5640_M_IN_L_RM_L_SFT, 1, 1), 603 RT5640_M_IN_L_RM_L_SFT, 1, 1),
604 SOC_DAPM_SINGLE("BST3 Switch", RT5640_REC_L2_MIXER,
605 RT5640_M_BST2_RM_L_SFT, 1, 1),
601 SOC_DAPM_SINGLE("BST2 Switch", RT5640_REC_L2_MIXER, 606 SOC_DAPM_SINGLE("BST2 Switch", RT5640_REC_L2_MIXER,
602 RT5640_M_BST4_RM_L_SFT, 1, 1), 607 RT5640_M_BST4_RM_L_SFT, 1, 1),
603 SOC_DAPM_SINGLE("BST1 Switch", RT5640_REC_L2_MIXER, 608 SOC_DAPM_SINGLE("BST1 Switch", RT5640_REC_L2_MIXER,
@@ -611,6 +616,8 @@ static const struct snd_kcontrol_new rt5640_rec_r_mix[] = {
611 RT5640_M_HP_R_RM_R_SFT, 1, 1), 616 RT5640_M_HP_R_RM_R_SFT, 1, 1),
612 SOC_DAPM_SINGLE("INR Switch", RT5640_REC_R2_MIXER, 617 SOC_DAPM_SINGLE("INR Switch", RT5640_REC_R2_MIXER,
613 RT5640_M_IN_R_RM_R_SFT, 1, 1), 618 RT5640_M_IN_R_RM_R_SFT, 1, 1),
619 SOC_DAPM_SINGLE("BST3 Switch", RT5640_REC_R2_MIXER,
620 RT5640_M_BST2_RM_R_SFT, 1, 1),
614 SOC_DAPM_SINGLE("BST2 Switch", RT5640_REC_R2_MIXER, 621 SOC_DAPM_SINGLE("BST2 Switch", RT5640_REC_R2_MIXER,
615 RT5640_M_BST4_RM_R_SFT, 1, 1), 622 RT5640_M_BST4_RM_R_SFT, 1, 1),
616 SOC_DAPM_SINGLE("BST1 Switch", RT5640_REC_R2_MIXER, 623 SOC_DAPM_SINGLE("BST1 Switch", RT5640_REC_R2_MIXER,
@@ -1065,6 +1072,8 @@ static const struct snd_soc_dapm_widget rt5640_dapm_widgets[] = {
1065 SND_SOC_DAPM_INPUT("IN1N"), 1072 SND_SOC_DAPM_INPUT("IN1N"),
1066 SND_SOC_DAPM_INPUT("IN2P"), 1073 SND_SOC_DAPM_INPUT("IN2P"),
1067 SND_SOC_DAPM_INPUT("IN2N"), 1074 SND_SOC_DAPM_INPUT("IN2N"),
1075 SND_SOC_DAPM_INPUT("IN3P"),
1076 SND_SOC_DAPM_INPUT("IN3N"),
1068 SND_SOC_DAPM_PGA("DMIC L1", SND_SOC_NOPM, 0, 0, NULL, 0), 1077 SND_SOC_DAPM_PGA("DMIC L1", SND_SOC_NOPM, 0, 0, NULL, 0),
1069 SND_SOC_DAPM_PGA("DMIC R1", SND_SOC_NOPM, 0, 0, NULL, 0), 1078 SND_SOC_DAPM_PGA("DMIC R1", SND_SOC_NOPM, 0, 0, NULL, 0),
1070 SND_SOC_DAPM_PGA("DMIC L2", SND_SOC_NOPM, 0, 0, NULL, 0), 1079 SND_SOC_DAPM_PGA("DMIC L2", SND_SOC_NOPM, 0, 0, NULL, 0),
@@ -1081,6 +1090,8 @@ static const struct snd_soc_dapm_widget rt5640_dapm_widgets[] = {
1081 RT5640_PWR_BST1_BIT, 0, NULL, 0), 1090 RT5640_PWR_BST1_BIT, 0, NULL, 0),
1082 SND_SOC_DAPM_PGA("BST2", RT5640_PWR_ANLG2, 1091 SND_SOC_DAPM_PGA("BST2", RT5640_PWR_ANLG2,
1083 RT5640_PWR_BST4_BIT, 0, NULL, 0), 1092 RT5640_PWR_BST4_BIT, 0, NULL, 0),
1093 SND_SOC_DAPM_PGA("BST3", RT5640_PWR_ANLG2,
1094 RT5640_PWR_BST2_BIT, 0, NULL, 0),
1084 /* Input Volume */ 1095 /* Input Volume */
1085 SND_SOC_DAPM_PGA("INL VOL", RT5640_PWR_VOL, 1096 SND_SOC_DAPM_PGA("INL VOL", RT5640_PWR_VOL,
1086 RT5640_PWR_IN_L_BIT, 0, NULL, 0), 1097 RT5640_PWR_IN_L_BIT, 0, NULL, 0),
@@ -1310,6 +1321,7 @@ static const struct snd_soc_dapm_widget rt5639_specific_dapm_widgets[] = {
1310static const struct snd_soc_dapm_route rt5640_dapm_routes[] = { 1321static const struct snd_soc_dapm_route rt5640_dapm_routes[] = {
1311 {"IN1P", NULL, "LDO2"}, 1322 {"IN1P", NULL, "LDO2"},
1312 {"IN2P", NULL, "LDO2"}, 1323 {"IN2P", NULL, "LDO2"},
1324 {"IN3P", NULL, "LDO2"},
1313 1325
1314 {"DMIC L1", NULL, "DMIC1"}, 1326 {"DMIC L1", NULL, "DMIC1"},
1315 {"DMIC R1", NULL, "DMIC1"}, 1327 {"DMIC R1", NULL, "DMIC1"},
@@ -1320,18 +1332,22 @@ static const struct snd_soc_dapm_route rt5640_dapm_routes[] = {
1320 {"BST1", NULL, "IN1N"}, 1332 {"BST1", NULL, "IN1N"},
1321 {"BST2", NULL, "IN2P"}, 1333 {"BST2", NULL, "IN2P"},
1322 {"BST2", NULL, "IN2N"}, 1334 {"BST2", NULL, "IN2N"},
1335 {"BST3", NULL, "IN3P"},
1336 {"BST3", NULL, "IN3N"},
1323 1337
1324 {"INL VOL", NULL, "IN2P"}, 1338 {"INL VOL", NULL, "IN2P"},
1325 {"INR VOL", NULL, "IN2N"}, 1339 {"INR VOL", NULL, "IN2N"},
1326 1340
1327 {"RECMIXL", "HPOL Switch", "HPOL"}, 1341 {"RECMIXL", "HPOL Switch", "HPOL"},
1328 {"RECMIXL", "INL Switch", "INL VOL"}, 1342 {"RECMIXL", "INL Switch", "INL VOL"},
1343 {"RECMIXL", "BST3 Switch", "BST3"},
1329 {"RECMIXL", "BST2 Switch", "BST2"}, 1344 {"RECMIXL", "BST2 Switch", "BST2"},
1330 {"RECMIXL", "BST1 Switch", "BST1"}, 1345 {"RECMIXL", "BST1 Switch", "BST1"},
1331 {"RECMIXL", "OUT MIXL Switch", "OUT MIXL"}, 1346 {"RECMIXL", "OUT MIXL Switch", "OUT MIXL"},
1332 1347
1333 {"RECMIXR", "HPOR Switch", "HPOR"}, 1348 {"RECMIXR", "HPOR Switch", "HPOR"},
1334 {"RECMIXR", "INR Switch", "INR VOL"}, 1349 {"RECMIXR", "INR Switch", "INR VOL"},
1350 {"RECMIXR", "BST3 Switch", "BST3"},
1335 {"RECMIXR", "BST2 Switch", "BST2"}, 1351 {"RECMIXR", "BST2 Switch", "BST2"},
1336 {"RECMIXR", "BST1 Switch", "BST1"}, 1352 {"RECMIXR", "BST1 Switch", "BST1"},
1337 {"RECMIXR", "OUT MIXR Switch", "OUT MIXR"}, 1353 {"RECMIXR", "OUT MIXR Switch", "OUT MIXR"},
@@ -2260,6 +2276,10 @@ static int rt5640_i2c_probe(struct i2c_client *i2c,
2260 regmap_update_bits(rt5640->regmap, RT5640_IN3_IN4, 2276 regmap_update_bits(rt5640->regmap, RT5640_IN3_IN4,
2261 RT5640_IN_DF2, RT5640_IN_DF2); 2277 RT5640_IN_DF2, RT5640_IN_DF2);
2262 2278
2279 if (rt5640->pdata.in3_diff)
2280 regmap_update_bits(rt5640->regmap, RT5640_IN1_IN2,
2281 RT5640_IN_DF2, RT5640_IN_DF2);
2282
2263 rt5640->hp_mute = 1; 2283 rt5640->hp_mute = 1;
2264 2284
2265 return snd_soc_register_codec(&i2c->dev, &soc_codec_dev_rt5640, 2285 return snd_soc_register_codec(&i2c->dev, &soc_codec_dev_rt5640,
diff --git a/sound/soc/codecs/rt5645.c b/sound/soc/codecs/rt5645.c
index 5c101af0ac63..28132375e427 100644
--- a/sound/soc/codecs/rt5645.c
+++ b/sound/soc/codecs/rt5645.c
@@ -42,6 +42,8 @@
42 42
43#define RT5645_PR_BASE (RT5645_PR_RANGE_BASE + (0 * RT5645_PR_SPACING)) 43#define RT5645_PR_BASE (RT5645_PR_RANGE_BASE + (0 * RT5645_PR_SPACING))
44 44
45#define RT5645_HWEQ_NUM 57
46
45static const struct regmap_range_cfg rt5645_ranges[] = { 47static const struct regmap_range_cfg rt5645_ranges[] = {
46 { 48 {
47 .name = "PR", 49 .name = "PR",
@@ -224,6 +226,11 @@ static const struct reg_default rt5645_reg[] = {
224 { 0xff, 0x6308 }, 226 { 0xff, 0x6308 },
225}; 227};
226 228
229struct rt5645_eq_param_s {
230 unsigned short reg;
231 unsigned short val;
232};
233
227static const char *const rt5645_supply_names[] = { 234static const char *const rt5645_supply_names[] = {
228 "avdd", 235 "avdd",
229 "cpvdd", 236 "cpvdd",
@@ -240,6 +247,7 @@ struct rt5645_priv {
240 struct snd_soc_jack *btn_jack; 247 struct snd_soc_jack *btn_jack;
241 struct delayed_work jack_detect_work; 248 struct delayed_work jack_detect_work;
242 struct regulator_bulk_data supplies[ARRAY_SIZE(rt5645_supply_names)]; 249 struct regulator_bulk_data supplies[ARRAY_SIZE(rt5645_supply_names)];
250 struct rt5645_eq_param_s *eq_param;
243 251
244 int codec_type; 252 int codec_type;
245 int sysclk; 253 int sysclk;
@@ -469,6 +477,94 @@ static const DECLARE_TLV_DB_RANGE(bst_tlv,
469 8, 8, TLV_DB_SCALE_ITEM(5200, 0, 0) 477 8, 8, TLV_DB_SCALE_ITEM(5200, 0, 0)
470); 478);
471 479
480/* {-6, -4.5, -3, -1.5, 0, 0.82, 1.58, 2.28} dB */
481static const DECLARE_TLV_DB_RANGE(spk_clsd_tlv,
482 0, 4, TLV_DB_SCALE_ITEM(-600, 150, 0),
483 5, 5, TLV_DB_SCALE_ITEM(82, 0, 0),
484 6, 6, TLV_DB_SCALE_ITEM(158, 0, 0),
485 7, 7, TLV_DB_SCALE_ITEM(228, 0, 0)
486);
487
488static int rt5645_hweq_info(struct snd_kcontrol *kcontrol,
489 struct snd_ctl_elem_info *uinfo)
490{
491 uinfo->type = SNDRV_CTL_ELEM_TYPE_BYTES;
492 uinfo->count = RT5645_HWEQ_NUM * sizeof(struct rt5645_eq_param_s);
493
494 return 0;
495}
496
497static int rt5645_hweq_get(struct snd_kcontrol *kcontrol,
498 struct snd_ctl_elem_value *ucontrol)
499{
500 struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
501 struct rt5645_priv *rt5645 = snd_soc_component_get_drvdata(component);
502 struct rt5645_eq_param_s *eq_param =
503 (struct rt5645_eq_param_s *)ucontrol->value.bytes.data;
504 int i;
505
506 for (i = 0; i < RT5645_HWEQ_NUM; i++) {
507 eq_param[i].reg = cpu_to_be16(rt5645->eq_param[i].reg);
508 eq_param[i].val = cpu_to_be16(rt5645->eq_param[i].val);
509 }
510
511 return 0;
512}
513
514static bool rt5645_validate_hweq(unsigned short reg)
515{
516 if ((reg >= 0x1a4 && reg <= 0x1cd) | (reg >= 0x1e5 && reg <= 0x1f8) |
517 (reg == RT5645_EQ_CTRL2))
518 return true;
519
520 return false;
521}
522
523static int rt5645_hweq_put(struct snd_kcontrol *kcontrol,
524 struct snd_ctl_elem_value *ucontrol)
525{
526 struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
527 struct rt5645_priv *rt5645 = snd_soc_component_get_drvdata(component);
528 struct rt5645_eq_param_s *eq_param =
529 (struct rt5645_eq_param_s *)ucontrol->value.bytes.data;
530 int i;
531
532 for (i = 0; i < RT5645_HWEQ_NUM; i++) {
533 eq_param[i].reg = be16_to_cpu(eq_param[i].reg);
534 eq_param[i].val = be16_to_cpu(eq_param[i].val);
535 }
536
537 /* The final setting of the table should be RT5645_EQ_CTRL2 */
538 for (i = RT5645_HWEQ_NUM - 1; i >= 0; i--) {
539 if (eq_param[i].reg == 0)
540 continue;
541 else if (eq_param[i].reg != RT5645_EQ_CTRL2)
542 return 0;
543 else
544 break;
545 }
546
547 for (i = 0; i < RT5645_HWEQ_NUM; i++) {
548 if (!rt5645_validate_hweq(eq_param[i].reg) &&
549 eq_param[i].reg != 0)
550 return 0;
551 else if (eq_param[i].reg == 0)
552 break;
553 }
554
555 memcpy(rt5645->eq_param, eq_param,
556 RT5645_HWEQ_NUM * sizeof(struct rt5645_eq_param_s));
557
558 return 0;
559}
560
561#define RT5645_HWEQ(xname) \
562{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
563 .info = rt5645_hweq_info, \
564 .get = rt5645_hweq_get, \
565 .put = rt5645_hweq_put \
566}
567
472static const struct snd_kcontrol_new rt5645_snd_controls[] = { 568static const struct snd_kcontrol_new rt5645_snd_controls[] = {
473 /* Speaker Output Volume */ 569 /* Speaker Output Volume */
474 SOC_DOUBLE("Speaker Channel Switch", RT5645_SPK_VOL, 570 SOC_DOUBLE("Speaker Channel Switch", RT5645_SPK_VOL,
@@ -476,6 +572,10 @@ static const struct snd_kcontrol_new rt5645_snd_controls[] = {
476 SOC_DOUBLE_TLV("Speaker Playback Volume", RT5645_SPK_VOL, 572 SOC_DOUBLE_TLV("Speaker Playback Volume", RT5645_SPK_VOL,
477 RT5645_L_VOL_SFT, RT5645_R_VOL_SFT, 39, 1, out_vol_tlv), 573 RT5645_L_VOL_SFT, RT5645_R_VOL_SFT, 39, 1, out_vol_tlv),
478 574
575 /* ClassD modulator Speaker Gain Ratio */
576 SOC_SINGLE_TLV("Speaker ClassD Playback Volume", RT5645_SPO_CLSD_RATIO,
577 RT5645_SPK_G_CLSD_SFT, 7, 0, spk_clsd_tlv),
578
479 /* Headphone Output Volume */ 579 /* Headphone Output Volume */
480 SOC_DOUBLE("Headphone Channel Switch", RT5645_HP_VOL, 580 SOC_DOUBLE("Headphone Channel Switch", RT5645_HP_VOL,
481 RT5645_VOL_L_SFT, RT5645_VOL_R_SFT, 1, 1), 581 RT5645_VOL_L_SFT, RT5645_VOL_R_SFT, 1, 1),
@@ -529,6 +629,7 @@ static const struct snd_kcontrol_new rt5645_snd_controls[] = {
529 /* I2S2 function select */ 629 /* I2S2 function select */
530 SOC_SINGLE("I2S2 Func Switch", RT5645_GPIO_CTRL1, RT5645_I2S2_SEL_SFT, 630 SOC_SINGLE("I2S2 Func Switch", RT5645_GPIO_CTRL1, RT5645_I2S2_SEL_SFT,
531 1, 1), 631 1, 1),
632 RT5645_HWEQ("Speaker HWEQ"),
532}; 633};
533 634
534/** 635/**
@@ -619,6 +720,22 @@ static int is_using_asrc(struct snd_soc_dapm_widget *source,
619 720
620} 721}
621 722
723static int rt5645_enable_hweq(struct snd_soc_codec *codec)
724{
725 struct rt5645_priv *rt5645 = snd_soc_codec_get_drvdata(codec);
726 int i;
727
728 for (i = 0; i < RT5645_HWEQ_NUM; i++) {
729 if (rt5645_validate_hweq(rt5645->eq_param[i].reg))
730 regmap_write(rt5645->regmap, rt5645->eq_param[i].reg,
731 rt5645->eq_param[i].val);
732 else
733 break;
734 }
735
736 return 0;
737}
738
622/** 739/**
623 * rt5645_sel_asrc_clk_src - select ASRC clock source for a set of filters 740 * rt5645_sel_asrc_clk_src - select ASRC clock source for a set of filters
624 * @codec: SoC audio codec device. 741 * @codec: SoC audio codec device.
@@ -1523,6 +1640,7 @@ static int rt5645_spk_event(struct snd_soc_dapm_widget *w,
1523 1640
1524 switch (event) { 1641 switch (event) {
1525 case SND_SOC_DAPM_POST_PMU: 1642 case SND_SOC_DAPM_POST_PMU:
1643 rt5645_enable_hweq(codec);
1526 snd_soc_update_bits(codec, RT5645_PWR_DIG1, 1644 snd_soc_update_bits(codec, RT5645_PWR_DIG1,
1527 RT5645_PWR_CLS_D | RT5645_PWR_CLS_D_R | 1645 RT5645_PWR_CLS_D | RT5645_PWR_CLS_D_R |
1528 RT5645_PWR_CLS_D_L, 1646 RT5645_PWR_CLS_D_L,
@@ -1531,6 +1649,7 @@ static int rt5645_spk_event(struct snd_soc_dapm_widget *w,
1531 break; 1649 break;
1532 1650
1533 case SND_SOC_DAPM_PRE_PMD: 1651 case SND_SOC_DAPM_PRE_PMD:
1652 snd_soc_write(codec, RT5645_EQ_CTRL2, 0);
1534 snd_soc_update_bits(codec, RT5645_PWR_DIG1, 1653 snd_soc_update_bits(codec, RT5645_PWR_DIG1,
1535 RT5645_PWR_CLS_D | RT5645_PWR_CLS_D_R | 1654 RT5645_PWR_CLS_D | RT5645_PWR_CLS_D_R |
1536 RT5645_PWR_CLS_D_L, 0); 1655 RT5645_PWR_CLS_D_L, 0);
@@ -2733,6 +2852,10 @@ static int rt5645_set_bias_level(struct snd_soc_codec *codec,
2733 snd_soc_update_bits(codec, RT5645_PWR_ANLG1, 2852 snd_soc_update_bits(codec, RT5645_PWR_ANLG1,
2734 RT5645_PWR_FV1 | RT5645_PWR_FV2, 2853 RT5645_PWR_FV1 | RT5645_PWR_FV2,
2735 RT5645_PWR_FV1 | RT5645_PWR_FV2); 2854 RT5645_PWR_FV1 | RT5645_PWR_FV2);
2855 if (rt5645->en_button_func &&
2856 snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF)
2857 queue_delayed_work(system_power_efficient_wq,
2858 &rt5645->jack_detect_work, msecs_to_jiffies(0));
2736 break; 2859 break;
2737 2860
2738 case SND_SOC_BIAS_OFF: 2861 case SND_SOC_BIAS_OFF:
@@ -2829,6 +2952,9 @@ static int rt5645_jack_detect(struct snd_soc_codec *codec, int jack_insert)
2829 snd_soc_dapm_sync(dapm); 2952 snd_soc_dapm_sync(dapm);
2830 rt5645->jack_type = SND_JACK_HEADPHONE; 2953 rt5645->jack_type = SND_JACK_HEADPHONE;
2831 } 2954 }
2955 if (rt5645->pdata.jd_invert)
2956 regmap_update_bits(rt5645->regmap, RT5645_IRQ_CTRL2,
2957 RT5645_JD_1_1_MASK, RT5645_JD_1_1_INV);
2832 } else { /* jack out */ 2958 } else { /* jack out */
2833 rt5645->jack_type = 0; 2959 rt5645->jack_type = 0;
2834 2960
@@ -2847,6 +2973,9 @@ static int rt5645_jack_detect(struct snd_soc_codec *codec, int jack_insert)
2847 snd_soc_dapm_disable_pin(dapm, "LDO2"); 2973 snd_soc_dapm_disable_pin(dapm, "LDO2");
2848 snd_soc_dapm_disable_pin(dapm, "Mic Det Power"); 2974 snd_soc_dapm_disable_pin(dapm, "Mic Det Power");
2849 snd_soc_dapm_sync(dapm); 2975 snd_soc_dapm_sync(dapm);
2976 if (rt5645->pdata.jd_invert)
2977 regmap_update_bits(rt5645->regmap, RT5645_IRQ_CTRL2,
2978 RT5645_JD_1_1_MASK, RT5645_JD_1_1_NOR);
2850 } 2979 }
2851 2980
2852 return rt5645->jack_type; 2981 return rt5645->jack_type;
@@ -3038,6 +3167,9 @@ static int rt5645_probe(struct snd_soc_codec *codec)
3038 snd_soc_dapm_sync(dapm); 3167 snd_soc_dapm_sync(dapm);
3039 } 3168 }
3040 3169
3170 rt5645->eq_param = devm_kzalloc(codec->dev,
3171 RT5645_HWEQ_NUM * sizeof(struct rt5645_eq_param_s), GFP_KERNEL);
3172
3041 return 0; 3173 return 0;
3042} 3174}
3043 3175
@@ -3098,7 +3230,7 @@ static struct snd_soc_dai_driver rt5645_dai[] = {
3098 .capture = { 3230 .capture = {
3099 .stream_name = "AIF1 Capture", 3231 .stream_name = "AIF1 Capture",
3100 .channels_min = 1, 3232 .channels_min = 1,
3101 .channels_max = 2, 3233 .channels_max = 4,
3102 .rates = RT5645_STEREO_RATES, 3234 .rates = RT5645_STEREO_RATES,
3103 .formats = RT5645_FORMATS, 3235 .formats = RT5645_FORMATS,
3104 }, 3236 },
@@ -3209,9 +3341,42 @@ static const struct dmi_system_id dmi_platform_intel_braswell[] = {
3209 DMI_MATCH(DMI_PRODUCT_NAME, "Ultima"), 3341 DMI_MATCH(DMI_PRODUCT_NAME, "Ultima"),
3210 }, 3342 },
3211 }, 3343 },
3344 {
3345 .ident = "Google Reks",
3346 .callback = strago_quirk_cb,
3347 .matches = {
3348 DMI_MATCH(DMI_PRODUCT_NAME, "Reks"),
3349 },
3350 },
3212 { } 3351 { }
3213}; 3352};
3214 3353
3354static struct rt5645_platform_data buddy_platform_data = {
3355 .dmic1_data_pin = RT5645_DMIC_DATA_GPIO5,
3356 .dmic2_data_pin = RT5645_DMIC_DATA_IN2P,
3357 .jd_mode = 3,
3358 .jd_invert = true,
3359};
3360
3361static int buddy_quirk_cb(const struct dmi_system_id *id)
3362{
3363 rt5645_pdata = &buddy_platform_data;
3364
3365 return 1;
3366}
3367
3368static struct dmi_system_id dmi_platform_intel_broadwell[] = {
3369 {
3370 .ident = "Chrome Buddy",
3371 .callback = buddy_quirk_cb,
3372 .matches = {
3373 DMI_MATCH(DMI_PRODUCT_NAME, "Buddy"),
3374 },
3375 },
3376 { }
3377};
3378
3379
3215static int rt5645_parse_dt(struct rt5645_priv *rt5645, struct device *dev) 3380static int rt5645_parse_dt(struct rt5645_priv *rt5645, struct device *dev)
3216{ 3381{
3217 rt5645->pdata.in2_diff = device_property_read_bool(dev, 3382 rt5645->pdata.in2_diff = device_property_read_bool(dev,
@@ -3244,7 +3409,8 @@ static int rt5645_i2c_probe(struct i2c_client *i2c,
3244 3409
3245 if (pdata) 3410 if (pdata)
3246 rt5645->pdata = *pdata; 3411 rt5645->pdata = *pdata;
3247 else if (dmi_check_system(dmi_platform_intel_braswell)) 3412 else if (dmi_check_system(dmi_platform_intel_braswell) ||
3413 dmi_check_system(dmi_platform_intel_broadwell))
3248 rt5645->pdata = *rt5645_pdata; 3414 rt5645->pdata = *rt5645_pdata;
3249 else 3415 else
3250 rt5645_parse_dt(rt5645, &i2c->dev); 3416 rt5645_parse_dt(rt5645, &i2c->dev);
@@ -3472,6 +3638,8 @@ static void rt5645_i2c_shutdown(struct i2c_client *i2c)
3472 RT5645_CBJ_MN_JD); 3638 RT5645_CBJ_MN_JD);
3473 regmap_update_bits(rt5645->regmap, RT5645_IN1_CTRL1, RT5645_CBJ_BST1_EN, 3639 regmap_update_bits(rt5645->regmap, RT5645_IN1_CTRL1, RT5645_CBJ_BST1_EN,
3474 0); 3640 0);
3641 msleep(20);
3642 regmap_write(rt5645->regmap, RT5645_RESET, 0);
3475} 3643}
3476 3644
3477static struct i2c_driver rt5645_i2c_driver = { 3645static struct i2c_driver rt5645_i2c_driver = {
diff --git a/sound/soc/codecs/rt5645.h b/sound/soc/codecs/rt5645.h
index 8c964cfb120d..093e46d559fb 100644
--- a/sound/soc/codecs/rt5645.h
+++ b/sound/soc/codecs/rt5645.h
@@ -621,14 +621,14 @@
621#define RT5645_G_OM_L_SM_L_SFT 6 621#define RT5645_G_OM_L_SM_L_SFT 6
622#define RT5645_M_BST1_L_SM_L (0x1 << 5) 622#define RT5645_M_BST1_L_SM_L (0x1 << 5)
623#define RT5645_M_BST1_L_SM_L_SFT 5 623#define RT5645_M_BST1_L_SM_L_SFT 5
624#define RT5645_M_BST3_L_SM_L (0x1 << 4)
625#define RT5645_M_BST3_L_SM_L_SFT 4
624#define RT5645_M_IN_L_SM_L (0x1 << 3) 626#define RT5645_M_IN_L_SM_L (0x1 << 3)
625#define RT5645_M_IN_L_SM_L_SFT 3 627#define RT5645_M_IN_L_SM_L_SFT 3
626#define RT5645_M_DAC_L1_SM_L (0x1 << 1)
627#define RT5645_M_DAC_L1_SM_L_SFT 1
628#define RT5645_M_DAC_L2_SM_L (0x1 << 2) 628#define RT5645_M_DAC_L2_SM_L (0x1 << 2)
629#define RT5645_M_DAC_L2_SM_L_SFT 2 629#define RT5645_M_DAC_L2_SM_L_SFT 2
630#define RT5645_M_BST3_L_SM_L (0x1 << 4) 630#define RT5645_M_DAC_L1_SM_L (0x1 << 1)
631#define RT5645_M_BST3_L_SM_L_SFT 4 631#define RT5645_M_DAC_L1_SM_L_SFT 1
632 632
633/* SPK Right Mixer Control (0x47) */ 633/* SPK Right Mixer Control (0x47) */
634#define RT5645_G_RM_R_SM_R_MASK (0x3 << 14) 634#define RT5645_G_RM_R_SM_R_MASK (0x3 << 14)
@@ -643,14 +643,14 @@
643#define RT5645_G_OM_R_SM_R_SFT 6 643#define RT5645_G_OM_R_SM_R_SFT 6
644#define RT5645_M_BST2_R_SM_R (0x1 << 5) 644#define RT5645_M_BST2_R_SM_R (0x1 << 5)
645#define RT5645_M_BST2_R_SM_R_SFT 5 645#define RT5645_M_BST2_R_SM_R_SFT 5
646#define RT5645_M_BST3_R_SM_R (0x1 << 4)
647#define RT5645_M_BST3_R_SM_R_SFT 4
646#define RT5645_M_IN_R_SM_R (0x1 << 3) 648#define RT5645_M_IN_R_SM_R (0x1 << 3)
647#define RT5645_M_IN_R_SM_R_SFT 3 649#define RT5645_M_IN_R_SM_R_SFT 3
648#define RT5645_M_DAC_R1_SM_R (0x1 << 1)
649#define RT5645_M_DAC_R1_SM_R_SFT 1
650#define RT5645_M_DAC_R2_SM_R (0x1 << 2) 650#define RT5645_M_DAC_R2_SM_R (0x1 << 2)
651#define RT5645_M_DAC_R2_SM_R_SFT 2 651#define RT5645_M_DAC_R2_SM_R_SFT 2
652#define RT5645_M_BST3_R_SM_R (0x1 << 4) 652#define RT5645_M_DAC_R1_SM_R (0x1 << 1)
653#define RT5645_M_BST3_R_SM_R_SFT 4 653#define RT5645_M_DAC_R1_SM_R_SFT 1
654 654
655/* SPOLMIX Control (0x48) */ 655/* SPOLMIX Control (0x48) */
656#define RT5645_M_DAC_L1_SPM_L (0x1 << 15) 656#define RT5645_M_DAC_L1_SPM_L (0x1 << 15)
@@ -670,13 +670,17 @@
670#define RT5645_M_SV_R_SPM_R (0x1 << 0) 670#define RT5645_M_SV_R_SPM_R (0x1 << 0)
671#define RT5645_M_SV_R_SPM_R_SFT 0 671#define RT5645_M_SV_R_SPM_R_SFT 0
672 672
673/* SPOMIX Ratio Control (0x4a) */
674#define RT5645_SPK_G_CLSD_MASK (0x7 << 0)
675#define RT5645_SPK_G_CLSD_SFT 0
676
673/* Mono Output Mixer Control (0x4c) */ 677/* Mono Output Mixer Control (0x4c) */
678#define RT5645_G_MONOMIX_MASK (0x1 << 10)
679#define RT5645_G_MONOMIX_SFT 10
674#define RT5645_M_OV_L_MM (0x1 << 9) 680#define RT5645_M_OV_L_MM (0x1 << 9)
675#define RT5645_M_OV_L_MM_SFT 9 681#define RT5645_M_OV_L_MM_SFT 9
676#define RT5645_M_DAC_L2_MA (0x1 << 8) 682#define RT5645_M_DAC_L2_MA (0x1 << 8)
677#define RT5645_M_DAC_L2_MA_SFT 8 683#define RT5645_M_DAC_L2_MA_SFT 8
678#define RT5645_G_MONOMIX_MASK (0x1 << 10)
679#define RT5645_G_MONOMIX_SFT 10
680#define RT5645_M_BST2_MM (0x1 << 4) 684#define RT5645_M_BST2_MM (0x1 << 4)
681#define RT5645_M_BST2_MM_SFT 4 685#define RT5645_M_BST2_MM_SFT 4
682#define RT5645_M_DAC_R1_MM (0x1 << 3) 686#define RT5645_M_DAC_R1_MM (0x1 << 3)
@@ -779,8 +783,6 @@
779#define RT5645_PWR_CLS_D_R_BIT 9 783#define RT5645_PWR_CLS_D_R_BIT 9
780#define RT5645_PWR_CLS_D_L (0x1 << 8) 784#define RT5645_PWR_CLS_D_L (0x1 << 8)
781#define RT5645_PWR_CLS_D_L_BIT 8 785#define RT5645_PWR_CLS_D_L_BIT 8
782#define RT5645_PWR_ADC_R (0x1 << 1)
783#define RT5645_PWR_ADC_R_BIT 1
784#define RT5645_PWR_DAC_L2 (0x1 << 7) 786#define RT5645_PWR_DAC_L2 (0x1 << 7)
785#define RT5645_PWR_DAC_L2_BIT 7 787#define RT5645_PWR_DAC_L2_BIT 7
786#define RT5645_PWR_DAC_R2 (0x1 << 6) 788#define RT5645_PWR_DAC_R2 (0x1 << 6)
@@ -1628,6 +1630,10 @@
1628#define RT5645_OT_P_NOR (0x0 << 10) 1630#define RT5645_OT_P_NOR (0x0 << 10)
1629#define RT5645_OT_P_INV (0x1 << 10) 1631#define RT5645_OT_P_INV (0x1 << 10)
1630#define RT5645_IRQ_JD_1_1_EN (0x1 << 9) 1632#define RT5645_IRQ_JD_1_1_EN (0x1 << 9)
1633#define RT5645_JD_1_1_MASK (0x1 << 7)
1634#define RT5645_JD_1_1_SFT 7
1635#define RT5645_JD_1_1_NOR (0x0 << 7)
1636#define RT5645_JD_1_1_INV (0x1 << 7)
1631 1637
1632/* IRQ Control 2 (0xbe) */ 1638/* IRQ Control 2 (0xbe) */
1633#define RT5645_IRQ_MB1_OC_MASK (0x1 << 15) 1639#define RT5645_IRQ_MB1_OC_MASK (0x1 << 15)
diff --git a/sound/soc/codecs/ssm2518.c b/sound/soc/codecs/ssm2518.c
index ddb0203fc649..86b81a60ac52 100644
--- a/sound/soc/codecs/ssm2518.c
+++ b/sound/soc/codecs/ssm2518.c
@@ -723,17 +723,11 @@ static struct snd_soc_codec_driver ssm2518_codec_driver = {
723 .num_dapm_routes = ARRAY_SIZE(ssm2518_routes), 723 .num_dapm_routes = ARRAY_SIZE(ssm2518_routes),
724}; 724};
725 725
726static bool ssm2518_register_volatile(struct device *dev, unsigned int reg)
727{
728 return false;
729}
730
731static const struct regmap_config ssm2518_regmap_config = { 726static const struct regmap_config ssm2518_regmap_config = {
732 .val_bits = 8, 727 .val_bits = 8,
733 .reg_bits = 8, 728 .reg_bits = 8,
734 729
735 .max_register = SSM2518_REG_DRC_9, 730 .max_register = SSM2518_REG_DRC_9,
736 .volatile_reg = ssm2518_register_volatile,
737 731
738 .cache_type = REGCACHE_RBTREE, 732 .cache_type = REGCACHE_RBTREE,
739 .reg_defaults = ssm2518_reg_defaults, 733 .reg_defaults = ssm2518_reg_defaults,
diff --git a/sound/soc/codecs/tlv320aic3x.c b/sound/soc/codecs/tlv320aic3x.c
index 8739126a1f6f..a564759845f9 100644
--- a/sound/soc/codecs/tlv320aic3x.c
+++ b/sound/soc/codecs/tlv320aic3x.c
@@ -80,6 +80,7 @@ struct aic3x_priv {
80 unsigned int sysclk; 80 unsigned int sysclk;
81 unsigned int dai_fmt; 81 unsigned int dai_fmt;
82 unsigned int tdm_delay; 82 unsigned int tdm_delay;
83 unsigned int slot_width;
83 struct list_head list; 84 struct list_head list;
84 int master; 85 int master;
85 int gpio_reset; 86 int gpio_reset;
@@ -1025,10 +1026,14 @@ static int aic3x_hw_params(struct snd_pcm_substream *substream,
1025 u8 data, j, r, p, pll_q, pll_p = 1, pll_r = 1, pll_j = 1; 1026 u8 data, j, r, p, pll_q, pll_p = 1, pll_r = 1, pll_j = 1;
1026 u16 d, pll_d = 1; 1027 u16 d, pll_d = 1;
1027 int clk; 1028 int clk;
1029 int width = aic3x->slot_width;
1030
1031 if (!width)
1032 width = params_width(params);
1028 1033
1029 /* select data word length */ 1034 /* select data word length */
1030 data = snd_soc_read(codec, AIC3X_ASD_INTF_CTRLB) & (~(0x3 << 4)); 1035 data = snd_soc_read(codec, AIC3X_ASD_INTF_CTRLB) & (~(0x3 << 4));
1031 switch (params_width(params)) { 1036 switch (width) {
1032 case 16: 1037 case 16:
1033 break; 1038 break;
1034 case 20: 1039 case 20:
@@ -1170,12 +1175,16 @@ static int aic3x_prepare(struct snd_pcm_substream *substream,
1170 struct snd_soc_codec *codec = dai->codec; 1175 struct snd_soc_codec *codec = dai->codec;
1171 struct aic3x_priv *aic3x = snd_soc_codec_get_drvdata(codec); 1176 struct aic3x_priv *aic3x = snd_soc_codec_get_drvdata(codec);
1172 int delay = 0; 1177 int delay = 0;
1178 int width = aic3x->slot_width;
1179
1180 if (!width)
1181 width = substream->runtime->sample_bits;
1173 1182
1174 /* TDM slot selection only valid in DSP_A/_B mode */ 1183 /* TDM slot selection only valid in DSP_A/_B mode */
1175 if (aic3x->dai_fmt == SND_SOC_DAIFMT_DSP_A) 1184 if (aic3x->dai_fmt == SND_SOC_DAIFMT_DSP_A)
1176 delay += (aic3x->tdm_delay + 1); 1185 delay += (aic3x->tdm_delay*width + 1);
1177 else if (aic3x->dai_fmt == SND_SOC_DAIFMT_DSP_B) 1186 else if (aic3x->dai_fmt == SND_SOC_DAIFMT_DSP_B)
1178 delay += aic3x->tdm_delay; 1187 delay += aic3x->tdm_delay*width;
1179 1188
1180 /* Configure data delay */ 1189 /* Configure data delay */
1181 snd_soc_write(codec, AIC3X_ASD_INTF_CTRLC, delay); 1190 snd_soc_write(codec, AIC3X_ASD_INTF_CTRLC, delay);
@@ -1296,7 +1305,20 @@ static int aic3x_set_dai_tdm_slot(struct snd_soc_dai *codec_dai,
1296 return -EINVAL; 1305 return -EINVAL;
1297 } 1306 }
1298 1307
1299 aic3x->tdm_delay = lsb * slot_width; 1308 switch (slot_width) {
1309 case 16:
1310 case 20:
1311 case 24:
1312 case 32:
1313 break;
1314 default:
1315 dev_err(codec->dev, "Unsupported slot width %d\n", slot_width);
1316 return -EINVAL;
1317 }
1318
1319
1320 aic3x->tdm_delay = lsb;
1321 aic3x->slot_width = slot_width;
1300 1322
1301 /* DOUT in high-impedance on inactive bit clocks */ 1323 /* DOUT in high-impedance on inactive bit clocks */
1302 snd_soc_update_bits(codec, AIC3X_ASD_INTF_CTRLA, 1324 snd_soc_update_bits(codec, AIC3X_ASD_INTF_CTRLA,
diff --git a/sound/soc/codecs/twl4030.c b/sound/soc/codecs/twl4030.c
index 2713e1845cbc..a5a4e9f75c57 100644
--- a/sound/soc/codecs/twl4030.c
+++ b/sound/soc/codecs/twl4030.c
@@ -1612,19 +1612,16 @@ static void twl4030_constraints(struct twl4030_priv *twl4030,
1612 return; 1612 return;
1613 1613
1614 /* Set the constraints according to the already configured stream */ 1614 /* Set the constraints according to the already configured stream */
1615 snd_pcm_hw_constraint_minmax(slv_substream->runtime, 1615 snd_pcm_hw_constraint_single(slv_substream->runtime,
1616 SNDRV_PCM_HW_PARAM_RATE, 1616 SNDRV_PCM_HW_PARAM_RATE,
1617 twl4030->rate,
1618 twl4030->rate); 1617 twl4030->rate);
1619 1618
1620 snd_pcm_hw_constraint_minmax(slv_substream->runtime, 1619 snd_pcm_hw_constraint_single(slv_substream->runtime,
1621 SNDRV_PCM_HW_PARAM_SAMPLE_BITS, 1620 SNDRV_PCM_HW_PARAM_SAMPLE_BITS,
1622 twl4030->sample_bits,
1623 twl4030->sample_bits); 1621 twl4030->sample_bits);
1624 1622
1625 snd_pcm_hw_constraint_minmax(slv_substream->runtime, 1623 snd_pcm_hw_constraint_single(slv_substream->runtime,
1626 SNDRV_PCM_HW_PARAM_CHANNELS, 1624 SNDRV_PCM_HW_PARAM_CHANNELS,
1627 twl4030->channels,
1628 twl4030->channels); 1625 twl4030->channels);
1629} 1626}
1630 1627
@@ -1669,9 +1666,9 @@ static int twl4030_startup(struct snd_pcm_substream *substream,
1669 /* In option2 4 channel is not supported, set the 1666 /* In option2 4 channel is not supported, set the
1670 * constraint for the first stream for channels, the 1667 * constraint for the first stream for channels, the
1671 * second stream will 'inherit' this cosntraint */ 1668 * second stream will 'inherit' this cosntraint */
1672 snd_pcm_hw_constraint_minmax(substream->runtime, 1669 snd_pcm_hw_constraint_single(substream->runtime,
1673 SNDRV_PCM_HW_PARAM_CHANNELS, 1670 SNDRV_PCM_HW_PARAM_CHANNELS,
1674 2, 2); 1671 2);
1675 } 1672 }
1676 twl4030->master_substream = substream; 1673 twl4030->master_substream = substream;
1677 } 1674 }
diff --git a/sound/soc/codecs/uda134x.c b/sound/soc/codecs/uda134x.c
index e19026380534..e4c694c758b8 100644
--- a/sound/soc/codecs/uda134x.c
+++ b/sound/soc/codecs/uda134x.c
@@ -150,14 +150,12 @@ static int uda134x_startup(struct snd_pcm_substream *substream,
150 master_runtime->sample_bits, 150 master_runtime->sample_bits,
151 master_runtime->rate); 151 master_runtime->rate);
152 152
153 snd_pcm_hw_constraint_minmax(substream->runtime, 153 snd_pcm_hw_constraint_single(substream->runtime,
154 SNDRV_PCM_HW_PARAM_RATE, 154 SNDRV_PCM_HW_PARAM_RATE,
155 master_runtime->rate,
156 master_runtime->rate); 155 master_runtime->rate);
157 156
158 snd_pcm_hw_constraint_minmax(substream->runtime, 157 snd_pcm_hw_constraint_single(substream->runtime,
159 SNDRV_PCM_HW_PARAM_SAMPLE_BITS, 158 SNDRV_PCM_HW_PARAM_SAMPLE_BITS,
160 master_runtime->sample_bits,
161 master_runtime->sample_bits); 159 master_runtime->sample_bits);
162 160
163 uda134x->slave_substream = substream; 161 uda134x->slave_substream = substream;
diff --git a/sound/soc/codecs/wl1273.c b/sound/soc/codecs/wl1273.c
index 80fb1dc81f6c..7693c1129bab 100644
--- a/sound/soc/codecs/wl1273.c
+++ b/sound/soc/codecs/wl1273.c
@@ -307,11 +307,10 @@ static int wl1273_startup(struct snd_pcm_substream *substream,
307 307
308 switch (wl1273->mode) { 308 switch (wl1273->mode) {
309 case WL1273_MODE_BT: 309 case WL1273_MODE_BT:
310 snd_pcm_hw_constraint_minmax(substream->runtime, 310 snd_pcm_hw_constraint_single(substream->runtime,
311 SNDRV_PCM_HW_PARAM_RATE, 311 SNDRV_PCM_HW_PARAM_RATE, 8000);
312 8000, 8000); 312 snd_pcm_hw_constraint_single(substream->runtime,
313 snd_pcm_hw_constraint_minmax(substream->runtime, 313 SNDRV_PCM_HW_PARAM_CHANNELS, 1);
314 SNDRV_PCM_HW_PARAM_CHANNELS, 1, 1);
315 break; 314 break;
316 case WL1273_MODE_FM_RX: 315 case WL1273_MODE_FM_RX:
317 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { 316 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
diff --git a/sound/soc/codecs/wm2000.c b/sound/soc/codecs/wm2000.c
index 786abd02b140..a67ea10f41a1 100644
--- a/sound/soc/codecs/wm2000.c
+++ b/sound/soc/codecs/wm2000.c
@@ -620,7 +620,7 @@ static int wm2000_anc_mode_put(struct snd_kcontrol *kcontrol,
620{ 620{
621 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); 621 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
622 struct wm2000_priv *wm2000 = dev_get_drvdata(codec->dev); 622 struct wm2000_priv *wm2000 = dev_get_drvdata(codec->dev);
623 int anc_active = ucontrol->value.integer.value[0]; 623 unsigned int anc_active = ucontrol->value.integer.value[0];
624 int ret; 624 int ret;
625 625
626 if (anc_active > 1) 626 if (anc_active > 1)
@@ -653,7 +653,7 @@ static int wm2000_speaker_put(struct snd_kcontrol *kcontrol,
653{ 653{
654 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); 654 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
655 struct wm2000_priv *wm2000 = dev_get_drvdata(codec->dev); 655 struct wm2000_priv *wm2000 = dev_get_drvdata(codec->dev);
656 int val = ucontrol->value.integer.value[0]; 656 unsigned int val = ucontrol->value.integer.value[0];
657 int ret; 657 int ret;
658 658
659 if (val > 1) 659 if (val > 1)
diff --git a/sound/soc/codecs/wm5110.c b/sound/soc/codecs/wm5110.c
index 9756578fc752..c04c0bc6f58a 100644
--- a/sound/soc/codecs/wm5110.c
+++ b/sound/soc/codecs/wm5110.c
@@ -38,6 +38,12 @@
38struct wm5110_priv { 38struct wm5110_priv {
39 struct arizona_priv core; 39 struct arizona_priv core;
40 struct arizona_fll fll[2]; 40 struct arizona_fll fll[2];
41
42 unsigned int in_value;
43 int in_pre_pending;
44 int in_post_pending;
45
46 unsigned int in_pga_cache[6];
41}; 47};
42 48
43static const struct wm_adsp_region wm5110_dsp1_regions[] = { 49static const struct wm_adsp_region wm5110_dsp1_regions[] = {
@@ -428,6 +434,127 @@ err:
428 return ret; 434 return ret;
429} 435}
430 436
437static int wm5110_in_pga_get(struct snd_kcontrol *kcontrol,
438 struct snd_ctl_elem_value *ucontrol)
439{
440 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
441 struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
442 struct snd_soc_card *card = dapm->card;
443 int ret;
444
445 /*
446 * PGA Volume is also used as part of the enable sequence, so
447 * usage of it should be avoided whilst that is running.
448 */
449 mutex_lock_nested(&card->dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME);
450
451 ret = snd_soc_get_volsw_range(kcontrol, ucontrol);
452
453 mutex_unlock(&card->dapm_mutex);
454
455 return ret;
456}
457
458static int wm5110_in_pga_put(struct snd_kcontrol *kcontrol,
459 struct snd_ctl_elem_value *ucontrol)
460{
461 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
462 struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
463 struct snd_soc_card *card = dapm->card;
464 int ret;
465
466 /*
467 * PGA Volume is also used as part of the enable sequence, so
468 * usage of it should be avoided whilst that is running.
469 */
470 mutex_lock_nested(&card->dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME);
471
472 ret = snd_soc_put_volsw_range(kcontrol, ucontrol);
473
474 mutex_unlock(&card->dapm_mutex);
475
476 return ret;
477}
478
479static int wm5110_in_analog_ev(struct snd_soc_dapm_widget *w,
480 struct snd_kcontrol *kcontrol, int event)
481{
482 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
483 struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
484 struct wm5110_priv *wm5110 = snd_soc_codec_get_drvdata(codec);
485 struct arizona *arizona = priv->arizona;
486 unsigned int reg, mask;
487 struct reg_sequence analog_seq[] = {
488 { 0x80, 0x3 },
489 { 0x35d, 0 },
490 { 0x80, 0x0 },
491 };
492
493 reg = ARIZONA_IN1L_CONTROL + ((w->shift ^ 0x1) * 4);
494 mask = ARIZONA_IN1L_PGA_VOL_MASK;
495
496 switch (event) {
497 case SND_SOC_DAPM_WILL_PMU:
498 wm5110->in_value |= 0x3 << ((w->shift ^ 0x1) * 2);
499 wm5110->in_pre_pending++;
500 wm5110->in_post_pending++;
501 return 0;
502 case SND_SOC_DAPM_PRE_PMU:
503 wm5110->in_pga_cache[w->shift] = snd_soc_read(codec, reg);
504
505 snd_soc_update_bits(codec, reg, mask,
506 0x40 << ARIZONA_IN1L_PGA_VOL_SHIFT);
507
508 wm5110->in_pre_pending--;
509 if (wm5110->in_pre_pending == 0) {
510 analog_seq[1].def = wm5110->in_value;
511 regmap_multi_reg_write_bypassed(arizona->regmap,
512 analog_seq,
513 ARRAY_SIZE(analog_seq));
514
515 msleep(55);
516
517 wm5110->in_value = 0;
518 }
519
520 break;
521 case SND_SOC_DAPM_POST_PMU:
522 snd_soc_update_bits(codec, reg, mask,
523 wm5110->in_pga_cache[w->shift]);
524
525 wm5110->in_post_pending--;
526 if (wm5110->in_post_pending == 0)
527 regmap_multi_reg_write_bypassed(arizona->regmap,
528 analog_seq,
529 ARRAY_SIZE(analog_seq));
530 break;
531 default:
532 break;
533 }
534
535 return 0;
536}
537
538static int wm5110_in_ev(struct snd_soc_dapm_widget *w,
539 struct snd_kcontrol *kcontrol, int event)
540{
541 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
542 struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
543 struct arizona *arizona = priv->arizona;
544
545 switch (arizona->rev) {
546 case 0 ... 4:
547 if (arizona_input_analog(codec, w->shift))
548 wm5110_in_analog_ev(w, kcontrol, event);
549
550 break;
551 default:
552 break;
553 }
554
555 return arizona_in_ev(w, kcontrol, event);
556}
557
431static DECLARE_TLV_DB_SCALE(ana_tlv, 0, 100, 0); 558static DECLARE_TLV_DB_SCALE(ana_tlv, 0, 100, 0);
432static DECLARE_TLV_DB_SCALE(eq_tlv, -1200, 100, 0); 559static DECLARE_TLV_DB_SCALE(eq_tlv, -1200, 100, 0);
433static DECLARE_TLV_DB_SCALE(digital_tlv, -6400, 50, 0); 560static DECLARE_TLV_DB_SCALE(digital_tlv, -6400, 50, 0);
@@ -454,18 +581,24 @@ SOC_ENUM("IN2 OSR", arizona_in_dmic_osr[1]),
454SOC_ENUM("IN3 OSR", arizona_in_dmic_osr[2]), 581SOC_ENUM("IN3 OSR", arizona_in_dmic_osr[2]),
455SOC_ENUM("IN4 OSR", arizona_in_dmic_osr[3]), 582SOC_ENUM("IN4 OSR", arizona_in_dmic_osr[3]),
456 583
457SOC_SINGLE_RANGE_TLV("IN1L Volume", ARIZONA_IN1L_CONTROL, 584SOC_SINGLE_RANGE_EXT_TLV("IN1L Volume", ARIZONA_IN1L_CONTROL,
458 ARIZONA_IN1L_PGA_VOL_SHIFT, 0x40, 0x5f, 0, ana_tlv), 585 ARIZONA_IN1L_PGA_VOL_SHIFT, 0x40, 0x5f, 0,
459SOC_SINGLE_RANGE_TLV("IN1R Volume", ARIZONA_IN1R_CONTROL, 586 wm5110_in_pga_get, wm5110_in_pga_put, ana_tlv),
460 ARIZONA_IN1R_PGA_VOL_SHIFT, 0x40, 0x5f, 0, ana_tlv), 587SOC_SINGLE_RANGE_EXT_TLV("IN1R Volume", ARIZONA_IN1R_CONTROL,
461SOC_SINGLE_RANGE_TLV("IN2L Volume", ARIZONA_IN2L_CONTROL, 588 ARIZONA_IN1R_PGA_VOL_SHIFT, 0x40, 0x5f, 0,
462 ARIZONA_IN2L_PGA_VOL_SHIFT, 0x40, 0x5f, 0, ana_tlv), 589 wm5110_in_pga_get, wm5110_in_pga_put, ana_tlv),
463SOC_SINGLE_RANGE_TLV("IN2R Volume", ARIZONA_IN2R_CONTROL, 590SOC_SINGLE_RANGE_EXT_TLV("IN2L Volume", ARIZONA_IN2L_CONTROL,
464 ARIZONA_IN2R_PGA_VOL_SHIFT, 0x40, 0x5f, 0, ana_tlv), 591 ARIZONA_IN2L_PGA_VOL_SHIFT, 0x40, 0x5f, 0,
465SOC_SINGLE_RANGE_TLV("IN3L Volume", ARIZONA_IN3L_CONTROL, 592 wm5110_in_pga_get, wm5110_in_pga_put, ana_tlv),
466 ARIZONA_IN3L_PGA_VOL_SHIFT, 0x40, 0x5f, 0, ana_tlv), 593SOC_SINGLE_RANGE_EXT_TLV("IN2R Volume", ARIZONA_IN2R_CONTROL,
467SOC_SINGLE_RANGE_TLV("IN3R Volume", ARIZONA_IN3R_CONTROL, 594 ARIZONA_IN2R_PGA_VOL_SHIFT, 0x40, 0x5f, 0,
468 ARIZONA_IN3R_PGA_VOL_SHIFT, 0x40, 0x5f, 0, ana_tlv), 595 wm5110_in_pga_get, wm5110_in_pga_put, ana_tlv),
596SOC_SINGLE_RANGE_EXT_TLV("IN3L Volume", ARIZONA_IN3L_CONTROL,
597 ARIZONA_IN3L_PGA_VOL_SHIFT, 0x40, 0x5f, 0,
598 wm5110_in_pga_get, wm5110_in_pga_put, ana_tlv),
599SOC_SINGLE_RANGE_EXT_TLV("IN3R Volume", ARIZONA_IN3R_CONTROL,
600 ARIZONA_IN3R_PGA_VOL_SHIFT, 0x40, 0x5f, 0,
601 wm5110_in_pga_get, wm5110_in_pga_put, ana_tlv),
469 602
470SOC_ENUM("IN HPF Cutoff Frequency", arizona_in_hpf_cut_enum), 603SOC_ENUM("IN HPF Cutoff Frequency", arizona_in_hpf_cut_enum),
471 604
@@ -896,29 +1029,35 @@ SND_SOC_DAPM_OUTPUT("DRC1 Signal Activity"),
896SND_SOC_DAPM_OUTPUT("DRC2 Signal Activity"), 1029SND_SOC_DAPM_OUTPUT("DRC2 Signal Activity"),
897 1030
898SND_SOC_DAPM_PGA_E("IN1L PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN1L_ENA_SHIFT, 1031SND_SOC_DAPM_PGA_E("IN1L PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN1L_ENA_SHIFT,
899 0, NULL, 0, arizona_in_ev, 1032 0, NULL, 0, wm5110_in_ev,
900 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD | 1033 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD |
901 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU), 1034 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
1035 SND_SOC_DAPM_WILL_PMU),
902SND_SOC_DAPM_PGA_E("IN1R PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN1R_ENA_SHIFT, 1036SND_SOC_DAPM_PGA_E("IN1R PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN1R_ENA_SHIFT,
903 0, NULL, 0, arizona_in_ev, 1037 0, NULL, 0, wm5110_in_ev,
904 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD | 1038 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD |
905 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU), 1039 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
1040 SND_SOC_DAPM_WILL_PMU),
906SND_SOC_DAPM_PGA_E("IN2L PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN2L_ENA_SHIFT, 1041SND_SOC_DAPM_PGA_E("IN2L PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN2L_ENA_SHIFT,
907 0, NULL, 0, arizona_in_ev, 1042 0, NULL, 0, wm5110_in_ev,
908 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD | 1043 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD |
909 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU), 1044 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
1045 SND_SOC_DAPM_WILL_PMU),
910SND_SOC_DAPM_PGA_E("IN2R PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN2R_ENA_SHIFT, 1046SND_SOC_DAPM_PGA_E("IN2R PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN2R_ENA_SHIFT,
911 0, NULL, 0, arizona_in_ev, 1047 0, NULL, 0, wm5110_in_ev,
912 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD | 1048 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD |
913 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU), 1049 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
1050 SND_SOC_DAPM_WILL_PMU),
914SND_SOC_DAPM_PGA_E("IN3L PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN3L_ENA_SHIFT, 1051SND_SOC_DAPM_PGA_E("IN3L PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN3L_ENA_SHIFT,
915 0, NULL, 0, arizona_in_ev, 1052 0, NULL, 0, wm5110_in_ev,
916 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD | 1053 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD |
917 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU), 1054 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
1055 SND_SOC_DAPM_WILL_PMU),
918SND_SOC_DAPM_PGA_E("IN3R PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN3R_ENA_SHIFT, 1056SND_SOC_DAPM_PGA_E("IN3R PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN3R_ENA_SHIFT,
919 0, NULL, 0, arizona_in_ev, 1057 0, NULL, 0, wm5110_in_ev,
920 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD | 1058 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD |
921 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU), 1059 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
1060 SND_SOC_DAPM_WILL_PMU),
922SND_SOC_DAPM_PGA_E("IN4L PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN4L_ENA_SHIFT, 1061SND_SOC_DAPM_PGA_E("IN4L PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN4L_ENA_SHIFT,
923 0, NULL, 0, arizona_in_ev, 1062 0, NULL, 0, arizona_in_ev,
924 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD | 1063 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD |
diff --git a/sound/soc/codecs/wm8731.c b/sound/soc/codecs/wm8731.c
index 15bd547e3c84..4bcf5f8ece50 100644
--- a/sound/soc/codecs/wm8731.c
+++ b/sound/soc/codecs/wm8731.c
@@ -132,7 +132,7 @@ static int wm8731_put_deemph(struct snd_kcontrol *kcontrol,
132{ 132{
133 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); 133 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
134 struct wm8731_priv *wm8731 = snd_soc_codec_get_drvdata(codec); 134 struct wm8731_priv *wm8731 = snd_soc_codec_get_drvdata(codec);
135 int deemph = ucontrol->value.integer.value[0]; 135 unsigned int deemph = ucontrol->value.integer.value[0];
136 int ret = 0; 136 int ret = 0;
137 137
138 if (deemph > 1) 138 if (deemph > 1)
diff --git a/sound/soc/codecs/wm8903.c b/sound/soc/codecs/wm8903.c
index b011253459af..e4cc41e6c23e 100644
--- a/sound/soc/codecs/wm8903.c
+++ b/sound/soc/codecs/wm8903.c
@@ -452,7 +452,7 @@ static int wm8903_put_deemph(struct snd_kcontrol *kcontrol,
452{ 452{
453 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); 453 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
454 struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec); 454 struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec);
455 int deemph = ucontrol->value.integer.value[0]; 455 unsigned int deemph = ucontrol->value.integer.value[0];
456 int ret = 0; 456 int ret = 0;
457 457
458 if (deemph > 1) 458 if (deemph > 1)
diff --git a/sound/soc/codecs/wm8904.c b/sound/soc/codecs/wm8904.c
index b783743dc97e..2aa23f1b9e3c 100644
--- a/sound/soc/codecs/wm8904.c
+++ b/sound/soc/codecs/wm8904.c
@@ -534,7 +534,7 @@ static int wm8904_put_deemph(struct snd_kcontrol *kcontrol,
534{ 534{
535 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); 535 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
536 struct wm8904_priv *wm8904 = snd_soc_codec_get_drvdata(codec); 536 struct wm8904_priv *wm8904 = snd_soc_codec_get_drvdata(codec);
537 int deemph = ucontrol->value.integer.value[0]; 537 unsigned int deemph = ucontrol->value.integer.value[0];
538 538
539 if (deemph > 1) 539 if (deemph > 1)
540 return -EINVAL; 540 return -EINVAL;
diff --git a/sound/soc/codecs/wm8955.c b/sound/soc/codecs/wm8955.c
index 12e4435f00f8..9db00d53abe7 100644
--- a/sound/soc/codecs/wm8955.c
+++ b/sound/soc/codecs/wm8955.c
@@ -402,7 +402,7 @@ static int wm8955_put_deemph(struct snd_kcontrol *kcontrol,
402{ 402{
403 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); 403 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
404 struct wm8955_priv *wm8955 = snd_soc_codec_get_drvdata(codec); 404 struct wm8955_priv *wm8955 = snd_soc_codec_get_drvdata(codec);
405 int deemph = ucontrol->value.integer.value[0]; 405 unsigned int deemph = ucontrol->value.integer.value[0];
406 406
407 if (deemph > 1) 407 if (deemph > 1)
408 return -EINVAL; 408 return -EINVAL;
diff --git a/sound/soc/codecs/wm8960.c b/sound/soc/codecs/wm8960.c
index dbd88408861a..056375339ea3 100644
--- a/sound/soc/codecs/wm8960.c
+++ b/sound/soc/codecs/wm8960.c
@@ -201,7 +201,7 @@ static int wm8960_put_deemph(struct snd_kcontrol *kcontrol,
201{ 201{
202 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); 202 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
203 struct wm8960_priv *wm8960 = snd_soc_codec_get_drvdata(codec); 203 struct wm8960_priv *wm8960 = snd_soc_codec_get_drvdata(codec);
204 int deemph = ucontrol->value.integer.value[0]; 204 unsigned int deemph = ucontrol->value.integer.value[0];
205 205
206 if (deemph > 1) 206 if (deemph > 1)
207 return -EINVAL; 207 return -EINVAL;
diff --git a/sound/soc/codecs/wm8998.c b/sound/soc/codecs/wm8998.c
new file mode 100644
index 000000000000..8782dfb628ab
--- /dev/null
+++ b/sound/soc/codecs/wm8998.c
@@ -0,0 +1,1430 @@
1/*
2 * wm8998.c -- ALSA SoC Audio driver for WM8998 codecs
3 *
4 * Copyright 2015 Cirrus Logic, Inc.
5 *
6 * Author: Richard Fitzgerald <rf@opensource.wolfsonmicro.com>
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/pm_runtime.h>
19#include <linux/regmap.h>
20#include <linux/slab.h>
21#include <sound/core.h>
22#include <sound/pcm.h>
23#include <sound/pcm_params.h>
24#include <sound/soc.h>
25#include <sound/jack.h>
26#include <sound/initval.h>
27#include <sound/tlv.h>
28
29#include <linux/mfd/arizona/core.h>
30#include <linux/mfd/arizona/registers.h>
31
32#include "arizona.h"
33#include "wm8998.h"
34
35struct wm8998_priv {
36 struct arizona_priv core;
37 struct arizona_fll fll[2];
38};
39
40static int wm8998_asrc_ev(struct snd_soc_dapm_widget *w,
41 struct snd_kcontrol *kcontrol,
42 int event)
43{
44 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
45 unsigned int val;
46
47 switch (event) {
48 case SND_SOC_DAPM_PRE_PMU:
49 val = snd_soc_read(codec, ARIZONA_ASRC_RATE1);
50 val &= ARIZONA_ASRC_RATE1_MASK;
51 val >>= ARIZONA_ASRC_RATE1_SHIFT;
52
53 switch (val) {
54 case 0:
55 case 1:
56 case 2:
57 val = snd_soc_read(codec,
58 ARIZONA_SAMPLE_RATE_1 + val);
59 if (val >= 0x11) {
60 dev_warn(codec->dev,
61 "Unsupported ASRC rate1 (%s)\n",
62 arizona_sample_rate_val_to_name(val));
63 return -EINVAL;
64 }
65 break;
66 default:
67 dev_err(codec->dev,
68 "Illegal ASRC rate1 selector (0x%x)\n",
69 val);
70 return -EINVAL;
71 }
72
73 val = snd_soc_read(codec, ARIZONA_ASRC_RATE2);
74 val &= ARIZONA_ASRC_RATE2_MASK;
75 val >>= ARIZONA_ASRC_RATE2_SHIFT;
76
77 switch (val) {
78 case 8:
79 case 9:
80 val -= 0x8;
81 val = snd_soc_read(codec,
82 ARIZONA_ASYNC_SAMPLE_RATE_1 + val);
83 if (val >= 0x11) {
84 dev_warn(codec->dev,
85 "Unsupported ASRC rate2 (%s)\n",
86 arizona_sample_rate_val_to_name(val));
87 return -EINVAL;
88 }
89 break;
90 default:
91 dev_err(codec->dev,
92 "Illegal ASRC rate2 selector (0x%x)\n",
93 val);
94 return -EINVAL;
95 }
96 break;
97 default:
98 return -EINVAL;
99 }
100
101 return 0;
102}
103
104static int wm8998_in1mux_put(struct snd_kcontrol *kcontrol,
105 struct snd_ctl_elem_value *ucontrol)
106{
107 struct snd_soc_codec *codec = snd_soc_dapm_kcontrol_codec(kcontrol);
108 struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
109 struct wm8998_priv *wm8998 = snd_soc_codec_get_drvdata(codec);
110 struct arizona *arizona = wm8998->core.arizona;
111 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
112 unsigned int mux, inmode;
113 unsigned int mode_val, src_val;
114
115 mux = ucontrol->value.enumerated.item[0];
116 if (mux > 1)
117 return -EINVAL;
118
119 /* L and R registers have same shift and mask */
120 inmode = arizona->pdata.inmode[2 * mux];
121 src_val = mux << ARIZONA_IN1L_SRC_SHIFT;
122 if (inmode & ARIZONA_INMODE_SE)
123 src_val |= 1 << ARIZONA_IN1L_SRC_SE_SHIFT;
124
125 switch (arizona->pdata.inmode[0]) {
126 case ARIZONA_INMODE_DMIC:
127 if (mux)
128 mode_val = 0; /* B always analogue */
129 else
130 mode_val = 1 << ARIZONA_IN1_MODE_SHIFT;
131
132 snd_soc_update_bits(codec, ARIZONA_IN1L_CONTROL,
133 ARIZONA_IN1_MODE_MASK, mode_val);
134
135 /* IN1A is digital so L and R must change together */
136 /* src_val setting same for both registers */
137 snd_soc_update_bits(codec,
138 ARIZONA_ADC_DIGITAL_VOLUME_1L,
139 ARIZONA_IN1L_SRC_MASK |
140 ARIZONA_IN1L_SRC_SE_MASK, src_val);
141 snd_soc_update_bits(codec,
142 ARIZONA_ADC_DIGITAL_VOLUME_1R,
143 ARIZONA_IN1R_SRC_MASK |
144 ARIZONA_IN1R_SRC_SE_MASK, src_val);
145 break;
146 default:
147 /* both analogue */
148 snd_soc_update_bits(codec,
149 e->reg,
150 ARIZONA_IN1L_SRC_MASK |
151 ARIZONA_IN1L_SRC_SE_MASK,
152 src_val);
153 break;
154 }
155
156 return snd_soc_dapm_mux_update_power(dapm, kcontrol,
157 ucontrol->value.enumerated.item[0],
158 e, NULL);
159}
160
161static int wm8998_in2mux_put(struct snd_kcontrol *kcontrol,
162 struct snd_ctl_elem_value *ucontrol)
163{
164 struct snd_soc_codec *codec = snd_soc_dapm_kcontrol_codec(kcontrol);
165 struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
166 struct wm8998_priv *wm8998 = snd_soc_codec_get_drvdata(codec);
167 struct arizona *arizona = wm8998->core.arizona;
168 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
169 unsigned int mux, inmode, src_val, mode_val;
170
171 mux = ucontrol->value.enumerated.item[0];
172 if (mux > 1)
173 return -EINVAL;
174
175 inmode = arizona->pdata.inmode[1 + (2 * mux)];
176 if (inmode & ARIZONA_INMODE_DMIC)
177 mode_val = 1 << ARIZONA_IN2_MODE_SHIFT;
178 else
179 mode_val = 0;
180
181 src_val = mux << ARIZONA_IN2L_SRC_SHIFT;
182 if (inmode & ARIZONA_INMODE_SE)
183 src_val |= 1 << ARIZONA_IN2L_SRC_SE_SHIFT;
184
185 snd_soc_update_bits(codec, ARIZONA_IN2L_CONTROL,
186 ARIZONA_IN2_MODE_MASK, mode_val);
187
188 snd_soc_update_bits(codec, ARIZONA_ADC_DIGITAL_VOLUME_2L,
189 ARIZONA_IN2L_SRC_MASK | ARIZONA_IN2L_SRC_SE_MASK,
190 src_val);
191
192 return snd_soc_dapm_mux_update_power(dapm, kcontrol,
193 ucontrol->value.enumerated.item[0],
194 e, NULL);
195}
196
197static const char * const wm8998_inmux_texts[] = {
198 "A",
199 "B",
200};
201
202static const SOC_ENUM_SINGLE_DECL(wm8998_in1muxl_enum,
203 ARIZONA_ADC_DIGITAL_VOLUME_1L,
204 ARIZONA_IN1L_SRC_SHIFT,
205 wm8998_inmux_texts);
206
207static const SOC_ENUM_SINGLE_DECL(wm8998_in1muxr_enum,
208 ARIZONA_ADC_DIGITAL_VOLUME_1R,
209 ARIZONA_IN1R_SRC_SHIFT,
210 wm8998_inmux_texts);
211
212static const SOC_ENUM_SINGLE_DECL(wm8998_in2mux_enum,
213 ARIZONA_ADC_DIGITAL_VOLUME_2L,
214 ARIZONA_IN2L_SRC_SHIFT,
215 wm8998_inmux_texts);
216
217static const struct snd_kcontrol_new wm8998_in1mux[2] = {
218 SOC_DAPM_ENUM_EXT("IN1L Mux", wm8998_in1muxl_enum,
219 snd_soc_dapm_get_enum_double, wm8998_in1mux_put),
220 SOC_DAPM_ENUM_EXT("IN1R Mux", wm8998_in1muxr_enum,
221 snd_soc_dapm_get_enum_double, wm8998_in1mux_put),
222};
223
224static const struct snd_kcontrol_new wm8998_in2mux =
225 SOC_DAPM_ENUM_EXT("IN2 Mux", wm8998_in2mux_enum,
226 snd_soc_dapm_get_enum_double, wm8998_in2mux_put);
227
228static DECLARE_TLV_DB_SCALE(ana_tlv, 0, 100, 0);
229static DECLARE_TLV_DB_SCALE(eq_tlv, -1200, 100, 0);
230static DECLARE_TLV_DB_SCALE(digital_tlv, -6400, 50, 0);
231static DECLARE_TLV_DB_SCALE(ng_tlv, -10200, 600, 0);
232
233#define WM8998_NG_SRC(name, base) \
234 SOC_SINGLE(name " NG HPOUTL Switch", base, 0, 1, 0), \
235 SOC_SINGLE(name " NG HPOUTR Switch", base, 1, 1, 0), \
236 SOC_SINGLE(name " NG LINEOUTL Switch", base, 2, 1, 0), \
237 SOC_SINGLE(name " NG LINEOUTR Switch", base, 3, 1, 0), \
238 SOC_SINGLE(name " NG EPOUT Switch", base, 4, 1, 0), \
239 SOC_SINGLE(name " NG SPKOUTL Switch", base, 6, 1, 0), \
240 SOC_SINGLE(name " NG SPKOUTR Switch", base, 7, 1, 0)
241
242static const struct snd_kcontrol_new wm8998_snd_controls[] = {
243SOC_ENUM("IN1 OSR", arizona_in_dmic_osr[0]),
244SOC_ENUM("IN2 OSR", arizona_in_dmic_osr[1]),
245
246SOC_SINGLE_RANGE_TLV("IN1L Volume", ARIZONA_IN1L_CONTROL,
247 ARIZONA_IN1L_PGA_VOL_SHIFT, 0x40, 0x5f, 0, ana_tlv),
248SOC_SINGLE_RANGE_TLV("IN1R Volume", ARIZONA_IN1R_CONTROL,
249 ARIZONA_IN1R_PGA_VOL_SHIFT, 0x40, 0x5f, 0, ana_tlv),
250SOC_SINGLE_RANGE_TLV("IN2 Volume", ARIZONA_IN2L_CONTROL,
251 ARIZONA_IN2L_PGA_VOL_SHIFT, 0x40, 0x5f, 0, ana_tlv),
252
253SOC_ENUM("IN HPF Cutoff Frequency", arizona_in_hpf_cut_enum),
254
255SOC_SINGLE("IN1L HPF Switch", ARIZONA_IN1L_CONTROL,
256 ARIZONA_IN1L_HPF_SHIFT, 1, 0),
257SOC_SINGLE("IN1R HPF Switch", ARIZONA_IN1R_CONTROL,
258 ARIZONA_IN1R_HPF_SHIFT, 1, 0),
259SOC_SINGLE("IN2 HPF Switch", ARIZONA_IN2L_CONTROL,
260 ARIZONA_IN2L_HPF_SHIFT, 1, 0),
261
262SOC_SINGLE_TLV("IN1L Digital Volume", ARIZONA_ADC_DIGITAL_VOLUME_1L,
263 ARIZONA_IN1L_DIG_VOL_SHIFT, 0xbf, 0, digital_tlv),
264SOC_SINGLE_TLV("IN1R Digital Volume", ARIZONA_ADC_DIGITAL_VOLUME_1R,
265 ARIZONA_IN1R_DIG_VOL_SHIFT, 0xbf, 0, digital_tlv),
266SOC_SINGLE_TLV("IN2 Digital Volume", ARIZONA_ADC_DIGITAL_VOLUME_2L,
267 ARIZONA_IN2L_DIG_VOL_SHIFT, 0xbf, 0, digital_tlv),
268
269SOC_ENUM("Input Ramp Up", arizona_in_vi_ramp),
270SOC_ENUM("Input Ramp Down", arizona_in_vd_ramp),
271
272ARIZONA_GAINMUX_CONTROLS("EQ1", ARIZONA_EQ1MIX_INPUT_1_SOURCE),
273ARIZONA_GAINMUX_CONTROLS("EQ2", ARIZONA_EQ2MIX_INPUT_1_SOURCE),
274ARIZONA_GAINMUX_CONTROLS("EQ3", ARIZONA_EQ3MIX_INPUT_1_SOURCE),
275ARIZONA_GAINMUX_CONTROLS("EQ4", ARIZONA_EQ4MIX_INPUT_1_SOURCE),
276
277SND_SOC_BYTES("EQ1 Coefficients", ARIZONA_EQ1_3, 19),
278SOC_SINGLE("EQ1 Mode Switch", ARIZONA_EQ1_2, ARIZONA_EQ1_B1_MODE_SHIFT, 1, 0),
279SOC_SINGLE_TLV("EQ1 B1 Volume", ARIZONA_EQ1_1, ARIZONA_EQ1_B1_GAIN_SHIFT,
280 24, 0, eq_tlv),
281SOC_SINGLE_TLV("EQ1 B2 Volume", ARIZONA_EQ1_1, ARIZONA_EQ1_B2_GAIN_SHIFT,
282 24, 0, eq_tlv),
283SOC_SINGLE_TLV("EQ1 B3 Volume", ARIZONA_EQ1_1, ARIZONA_EQ1_B3_GAIN_SHIFT,
284 24, 0, eq_tlv),
285SOC_SINGLE_TLV("EQ1 B4 Volume", ARIZONA_EQ1_2, ARIZONA_EQ1_B4_GAIN_SHIFT,
286 24, 0, eq_tlv),
287SOC_SINGLE_TLV("EQ1 B5 Volume", ARIZONA_EQ1_2, ARIZONA_EQ1_B5_GAIN_SHIFT,
288 24, 0, eq_tlv),
289
290SND_SOC_BYTES("EQ2 Coefficients", ARIZONA_EQ2_3, 19),
291SOC_SINGLE("EQ2 Mode Switch", ARIZONA_EQ2_2, ARIZONA_EQ2_B1_MODE_SHIFT, 1, 0),
292SOC_SINGLE_TLV("EQ2 B1 Volume", ARIZONA_EQ2_1, ARIZONA_EQ2_B1_GAIN_SHIFT,
293 24, 0, eq_tlv),
294SOC_SINGLE_TLV("EQ2 B2 Volume", ARIZONA_EQ2_1, ARIZONA_EQ2_B2_GAIN_SHIFT,
295 24, 0, eq_tlv),
296SOC_SINGLE_TLV("EQ2 B3 Volume", ARIZONA_EQ2_1, ARIZONA_EQ2_B3_GAIN_SHIFT,
297 24, 0, eq_tlv),
298SOC_SINGLE_TLV("EQ2 B4 Volume", ARIZONA_EQ2_2, ARIZONA_EQ2_B4_GAIN_SHIFT,
299 24, 0, eq_tlv),
300SOC_SINGLE_TLV("EQ2 B5 Volume", ARIZONA_EQ2_2, ARIZONA_EQ2_B5_GAIN_SHIFT,
301 24, 0, eq_tlv),
302
303SND_SOC_BYTES("EQ3 Coefficients", ARIZONA_EQ3_3, 19),
304SOC_SINGLE("EQ3 Mode Switch", ARIZONA_EQ3_2, ARIZONA_EQ3_B1_MODE_SHIFT, 1, 0),
305SOC_SINGLE_TLV("EQ3 B1 Volume", ARIZONA_EQ3_1, ARIZONA_EQ3_B1_GAIN_SHIFT,
306 24, 0, eq_tlv),
307SOC_SINGLE_TLV("EQ3 B2 Volume", ARIZONA_EQ3_1, ARIZONA_EQ3_B2_GAIN_SHIFT,
308 24, 0, eq_tlv),
309SOC_SINGLE_TLV("EQ3 B3 Volume", ARIZONA_EQ3_1, ARIZONA_EQ3_B3_GAIN_SHIFT,
310 24, 0, eq_tlv),
311SOC_SINGLE_TLV("EQ3 B4 Volume", ARIZONA_EQ3_2, ARIZONA_EQ3_B4_GAIN_SHIFT,
312 24, 0, eq_tlv),
313SOC_SINGLE_TLV("EQ3 B5 Volume", ARIZONA_EQ3_2, ARIZONA_EQ3_B5_GAIN_SHIFT,
314 24, 0, eq_tlv),
315
316SND_SOC_BYTES("EQ4 Coefficients", ARIZONA_EQ4_3, 19),
317SOC_SINGLE("EQ4 Mode Switch", ARIZONA_EQ4_2, ARIZONA_EQ4_B1_MODE_SHIFT, 1, 0),
318SOC_SINGLE_TLV("EQ4 B1 Volume", ARIZONA_EQ4_1, ARIZONA_EQ4_B1_GAIN_SHIFT,
319 24, 0, eq_tlv),
320SOC_SINGLE_TLV("EQ4 B2 Volume", ARIZONA_EQ4_1, ARIZONA_EQ4_B2_GAIN_SHIFT,
321 24, 0, eq_tlv),
322SOC_SINGLE_TLV("EQ4 B3 Volume", ARIZONA_EQ4_1, ARIZONA_EQ4_B3_GAIN_SHIFT,
323 24, 0, eq_tlv),
324SOC_SINGLE_TLV("EQ4 B4 Volume", ARIZONA_EQ4_2, ARIZONA_EQ4_B4_GAIN_SHIFT,
325 24, 0, eq_tlv),
326SOC_SINGLE_TLV("EQ4 B5 Volume", ARIZONA_EQ4_2, ARIZONA_EQ4_B5_GAIN_SHIFT,
327 24, 0, eq_tlv),
328
329ARIZONA_GAINMUX_CONTROLS("DRC1L", ARIZONA_DRC1LMIX_INPUT_1_SOURCE),
330ARIZONA_GAINMUX_CONTROLS("DRC1R", ARIZONA_DRC1RMIX_INPUT_1_SOURCE),
331
332SND_SOC_BYTES_MASK("DRC1", ARIZONA_DRC1_CTRL1, 5,
333 ARIZONA_DRC1R_ENA | ARIZONA_DRC1L_ENA),
334
335ARIZONA_MIXER_CONTROLS("LHPF1", ARIZONA_HPLP1MIX_INPUT_1_SOURCE),
336ARIZONA_MIXER_CONTROLS("LHPF2", ARIZONA_HPLP2MIX_INPUT_1_SOURCE),
337ARIZONA_MIXER_CONTROLS("LHPF3", ARIZONA_HPLP3MIX_INPUT_1_SOURCE),
338ARIZONA_MIXER_CONTROLS("LHPF4", ARIZONA_HPLP4MIX_INPUT_1_SOURCE),
339
340SND_SOC_BYTES("LHPF1 Coefficients", ARIZONA_HPLPF1_2, 1),
341SND_SOC_BYTES("LHPF2 Coefficients", ARIZONA_HPLPF2_2, 1),
342SND_SOC_BYTES("LHPF3 Coefficients", ARIZONA_HPLPF3_2, 1),
343SND_SOC_BYTES("LHPF4 Coefficients", ARIZONA_HPLPF4_2, 1),
344
345SOC_ENUM("LHPF1 Mode", arizona_lhpf1_mode),
346SOC_ENUM("LHPF2 Mode", arizona_lhpf2_mode),
347SOC_ENUM("LHPF3 Mode", arizona_lhpf3_mode),
348SOC_ENUM("LHPF4 Mode", arizona_lhpf4_mode),
349
350SOC_ENUM("ISRC1 FSL", arizona_isrc_fsl[0]),
351SOC_ENUM("ISRC2 FSL", arizona_isrc_fsl[1]),
352SOC_ENUM("ISRC1 FSH", arizona_isrc_fsh[0]),
353SOC_ENUM("ISRC2 FSH", arizona_isrc_fsh[1]),
354SOC_ENUM("ASRC RATE 1", arizona_asrc_rate1),
355
356ARIZONA_MIXER_CONTROLS("HPOUTL", ARIZONA_OUT1LMIX_INPUT_1_SOURCE),
357ARIZONA_MIXER_CONTROLS("HPOUTR", ARIZONA_OUT1RMIX_INPUT_1_SOURCE),
358ARIZONA_MIXER_CONTROLS("LINEOUTL", ARIZONA_OUT2LMIX_INPUT_1_SOURCE),
359ARIZONA_MIXER_CONTROLS("LINEOUTR", ARIZONA_OUT2RMIX_INPUT_1_SOURCE),
360ARIZONA_MIXER_CONTROLS("EPOUT", ARIZONA_OUT3LMIX_INPUT_1_SOURCE),
361ARIZONA_MIXER_CONTROLS("SPKOUTL", ARIZONA_OUT4LMIX_INPUT_1_SOURCE),
362ARIZONA_MIXER_CONTROLS("SPKOUTR", ARIZONA_OUT4RMIX_INPUT_1_SOURCE),
363ARIZONA_MIXER_CONTROLS("SPKDATL", ARIZONA_OUT5LMIX_INPUT_1_SOURCE),
364ARIZONA_MIXER_CONTROLS("SPKDATR", ARIZONA_OUT5RMIX_INPUT_1_SOURCE),
365
366SOC_DOUBLE_R("HPOUT Digital Switch", ARIZONA_DAC_DIGITAL_VOLUME_1L,
367 ARIZONA_DAC_DIGITAL_VOLUME_1R, ARIZONA_OUT1L_MUTE_SHIFT, 1, 1),
368SOC_DOUBLE_R("LINEOUT Digital Switch", ARIZONA_DAC_DIGITAL_VOLUME_2L,
369 ARIZONA_DAC_DIGITAL_VOLUME_2R, ARIZONA_OUT2L_MUTE_SHIFT, 1, 1),
370SOC_SINGLE("EPOUT Digital Switch", ARIZONA_DAC_DIGITAL_VOLUME_3L,
371 ARIZONA_OUT3L_MUTE_SHIFT, 1, 1),
372SOC_DOUBLE_R("Speaker Digital Switch", ARIZONA_DAC_DIGITAL_VOLUME_4L,
373 ARIZONA_DAC_DIGITAL_VOLUME_4R, ARIZONA_OUT4L_MUTE_SHIFT, 1, 1),
374SOC_DOUBLE_R("SPKDAT Digital Switch", ARIZONA_DAC_DIGITAL_VOLUME_5L,
375 ARIZONA_DAC_DIGITAL_VOLUME_5R, ARIZONA_OUT5L_MUTE_SHIFT, 1, 1),
376
377SOC_DOUBLE_R_TLV("HPOUT Digital Volume", ARIZONA_DAC_DIGITAL_VOLUME_1L,
378 ARIZONA_DAC_DIGITAL_VOLUME_1R, ARIZONA_OUT1L_VOL_SHIFT,
379 0xbf, 0, digital_tlv),
380SOC_DOUBLE_R_TLV("LINEOUT Digital Volume", ARIZONA_DAC_DIGITAL_VOLUME_2L,
381 ARIZONA_DAC_DIGITAL_VOLUME_2R, ARIZONA_OUT2L_VOL_SHIFT,
382 0xbf, 0, digital_tlv),
383SOC_SINGLE_TLV("EPOUT Digital Volume", ARIZONA_DAC_DIGITAL_VOLUME_3L,
384 ARIZONA_OUT3L_VOL_SHIFT, 0xbf, 0, digital_tlv),
385SOC_DOUBLE_R_TLV("Speaker Digital Volume", ARIZONA_DAC_DIGITAL_VOLUME_4L,
386 ARIZONA_DAC_DIGITAL_VOLUME_4R, ARIZONA_OUT4L_VOL_SHIFT,
387 0xbf, 0, digital_tlv),
388SOC_DOUBLE_R_TLV("SPKDAT Digital Volume", ARIZONA_DAC_DIGITAL_VOLUME_5L,
389 ARIZONA_DAC_DIGITAL_VOLUME_5R, ARIZONA_OUT5L_VOL_SHIFT,
390 0xbf, 0, digital_tlv),
391
392SOC_DOUBLE("SPKDAT Switch", ARIZONA_PDM_SPK1_CTRL_1, ARIZONA_SPK1L_MUTE_SHIFT,
393 ARIZONA_SPK1R_MUTE_SHIFT, 1, 1),
394
395SOC_ENUM("Output Ramp Up", arizona_out_vi_ramp),
396SOC_ENUM("Output Ramp Down", arizona_out_vd_ramp),
397
398SOC_SINGLE("Noise Gate Switch", ARIZONA_NOISE_GATE_CONTROL,
399 ARIZONA_NGATE_ENA_SHIFT, 1, 0),
400SOC_SINGLE_TLV("Noise Gate Threshold Volume", ARIZONA_NOISE_GATE_CONTROL,
401 ARIZONA_NGATE_THR_SHIFT, 7, 1, ng_tlv),
402SOC_ENUM("Noise Gate Hold", arizona_ng_hold),
403
404WM8998_NG_SRC("HPOUTL", ARIZONA_NOISE_GATE_SELECT_1L),
405WM8998_NG_SRC("HPOUTR", ARIZONA_NOISE_GATE_SELECT_1R),
406WM8998_NG_SRC("LINEOUTL", ARIZONA_NOISE_GATE_SELECT_2L),
407WM8998_NG_SRC("LINEOUTR", ARIZONA_NOISE_GATE_SELECT_2R),
408WM8998_NG_SRC("EPOUT", ARIZONA_NOISE_GATE_SELECT_3L),
409WM8998_NG_SRC("SPKOUTL", ARIZONA_NOISE_GATE_SELECT_4L),
410WM8998_NG_SRC("SPKOUTR", ARIZONA_NOISE_GATE_SELECT_4R),
411WM8998_NG_SRC("SPKDATL", ARIZONA_NOISE_GATE_SELECT_5L),
412WM8998_NG_SRC("SPKDATR", ARIZONA_NOISE_GATE_SELECT_5R),
413
414ARIZONA_MIXER_CONTROLS("AIF1TX1", ARIZONA_AIF1TX1MIX_INPUT_1_SOURCE),
415ARIZONA_MIXER_CONTROLS("AIF1TX2", ARIZONA_AIF1TX2MIX_INPUT_1_SOURCE),
416ARIZONA_MIXER_CONTROLS("AIF1TX3", ARIZONA_AIF1TX3MIX_INPUT_1_SOURCE),
417ARIZONA_MIXER_CONTROLS("AIF1TX4", ARIZONA_AIF1TX4MIX_INPUT_1_SOURCE),
418ARIZONA_MIXER_CONTROLS("AIF1TX5", ARIZONA_AIF1TX5MIX_INPUT_1_SOURCE),
419ARIZONA_MIXER_CONTROLS("AIF1TX6", ARIZONA_AIF1TX6MIX_INPUT_1_SOURCE),
420
421ARIZONA_MIXER_CONTROLS("AIF2TX1", ARIZONA_AIF2TX1MIX_INPUT_1_SOURCE),
422ARIZONA_MIXER_CONTROLS("AIF2TX2", ARIZONA_AIF2TX2MIX_INPUT_1_SOURCE),
423ARIZONA_MIXER_CONTROLS("AIF2TX3", ARIZONA_AIF2TX3MIX_INPUT_1_SOURCE),
424ARIZONA_MIXER_CONTROLS("AIF2TX4", ARIZONA_AIF2TX4MIX_INPUT_1_SOURCE),
425ARIZONA_MIXER_CONTROLS("AIF2TX5", ARIZONA_AIF2TX5MIX_INPUT_1_SOURCE),
426ARIZONA_MIXER_CONTROLS("AIF2TX6", ARIZONA_AIF2TX6MIX_INPUT_1_SOURCE),
427
428ARIZONA_MIXER_CONTROLS("AIF3TX1", ARIZONA_AIF3TX1MIX_INPUT_1_SOURCE),
429ARIZONA_MIXER_CONTROLS("AIF3TX2", ARIZONA_AIF3TX2MIX_INPUT_1_SOURCE),
430
431ARIZONA_GAINMUX_CONTROLS("SLIMTX1", ARIZONA_SLIMTX1MIX_INPUT_1_SOURCE),
432ARIZONA_GAINMUX_CONTROLS("SLIMTX2", ARIZONA_SLIMTX2MIX_INPUT_1_SOURCE),
433ARIZONA_GAINMUX_CONTROLS("SLIMTX3", ARIZONA_SLIMTX3MIX_INPUT_1_SOURCE),
434ARIZONA_GAINMUX_CONTROLS("SLIMTX4", ARIZONA_SLIMTX4MIX_INPUT_1_SOURCE),
435ARIZONA_GAINMUX_CONTROLS("SLIMTX5", ARIZONA_SLIMTX5MIX_INPUT_1_SOURCE),
436ARIZONA_GAINMUX_CONTROLS("SLIMTX6", ARIZONA_SLIMTX6MIX_INPUT_1_SOURCE),
437
438ARIZONA_GAINMUX_CONTROLS("SPDIFTX1", ARIZONA_SPDIFTX1MIX_INPUT_1_SOURCE),
439ARIZONA_GAINMUX_CONTROLS("SPDIFTX2", ARIZONA_SPDIFTX2MIX_INPUT_1_SOURCE),
440};
441
442ARIZONA_MUX_ENUMS(EQ1, ARIZONA_EQ1MIX_INPUT_1_SOURCE);
443ARIZONA_MUX_ENUMS(EQ2, ARIZONA_EQ2MIX_INPUT_1_SOURCE);
444ARIZONA_MUX_ENUMS(EQ3, ARIZONA_EQ3MIX_INPUT_1_SOURCE);
445ARIZONA_MUX_ENUMS(EQ4, ARIZONA_EQ4MIX_INPUT_1_SOURCE);
446
447ARIZONA_MUX_ENUMS(DRC1L, ARIZONA_DRC1LMIX_INPUT_1_SOURCE);
448ARIZONA_MUX_ENUMS(DRC1R, ARIZONA_DRC1RMIX_INPUT_1_SOURCE);
449
450ARIZONA_MIXER_ENUMS(LHPF1, ARIZONA_HPLP1MIX_INPUT_1_SOURCE);
451ARIZONA_MIXER_ENUMS(LHPF2, ARIZONA_HPLP2MIX_INPUT_1_SOURCE);
452ARIZONA_MIXER_ENUMS(LHPF3, ARIZONA_HPLP3MIX_INPUT_1_SOURCE);
453ARIZONA_MIXER_ENUMS(LHPF4, ARIZONA_HPLP4MIX_INPUT_1_SOURCE);
454
455ARIZONA_MIXER_ENUMS(PWM1, ARIZONA_PWM1MIX_INPUT_1_SOURCE);
456ARIZONA_MIXER_ENUMS(PWM2, ARIZONA_PWM2MIX_INPUT_1_SOURCE);
457
458ARIZONA_MIXER_ENUMS(OUT1L, ARIZONA_OUT1LMIX_INPUT_1_SOURCE);
459ARIZONA_MIXER_ENUMS(OUT1R, ARIZONA_OUT1RMIX_INPUT_1_SOURCE);
460ARIZONA_MIXER_ENUMS(OUT2L, ARIZONA_OUT2LMIX_INPUT_1_SOURCE);
461ARIZONA_MIXER_ENUMS(OUT2R, ARIZONA_OUT2RMIX_INPUT_1_SOURCE);
462ARIZONA_MIXER_ENUMS(OUT3, ARIZONA_OUT3LMIX_INPUT_1_SOURCE);
463ARIZONA_MIXER_ENUMS(SPKOUTL, ARIZONA_OUT4LMIX_INPUT_1_SOURCE);
464ARIZONA_MIXER_ENUMS(SPKOUTR, ARIZONA_OUT4RMIX_INPUT_1_SOURCE);
465ARIZONA_MIXER_ENUMS(SPKDATL, ARIZONA_OUT5LMIX_INPUT_1_SOURCE);
466ARIZONA_MIXER_ENUMS(SPKDATR, ARIZONA_OUT5RMIX_INPUT_1_SOURCE);
467
468ARIZONA_MIXER_ENUMS(AIF1TX1, ARIZONA_AIF1TX1MIX_INPUT_1_SOURCE);
469ARIZONA_MIXER_ENUMS(AIF1TX2, ARIZONA_AIF1TX2MIX_INPUT_1_SOURCE);
470ARIZONA_MIXER_ENUMS(AIF1TX3, ARIZONA_AIF1TX3MIX_INPUT_1_SOURCE);
471ARIZONA_MIXER_ENUMS(AIF1TX4, ARIZONA_AIF1TX4MIX_INPUT_1_SOURCE);
472ARIZONA_MIXER_ENUMS(AIF1TX5, ARIZONA_AIF1TX5MIX_INPUT_1_SOURCE);
473ARIZONA_MIXER_ENUMS(AIF1TX6, ARIZONA_AIF1TX6MIX_INPUT_1_SOURCE);
474
475ARIZONA_MIXER_ENUMS(AIF2TX1, ARIZONA_AIF2TX1MIX_INPUT_1_SOURCE);
476ARIZONA_MIXER_ENUMS(AIF2TX2, ARIZONA_AIF2TX2MIX_INPUT_1_SOURCE);
477ARIZONA_MIXER_ENUMS(AIF2TX3, ARIZONA_AIF2TX3MIX_INPUT_1_SOURCE);
478ARIZONA_MIXER_ENUMS(AIF2TX4, ARIZONA_AIF2TX4MIX_INPUT_1_SOURCE);
479ARIZONA_MIXER_ENUMS(AIF2TX5, ARIZONA_AIF2TX5MIX_INPUT_1_SOURCE);
480ARIZONA_MIXER_ENUMS(AIF2TX6, ARIZONA_AIF2TX6MIX_INPUT_1_SOURCE);
481
482ARIZONA_MIXER_ENUMS(AIF3TX1, ARIZONA_AIF3TX1MIX_INPUT_1_SOURCE);
483ARIZONA_MIXER_ENUMS(AIF3TX2, ARIZONA_AIF3TX2MIX_INPUT_1_SOURCE);
484
485ARIZONA_MUX_ENUMS(SLIMTX1, ARIZONA_SLIMTX1MIX_INPUT_1_SOURCE);
486ARIZONA_MUX_ENUMS(SLIMTX2, ARIZONA_SLIMTX2MIX_INPUT_1_SOURCE);
487ARIZONA_MUX_ENUMS(SLIMTX3, ARIZONA_SLIMTX3MIX_INPUT_1_SOURCE);
488ARIZONA_MUX_ENUMS(SLIMTX4, ARIZONA_SLIMTX4MIX_INPUT_1_SOURCE);
489ARIZONA_MUX_ENUMS(SLIMTX5, ARIZONA_SLIMTX5MIX_INPUT_1_SOURCE);
490ARIZONA_MUX_ENUMS(SLIMTX6, ARIZONA_SLIMTX6MIX_INPUT_1_SOURCE);
491
492ARIZONA_MUX_ENUMS(SPD1TX1, ARIZONA_SPDIFTX1MIX_INPUT_1_SOURCE);
493ARIZONA_MUX_ENUMS(SPD1TX2, ARIZONA_SPDIFTX2MIX_INPUT_1_SOURCE);
494
495ARIZONA_MUX_ENUMS(ASRC1L, ARIZONA_ASRC1LMIX_INPUT_1_SOURCE);
496ARIZONA_MUX_ENUMS(ASRC1R, ARIZONA_ASRC1RMIX_INPUT_1_SOURCE);
497ARIZONA_MUX_ENUMS(ASRC2L, ARIZONA_ASRC2LMIX_INPUT_1_SOURCE);
498ARIZONA_MUX_ENUMS(ASRC2R, ARIZONA_ASRC2RMIX_INPUT_1_SOURCE);
499
500ARIZONA_MUX_ENUMS(ISRC1INT1, ARIZONA_ISRC1INT1MIX_INPUT_1_SOURCE);
501ARIZONA_MUX_ENUMS(ISRC1INT2, ARIZONA_ISRC1INT2MIX_INPUT_1_SOURCE);
502ARIZONA_MUX_ENUMS(ISRC1INT3, ARIZONA_ISRC1INT3MIX_INPUT_1_SOURCE);
503ARIZONA_MUX_ENUMS(ISRC1INT4, ARIZONA_ISRC1INT4MIX_INPUT_1_SOURCE);
504
505ARIZONA_MUX_ENUMS(ISRC1DEC1, ARIZONA_ISRC1DEC1MIX_INPUT_1_SOURCE);
506ARIZONA_MUX_ENUMS(ISRC1DEC2, ARIZONA_ISRC1DEC2MIX_INPUT_1_SOURCE);
507ARIZONA_MUX_ENUMS(ISRC1DEC3, ARIZONA_ISRC1DEC3MIX_INPUT_1_SOURCE);
508ARIZONA_MUX_ENUMS(ISRC1DEC4, ARIZONA_ISRC1DEC4MIX_INPUT_1_SOURCE);
509
510ARIZONA_MUX_ENUMS(ISRC2INT1, ARIZONA_ISRC2INT1MIX_INPUT_1_SOURCE);
511ARIZONA_MUX_ENUMS(ISRC2INT2, ARIZONA_ISRC2INT2MIX_INPUT_1_SOURCE);
512
513ARIZONA_MUX_ENUMS(ISRC2DEC1, ARIZONA_ISRC2DEC1MIX_INPUT_1_SOURCE);
514ARIZONA_MUX_ENUMS(ISRC2DEC2, ARIZONA_ISRC2DEC2MIX_INPUT_1_SOURCE);
515
516static const char * const wm8998_aec_loopback_texts[] = {
517 "HPOUTL", "HPOUTR", "LINEOUTL", "LINEOUTR", "EPOUT",
518 "SPKOUTL", "SPKOUTR", "SPKDATL", "SPKDATR",
519};
520
521static const unsigned int wm8998_aec_loopback_values[] = {
522 0, 1, 2, 3, 4, 6, 7, 8, 9,
523};
524
525static const SOC_VALUE_ENUM_SINGLE_DECL(wm8998_aec1_loopback,
526 ARIZONA_DAC_AEC_CONTROL_1,
527 ARIZONA_AEC_LOOPBACK_SRC_SHIFT, 0xf,
528 wm8998_aec_loopback_texts,
529 wm8998_aec_loopback_values);
530
531static const SOC_VALUE_ENUM_SINGLE_DECL(wm8998_aec2_loopback,
532 ARIZONA_DAC_AEC_CONTROL_2,
533 ARIZONA_AEC_LOOPBACK_SRC_SHIFT, 0xf,
534 wm8998_aec_loopback_texts,
535 wm8998_aec_loopback_values);
536
537static const struct snd_kcontrol_new wm8998_aec_loopback_mux[] = {
538 SOC_DAPM_ENUM("AEC1 Loopback", wm8998_aec1_loopback),
539 SOC_DAPM_ENUM("AEC2 Loopback", wm8998_aec2_loopback),
540};
541
542static const struct snd_soc_dapm_widget wm8998_dapm_widgets[] = {
543SND_SOC_DAPM_SUPPLY("SYSCLK", ARIZONA_SYSTEM_CLOCK_1,
544 ARIZONA_SYSCLK_ENA_SHIFT, 0, NULL, 0),
545SND_SOC_DAPM_SUPPLY("ASYNCCLK", ARIZONA_ASYNC_CLOCK_1,
546 ARIZONA_ASYNC_CLK_ENA_SHIFT, 0, NULL, 0),
547SND_SOC_DAPM_SUPPLY("OPCLK", ARIZONA_OUTPUT_SYSTEM_CLOCK,
548 ARIZONA_OPCLK_ENA_SHIFT, 0, NULL, 0),
549SND_SOC_DAPM_SUPPLY("ASYNCOPCLK", ARIZONA_OUTPUT_ASYNC_CLOCK,
550 ARIZONA_OPCLK_ASYNC_ENA_SHIFT, 0, NULL, 0),
551
552SND_SOC_DAPM_REGULATOR_SUPPLY("DBVDD2", 0, 0),
553SND_SOC_DAPM_REGULATOR_SUPPLY("DBVDD3", 0, 0),
554SND_SOC_DAPM_REGULATOR_SUPPLY("CPVDD", 20, 0),
555SND_SOC_DAPM_REGULATOR_SUPPLY("MICVDD", 0, SND_SOC_DAPM_REGULATOR_BYPASS),
556SND_SOC_DAPM_REGULATOR_SUPPLY("SPKVDDL", 0, 0),
557SND_SOC_DAPM_REGULATOR_SUPPLY("SPKVDDR", 0, 0),
558
559SND_SOC_DAPM_SIGGEN("TONE"),
560SND_SOC_DAPM_SIGGEN("HAPTICS"),
561
562SND_SOC_DAPM_INPUT("IN1AL"),
563SND_SOC_DAPM_INPUT("IN1AR"),
564SND_SOC_DAPM_INPUT("IN1BL"),
565SND_SOC_DAPM_INPUT("IN1BR"),
566SND_SOC_DAPM_INPUT("IN2A"),
567SND_SOC_DAPM_INPUT("IN2B"),
568
569SND_SOC_DAPM_MUX("IN1L Mux", SND_SOC_NOPM, 0, 0, &wm8998_in1mux[0]),
570SND_SOC_DAPM_MUX("IN1R Mux", SND_SOC_NOPM, 0, 0, &wm8998_in1mux[1]),
571SND_SOC_DAPM_MUX("IN2 Mux", SND_SOC_NOPM, 0, 0, &wm8998_in2mux),
572
573SND_SOC_DAPM_OUTPUT("DRC1 Signal Activity"),
574
575SND_SOC_DAPM_PGA_E("IN1L PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN1L_ENA_SHIFT,
576 0, NULL, 0, arizona_in_ev,
577 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD |
578 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU),
579SND_SOC_DAPM_PGA_E("IN1R PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN1R_ENA_SHIFT,
580 0, NULL, 0, arizona_in_ev,
581 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD |
582 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU),
583SND_SOC_DAPM_PGA_E("IN2 PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN2L_ENA_SHIFT,
584 0, NULL, 0, arizona_in_ev,
585 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD |
586 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU),
587
588SND_SOC_DAPM_SUPPLY("MICBIAS1", ARIZONA_MIC_BIAS_CTRL_1,
589 ARIZONA_MICB1_ENA_SHIFT, 0, NULL, 0),
590SND_SOC_DAPM_SUPPLY("MICBIAS2", ARIZONA_MIC_BIAS_CTRL_2,
591 ARIZONA_MICB1_ENA_SHIFT, 0, NULL, 0),
592SND_SOC_DAPM_SUPPLY("MICBIAS3", ARIZONA_MIC_BIAS_CTRL_3,
593 ARIZONA_MICB1_ENA_SHIFT, 0, NULL, 0),
594
595SND_SOC_DAPM_PGA("Tone Generator 1", ARIZONA_TONE_GENERATOR_1,
596 ARIZONA_TONE1_ENA_SHIFT, 0, NULL, 0),
597SND_SOC_DAPM_PGA("Tone Generator 2", ARIZONA_TONE_GENERATOR_1,
598 ARIZONA_TONE2_ENA_SHIFT, 0, NULL, 0),
599
600SND_SOC_DAPM_PGA("EQ1", ARIZONA_EQ1_1, ARIZONA_EQ1_ENA_SHIFT, 0, NULL, 0),
601SND_SOC_DAPM_PGA("EQ2", ARIZONA_EQ2_1, ARIZONA_EQ2_ENA_SHIFT, 0, NULL, 0),
602SND_SOC_DAPM_PGA("EQ3", ARIZONA_EQ3_1, ARIZONA_EQ3_ENA_SHIFT, 0, NULL, 0),
603SND_SOC_DAPM_PGA("EQ4", ARIZONA_EQ4_1, ARIZONA_EQ4_ENA_SHIFT, 0, NULL, 0),
604
605SND_SOC_DAPM_PGA("DRC1L", ARIZONA_DRC1_CTRL1, ARIZONA_DRC1L_ENA_SHIFT, 0,
606 NULL, 0),
607SND_SOC_DAPM_PGA("DRC1R", ARIZONA_DRC1_CTRL1, ARIZONA_DRC1R_ENA_SHIFT, 0,
608 NULL, 0),
609
610SND_SOC_DAPM_PGA("LHPF1", ARIZONA_HPLPF1_1, ARIZONA_LHPF1_ENA_SHIFT, 0,
611 NULL, 0),
612SND_SOC_DAPM_PGA("LHPF2", ARIZONA_HPLPF2_1, ARIZONA_LHPF2_ENA_SHIFT, 0,
613 NULL, 0),
614SND_SOC_DAPM_PGA("LHPF3", ARIZONA_HPLPF3_1, ARIZONA_LHPF3_ENA_SHIFT, 0,
615 NULL, 0),
616SND_SOC_DAPM_PGA("LHPF4", ARIZONA_HPLPF4_1, ARIZONA_LHPF4_ENA_SHIFT, 0,
617 NULL, 0),
618
619SND_SOC_DAPM_PGA("PWM1 Driver", ARIZONA_PWM_DRIVE_1, ARIZONA_PWM1_ENA_SHIFT,
620 0, NULL, 0),
621SND_SOC_DAPM_PGA("PWM2 Driver", ARIZONA_PWM_DRIVE_1, ARIZONA_PWM2_ENA_SHIFT,
622 0, NULL, 0),
623
624SND_SOC_DAPM_PGA_E("ASRC1L", ARIZONA_ASRC_ENABLE, ARIZONA_ASRC1L_ENA_SHIFT, 0,
625 NULL, 0, wm8998_asrc_ev, SND_SOC_DAPM_PRE_PMU),
626SND_SOC_DAPM_PGA_E("ASRC1R", ARIZONA_ASRC_ENABLE, ARIZONA_ASRC1R_ENA_SHIFT, 0,
627 NULL, 0, wm8998_asrc_ev, SND_SOC_DAPM_PRE_PMU),
628SND_SOC_DAPM_PGA_E("ASRC2L", ARIZONA_ASRC_ENABLE, ARIZONA_ASRC2L_ENA_SHIFT, 0,
629 NULL, 0, wm8998_asrc_ev, SND_SOC_DAPM_PRE_PMU),
630SND_SOC_DAPM_PGA_E("ASRC2R", ARIZONA_ASRC_ENABLE, ARIZONA_ASRC2R_ENA_SHIFT, 0,
631 NULL, 0, wm8998_asrc_ev, SND_SOC_DAPM_PRE_PMU),
632
633SND_SOC_DAPM_PGA("ISRC1INT1", ARIZONA_ISRC_1_CTRL_3,
634 ARIZONA_ISRC1_INT0_ENA_SHIFT, 0, NULL, 0),
635SND_SOC_DAPM_PGA("ISRC1INT2", ARIZONA_ISRC_1_CTRL_3,
636 ARIZONA_ISRC1_INT1_ENA_SHIFT, 0, NULL, 0),
637SND_SOC_DAPM_PGA("ISRC1INT3", ARIZONA_ISRC_1_CTRL_3,
638 ARIZONA_ISRC1_INT2_ENA_SHIFT, 0, NULL, 0),
639SND_SOC_DAPM_PGA("ISRC1INT4", ARIZONA_ISRC_1_CTRL_3,
640 ARIZONA_ISRC1_INT3_ENA_SHIFT, 0, NULL, 0),
641
642SND_SOC_DAPM_PGA("ISRC1DEC1", ARIZONA_ISRC_1_CTRL_3,
643 ARIZONA_ISRC1_DEC0_ENA_SHIFT, 0, NULL, 0),
644SND_SOC_DAPM_PGA("ISRC1DEC2", ARIZONA_ISRC_1_CTRL_3,
645 ARIZONA_ISRC1_DEC1_ENA_SHIFT, 0, NULL, 0),
646SND_SOC_DAPM_PGA("ISRC1DEC3", ARIZONA_ISRC_1_CTRL_3,
647 ARIZONA_ISRC1_DEC2_ENA_SHIFT, 0, NULL, 0),
648SND_SOC_DAPM_PGA("ISRC1DEC4", ARIZONA_ISRC_1_CTRL_3,
649 ARIZONA_ISRC1_DEC3_ENA_SHIFT, 0, NULL, 0),
650
651SND_SOC_DAPM_PGA("ISRC2INT1", ARIZONA_ISRC_2_CTRL_3,
652 ARIZONA_ISRC2_INT0_ENA_SHIFT, 0, NULL, 0),
653SND_SOC_DAPM_PGA("ISRC2INT2", ARIZONA_ISRC_2_CTRL_3,
654 ARIZONA_ISRC2_INT1_ENA_SHIFT, 0, NULL, 0),
655
656SND_SOC_DAPM_PGA("ISRC2DEC1", ARIZONA_ISRC_2_CTRL_3,
657 ARIZONA_ISRC2_DEC0_ENA_SHIFT, 0, NULL, 0),
658SND_SOC_DAPM_PGA("ISRC2DEC2", ARIZONA_ISRC_2_CTRL_3,
659 ARIZONA_ISRC2_DEC1_ENA_SHIFT, 0, NULL, 0),
660
661SND_SOC_DAPM_MUX("AEC1 Loopback", ARIZONA_DAC_AEC_CONTROL_1,
662 ARIZONA_AEC_LOOPBACK_ENA_SHIFT, 0,
663 &wm8998_aec_loopback_mux[0]),
664
665SND_SOC_DAPM_MUX("AEC2 Loopback", ARIZONA_DAC_AEC_CONTROL_2,
666 ARIZONA_AEC_LOOPBACK_ENA_SHIFT, 0,
667 &wm8998_aec_loopback_mux[1]),
668
669SND_SOC_DAPM_AIF_OUT("AIF1TX1", NULL, 0,
670 ARIZONA_AIF1_TX_ENABLES, ARIZONA_AIF1TX1_ENA_SHIFT, 0),
671SND_SOC_DAPM_AIF_OUT("AIF1TX2", NULL, 0,
672 ARIZONA_AIF1_TX_ENABLES, ARIZONA_AIF1TX2_ENA_SHIFT, 0),
673SND_SOC_DAPM_AIF_OUT("AIF1TX3", NULL, 0,
674 ARIZONA_AIF1_TX_ENABLES, ARIZONA_AIF1TX3_ENA_SHIFT, 0),
675SND_SOC_DAPM_AIF_OUT("AIF1TX4", NULL, 0,
676 ARIZONA_AIF1_TX_ENABLES, ARIZONA_AIF1TX4_ENA_SHIFT, 0),
677SND_SOC_DAPM_AIF_OUT("AIF1TX5", NULL, 0,
678 ARIZONA_AIF1_TX_ENABLES, ARIZONA_AIF1TX5_ENA_SHIFT, 0),
679SND_SOC_DAPM_AIF_OUT("AIF1TX6", NULL, 0,
680 ARIZONA_AIF1_TX_ENABLES, ARIZONA_AIF1TX6_ENA_SHIFT, 0),
681
682SND_SOC_DAPM_AIF_IN("AIF1RX1", NULL, 0,
683 ARIZONA_AIF1_RX_ENABLES, ARIZONA_AIF1RX1_ENA_SHIFT, 0),
684SND_SOC_DAPM_AIF_IN("AIF1RX2", NULL, 0,
685 ARIZONA_AIF1_RX_ENABLES, ARIZONA_AIF1RX2_ENA_SHIFT, 0),
686SND_SOC_DAPM_AIF_IN("AIF1RX3", NULL, 0,
687 ARIZONA_AIF1_RX_ENABLES, ARIZONA_AIF1RX3_ENA_SHIFT, 0),
688SND_SOC_DAPM_AIF_IN("AIF1RX4", NULL, 0,
689 ARIZONA_AIF1_RX_ENABLES, ARIZONA_AIF1RX4_ENA_SHIFT, 0),
690SND_SOC_DAPM_AIF_IN("AIF1RX5", NULL, 0,
691 ARIZONA_AIF1_RX_ENABLES, ARIZONA_AIF1RX5_ENA_SHIFT, 0),
692SND_SOC_DAPM_AIF_IN("AIF1RX6", NULL, 0,
693 ARIZONA_AIF1_RX_ENABLES, ARIZONA_AIF1RX6_ENA_SHIFT, 0),
694
695SND_SOC_DAPM_AIF_OUT("AIF2TX1", NULL, 0,
696 ARIZONA_AIF2_TX_ENABLES, ARIZONA_AIF2TX1_ENA_SHIFT, 0),
697SND_SOC_DAPM_AIF_OUT("AIF2TX2", NULL, 0,
698 ARIZONA_AIF2_TX_ENABLES, ARIZONA_AIF2TX2_ENA_SHIFT, 0),
699SND_SOC_DAPM_AIF_OUT("AIF2TX3", NULL, 0,
700 ARIZONA_AIF2_TX_ENABLES, ARIZONA_AIF2TX3_ENA_SHIFT, 0),
701SND_SOC_DAPM_AIF_OUT("AIF2TX4", NULL, 0,
702 ARIZONA_AIF2_TX_ENABLES, ARIZONA_AIF2TX4_ENA_SHIFT, 0),
703SND_SOC_DAPM_AIF_OUT("AIF2TX5", NULL, 0,
704 ARIZONA_AIF2_TX_ENABLES, ARIZONA_AIF2TX5_ENA_SHIFT, 0),
705SND_SOC_DAPM_AIF_OUT("AIF2TX6", NULL, 0,
706 ARIZONA_AIF2_TX_ENABLES, ARIZONA_AIF2TX6_ENA_SHIFT, 0),
707
708SND_SOC_DAPM_AIF_IN("AIF2RX1", NULL, 0,
709 ARIZONA_AIF2_RX_ENABLES, ARIZONA_AIF2RX1_ENA_SHIFT, 0),
710SND_SOC_DAPM_AIF_IN("AIF2RX2", NULL, 0,
711 ARIZONA_AIF2_RX_ENABLES, ARIZONA_AIF2RX2_ENA_SHIFT, 0),
712SND_SOC_DAPM_AIF_IN("AIF2RX3", NULL, 0,
713 ARIZONA_AIF2_RX_ENABLES, ARIZONA_AIF2RX3_ENA_SHIFT, 0),
714SND_SOC_DAPM_AIF_IN("AIF2RX4", NULL, 0,
715 ARIZONA_AIF2_RX_ENABLES, ARIZONA_AIF2RX4_ENA_SHIFT, 0),
716SND_SOC_DAPM_AIF_IN("AIF2RX5", NULL, 0,
717 ARIZONA_AIF2_RX_ENABLES, ARIZONA_AIF2RX5_ENA_SHIFT, 0),
718SND_SOC_DAPM_AIF_IN("AIF2RX6", NULL, 0,
719 ARIZONA_AIF2_RX_ENABLES, ARIZONA_AIF2RX6_ENA_SHIFT, 0),
720
721SND_SOC_DAPM_AIF_IN("SLIMRX1", NULL, 0,
722 ARIZONA_SLIMBUS_RX_CHANNEL_ENABLE,
723 ARIZONA_SLIMRX1_ENA_SHIFT, 0),
724SND_SOC_DAPM_AIF_IN("SLIMRX2", NULL, 0,
725 ARIZONA_SLIMBUS_RX_CHANNEL_ENABLE,
726 ARIZONA_SLIMRX2_ENA_SHIFT, 0),
727SND_SOC_DAPM_AIF_IN("SLIMRX3", NULL, 0,
728 ARIZONA_SLIMBUS_RX_CHANNEL_ENABLE,
729 ARIZONA_SLIMRX3_ENA_SHIFT, 0),
730SND_SOC_DAPM_AIF_IN("SLIMRX4", NULL, 0,
731 ARIZONA_SLIMBUS_RX_CHANNEL_ENABLE,
732 ARIZONA_SLIMRX4_ENA_SHIFT, 0),
733
734SND_SOC_DAPM_AIF_OUT("SLIMTX1", NULL, 0,
735 ARIZONA_SLIMBUS_TX_CHANNEL_ENABLE,
736 ARIZONA_SLIMTX1_ENA_SHIFT, 0),
737SND_SOC_DAPM_AIF_OUT("SLIMTX2", NULL, 0,
738 ARIZONA_SLIMBUS_TX_CHANNEL_ENABLE,
739 ARIZONA_SLIMTX2_ENA_SHIFT, 0),
740SND_SOC_DAPM_AIF_OUT("SLIMTX3", NULL, 0,
741 ARIZONA_SLIMBUS_TX_CHANNEL_ENABLE,
742 ARIZONA_SLIMTX3_ENA_SHIFT, 0),
743SND_SOC_DAPM_AIF_OUT("SLIMTX4", NULL, 0,
744 ARIZONA_SLIMBUS_TX_CHANNEL_ENABLE,
745 ARIZONA_SLIMTX4_ENA_SHIFT, 0),
746SND_SOC_DAPM_AIF_OUT("SLIMTX5", NULL, 0,
747 ARIZONA_SLIMBUS_TX_CHANNEL_ENABLE,
748 ARIZONA_SLIMTX5_ENA_SHIFT, 0),
749SND_SOC_DAPM_AIF_OUT("SLIMTX6", NULL, 0,
750 ARIZONA_SLIMBUS_TX_CHANNEL_ENABLE,
751 ARIZONA_SLIMTX6_ENA_SHIFT, 0),
752
753SND_SOC_DAPM_AIF_OUT("AIF3TX1", NULL, 0,
754 ARIZONA_AIF3_TX_ENABLES, ARIZONA_AIF3TX1_ENA_SHIFT, 0),
755SND_SOC_DAPM_AIF_OUT("AIF3TX2", NULL, 0,
756 ARIZONA_AIF3_TX_ENABLES, ARIZONA_AIF3TX2_ENA_SHIFT, 0),
757
758SND_SOC_DAPM_AIF_IN("AIF3RX1", NULL, 0,
759 ARIZONA_AIF3_RX_ENABLES, ARIZONA_AIF3RX1_ENA_SHIFT, 0),
760SND_SOC_DAPM_AIF_IN("AIF3RX2", NULL, 0,
761 ARIZONA_AIF3_RX_ENABLES, ARIZONA_AIF3RX2_ENA_SHIFT, 0),
762
763SND_SOC_DAPM_PGA_E("OUT1L", SND_SOC_NOPM,
764 ARIZONA_OUT1L_ENA_SHIFT, 0, NULL, 0, arizona_hp_ev,
765 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
766SND_SOC_DAPM_PGA_E("OUT1R", SND_SOC_NOPM,
767 ARIZONA_OUT1R_ENA_SHIFT, 0, NULL, 0, arizona_hp_ev,
768 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
769SND_SOC_DAPM_PGA_E("OUT2L", ARIZONA_OUTPUT_ENABLES_1,
770 ARIZONA_OUT2L_ENA_SHIFT, 0, NULL, 0, arizona_out_ev,
771 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
772SND_SOC_DAPM_PGA_E("OUT2R", ARIZONA_OUTPUT_ENABLES_1,
773 ARIZONA_OUT2R_ENA_SHIFT, 0, NULL, 0, arizona_out_ev,
774 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
775SND_SOC_DAPM_PGA_E("OUT3", ARIZONA_OUTPUT_ENABLES_1,
776 ARIZONA_OUT3L_ENA_SHIFT, 0, NULL, 0, arizona_out_ev,
777 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
778SND_SOC_DAPM_PGA_E("OUT5L", ARIZONA_OUTPUT_ENABLES_1,
779 ARIZONA_OUT5L_ENA_SHIFT, 0, NULL, 0, arizona_out_ev,
780 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
781SND_SOC_DAPM_PGA_E("OUT5R", ARIZONA_OUTPUT_ENABLES_1,
782 ARIZONA_OUT5R_ENA_SHIFT, 0, NULL, 0, arizona_out_ev,
783 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
784
785SND_SOC_DAPM_PGA("SPD1TX1", ARIZONA_SPD1_TX_CONTROL,
786 ARIZONA_SPD1_VAL1_SHIFT, 0, NULL, 0),
787SND_SOC_DAPM_PGA("SPD1TX2", ARIZONA_SPD1_TX_CONTROL,
788 ARIZONA_SPD1_VAL2_SHIFT, 0, NULL, 0),
789SND_SOC_DAPM_OUT_DRV("SPD1", ARIZONA_SPD1_TX_CONTROL,
790 ARIZONA_SPD1_ENA_SHIFT, 0, NULL, 0),
791
792ARIZONA_MUX_WIDGETS(EQ1, "EQ1"),
793ARIZONA_MUX_WIDGETS(EQ2, "EQ2"),
794ARIZONA_MUX_WIDGETS(EQ3, "EQ3"),
795ARIZONA_MUX_WIDGETS(EQ4, "EQ4"),
796
797ARIZONA_MUX_WIDGETS(DRC1L, "DRC1L"),
798ARIZONA_MUX_WIDGETS(DRC1R, "DRC1R"),
799
800ARIZONA_MIXER_WIDGETS(LHPF1, "LHPF1"),
801ARIZONA_MIXER_WIDGETS(LHPF2, "LHPF2"),
802ARIZONA_MIXER_WIDGETS(LHPF3, "LHPF3"),
803ARIZONA_MIXER_WIDGETS(LHPF4, "LHPF4"),
804
805ARIZONA_MIXER_WIDGETS(PWM1, "PWM1"),
806ARIZONA_MIXER_WIDGETS(PWM2, "PWM2"),
807
808ARIZONA_MIXER_WIDGETS(OUT1L, "HPOUTL"),
809ARIZONA_MIXER_WIDGETS(OUT1R, "HPOUTR"),
810ARIZONA_MIXER_WIDGETS(OUT2L, "LINEOUTL"),
811ARIZONA_MIXER_WIDGETS(OUT2R, "LINEOUTR"),
812ARIZONA_MIXER_WIDGETS(OUT3, "EPOUT"),
813ARIZONA_MIXER_WIDGETS(SPKOUTL, "SPKOUTL"),
814ARIZONA_MIXER_WIDGETS(SPKOUTR, "SPKOUTR"),
815ARIZONA_MIXER_WIDGETS(SPKDATL, "SPKDATL"),
816ARIZONA_MIXER_WIDGETS(SPKDATR, "SPKDATR"),
817
818ARIZONA_MIXER_WIDGETS(AIF1TX1, "AIF1TX1"),
819ARIZONA_MIXER_WIDGETS(AIF1TX2, "AIF1TX2"),
820ARIZONA_MIXER_WIDGETS(AIF1TX3, "AIF1TX3"),
821ARIZONA_MIXER_WIDGETS(AIF1TX4, "AIF1TX4"),
822ARIZONA_MIXER_WIDGETS(AIF1TX5, "AIF1TX5"),
823ARIZONA_MIXER_WIDGETS(AIF1TX6, "AIF1TX6"),
824
825ARIZONA_MIXER_WIDGETS(AIF2TX1, "AIF2TX1"),
826ARIZONA_MIXER_WIDGETS(AIF2TX2, "AIF2TX2"),
827ARIZONA_MIXER_WIDGETS(AIF2TX3, "AIF2TX3"),
828ARIZONA_MIXER_WIDGETS(AIF2TX4, "AIF2TX4"),
829ARIZONA_MIXER_WIDGETS(AIF2TX5, "AIF2TX5"),
830ARIZONA_MIXER_WIDGETS(AIF2TX6, "AIF2TX6"),
831
832ARIZONA_MIXER_WIDGETS(AIF3TX1, "AIF3TX1"),
833ARIZONA_MIXER_WIDGETS(AIF3TX2, "AIF3TX2"),
834
835ARIZONA_MUX_WIDGETS(SLIMTX1, "SLIMTX1"),
836ARIZONA_MUX_WIDGETS(SLIMTX2, "SLIMTX2"),
837ARIZONA_MUX_WIDGETS(SLIMTX3, "SLIMTX3"),
838ARIZONA_MUX_WIDGETS(SLIMTX4, "SLIMTX4"),
839ARIZONA_MUX_WIDGETS(SLIMTX5, "SLIMTX5"),
840ARIZONA_MUX_WIDGETS(SLIMTX6, "SLIMTX6"),
841
842ARIZONA_MUX_WIDGETS(SPD1TX1, "SPDIFTX1"),
843ARIZONA_MUX_WIDGETS(SPD1TX2, "SPDIFTX2"),
844
845ARIZONA_MUX_WIDGETS(ASRC1L, "ASRC1L"),
846ARIZONA_MUX_WIDGETS(ASRC1R, "ASRC1R"),
847ARIZONA_MUX_WIDGETS(ASRC2L, "ASRC2L"),
848ARIZONA_MUX_WIDGETS(ASRC2R, "ASRC2R"),
849
850ARIZONA_MUX_WIDGETS(ISRC1DEC1, "ISRC1DEC1"),
851ARIZONA_MUX_WIDGETS(ISRC1DEC2, "ISRC1DEC2"),
852ARIZONA_MUX_WIDGETS(ISRC1DEC3, "ISRC1DEC3"),
853ARIZONA_MUX_WIDGETS(ISRC1DEC4, "ISRC1DEC4"),
854
855ARIZONA_MUX_WIDGETS(ISRC1INT1, "ISRC1INT1"),
856ARIZONA_MUX_WIDGETS(ISRC1INT2, "ISRC1INT2"),
857ARIZONA_MUX_WIDGETS(ISRC1INT3, "ISRC1INT3"),
858ARIZONA_MUX_WIDGETS(ISRC1INT4, "ISRC1INT4"),
859
860ARIZONA_MUX_WIDGETS(ISRC2DEC1, "ISRC2DEC1"),
861ARIZONA_MUX_WIDGETS(ISRC2DEC2, "ISRC2DEC2"),
862
863ARIZONA_MUX_WIDGETS(ISRC2INT1, "ISRC2INT1"),
864ARIZONA_MUX_WIDGETS(ISRC2INT2, "ISRC2INT2"),
865
866SND_SOC_DAPM_OUTPUT("HPOUTL"),
867SND_SOC_DAPM_OUTPUT("HPOUTR"),
868SND_SOC_DAPM_OUTPUT("LINEOUTL"),
869SND_SOC_DAPM_OUTPUT("LINEOUTR"),
870SND_SOC_DAPM_OUTPUT("EPOUT"),
871SND_SOC_DAPM_OUTPUT("SPKOUTLN"),
872SND_SOC_DAPM_OUTPUT("SPKOUTLP"),
873SND_SOC_DAPM_OUTPUT("SPKOUTRN"),
874SND_SOC_DAPM_OUTPUT("SPKOUTRP"),
875SND_SOC_DAPM_OUTPUT("SPKDATL"),
876SND_SOC_DAPM_OUTPUT("SPKDATR"),
877SND_SOC_DAPM_OUTPUT("SPDIF"),
878
879SND_SOC_DAPM_OUTPUT("MICSUPP"),
880};
881
882#define ARIZONA_MIXER_INPUT_ROUTES(name) \
883 { name, "Tone Generator 1", "Tone Generator 1" }, \
884 { name, "Tone Generator 2", "Tone Generator 2" }, \
885 { name, "Haptics", "HAPTICS" }, \
886 { name, "AEC", "AEC1 Loopback" }, \
887 { name, "AEC2", "AEC2 Loopback" }, \
888 { name, "IN1L", "IN1L PGA" }, \
889 { name, "IN1R", "IN1R PGA" }, \
890 { name, "IN2L", "IN2 PGA" }, \
891 { name, "AIF1RX1", "AIF1RX1" }, \
892 { name, "AIF1RX2", "AIF1RX2" }, \
893 { name, "AIF1RX3", "AIF1RX3" }, \
894 { name, "AIF1RX4", "AIF1RX4" }, \
895 { name, "AIF1RX5", "AIF1RX5" }, \
896 { name, "AIF1RX6", "AIF1RX6" }, \
897 { name, "AIF2RX1", "AIF2RX1" }, \
898 { name, "AIF2RX2", "AIF2RX2" }, \
899 { name, "AIF2RX3", "AIF2RX3" }, \
900 { name, "AIF2RX4", "AIF2RX4" }, \
901 { name, "AIF2RX5", "AIF2RX5" }, \
902 { name, "AIF2RX6", "AIF2RX6" }, \
903 { name, "AIF3RX1", "AIF3RX1" }, \
904 { name, "AIF3RX2", "AIF3RX2" }, \
905 { name, "SLIMRX1", "SLIMRX1" }, \
906 { name, "SLIMRX2", "SLIMRX2" }, \
907 { name, "SLIMRX3", "SLIMRX3" }, \
908 { name, "SLIMRX4", "SLIMRX4" }, \
909 { name, "EQ1", "EQ1" }, \
910 { name, "EQ2", "EQ2" }, \
911 { name, "EQ3", "EQ3" }, \
912 { name, "EQ4", "EQ4" }, \
913 { name, "DRC1L", "DRC1L" }, \
914 { name, "DRC1R", "DRC1R" }, \
915 { name, "LHPF1", "LHPF1" }, \
916 { name, "LHPF2", "LHPF2" }, \
917 { name, "LHPF3", "LHPF3" }, \
918 { name, "LHPF4", "LHPF4" }, \
919 { name, "ASRC1L", "ASRC1L" }, \
920 { name, "ASRC1R", "ASRC1R" }, \
921 { name, "ASRC2L", "ASRC2L" }, \
922 { name, "ASRC2R", "ASRC2R" }, \
923 { name, "ISRC1DEC1", "ISRC1DEC1" }, \
924 { name, "ISRC1DEC2", "ISRC1DEC2" }, \
925 { name, "ISRC1DEC3", "ISRC1DEC3" }, \
926 { name, "ISRC1DEC4", "ISRC1DEC4" }, \
927 { name, "ISRC1INT1", "ISRC1INT1" }, \
928 { name, "ISRC1INT2", "ISRC1INT2" }, \
929 { name, "ISRC1INT3", "ISRC1INT3" }, \
930 { name, "ISRC1INT4", "ISRC1INT4" }, \
931 { name, "ISRC2DEC1", "ISRC2DEC1" }, \
932 { name, "ISRC2DEC2", "ISRC2DEC2" }, \
933 { name, "ISRC2INT1", "ISRC2INT1" }, \
934 { name, "ISRC2INT2", "ISRC2INT2" }
935
936static const struct snd_soc_dapm_route wm8998_dapm_routes[] = {
937 { "AIF2 Capture", NULL, "DBVDD2" },
938 { "AIF2 Playback", NULL, "DBVDD2" },
939
940 { "AIF3 Capture", NULL, "DBVDD3" },
941 { "AIF3 Playback", NULL, "DBVDD3" },
942
943 { "OUT1L", NULL, "CPVDD" },
944 { "OUT1R", NULL, "CPVDD" },
945 { "OUT2L", NULL, "CPVDD" },
946 { "OUT2R", NULL, "CPVDD" },
947 { "OUT3", NULL, "CPVDD" },
948
949 { "OUT4L", NULL, "SPKVDDL" },
950 { "OUT4R", NULL, "SPKVDDR" },
951
952 { "OUT1L", NULL, "SYSCLK" },
953 { "OUT1R", NULL, "SYSCLK" },
954 { "OUT2L", NULL, "SYSCLK" },
955 { "OUT2R", NULL, "SYSCLK" },
956 { "OUT3", NULL, "SYSCLK" },
957 { "OUT4L", NULL, "SYSCLK" },
958 { "OUT4R", NULL, "SYSCLK" },
959 { "OUT5L", NULL, "SYSCLK" },
960 { "OUT5R", NULL, "SYSCLK" },
961
962 { "IN1AL", NULL, "SYSCLK" },
963 { "IN1AR", NULL, "SYSCLK" },
964 { "IN1BL", NULL, "SYSCLK" },
965 { "IN1BR", NULL, "SYSCLK" },
966 { "IN2A", NULL, "SYSCLK" },
967 { "IN2B", NULL, "SYSCLK" },
968
969 { "SPD1", NULL, "SYSCLK" },
970 { "SPD1", NULL, "SPD1TX1" },
971 { "SPD1", NULL, "SPD1TX2" },
972
973 { "MICBIAS1", NULL, "MICVDD" },
974 { "MICBIAS2", NULL, "MICVDD" },
975 { "MICBIAS3", NULL, "MICVDD" },
976
977 { "Tone Generator 1", NULL, "SYSCLK" },
978 { "Tone Generator 2", NULL, "SYSCLK" },
979
980 { "Tone Generator 1", NULL, "TONE" },
981 { "Tone Generator 2", NULL, "TONE" },
982
983 { "AIF1 Capture", NULL, "AIF1TX1" },
984 { "AIF1 Capture", NULL, "AIF1TX2" },
985 { "AIF1 Capture", NULL, "AIF1TX3" },
986 { "AIF1 Capture", NULL, "AIF1TX4" },
987 { "AIF1 Capture", NULL, "AIF1TX5" },
988 { "AIF1 Capture", NULL, "AIF1TX6" },
989
990 { "AIF1RX1", NULL, "AIF1 Playback" },
991 { "AIF1RX2", NULL, "AIF1 Playback" },
992 { "AIF1RX3", NULL, "AIF1 Playback" },
993 { "AIF1RX4", NULL, "AIF1 Playback" },
994 { "AIF1RX5", NULL, "AIF1 Playback" },
995 { "AIF1RX6", NULL, "AIF1 Playback" },
996
997 { "AIF2 Capture", NULL, "AIF2TX1" },
998 { "AIF2 Capture", NULL, "AIF2TX2" },
999 { "AIF2 Capture", NULL, "AIF2TX3" },
1000 { "AIF2 Capture", NULL, "AIF2TX4" },
1001 { "AIF2 Capture", NULL, "AIF2TX5" },
1002 { "AIF2 Capture", NULL, "AIF2TX6" },
1003
1004 { "AIF2RX1", NULL, "AIF2 Playback" },
1005 { "AIF2RX2", NULL, "AIF2 Playback" },
1006 { "AIF2RX3", NULL, "AIF2 Playback" },
1007 { "AIF2RX4", NULL, "AIF2 Playback" },
1008 { "AIF2RX5", NULL, "AIF2 Playback" },
1009 { "AIF2RX6", NULL, "AIF2 Playback" },
1010
1011 { "AIF3 Capture", NULL, "AIF3TX1" },
1012 { "AIF3 Capture", NULL, "AIF3TX2" },
1013
1014 { "AIF3RX1", NULL, "AIF3 Playback" },
1015 { "AIF3RX2", NULL, "AIF3 Playback" },
1016
1017 { "Slim1 Capture", NULL, "SLIMTX1" },
1018 { "Slim1 Capture", NULL, "SLIMTX2" },
1019 { "Slim1 Capture", NULL, "SLIMTX3" },
1020 { "Slim1 Capture", NULL, "SLIMTX4" },
1021
1022 { "Slim2 Capture", NULL, "SLIMTX5" },
1023 { "Slim2 Capture", NULL, "SLIMTX6" },
1024
1025 { "SLIMRX1", NULL, "Slim1 Playback" },
1026 { "SLIMRX2", NULL, "Slim1 Playback" },
1027
1028 { "SLIMRX3", NULL, "Slim2 Playback" },
1029 { "SLIMRX4", NULL, "Slim2 Playback" },
1030
1031 { "AIF1 Playback", NULL, "SYSCLK" },
1032 { "AIF2 Playback", NULL, "SYSCLK" },
1033 { "AIF3 Playback", NULL, "SYSCLK" },
1034 { "Slim1 Playback", NULL, "SYSCLK" },
1035 { "Slim2 Playback", NULL, "SYSCLK" },
1036
1037 { "AIF1 Capture", NULL, "SYSCLK" },
1038 { "AIF2 Capture", NULL, "SYSCLK" },
1039 { "AIF3 Capture", NULL, "SYSCLK" },
1040 { "Slim1 Capture", NULL, "SYSCLK" },
1041 { "Slim2 Capture", NULL, "SYSCLK" },
1042
1043 { "IN1L Mux", "A", "IN1AL" },
1044 { "IN1R Mux", "A", "IN1AR" },
1045 { "IN1L Mux", "B", "IN1BL" },
1046 { "IN1R Mux", "B", "IN1BR" },
1047
1048 { "IN2 Mux", "A", "IN2A" },
1049 { "IN2 Mux", "B", "IN2B" },
1050
1051 { "IN1L PGA", NULL, "IN1L Mux" },
1052 { "IN1R PGA", NULL, "IN1R Mux" },
1053 { "IN2 PGA", NULL, "IN2 Mux" },
1054
1055 ARIZONA_MIXER_ROUTES("OUT1L", "HPOUTL"),
1056 ARIZONA_MIXER_ROUTES("OUT1R", "HPOUTR"),
1057 ARIZONA_MIXER_ROUTES("OUT2L", "LINEOUTL"),
1058 ARIZONA_MIXER_ROUTES("OUT2R", "LINEOUTR"),
1059 ARIZONA_MIXER_ROUTES("OUT3", "EPOUT"),
1060
1061 ARIZONA_MIXER_ROUTES("OUT4L", "SPKOUTL"),
1062 ARIZONA_MIXER_ROUTES("OUT4R", "SPKOUTR"),
1063 ARIZONA_MIXER_ROUTES("OUT5L", "SPKDATL"),
1064 ARIZONA_MIXER_ROUTES("OUT5R", "SPKDATR"),
1065
1066 ARIZONA_MIXER_ROUTES("PWM1 Driver", "PWM1"),
1067 ARIZONA_MIXER_ROUTES("PWM2 Driver", "PWM2"),
1068
1069 ARIZONA_MIXER_ROUTES("AIF1TX1", "AIF1TX1"),
1070 ARIZONA_MIXER_ROUTES("AIF1TX2", "AIF1TX2"),
1071 ARIZONA_MIXER_ROUTES("AIF1TX3", "AIF1TX3"),
1072 ARIZONA_MIXER_ROUTES("AIF1TX4", "AIF1TX4"),
1073 ARIZONA_MIXER_ROUTES("AIF1TX5", "AIF1TX5"),
1074 ARIZONA_MIXER_ROUTES("AIF1TX6", "AIF1TX6"),
1075
1076 ARIZONA_MIXER_ROUTES("AIF2TX1", "AIF2TX1"),
1077 ARIZONA_MIXER_ROUTES("AIF2TX2", "AIF2TX2"),
1078 ARIZONA_MIXER_ROUTES("AIF2TX3", "AIF2TX3"),
1079 ARIZONA_MIXER_ROUTES("AIF2TX4", "AIF2TX4"),
1080 ARIZONA_MIXER_ROUTES("AIF2TX5", "AIF2TX5"),
1081 ARIZONA_MIXER_ROUTES("AIF2TX6", "AIF2TX6"),
1082
1083 ARIZONA_MIXER_ROUTES("AIF3TX1", "AIF3TX1"),
1084 ARIZONA_MIXER_ROUTES("AIF3TX2", "AIF3TX2"),
1085
1086 ARIZONA_MUX_ROUTES("SLIMTX1", "SLIMTX1"),
1087 ARIZONA_MUX_ROUTES("SLIMTX2", "SLIMTX2"),
1088 ARIZONA_MUX_ROUTES("SLIMTX3", "SLIMTX3"),
1089 ARIZONA_MUX_ROUTES("SLIMTX4", "SLIMTX4"),
1090 ARIZONA_MUX_ROUTES("SLIMTX5", "SLIMTX5"),
1091 ARIZONA_MUX_ROUTES("SLIMTX6", "SLIMTX6"),
1092
1093 ARIZONA_MUX_ROUTES("SPD1TX1", "SPDIFTX1"),
1094 ARIZONA_MUX_ROUTES("SPD1TX2", "SPDIFTX2"),
1095
1096 ARIZONA_MUX_ROUTES("EQ1", "EQ1"),
1097 ARIZONA_MUX_ROUTES("EQ2", "EQ2"),
1098 ARIZONA_MUX_ROUTES("EQ3", "EQ3"),
1099 ARIZONA_MUX_ROUTES("EQ4", "EQ4"),
1100
1101 ARIZONA_MUX_ROUTES("DRC1L", "DRC1L"),
1102 ARIZONA_MUX_ROUTES("DRC1R", "DRC1R"),
1103
1104 ARIZONA_MIXER_ROUTES("LHPF1", "LHPF1"),
1105 ARIZONA_MIXER_ROUTES("LHPF2", "LHPF2"),
1106 ARIZONA_MIXER_ROUTES("LHPF3", "LHPF3"),
1107 ARIZONA_MIXER_ROUTES("LHPF4", "LHPF4"),
1108
1109 ARIZONA_MUX_ROUTES("ASRC1L", "ASRC1L"),
1110 ARIZONA_MUX_ROUTES("ASRC1R", "ASRC1R"),
1111 ARIZONA_MUX_ROUTES("ASRC2L", "ASRC2L"),
1112 ARIZONA_MUX_ROUTES("ASRC2R", "ASRC2R"),
1113
1114 ARIZONA_MUX_ROUTES("ISRC1INT1", "ISRC1INT1"),
1115 ARIZONA_MUX_ROUTES("ISRC1INT2", "ISRC1INT2"),
1116 ARIZONA_MUX_ROUTES("ISRC1INT3", "ISRC1INT3"),
1117 ARIZONA_MUX_ROUTES("ISRC1INT4", "ISRC1INT4"),
1118
1119 ARIZONA_MUX_ROUTES("ISRC1DEC1", "ISRC1DEC1"),
1120 ARIZONA_MUX_ROUTES("ISRC1DEC2", "ISRC1DEC2"),
1121 ARIZONA_MUX_ROUTES("ISRC1DEC3", "ISRC1DEC3"),
1122 ARIZONA_MUX_ROUTES("ISRC1DEC4", "ISRC1DEC4"),
1123
1124 ARIZONA_MUX_ROUTES("ISRC2INT1", "ISRC2INT1"),
1125 ARIZONA_MUX_ROUTES("ISRC2INT2", "ISRC2INT2"),
1126
1127 ARIZONA_MUX_ROUTES("ISRC2DEC1", "ISRC2DEC1"),
1128 ARIZONA_MUX_ROUTES("ISRC2DEC2", "ISRC2DEC2"),
1129
1130 { "AEC1 Loopback", "HPOUTL", "OUT1L" },
1131 { "AEC1 Loopback", "HPOUTR", "OUT1R" },
1132 { "AEC2 Loopback", "HPOUTL", "OUT1L" },
1133 { "AEC2 Loopback", "HPOUTR", "OUT1R" },
1134 { "HPOUTL", NULL, "OUT1L" },
1135 { "HPOUTR", NULL, "OUT1R" },
1136
1137 { "AEC1 Loopback", "LINEOUTL", "OUT2L" },
1138 { "AEC1 Loopback", "LINEOUTR", "OUT2R" },
1139 { "AEC2 Loopback", "LINEOUTL", "OUT2L" },
1140 { "AEC2 Loopback", "LINEOUTR", "OUT2R" },
1141 { "LINEOUTL", NULL, "OUT2L" },
1142 { "LINEOUTR", NULL, "OUT2R" },
1143
1144 { "AEC1 Loopback", "EPOUT", "OUT3" },
1145 { "AEC2 Loopback", "EPOUT", "OUT3" },
1146 { "EPOUT", NULL, "OUT3" },
1147
1148 { "AEC1 Loopback", "SPKOUTL", "OUT4L" },
1149 { "AEC2 Loopback", "SPKOUTL", "OUT4L" },
1150 { "SPKOUTLN", NULL, "OUT4L" },
1151 { "SPKOUTLP", NULL, "OUT4L" },
1152
1153 { "AEC1 Loopback", "SPKOUTR", "OUT4R" },
1154 { "AEC2 Loopback", "SPKOUTR", "OUT4R" },
1155 { "SPKOUTRN", NULL, "OUT4R" },
1156 { "SPKOUTRP", NULL, "OUT4R" },
1157
1158 { "SPDIF", NULL, "SPD1" },
1159
1160 { "AEC1 Loopback", "SPKDATL", "OUT5L" },
1161 { "AEC1 Loopback", "SPKDATR", "OUT5R" },
1162 { "AEC2 Loopback", "SPKDATL", "OUT5L" },
1163 { "AEC2 Loopback", "SPKDATR", "OUT5R" },
1164 { "SPKDATL", NULL, "OUT5L" },
1165 { "SPKDATR", NULL, "OUT5R" },
1166
1167 { "MICSUPP", NULL, "SYSCLK" },
1168
1169 { "DRC1 Signal Activity", NULL, "DRC1L" },
1170 { "DRC1 Signal Activity", NULL, "DRC1R" },
1171};
1172
1173#define WM8998_RATES SNDRV_PCM_RATE_8000_192000
1174
1175#define WM8998_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
1176 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
1177
1178static struct snd_soc_dai_driver wm8998_dai[] = {
1179 {
1180 .name = "wm8998-aif1",
1181 .id = 1,
1182 .base = ARIZONA_AIF1_BCLK_CTRL,
1183 .playback = {
1184 .stream_name = "AIF1 Playback",
1185 .channels_min = 1,
1186 .channels_max = 6,
1187 .rates = WM8998_RATES,
1188 .formats = WM8998_FORMATS,
1189 },
1190 .capture = {
1191 .stream_name = "AIF1 Capture",
1192 .channels_min = 1,
1193 .channels_max = 6,
1194 .rates = WM8998_RATES,
1195 .formats = WM8998_FORMATS,
1196 },
1197 .ops = &arizona_dai_ops,
1198 .symmetric_rates = 1,
1199 .symmetric_samplebits = 1,
1200 },
1201 {
1202 .name = "wm8998-aif2",
1203 .id = 2,
1204 .base = ARIZONA_AIF2_BCLK_CTRL,
1205 .playback = {
1206 .stream_name = "AIF2 Playback",
1207 .channels_min = 1,
1208 .channels_max = 6,
1209 .rates = WM8998_RATES,
1210 .formats = WM8998_FORMATS,
1211 },
1212 .capture = {
1213 .stream_name = "AIF2 Capture",
1214 .channels_min = 1,
1215 .channels_max = 6,
1216 .rates = WM8998_RATES,
1217 .formats = WM8998_FORMATS,
1218 },
1219 .ops = &arizona_dai_ops,
1220 .symmetric_rates = 1,
1221 .symmetric_samplebits = 1,
1222 },
1223 {
1224 .name = "wm8998-aif3",
1225 .id = 3,
1226 .base = ARIZONA_AIF3_BCLK_CTRL,
1227 .playback = {
1228 .stream_name = "AIF3 Playback",
1229 .channels_min = 1,
1230 .channels_max = 2,
1231 .rates = WM8998_RATES,
1232 .formats = WM8998_FORMATS,
1233 },
1234 .capture = {
1235 .stream_name = "AIF3 Capture",
1236 .channels_min = 1,
1237 .channels_max = 2,
1238 .rates = WM8998_RATES,
1239 .formats = WM8998_FORMATS,
1240 },
1241 .ops = &arizona_dai_ops,
1242 .symmetric_rates = 1,
1243 .symmetric_samplebits = 1,
1244 },
1245 {
1246 .name = "wm8998-slim1",
1247 .id = 4,
1248 .playback = {
1249 .stream_name = "Slim1 Playback",
1250 .channels_min = 1,
1251 .channels_max = 2,
1252 .rates = WM8998_RATES,
1253 .formats = WM8998_FORMATS,
1254 },
1255 .capture = {
1256 .stream_name = "Slim1 Capture",
1257 .channels_min = 1,
1258 .channels_max = 4,
1259 .rates = WM8998_RATES,
1260 .formats = WM8998_FORMATS,
1261 },
1262 .ops = &arizona_simple_dai_ops,
1263 },
1264 {
1265 .name = "wm8998-slim2",
1266 .id = 5,
1267 .playback = {
1268 .stream_name = "Slim2 Playback",
1269 .channels_min = 1,
1270 .channels_max = 2,
1271 .rates = WM8998_RATES,
1272 .formats = WM8998_FORMATS,
1273 },
1274 .capture = {
1275 .stream_name = "Slim2 Capture",
1276 .channels_min = 1,
1277 .channels_max = 2,
1278 .rates = WM8998_RATES,
1279 .formats = WM8998_FORMATS,
1280 },
1281 .ops = &arizona_simple_dai_ops,
1282 },
1283};
1284
1285static int wm8998_set_fll(struct snd_soc_codec *codec, int fll_id, int source,
1286 unsigned int Fref, unsigned int Fout)
1287{
1288 struct wm8998_priv *wm8998 = snd_soc_codec_get_drvdata(codec);
1289
1290 switch (fll_id) {
1291 case WM8998_FLL1:
1292 return arizona_set_fll(&wm8998->fll[0], source, Fref, Fout);
1293 case WM8998_FLL2:
1294 return arizona_set_fll(&wm8998->fll[1], source, Fref, Fout);
1295 case WM8998_FLL1_REFCLK:
1296 return arizona_set_fll_refclk(&wm8998->fll[0], source, Fref,
1297 Fout);
1298 case WM8998_FLL2_REFCLK:
1299 return arizona_set_fll_refclk(&wm8998->fll[1], source, Fref,
1300 Fout);
1301 default:
1302 return -EINVAL;
1303 }
1304}
1305
1306static int wm8998_codec_probe(struct snd_soc_codec *codec)
1307{
1308 struct wm8998_priv *priv = snd_soc_codec_get_drvdata(codec);
1309 struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
1310
1311 priv->core.arizona->dapm = dapm;
1312
1313 arizona_init_spk(codec);
1314 arizona_init_gpio(codec);
1315
1316 snd_soc_dapm_disable_pin(dapm, "HAPTICS");
1317
1318 return 0;
1319}
1320
1321static int wm8998_codec_remove(struct snd_soc_codec *codec)
1322{
1323 struct wm8998_priv *priv = snd_soc_codec_get_drvdata(codec);
1324
1325 priv->core.arizona->dapm = NULL;
1326
1327 return 0;
1328}
1329
1330#define WM8998_DIG_VU 0x0200
1331
1332static unsigned int wm8998_digital_vu[] = {
1333 ARIZONA_DAC_DIGITAL_VOLUME_1L,
1334 ARIZONA_DAC_DIGITAL_VOLUME_1R,
1335 ARIZONA_DAC_DIGITAL_VOLUME_2L,
1336 ARIZONA_DAC_DIGITAL_VOLUME_2R,
1337 ARIZONA_DAC_DIGITAL_VOLUME_3L,
1338 ARIZONA_DAC_DIGITAL_VOLUME_4L,
1339 ARIZONA_DAC_DIGITAL_VOLUME_4R,
1340 ARIZONA_DAC_DIGITAL_VOLUME_5L,
1341 ARIZONA_DAC_DIGITAL_VOLUME_5R,
1342};
1343
1344static struct regmap *wm8998_get_regmap(struct device *dev)
1345{
1346 struct wm8998_priv *priv = dev_get_drvdata(dev);
1347
1348 return priv->core.arizona->regmap;
1349}
1350
1351static struct snd_soc_codec_driver soc_codec_dev_wm8998 = {
1352 .probe = wm8998_codec_probe,
1353 .remove = wm8998_codec_remove,
1354 .get_regmap = wm8998_get_regmap,
1355
1356 .idle_bias_off = true,
1357
1358 .set_sysclk = arizona_set_sysclk,
1359 .set_pll = wm8998_set_fll,
1360
1361 .controls = wm8998_snd_controls,
1362 .num_controls = ARRAY_SIZE(wm8998_snd_controls),
1363 .dapm_widgets = wm8998_dapm_widgets,
1364 .num_dapm_widgets = ARRAY_SIZE(wm8998_dapm_widgets),
1365 .dapm_routes = wm8998_dapm_routes,
1366 .num_dapm_routes = ARRAY_SIZE(wm8998_dapm_routes),
1367};
1368
1369static int wm8998_probe(struct platform_device *pdev)
1370{
1371 struct arizona *arizona = dev_get_drvdata(pdev->dev.parent);
1372 struct wm8998_priv *wm8998;
1373 int i;
1374
1375 wm8998 = devm_kzalloc(&pdev->dev, sizeof(struct wm8998_priv),
1376 GFP_KERNEL);
1377 if (!wm8998)
1378 return -ENOMEM;
1379 platform_set_drvdata(pdev, wm8998);
1380
1381 wm8998->core.arizona = arizona;
1382 wm8998->core.num_inputs = 3; /* IN1L, IN1R, IN2 */
1383
1384 for (i = 0; i < ARRAY_SIZE(wm8998->fll); i++)
1385 wm8998->fll[i].vco_mult = 1;
1386
1387 arizona_init_fll(arizona, 1, ARIZONA_FLL1_CONTROL_1 - 1,
1388 ARIZONA_IRQ_FLL1_LOCK, ARIZONA_IRQ_FLL1_CLOCK_OK,
1389 &wm8998->fll[0]);
1390 arizona_init_fll(arizona, 2, ARIZONA_FLL2_CONTROL_1 - 1,
1391 ARIZONA_IRQ_FLL2_LOCK, ARIZONA_IRQ_FLL2_CLOCK_OK,
1392 &wm8998->fll[1]);
1393
1394 for (i = 0; i < ARRAY_SIZE(wm8998_dai); i++)
1395 arizona_init_dai(&wm8998->core, i);
1396
1397 /* Latch volume update bits */
1398 for (i = 0; i < ARRAY_SIZE(wm8998_digital_vu); i++)
1399 regmap_update_bits(arizona->regmap, wm8998_digital_vu[i],
1400 WM8998_DIG_VU, WM8998_DIG_VU);
1401
1402 pm_runtime_enable(&pdev->dev);
1403 pm_runtime_idle(&pdev->dev);
1404
1405 return snd_soc_register_codec(&pdev->dev, &soc_codec_dev_wm8998,
1406 wm8998_dai, ARRAY_SIZE(wm8998_dai));
1407}
1408
1409static int wm8998_remove(struct platform_device *pdev)
1410{
1411 snd_soc_unregister_codec(&pdev->dev);
1412 pm_runtime_disable(&pdev->dev);
1413
1414 return 0;
1415}
1416
1417static struct platform_driver wm8998_codec_driver = {
1418 .driver = {
1419 .name = "wm8998-codec",
1420 },
1421 .probe = wm8998_probe,
1422 .remove = wm8998_remove,
1423};
1424
1425module_platform_driver(wm8998_codec_driver);
1426
1427MODULE_DESCRIPTION("ASoC WM8998 driver");
1428MODULE_AUTHOR("Richard Fitzgerald <rf@opensource.wolfsonmicro.com>");
1429MODULE_LICENSE("GPL v2");
1430MODULE_ALIAS("platform:wm8998-codec");
diff --git a/sound/soc/codecs/wm8998.h b/sound/soc/codecs/wm8998.h
new file mode 100644
index 000000000000..1e8647252162
--- /dev/null
+++ b/sound/soc/codecs/wm8998.h
@@ -0,0 +1,23 @@
1/*
2 * wm8998.h -- ALSA SoC Audio driver for WM8998 codecs
3 *
4 * Copyright 2015 Cirrus Logic, Inc.
5 *
6 * Author: Richard Fitzgerald <rf@opensource.wolfsonmicro.com>
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#ifndef _WM8998_H
14#define _WM8998_H
15
16#include "arizona.h"
17
18#define WM8998_FLL1 1
19#define WM8998_FLL2 2
20#define WM8998_FLL1_REFCLK 3
21#define WM8998_FLL2_REFCLK 4
22
23#endif
diff --git a/sound/soc/davinci/davinci-mcasp.c b/sound/soc/davinci/davinci-mcasp.c
index 7d45d98a861f..4495a40a9468 100644
--- a/sound/soc/davinci/davinci-mcasp.c
+++ b/sound/soc/davinci/davinci-mcasp.c
@@ -80,12 +80,13 @@ struct davinci_mcasp {
80 80
81 /* McASP specific data */ 81 /* McASP specific data */
82 int tdm_slots; 82 int tdm_slots;
83 u32 tdm_mask[2];
84 int slot_width;
83 u8 op_mode; 85 u8 op_mode;
84 u8 num_serializer; 86 u8 num_serializer;
85 u8 *serial_dir; 87 u8 *serial_dir;
86 u8 version; 88 u8 version;
87 u8 bclk_div; 89 u8 bclk_div;
88 u16 bclk_lrclk_ratio;
89 int streams; 90 int streams;
90 u32 irq_request[2]; 91 u32 irq_request[2];
91 int dma_request[2]; 92 int dma_request[2];
@@ -556,8 +557,21 @@ static int __davinci_mcasp_set_clkdiv(struct snd_soc_dai *dai, int div_id,
556 mcasp->bclk_div = div; 557 mcasp->bclk_div = div;
557 break; 558 break;
558 559
559 case 2: /* BCLK/LRCLK ratio */ 560 case 2: /*
560 mcasp->bclk_lrclk_ratio = div; 561 * BCLK/LRCLK ratio descries how many bit-clock cycles
562 * fit into one frame. The clock ratio is given for a
563 * full period of data (for I2S format both left and
564 * right channels), so it has to be divided by number
565 * of tdm-slots (for I2S - divided by 2).
566 * Instead of storing this ratio, we calculate a new
567 * tdm_slot width by dividing the the ratio by the
568 * number of configured tdm slots.
569 */
570 mcasp->slot_width = div / mcasp->tdm_slots;
571 if (div % mcasp->tdm_slots)
572 dev_warn(mcasp->dev,
573 "%s(): BCLK/LRCLK %d is not divisible by %d tdm slots",
574 __func__, div, mcasp->tdm_slots);
561 break; 575 break;
562 576
563 default: 577 default:
@@ -596,12 +610,92 @@ static int davinci_mcasp_set_sysclk(struct snd_soc_dai *dai, int clk_id,
596 return 0; 610 return 0;
597} 611}
598 612
613/* All serializers must have equal number of channels */
614static int davinci_mcasp_ch_constraint(struct davinci_mcasp *mcasp, int stream,
615 int serializers)
616{
617 struct snd_pcm_hw_constraint_list *cl = &mcasp->chconstr[stream];
618 unsigned int *list = (unsigned int *) cl->list;
619 int slots = mcasp->tdm_slots;
620 int i, count = 0;
621
622 if (mcasp->tdm_mask[stream])
623 slots = hweight32(mcasp->tdm_mask[stream]);
624
625 for (i = 2; i <= slots; i++)
626 list[count++] = i;
627
628 for (i = 2; i <= serializers; i++)
629 list[count++] = i*slots;
630
631 cl->count = count;
632
633 return 0;
634}
635
636static int davinci_mcasp_set_ch_constraints(struct davinci_mcasp *mcasp)
637{
638 int rx_serializers = 0, tx_serializers = 0, ret, i;
639
640 for (i = 0; i < mcasp->num_serializer; i++)
641 if (mcasp->serial_dir[i] == TX_MODE)
642 tx_serializers++;
643 else if (mcasp->serial_dir[i] == RX_MODE)
644 rx_serializers++;
645
646 ret = davinci_mcasp_ch_constraint(mcasp, SNDRV_PCM_STREAM_PLAYBACK,
647 tx_serializers);
648 if (ret)
649 return ret;
650
651 ret = davinci_mcasp_ch_constraint(mcasp, SNDRV_PCM_STREAM_CAPTURE,
652 rx_serializers);
653
654 return ret;
655}
656
657
658static int davinci_mcasp_set_tdm_slot(struct snd_soc_dai *dai,
659 unsigned int tx_mask,
660 unsigned int rx_mask,
661 int slots, int slot_width)
662{
663 struct davinci_mcasp *mcasp = snd_soc_dai_get_drvdata(dai);
664
665 dev_dbg(mcasp->dev,
666 "%s() tx_mask 0x%08x rx_mask 0x%08x slots %d width %d\n",
667 __func__, tx_mask, rx_mask, slots, slot_width);
668
669 if (tx_mask >= (1<<slots) || rx_mask >= (1<<slots)) {
670 dev_err(mcasp->dev,
671 "Bad tdm mask tx: 0x%08x rx: 0x%08x slots %d\n",
672 tx_mask, rx_mask, slots);
673 return -EINVAL;
674 }
675
676 if (slot_width &&
677 (slot_width < 8 || slot_width > 32 || slot_width % 4 != 0)) {
678 dev_err(mcasp->dev, "%s: Unsupported slot_width %d\n",
679 __func__, slot_width);
680 return -EINVAL;
681 }
682
683 mcasp->tdm_slots = slots;
684 mcasp->tdm_mask[SNDRV_PCM_STREAM_PLAYBACK] = rx_mask;
685 mcasp->tdm_mask[SNDRV_PCM_STREAM_CAPTURE] = tx_mask;
686 mcasp->slot_width = slot_width;
687
688 return davinci_mcasp_set_ch_constraints(mcasp);
689}
690
599static int davinci_config_channel_size(struct davinci_mcasp *mcasp, 691static int davinci_config_channel_size(struct davinci_mcasp *mcasp,
600 int word_length) 692 int sample_width)
601{ 693{
602 u32 fmt; 694 u32 fmt;
603 u32 tx_rotate = (word_length / 4) & 0x7; 695 u32 tx_rotate = (sample_width / 4) & 0x7;
604 u32 mask = (1ULL << word_length) - 1; 696 u32 mask = (1ULL << sample_width) - 1;
697 u32 slot_width = sample_width;
698
605 /* 699 /*
606 * For captured data we should not rotate, inversion and masking is 700 * For captured data we should not rotate, inversion and masking is
607 * enoguh to get the data to the right position: 701 * enoguh to get the data to the right position:
@@ -614,28 +708,23 @@ static int davinci_config_channel_size(struct davinci_mcasp *mcasp,
614 u32 rx_rotate = 0; 708 u32 rx_rotate = 0;
615 709
616 /* 710 /*
617 * if s BCLK-to-LRCLK ratio has been configured via the set_clkdiv() 711 * Setting the tdm slot width either with set_clkdiv() or
618 * callback, take it into account here. That allows us to for example 712 * set_tdm_slot() allows us to for example send 32 bits per
619 * send 32 bits per channel to the codec, while only 16 of them carry 713 * channel to the codec, while only 16 of them carry audio
620 * audio payload. 714 * payload.
621 * The clock ratio is given for a full period of data (for I2S format
622 * both left and right channels), so it has to be divided by number of
623 * tdm-slots (for I2S - divided by 2).
624 */ 715 */
625 if (mcasp->bclk_lrclk_ratio) { 716 if (mcasp->slot_width) {
626 u32 slot_length = mcasp->bclk_lrclk_ratio / mcasp->tdm_slots;
627
628 /* 717 /*
629 * When we have more bclk then it is needed for the data, we 718 * When we have more bclk then it is needed for the
630 * need to use the rotation to move the received samples to have 719 * data, we need to use the rotation to move the
631 * correct alignment. 720 * received samples to have correct alignment.
632 */ 721 */
633 rx_rotate = (slot_length - word_length) / 4; 722 slot_width = mcasp->slot_width;
634 word_length = slot_length; 723 rx_rotate = (slot_width - sample_width) / 4;
635 } 724 }
636 725
637 /* mapping of the XSSZ bit-field as described in the datasheet */ 726 /* mapping of the XSSZ bit-field as described in the datasheet */
638 fmt = (word_length >> 1) - 1; 727 fmt = (slot_width >> 1) - 1;
639 728
640 if (mcasp->op_mode != DAVINCI_MCASP_DIT_MODE) { 729 if (mcasp->op_mode != DAVINCI_MCASP_DIT_MODE) {
641 mcasp_mod_bits(mcasp, DAVINCI_MCASP_RXFMT_REG, RXSSZ(fmt), 730 mcasp_mod_bits(mcasp, DAVINCI_MCASP_RXFMT_REG, RXSSZ(fmt),
@@ -776,33 +865,50 @@ static int mcasp_i2s_hw_param(struct davinci_mcasp *mcasp, int stream,
776 865
777 /* 866 /*
778 * If more than one serializer is needed, then use them with 867 * If more than one serializer is needed, then use them with
779 * their specified tdm_slots count. Otherwise, one serializer 868 * all the specified tdm_slots. Otherwise, one serializer can
780 * can cope with the transaction using as many slots as channels 869 * cope with the transaction using just as many slots as there
781 * in the stream, requires channels symmetry 870 * are channels in the stream.
782 */ 871 */
783 active_serializers = (channels + total_slots - 1) / total_slots; 872 if (mcasp->tdm_mask[stream]) {
784 if (active_serializers == 1) 873 active_slots = hweight32(mcasp->tdm_mask[stream]);
785 active_slots = channels; 874 active_serializers = (channels + active_slots - 1) /
786 else 875 active_slots;
787 active_slots = total_slots; 876 if (active_serializers == 1) {
788 877 active_slots = channels;
789 for (i = 0; i < active_slots; i++) 878 for (i = 0; i < total_slots; i++) {
790 mask |= (1 << i); 879 if ((1 << i) & mcasp->tdm_mask[stream]) {
880 mask |= (1 << i);
881 if (--active_slots <= 0)
882 break;
883 }
884 }
885 }
886 } else {
887 active_serializers = (channels + total_slots - 1) / total_slots;
888 if (active_serializers == 1)
889 active_slots = channels;
890 else
891 active_slots = total_slots;
791 892
893 for (i = 0; i < active_slots; i++)
894 mask |= (1 << i);
895 }
792 mcasp_clr_bits(mcasp, DAVINCI_MCASP_ACLKXCTL_REG, TX_ASYNC); 896 mcasp_clr_bits(mcasp, DAVINCI_MCASP_ACLKXCTL_REG, TX_ASYNC);
793 897
794 if (!mcasp->dat_port) 898 if (!mcasp->dat_port)
795 busel = TXSEL; 899 busel = TXSEL;
796 900
797 mcasp_set_reg(mcasp, DAVINCI_MCASP_TXTDM_REG, mask); 901 if (stream == SNDRV_PCM_STREAM_PLAYBACK) {
798 mcasp_set_bits(mcasp, DAVINCI_MCASP_TXFMT_REG, busel | TXORD); 902 mcasp_set_reg(mcasp, DAVINCI_MCASP_TXTDM_REG, mask);
799 mcasp_mod_bits(mcasp, DAVINCI_MCASP_TXFMCTL_REG, 903 mcasp_set_bits(mcasp, DAVINCI_MCASP_TXFMT_REG, busel | TXORD);
800 FSXMOD(total_slots), FSXMOD(0x1FF)); 904 mcasp_mod_bits(mcasp, DAVINCI_MCASP_TXFMCTL_REG,
801 905 FSXMOD(total_slots), FSXMOD(0x1FF));
802 mcasp_set_reg(mcasp, DAVINCI_MCASP_RXTDM_REG, mask); 906 } else if (stream == SNDRV_PCM_STREAM_CAPTURE) {
803 mcasp_set_bits(mcasp, DAVINCI_MCASP_RXFMT_REG, busel | RXORD); 907 mcasp_set_reg(mcasp, DAVINCI_MCASP_RXTDM_REG, mask);
804 mcasp_mod_bits(mcasp, DAVINCI_MCASP_RXFMCTL_REG, 908 mcasp_set_bits(mcasp, DAVINCI_MCASP_RXFMT_REG, busel | RXORD);
805 FSRMOD(total_slots), FSRMOD(0x1FF)); 909 mcasp_mod_bits(mcasp, DAVINCI_MCASP_RXFMCTL_REG,
910 FSRMOD(total_slots), FSRMOD(0x1FF));
911 }
806 912
807 return 0; 913 return 0;
808} 914}
@@ -922,6 +1028,9 @@ static int davinci_mcasp_hw_params(struct snd_pcm_substream *substream,
922 int sbits = params_width(params); 1028 int sbits = params_width(params);
923 int ppm, div; 1029 int ppm, div;
924 1030
1031 if (mcasp->slot_width)
1032 sbits = mcasp->slot_width;
1033
925 div = davinci_mcasp_calc_clk_div(mcasp, rate*sbits*slots, 1034 div = davinci_mcasp_calc_clk_div(mcasp, rate*sbits*slots,
926 &ppm); 1035 &ppm);
927 if (ppm) 1036 if (ppm)
@@ -1027,6 +1136,9 @@ static int davinci_mcasp_hw_rule_rate(struct snd_pcm_hw_params *params,
1027 struct snd_interval range; 1136 struct snd_interval range;
1028 int i; 1137 int i;
1029 1138
1139 if (rd->mcasp->slot_width)
1140 sbits = rd->mcasp->slot_width;
1141
1030 snd_interval_any(&range); 1142 snd_interval_any(&range);
1031 range.empty = 1; 1143 range.empty = 1;
1032 1144
@@ -1069,10 +1181,14 @@ static int davinci_mcasp_hw_rule_format(struct snd_pcm_hw_params *params,
1069 1181
1070 for (i = 0; i < SNDRV_PCM_FORMAT_LAST; i++) { 1182 for (i = 0; i < SNDRV_PCM_FORMAT_LAST; i++) {
1071 if (snd_mask_test(fmt, i)) { 1183 if (snd_mask_test(fmt, i)) {
1072 uint bclk_freq = snd_pcm_format_width(i)*slots*rate; 1184 uint sbits = snd_pcm_format_width(i);
1073 int ppm; 1185 int ppm;
1074 1186
1075 davinci_mcasp_calc_clk_div(rd->mcasp, bclk_freq, &ppm); 1187 if (rd->mcasp->slot_width)
1188 sbits = rd->mcasp->slot_width;
1189
1190 davinci_mcasp_calc_clk_div(rd->mcasp, sbits*slots*rate,
1191 &ppm);
1076 if (abs(ppm) < DAVINCI_MAX_RATE_ERROR_PPM) { 1192 if (abs(ppm) < DAVINCI_MAX_RATE_ERROR_PPM) {
1077 snd_mask_set(&nfmt, i); 1193 snd_mask_set(&nfmt, i);
1078 count++; 1194 count++;
@@ -1094,6 +1210,10 @@ static int davinci_mcasp_startup(struct snd_pcm_substream *substream,
1094 &mcasp->ruledata[substream->stream]; 1210 &mcasp->ruledata[substream->stream];
1095 u32 max_channels = 0; 1211 u32 max_channels = 0;
1096 int i, dir; 1212 int i, dir;
1213 int tdm_slots = mcasp->tdm_slots;
1214
1215 if (mcasp->tdm_mask[substream->stream])
1216 tdm_slots = hweight32(mcasp->tdm_mask[substream->stream]);
1097 1217
1098 mcasp->substreams[substream->stream] = substream; 1218 mcasp->substreams[substream->stream] = substream;
1099 1219
@@ -1114,7 +1234,7 @@ static int davinci_mcasp_startup(struct snd_pcm_substream *substream,
1114 max_channels++; 1234 max_channels++;
1115 } 1235 }
1116 ruledata->serializers = max_channels; 1236 ruledata->serializers = max_channels;
1117 max_channels *= mcasp->tdm_slots; 1237 max_channels *= tdm_slots;
1118 /* 1238 /*
1119 * If the already active stream has less channels than the calculated 1239 * If the already active stream has less channels than the calculated
1120 * limnit based on the seirializers * tdm_slots, we need to use that as 1240 * limnit based on the seirializers * tdm_slots, we need to use that as
@@ -1124,15 +1244,25 @@ static int davinci_mcasp_startup(struct snd_pcm_substream *substream,
1124 */ 1244 */
1125 if (mcasp->channels && mcasp->channels < max_channels) 1245 if (mcasp->channels && mcasp->channels < max_channels)
1126 max_channels = mcasp->channels; 1246 max_channels = mcasp->channels;
1247 /*
1248 * But we can always allow channels upto the amount of
1249 * the available tdm_slots.
1250 */
1251 if (max_channels < tdm_slots)
1252 max_channels = tdm_slots;
1127 1253
1128 snd_pcm_hw_constraint_minmax(substream->runtime, 1254 snd_pcm_hw_constraint_minmax(substream->runtime,
1129 SNDRV_PCM_HW_PARAM_CHANNELS, 1255 SNDRV_PCM_HW_PARAM_CHANNELS,
1130 2, max_channels); 1256 2, max_channels);
1131 1257
1132 if (mcasp->chconstr[substream->stream].count) 1258 snd_pcm_hw_constraint_list(substream->runtime,
1133 snd_pcm_hw_constraint_list(substream->runtime, 1259 0, SNDRV_PCM_HW_PARAM_CHANNELS,
1134 0, SNDRV_PCM_HW_PARAM_CHANNELS, 1260 &mcasp->chconstr[substream->stream]);
1135 &mcasp->chconstr[substream->stream]); 1261
1262 if (mcasp->slot_width)
1263 snd_pcm_hw_constraint_minmax(substream->runtime,
1264 SNDRV_PCM_HW_PARAM_SAMPLE_BITS,
1265 8, mcasp->slot_width);
1136 1266
1137 /* 1267 /*
1138 * If we rely on implicit BCLK divider setting we should 1268 * If we rely on implicit BCLK divider setting we should
@@ -1184,6 +1314,7 @@ static const struct snd_soc_dai_ops davinci_mcasp_dai_ops = {
1184 .set_fmt = davinci_mcasp_set_dai_fmt, 1314 .set_fmt = davinci_mcasp_set_dai_fmt,
1185 .set_clkdiv = davinci_mcasp_set_clkdiv, 1315 .set_clkdiv = davinci_mcasp_set_clkdiv,
1186 .set_sysclk = davinci_mcasp_set_sysclk, 1316 .set_sysclk = davinci_mcasp_set_sysclk,
1317 .set_tdm_slot = davinci_mcasp_set_tdm_slot,
1187}; 1318};
1188 1319
1189static int davinci_mcasp_dai_probe(struct snd_soc_dai *dai) 1320static int davinci_mcasp_dai_probe(struct snd_soc_dai *dai)
@@ -1514,59 +1645,6 @@ nodata:
1514 return pdata; 1645 return pdata;
1515} 1646}
1516 1647
1517/* All serializers must have equal number of channels */
1518static int davinci_mcasp_ch_constraint(struct davinci_mcasp *mcasp,
1519 struct snd_pcm_hw_constraint_list *cl,
1520 int serializers)
1521{
1522 unsigned int *list;
1523 int i, count = 0;
1524
1525 if (serializers <= 1)
1526 return 0;
1527
1528 list = devm_kzalloc(mcasp->dev, sizeof(unsigned int) *
1529 (mcasp->tdm_slots + serializers - 2),
1530 GFP_KERNEL);
1531 if (!list)
1532 return -ENOMEM;
1533
1534 for (i = 2; i <= mcasp->tdm_slots; i++)
1535 list[count++] = i;
1536
1537 for (i = 2; i <= serializers; i++)
1538 list[count++] = i*mcasp->tdm_slots;
1539
1540 cl->count = count;
1541 cl->list = list;
1542
1543 return 0;
1544}
1545
1546
1547static int davinci_mcasp_init_ch_constraints(struct davinci_mcasp *mcasp)
1548{
1549 int rx_serializers = 0, tx_serializers = 0, ret, i;
1550
1551 for (i = 0; i < mcasp->num_serializer; i++)
1552 if (mcasp->serial_dir[i] == TX_MODE)
1553 tx_serializers++;
1554 else if (mcasp->serial_dir[i] == RX_MODE)
1555 rx_serializers++;
1556
1557 ret = davinci_mcasp_ch_constraint(mcasp, &mcasp->chconstr[
1558 SNDRV_PCM_STREAM_PLAYBACK],
1559 tx_serializers);
1560 if (ret)
1561 return ret;
1562
1563 ret = davinci_mcasp_ch_constraint(mcasp, &mcasp->chconstr[
1564 SNDRV_PCM_STREAM_CAPTURE],
1565 rx_serializers);
1566
1567 return ret;
1568}
1569
1570enum { 1648enum {
1571 PCM_EDMA, 1649 PCM_EDMA,
1572 PCM_SDMA, 1650 PCM_SDMA,
@@ -1783,7 +1861,28 @@ static int davinci_mcasp_probe(struct platform_device *pdev)
1783 mcasp->fifo_base = DAVINCI_MCASP_V3_AFIFO_BASE; 1861 mcasp->fifo_base = DAVINCI_MCASP_V3_AFIFO_BASE;
1784 } 1862 }
1785 1863
1786 ret = davinci_mcasp_init_ch_constraints(mcasp); 1864 /* Allocate memory for long enough list for all possible
1865 * scenarios. Maximum number tdm slots is 32 and there cannot
1866 * be more serializers than given in the configuration. The
1867 * serializer directions could be taken into account, but it
1868 * would make code much more complex and save only couple of
1869 * bytes.
1870 */
1871 mcasp->chconstr[SNDRV_PCM_STREAM_PLAYBACK].list =
1872 devm_kzalloc(mcasp->dev, sizeof(unsigned int) *
1873 (32 + mcasp->num_serializer - 2),
1874 GFP_KERNEL);
1875
1876 mcasp->chconstr[SNDRV_PCM_STREAM_CAPTURE].list =
1877 devm_kzalloc(mcasp->dev, sizeof(unsigned int) *
1878 (32 + mcasp->num_serializer - 2),
1879 GFP_KERNEL);
1880
1881 if (!mcasp->chconstr[SNDRV_PCM_STREAM_PLAYBACK].list ||
1882 !mcasp->chconstr[SNDRV_PCM_STREAM_CAPTURE].list)
1883 return -ENOMEM;
1884
1885 ret = davinci_mcasp_set_ch_constraints(mcasp);
1787 if (ret) 1886 if (ret)
1788 goto err; 1887 goto err;
1789 1888
diff --git a/sound/soc/dwc/designware_i2s.c b/sound/soc/dwc/designware_i2s.c
index ba34252b7bba..6e6a70c5c2bd 100644
--- a/sound/soc/dwc/designware_i2s.c
+++ b/sound/soc/dwc/designware_i2s.c
@@ -282,23 +282,25 @@ static int dw_i2s_hw_params(struct snd_pcm_substream *substream,
282 282
283 config->sample_rate = params_rate(params); 283 config->sample_rate = params_rate(params);
284 284
285 if (dev->i2s_clk_cfg) { 285 if (dev->capability & DW_I2S_MASTER) {
286 ret = dev->i2s_clk_cfg(config); 286 if (dev->i2s_clk_cfg) {
287 if (ret < 0) { 287 ret = dev->i2s_clk_cfg(config);
288 dev_err(dev->dev, "runtime audio clk config fail\n"); 288 if (ret < 0) {
289 return ret; 289 dev_err(dev->dev, "runtime audio clk config fail\n");
290 } 290 return ret;
291 } else { 291 }
292 u32 bitclk = config->sample_rate * config->data_width * 2; 292 } else {
293 293 u32 bitclk = config->sample_rate *
294 ret = clk_set_rate(dev->clk, bitclk); 294 config->data_width * 2;
295 if (ret) { 295
296 dev_err(dev->dev, "Can't set I2S clock rate: %d\n", 296 ret = clk_set_rate(dev->clk, bitclk);
297 ret); 297 if (ret) {
298 return ret; 298 dev_err(dev->dev, "Can't set I2S clock rate: %d\n",
299 ret);
300 return ret;
301 }
299 } 302 }
300 } 303 }
301
302 return 0; 304 return 0;
303} 305}
304 306
@@ -348,12 +350,43 @@ static int dw_i2s_trigger(struct snd_pcm_substream *substream,
348 return ret; 350 return ret;
349} 351}
350 352
353static int dw_i2s_set_fmt(struct snd_soc_dai *cpu_dai, unsigned int fmt)
354{
355 struct dw_i2s_dev *dev = snd_soc_dai_get_drvdata(cpu_dai);
356 int ret = 0;
357
358 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
359 case SND_SOC_DAIFMT_CBM_CFM:
360 if (dev->capability & DW_I2S_SLAVE)
361 ret = 0;
362 else
363 ret = -EINVAL;
364 break;
365 case SND_SOC_DAIFMT_CBS_CFS:
366 if (dev->capability & DW_I2S_MASTER)
367 ret = 0;
368 else
369 ret = -EINVAL;
370 break;
371 case SND_SOC_DAIFMT_CBM_CFS:
372 case SND_SOC_DAIFMT_CBS_CFM:
373 ret = -EINVAL;
374 break;
375 default:
376 dev_dbg(dev->dev, "dwc : Invalid master/slave format\n");
377 ret = -EINVAL;
378 break;
379 }
380 return ret;
381}
382
351static struct snd_soc_dai_ops dw_i2s_dai_ops = { 383static struct snd_soc_dai_ops dw_i2s_dai_ops = {
352 .startup = dw_i2s_startup, 384 .startup = dw_i2s_startup,
353 .shutdown = dw_i2s_shutdown, 385 .shutdown = dw_i2s_shutdown,
354 .hw_params = dw_i2s_hw_params, 386 .hw_params = dw_i2s_hw_params,
355 .prepare = dw_i2s_prepare, 387 .prepare = dw_i2s_prepare,
356 .trigger = dw_i2s_trigger, 388 .trigger = dw_i2s_trigger,
389 .set_fmt = dw_i2s_set_fmt,
357}; 390};
358 391
359static const struct snd_soc_component_driver dw_i2s_component = { 392static const struct snd_soc_component_driver dw_i2s_component = {
@@ -366,7 +399,8 @@ static int dw_i2s_suspend(struct snd_soc_dai *dai)
366{ 399{
367 struct dw_i2s_dev *dev = snd_soc_dai_get_drvdata(dai); 400 struct dw_i2s_dev *dev = snd_soc_dai_get_drvdata(dai);
368 401
369 clk_disable(dev->clk); 402 if (dev->capability & DW_I2S_MASTER)
403 clk_disable(dev->clk);
370 return 0; 404 return 0;
371} 405}
372 406
@@ -374,7 +408,8 @@ static int dw_i2s_resume(struct snd_soc_dai *dai)
374{ 408{
375 struct dw_i2s_dev *dev = snd_soc_dai_get_drvdata(dai); 409 struct dw_i2s_dev *dev = snd_soc_dai_get_drvdata(dai);
376 410
377 clk_enable(dev->clk); 411 if (dev->capability & DW_I2S_MASTER)
412 clk_enable(dev->clk);
378 return 0; 413 return 0;
379} 414}
380 415
@@ -452,6 +487,14 @@ static int dw_configure_dai(struct dw_i2s_dev *dev,
452 dw_i2s_dai->capture.rates = rates; 487 dw_i2s_dai->capture.rates = rates;
453 } 488 }
454 489
490 if (COMP1_MODE_EN(comp1)) {
491 dev_dbg(dev->dev, "designware: i2s master mode supported\n");
492 dev->capability |= DW_I2S_MASTER;
493 } else {
494 dev_dbg(dev->dev, "designware: i2s slave mode supported\n");
495 dev->capability |= DW_I2S_SLAVE;
496 }
497
455 return 0; 498 return 0;
456} 499}
457 500
@@ -538,6 +581,7 @@ static int dw_i2s_probe(struct platform_device *pdev)
538 struct resource *res; 581 struct resource *res;
539 int ret; 582 int ret;
540 struct snd_soc_dai_driver *dw_i2s_dai; 583 struct snd_soc_dai_driver *dw_i2s_dai;
584 const char *clk_id;
541 585
542 dev = devm_kzalloc(&pdev->dev, sizeof(*dev), GFP_KERNEL); 586 dev = devm_kzalloc(&pdev->dev, sizeof(*dev), GFP_KERNEL);
543 if (!dev) { 587 if (!dev) {
@@ -559,32 +603,35 @@ static int dw_i2s_probe(struct platform_device *pdev)
559 return PTR_ERR(dev->i2s_base); 603 return PTR_ERR(dev->i2s_base);
560 604
561 dev->dev = &pdev->dev; 605 dev->dev = &pdev->dev;
606
562 if (pdata) { 607 if (pdata) {
608 dev->capability = pdata->cap;
609 clk_id = NULL;
563 ret = dw_configure_dai_by_pd(dev, dw_i2s_dai, res, pdata); 610 ret = dw_configure_dai_by_pd(dev, dw_i2s_dai, res, pdata);
564 if (ret < 0) 611 } else {
565 return ret; 612 clk_id = "i2sclk";
613 ret = dw_configure_dai_by_dt(dev, dw_i2s_dai, res);
614 }
615 if (ret < 0)
616 return ret;
566 617
567 dev->capability = pdata->cap; 618 if (dev->capability & DW_I2S_MASTER) {
568 dev->i2s_clk_cfg = pdata->i2s_clk_cfg; 619 if (pdata) {
569 if (!dev->i2s_clk_cfg) { 620 dev->i2s_clk_cfg = pdata->i2s_clk_cfg;
570 dev_err(&pdev->dev, "no clock configure method\n"); 621 if (!dev->i2s_clk_cfg) {
571 return -ENODEV; 622 dev_err(&pdev->dev, "no clock configure method\n");
623 return -ENODEV;
624 }
572 } 625 }
626 dev->clk = devm_clk_get(&pdev->dev, clk_id);
573 627
574 dev->clk = devm_clk_get(&pdev->dev, NULL); 628 if (IS_ERR(dev->clk))
575 } else { 629 return PTR_ERR(dev->clk);
576 ret = dw_configure_dai_by_dt(dev, dw_i2s_dai, res); 630
631 ret = clk_prepare_enable(dev->clk);
577 if (ret < 0) 632 if (ret < 0)
578 return ret; 633 return ret;
579
580 dev->clk = devm_clk_get(&pdev->dev, "i2sclk");
581 } 634 }
582 if (IS_ERR(dev->clk))
583 return PTR_ERR(dev->clk);
584
585 ret = clk_prepare_enable(dev->clk);
586 if (ret < 0)
587 return ret;
588 635
589 dev_set_drvdata(&pdev->dev, dev); 636 dev_set_drvdata(&pdev->dev, dev);
590 ret = devm_snd_soc_register_component(&pdev->dev, &dw_i2s_component, 637 ret = devm_snd_soc_register_component(&pdev->dev, &dw_i2s_component,
@@ -606,7 +653,8 @@ static int dw_i2s_probe(struct platform_device *pdev)
606 return 0; 653 return 0;
607 654
608err_clk_disable: 655err_clk_disable:
609 clk_disable_unprepare(dev->clk); 656 if (dev->capability & DW_I2S_MASTER)
657 clk_disable_unprepare(dev->clk);
610 return ret; 658 return ret;
611} 659}
612 660
@@ -614,7 +662,8 @@ static int dw_i2s_remove(struct platform_device *pdev)
614{ 662{
615 struct dw_i2s_dev *dev = dev_get_drvdata(&pdev->dev); 663 struct dw_i2s_dev *dev = dev_get_drvdata(&pdev->dev);
616 664
617 clk_disable_unprepare(dev->clk); 665 if (dev->capability & DW_I2S_MASTER)
666 clk_disable_unprepare(dev->clk);
618 667
619 return 0; 668 return 0;
620} 669}
diff --git a/sound/soc/fsl/fsl-asoc-card.c b/sound/soc/fsl/fsl-asoc-card.c
index 96f55ae75c71..1b05d1c5d9fd 100644
--- a/sound/soc/fsl/fsl-asoc-card.c
+++ b/sound/soc/fsl/fsl-asoc-card.c
@@ -14,6 +14,9 @@
14#include <linux/i2c.h> 14#include <linux/i2c.h>
15#include <linux/module.h> 15#include <linux/module.h>
16#include <linux/of_platform.h> 16#include <linux/of_platform.h>
17#if IS_ENABLED(CONFIG_SND_AC97_CODEC)
18#include <sound/ac97_codec.h>
19#endif
17#include <sound/pcm_params.h> 20#include <sound/pcm_params.h>
18#include <sound/soc.h> 21#include <sound/soc.h>
19 22
@@ -115,6 +118,11 @@ static const struct snd_soc_dapm_widget fsl_asoc_card_dapm_widgets[] = {
115 SND_SOC_DAPM_MIC("DMIC", NULL), 118 SND_SOC_DAPM_MIC("DMIC", NULL),
116}; 119};
117 120
121static bool fsl_asoc_card_is_ac97(struct fsl_asoc_card_priv *priv)
122{
123 return priv->dai_fmt == SND_SOC_DAIFMT_AC97;
124}
125
118static int fsl_asoc_card_hw_params(struct snd_pcm_substream *substream, 126static int fsl_asoc_card_hw_params(struct snd_pcm_substream *substream,
119 struct snd_pcm_hw_params *params) 127 struct snd_pcm_hw_params *params)
120{ 128{
@@ -133,7 +141,9 @@ static int fsl_asoc_card_hw_params(struct snd_pcm_substream *substream,
133 * set_bias_level(), bypass the remaining settings in hw_params(). 141 * set_bias_level(), bypass the remaining settings in hw_params().
134 * Note: (dai_fmt & CBM_CFM) includes CBM_CFM and CBM_CFS. 142 * Note: (dai_fmt & CBM_CFM) includes CBM_CFM and CBM_CFS.
135 */ 143 */
136 if (priv->card.set_bias_level && priv->dai_fmt & SND_SOC_DAIFMT_CBM_CFM) 144 if ((priv->card.set_bias_level &&
145 priv->dai_fmt & SND_SOC_DAIFMT_CBM_CFM) ||
146 fsl_asoc_card_is_ac97(priv))
137 return 0; 147 return 0;
138 148
139 /* Specific configurations of DAIs starts from here */ 149 /* Specific configurations of DAIs starts from here */
@@ -300,7 +310,7 @@ static int fsl_asoc_card_audmux_init(struct device_node *np,
300 ext_port--; 310 ext_port--;
301 311
302 /* 312 /*
303 * Use asynchronous mode (6 wires) for all cases. 313 * Use asynchronous mode (6 wires) for all cases except AC97.
304 * If only 4 wires are needed, just set SSI into 314 * If only 4 wires are needed, just set SSI into
305 * synchronous mode and enable 4 PADs in IOMUX. 315 * synchronous mode and enable 4 PADs in IOMUX.
306 */ 316 */
@@ -346,15 +356,30 @@ static int fsl_asoc_card_audmux_init(struct device_node *np,
346 IMX_AUDMUX_V2_PTCR_TCLKDIR; 356 IMX_AUDMUX_V2_PTCR_TCLKDIR;
347 break; 357 break;
348 default: 358 default:
349 return -EINVAL; 359 if (!fsl_asoc_card_is_ac97(priv))
360 return -EINVAL;
361 }
362
363 if (fsl_asoc_card_is_ac97(priv)) {
364 int_ptcr = IMX_AUDMUX_V2_PTCR_SYN |
365 IMX_AUDMUX_V2_PTCR_TCSEL(ext_port) |
366 IMX_AUDMUX_V2_PTCR_TCLKDIR;
367 ext_ptcr = IMX_AUDMUX_V2_PTCR_SYN |
368 IMX_AUDMUX_V2_PTCR_TFSEL(int_port) |
369 IMX_AUDMUX_V2_PTCR_TFSDIR;
350 } 370 }
351 371
352 /* Asynchronous mode can not be set along with RCLKDIR */ 372 /* Asynchronous mode can not be set along with RCLKDIR */
353 ret = imx_audmux_v2_configure_port(int_port, 0, 373 if (!fsl_asoc_card_is_ac97(priv)) {
354 IMX_AUDMUX_V2_PDCR_RXDSEL(ext_port)); 374 unsigned int pdcr =
355 if (ret) { 375 IMX_AUDMUX_V2_PDCR_RXDSEL(ext_port);
356 dev_err(dev, "audmux internal port setup failed\n"); 376
357 return ret; 377 ret = imx_audmux_v2_configure_port(int_port, 0,
378 pdcr);
379 if (ret) {
380 dev_err(dev, "audmux internal port setup failed\n");
381 return ret;
382 }
358 } 383 }
359 384
360 ret = imx_audmux_v2_configure_port(int_port, int_ptcr, 385 ret = imx_audmux_v2_configure_port(int_port, int_ptcr,
@@ -364,11 +389,16 @@ static int fsl_asoc_card_audmux_init(struct device_node *np,
364 return ret; 389 return ret;
365 } 390 }
366 391
367 ret = imx_audmux_v2_configure_port(ext_port, 0, 392 if (!fsl_asoc_card_is_ac97(priv)) {
368 IMX_AUDMUX_V2_PDCR_RXDSEL(int_port)); 393 unsigned int pdcr =
369 if (ret) { 394 IMX_AUDMUX_V2_PDCR_RXDSEL(int_port);
370 dev_err(dev, "audmux external port setup failed\n"); 395
371 return ret; 396 ret = imx_audmux_v2_configure_port(ext_port, 0,
397 pdcr);
398 if (ret) {
399 dev_err(dev, "audmux external port setup failed\n");
400 return ret;
401 }
372 } 402 }
373 403
374 ret = imx_audmux_v2_configure_port(ext_port, ext_ptcr, 404 ret = imx_audmux_v2_configure_port(ext_port, ext_ptcr,
@@ -389,6 +419,23 @@ static int fsl_asoc_card_late_probe(struct snd_soc_card *card)
389 struct device *dev = card->dev; 419 struct device *dev = card->dev;
390 int ret; 420 int ret;
391 421
422 if (fsl_asoc_card_is_ac97(priv)) {
423#if IS_ENABLED(CONFIG_SND_AC97_CODEC)
424 struct snd_soc_codec *codec = card->rtd[0].codec;
425 struct snd_ac97 *ac97 = snd_soc_codec_get_drvdata(codec);
426
427 /*
428 * Use slots 3/4 for S/PDIF so SSI won't try to enable
429 * other slots and send some samples there
430 * due to SLOTREQ bits for S/PDIF received from codec
431 */
432 snd_ac97_update_bits(ac97, AC97_EXTENDED_STATUS,
433 AC97_EA_SPSA_SLOT_MASK, AC97_EA_SPSA_3_4);
434#endif
435
436 return 0;
437 }
438
392 ret = snd_soc_dai_set_sysclk(codec_dai, codec_priv->mclk_id, 439 ret = snd_soc_dai_set_sysclk(codec_dai, codec_priv->mclk_id,
393 codec_priv->mclk_freq, SND_SOC_CLOCK_IN); 440 codec_priv->mclk_freq, SND_SOC_CLOCK_IN);
394 if (ret) { 441 if (ret) {
@@ -407,7 +454,6 @@ static int fsl_asoc_card_probe(struct platform_device *pdev)
407 struct platform_device *cpu_pdev; 454 struct platform_device *cpu_pdev;
408 struct fsl_asoc_card_priv *priv; 455 struct fsl_asoc_card_priv *priv;
409 struct i2c_client *codec_dev; 456 struct i2c_client *codec_dev;
410 struct clk *codec_clk;
411 const char *codec_dai_name; 457 const char *codec_dai_name;
412 u32 width; 458 u32 width;
413 int ret; 459 int ret;
@@ -420,9 +466,8 @@ static int fsl_asoc_card_probe(struct platform_device *pdev)
420 /* Give a chance to old DT binding */ 466 /* Give a chance to old DT binding */
421 if (!cpu_np) 467 if (!cpu_np)
422 cpu_np = of_parse_phandle(np, "ssi-controller", 0); 468 cpu_np = of_parse_phandle(np, "ssi-controller", 0);
423 codec_np = of_parse_phandle(np, "audio-codec", 0); 469 if (!cpu_np) {
424 if (!cpu_np || !codec_np) { 470 dev_err(&pdev->dev, "CPU phandle missing or invalid\n");
425 dev_err(&pdev->dev, "phandle missing or invalid\n");
426 ret = -EINVAL; 471 ret = -EINVAL;
427 goto fail; 472 goto fail;
428 } 473 }
@@ -434,22 +479,24 @@ static int fsl_asoc_card_probe(struct platform_device *pdev)
434 goto fail; 479 goto fail;
435 } 480 }
436 481
437 codec_dev = of_find_i2c_device_by_node(codec_np); 482 codec_np = of_parse_phandle(np, "audio-codec", 0);
438 if (!codec_dev) { 483 if (codec_np)
439 dev_err(&pdev->dev, "failed to find codec platform device\n"); 484 codec_dev = of_find_i2c_device_by_node(codec_np);
440 ret = -EINVAL; 485 else
441 goto fail; 486 codec_dev = NULL;
442 }
443 487
444 asrc_np = of_parse_phandle(np, "audio-asrc", 0); 488 asrc_np = of_parse_phandle(np, "audio-asrc", 0);
445 if (asrc_np) 489 if (asrc_np)
446 asrc_pdev = of_find_device_by_node(asrc_np); 490 asrc_pdev = of_find_device_by_node(asrc_np);
447 491
448 /* Get the MCLK rate only, and leave it controlled by CODEC drivers */ 492 /* Get the MCLK rate only, and leave it controlled by CODEC drivers */
449 codec_clk = clk_get(&codec_dev->dev, NULL); 493 if (codec_dev) {
450 if (!IS_ERR(codec_clk)) { 494 struct clk *codec_clk = clk_get(&codec_dev->dev, NULL);
451 priv->codec_priv.mclk_freq = clk_get_rate(codec_clk); 495
452 clk_put(codec_clk); 496 if (!IS_ERR(codec_clk)) {
497 priv->codec_priv.mclk_freq = clk_get_rate(codec_clk);
498 clk_put(codec_clk);
499 }
453 } 500 }
454 501
455 /* Default sample rate and format, will be updated in hw_params() */ 502 /* Default sample rate and format, will be updated in hw_params() */
@@ -486,12 +533,22 @@ static int fsl_asoc_card_probe(struct platform_device *pdev)
486 priv->codec_priv.fll_id = WM8960_SYSCLK_AUTO; 533 priv->codec_priv.fll_id = WM8960_SYSCLK_AUTO;
487 priv->codec_priv.pll_id = WM8960_SYSCLK_AUTO; 534 priv->codec_priv.pll_id = WM8960_SYSCLK_AUTO;
488 priv->dai_fmt |= SND_SOC_DAIFMT_CBM_CFM; 535 priv->dai_fmt |= SND_SOC_DAIFMT_CBM_CFM;
536 } else if (of_device_is_compatible(np, "fsl,imx-audio-ac97")) {
537 codec_dai_name = "ac97-hifi";
538 priv->card.set_bias_level = NULL;
539 priv->dai_fmt = SND_SOC_DAIFMT_AC97;
489 } else { 540 } else {
490 dev_err(&pdev->dev, "unknown Device Tree compatible\n"); 541 dev_err(&pdev->dev, "unknown Device Tree compatible\n");
491 ret = -EINVAL; 542 ret = -EINVAL;
492 goto asrc_fail; 543 goto asrc_fail;
493 } 544 }
494 545
546 if (!fsl_asoc_card_is_ac97(priv) && !codec_dev) {
547 dev_err(&pdev->dev, "failed to find codec device\n");
548 ret = -EINVAL;
549 goto asrc_fail;
550 }
551
495 /* Common settings for corresponding Freescale CPU DAI driver */ 552 /* Common settings for corresponding Freescale CPU DAI driver */
496 if (strstr(cpu_np->name, "ssi")) { 553 if (strstr(cpu_np->name, "ssi")) {
497 /* Only SSI needs to configure AUDMUX */ 554 /* Only SSI needs to configure AUDMUX */
@@ -508,7 +565,9 @@ static int fsl_asoc_card_probe(struct platform_device *pdev)
508 priv->cpu_priv.sysclk_id[0] = FSL_SAI_CLK_MAST1; 565 priv->cpu_priv.sysclk_id[0] = FSL_SAI_CLK_MAST1;
509 } 566 }
510 567
511 sprintf(priv->name, "%s-audio", codec_dev->name); 568 snprintf(priv->name, sizeof(priv->name), "%s-audio",
569 fsl_asoc_card_is_ac97(priv) ? "ac97" :
570 codec_dev->name);
512 571
513 /* Initialize sound card */ 572 /* Initialize sound card */
514 priv->pdev = pdev; 573 priv->pdev = pdev;
@@ -532,8 +591,26 @@ static int fsl_asoc_card_probe(struct platform_device *pdev)
532 591
533 /* Normal DAI Link */ 592 /* Normal DAI Link */
534 priv->dai_link[0].cpu_of_node = cpu_np; 593 priv->dai_link[0].cpu_of_node = cpu_np;
535 priv->dai_link[0].codec_of_node = codec_np;
536 priv->dai_link[0].codec_dai_name = codec_dai_name; 594 priv->dai_link[0].codec_dai_name = codec_dai_name;
595
596 if (!fsl_asoc_card_is_ac97(priv))
597 priv->dai_link[0].codec_of_node = codec_np;
598 else {
599 u32 idx;
600
601 ret = of_property_read_u32(cpu_np, "cell-index", &idx);
602 if (ret) {
603 dev_err(&pdev->dev,
604 "cannot get CPU index property\n");
605 goto asrc_fail;
606 }
607
608 priv->dai_link[0].codec_name =
609 devm_kasprintf(&pdev->dev, GFP_KERNEL,
610 "ac97-codec.%u",
611 (unsigned int)idx);
612 }
613
537 priv->dai_link[0].platform_of_node = cpu_np; 614 priv->dai_link[0].platform_of_node = cpu_np;
538 priv->dai_link[0].dai_fmt = priv->dai_fmt; 615 priv->dai_link[0].dai_fmt = priv->dai_fmt;
539 priv->card.num_links = 1; 616 priv->card.num_links = 1;
@@ -544,6 +621,8 @@ static int fsl_asoc_card_probe(struct platform_device *pdev)
544 priv->dai_link[1].platform_of_node = asrc_np; 621 priv->dai_link[1].platform_of_node = asrc_np;
545 priv->dai_link[2].codec_dai_name = codec_dai_name; 622 priv->dai_link[2].codec_dai_name = codec_dai_name;
546 priv->dai_link[2].codec_of_node = codec_np; 623 priv->dai_link[2].codec_of_node = codec_np;
624 priv->dai_link[2].codec_name =
625 priv->dai_link[0].codec_name;
547 priv->dai_link[2].cpu_of_node = cpu_np; 626 priv->dai_link[2].cpu_of_node = cpu_np;
548 priv->dai_link[2].dai_fmt = priv->dai_fmt; 627 priv->dai_link[2].dai_fmt = priv->dai_fmt;
549 priv->card.num_links = 3; 628 priv->card.num_links = 3;
@@ -579,20 +658,22 @@ static int fsl_asoc_card_probe(struct platform_device *pdev)
579 658
580asrc_fail: 659asrc_fail:
581 of_node_put(asrc_np); 660 of_node_put(asrc_np);
582fail:
583 of_node_put(codec_np); 661 of_node_put(codec_np);
662fail:
584 of_node_put(cpu_np); 663 of_node_put(cpu_np);
585 664
586 return ret; 665 return ret;
587} 666}
588 667
589static const struct of_device_id fsl_asoc_card_dt_ids[] = { 668static const struct of_device_id fsl_asoc_card_dt_ids[] = {
669 { .compatible = "fsl,imx-audio-ac97", },
590 { .compatible = "fsl,imx-audio-cs42888", }, 670 { .compatible = "fsl,imx-audio-cs42888", },
591 { .compatible = "fsl,imx-audio-sgtl5000", }, 671 { .compatible = "fsl,imx-audio-sgtl5000", },
592 { .compatible = "fsl,imx-audio-wm8962", }, 672 { .compatible = "fsl,imx-audio-wm8962", },
593 { .compatible = "fsl,imx-audio-wm8960", }, 673 { .compatible = "fsl,imx-audio-wm8960", },
594 {} 674 {}
595}; 675};
676MODULE_DEVICE_TABLE(of, fsl_asoc_card_dt_ids);
596 677
597static struct platform_driver fsl_asoc_card_driver = { 678static struct platform_driver fsl_asoc_card_driver = {
598 .probe = fsl_asoc_card_probe, 679 .probe = fsl_asoc_card_probe,
diff --git a/sound/soc/fsl/fsl_esai.c b/sound/soc/fsl/fsl_esai.c
index 837979ea5c92..59f234e51971 100644
--- a/sound/soc/fsl/fsl_esai.c
+++ b/sound/soc/fsl/fsl_esai.c
@@ -652,6 +652,24 @@ static const struct snd_soc_component_driver fsl_esai_component = {
652 .name = "fsl-esai", 652 .name = "fsl-esai",
653}; 653};
654 654
655static const struct reg_default fsl_esai_reg_defaults[] = {
656 {0x8, 0x00000000},
657 {0x10, 0x00000000},
658 {0x18, 0x00000000},
659 {0x98, 0x00000000},
660 {0xd0, 0x00000000},
661 {0xd4, 0x00000000},
662 {0xd8, 0x00000000},
663 {0xdc, 0x00000000},
664 {0xe0, 0x00000000},
665 {0xe4, 0x0000ffff},
666 {0xe8, 0x0000ffff},
667 {0xec, 0x0000ffff},
668 {0xf0, 0x0000ffff},
669 {0xf8, 0x00000000},
670 {0xfc, 0x00000000},
671};
672
655static bool fsl_esai_readable_reg(struct device *dev, unsigned int reg) 673static bool fsl_esai_readable_reg(struct device *dev, unsigned int reg)
656{ 674{
657 switch (reg) { 675 switch (reg) {
@@ -684,6 +702,31 @@ static bool fsl_esai_readable_reg(struct device *dev, unsigned int reg)
684 } 702 }
685} 703}
686 704
705static bool fsl_esai_volatile_reg(struct device *dev, unsigned int reg)
706{
707 switch (reg) {
708 case REG_ESAI_ETDR:
709 case REG_ESAI_ERDR:
710 case REG_ESAI_ESR:
711 case REG_ESAI_TFSR:
712 case REG_ESAI_RFSR:
713 case REG_ESAI_TX0:
714 case REG_ESAI_TX1:
715 case REG_ESAI_TX2:
716 case REG_ESAI_TX3:
717 case REG_ESAI_TX4:
718 case REG_ESAI_TX5:
719 case REG_ESAI_RX0:
720 case REG_ESAI_RX1:
721 case REG_ESAI_RX2:
722 case REG_ESAI_RX3:
723 case REG_ESAI_SAISR:
724 return true;
725 default:
726 return false;
727 }
728}
729
687static bool fsl_esai_writeable_reg(struct device *dev, unsigned int reg) 730static bool fsl_esai_writeable_reg(struct device *dev, unsigned int reg)
688{ 731{
689 switch (reg) { 732 switch (reg) {
@@ -721,8 +764,12 @@ static const struct regmap_config fsl_esai_regmap_config = {
721 .val_bits = 32, 764 .val_bits = 32,
722 765
723 .max_register = REG_ESAI_PCRC, 766 .max_register = REG_ESAI_PCRC,
767 .reg_defaults = fsl_esai_reg_defaults,
768 .num_reg_defaults = ARRAY_SIZE(fsl_esai_reg_defaults),
724 .readable_reg = fsl_esai_readable_reg, 769 .readable_reg = fsl_esai_readable_reg,
770 .volatile_reg = fsl_esai_volatile_reg,
725 .writeable_reg = fsl_esai_writeable_reg, 771 .writeable_reg = fsl_esai_writeable_reg,
772 .cache_type = REGCACHE_RBTREE,
726}; 773};
727 774
728static int fsl_esai_probe(struct platform_device *pdev) 775static int fsl_esai_probe(struct platform_device *pdev)
@@ -853,10 +900,51 @@ static const struct of_device_id fsl_esai_dt_ids[] = {
853}; 900};
854MODULE_DEVICE_TABLE(of, fsl_esai_dt_ids); 901MODULE_DEVICE_TABLE(of, fsl_esai_dt_ids);
855 902
903#ifdef CONFIG_PM_SLEEP
904static int fsl_esai_suspend(struct device *dev)
905{
906 struct fsl_esai *esai = dev_get_drvdata(dev);
907
908 regcache_cache_only(esai->regmap, true);
909 regcache_mark_dirty(esai->regmap);
910
911 return 0;
912}
913
914static int fsl_esai_resume(struct device *dev)
915{
916 struct fsl_esai *esai = dev_get_drvdata(dev);
917 int ret;
918
919 regcache_cache_only(esai->regmap, false);
920
921 /* FIFO reset for safety */
922 regmap_update_bits(esai->regmap, REG_ESAI_TFCR,
923 ESAI_xFCR_xFR, ESAI_xFCR_xFR);
924 regmap_update_bits(esai->regmap, REG_ESAI_RFCR,
925 ESAI_xFCR_xFR, ESAI_xFCR_xFR);
926
927 ret = regcache_sync(esai->regmap);
928 if (ret)
929 return ret;
930
931 /* FIFO reset done */
932 regmap_update_bits(esai->regmap, REG_ESAI_TFCR, ESAI_xFCR_xFR, 0);
933 regmap_update_bits(esai->regmap, REG_ESAI_RFCR, ESAI_xFCR_xFR, 0);
934
935 return 0;
936}
937#endif /* CONFIG_PM_SLEEP */
938
939static const struct dev_pm_ops fsl_esai_pm_ops = {
940 SET_SYSTEM_SLEEP_PM_OPS(fsl_esai_suspend, fsl_esai_resume)
941};
942
856static struct platform_driver fsl_esai_driver = { 943static struct platform_driver fsl_esai_driver = {
857 .probe = fsl_esai_probe, 944 .probe = fsl_esai_probe,
858 .driver = { 945 .driver = {
859 .name = "fsl-esai-dai", 946 .name = "fsl-esai-dai",
947 .pm = &fsl_esai_pm_ops,
860 .of_match_table = fsl_esai_dt_ids, 948 .of_match_table = fsl_esai_dt_ids,
861 }, 949 },
862}; 950};
diff --git a/sound/soc/fsl/fsl_sai.c b/sound/soc/fsl/fsl_sai.c
index a18fd92c4a85..a4435f5e3be9 100644
--- a/sound/soc/fsl/fsl_sai.c
+++ b/sound/soc/fsl/fsl_sai.c
@@ -27,13 +27,13 @@
27#define FSL_SAI_FLAGS (FSL_SAI_CSR_SEIE |\ 27#define FSL_SAI_FLAGS (FSL_SAI_CSR_SEIE |\
28 FSL_SAI_CSR_FEIE) 28 FSL_SAI_CSR_FEIE)
29 29
30static u32 fsl_sai_rates[] = { 30static const unsigned int fsl_sai_rates[] = {
31 8000, 11025, 12000, 16000, 22050, 31 8000, 11025, 12000, 16000, 22050,
32 24000, 32000, 44100, 48000, 64000, 32 24000, 32000, 44100, 48000, 64000,
33 88200, 96000, 176400, 192000 33 88200, 96000, 176400, 192000
34}; 34};
35 35
36static struct snd_pcm_hw_constraint_list fsl_sai_rate_constraints = { 36static const struct snd_pcm_hw_constraint_list fsl_sai_rate_constraints = {
37 .count = ARRAY_SIZE(fsl_sai_rates), 37 .count = ARRAY_SIZE(fsl_sai_rates),
38 .list = fsl_sai_rates, 38 .list = fsl_sai_rates,
39}; 39};
@@ -637,6 +637,8 @@ static bool fsl_sai_readable_reg(struct device *dev, unsigned int reg)
637static bool fsl_sai_volatile_reg(struct device *dev, unsigned int reg) 637static bool fsl_sai_volatile_reg(struct device *dev, unsigned int reg)
638{ 638{
639 switch (reg) { 639 switch (reg) {
640 case FSL_SAI_TCSR:
641 case FSL_SAI_RCSR:
640 case FSL_SAI_TFR: 642 case FSL_SAI_TFR:
641 case FSL_SAI_RFR: 643 case FSL_SAI_RFR:
642 case FSL_SAI_TDR: 644 case FSL_SAI_TDR:
@@ -681,6 +683,7 @@ static const struct regmap_config fsl_sai_regmap_config = {
681 .readable_reg = fsl_sai_readable_reg, 683 .readable_reg = fsl_sai_readable_reg,
682 .volatile_reg = fsl_sai_volatile_reg, 684 .volatile_reg = fsl_sai_volatile_reg,
683 .writeable_reg = fsl_sai_writeable_reg, 685 .writeable_reg = fsl_sai_writeable_reg,
686 .cache_type = REGCACHE_FLAT,
684}; 687};
685 688
686static int fsl_sai_probe(struct platform_device *pdev) 689static int fsl_sai_probe(struct platform_device *pdev)
@@ -801,11 +804,42 @@ static const struct of_device_id fsl_sai_ids[] = {
801 { .compatible = "fsl,imx6sx-sai", }, 804 { .compatible = "fsl,imx6sx-sai", },
802 { /* sentinel */ } 805 { /* sentinel */ }
803}; 806};
807MODULE_DEVICE_TABLE(of, fsl_sai_ids);
808
809#ifdef CONFIG_PM_SLEEP
810static int fsl_sai_suspend(struct device *dev)
811{
812 struct fsl_sai *sai = dev_get_drvdata(dev);
813
814 regcache_cache_only(sai->regmap, true);
815 regcache_mark_dirty(sai->regmap);
816
817 return 0;
818}
819
820static int fsl_sai_resume(struct device *dev)
821{
822 struct fsl_sai *sai = dev_get_drvdata(dev);
823
824 regcache_cache_only(sai->regmap, false);
825 regmap_write(sai->regmap, FSL_SAI_TCSR, FSL_SAI_CSR_SR);
826 regmap_write(sai->regmap, FSL_SAI_RCSR, FSL_SAI_CSR_SR);
827 msleep(1);
828 regmap_write(sai->regmap, FSL_SAI_TCSR, 0);
829 regmap_write(sai->regmap, FSL_SAI_RCSR, 0);
830 return regcache_sync(sai->regmap);
831}
832#endif /* CONFIG_PM_SLEEP */
833
834static const struct dev_pm_ops fsl_sai_pm_ops = {
835 SET_SYSTEM_SLEEP_PM_OPS(fsl_sai_suspend, fsl_sai_resume)
836};
804 837
805static struct platform_driver fsl_sai_driver = { 838static struct platform_driver fsl_sai_driver = {
806 .probe = fsl_sai_probe, 839 .probe = fsl_sai_probe,
807 .driver = { 840 .driver = {
808 .name = "fsl-sai", 841 .name = "fsl-sai",
842 .pm = &fsl_sai_pm_ops,
809 .of_match_table = fsl_sai_ids, 843 .of_match_table = fsl_sai_ids,
810 }, 844 },
811}; 845};
diff --git a/sound/soc/fsl/fsl_spdif.c b/sound/soc/fsl/fsl_spdif.c
index ab729f2426fe..3d59bb6719f2 100644
--- a/sound/soc/fsl/fsl_spdif.c
+++ b/sound/soc/fsl/fsl_spdif.c
@@ -108,6 +108,8 @@ struct fsl_spdif_priv {
108 struct clk *sysclk; 108 struct clk *sysclk;
109 struct snd_dmaengine_dai_dma_data dma_params_tx; 109 struct snd_dmaengine_dai_dma_data dma_params_tx;
110 struct snd_dmaengine_dai_dma_data dma_params_rx; 110 struct snd_dmaengine_dai_dma_data dma_params_rx;
111 /* regcache for SRPC */
112 u32 regcache_srpc;
111}; 113};
112 114
113/* DPLL locked and lock loss interrupt handler */ 115/* DPLL locked and lock loss interrupt handler */
@@ -300,6 +302,8 @@ static int spdif_softreset(struct fsl_spdif_priv *spdif_priv)
300 struct regmap *regmap = spdif_priv->regmap; 302 struct regmap *regmap = spdif_priv->regmap;
301 u32 val, cycle = 1000; 303 u32 val, cycle = 1000;
302 304
305 regcache_cache_bypass(regmap, true);
306
303 regmap_write(regmap, REG_SPDIF_SCR, SCR_SOFT_RESET); 307 regmap_write(regmap, REG_SPDIF_SCR, SCR_SOFT_RESET);
304 308
305 /* 309 /*
@@ -310,6 +314,10 @@ static int spdif_softreset(struct fsl_spdif_priv *spdif_priv)
310 regmap_read(regmap, REG_SPDIF_SCR, &val); 314 regmap_read(regmap, REG_SPDIF_SCR, &val);
311 } while ((val & SCR_SOFT_RESET) && cycle--); 315 } while ((val & SCR_SOFT_RESET) && cycle--);
312 316
317 regcache_cache_bypass(regmap, false);
318 regcache_mark_dirty(regmap);
319 regcache_sync(regmap);
320
313 if (cycle) 321 if (cycle)
314 return 0; 322 return 0;
315 else 323 else
@@ -997,6 +1005,14 @@ static const struct snd_soc_component_driver fsl_spdif_component = {
997}; 1005};
998 1006
999/* FSL SPDIF REGMAP */ 1007/* FSL SPDIF REGMAP */
1008static const struct reg_default fsl_spdif_reg_defaults[] = {
1009 {0x0, 0x00000400},
1010 {0x4, 0x00000000},
1011 {0xc, 0x00000000},
1012 {0x34, 0x00000000},
1013 {0x38, 0x00000000},
1014 {0x50, 0x00020f00},
1015};
1000 1016
1001static bool fsl_spdif_readable_reg(struct device *dev, unsigned int reg) 1017static bool fsl_spdif_readable_reg(struct device *dev, unsigned int reg)
1002{ 1018{
@@ -1022,6 +1038,26 @@ static bool fsl_spdif_readable_reg(struct device *dev, unsigned int reg)
1022 } 1038 }
1023} 1039}
1024 1040
1041static bool fsl_spdif_volatile_reg(struct device *dev, unsigned int reg)
1042{
1043 switch (reg) {
1044 case REG_SPDIF_SRPC:
1045 case REG_SPDIF_SIS:
1046 case REG_SPDIF_SRL:
1047 case REG_SPDIF_SRR:
1048 case REG_SPDIF_SRCSH:
1049 case REG_SPDIF_SRCSL:
1050 case REG_SPDIF_SRU:
1051 case REG_SPDIF_SRQ:
1052 case REG_SPDIF_STL:
1053 case REG_SPDIF_STR:
1054 case REG_SPDIF_SRFM:
1055 return true;
1056 default:
1057 return false;
1058 }
1059}
1060
1025static bool fsl_spdif_writeable_reg(struct device *dev, unsigned int reg) 1061static bool fsl_spdif_writeable_reg(struct device *dev, unsigned int reg)
1026{ 1062{
1027 switch (reg) { 1063 switch (reg) {
@@ -1047,8 +1083,12 @@ static const struct regmap_config fsl_spdif_regmap_config = {
1047 .val_bits = 32, 1083 .val_bits = 32,
1048 1084
1049 .max_register = REG_SPDIF_STC, 1085 .max_register = REG_SPDIF_STC,
1086 .reg_defaults = fsl_spdif_reg_defaults,
1087 .num_reg_defaults = ARRAY_SIZE(fsl_spdif_reg_defaults),
1050 .readable_reg = fsl_spdif_readable_reg, 1088 .readable_reg = fsl_spdif_readable_reg,
1089 .volatile_reg = fsl_spdif_volatile_reg,
1051 .writeable_reg = fsl_spdif_writeable_reg, 1090 .writeable_reg = fsl_spdif_writeable_reg,
1091 .cache_type = REGCACHE_RBTREE,
1052}; 1092};
1053 1093
1054static u32 fsl_spdif_txclk_caldiv(struct fsl_spdif_priv *spdif_priv, 1094static u32 fsl_spdif_txclk_caldiv(struct fsl_spdif_priv *spdif_priv,
@@ -1271,6 +1311,38 @@ static int fsl_spdif_probe(struct platform_device *pdev)
1271 return ret; 1311 return ret;
1272} 1312}
1273 1313
1314#ifdef CONFIG_PM_SLEEP
1315static int fsl_spdif_suspend(struct device *dev)
1316{
1317 struct fsl_spdif_priv *spdif_priv = dev_get_drvdata(dev);
1318
1319 regmap_read(spdif_priv->regmap, REG_SPDIF_SRPC,
1320 &spdif_priv->regcache_srpc);
1321
1322 regcache_cache_only(spdif_priv->regmap, true);
1323 regcache_mark_dirty(spdif_priv->regmap);
1324
1325 return 0;
1326}
1327
1328static int fsl_spdif_resume(struct device *dev)
1329{
1330 struct fsl_spdif_priv *spdif_priv = dev_get_drvdata(dev);
1331
1332 regcache_cache_only(spdif_priv->regmap, false);
1333
1334 regmap_update_bits(spdif_priv->regmap, REG_SPDIF_SRPC,
1335 SRPC_CLKSRC_SEL_MASK | SRPC_GAINSEL_MASK,
1336 spdif_priv->regcache_srpc);
1337
1338 return regcache_sync(spdif_priv->regmap);
1339}
1340#endif /* CONFIG_PM_SLEEP */
1341
1342static const struct dev_pm_ops fsl_spdif_pm = {
1343 SET_SYSTEM_SLEEP_PM_OPS(fsl_spdif_suspend, fsl_spdif_resume)
1344};
1345
1274static const struct of_device_id fsl_spdif_dt_ids[] = { 1346static const struct of_device_id fsl_spdif_dt_ids[] = {
1275 { .compatible = "fsl,imx35-spdif", }, 1347 { .compatible = "fsl,imx35-spdif", },
1276 { .compatible = "fsl,vf610-spdif", }, 1348 { .compatible = "fsl,vf610-spdif", },
@@ -1282,6 +1354,7 @@ static struct platform_driver fsl_spdif_driver = {
1282 .driver = { 1354 .driver = {
1283 .name = "fsl-spdif-dai", 1355 .name = "fsl-spdif-dai",
1284 .of_match_table = fsl_spdif_dt_ids, 1356 .of_match_table = fsl_spdif_dt_ids,
1357 .pm = &fsl_spdif_pm,
1285 }, 1358 },
1286 .probe = fsl_spdif_probe, 1359 .probe = fsl_spdif_probe,
1287}; 1360};
diff --git a/sound/soc/fsl/fsl_ssi.c b/sound/soc/fsl/fsl_ssi.c
index 37c5cd4d0e59..95d2392303eb 100644
--- a/sound/soc/fsl/fsl_ssi.c
+++ b/sound/soc/fsl/fsl_ssi.c
@@ -111,12 +111,75 @@ struct fsl_ssi_rxtx_reg_val {
111 struct fsl_ssi_reg_val rx; 111 struct fsl_ssi_reg_val rx;
112 struct fsl_ssi_reg_val tx; 112 struct fsl_ssi_reg_val tx;
113}; 113};
114
115static const struct reg_default fsl_ssi_reg_defaults[] = {
116 {0x10, 0x00000000},
117 {0x18, 0x00003003},
118 {0x1c, 0x00000200},
119 {0x20, 0x00000200},
120 {0x24, 0x00040000},
121 {0x28, 0x00040000},
122 {0x38, 0x00000000},
123 {0x48, 0x00000000},
124 {0x4c, 0x00000000},
125 {0x54, 0x00000000},
126 {0x58, 0x00000000},
127};
128
129static bool fsl_ssi_readable_reg(struct device *dev, unsigned int reg)
130{
131 switch (reg) {
132 case CCSR_SSI_SACCEN:
133 case CCSR_SSI_SACCDIS:
134 return false;
135 default:
136 return true;
137 }
138}
139
140static bool fsl_ssi_volatile_reg(struct device *dev, unsigned int reg)
141{
142 switch (reg) {
143 case CCSR_SSI_STX0:
144 case CCSR_SSI_STX1:
145 case CCSR_SSI_SRX0:
146 case CCSR_SSI_SRX1:
147 case CCSR_SSI_SISR:
148 case CCSR_SSI_SFCSR:
149 case CCSR_SSI_SACADD:
150 case CCSR_SSI_SACDAT:
151 case CCSR_SSI_SATAG:
152 case CCSR_SSI_SACCST:
153 return true;
154 default:
155 return false;
156 }
157}
158
159static bool fsl_ssi_writeable_reg(struct device *dev, unsigned int reg)
160{
161 switch (reg) {
162 case CCSR_SSI_SRX0:
163 case CCSR_SSI_SRX1:
164 case CCSR_SSI_SACCST:
165 return false;
166 default:
167 return true;
168 }
169}
170
114static const struct regmap_config fsl_ssi_regconfig = { 171static const struct regmap_config fsl_ssi_regconfig = {
115 .max_register = CCSR_SSI_SACCDIS, 172 .max_register = CCSR_SSI_SACCDIS,
116 .reg_bits = 32, 173 .reg_bits = 32,
117 .val_bits = 32, 174 .val_bits = 32,
118 .reg_stride = 4, 175 .reg_stride = 4,
119 .val_format_endian = REGMAP_ENDIAN_NATIVE, 176 .val_format_endian = REGMAP_ENDIAN_NATIVE,
177 .reg_defaults = fsl_ssi_reg_defaults,
178 .num_reg_defaults = ARRAY_SIZE(fsl_ssi_reg_defaults),
179 .readable_reg = fsl_ssi_readable_reg,
180 .volatile_reg = fsl_ssi_volatile_reg,
181 .writeable_reg = fsl_ssi_writeable_reg,
182 .cache_type = REGCACHE_RBTREE,
120}; 183};
121 184
122struct fsl_ssi_soc_data { 185struct fsl_ssi_soc_data {
@@ -176,6 +239,9 @@ struct fsl_ssi_private {
176 unsigned int baudclk_streams; 239 unsigned int baudclk_streams;
177 unsigned int bitclk_freq; 240 unsigned int bitclk_freq;
178 241
242 /*regcache for SFCSR*/
243 u32 regcache_sfcsr;
244
179 /* DMA params */ 245 /* DMA params */
180 struct snd_dmaengine_dai_dma_data dma_params_tx; 246 struct snd_dmaengine_dai_dma_data dma_params_tx;
181 struct snd_dmaengine_dai_dma_data dma_params_rx; 247 struct snd_dmaengine_dai_dma_data dma_params_rx;
@@ -1514,10 +1580,46 @@ static int fsl_ssi_remove(struct platform_device *pdev)
1514 return 0; 1580 return 0;
1515} 1581}
1516 1582
1583#ifdef CONFIG_PM_SLEEP
1584static int fsl_ssi_suspend(struct device *dev)
1585{
1586 struct fsl_ssi_private *ssi_private = dev_get_drvdata(dev);
1587 struct regmap *regs = ssi_private->regs;
1588
1589 regmap_read(regs, CCSR_SSI_SFCSR,
1590 &ssi_private->regcache_sfcsr);
1591
1592 regcache_cache_only(regs, true);
1593 regcache_mark_dirty(regs);
1594
1595 return 0;
1596}
1597
1598static int fsl_ssi_resume(struct device *dev)
1599{
1600 struct fsl_ssi_private *ssi_private = dev_get_drvdata(dev);
1601 struct regmap *regs = ssi_private->regs;
1602
1603 regcache_cache_only(regs, false);
1604
1605 regmap_update_bits(regs, CCSR_SSI_SFCSR,
1606 CCSR_SSI_SFCSR_RFWM1_MASK | CCSR_SSI_SFCSR_TFWM1_MASK |
1607 CCSR_SSI_SFCSR_RFWM0_MASK | CCSR_SSI_SFCSR_TFWM0_MASK,
1608 ssi_private->regcache_sfcsr);
1609
1610 return regcache_sync(regs);
1611}
1612#endif /* CONFIG_PM_SLEEP */
1613
1614static const struct dev_pm_ops fsl_ssi_pm = {
1615 SET_SYSTEM_SLEEP_PM_OPS(fsl_ssi_suspend, fsl_ssi_resume)
1616};
1617
1517static struct platform_driver fsl_ssi_driver = { 1618static struct platform_driver fsl_ssi_driver = {
1518 .driver = { 1619 .driver = {
1519 .name = "fsl-ssi-dai", 1620 .name = "fsl-ssi-dai",
1520 .of_match_table = fsl_ssi_ids, 1621 .of_match_table = fsl_ssi_ids,
1622 .pm = &fsl_ssi_pm,
1521 }, 1623 },
1522 .probe = fsl_ssi_probe, 1624 .probe = fsl_ssi_probe,
1523 .remove = fsl_ssi_remove, 1625 .remove = fsl_ssi_remove,
diff --git a/sound/soc/fsl/imx-spdif.c b/sound/soc/fsl/imx-spdif.c
index 33da26a12457..a407e833c612 100644
--- a/sound/soc/fsl/imx-spdif.c
+++ b/sound/soc/fsl/imx-spdif.c
@@ -89,6 +89,7 @@ MODULE_DEVICE_TABLE(of, imx_spdif_dt_ids);
89static struct platform_driver imx_spdif_driver = { 89static struct platform_driver imx_spdif_driver = {
90 .driver = { 90 .driver = {
91 .name = "imx-spdif", 91 .name = "imx-spdif",
92 .pm = &snd_soc_pm_ops,
92 .of_match_table = imx_spdif_dt_ids, 93 .of_match_table = imx_spdif_dt_ids,
93 }, 94 },
94 .probe = imx_spdif_audio_probe, 95 .probe = imx_spdif_audio_probe,
diff --git a/sound/soc/generic/simple-card.c b/sound/soc/generic/simple-card.c
index 3ff76d419436..54c33204541f 100644
--- a/sound/soc/generic/simple-card.c
+++ b/sound/soc/generic/simple-card.c
@@ -151,7 +151,9 @@ static int __asoc_simple_card_dai_init(struct snd_soc_dai *dai,
151 } 151 }
152 152
153 if (set->slots) { 153 if (set->slots) {
154 ret = snd_soc_dai_set_tdm_slot(dai, 0, 0, 154 ret = snd_soc_dai_set_tdm_slot(dai,
155 set->tx_slot_mask,
156 set->rx_slot_mask,
155 set->slots, 157 set->slots,
156 set->slot_width); 158 set->slot_width);
157 if (ret && ret != -ENOTSUPP) { 159 if (ret && ret != -ENOTSUPP) {
@@ -243,7 +245,9 @@ asoc_simple_card_sub_parse_of(struct device_node *np,
243 return ret; 245 return ret;
244 246
245 /* Parse TDM slot */ 247 /* Parse TDM slot */
246 ret = snd_soc_of_parse_tdm_slot(np, &dai->slots, &dai->slot_width); 248 ret = snd_soc_of_parse_tdm_slot(np, &dai->tx_slot_mask,
249 &dai->rx_slot_mask,
250 &dai->slots, &dai->slot_width);
247 if (ret) 251 if (ret)
248 return ret; 252 return ret;
249 253
diff --git a/sound/soc/intel/Kconfig b/sound/soc/intel/Kconfig
index 05fde5e6e257..7b778ab85f8b 100644
--- a/sound/soc/intel/Kconfig
+++ b/sound/soc/intel/Kconfig
@@ -12,6 +12,7 @@ config SND_MFLD_MACHINE
12 12
13config SND_SST_MFLD_PLATFORM 13config SND_SST_MFLD_PLATFORM
14 tristate 14 tristate
15 select SND_SOC_COMPRESS
15 16
16config SND_SST_IPC 17config SND_SST_IPC
17 tristate 18 tristate
@@ -138,4 +139,18 @@ config SND_SOC_INTEL_CHT_BSW_MAX98090_TI_MACH
138config SND_SOC_INTEL_SKYLAKE 139config SND_SOC_INTEL_SKYLAKE
139 tristate 140 tristate
140 select SND_HDA_EXT_CORE 141 select SND_HDA_EXT_CORE
142 select SND_SOC_TOPOLOGY
141 select SND_SOC_INTEL_SST 143 select SND_SOC_INTEL_SST
144
145config SND_SOC_INTEL_SKL_RT286_MACH
146 tristate "ASoC Audio driver for SKL with RT286 I2S mode"
147 depends on X86 && ACPI
148 select SND_SOC_INTEL_SST
149 select SND_SOC_INTEL_SKYLAKE
150 select SND_SOC_RT286
151 select SND_SOC_DMIC
152 help
153 This adds support for ASoC machine driver for Skylake platforms
154 with RT286 I2S audio codec.
155 Say Y if you have such a device
156 If unsure select "N".
diff --git a/sound/soc/intel/atom/sst-mfld-platform-pcm.c b/sound/soc/intel/atom/sst-mfld-platform-pcm.c
index 683e50116152..0487cfaac538 100644
--- a/sound/soc/intel/atom/sst-mfld-platform-pcm.c
+++ b/sound/soc/intel/atom/sst-mfld-platform-pcm.c
@@ -368,23 +368,6 @@ static void sst_media_close(struct snd_pcm_substream *substream,
368 kfree(stream); 368 kfree(stream);
369} 369}
370 370
371static inline unsigned int get_current_pipe_id(struct snd_soc_dai *dai,
372 struct snd_pcm_substream *substream)
373{
374 struct sst_data *sst = snd_soc_dai_get_drvdata(dai);
375 struct sst_dev_stream_map *map = sst->pdata->pdev_strm_map;
376 struct sst_runtime_stream *stream =
377 substream->runtime->private_data;
378 u32 str_id = stream->stream_info.str_id;
379 unsigned int pipe_id;
380
381 pipe_id = map[str_id].device_id;
382
383 dev_dbg(dai->dev, "got pipe_id = %#x for str_id = %d\n",
384 pipe_id, str_id);
385 return pipe_id;
386}
387
388static int sst_media_prepare(struct snd_pcm_substream *substream, 371static int sst_media_prepare(struct snd_pcm_substream *substream,
389 struct snd_soc_dai *dai) 372 struct snd_soc_dai *dai)
390{ 373{
@@ -529,7 +512,7 @@ static struct snd_soc_dai_driver sst_platform_dai[] = {
529}, 512},
530{ 513{
531 .name = "compress-cpu-dai", 514 .name = "compress-cpu-dai",
532 .compress_dai = 1, 515 .compress_new = snd_soc_new_compress,
533 .ops = &sst_compr_dai_ops, 516 .ops = &sst_compr_dai_ops,
534 .playback = { 517 .playback = {
535 .stream_name = "Compress Playback", 518 .stream_name = "Compress Playback",
diff --git a/sound/soc/intel/boards/Makefile b/sound/soc/intel/boards/Makefile
index cb94895c9edb..371c4565cad8 100644
--- a/sound/soc/intel/boards/Makefile
+++ b/sound/soc/intel/boards/Makefile
@@ -6,6 +6,7 @@ snd-soc-sst-bytcr-rt5640-objs := bytcr_rt5640.o
6snd-soc-sst-cht-bsw-rt5672-objs := cht_bsw_rt5672.o 6snd-soc-sst-cht-bsw-rt5672-objs := cht_bsw_rt5672.o
7snd-soc-sst-cht-bsw-rt5645-objs := cht_bsw_rt5645.o 7snd-soc-sst-cht-bsw-rt5645-objs := cht_bsw_rt5645.o
8snd-soc-sst-cht-bsw-max98090_ti-objs := cht_bsw_max98090_ti.o 8snd-soc-sst-cht-bsw-max98090_ti-objs := cht_bsw_max98090_ti.o
9snd-soc-skl_rt286-objs := skl_rt286.o
9 10
10obj-$(CONFIG_SND_SOC_INTEL_HASWELL_MACH) += snd-soc-sst-haswell.o 11obj-$(CONFIG_SND_SOC_INTEL_HASWELL_MACH) += snd-soc-sst-haswell.o
11obj-$(CONFIG_SND_SOC_INTEL_BYT_RT5640_MACH) += snd-soc-sst-byt-rt5640-mach.o 12obj-$(CONFIG_SND_SOC_INTEL_BYT_RT5640_MACH) += snd-soc-sst-byt-rt5640-mach.o
@@ -15,3 +16,4 @@ obj-$(CONFIG_SND_SOC_INTEL_BYTCR_RT5640_MACH) += snd-soc-sst-bytcr-rt5640.o
15obj-$(CONFIG_SND_SOC_INTEL_CHT_BSW_RT5672_MACH) += snd-soc-sst-cht-bsw-rt5672.o 16obj-$(CONFIG_SND_SOC_INTEL_CHT_BSW_RT5672_MACH) += snd-soc-sst-cht-bsw-rt5672.o
16obj-$(CONFIG_SND_SOC_INTEL_CHT_BSW_RT5645_MACH) += snd-soc-sst-cht-bsw-rt5645.o 17obj-$(CONFIG_SND_SOC_INTEL_CHT_BSW_RT5645_MACH) += snd-soc-sst-cht-bsw-rt5645.o
17obj-$(CONFIG_SND_SOC_INTEL_CHT_BSW_MAX98090_TI_MACH) += snd-soc-sst-cht-bsw-max98090_ti.o 18obj-$(CONFIG_SND_SOC_INTEL_CHT_BSW_MAX98090_TI_MACH) += snd-soc-sst-cht-bsw-max98090_ti.o
19obj-$(CONFIG_SND_SOC_INTEL_SKL_RT286_MACH) += snd-soc-skl_rt286.o
diff --git a/sound/soc/intel/boards/broadwell.c b/sound/soc/intel/boards/broadwell.c
index 8bafaf6ceab1..3f8a1e10bed0 100644
--- a/sound/soc/intel/boards/broadwell.c
+++ b/sound/soc/intel/boards/broadwell.c
@@ -266,18 +266,11 @@ static int broadwell_audio_probe(struct platform_device *pdev)
266{ 266{
267 broadwell_rt286.dev = &pdev->dev; 267 broadwell_rt286.dev = &pdev->dev;
268 268
269 return snd_soc_register_card(&broadwell_rt286); 269 return devm_snd_soc_register_card(&pdev->dev, &broadwell_rt286);
270}
271
272static int broadwell_audio_remove(struct platform_device *pdev)
273{
274 snd_soc_unregister_card(&broadwell_rt286);
275 return 0;
276} 270}
277 271
278static struct platform_driver broadwell_audio = { 272static struct platform_driver broadwell_audio = {
279 .probe = broadwell_audio_probe, 273 .probe = broadwell_audio_probe,
280 .remove = broadwell_audio_remove,
281 .driver = { 274 .driver = {
282 .name = "broadwell-audio", 275 .name = "broadwell-audio",
283 }, 276 },
diff --git a/sound/soc/intel/boards/bytcr_rt5640.c b/sound/soc/intel/boards/bytcr_rt5640.c
index c4453120b11a..7a5c9a36c1db 100644
--- a/sound/soc/intel/boards/bytcr_rt5640.c
+++ b/sound/soc/intel/boards/bytcr_rt5640.c
@@ -117,20 +117,10 @@ static int byt_codec_fixup(struct snd_soc_pcm_runtime *rtd,
117 return 0; 117 return 0;
118} 118}
119 119
120static unsigned int rates_48000[] = {
121 48000,
122};
123
124static struct snd_pcm_hw_constraint_list constraints_48000 = {
125 .count = ARRAY_SIZE(rates_48000),
126 .list = rates_48000,
127};
128
129static int byt_aif1_startup(struct snd_pcm_substream *substream) 120static int byt_aif1_startup(struct snd_pcm_substream *substream)
130{ 121{
131 return snd_pcm_hw_constraint_list(substream->runtime, 0, 122 return snd_pcm_hw_constraint_single(substream->runtime,
132 SNDRV_PCM_HW_PARAM_RATE, 123 SNDRV_PCM_HW_PARAM_RATE, 48000);
133 &constraints_48000);
134} 124}
135 125
136static struct snd_soc_ops byt_aif1_ops = { 126static struct snd_soc_ops byt_aif1_ops = {
diff --git a/sound/soc/intel/boards/cht_bsw_max98090_ti.c b/sound/soc/intel/boards/cht_bsw_max98090_ti.c
index 49f4869cec48..4e2fcf188dd1 100644
--- a/sound/soc/intel/boards/cht_bsw_max98090_ti.c
+++ b/sound/soc/intel/boards/cht_bsw_max98090_ti.c
@@ -193,20 +193,10 @@ static int cht_codec_fixup(struct snd_soc_pcm_runtime *rtd,
193 return 0; 193 return 0;
194} 194}
195 195
196static unsigned int rates_48000[] = {
197 48000,
198};
199
200static struct snd_pcm_hw_constraint_list constraints_48000 = {
201 .count = ARRAY_SIZE(rates_48000),
202 .list = rates_48000,
203};
204
205static int cht_aif1_startup(struct snd_pcm_substream *substream) 196static int cht_aif1_startup(struct snd_pcm_substream *substream)
206{ 197{
207 return snd_pcm_hw_constraint_list(substream->runtime, 0, 198 return snd_pcm_hw_constraint_single(substream->runtime,
208 SNDRV_PCM_HW_PARAM_RATE, 199 SNDRV_PCM_HW_PARAM_RATE, 48000);
209 &constraints_48000);
210} 200}
211 201
212static int cht_max98090_headset_init(struct snd_soc_component *component) 202static int cht_max98090_headset_init(struct snd_soc_component *component)
diff --git a/sound/soc/intel/boards/cht_bsw_rt5645.c b/sound/soc/intel/boards/cht_bsw_rt5645.c
index 7be8461e4d3b..38d65a3529c4 100644
--- a/sound/soc/intel/boards/cht_bsw_rt5645.c
+++ b/sound/soc/intel/boards/cht_bsw_rt5645.c
@@ -235,20 +235,10 @@ static int cht_codec_fixup(struct snd_soc_pcm_runtime *rtd,
235 return 0; 235 return 0;
236} 236}
237 237
238static unsigned int rates_48000[] = {
239 48000,
240};
241
242static struct snd_pcm_hw_constraint_list constraints_48000 = {
243 .count = ARRAY_SIZE(rates_48000),
244 .list = rates_48000,
245};
246
247static int cht_aif1_startup(struct snd_pcm_substream *substream) 238static int cht_aif1_startup(struct snd_pcm_substream *substream)
248{ 239{
249 return snd_pcm_hw_constraint_list(substream->runtime, 0, 240 return snd_pcm_hw_constraint_single(substream->runtime,
250 SNDRV_PCM_HW_PARAM_RATE, 241 SNDRV_PCM_HW_PARAM_RATE, 48000);
251 &constraints_48000);
252} 242}
253 243
254static struct snd_soc_ops cht_aif1_ops = { 244static struct snd_soc_ops cht_aif1_ops = {
diff --git a/sound/soc/intel/boards/cht_bsw_rt5672.c b/sound/soc/intel/boards/cht_bsw_rt5672.c
index 23fe04075142..5621ccd92992 100644
--- a/sound/soc/intel/boards/cht_bsw_rt5672.c
+++ b/sound/soc/intel/boards/cht_bsw_rt5672.c
@@ -222,20 +222,10 @@ static int cht_codec_fixup(struct snd_soc_pcm_runtime *rtd,
222 return 0; 222 return 0;
223} 223}
224 224
225static unsigned int rates_48000[] = {
226 48000,
227};
228
229static struct snd_pcm_hw_constraint_list constraints_48000 = {
230 .count = ARRAY_SIZE(rates_48000),
231 .list = rates_48000,
232};
233
234static int cht_aif1_startup(struct snd_pcm_substream *substream) 225static int cht_aif1_startup(struct snd_pcm_substream *substream)
235{ 226{
236 return snd_pcm_hw_constraint_list(substream->runtime, 0, 227 return snd_pcm_hw_constraint_single(substream->runtime,
237 SNDRV_PCM_HW_PARAM_RATE, 228 SNDRV_PCM_HW_PARAM_RATE, 48000);
238 &constraints_48000);
239} 229}
240 230
241static struct snd_soc_ops cht_aif1_ops = { 231static struct snd_soc_ops cht_aif1_ops = {
diff --git a/sound/soc/intel/boards/skl_rt286.c b/sound/soc/intel/boards/skl_rt286.c
new file mode 100644
index 000000000000..a73a431bd8b7
--- /dev/null
+++ b/sound/soc/intel/boards/skl_rt286.c
@@ -0,0 +1,259 @@
1/*
2 * Intel Skylake I2S Machine Driver
3 *
4 * Copyright (C) 2014-2015, Intel Corporation. All rights reserved.
5 *
6 * Modified from:
7 * Intel Broadwell Wildcatpoint SST Audio
8 *
9 * Copyright (C) 2013, Intel Corporation. All rights reserved.
10 *
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License version
13 * 2 as published by the Free Software Foundation.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 */
20
21#include <linux/module.h>
22#include <linux/platform_device.h>
23#include <sound/core.h>
24#include <sound/pcm.h>
25#include <sound/soc.h>
26#include <sound/jack.h>
27#include <sound/pcm_params.h>
28#include "../../codecs/rt286.h"
29
30static struct snd_soc_jack skylake_headset;
31/* Headset jack detection DAPM pins */
32static struct snd_soc_jack_pin skylake_headset_pins[] = {
33 {
34 .pin = "Mic Jack",
35 .mask = SND_JACK_MICROPHONE,
36 },
37 {
38 .pin = "Headphone Jack",
39 .mask = SND_JACK_HEADPHONE,
40 },
41};
42
43static const struct snd_kcontrol_new skylake_controls[] = {
44 SOC_DAPM_PIN_SWITCH("Speaker"),
45 SOC_DAPM_PIN_SWITCH("Headphone Jack"),
46 SOC_DAPM_PIN_SWITCH("Mic Jack"),
47};
48
49static const struct snd_soc_dapm_widget skylake_widgets[] = {
50 SND_SOC_DAPM_HP("Headphone Jack", NULL),
51 SND_SOC_DAPM_SPK("Speaker", NULL),
52 SND_SOC_DAPM_MIC("Mic Jack", NULL),
53 SND_SOC_DAPM_MIC("DMIC2", NULL),
54 SND_SOC_DAPM_MIC("SoC DMIC", NULL),
55};
56
57static const struct snd_soc_dapm_route skylake_rt286_map[] = {
58 /* speaker */
59 {"Speaker", NULL, "SPOR"},
60 {"Speaker", NULL, "SPOL"},
61
62 /* HP jack connectors - unknown if we have jack deteck */
63 {"Headphone Jack", NULL, "HPO Pin"},
64
65 /* other jacks */
66 {"MIC1", NULL, "Mic Jack"},
67
68 /* digital mics */
69 {"DMIC1 Pin", NULL, "DMIC2"},
70 {"DMIC AIF", NULL, "SoC DMIC"},
71
72 /* CODEC BE connections */
73 { "AIF1 Playback", NULL, "ssp0 Tx"},
74 { "ssp0 Tx", NULL, "codec0_out"},
75 { "ssp0 Tx", NULL, "codec1_out"},
76
77 { "codec0_in", NULL, "ssp0 Rx" },
78 { "codec1_in", NULL, "ssp0 Rx" },
79 { "ssp0 Rx", NULL, "AIF1 Capture" },
80
81 { "dmic01_hifi", NULL, "DMIC01 Rx" },
82 { "DMIC01 Rx", NULL, "Capture" },
83
84 { "hif1", NULL, "iDisp Tx"},
85 { "iDisp Tx", NULL, "iDisp_out"},
86
87};
88
89static int skylake_rt286_codec_init(struct snd_soc_pcm_runtime *rtd)
90{
91 struct snd_soc_codec *codec = rtd->codec;
92 int ret;
93
94 ret = snd_soc_card_jack_new(rtd->card, "Headset",
95 SND_JACK_HEADSET | SND_JACK_BTN_0,
96 &skylake_headset,
97 skylake_headset_pins, ARRAY_SIZE(skylake_headset_pins));
98
99 if (ret)
100 return ret;
101
102 rt286_mic_detect(codec, &skylake_headset);
103
104 return 0;
105}
106
107
108static int skylake_ssp0_fixup(struct snd_soc_pcm_runtime *rtd,
109 struct snd_pcm_hw_params *params)
110{
111 struct snd_interval *rate = hw_param_interval(params,
112 SNDRV_PCM_HW_PARAM_RATE);
113 struct snd_interval *channels = hw_param_interval(params,
114 SNDRV_PCM_HW_PARAM_CHANNELS);
115
116 /* The output is 48KHz, stereo, 16bits */
117 rate->min = rate->max = 48000;
118 channels->min = channels->max = 2;
119 params_set_format(params, SNDRV_PCM_FORMAT_S16_LE);
120
121 return 0;
122}
123
124static int skylake_rt286_hw_params(struct snd_pcm_substream *substream,
125 struct snd_pcm_hw_params *params)
126{
127 struct snd_soc_pcm_runtime *rtd = substream->private_data;
128 struct snd_soc_dai *codec_dai = rtd->codec_dai;
129 int ret;
130
131 ret = snd_soc_dai_set_sysclk(codec_dai, RT286_SCLK_S_PLL, 24000000,
132 SND_SOC_CLOCK_IN);
133 if (ret < 0)
134 dev_err(rtd->dev, "set codec sysclk failed: %d\n", ret);
135
136 return ret;
137}
138
139static struct snd_soc_ops skylake_rt286_ops = {
140 .hw_params = skylake_rt286_hw_params,
141};
142
143/* skylake digital audio interface glue - connects codec <--> CPU */
144static struct snd_soc_dai_link skylake_rt286_dais[] = {
145 /* Front End DAI links */
146 {
147 .name = "Skl Audio Port",
148 .stream_name = "Audio",
149 .cpu_dai_name = "System Pin",
150 .platform_name = "0000:00:1f.3",
151 .nonatomic = 1,
152 .dynamic = 1,
153 .codec_name = "snd-soc-dummy",
154 .codec_dai_name = "snd-soc-dummy-dai",
155 .trigger = {
156 SND_SOC_DPCM_TRIGGER_POST,
157 SND_SOC_DPCM_TRIGGER_POST
158 },
159 .dpcm_playback = 1,
160 },
161 {
162 .name = "Skl Audio Capture Port",
163 .stream_name = "Audio Record",
164 .cpu_dai_name = "System Pin",
165 .platform_name = "0000:00:1f.3",
166 .nonatomic = 1,
167 .dynamic = 1,
168 .codec_name = "snd-soc-dummy",
169 .codec_dai_name = "snd-soc-dummy-dai",
170 .trigger = {
171 SND_SOC_DPCM_TRIGGER_POST,
172 SND_SOC_DPCM_TRIGGER_POST
173 },
174 .dpcm_capture = 1,
175 },
176 {
177 .name = "Skl Audio Reference cap",
178 .stream_name = "refcap",
179 .cpu_dai_name = "Reference Pin",
180 .codec_name = "snd-soc-dummy",
181 .codec_dai_name = "snd-soc-dummy-dai",
182 .platform_name = "0000:00:1f.3",
183 .init = NULL,
184 .dpcm_capture = 1,
185 .ignore_suspend = 1,
186 .nonatomic = 1,
187 .dynamic = 1,
188 },
189
190 /* Back End DAI links */
191 {
192 /* SSP0 - Codec */
193 .name = "SSP0-Codec",
194 .be_id = 0,
195 .cpu_dai_name = "SSP0 Pin",
196 .platform_name = "0000:00:1f.3",
197 .no_pcm = 1,
198 .codec_name = "i2c-INT343A:00",
199 .codec_dai_name = "rt286-aif1",
200 .init = skylake_rt286_codec_init,
201 .dai_fmt = SND_SOC_DAIFMT_I2S |
202 SND_SOC_DAIFMT_NB_NF |
203 SND_SOC_DAIFMT_CBS_CFS,
204 .ignore_suspend = 1,
205 .ignore_pmdown_time = 1,
206 .be_hw_params_fixup = skylake_ssp0_fixup,
207 .ops = &skylake_rt286_ops,
208 .dpcm_playback = 1,
209 .dpcm_capture = 1,
210 },
211 {
212 .name = "dmic01",
213 .be_id = 1,
214 .cpu_dai_name = "DMIC01 Pin",
215 .codec_name = "dmic-codec",
216 .codec_dai_name = "dmic-hifi",
217 .platform_name = "0000:00:1f.3",
218 .ignore_suspend = 1,
219 .dpcm_capture = 1,
220 .no_pcm = 1,
221 },
222};
223
224/* skylake audio machine driver for SPT + RT286S */
225static struct snd_soc_card skylake_rt286 = {
226 .name = "skylake-rt286",
227 .owner = THIS_MODULE,
228 .dai_link = skylake_rt286_dais,
229 .num_links = ARRAY_SIZE(skylake_rt286_dais),
230 .controls = skylake_controls,
231 .num_controls = ARRAY_SIZE(skylake_controls),
232 .dapm_widgets = skylake_widgets,
233 .num_dapm_widgets = ARRAY_SIZE(skylake_widgets),
234 .dapm_routes = skylake_rt286_map,
235 .num_dapm_routes = ARRAY_SIZE(skylake_rt286_map),
236 .fully_routed = true,
237};
238
239static int skylake_audio_probe(struct platform_device *pdev)
240{
241 skylake_rt286.dev = &pdev->dev;
242
243 return devm_snd_soc_register_card(&pdev->dev, &skylake_rt286);
244}
245
246static struct platform_driver skylake_audio = {
247 .probe = skylake_audio_probe,
248 .driver = {
249 .name = "skl_alc286s_i2s",
250 },
251};
252
253module_platform_driver(skylake_audio)
254
255/* Module information */
256MODULE_AUTHOR("Omair Mohammed Abdullah <omair.m.abdullah@intel.com>");
257MODULE_DESCRIPTION("Intel SST Audio for Skylake");
258MODULE_LICENSE("GPL v2");
259MODULE_ALIAS("platform:skl_alc286s_i2s");
diff --git a/sound/soc/intel/common/Makefile b/sound/soc/intel/common/Makefile
index f24154ca4e98..d9105584c51f 100644
--- a/sound/soc/intel/common/Makefile
+++ b/sound/soc/intel/common/Makefile
@@ -1,7 +1,11 @@
1snd-soc-sst-dsp-objs := sst-dsp.o sst-firmware.o 1snd-soc-sst-dsp-objs := sst-dsp.o
2snd-soc-sst-acpi-objs := sst-acpi.o 2snd-soc-sst-acpi-objs := sst-acpi.o
3snd-soc-sst-ipc-objs := sst-ipc.o 3snd-soc-sst-ipc-objs := sst-ipc.o
4 4
5ifneq ($(CONFIG_DW_DMAC_CORE),)
6snd-soc-sst-dsp-objs += sst-firmware.o
7endif
8
5obj-$(CONFIG_SND_SOC_INTEL_SST) += snd-soc-sst-dsp.o snd-soc-sst-ipc.o 9obj-$(CONFIG_SND_SOC_INTEL_SST) += snd-soc-sst-dsp.o snd-soc-sst-ipc.o
6obj-$(CONFIG_SND_SOC_INTEL_SST_ACPI) += snd-soc-sst-acpi.o 10obj-$(CONFIG_SND_SOC_INTEL_SST_ACPI) += snd-soc-sst-acpi.o
7 11
diff --git a/sound/soc/intel/common/sst-dsp-priv.h b/sound/soc/intel/common/sst-dsp-priv.h
index cbd568eac033..2151652d37b7 100644
--- a/sound/soc/intel/common/sst-dsp-priv.h
+++ b/sound/soc/intel/common/sst-dsp-priv.h
@@ -314,6 +314,7 @@ struct sst_dsp {
314 int sst_state; 314 int sst_state;
315 struct skl_cl_dev cl_dev; 315 struct skl_cl_dev cl_dev;
316 u32 intr_status; 316 u32 intr_status;
317 const struct firmware *fw;
317}; 318};
318 319
319/* Size optimised DRAM/IRAM memcpy */ 320/* Size optimised DRAM/IRAM memcpy */
diff --git a/sound/soc/intel/common/sst-dsp.c b/sound/soc/intel/common/sst-dsp.c
index a627236dd1f5..c9452e02e0dd 100644
--- a/sound/soc/intel/common/sst-dsp.c
+++ b/sound/soc/intel/common/sst-dsp.c
@@ -420,6 +420,7 @@ void sst_dsp_inbox_read(struct sst_dsp *sst, void *message, size_t bytes)
420} 420}
421EXPORT_SYMBOL_GPL(sst_dsp_inbox_read); 421EXPORT_SYMBOL_GPL(sst_dsp_inbox_read);
422 422
423#if IS_ENABLED(CONFIG_DW_DMAC_CORE)
423struct sst_dsp *sst_dsp_new(struct device *dev, 424struct sst_dsp *sst_dsp_new(struct device *dev,
424 struct sst_dsp_device *sst_dev, struct sst_pdata *pdata) 425 struct sst_dsp_device *sst_dev, struct sst_pdata *pdata)
425{ 426{
@@ -484,6 +485,7 @@ void sst_dsp_free(struct sst_dsp *sst)
484 sst_dma_free(sst->dma); 485 sst_dma_free(sst->dma);
485} 486}
486EXPORT_SYMBOL_GPL(sst_dsp_free); 487EXPORT_SYMBOL_GPL(sst_dsp_free);
488#endif
487 489
488/* Module information */ 490/* Module information */
489MODULE_AUTHOR("Liam Girdwood"); 491MODULE_AUTHOR("Liam Girdwood");
diff --git a/sound/soc/intel/common/sst-dsp.h b/sound/soc/intel/common/sst-dsp.h
index 1f45f18715c0..859f0de00339 100644
--- a/sound/soc/intel/common/sst-dsp.h
+++ b/sound/soc/intel/common/sst-dsp.h
@@ -216,10 +216,12 @@ struct sst_pdata {
216 void *dsp; 216 void *dsp;
217}; 217};
218 218
219#if IS_ENABLED(CONFIG_DW_DMAC_CORE)
219/* Initialization */ 220/* Initialization */
220struct sst_dsp *sst_dsp_new(struct device *dev, 221struct sst_dsp *sst_dsp_new(struct device *dev,
221 struct sst_dsp_device *sst_dev, struct sst_pdata *pdata); 222 struct sst_dsp_device *sst_dev, struct sst_pdata *pdata);
222void sst_dsp_free(struct sst_dsp *sst); 223void sst_dsp_free(struct sst_dsp *sst);
224#endif
223 225
224/* SHIM Read / Write */ 226/* SHIM Read / Write */
225void sst_dsp_shim_write(struct sst_dsp *sst, u32 offset, u32 value); 227void sst_dsp_shim_write(struct sst_dsp *sst, u32 offset, u32 value);
diff --git a/sound/soc/intel/common/sst-firmware.c b/sound/soc/intel/common/sst-firmware.c
index ebcca6dc48d1..1636a1eeb002 100644
--- a/sound/soc/intel/common/sst-firmware.c
+++ b/sound/soc/intel/common/sst-firmware.c
@@ -26,7 +26,6 @@
26#include <linux/acpi.h> 26#include <linux/acpi.h>
27 27
28/* supported DMA engine drivers */ 28/* supported DMA engine drivers */
29#include <linux/platform_data/dma-dw.h>
30#include <linux/dma/dw.h> 29#include <linux/dma/dw.h>
31 30
32#include <asm/page.h> 31#include <asm/page.h>
@@ -169,12 +168,6 @@ err:
169 return ret; 168 return ret;
170} 169}
171 170
172static struct dw_dma_platform_data dw_pdata = {
173 .is_private = 1,
174 .chan_allocation_order = CHAN_ALLOCATION_ASCENDING,
175 .chan_priority = CHAN_PRIORITY_ASCENDING,
176};
177
178static struct dw_dma_chip *dw_probe(struct device *dev, struct resource *mem, 171static struct dw_dma_chip *dw_probe(struct device *dev, struct resource *mem,
179 int irq) 172 int irq)
180{ 173{
@@ -195,7 +188,8 @@ static struct dw_dma_chip *dw_probe(struct device *dev, struct resource *mem,
195 return ERR_PTR(err); 188 return ERR_PTR(err);
196 189
197 chip->dev = dev; 190 chip->dev = dev;
198 err = dw_dma_probe(chip, &dw_pdata); 191
192 err = dw_dma_probe(chip, NULL);
199 if (err) 193 if (err)
200 return ERR_PTR(err); 194 return ERR_PTR(err);
201 195
diff --git a/sound/soc/intel/skylake/Makefile b/sound/soc/intel/skylake/Makefile
index 27db22178204..914b6dab9bea 100644
--- a/sound/soc/intel/skylake/Makefile
+++ b/sound/soc/intel/skylake/Makefile
@@ -1,4 +1,5 @@
1snd-soc-skl-objs := skl.o skl-pcm.o skl-nhlt.o skl-messages.o 1snd-soc-skl-objs := skl.o skl-pcm.o skl-nhlt.o skl-messages.o \
2skl-topology.o
2 3
3obj-$(CONFIG_SND_SOC_INTEL_SKYLAKE) += snd-soc-skl.o 4obj-$(CONFIG_SND_SOC_INTEL_SKYLAKE) += snd-soc-skl.o
4 5
diff --git a/sound/soc/intel/skylake/skl-messages.c b/sound/soc/intel/skylake/skl-messages.c
index 826d4fd8930a..50a109503a3f 100644
--- a/sound/soc/intel/skylake/skl-messages.c
+++ b/sound/soc/intel/skylake/skl-messages.c
@@ -54,6 +54,24 @@ static int skl_free_dma_buf(struct device *dev, struct snd_dma_buffer *dmab)
54 return 0; 54 return 0;
55} 55}
56 56
57#define NOTIFICATION_PARAM_ID 3
58#define NOTIFICATION_MASK 0xf
59
60/* disable notfication for underruns/overruns from firmware module */
61static void skl_dsp_enable_notification(struct skl_sst *ctx, bool enable)
62{
63 struct notification_mask mask;
64 struct skl_ipc_large_config_msg msg = {0};
65
66 mask.notify = NOTIFICATION_MASK;
67 mask.enable = enable;
68
69 msg.large_param_id = NOTIFICATION_PARAM_ID;
70 msg.param_data_size = sizeof(mask);
71
72 skl_ipc_set_large_config(&ctx->ipc, &msg, (u32 *)&mask);
73}
74
57int skl_init_dsp(struct skl *skl) 75int skl_init_dsp(struct skl *skl)
58{ 76{
59 void __iomem *mmio_base; 77 void __iomem *mmio_base;
@@ -79,7 +97,10 @@ int skl_init_dsp(struct skl *skl)
79 97
80 ret = skl_sst_dsp_init(bus->dev, mmio_base, irq, 98 ret = skl_sst_dsp_init(bus->dev, mmio_base, irq,
81 loader_ops, &skl->skl_sst); 99 loader_ops, &skl->skl_sst);
100 if (ret < 0)
101 return ret;
82 102
103 skl_dsp_enable_notification(skl->skl_sst, false);
83 dev_dbg(bus->dev, "dsp registration status=%d\n", ret); 104 dev_dbg(bus->dev, "dsp registration status=%d\n", ret);
84 105
85 return ret; 106 return ret;
@@ -122,6 +143,7 @@ int skl_suspend_dsp(struct skl *skl)
122int skl_resume_dsp(struct skl *skl) 143int skl_resume_dsp(struct skl *skl)
123{ 144{
124 struct skl_sst *ctx = skl->skl_sst; 145 struct skl_sst *ctx = skl->skl_sst;
146 int ret;
125 147
126 /* if ppcap is not supported return 0 */ 148 /* if ppcap is not supported return 0 */
127 if (!skl->ebus.ppcap) 149 if (!skl->ebus.ppcap)
@@ -131,7 +153,12 @@ int skl_resume_dsp(struct skl *skl)
131 snd_hdac_ext_bus_ppcap_enable(&skl->ebus, true); 153 snd_hdac_ext_bus_ppcap_enable(&skl->ebus, true);
132 snd_hdac_ext_bus_ppcap_int_enable(&skl->ebus, true); 154 snd_hdac_ext_bus_ppcap_int_enable(&skl->ebus, true);
133 155
134 return skl_dsp_wake(ctx->dsp); 156 ret = skl_dsp_wake(ctx->dsp);
157 if (ret < 0)
158 return ret;
159
160 skl_dsp_enable_notification(skl->skl_sst, false);
161 return ret;
135} 162}
136 163
137enum skl_bitdepth skl_get_bit_depth(int params) 164enum skl_bitdepth skl_get_bit_depth(int params)
@@ -294,6 +321,7 @@ static void skl_copy_copier_caps(struct skl_module_cfg *mconfig,
294 (mconfig->formats_config.caps_size) / 4; 321 (mconfig->formats_config.caps_size) / 4;
295} 322}
296 323
324#define SKL_NON_GATEWAY_CPR_NODE_ID 0xFFFFFFFF
297/* 325/*
298 * Calculate the gatewat settings required for copier module, type of 326 * Calculate the gatewat settings required for copier module, type of
299 * gateway and index of gateway to use 327 * gateway and index of gateway to use
@@ -303,6 +331,7 @@ static void skl_setup_cpr_gateway_cfg(struct skl_sst *ctx,
303 struct skl_cpr_cfg *cpr_mconfig) 331 struct skl_cpr_cfg *cpr_mconfig)
304{ 332{
305 union skl_connector_node_id node_id = {0}; 333 union skl_connector_node_id node_id = {0};
334 union skl_ssp_dma_node ssp_node = {0};
306 struct skl_pipe_params *params = mconfig->pipe->p_params; 335 struct skl_pipe_params *params = mconfig->pipe->p_params;
307 336
308 switch (mconfig->dev_type) { 337 switch (mconfig->dev_type) {
@@ -320,9 +349,9 @@ static void skl_setup_cpr_gateway_cfg(struct skl_sst *ctx,
320 (SKL_CONN_SOURCE == mconfig->hw_conn_type) ? 349 (SKL_CONN_SOURCE == mconfig->hw_conn_type) ?
321 SKL_DMA_I2S_LINK_OUTPUT_CLASS : 350 SKL_DMA_I2S_LINK_OUTPUT_CLASS :
322 SKL_DMA_I2S_LINK_INPUT_CLASS; 351 SKL_DMA_I2S_LINK_INPUT_CLASS;
323 node_id.node.vindex = params->host_dma_id + 352 ssp_node.dma_node.time_slot_index = mconfig->time_slot;
324 (mconfig->time_slot << 1) + 353 ssp_node.dma_node.i2s_instance = mconfig->vbus_id;
325 (mconfig->vbus_id << 3); 354 node_id.node.vindex = ssp_node.val;
326 break; 355 break;
327 356
328 case SKL_DEVICE_DMIC: 357 case SKL_DEVICE_DMIC:
@@ -339,13 +368,18 @@ static void skl_setup_cpr_gateway_cfg(struct skl_sst *ctx,
339 node_id.node.vindex = params->link_dma_id; 368 node_id.node.vindex = params->link_dma_id;
340 break; 369 break;
341 370
342 default: 371 case SKL_DEVICE_HDAHOST:
343 node_id.node.dma_type = 372 node_id.node.dma_type =
344 (SKL_CONN_SOURCE == mconfig->hw_conn_type) ? 373 (SKL_CONN_SOURCE == mconfig->hw_conn_type) ?
345 SKL_DMA_HDA_HOST_OUTPUT_CLASS : 374 SKL_DMA_HDA_HOST_OUTPUT_CLASS :
346 SKL_DMA_HDA_HOST_INPUT_CLASS; 375 SKL_DMA_HDA_HOST_INPUT_CLASS;
347 node_id.node.vindex = params->host_dma_id; 376 node_id.node.vindex = params->host_dma_id;
348 break; 377 break;
378
379 default:
380 cpr_mconfig->gtw_cfg.node_id = SKL_NON_GATEWAY_CPR_NODE_ID;
381 cpr_mconfig->cpr_feature_mask = 0;
382 return;
349 } 383 }
350 384
351 cpr_mconfig->gtw_cfg.node_id = node_id.val; 385 cpr_mconfig->gtw_cfg.node_id = node_id.val;
diff --git a/sound/soc/intel/skylake/skl-nhlt.c b/sound/soc/intel/skylake/skl-nhlt.c
index 13036b19d7e5..b0c7bd113aac 100644
--- a/sound/soc/intel/skylake/skl-nhlt.c
+++ b/sound/soc/intel/skylake/skl-nhlt.c
@@ -25,7 +25,7 @@ static u8 OSC_UUID[16] = {0x6E, 0x88, 0x9F, 0xA6, 0xEB, 0x6C, 0x94, 0x45,
25 25
26#define DSDT_NHLT_PATH "\\_SB.PCI0.HDAS" 26#define DSDT_NHLT_PATH "\\_SB.PCI0.HDAS"
27 27
28void __iomem *skl_nhlt_init(struct device *dev) 28void *skl_nhlt_init(struct device *dev)
29{ 29{
30 acpi_handle handle; 30 acpi_handle handle;
31 union acpi_object *obj; 31 union acpi_object *obj;
@@ -40,17 +40,17 @@ void __iomem *skl_nhlt_init(struct device *dev)
40 if (obj && obj->type == ACPI_TYPE_BUFFER) { 40 if (obj && obj->type == ACPI_TYPE_BUFFER) {
41 nhlt_ptr = (struct nhlt_resource_desc *)obj->buffer.pointer; 41 nhlt_ptr = (struct nhlt_resource_desc *)obj->buffer.pointer;
42 42
43 return ioremap_cache(nhlt_ptr->min_addr, nhlt_ptr->length); 43 return memremap(nhlt_ptr->min_addr, nhlt_ptr->length,
44 MEMREMAP_WB);
44 } 45 }
45 46
46 dev_err(dev, "device specific method to extract NHLT blob failed\n"); 47 dev_err(dev, "device specific method to extract NHLT blob failed\n");
47 return NULL; 48 return NULL;
48} 49}
49 50
50void skl_nhlt_free(void __iomem *addr) 51void skl_nhlt_free(void *addr)
51{ 52{
52 iounmap(addr); 53 memunmap(addr);
53 addr = NULL;
54} 54}
55 55
56static struct nhlt_specific_cfg *skl_get_specific_cfg( 56static struct nhlt_specific_cfg *skl_get_specific_cfg(
diff --git a/sound/soc/intel/skylake/skl-pcm.c b/sound/soc/intel/skylake/skl-pcm.c
index 7d617bf493bc..a2f94ce1679d 100644
--- a/sound/soc/intel/skylake/skl-pcm.c
+++ b/sound/soc/intel/skylake/skl-pcm.c
@@ -24,6 +24,7 @@
24#include <sound/pcm_params.h> 24#include <sound/pcm_params.h>
25#include <sound/soc.h> 25#include <sound/soc.h>
26#include "skl.h" 26#include "skl.h"
27#include "skl-topology.h"
27 28
28#define HDA_MONO 1 29#define HDA_MONO 1
29#define HDA_STEREO 2 30#define HDA_STEREO 2
@@ -115,7 +116,7 @@ static int skl_pcm_open(struct snd_pcm_substream *substream,
115 116
116 dev_dbg(dai->dev, "%s: %s\n", __func__, dai->name); 117 dev_dbg(dai->dev, "%s: %s\n", __func__, dai->name);
117 ret = pm_runtime_get_sync(dai->dev); 118 ret = pm_runtime_get_sync(dai->dev);
118 if (ret) 119 if (ret < 0)
119 return ret; 120 return ret;
120 121
121 stream = snd_hdac_ext_stream_assign(ebus, substream, 122 stream = snd_hdac_ext_stream_assign(ebus, substream,
@@ -214,6 +215,8 @@ static int skl_pcm_hw_params(struct snd_pcm_substream *substream,
214 struct hdac_ext_bus *ebus = dev_get_drvdata(dai->dev); 215 struct hdac_ext_bus *ebus = dev_get_drvdata(dai->dev);
215 struct hdac_ext_stream *stream = get_hdac_ext_stream(substream); 216 struct hdac_ext_stream *stream = get_hdac_ext_stream(substream);
216 struct snd_pcm_runtime *runtime = substream->runtime; 217 struct snd_pcm_runtime *runtime = substream->runtime;
218 struct skl_pipe_params p_params = {0};
219 struct skl_module_cfg *m_cfg;
217 int ret, dma_id; 220 int ret, dma_id;
218 221
219 dev_dbg(dai->dev, "%s: %s\n", __func__, dai->name); 222 dev_dbg(dai->dev, "%s: %s\n", __func__, dai->name);
@@ -228,6 +231,16 @@ static int skl_pcm_hw_params(struct snd_pcm_substream *substream,
228 dma_id = hdac_stream(stream)->stream_tag - 1; 231 dma_id = hdac_stream(stream)->stream_tag - 1;
229 dev_dbg(dai->dev, "dma_id=%d\n", dma_id); 232 dev_dbg(dai->dev, "dma_id=%d\n", dma_id);
230 233
234 p_params.s_fmt = snd_pcm_format_width(params_format(params));
235 p_params.ch = params_channels(params);
236 p_params.s_freq = params_rate(params);
237 p_params.host_dma_id = dma_id;
238 p_params.stream = substream->stream;
239
240 m_cfg = skl_tplg_fe_get_cpr_module(dai, p_params.stream);
241 if (m_cfg)
242 skl_tplg_update_pipe_params(dai->dev, m_cfg, &p_params);
243
231 return 0; 244 return 0;
232} 245}
233 246
@@ -268,6 +281,46 @@ static int skl_pcm_hw_free(struct snd_pcm_substream *substream,
268 return skl_substream_free_pages(ebus_to_hbus(ebus), substream); 281 return skl_substream_free_pages(ebus_to_hbus(ebus), substream);
269} 282}
270 283
284static int skl_be_hw_params(struct snd_pcm_substream *substream,
285 struct snd_pcm_hw_params *params,
286 struct snd_soc_dai *dai)
287{
288 struct skl_pipe_params p_params = {0};
289
290 p_params.s_fmt = snd_pcm_format_width(params_format(params));
291 p_params.ch = params_channels(params);
292 p_params.s_freq = params_rate(params);
293 p_params.stream = substream->stream;
294 skl_tplg_be_update_params(dai, &p_params);
295
296 return 0;
297}
298
299static int skl_pcm_trigger(struct snd_pcm_substream *substream, int cmd,
300 struct snd_soc_dai *dai)
301{
302 struct skl *skl = get_skl_ctx(dai->dev);
303 struct skl_sst *ctx = skl->skl_sst;
304 struct skl_module_cfg *mconfig;
305
306 mconfig = skl_tplg_fe_get_cpr_module(dai, substream->stream);
307 if (!mconfig)
308 return -EIO;
309
310 switch (cmd) {
311 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
312 case SNDRV_PCM_TRIGGER_RESUME:
313 return skl_run_pipe(ctx, mconfig->pipe);
314
315 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
316 case SNDRV_PCM_TRIGGER_SUSPEND:
317 return skl_stop_pipe(ctx, mconfig->pipe);
318
319 default:
320 return 0;
321 }
322}
323
271static int skl_link_hw_params(struct snd_pcm_substream *substream, 324static int skl_link_hw_params(struct snd_pcm_substream *substream,
272 struct snd_pcm_hw_params *params, 325 struct snd_pcm_hw_params *params,
273 struct snd_soc_dai *dai) 326 struct snd_soc_dai *dai)
@@ -277,9 +330,8 @@ static int skl_link_hw_params(struct snd_pcm_substream *substream,
277 struct snd_soc_pcm_runtime *rtd = snd_pcm_substream_chip(substream); 330 struct snd_soc_pcm_runtime *rtd = snd_pcm_substream_chip(substream);
278 struct skl_dma_params *dma_params; 331 struct skl_dma_params *dma_params;
279 struct snd_soc_dai *codec_dai = rtd->codec_dai; 332 struct snd_soc_dai *codec_dai = rtd->codec_dai;
280 int dma_id; 333 struct skl_pipe_params p_params = {0};
281 334
282 pr_debug("%s\n", __func__);
283 link_dev = snd_hdac_ext_stream_assign(ebus, substream, 335 link_dev = snd_hdac_ext_stream_assign(ebus, substream,
284 HDAC_EXT_STREAM_TYPE_LINK); 336 HDAC_EXT_STREAM_TYPE_LINK);
285 if (!link_dev) 337 if (!link_dev)
@@ -293,7 +345,14 @@ static int skl_link_hw_params(struct snd_pcm_substream *substream,
293 if (dma_params) 345 if (dma_params)
294 dma_params->stream_tag = hdac_stream(link_dev)->stream_tag; 346 dma_params->stream_tag = hdac_stream(link_dev)->stream_tag;
295 snd_soc_dai_set_dma_data(codec_dai, substream, (void *)dma_params); 347 snd_soc_dai_set_dma_data(codec_dai, substream, (void *)dma_params);
296 dma_id = hdac_stream(link_dev)->stream_tag - 1; 348
349 p_params.s_fmt = snd_pcm_format_width(params_format(params));
350 p_params.ch = params_channels(params);
351 p_params.s_freq = params_rate(params);
352 p_params.stream = substream->stream;
353 p_params.link_dma_id = hdac_stream(link_dev)->stream_tag - 1;
354
355 skl_tplg_be_update_params(dai, &p_params);
297 356
298 return 0; 357 return 0;
299} 358}
@@ -308,27 +367,12 @@ static int skl_link_pcm_prepare(struct snd_pcm_substream *substream,
308 unsigned int format_val = 0; 367 unsigned int format_val = 0;
309 struct skl_dma_params *dma_params; 368 struct skl_dma_params *dma_params;
310 struct snd_soc_dai *codec_dai = rtd->codec_dai; 369 struct snd_soc_dai *codec_dai = rtd->codec_dai;
311 struct snd_pcm_hw_params *params;
312 struct snd_interval *channels, *rate;
313 struct hdac_ext_link *link; 370 struct hdac_ext_link *link;
314 371
315 dev_dbg(dai->dev, "%s: %s\n", __func__, dai->name);
316 if (link_dev->link_prepared) { 372 if (link_dev->link_prepared) {
317 dev_dbg(dai->dev, "already stream is prepared - returning\n"); 373 dev_dbg(dai->dev, "already stream is prepared - returning\n");
318 return 0; 374 return 0;
319 } 375 }
320 params = devm_kzalloc(dai->dev, sizeof(*params), GFP_KERNEL);
321 if (params == NULL)
322 return -ENOMEM;
323
324 channels = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS);
325 channels->min = channels->max = substream->runtime->channels;
326 rate = hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE);
327 rate->min = rate->max = substream->runtime->rate;
328 snd_mask_set(&params->masks[SNDRV_PCM_HW_PARAM_FORMAT -
329 SNDRV_PCM_HW_PARAM_FIRST_MASK],
330 substream->runtime->format);
331
332 376
333 dma_params = (struct skl_dma_params *) 377 dma_params = (struct skl_dma_params *)
334 snd_soc_dai_get_dma_data(codec_dai, substream); 378 snd_soc_dai_get_dma_data(codec_dai, substream);
@@ -399,13 +443,13 @@ static int skl_link_hw_free(struct snd_pcm_substream *substream,
399 return 0; 443 return 0;
400} 444}
401 445
402static int skl_hda_be_startup(struct snd_pcm_substream *substream, 446static int skl_be_startup(struct snd_pcm_substream *substream,
403 struct snd_soc_dai *dai) 447 struct snd_soc_dai *dai)
404{ 448{
405 return pm_runtime_get_sync(dai->dev); 449 return pm_runtime_get_sync(dai->dev);
406} 450}
407 451
408static void skl_hda_be_shutdown(struct snd_pcm_substream *substream, 452static void skl_be_shutdown(struct snd_pcm_substream *substream,
409 struct snd_soc_dai *dai) 453 struct snd_soc_dai *dai)
410{ 454{
411 pm_runtime_mark_last_busy(dai->dev); 455 pm_runtime_mark_last_busy(dai->dev);
@@ -418,20 +462,28 @@ static struct snd_soc_dai_ops skl_pcm_dai_ops = {
418 .prepare = skl_pcm_prepare, 462 .prepare = skl_pcm_prepare,
419 .hw_params = skl_pcm_hw_params, 463 .hw_params = skl_pcm_hw_params,
420 .hw_free = skl_pcm_hw_free, 464 .hw_free = skl_pcm_hw_free,
465 .trigger = skl_pcm_trigger,
421}; 466};
422 467
423static struct snd_soc_dai_ops skl_dmic_dai_ops = { 468static struct snd_soc_dai_ops skl_dmic_dai_ops = {
424 .startup = skl_hda_be_startup, 469 .startup = skl_be_startup,
425 .shutdown = skl_hda_be_shutdown, 470 .hw_params = skl_be_hw_params,
471 .shutdown = skl_be_shutdown,
472};
473
474static struct snd_soc_dai_ops skl_be_ssp_dai_ops = {
475 .startup = skl_be_startup,
476 .hw_params = skl_be_hw_params,
477 .shutdown = skl_be_shutdown,
426}; 478};
427 479
428static struct snd_soc_dai_ops skl_link_dai_ops = { 480static struct snd_soc_dai_ops skl_link_dai_ops = {
429 .startup = skl_hda_be_startup, 481 .startup = skl_be_startup,
430 .prepare = skl_link_pcm_prepare, 482 .prepare = skl_link_pcm_prepare,
431 .hw_params = skl_link_hw_params, 483 .hw_params = skl_link_hw_params,
432 .hw_free = skl_link_hw_free, 484 .hw_free = skl_link_hw_free,
433 .trigger = skl_link_pcm_trigger, 485 .trigger = skl_link_pcm_trigger,
434 .shutdown = skl_hda_be_shutdown, 486 .shutdown = skl_be_shutdown,
435}; 487};
436 488
437static struct snd_soc_dai_driver skl_platform_dai[] = { 489static struct snd_soc_dai_driver skl_platform_dai[] = {
@@ -488,6 +540,24 @@ static struct snd_soc_dai_driver skl_platform_dai[] = {
488}, 540},
489/* BE CPU Dais */ 541/* BE CPU Dais */
490{ 542{
543 .name = "SSP0 Pin",
544 .ops = &skl_be_ssp_dai_ops,
545 .playback = {
546 .stream_name = "ssp0 Tx",
547 .channels_min = HDA_STEREO,
548 .channels_max = HDA_STEREO,
549 .rates = SNDRV_PCM_RATE_48000,
550 .formats = SNDRV_PCM_FMTBIT_S16_LE,
551 },
552 .capture = {
553 .stream_name = "ssp0 Rx",
554 .channels_min = HDA_STEREO,
555 .channels_max = HDA_STEREO,
556 .rates = SNDRV_PCM_RATE_48000,
557 .formats = SNDRV_PCM_FMTBIT_S16_LE,
558 },
559},
560{
491 .name = "iDisp Pin", 561 .name = "iDisp Pin",
492 .ops = &skl_link_dai_ops, 562 .ops = &skl_link_dai_ops,
493 .playback = { 563 .playback = {
@@ -510,17 +580,6 @@ static struct snd_soc_dai_driver skl_platform_dai[] = {
510 }, 580 },
511}, 581},
512{ 582{
513 .name = "DMIC23 Pin",
514 .ops = &skl_dmic_dai_ops,
515 .capture = {
516 .stream_name = "DMIC23 Rx",
517 .channels_min = HDA_STEREO,
518 .channels_max = HDA_STEREO,
519 .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_16000,
520 .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE,
521 },
522},
523{
524 .name = "HD-Codec Pin", 583 .name = "HD-Codec Pin",
525 .ops = &skl_link_dai_ops, 584 .ops = &skl_link_dai_ops,
526 .playback = { 585 .playback = {
@@ -538,28 +597,6 @@ static struct snd_soc_dai_driver skl_platform_dai[] = {
538 .formats = SNDRV_PCM_FMTBIT_S16_LE, 597 .formats = SNDRV_PCM_FMTBIT_S16_LE,
539 }, 598 },
540}, 599},
541{
542 .name = "HD-Codec-SPK Pin",
543 .ops = &skl_link_dai_ops,
544 .playback = {
545 .stream_name = "HD-Codec-SPK Tx",
546 .channels_min = HDA_STEREO,
547 .channels_max = HDA_STEREO,
548 .rates = SNDRV_PCM_RATE_48000,
549 .formats = SNDRV_PCM_FMTBIT_S16_LE,
550 },
551},
552{
553 .name = "HD-Codec-AMIC Pin",
554 .ops = &skl_link_dai_ops,
555 .capture = {
556 .stream_name = "HD-Codec-AMIC Rx",
557 .channels_min = HDA_STEREO,
558 .channels_max = HDA_STEREO,
559 .rates = SNDRV_PCM_RATE_48000,
560 .formats = SNDRV_PCM_FMTBIT_S16_LE,
561 },
562},
563}; 600};
564 601
565static int skl_platform_open(struct snd_pcm_substream *substream) 602static int skl_platform_open(struct snd_pcm_substream *substream)
@@ -577,7 +614,7 @@ static int skl_platform_open(struct snd_pcm_substream *substream)
577 return 0; 614 return 0;
578} 615}
579 616
580static int skl_pcm_trigger(struct snd_pcm_substream *substream, 617static int skl_coupled_trigger(struct snd_pcm_substream *substream,
581 int cmd) 618 int cmd)
582{ 619{
583 struct hdac_ext_bus *ebus = get_bus_ctx(substream); 620 struct hdac_ext_bus *ebus = get_bus_ctx(substream);
@@ -651,7 +688,7 @@ static int skl_pcm_trigger(struct snd_pcm_substream *substream,
651 return 0; 688 return 0;
652} 689}
653 690
654static int skl_dsp_trigger(struct snd_pcm_substream *substream, 691static int skl_decoupled_trigger(struct snd_pcm_substream *substream,
655 int cmd) 692 int cmd)
656{ 693{
657 struct hdac_ext_bus *ebus = get_bus_ctx(substream); 694 struct hdac_ext_bus *ebus = get_bus_ctx(substream);
@@ -708,9 +745,9 @@ static int skl_platform_pcm_trigger(struct snd_pcm_substream *substream,
708 struct hdac_ext_bus *ebus = get_bus_ctx(substream); 745 struct hdac_ext_bus *ebus = get_bus_ctx(substream);
709 746
710 if (ebus->ppcap) 747 if (ebus->ppcap)
711 return skl_dsp_trigger(substream, cmd); 748 return skl_decoupled_trigger(substream, cmd);
712 else 749 else
713 return skl_pcm_trigger(substream, cmd); 750 return skl_coupled_trigger(substream, cmd);
714} 751}
715 752
716/* calculate runtime delay from LPIB */ 753/* calculate runtime delay from LPIB */
@@ -877,7 +914,17 @@ static int skl_pcm_new(struct snd_soc_pcm_runtime *rtd)
877 return retval; 914 return retval;
878} 915}
879 916
917static int skl_platform_soc_probe(struct snd_soc_platform *platform)
918{
919 struct hdac_ext_bus *ebus = dev_get_drvdata(platform->dev);
920
921 if (ebus->ppcap)
922 return skl_tplg_init(platform, ebus);
923
924 return 0;
925}
880static struct snd_soc_platform_driver skl_platform_drv = { 926static struct snd_soc_platform_driver skl_platform_drv = {
927 .probe = skl_platform_soc_probe,
881 .ops = &skl_platform_ops, 928 .ops = &skl_platform_ops,
882 .pcm_new = skl_pcm_new, 929 .pcm_new = skl_pcm_new,
883 .pcm_free = skl_pcm_free, 930 .pcm_free = skl_pcm_free,
@@ -890,6 +937,11 @@ static const struct snd_soc_component_driver skl_component = {
890int skl_platform_register(struct device *dev) 937int skl_platform_register(struct device *dev)
891{ 938{
892 int ret; 939 int ret;
940 struct hdac_ext_bus *ebus = dev_get_drvdata(dev);
941 struct skl *skl = ebus_to_skl(ebus);
942
943 INIT_LIST_HEAD(&skl->ppl_list);
944 INIT_LIST_HEAD(&skl->dapm_path_list);
893 945
894 ret = snd_soc_register_platform(dev, &skl_platform_drv); 946 ret = snd_soc_register_platform(dev, &skl_platform_drv);
895 if (ret) { 947 if (ret) {
diff --git a/sound/soc/intel/skylake/skl-sst-dsp.c b/sound/soc/intel/skylake/skl-sst-dsp.c
index 94875b008b0b..1bfb7f63b572 100644
--- a/sound/soc/intel/skylake/skl-sst-dsp.c
+++ b/sound/soc/intel/skylake/skl-sst-dsp.c
@@ -175,7 +175,7 @@ static int skl_dsp_core_power_down(struct sst_dsp *ctx)
175 /* poll with timeout to check if operation successful */ 175 /* poll with timeout to check if operation successful */
176 return sst_dsp_register_poll(ctx, 176 return sst_dsp_register_poll(ctx,
177 SKL_ADSP_REG_ADSPCS, 177 SKL_ADSP_REG_ADSPCS,
178 SKL_ADSPCS_SPA_MASK, 178 SKL_ADSPCS_CPA_MASK,
179 0, 179 0,
180 SKL_DSP_PD_TO, 180 SKL_DSP_PD_TO,
181 "Power down"); 181 "Power down");
@@ -262,6 +262,11 @@ irqreturn_t skl_dsp_sst_interrupt(int irq, void *dev_id)
262 val = sst_dsp_shim_read_unlocked(ctx, SKL_ADSP_REG_ADSPIS); 262 val = sst_dsp_shim_read_unlocked(ctx, SKL_ADSP_REG_ADSPIS);
263 ctx->intr_status = val; 263 ctx->intr_status = val;
264 264
265 if (val == 0xffffffff) {
266 spin_unlock(&ctx->spinlock);
267 return IRQ_NONE;
268 }
269
265 if (val & SKL_ADSPIS_IPC) { 270 if (val & SKL_ADSPIS_IPC) {
266 skl_ipc_int_disable(ctx); 271 skl_ipc_int_disable(ctx);
267 result = IRQ_WAKE_THREAD; 272 result = IRQ_WAKE_THREAD;
diff --git a/sound/soc/intel/skylake/skl-sst-ipc.c b/sound/soc/intel/skylake/skl-sst-ipc.c
index 937a0a3a63a0..3345ea0d4414 100644
--- a/sound/soc/intel/skylake/skl-sst-ipc.c
+++ b/sound/soc/intel/skylake/skl-sst-ipc.c
@@ -464,6 +464,18 @@ void skl_ipc_op_int_enable(struct sst_dsp *ctx)
464 SKL_ADSP_REG_HIPCCTL_BUSY, SKL_ADSP_REG_HIPCCTL_BUSY); 464 SKL_ADSP_REG_HIPCCTL_BUSY, SKL_ADSP_REG_HIPCCTL_BUSY);
465} 465}
466 466
467void skl_ipc_op_int_disable(struct sst_dsp *ctx)
468{
469 /* disable IPC DONE interrupt */
470 sst_dsp_shim_update_bits_unlocked(ctx, SKL_ADSP_REG_HIPCCTL,
471 SKL_ADSP_REG_HIPCCTL_DONE, 0);
472
473 /* Disable IPC BUSY interrupt */
474 sst_dsp_shim_update_bits_unlocked(ctx, SKL_ADSP_REG_HIPCCTL,
475 SKL_ADSP_REG_HIPCCTL_BUSY, 0);
476
477}
478
467bool skl_ipc_int_status(struct sst_dsp *ctx) 479bool skl_ipc_int_status(struct sst_dsp *ctx)
468{ 480{
469 return sst_dsp_shim_read_unlocked(ctx, 481 return sst_dsp_shim_read_unlocked(ctx,
diff --git a/sound/soc/intel/skylake/skl-sst-ipc.h b/sound/soc/intel/skylake/skl-sst-ipc.h
index 9f5f67202858..f1a154e45dc3 100644
--- a/sound/soc/intel/skylake/skl-sst-ipc.h
+++ b/sound/soc/intel/skylake/skl-sst-ipc.h
@@ -116,6 +116,7 @@ int skl_ipc_set_large_config(struct sst_generic_ipc *ipc,
116 116
117void skl_ipc_int_enable(struct sst_dsp *dsp); 117void skl_ipc_int_enable(struct sst_dsp *dsp);
118void skl_ipc_op_int_enable(struct sst_dsp *ctx); 118void skl_ipc_op_int_enable(struct sst_dsp *ctx);
119void skl_ipc_op_int_disable(struct sst_dsp *ctx);
119void skl_ipc_int_disable(struct sst_dsp *dsp); 120void skl_ipc_int_disable(struct sst_dsp *dsp);
120 121
121bool skl_ipc_int_status(struct sst_dsp *dsp); 122bool skl_ipc_int_status(struct sst_dsp *dsp);
diff --git a/sound/soc/intel/skylake/skl-sst.c b/sound/soc/intel/skylake/skl-sst.c
index c18ea51b7484..3b83dc99f1d4 100644
--- a/sound/soc/intel/skylake/skl-sst.c
+++ b/sound/soc/intel/skylake/skl-sst.c
@@ -70,15 +70,31 @@ static int skl_transfer_firmware(struct sst_dsp *ctx,
70static int skl_load_base_firmware(struct sst_dsp *ctx) 70static int skl_load_base_firmware(struct sst_dsp *ctx)
71{ 71{
72 int ret = 0, i; 72 int ret = 0, i;
73 const struct firmware *fw = NULL;
74 struct skl_sst *skl = ctx->thread_context; 73 struct skl_sst *skl = ctx->thread_context;
75 u32 reg; 74 u32 reg;
76 75
77 ret = request_firmware(&fw, "dsp_fw_release.bin", ctx->dev); 76 skl->boot_complete = false;
77 init_waitqueue_head(&skl->boot_wait);
78
79 if (ctx->fw == NULL) {
80 ret = request_firmware(&ctx->fw, "dsp_fw_release.bin", ctx->dev);
81 if (ret < 0) {
82 dev_err(ctx->dev, "Request firmware failed %d\n", ret);
83 skl_dsp_disable_core(ctx);
84 return -EIO;
85 }
86 }
87
88 ret = skl_dsp_boot(ctx);
78 if (ret < 0) { 89 if (ret < 0) {
79 dev_err(ctx->dev, "Request firmware failed %d\n", ret); 90 dev_err(ctx->dev, "Boot dsp core failed ret: %d", ret);
80 skl_dsp_disable_core(ctx); 91 goto skl_load_base_firmware_failed;
81 return -EIO; 92 }
93
94 ret = skl_cldma_prepare(ctx);
95 if (ret < 0) {
96 dev_err(ctx->dev, "CL dma prepare failed : %d", ret);
97 goto skl_load_base_firmware_failed;
82 } 98 }
83 99
84 /* enable Interrupt */ 100 /* enable Interrupt */
@@ -102,7 +118,7 @@ static int skl_load_base_firmware(struct sst_dsp *ctx)
102 goto skl_load_base_firmware_failed; 118 goto skl_load_base_firmware_failed;
103 } 119 }
104 120
105 ret = skl_transfer_firmware(ctx, fw->data, fw->size); 121 ret = skl_transfer_firmware(ctx, ctx->fw->data, ctx->fw->size);
106 if (ret < 0) { 122 if (ret < 0) {
107 dev_err(ctx->dev, "Transfer firmware failed%d\n", ret); 123 dev_err(ctx->dev, "Transfer firmware failed%d\n", ret);
108 goto skl_load_base_firmware_failed; 124 goto skl_load_base_firmware_failed;
@@ -118,13 +134,12 @@ static int skl_load_base_firmware(struct sst_dsp *ctx)
118 dev_dbg(ctx->dev, "Download firmware successful%d\n", ret); 134 dev_dbg(ctx->dev, "Download firmware successful%d\n", ret);
119 skl_dsp_set_state_locked(ctx, SKL_DSP_RUNNING); 135 skl_dsp_set_state_locked(ctx, SKL_DSP_RUNNING);
120 } 136 }
121 release_firmware(fw);
122
123 return 0; 137 return 0;
124 138
125skl_load_base_firmware_failed: 139skl_load_base_firmware_failed:
126 skl_dsp_disable_core(ctx); 140 skl_dsp_disable_core(ctx);
127 release_firmware(fw); 141 release_firmware(ctx->fw);
142 ctx->fw = NULL;
128 return ret; 143 return ret;
129} 144}
130 145
@@ -172,6 +187,12 @@ static int skl_set_dsp_D3(struct sst_dsp *ctx)
172 } 187 }
173 skl_dsp_set_state_locked(ctx, SKL_DSP_RESET); 188 skl_dsp_set_state_locked(ctx, SKL_DSP_RESET);
174 189
190 /* disable Interrupt */
191 ctx->cl_dev.ops.cl_cleanup_controller(ctx);
192 skl_cldma_int_disable(ctx);
193 skl_ipc_op_int_disable(ctx);
194 skl_ipc_int_disable(ctx);
195
175 return ret; 196 return ret;
176} 197}
177 198
@@ -235,22 +256,6 @@ int skl_sst_dsp_init(struct device *dev, void __iomem *mmio_base, int irq,
235 if (ret) 256 if (ret)
236 return ret; 257 return ret;
237 258
238 skl->boot_complete = false;
239 init_waitqueue_head(&skl->boot_wait);
240
241 ret = skl_dsp_boot(sst);
242 if (ret < 0) {
243 dev_err(skl->dev, "Boot dsp core failed ret: %d", ret);
244 goto free_ipc;
245 }
246
247 ret = skl_cldma_prepare(sst);
248 if (ret < 0) {
249 dev_err(dev, "CL dma prepare failed : %d", ret);
250 goto free_ipc;
251 }
252
253
254 ret = sst->fw_ops.load_fw(sst); 259 ret = sst->fw_ops.load_fw(sst);
255 if (ret < 0) { 260 if (ret < 0) {
256 dev_err(dev, "Load base fw failed : %d", ret); 261 dev_err(dev, "Load base fw failed : %d", ret);
@@ -262,7 +267,6 @@ int skl_sst_dsp_init(struct device *dev, void __iomem *mmio_base, int irq,
262 267
263 return 0; 268 return 0;
264 269
265free_ipc:
266 skl_ipc_free(&skl->ipc); 270 skl_ipc_free(&skl->ipc);
267 return ret; 271 return ret;
268} 272}
diff --git a/sound/soc/intel/skylake/skl-topology.c b/sound/soc/intel/skylake/skl-topology.c
new file mode 100644
index 000000000000..a7854c8fc523
--- /dev/null
+++ b/sound/soc/intel/skylake/skl-topology.c
@@ -0,0 +1,1252 @@
1/*
2 * skl-topology.c - Implements Platform component ALSA controls/widget
3 * handlers.
4 *
5 * Copyright (C) 2014-2015 Intel Corp
6 * Author: Jeeja KP <jeeja.kp@intel.com>
7 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as version 2, as
11 * published by the Free Software Foundation.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 */
18
19#include <linux/slab.h>
20#include <linux/types.h>
21#include <linux/firmware.h>
22#include <sound/soc.h>
23#include <sound/soc-topology.h>
24#include "skl-sst-dsp.h"
25#include "skl-sst-ipc.h"
26#include "skl-topology.h"
27#include "skl.h"
28#include "skl-tplg-interface.h"
29
30#define SKL_CH_FIXUP_MASK (1 << 0)
31#define SKL_RATE_FIXUP_MASK (1 << 1)
32#define SKL_FMT_FIXUP_MASK (1 << 2)
33
34/*
35 * SKL DSP driver modelling uses only few DAPM widgets so for rest we will
36 * ignore. This helpers checks if the SKL driver handles this widget type
37 */
38static int is_skl_dsp_widget_type(struct snd_soc_dapm_widget *w)
39{
40 switch (w->id) {
41 case snd_soc_dapm_dai_link:
42 case snd_soc_dapm_dai_in:
43 case snd_soc_dapm_aif_in:
44 case snd_soc_dapm_aif_out:
45 case snd_soc_dapm_dai_out:
46 case snd_soc_dapm_switch:
47 return false;
48 default:
49 return true;
50 }
51}
52
53/*
54 * Each pipelines needs memory to be allocated. Check if we have free memory
55 * from available pool. Then only add this to pool
56 * This is freed when pipe is deleted
57 * Note: DSP does actual memory management we only keep track for complete
58 * pool
59 */
60static bool skl_tplg_alloc_pipe_mem(struct skl *skl,
61 struct skl_module_cfg *mconfig)
62{
63 struct skl_sst *ctx = skl->skl_sst;
64
65 if (skl->resource.mem + mconfig->pipe->memory_pages >
66 skl->resource.max_mem) {
67 dev_err(ctx->dev,
68 "%s: module_id %d instance %d\n", __func__,
69 mconfig->id.module_id,
70 mconfig->id.instance_id);
71 dev_err(ctx->dev,
72 "exceeds ppl memory available %d mem %d\n",
73 skl->resource.max_mem, skl->resource.mem);
74 return false;
75 }
76
77 skl->resource.mem += mconfig->pipe->memory_pages;
78 return true;
79}
80
81/*
82 * Pipeline needs needs DSP CPU resources for computation, this is
83 * quantified in MCPS (Million Clocks Per Second) required for module/pipe
84 *
85 * Each pipelines needs mcps to be allocated. Check if we have mcps for this
86 * pipe. This adds the mcps to driver counter
87 * This is removed on pipeline delete
88 */
89static bool skl_tplg_alloc_pipe_mcps(struct skl *skl,
90 struct skl_module_cfg *mconfig)
91{
92 struct skl_sst *ctx = skl->skl_sst;
93
94 if (skl->resource.mcps + mconfig->mcps > skl->resource.max_mcps) {
95 dev_err(ctx->dev,
96 "%s: module_id %d instance %d\n", __func__,
97 mconfig->id.module_id, mconfig->id.instance_id);
98 dev_err(ctx->dev,
99 "exceeds ppl memory available %d > mem %d\n",
100 skl->resource.max_mcps, skl->resource.mcps);
101 return false;
102 }
103
104 skl->resource.mcps += mconfig->mcps;
105 return true;
106}
107
108/*
109 * Free the mcps when tearing down
110 */
111static void
112skl_tplg_free_pipe_mcps(struct skl *skl, struct skl_module_cfg *mconfig)
113{
114 skl->resource.mcps -= mconfig->mcps;
115}
116
117/*
118 * Free the memory when tearing down
119 */
120static void
121skl_tplg_free_pipe_mem(struct skl *skl, struct skl_module_cfg *mconfig)
122{
123 skl->resource.mem -= mconfig->pipe->memory_pages;
124}
125
126
127static void skl_dump_mconfig(struct skl_sst *ctx,
128 struct skl_module_cfg *mcfg)
129{
130 dev_dbg(ctx->dev, "Dumping config\n");
131 dev_dbg(ctx->dev, "Input Format:\n");
132 dev_dbg(ctx->dev, "channels = %d\n", mcfg->in_fmt.channels);
133 dev_dbg(ctx->dev, "s_freq = %d\n", mcfg->in_fmt.s_freq);
134 dev_dbg(ctx->dev, "ch_cfg = %d\n", mcfg->in_fmt.ch_cfg);
135 dev_dbg(ctx->dev, "valid bit depth = %d\n",
136 mcfg->in_fmt.valid_bit_depth);
137 dev_dbg(ctx->dev, "Output Format:\n");
138 dev_dbg(ctx->dev, "channels = %d\n", mcfg->out_fmt.channels);
139 dev_dbg(ctx->dev, "s_freq = %d\n", mcfg->out_fmt.s_freq);
140 dev_dbg(ctx->dev, "valid bit depth = %d\n",
141 mcfg->out_fmt.valid_bit_depth);
142 dev_dbg(ctx->dev, "ch_cfg = %d\n", mcfg->out_fmt.ch_cfg);
143}
144
145static void skl_tplg_update_params(struct skl_module_fmt *fmt,
146 struct skl_pipe_params *params, int fixup)
147{
148 if (fixup & SKL_RATE_FIXUP_MASK)
149 fmt->s_freq = params->s_freq;
150 if (fixup & SKL_CH_FIXUP_MASK)
151 fmt->channels = params->ch;
152 if (fixup & SKL_FMT_FIXUP_MASK)
153 fmt->valid_bit_depth = params->s_fmt;
154}
155
156/*
157 * A pipeline may have modules which impact the pcm parameters, like SRC,
158 * channel converter, format converter.
159 * We need to calculate the output params by applying the 'fixup'
160 * Topology will tell driver which type of fixup is to be applied by
161 * supplying the fixup mask, so based on that we calculate the output
162 *
163 * Now In FE the pcm hw_params is source/target format. Same is applicable
164 * for BE with its hw_params invoked.
165 * here based on FE, BE pipeline and direction we calculate the input and
166 * outfix and then apply that for a module
167 */
168static void skl_tplg_update_params_fixup(struct skl_module_cfg *m_cfg,
169 struct skl_pipe_params *params, bool is_fe)
170{
171 int in_fixup, out_fixup;
172 struct skl_module_fmt *in_fmt, *out_fmt;
173
174 in_fmt = &m_cfg->in_fmt;
175 out_fmt = &m_cfg->out_fmt;
176
177 if (params->stream == SNDRV_PCM_STREAM_PLAYBACK) {
178 if (is_fe) {
179 in_fixup = m_cfg->params_fixup;
180 out_fixup = (~m_cfg->converter) &
181 m_cfg->params_fixup;
182 } else {
183 out_fixup = m_cfg->params_fixup;
184 in_fixup = (~m_cfg->converter) &
185 m_cfg->params_fixup;
186 }
187 } else {
188 if (is_fe) {
189 out_fixup = m_cfg->params_fixup;
190 in_fixup = (~m_cfg->converter) &
191 m_cfg->params_fixup;
192 } else {
193 in_fixup = m_cfg->params_fixup;
194 out_fixup = (~m_cfg->converter) &
195 m_cfg->params_fixup;
196 }
197 }
198
199 skl_tplg_update_params(in_fmt, params, in_fixup);
200 skl_tplg_update_params(out_fmt, params, out_fixup);
201}
202
203/*
204 * A module needs input and output buffers, which are dependent upon pcm
205 * params, so once we have calculate params, we need buffer calculation as
206 * well.
207 */
208static void skl_tplg_update_buffer_size(struct skl_sst *ctx,
209 struct skl_module_cfg *mcfg)
210{
211 int multiplier = 1;
212
213 if (mcfg->m_type == SKL_MODULE_TYPE_SRCINT)
214 multiplier = 5;
215
216 mcfg->ibs = (mcfg->in_fmt.s_freq / 1000) *
217 (mcfg->in_fmt.channels) *
218 (mcfg->in_fmt.bit_depth >> 3) *
219 multiplier;
220
221 mcfg->obs = (mcfg->out_fmt.s_freq / 1000) *
222 (mcfg->out_fmt.channels) *
223 (mcfg->out_fmt.bit_depth >> 3) *
224 multiplier;
225}
226
227static void skl_tplg_update_module_params(struct snd_soc_dapm_widget *w,
228 struct skl_sst *ctx)
229{
230 struct skl_module_cfg *m_cfg = w->priv;
231 struct skl_pipe_params *params = m_cfg->pipe->p_params;
232 int p_conn_type = m_cfg->pipe->conn_type;
233 bool is_fe;
234
235 if (!m_cfg->params_fixup)
236 return;
237
238 dev_dbg(ctx->dev, "Mconfig for widget=%s BEFORE updation\n",
239 w->name);
240
241 skl_dump_mconfig(ctx, m_cfg);
242
243 if (p_conn_type == SKL_PIPE_CONN_TYPE_FE)
244 is_fe = true;
245 else
246 is_fe = false;
247
248 skl_tplg_update_params_fixup(m_cfg, params, is_fe);
249 skl_tplg_update_buffer_size(ctx, m_cfg);
250
251 dev_dbg(ctx->dev, "Mconfig for widget=%s AFTER updation\n",
252 w->name);
253
254 skl_dump_mconfig(ctx, m_cfg);
255}
256
257/*
258 * A pipe can have multiple modules, each of them will be a DAPM widget as
259 * well. While managing a pipeline we need to get the list of all the
260 * widgets in a pipelines, so this helper - skl_tplg_get_pipe_widget() helps
261 * to get the SKL type widgets in that pipeline
262 */
263static int skl_tplg_alloc_pipe_widget(struct device *dev,
264 struct snd_soc_dapm_widget *w, struct skl_pipe *pipe)
265{
266 struct skl_module_cfg *src_module = NULL;
267 struct snd_soc_dapm_path *p = NULL;
268 struct skl_pipe_module *p_module = NULL;
269
270 p_module = devm_kzalloc(dev, sizeof(*p_module), GFP_KERNEL);
271 if (!p_module)
272 return -ENOMEM;
273
274 p_module->w = w;
275 list_add_tail(&p_module->node, &pipe->w_list);
276
277 snd_soc_dapm_widget_for_each_sink_path(w, p) {
278 if ((p->sink->priv == NULL)
279 && (!is_skl_dsp_widget_type(w)))
280 continue;
281
282 if ((p->sink->priv != NULL) && p->connect
283 && is_skl_dsp_widget_type(p->sink)) {
284
285 src_module = p->sink->priv;
286 if (pipe->ppl_id == src_module->pipe->ppl_id)
287 skl_tplg_alloc_pipe_widget(dev,
288 p->sink, pipe);
289 }
290 }
291 return 0;
292}
293
294/*
295 * Inside a pipe instance, we can have various modules. These modules need
296 * to instantiated in DSP by invoking INIT_MODULE IPC, which is achieved by
297 * skl_init_module() routine, so invoke that for all modules in a pipeline
298 */
299static int
300skl_tplg_init_pipe_modules(struct skl *skl, struct skl_pipe *pipe)
301{
302 struct skl_pipe_module *w_module;
303 struct snd_soc_dapm_widget *w;
304 struct skl_module_cfg *mconfig;
305 struct skl_sst *ctx = skl->skl_sst;
306 int ret = 0;
307
308 list_for_each_entry(w_module, &pipe->w_list, node) {
309 w = w_module->w;
310 mconfig = w->priv;
311
312 /* check resource available */
313 if (!skl_tplg_alloc_pipe_mcps(skl, mconfig))
314 return -ENOMEM;
315
316 /*
317 * apply fix/conversion to module params based on
318 * FE/BE params
319 */
320 skl_tplg_update_module_params(w, ctx);
321 ret = skl_init_module(ctx, mconfig, NULL);
322 if (ret < 0)
323 return ret;
324 }
325
326 return 0;
327}
328
329/*
330 * Mixer module represents a pipeline. So in the Pre-PMU event of mixer we
331 * need create the pipeline. So we do following:
332 * - check the resources
333 * - Create the pipeline
334 * - Initialize the modules in pipeline
335 * - finally bind all modules together
336 */
337static int skl_tplg_mixer_dapm_pre_pmu_event(struct snd_soc_dapm_widget *w,
338 struct skl *skl)
339{
340 int ret;
341 struct skl_module_cfg *mconfig = w->priv;
342 struct skl_pipe_module *w_module;
343 struct skl_pipe *s_pipe = mconfig->pipe;
344 struct skl_module_cfg *src_module = NULL, *dst_module;
345 struct skl_sst *ctx = skl->skl_sst;
346
347 /* check resource available */
348 if (!skl_tplg_alloc_pipe_mcps(skl, mconfig))
349 return -EBUSY;
350
351 if (!skl_tplg_alloc_pipe_mem(skl, mconfig))
352 return -ENOMEM;
353
354 /*
355 * Create a list of modules for pipe.
356 * This list contains modules from source to sink
357 */
358 ret = skl_create_pipeline(ctx, mconfig->pipe);
359 if (ret < 0)
360 return ret;
361
362 /*
363 * we create a w_list of all widgets in that pipe. This list is not
364 * freed on PMD event as widgets within a pipe are static. This
365 * saves us cycles to get widgets in pipe every time.
366 *
367 * So if we have already initialized all the widgets of a pipeline
368 * we skip, so check for list_empty and create the list if empty
369 */
370 if (list_empty(&s_pipe->w_list)) {
371 ret = skl_tplg_alloc_pipe_widget(ctx->dev, w, s_pipe);
372 if (ret < 0)
373 return ret;
374 }
375
376 /* Init all pipe modules from source to sink */
377 ret = skl_tplg_init_pipe_modules(skl, s_pipe);
378 if (ret < 0)
379 return ret;
380
381 /* Bind modules from source to sink */
382 list_for_each_entry(w_module, &s_pipe->w_list, node) {
383 dst_module = w_module->w->priv;
384
385 if (src_module == NULL) {
386 src_module = dst_module;
387 continue;
388 }
389
390 ret = skl_bind_modules(ctx, src_module, dst_module);
391 if (ret < 0)
392 return ret;
393
394 src_module = dst_module;
395 }
396
397 return 0;
398}
399
400/*
401 * A PGA represents a module in a pipeline. So in the Pre-PMU event of PGA
402 * we need to do following:
403 * - Bind to sink pipeline
404 * Since the sink pipes can be running and we don't get mixer event on
405 * connect for already running mixer, we need to find the sink pipes
406 * here and bind to them. This way dynamic connect works.
407 * - Start sink pipeline, if not running
408 * - Then run current pipe
409 */
410static int skl_tplg_pga_dapm_pre_pmu_event(struct snd_soc_dapm_widget *w,
411 struct skl *skl)
412{
413 struct snd_soc_dapm_path *p;
414 struct skl_dapm_path_list *path_list;
415 struct snd_soc_dapm_widget *source, *sink;
416 struct skl_module_cfg *src_mconfig, *sink_mconfig;
417 struct skl_sst *ctx = skl->skl_sst;
418 int ret = 0;
419
420 source = w;
421 src_mconfig = source->priv;
422
423 /*
424 * find which sink it is connected to, bind with the sink,
425 * if sink is not started, start sink pipe first, then start
426 * this pipe
427 */
428 snd_soc_dapm_widget_for_each_source_path(w, p) {
429 if (!p->connect)
430 continue;
431
432 dev_dbg(ctx->dev, "%s: src widget=%s\n", __func__, w->name);
433 dev_dbg(ctx->dev, "%s: sink widget=%s\n", __func__, p->sink->name);
434
435 /*
436 * here we will check widgets in sink pipelines, so that
437 * can be any widgets type and we are only interested if
438 * they are ones used for SKL so check that first
439 */
440 if ((p->sink->priv != NULL) &&
441 is_skl_dsp_widget_type(p->sink)) {
442
443 sink = p->sink;
444 src_mconfig = source->priv;
445 sink_mconfig = sink->priv;
446
447 /* Bind source to sink, mixin is always source */
448 ret = skl_bind_modules(ctx, src_mconfig, sink_mconfig);
449 if (ret)
450 return ret;
451
452 /* Start sinks pipe first */
453 if (sink_mconfig->pipe->state != SKL_PIPE_STARTED) {
454 ret = skl_run_pipe(ctx, sink_mconfig->pipe);
455 if (ret)
456 return ret;
457 }
458
459 path_list = kzalloc(
460 sizeof(struct skl_dapm_path_list),
461 GFP_KERNEL);
462 if (path_list == NULL)
463 return -ENOMEM;
464
465 /* Add connected path to one global list */
466 path_list->dapm_path = p;
467 list_add_tail(&path_list->node, &skl->dapm_path_list);
468 break;
469 }
470 }
471
472 /* Start source pipe last after starting all sinks */
473 ret = skl_run_pipe(ctx, src_mconfig->pipe);
474 if (ret)
475 return ret;
476
477 return 0;
478}
479
480/*
481 * in the Post-PMU event of mixer we need to do following:
482 * - Check if this pipe is running
483 * - if not, then
484 * - bind this pipeline to its source pipeline
485 * if source pipe is already running, this means it is a dynamic
486 * connection and we need to bind only to that pipe
487 * - start this pipeline
488 */
489static int skl_tplg_mixer_dapm_post_pmu_event(struct snd_soc_dapm_widget *w,
490 struct skl *skl)
491{
492 int ret = 0;
493 struct snd_soc_dapm_path *p;
494 struct snd_soc_dapm_widget *source, *sink;
495 struct skl_module_cfg *src_mconfig, *sink_mconfig;
496 struct skl_sst *ctx = skl->skl_sst;
497 int src_pipe_started = 0;
498
499 sink = w;
500 sink_mconfig = sink->priv;
501
502 /*
503 * If source pipe is already started, that means source is driving
504 * one more sink before this sink got connected, Since source is
505 * started, bind this sink to source and start this pipe.
506 */
507 snd_soc_dapm_widget_for_each_sink_path(w, p) {
508 if (!p->connect)
509 continue;
510
511 dev_dbg(ctx->dev, "sink widget=%s\n", w->name);
512 dev_dbg(ctx->dev, "src widget=%s\n", p->source->name);
513
514 /*
515 * here we will check widgets in sink pipelines, so that
516 * can be any widgets type and we are only interested if
517 * they are ones used for SKL so check that first
518 */
519 if ((p->source->priv != NULL) &&
520 is_skl_dsp_widget_type(p->source)) {
521 source = p->source;
522 src_mconfig = source->priv;
523 sink_mconfig = sink->priv;
524 src_pipe_started = 1;
525
526 /*
527 * check pipe state, then no need to bind or start
528 * the pipe
529 */
530 if (src_mconfig->pipe->state != SKL_PIPE_STARTED)
531 src_pipe_started = 0;
532 }
533 }
534
535 if (src_pipe_started) {
536 ret = skl_bind_modules(ctx, src_mconfig, sink_mconfig);
537 if (ret)
538 return ret;
539
540 ret = skl_run_pipe(ctx, sink_mconfig->pipe);
541 }
542
543 return ret;
544}
545
546/*
547 * in the Pre-PMD event of mixer we need to do following:
548 * - Stop the pipe
549 * - find the source connections and remove that from dapm_path_list
550 * - unbind with source pipelines if still connected
551 */
552static int skl_tplg_mixer_dapm_pre_pmd_event(struct snd_soc_dapm_widget *w,
553 struct skl *skl)
554{
555 struct snd_soc_dapm_widget *source, *sink;
556 struct skl_module_cfg *src_mconfig, *sink_mconfig;
557 int ret = 0, path_found = 0;
558 struct skl_dapm_path_list *path_list, *tmp_list;
559 struct skl_sst *ctx = skl->skl_sst;
560
561 sink = w;
562 sink_mconfig = sink->priv;
563
564 /* Stop the pipe */
565 ret = skl_stop_pipe(ctx, sink_mconfig->pipe);
566 if (ret)
567 return ret;
568
569 /*
570 * This list, dapm_path_list handling here does not need any locks
571 * as we are under dapm lock while handling widget events.
572 * List can be manipulated safely only under dapm widgets handler
573 * routines
574 */
575 list_for_each_entry_safe(path_list, tmp_list,
576 &skl->dapm_path_list, node) {
577 if (path_list->dapm_path->sink == sink) {
578 dev_dbg(ctx->dev, "Path found = %s\n",
579 path_list->dapm_path->name);
580 source = path_list->dapm_path->source;
581 src_mconfig = source->priv;
582 path_found = 1;
583
584 list_del(&path_list->node);
585 kfree(path_list);
586 break;
587 }
588 }
589
590 /*
591 * If path_found == 1, that means pmd for source pipe has
592 * not occurred, source is connected to some other sink.
593 * so its responsibility of sink to unbind itself from source.
594 */
595 if (path_found) {
596 ret = skl_stop_pipe(ctx, src_mconfig->pipe);
597 if (ret < 0)
598 return ret;
599
600 ret = skl_unbind_modules(ctx, src_mconfig, sink_mconfig);
601 }
602
603 return ret;
604}
605
606/*
607 * in the Post-PMD event of mixer we need to do following:
608 * - Free the mcps used
609 * - Free the mem used
610 * - Unbind the modules within the pipeline
611 * - Delete the pipeline (modules are not required to be explicitly
612 * deleted, pipeline delete is enough here
613 */
614static int skl_tplg_mixer_dapm_post_pmd_event(struct snd_soc_dapm_widget *w,
615 struct skl *skl)
616{
617 struct skl_module_cfg *mconfig = w->priv;
618 struct skl_pipe_module *w_module;
619 struct skl_module_cfg *src_module = NULL, *dst_module;
620 struct skl_sst *ctx = skl->skl_sst;
621 struct skl_pipe *s_pipe = mconfig->pipe;
622 int ret = 0;
623
624 skl_tplg_free_pipe_mcps(skl, mconfig);
625
626 list_for_each_entry(w_module, &s_pipe->w_list, node) {
627 dst_module = w_module->w->priv;
628
629 if (src_module == NULL) {
630 src_module = dst_module;
631 continue;
632 }
633
634 ret = skl_unbind_modules(ctx, src_module, dst_module);
635 if (ret < 0)
636 return ret;
637
638 src_module = dst_module;
639 }
640
641 ret = skl_delete_pipe(ctx, mconfig->pipe);
642 skl_tplg_free_pipe_mem(skl, mconfig);
643
644 return ret;
645}
646
647/*
648 * in the Post-PMD event of PGA we need to do following:
649 * - Free the mcps used
650 * - Stop the pipeline
651 * - In source pipe is connected, unbind with source pipelines
652 */
653static int skl_tplg_pga_dapm_post_pmd_event(struct snd_soc_dapm_widget *w,
654 struct skl *skl)
655{
656 struct snd_soc_dapm_widget *source, *sink;
657 struct skl_module_cfg *src_mconfig, *sink_mconfig;
658 int ret = 0, path_found = 0;
659 struct skl_dapm_path_list *path_list, *tmp_path_list;
660 struct skl_sst *ctx = skl->skl_sst;
661
662 source = w;
663 src_mconfig = source->priv;
664
665 skl_tplg_free_pipe_mcps(skl, src_mconfig);
666 /* Stop the pipe since this is a mixin module */
667 ret = skl_stop_pipe(ctx, src_mconfig->pipe);
668 if (ret)
669 return ret;
670
671 list_for_each_entry_safe(path_list, tmp_path_list, &skl->dapm_path_list, node) {
672 if (path_list->dapm_path->source == source) {
673 dev_dbg(ctx->dev, "Path found = %s\n",
674 path_list->dapm_path->name);
675 sink = path_list->dapm_path->sink;
676 sink_mconfig = sink->priv;
677 path_found = 1;
678
679 list_del(&path_list->node);
680 kfree(path_list);
681 break;
682 }
683 }
684
685 /*
686 * This is a connector and if path is found that means
687 * unbind between source and sink has not happened yet
688 */
689 if (path_found) {
690 ret = skl_stop_pipe(ctx, src_mconfig->pipe);
691 if (ret < 0)
692 return ret;
693
694 ret = skl_unbind_modules(ctx, src_mconfig, sink_mconfig);
695 }
696
697 return ret;
698}
699
700/*
701 * In modelling, we assume there will be ONLY one mixer in a pipeline. If
702 * mixer is not required then it is treated as static mixer aka vmixer with
703 * a hard path to source module
704 * So we don't need to check if source is started or not as hard path puts
705 * dependency on each other
706 */
707static int skl_tplg_vmixer_event(struct snd_soc_dapm_widget *w,
708 struct snd_kcontrol *k, int event)
709{
710 struct snd_soc_dapm_context *dapm = w->dapm;
711 struct skl *skl = get_skl_ctx(dapm->dev);
712
713 switch (event) {
714 case SND_SOC_DAPM_PRE_PMU:
715 return skl_tplg_mixer_dapm_pre_pmu_event(w, skl);
716
717 case SND_SOC_DAPM_POST_PMD:
718 return skl_tplg_mixer_dapm_post_pmd_event(w, skl);
719 }
720
721 return 0;
722}
723
724/*
725 * In modelling, we assume there will be ONLY one mixer in a pipeline. If a
726 * second one is required that is created as another pipe entity.
727 * The mixer is responsible for pipe management and represent a pipeline
728 * instance
729 */
730static int skl_tplg_mixer_event(struct snd_soc_dapm_widget *w,
731 struct snd_kcontrol *k, int event)
732{
733 struct snd_soc_dapm_context *dapm = w->dapm;
734 struct skl *skl = get_skl_ctx(dapm->dev);
735
736 switch (event) {
737 case SND_SOC_DAPM_PRE_PMU:
738 return skl_tplg_mixer_dapm_pre_pmu_event(w, skl);
739
740 case SND_SOC_DAPM_POST_PMU:
741 return skl_tplg_mixer_dapm_post_pmu_event(w, skl);
742
743 case SND_SOC_DAPM_PRE_PMD:
744 return skl_tplg_mixer_dapm_pre_pmd_event(w, skl);
745
746 case SND_SOC_DAPM_POST_PMD:
747 return skl_tplg_mixer_dapm_post_pmd_event(w, skl);
748 }
749
750 return 0;
751}
752
753/*
754 * In modelling, we assumed rest of the modules in pipeline are PGA. But we
755 * are interested in last PGA (leaf PGA) in a pipeline to disconnect with
756 * the sink when it is running (two FE to one BE or one FE to two BE)
757 * scenarios
758 */
759static int skl_tplg_pga_event(struct snd_soc_dapm_widget *w,
760 struct snd_kcontrol *k, int event)
761
762{
763 struct snd_soc_dapm_context *dapm = w->dapm;
764 struct skl *skl = get_skl_ctx(dapm->dev);
765
766 switch (event) {
767 case SND_SOC_DAPM_PRE_PMU:
768 return skl_tplg_pga_dapm_pre_pmu_event(w, skl);
769
770 case SND_SOC_DAPM_POST_PMD:
771 return skl_tplg_pga_dapm_post_pmd_event(w, skl);
772 }
773
774 return 0;
775}
776
777/*
778 * The FE params are passed by hw_params of the DAI.
779 * On hw_params, the params are stored in Gateway module of the FE and we
780 * need to calculate the format in DSP module configuration, that
781 * conversion is done here
782 */
783int skl_tplg_update_pipe_params(struct device *dev,
784 struct skl_module_cfg *mconfig,
785 struct skl_pipe_params *params)
786{
787 struct skl_pipe *pipe = mconfig->pipe;
788 struct skl_module_fmt *format = NULL;
789
790 memcpy(pipe->p_params, params, sizeof(*params));
791
792 if (params->stream == SNDRV_PCM_STREAM_PLAYBACK)
793 format = &mconfig->in_fmt;
794 else
795 format = &mconfig->out_fmt;
796
797 /* set the hw_params */
798 format->s_freq = params->s_freq;
799 format->channels = params->ch;
800 format->valid_bit_depth = skl_get_bit_depth(params->s_fmt);
801
802 /*
803 * 16 bit is 16 bit container whereas 24 bit is in 32 bit
804 * container so update bit depth accordingly
805 */
806 switch (format->valid_bit_depth) {
807 case SKL_DEPTH_16BIT:
808 format->bit_depth = format->valid_bit_depth;
809 break;
810
811 case SKL_DEPTH_24BIT:
812 format->bit_depth = SKL_DEPTH_32BIT;
813 break;
814
815 default:
816 dev_err(dev, "Invalid bit depth %x for pipe\n",
817 format->valid_bit_depth);
818 return -EINVAL;
819 }
820
821 if (params->stream == SNDRV_PCM_STREAM_PLAYBACK) {
822 mconfig->ibs = (format->s_freq / 1000) *
823 (format->channels) *
824 (format->bit_depth >> 3);
825 } else {
826 mconfig->obs = (format->s_freq / 1000) *
827 (format->channels) *
828 (format->bit_depth >> 3);
829 }
830
831 return 0;
832}
833
834/*
835 * Query the module config for the FE DAI
836 * This is used to find the hw_params set for that DAI and apply to FE
837 * pipeline
838 */
839struct skl_module_cfg *
840skl_tplg_fe_get_cpr_module(struct snd_soc_dai *dai, int stream)
841{
842 struct snd_soc_dapm_widget *w;
843 struct snd_soc_dapm_path *p = NULL;
844
845 if (stream == SNDRV_PCM_STREAM_PLAYBACK) {
846 w = dai->playback_widget;
847 snd_soc_dapm_widget_for_each_sink_path(w, p) {
848 if (p->connect && p->sink->power &&
849 is_skl_dsp_widget_type(p->sink))
850 continue;
851
852 if (p->sink->priv) {
853 dev_dbg(dai->dev, "set params for %s\n",
854 p->sink->name);
855 return p->sink->priv;
856 }
857 }
858 } else {
859 w = dai->capture_widget;
860 snd_soc_dapm_widget_for_each_source_path(w, p) {
861 if (p->connect && p->source->power &&
862 is_skl_dsp_widget_type(p->source))
863 continue;
864
865 if (p->source->priv) {
866 dev_dbg(dai->dev, "set params for %s\n",
867 p->source->name);
868 return p->source->priv;
869 }
870 }
871 }
872
873 return NULL;
874}
875
876static u8 skl_tplg_be_link_type(int dev_type)
877{
878 int ret;
879
880 switch (dev_type) {
881 case SKL_DEVICE_BT:
882 ret = NHLT_LINK_SSP;
883 break;
884
885 case SKL_DEVICE_DMIC:
886 ret = NHLT_LINK_DMIC;
887 break;
888
889 case SKL_DEVICE_I2S:
890 ret = NHLT_LINK_SSP;
891 break;
892
893 case SKL_DEVICE_HDALINK:
894 ret = NHLT_LINK_HDA;
895 break;
896
897 default:
898 ret = NHLT_LINK_INVALID;
899 break;
900 }
901
902 return ret;
903}
904
905/*
906 * Fill the BE gateway parameters
907 * The BE gateway expects a blob of parameters which are kept in the ACPI
908 * NHLT blob, so query the blob for interface type (i2s/pdm) and instance.
909 * The port can have multiple settings so pick based on the PCM
910 * parameters
911 */
912static int skl_tplg_be_fill_pipe_params(struct snd_soc_dai *dai,
913 struct skl_module_cfg *mconfig,
914 struct skl_pipe_params *params)
915{
916 struct skl_pipe *pipe = mconfig->pipe;
917 struct nhlt_specific_cfg *cfg;
918 struct skl *skl = get_skl_ctx(dai->dev);
919 int link_type = skl_tplg_be_link_type(mconfig->dev_type);
920
921 memcpy(pipe->p_params, params, sizeof(*params));
922
923 /* update the blob based on virtual bus_id*/
924 cfg = skl_get_ep_blob(skl, mconfig->vbus_id, link_type,
925 params->s_fmt, params->ch,
926 params->s_freq, params->stream);
927 if (cfg) {
928 mconfig->formats_config.caps_size = cfg->size;
929 mconfig->formats_config.caps = (u32 *) &cfg->caps;
930 } else {
931 dev_err(dai->dev, "Blob NULL for id %x type %d dirn %d\n",
932 mconfig->vbus_id, link_type,
933 params->stream);
934 dev_err(dai->dev, "PCM: ch %d, freq %d, fmt %d\n",
935 params->ch, params->s_freq, params->s_fmt);
936 return -EINVAL;
937 }
938
939 return 0;
940}
941
942static int skl_tplg_be_set_src_pipe_params(struct snd_soc_dai *dai,
943 struct snd_soc_dapm_widget *w,
944 struct skl_pipe_params *params)
945{
946 struct snd_soc_dapm_path *p;
947 int ret = -EIO;
948
949 snd_soc_dapm_widget_for_each_source_path(w, p) {
950 if (p->connect && is_skl_dsp_widget_type(p->source) &&
951 p->source->priv) {
952
953 if (!p->source->power) {
954 ret = skl_tplg_be_fill_pipe_params(
955 dai, p->source->priv,
956 params);
957 if (ret < 0)
958 return ret;
959 } else {
960 return -EBUSY;
961 }
962 } else {
963 ret = skl_tplg_be_set_src_pipe_params(
964 dai, p->source, params);
965 if (ret < 0)
966 return ret;
967 }
968 }
969
970 return ret;
971}
972
973static int skl_tplg_be_set_sink_pipe_params(struct snd_soc_dai *dai,
974 struct snd_soc_dapm_widget *w, struct skl_pipe_params *params)
975{
976 struct snd_soc_dapm_path *p = NULL;
977 int ret = -EIO;
978
979 snd_soc_dapm_widget_for_each_sink_path(w, p) {
980 if (p->connect && is_skl_dsp_widget_type(p->sink) &&
981 p->sink->priv) {
982
983 if (!p->sink->power) {
984 ret = skl_tplg_be_fill_pipe_params(
985 dai, p->sink->priv, params);
986 if (ret < 0)
987 return ret;
988 } else {
989 return -EBUSY;
990 }
991
992 } else {
993 ret = skl_tplg_be_set_sink_pipe_params(
994 dai, p->sink, params);
995 if (ret < 0)
996 return ret;
997 }
998 }
999
1000 return ret;
1001}
1002
1003/*
1004 * BE hw_params can be a source parameters (capture) or sink parameters
1005 * (playback). Based on sink and source we need to either find the source
1006 * list or the sink list and set the pipeline parameters
1007 */
1008int skl_tplg_be_update_params(struct snd_soc_dai *dai,
1009 struct skl_pipe_params *params)
1010{
1011 struct snd_soc_dapm_widget *w;
1012
1013 if (params->stream == SNDRV_PCM_STREAM_PLAYBACK) {
1014 w = dai->playback_widget;
1015
1016 return skl_tplg_be_set_src_pipe_params(dai, w, params);
1017
1018 } else {
1019 w = dai->capture_widget;
1020
1021 return skl_tplg_be_set_sink_pipe_params(dai, w, params);
1022 }
1023
1024 return 0;
1025}
1026
1027static const struct snd_soc_tplg_widget_events skl_tplg_widget_ops[] = {
1028 {SKL_MIXER_EVENT, skl_tplg_mixer_event},
1029 {SKL_VMIXER_EVENT, skl_tplg_vmixer_event},
1030 {SKL_PGA_EVENT, skl_tplg_pga_event},
1031};
1032
1033/*
1034 * The topology binary passes the pin info for a module so initialize the pin
1035 * info passed into module instance
1036 */
1037static void skl_fill_module_pin_info(struct skl_dfw_module_pin *dfw_pin,
1038 struct skl_module_pin *m_pin,
1039 bool is_dynamic, int max_pin)
1040{
1041 int i;
1042
1043 for (i = 0; i < max_pin; i++) {
1044 m_pin[i].id.module_id = dfw_pin[i].module_id;
1045 m_pin[i].id.instance_id = dfw_pin[i].instance_id;
1046 m_pin[i].in_use = false;
1047 m_pin[i].is_dynamic = is_dynamic;
1048 }
1049}
1050
1051/*
1052 * Add pipeline from topology binary into driver pipeline list
1053 *
1054 * If already added we return that instance
1055 * Otherwise we create a new instance and add into driver list
1056 */
1057static struct skl_pipe *skl_tplg_add_pipe(struct device *dev,
1058 struct skl *skl, struct skl_dfw_pipe *dfw_pipe)
1059{
1060 struct skl_pipeline *ppl;
1061 struct skl_pipe *pipe;
1062 struct skl_pipe_params *params;
1063
1064 list_for_each_entry(ppl, &skl->ppl_list, node) {
1065 if (ppl->pipe->ppl_id == dfw_pipe->pipe_id)
1066 return ppl->pipe;
1067 }
1068
1069 ppl = devm_kzalloc(dev, sizeof(*ppl), GFP_KERNEL);
1070 if (!ppl)
1071 return NULL;
1072
1073 pipe = devm_kzalloc(dev, sizeof(*pipe), GFP_KERNEL);
1074 if (!pipe)
1075 return NULL;
1076
1077 params = devm_kzalloc(dev, sizeof(*params), GFP_KERNEL);
1078 if (!params)
1079 return NULL;
1080
1081 pipe->ppl_id = dfw_pipe->pipe_id;
1082 pipe->memory_pages = dfw_pipe->memory_pages;
1083 pipe->pipe_priority = dfw_pipe->pipe_priority;
1084 pipe->conn_type = dfw_pipe->conn_type;
1085 pipe->state = SKL_PIPE_INVALID;
1086 pipe->p_params = params;
1087 INIT_LIST_HEAD(&pipe->w_list);
1088
1089 ppl->pipe = pipe;
1090 list_add(&ppl->node, &skl->ppl_list);
1091
1092 return ppl->pipe;
1093}
1094
1095/*
1096 * Topology core widget load callback
1097 *
1098 * This is used to save the private data for each widget which gives
1099 * information to the driver about module and pipeline parameters which DSP
1100 * FW expects like ids, resource values, formats etc
1101 */
1102static int skl_tplg_widget_load(struct snd_soc_component *cmpnt,
1103 struct snd_soc_dapm_widget *w,
1104 struct snd_soc_tplg_dapm_widget *tplg_w)
1105{
1106 int ret;
1107 struct hdac_ext_bus *ebus = snd_soc_component_get_drvdata(cmpnt);
1108 struct skl *skl = ebus_to_skl(ebus);
1109 struct hdac_bus *bus = ebus_to_hbus(ebus);
1110 struct skl_module_cfg *mconfig;
1111 struct skl_pipe *pipe;
1112 struct skl_dfw_module *dfw_config =
1113 (struct skl_dfw_module *)tplg_w->priv.data;
1114
1115 if (!tplg_w->priv.size)
1116 goto bind_event;
1117
1118 mconfig = devm_kzalloc(bus->dev, sizeof(*mconfig), GFP_KERNEL);
1119
1120 if (!mconfig)
1121 return -ENOMEM;
1122
1123 w->priv = mconfig;
1124 mconfig->id.module_id = dfw_config->module_id;
1125 mconfig->id.instance_id = dfw_config->instance_id;
1126 mconfig->mcps = dfw_config->max_mcps;
1127 mconfig->ibs = dfw_config->ibs;
1128 mconfig->obs = dfw_config->obs;
1129 mconfig->core_id = dfw_config->core_id;
1130 mconfig->max_in_queue = dfw_config->max_in_queue;
1131 mconfig->max_out_queue = dfw_config->max_out_queue;
1132 mconfig->is_loadable = dfw_config->is_loadable;
1133 mconfig->in_fmt.channels = dfw_config->in_fmt.channels;
1134 mconfig->in_fmt.s_freq = dfw_config->in_fmt.freq;
1135 mconfig->in_fmt.bit_depth = dfw_config->in_fmt.bit_depth;
1136 mconfig->in_fmt.valid_bit_depth =
1137 dfw_config->in_fmt.valid_bit_depth;
1138 mconfig->in_fmt.ch_cfg = dfw_config->in_fmt.ch_cfg;
1139 mconfig->out_fmt.channels = dfw_config->out_fmt.channels;
1140 mconfig->out_fmt.s_freq = dfw_config->out_fmt.freq;
1141 mconfig->out_fmt.bit_depth = dfw_config->out_fmt.bit_depth;
1142 mconfig->out_fmt.valid_bit_depth =
1143 dfw_config->out_fmt.valid_bit_depth;
1144 mconfig->out_fmt.ch_cfg = dfw_config->out_fmt.ch_cfg;
1145 mconfig->params_fixup = dfw_config->params_fixup;
1146 mconfig->converter = dfw_config->converter;
1147 mconfig->m_type = dfw_config->module_type;
1148 mconfig->vbus_id = dfw_config->vbus_id;
1149
1150 pipe = skl_tplg_add_pipe(bus->dev, skl, &dfw_config->pipe);
1151 if (pipe)
1152 mconfig->pipe = pipe;
1153
1154 mconfig->dev_type = dfw_config->dev_type;
1155 mconfig->hw_conn_type = dfw_config->hw_conn_type;
1156 mconfig->time_slot = dfw_config->time_slot;
1157 mconfig->formats_config.caps_size = dfw_config->caps.caps_size;
1158
1159 mconfig->m_in_pin = devm_kzalloc(bus->dev,
1160 (mconfig->max_in_queue) *
1161 sizeof(*mconfig->m_in_pin),
1162 GFP_KERNEL);
1163 if (!mconfig->m_in_pin)
1164 return -ENOMEM;
1165
1166 mconfig->m_out_pin = devm_kzalloc(bus->dev, (mconfig->max_out_queue) *
1167 sizeof(*mconfig->m_out_pin),
1168 GFP_KERNEL);
1169 if (!mconfig->m_out_pin)
1170 return -ENOMEM;
1171
1172 skl_fill_module_pin_info(dfw_config->in_pin, mconfig->m_in_pin,
1173 dfw_config->is_dynamic_in_pin,
1174 mconfig->max_in_queue);
1175
1176 skl_fill_module_pin_info(dfw_config->out_pin, mconfig->m_out_pin,
1177 dfw_config->is_dynamic_out_pin,
1178 mconfig->max_out_queue);
1179
1180
1181 if (mconfig->formats_config.caps_size == 0)
1182 goto bind_event;
1183
1184 mconfig->formats_config.caps = (u32 *)devm_kzalloc(bus->dev,
1185 mconfig->formats_config.caps_size, GFP_KERNEL);
1186
1187 if (mconfig->formats_config.caps == NULL)
1188 return -ENOMEM;
1189
1190 memcpy(mconfig->formats_config.caps, dfw_config->caps.caps,
1191 dfw_config->caps.caps_size);
1192
1193bind_event:
1194 if (tplg_w->event_type == 0) {
1195 dev_dbg(bus->dev, "ASoC: No event handler required\n");
1196 return 0;
1197 }
1198
1199 ret = snd_soc_tplg_widget_bind_event(w, skl_tplg_widget_ops,
1200 ARRAY_SIZE(skl_tplg_widget_ops),
1201 tplg_w->event_type);
1202
1203 if (ret) {
1204 dev_err(bus->dev, "%s: No matching event handlers found for %d\n",
1205 __func__, tplg_w->event_type);
1206 return -EINVAL;
1207 }
1208
1209 return 0;
1210}
1211
1212static struct snd_soc_tplg_ops skl_tplg_ops = {
1213 .widget_load = skl_tplg_widget_load,
1214};
1215
1216/* This will be read from topology manifest, currently defined here */
1217#define SKL_MAX_MCPS 30000000
1218#define SKL_FW_MAX_MEM 1000000
1219
1220/*
1221 * SKL topology init routine
1222 */
1223int skl_tplg_init(struct snd_soc_platform *platform, struct hdac_ext_bus *ebus)
1224{
1225 int ret;
1226 const struct firmware *fw;
1227 struct hdac_bus *bus = ebus_to_hbus(ebus);
1228 struct skl *skl = ebus_to_skl(ebus);
1229
1230 ret = request_firmware(&fw, "dfw_sst.bin", bus->dev);
1231 if (ret < 0) {
1232 dev_err(bus->dev, "tplg fw %s load failed with %d\n",
1233 "dfw_sst.bin", ret);
1234 return ret;
1235 }
1236
1237 /*
1238 * The complete tplg for SKL is loaded as index 0, we don't use
1239 * any other index
1240 */
1241 ret = snd_soc_tplg_component_load(&platform->component,
1242 &skl_tplg_ops, fw, 0);
1243 if (ret < 0) {
1244 dev_err(bus->dev, "tplg component load failed%d\n", ret);
1245 return -EINVAL;
1246 }
1247
1248 skl->resource.max_mcps = SKL_MAX_MCPS;
1249 skl->resource.max_mem = SKL_FW_MAX_MEM;
1250
1251 return 0;
1252}
diff --git a/sound/soc/intel/skylake/skl-topology.h b/sound/soc/intel/skylake/skl-topology.h
index 8c7767baa94f..76053a8de41c 100644
--- a/sound/soc/intel/skylake/skl-topology.h
+++ b/sound/soc/intel/skylake/skl-topology.h
@@ -129,6 +129,11 @@ struct skl_src_module_cfg {
129 enum skl_s_freq src_cfg; 129 enum skl_s_freq src_cfg;
130} __packed; 130} __packed;
131 131
132struct notification_mask {
133 u32 notify;
134 u32 enable;
135} __packed;
136
132struct skl_up_down_mixer_cfg { 137struct skl_up_down_mixer_cfg {
133 struct skl_base_cfg base_cfg; 138 struct skl_base_cfg base_cfg;
134 enum skl_ch_cfg out_ch_cfg; 139 enum skl_ch_cfg out_ch_cfg;
@@ -153,8 +158,7 @@ enum skl_dma_type {
153union skl_ssp_dma_node { 158union skl_ssp_dma_node {
154 u8 val; 159 u8 val;
155 struct { 160 struct {
156 u8 dual_mono:1; 161 u8 time_slot_index:4;
157 u8 time_slot:3;
158 u8 i2s_instance:4; 162 u8 i2s_instance:4;
159 } dma_node; 163 } dma_node;
160}; 164};
@@ -263,6 +267,34 @@ struct skl_module_cfg {
263 struct skl_specific_cfg formats_config; 267 struct skl_specific_cfg formats_config;
264}; 268};
265 269
270struct skl_pipeline {
271 struct skl_pipe *pipe;
272 struct list_head node;
273};
274
275struct skl_dapm_path_list {
276 struct snd_soc_dapm_path *dapm_path;
277 struct list_head node;
278};
279
280static inline struct skl *get_skl_ctx(struct device *dev)
281{
282 struct hdac_ext_bus *ebus = dev_get_drvdata(dev);
283
284 return ebus_to_skl(ebus);
285}
286
287int skl_tplg_be_update_params(struct snd_soc_dai *dai,
288 struct skl_pipe_params *params);
289void skl_tplg_set_be_dmic_config(struct snd_soc_dai *dai,
290 struct skl_pipe_params *params, int stream);
291int skl_tplg_init(struct snd_soc_platform *platform,
292 struct hdac_ext_bus *ebus);
293struct skl_module_cfg *skl_tplg_fe_get_cpr_module(
294 struct snd_soc_dai *dai, int stream);
295int skl_tplg_update_pipe_params(struct device *dev,
296 struct skl_module_cfg *mconfig, struct skl_pipe_params *params);
297
266int skl_create_pipeline(struct skl_sst *ctx, struct skl_pipe *pipe); 298int skl_create_pipeline(struct skl_sst *ctx, struct skl_pipe *pipe);
267 299
268int skl_run_pipe(struct skl_sst *ctx, struct skl_pipe *pipe); 300int skl_run_pipe(struct skl_sst *ctx, struct skl_pipe *pipe);
diff --git a/sound/soc/intel/skylake/skl-tplg-interface.h b/sound/soc/intel/skylake/skl-tplg-interface.h
index a50689825bca..2bc396d54cbe 100644
--- a/sound/soc/intel/skylake/skl-tplg-interface.h
+++ b/sound/soc/intel/skylake/skl-tplg-interface.h
@@ -19,6 +19,29 @@
19#ifndef __HDA_TPLG_INTERFACE_H__ 19#ifndef __HDA_TPLG_INTERFACE_H__
20#define __HDA_TPLG_INTERFACE_H__ 20#define __HDA_TPLG_INTERFACE_H__
21 21
22/*
23 * Default types range from 0~12. type can range from 0 to 0xff
24 * SST types start at higher to avoid any overlapping in future
25 */
26#define SOC_CONTROL_TYPE_HDA_SST_ALGO_PARAMS 0x100
27#define SOC_CONTROL_TYPE_HDA_SST_MUX 0x101
28#define SOC_CONTROL_TYPE_HDA_SST_MIX 0x101
29#define SOC_CONTROL_TYPE_HDA_SST_BYTE 0x103
30
31#define HDA_SST_CFG_MAX 900 /* size of copier cfg*/
32#define MAX_IN_QUEUE 8
33#define MAX_OUT_QUEUE 8
34
35/* Event types goes here */
36/* Reserve event type 0 for no event handlers */
37enum skl_event_types {
38 SKL_EVENT_NONE = 0,
39 SKL_MIXER_EVENT,
40 SKL_MUX_EVENT,
41 SKL_VMIXER_EVENT,
42 SKL_PGA_EVENT
43};
44
22/** 45/**
23 * enum skl_ch_cfg - channel configuration 46 * enum skl_ch_cfg - channel configuration
24 * 47 *
@@ -83,6 +106,66 @@ enum skl_dev_type {
83 SKL_DEVICE_I2S = 0x2, 106 SKL_DEVICE_I2S = 0x2,
84 SKL_DEVICE_SLIMBUS = 0x3, 107 SKL_DEVICE_SLIMBUS = 0x3,
85 SKL_DEVICE_HDALINK = 0x4, 108 SKL_DEVICE_HDALINK = 0x4,
109 SKL_DEVICE_HDAHOST = 0x5,
86 SKL_DEVICE_NONE 110 SKL_DEVICE_NONE
87}; 111};
112
113struct skl_dfw_module_pin {
114 u16 module_id;
115 u16 instance_id;
116} __packed;
117
118struct skl_dfw_module_fmt {
119 u32 channels;
120 u32 freq;
121 u32 bit_depth;
122 u32 valid_bit_depth;
123 u32 ch_cfg;
124} __packed;
125
126struct skl_dfw_module_caps {
127 u32 caps_size;
128 u32 caps[HDA_SST_CFG_MAX];
129};
130
131struct skl_dfw_pipe {
132 u8 pipe_id;
133 u8 pipe_priority;
134 u16 conn_type;
135 u32 memory_pages;
136} __packed;
137
138struct skl_dfw_module {
139 u16 module_id;
140 u16 instance_id;
141 u32 max_mcps;
142 u8 core_id;
143 u8 max_in_queue;
144 u8 max_out_queue;
145 u8 is_loadable;
146 u8 conn_type;
147 u8 dev_type;
148 u8 hw_conn_type;
149 u8 time_slot;
150 u32 obs;
151 u32 ibs;
152 u32 params_fixup;
153 u32 converter;
154 u32 module_type;
155 u32 vbus_id;
156 u8 is_dynamic_in_pin;
157 u8 is_dynamic_out_pin;
158 struct skl_dfw_pipe pipe;
159 struct skl_dfw_module_fmt in_fmt;
160 struct skl_dfw_module_fmt out_fmt;
161 struct skl_dfw_module_pin in_pin[MAX_IN_QUEUE];
162 struct skl_dfw_module_pin out_pin[MAX_OUT_QUEUE];
163 struct skl_dfw_module_caps caps;
164} __packed;
165
166struct skl_dfw_algo_data {
167 u32 max;
168 char *params;
169} __packed;
170
88#endif 171#endif
diff --git a/sound/soc/intel/skylake/skl.c b/sound/soc/intel/skylake/skl.c
index 348d094e81d6..5319529aedf7 100644
--- a/sound/soc/intel/skylake/skl.c
+++ b/sound/soc/intel/skylake/skl.c
@@ -166,12 +166,20 @@ static int skl_runtime_suspend(struct device *dev)
166 struct pci_dev *pci = to_pci_dev(dev); 166 struct pci_dev *pci = to_pci_dev(dev);
167 struct hdac_ext_bus *ebus = pci_get_drvdata(pci); 167 struct hdac_ext_bus *ebus = pci_get_drvdata(pci);
168 struct hdac_bus *bus = ebus_to_hbus(ebus); 168 struct hdac_bus *bus = ebus_to_hbus(ebus);
169 struct skl *skl = ebus_to_skl(ebus);
170 int ret;
169 171
170 dev_dbg(bus->dev, "in %s\n", __func__); 172 dev_dbg(bus->dev, "in %s\n", __func__);
171 173
172 /* enable controller wake up event */ 174 /* enable controller wake up event */
173 snd_hdac_chip_updatew(bus, WAKEEN, 0, STATESTS_INT_MASK); 175 snd_hdac_chip_updatew(bus, WAKEEN, 0, STATESTS_INT_MASK);
174 176
177 snd_hdac_ext_bus_link_power_down_all(ebus);
178
179 ret = skl_suspend_dsp(skl);
180 if (ret < 0)
181 return ret;
182
175 snd_hdac_bus_stop_chip(bus); 183 snd_hdac_bus_stop_chip(bus);
176 snd_hdac_bus_enter_link_reset(bus); 184 snd_hdac_bus_enter_link_reset(bus);
177 185
@@ -183,7 +191,7 @@ static int skl_runtime_resume(struct device *dev)
183 struct pci_dev *pci = to_pci_dev(dev); 191 struct pci_dev *pci = to_pci_dev(dev);
184 struct hdac_ext_bus *ebus = pci_get_drvdata(pci); 192 struct hdac_ext_bus *ebus = pci_get_drvdata(pci);
185 struct hdac_bus *bus = ebus_to_hbus(ebus); 193 struct hdac_bus *bus = ebus_to_hbus(ebus);
186 struct skl *hda = ebus_to_skl(ebus); 194 struct skl *skl = ebus_to_skl(ebus);
187 int status; 195 int status;
188 196
189 dev_dbg(bus->dev, "in %s\n", __func__); 197 dev_dbg(bus->dev, "in %s\n", __func__);
@@ -191,12 +199,12 @@ static int skl_runtime_resume(struct device *dev)
191 /* Read STATESTS before controller reset */ 199 /* Read STATESTS before controller reset */
192 status = snd_hdac_chip_readw(bus, STATESTS); 200 status = snd_hdac_chip_readw(bus, STATESTS);
193 201
194 skl_init_pci(hda); 202 skl_init_pci(skl);
195 snd_hdac_bus_init_chip(bus, true); 203 snd_hdac_bus_init_chip(bus, true);
196 /* disable controller Wake Up event */ 204 /* disable controller Wake Up event */
197 snd_hdac_chip_updatew(bus, WAKEEN, STATESTS_INT_MASK, 0); 205 snd_hdac_chip_updatew(bus, WAKEEN, STATESTS_INT_MASK, 0);
198 206
199 return 0; 207 return skl_resume_dsp(skl);
200} 208}
201#endif /* CONFIG_PM */ 209#endif /* CONFIG_PM */
202 210
@@ -453,21 +461,28 @@ static int skl_probe(struct pci_dev *pci,
453 if (err < 0) 461 if (err < 0)
454 goto out_free; 462 goto out_free;
455 463
464 skl->nhlt = skl_nhlt_init(bus->dev);
465
466 if (skl->nhlt == NULL)
467 goto out_free;
468
456 pci_set_drvdata(skl->pci, ebus); 469 pci_set_drvdata(skl->pci, ebus);
457 470
458 /* check if dsp is there */ 471 /* check if dsp is there */
459 if (ebus->ppcap) { 472 if (ebus->ppcap) {
460 /* TODO register with dsp IPC */ 473 err = skl_init_dsp(skl);
461 dev_dbg(bus->dev, "Register dsp\n"); 474 if (err < 0) {
475 dev_dbg(bus->dev, "error failed to register dsp\n");
476 goto out_free;
477 }
462 } 478 }
463
464 if (ebus->mlcap) 479 if (ebus->mlcap)
465 snd_hdac_ext_bus_get_ml_capabilities(ebus); 480 snd_hdac_ext_bus_get_ml_capabilities(ebus);
466 481
467 /* create device for soc dmic */ 482 /* create device for soc dmic */
468 err = skl_dmic_device_register(skl); 483 err = skl_dmic_device_register(skl);
469 if (err < 0) 484 if (err < 0)
470 goto out_free; 485 goto out_dsp_free;
471 486
472 /* register platform dai and controls */ 487 /* register platform dai and controls */
473 err = skl_platform_register(bus->dev); 488 err = skl_platform_register(bus->dev);
@@ -491,6 +506,8 @@ out_unregister:
491 skl_platform_unregister(bus->dev); 506 skl_platform_unregister(bus->dev);
492out_dmic_free: 507out_dmic_free:
493 skl_dmic_device_unregister(skl); 508 skl_dmic_device_unregister(skl);
509out_dsp_free:
510 skl_free_dsp(skl);
494out_free: 511out_free:
495 skl->init_failed = 1; 512 skl->init_failed = 1;
496 skl_free(ebus); 513 skl_free(ebus);
@@ -507,6 +524,7 @@ static void skl_remove(struct pci_dev *pci)
507 pm_runtime_get_noresume(&pci->dev); 524 pm_runtime_get_noresume(&pci->dev);
508 pci_dev_put(pci); 525 pci_dev_put(pci);
509 skl_platform_unregister(&pci->dev); 526 skl_platform_unregister(&pci->dev);
527 skl_free_dsp(skl);
510 skl_dmic_device_unregister(skl); 528 skl_dmic_device_unregister(skl);
511 skl_free(ebus); 529 skl_free(ebus);
512 dev_set_drvdata(&pci->dev, NULL); 530 dev_set_drvdata(&pci->dev, NULL);
diff --git a/sound/soc/intel/skylake/skl.h b/sound/soc/intel/skylake/skl.h
index f7fdbb02947f..dd2e79ae45a8 100644
--- a/sound/soc/intel/skylake/skl.h
+++ b/sound/soc/intel/skylake/skl.h
@@ -48,6 +48,13 @@
48#define AZX_REG_VS_SDXEFIFOS_XBASE 0x1094 48#define AZX_REG_VS_SDXEFIFOS_XBASE 0x1094
49#define AZX_REG_VS_SDXEFIFOS_XINTERVAL 0x20 49#define AZX_REG_VS_SDXEFIFOS_XINTERVAL 0x20
50 50
51struct skl_dsp_resource {
52 u32 max_mcps;
53 u32 max_mem;
54 u32 mcps;
55 u32 mem;
56};
57
51struct skl { 58struct skl {
52 struct hdac_ext_bus ebus; 59 struct hdac_ext_bus ebus;
53 struct pci_dev *pci; 60 struct pci_dev *pci;
@@ -55,8 +62,12 @@ struct skl {
55 unsigned int init_failed:1; /* delayed init failed */ 62 unsigned int init_failed:1; /* delayed init failed */
56 struct platform_device *dmic_dev; 63 struct platform_device *dmic_dev;
57 64
58 void __iomem *nhlt; /* nhlt ptr */ 65 void *nhlt; /* nhlt ptr */
59 struct skl_sst *skl_sst; /* sst skl ctx */ 66 struct skl_sst *skl_sst; /* sst skl ctx */
67
68 struct skl_dsp_resource resource;
69 struct list_head ppl_list;
70 struct list_head dapm_path_list;
60}; 71};
61 72
62#define skl_to_ebus(s) (&(s)->ebus) 73#define skl_to_ebus(s) (&(s)->ebus)
@@ -72,8 +83,8 @@ struct skl_dma_params {
72int skl_platform_unregister(struct device *dev); 83int skl_platform_unregister(struct device *dev);
73int skl_platform_register(struct device *dev); 84int skl_platform_register(struct device *dev);
74 85
75void __iomem *skl_nhlt_init(struct device *dev); 86void *skl_nhlt_init(struct device *dev);
76void skl_nhlt_free(void __iomem *addr); 87void skl_nhlt_free(void *addr);
77struct nhlt_specific_cfg *skl_get_ep_blob(struct skl *skl, u32 instance, 88struct nhlt_specific_cfg *skl_get_ep_blob(struct skl *skl, u32 instance,
78 u8 link_type, u8 s_fmt, u8 no_ch, u32 s_rate, u8 dirn); 89 u8 link_type, u8 s_fmt, u8 no_ch, u32 s_rate, u8 dirn);
79 90
diff --git a/sound/soc/jz4740/jz4740-i2s.c b/sound/soc/jz4740/jz4740-i2s.c
index b05fb1c1a848..794a3499e567 100644
--- a/sound/soc/jz4740/jz4740-i2s.c
+++ b/sound/soc/jz4740/jz4740-i2s.c
@@ -485,6 +485,7 @@ static const struct of_device_id jz4740_of_matches[] = {
485 { .compatible = "ingenic,jz4780-i2s", .data = (void *)JZ_I2S_JZ4780 }, 485 { .compatible = "ingenic,jz4780-i2s", .data = (void *)JZ_I2S_JZ4780 },
486 { /* sentinel */ } 486 { /* sentinel */ }
487}; 487};
488MODULE_DEVICE_TABLE(of, jz4740_of_matches);
488#endif 489#endif
489 490
490static int jz4740_i2s_dev_probe(struct platform_device *pdev) 491static int jz4740_i2s_dev_probe(struct platform_device *pdev)
diff --git a/sound/soc/kirkwood/armada-370-db.c b/sound/soc/kirkwood/armada-370-db.c
index de7563bdc5c2..e0304d544f26 100644
--- a/sound/soc/kirkwood/armada-370-db.c
+++ b/sound/soc/kirkwood/armada-370-db.c
@@ -130,6 +130,7 @@ static const struct of_device_id a370db_dt_ids[] = {
130 { .compatible = "marvell,a370db-audio" }, 130 { .compatible = "marvell,a370db-audio" },
131 { }, 131 { },
132}; 132};
133MODULE_DEVICE_TABLE(of, a370db_dt_ids);
133 134
134static struct platform_driver a370db_driver = { 135static struct platform_driver a370db_driver = {
135 .driver = { 136 .driver = {
diff --git a/sound/soc/mediatek/mt8173-max98090.c b/sound/soc/mediatek/mt8173-max98090.c
index 684e8a78bed0..71a1a35047ba 100644
--- a/sound/soc/mediatek/mt8173-max98090.c
+++ b/sound/soc/mediatek/mt8173-max98090.c
@@ -179,21 +179,13 @@ static int mt8173_max98090_dev_probe(struct platform_device *pdev)
179 } 179 }
180 card->dev = &pdev->dev; 180 card->dev = &pdev->dev;
181 181
182 ret = snd_soc_register_card(card); 182 ret = devm_snd_soc_register_card(&pdev->dev, card);
183 if (ret) 183 if (ret)
184 dev_err(&pdev->dev, "%s snd_soc_register_card fail %d\n", 184 dev_err(&pdev->dev, "%s snd_soc_register_card fail %d\n",
185 __func__, ret); 185 __func__, ret);
186 return ret; 186 return ret;
187} 187}
188 188
189static int mt8173_max98090_dev_remove(struct platform_device *pdev)
190{
191 struct snd_soc_card *card = platform_get_drvdata(pdev);
192
193 snd_soc_unregister_card(card);
194 return 0;
195}
196
197static const struct of_device_id mt8173_max98090_dt_match[] = { 189static const struct of_device_id mt8173_max98090_dt_match[] = {
198 { .compatible = "mediatek,mt8173-max98090", }, 190 { .compatible = "mediatek,mt8173-max98090", },
199 { } 191 { }
@@ -209,7 +201,6 @@ static struct platform_driver mt8173_max98090_driver = {
209#endif 201#endif
210 }, 202 },
211 .probe = mt8173_max98090_dev_probe, 203 .probe = mt8173_max98090_dev_probe,
212 .remove = mt8173_max98090_dev_remove,
213}; 204};
214 205
215module_platform_driver(mt8173_max98090_driver); 206module_platform_driver(mt8173_max98090_driver);
diff --git a/sound/soc/mediatek/mt8173-rt5650-rt5676.c b/sound/soc/mediatek/mt8173-rt5650-rt5676.c
index 86cf9752f18a..50ba538eccb3 100644
--- a/sound/soc/mediatek/mt8173-rt5650-rt5676.c
+++ b/sound/soc/mediatek/mt8173-rt5650-rt5676.c
@@ -246,21 +246,13 @@ static int mt8173_rt5650_rt5676_dev_probe(struct platform_device *pdev)
246 card->dev = &pdev->dev; 246 card->dev = &pdev->dev;
247 platform_set_drvdata(pdev, card); 247 platform_set_drvdata(pdev, card);
248 248
249 ret = snd_soc_register_card(card); 249 ret = devm_snd_soc_register_card(&pdev->dev, card);
250 if (ret) 250 if (ret)
251 dev_err(&pdev->dev, "%s snd_soc_register_card fail %d\n", 251 dev_err(&pdev->dev, "%s snd_soc_register_card fail %d\n",
252 __func__, ret); 252 __func__, ret);
253 return ret; 253 return ret;
254} 254}
255 255
256static int mt8173_rt5650_rt5676_dev_remove(struct platform_device *pdev)
257{
258 struct snd_soc_card *card = platform_get_drvdata(pdev);
259
260 snd_soc_unregister_card(card);
261 return 0;
262}
263
264static const struct of_device_id mt8173_rt5650_rt5676_dt_match[] = { 256static const struct of_device_id mt8173_rt5650_rt5676_dt_match[] = {
265 { .compatible = "mediatek,mt8173-rt5650-rt5676", }, 257 { .compatible = "mediatek,mt8173-rt5650-rt5676", },
266 { } 258 { }
@@ -276,7 +268,6 @@ static struct platform_driver mt8173_rt5650_rt5676_driver = {
276#endif 268#endif
277 }, 269 },
278 .probe = mt8173_rt5650_rt5676_dev_probe, 270 .probe = mt8173_rt5650_rt5676_dev_probe,
279 .remove = mt8173_rt5650_rt5676_dev_remove,
280}; 271};
281 272
282module_platform_driver(mt8173_rt5650_rt5676_driver); 273module_platform_driver(mt8173_rt5650_rt5676_driver);
diff --git a/sound/soc/mxs/mxs-sgtl5000.c b/sound/soc/mxs/mxs-sgtl5000.c
index 6e6fce6a14ba..2b23ffbac6b1 100644
--- a/sound/soc/mxs/mxs-sgtl5000.c
+++ b/sound/soc/mxs/mxs-sgtl5000.c
@@ -142,7 +142,7 @@ static int mxs_sgtl5000_probe(struct platform_device *pdev)
142 card->dev = &pdev->dev; 142 card->dev = &pdev->dev;
143 platform_set_drvdata(pdev, card); 143 platform_set_drvdata(pdev, card);
144 144
145 ret = snd_soc_register_card(card); 145 ret = devm_snd_soc_register_card(&pdev->dev, card);
146 if (ret) { 146 if (ret) {
147 dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n", 147 dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n",
148 ret); 148 ret);
@@ -154,12 +154,8 @@ static int mxs_sgtl5000_probe(struct platform_device *pdev)
154 154
155static int mxs_sgtl5000_remove(struct platform_device *pdev) 155static int mxs_sgtl5000_remove(struct platform_device *pdev)
156{ 156{
157 struct snd_soc_card *card = platform_get_drvdata(pdev);
158
159 mxs_saif_put_mclk(0); 157 mxs_saif_put_mclk(0);
160 158
161 snd_soc_unregister_card(card);
162
163 return 0; 159 return 0;
164} 160}
165 161
diff --git a/sound/soc/omap/n810.c b/sound/soc/omap/n810.c
index dcb5336b5698..190f868e78b2 100644
--- a/sound/soc/omap/n810.c
+++ b/sound/soc/omap/n810.c
@@ -99,8 +99,7 @@ static int n810_startup(struct snd_pcm_substream *substream)
99 struct snd_pcm_runtime *runtime = substream->runtime; 99 struct snd_pcm_runtime *runtime = substream->runtime;
100 struct snd_soc_pcm_runtime *rtd = substream->private_data; 100 struct snd_soc_pcm_runtime *rtd = substream->private_data;
101 101
102 snd_pcm_hw_constraint_minmax(runtime, 102 snd_pcm_hw_constraint_single(runtime, SNDRV_PCM_HW_PARAM_CHANNELS, 2);
103 SNDRV_PCM_HW_PARAM_CHANNELS, 2, 2);
104 103
105 n810_ext_control(&rtd->card->dapm); 104 n810_ext_control(&rtd->card->dapm);
106 return clk_prepare_enable(sys_clkout2); 105 return clk_prepare_enable(sys_clkout2);
diff --git a/sound/soc/omap/rx51.c b/sound/soc/omap/rx51.c
index 3bebfb1d3a6f..5e21f08579d8 100644
--- a/sound/soc/omap/rx51.c
+++ b/sound/soc/omap/rx51.c
@@ -107,8 +107,7 @@ static int rx51_startup(struct snd_pcm_substream *substream)
107 struct snd_soc_pcm_runtime *rtd = substream->private_data; 107 struct snd_soc_pcm_runtime *rtd = substream->private_data;
108 struct snd_soc_card *card = rtd->card; 108 struct snd_soc_card *card = rtd->card;
109 109
110 snd_pcm_hw_constraint_minmax(runtime, 110 snd_pcm_hw_constraint_single(runtime, SNDRV_PCM_HW_PARAM_CHANNELS, 2);
111 SNDRV_PCM_HW_PARAM_CHANNELS, 2, 2);
112 rx51_ext_control(&card->dapm); 111 rx51_ext_control(&card->dapm);
113 112
114 return 0; 113 return 0;
@@ -297,7 +296,7 @@ static int rx51_aic34_init(struct snd_soc_pcm_runtime *rtd)
297 dev_err(card->dev, "Failed to add TPA6130A2 controls\n"); 296 dev_err(card->dev, "Failed to add TPA6130A2 controls\n");
298 return err; 297 return err;
299 } 298 }
300 snd_soc_limit_volume(codec, "TPA6130A2 Headphone Playback Volume", 42); 299 snd_soc_limit_volume(card, "TPA6130A2 Headphone Playback Volume", 42);
301 300
302 err = omap_mcbsp_st_add_controls(rtd, 2); 301 err = omap_mcbsp_st_add_controls(rtd, 2);
303 if (err < 0) { 302 if (err < 0) {
diff --git a/sound/soc/pxa/brownstone.c b/sound/soc/pxa/brownstone.c
index 2b26318bc200..6147e86e9b0f 100644
--- a/sound/soc/pxa/brownstone.c
+++ b/sound/soc/pxa/brownstone.c
@@ -116,26 +116,19 @@ static int brownstone_probe(struct platform_device *pdev)
116 int ret; 116 int ret;
117 117
118 brownstone.dev = &pdev->dev; 118 brownstone.dev = &pdev->dev;
119 ret = snd_soc_register_card(&brownstone); 119 ret = devm_snd_soc_register_card(&pdev->dev, &brownstone);
120 if (ret) 120 if (ret)
121 dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n", 121 dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n",
122 ret); 122 ret);
123 return ret; 123 return ret;
124} 124}
125 125
126static int brownstone_remove(struct platform_device *pdev)
127{
128 snd_soc_unregister_card(&brownstone);
129 return 0;
130}
131
132static struct platform_driver mmp_driver = { 126static struct platform_driver mmp_driver = {
133 .driver = { 127 .driver = {
134 .name = "brownstone-audio", 128 .name = "brownstone-audio",
135 .pm = &snd_soc_pm_ops, 129 .pm = &snd_soc_pm_ops,
136 }, 130 },
137 .probe = brownstone_probe, 131 .probe = brownstone_probe,
138 .remove = brownstone_remove,
139}; 132};
140 133
141module_platform_driver(mmp_driver); 134module_platform_driver(mmp_driver);
diff --git a/sound/soc/pxa/corgi.c b/sound/soc/pxa/corgi.c
index 3580d10c9f28..c97dc13d3608 100644
--- a/sound/soc/pxa/corgi.c
+++ b/sound/soc/pxa/corgi.c
@@ -295,28 +295,19 @@ static int corgi_probe(struct platform_device *pdev)
295 295
296 card->dev = &pdev->dev; 296 card->dev = &pdev->dev;
297 297
298 ret = snd_soc_register_card(card); 298 ret = devm_snd_soc_register_card(&pdev->dev, card);
299 if (ret) 299 if (ret)
300 dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n", 300 dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n",
301 ret); 301 ret);
302 return ret; 302 return ret;
303} 303}
304 304
305static int corgi_remove(struct platform_device *pdev)
306{
307 struct snd_soc_card *card = platform_get_drvdata(pdev);
308
309 snd_soc_unregister_card(card);
310 return 0;
311}
312
313static struct platform_driver corgi_driver = { 305static struct platform_driver corgi_driver = {
314 .driver = { 306 .driver = {
315 .name = "corgi-audio", 307 .name = "corgi-audio",
316 .pm = &snd_soc_pm_ops, 308 .pm = &snd_soc_pm_ops,
317 }, 309 },
318 .probe = corgi_probe, 310 .probe = corgi_probe,
319 .remove = corgi_remove,
320}; 311};
321 312
322module_platform_driver(corgi_driver); 313module_platform_driver(corgi_driver);
diff --git a/sound/soc/pxa/e740_wm9705.c b/sound/soc/pxa/e740_wm9705.c
index d72e124a3676..1de876529aa1 100644
--- a/sound/soc/pxa/e740_wm9705.c
+++ b/sound/soc/pxa/e740_wm9705.c
@@ -138,7 +138,7 @@ static int e740_probe(struct platform_device *pdev)
138 138
139 card->dev = &pdev->dev; 139 card->dev = &pdev->dev;
140 140
141 ret = snd_soc_register_card(card); 141 ret = devm_snd_soc_register_card(&pdev->dev, card);
142 if (ret) { 142 if (ret) {
143 dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n", 143 dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n",
144 ret); 144 ret);
@@ -149,10 +149,7 @@ static int e740_probe(struct platform_device *pdev)
149 149
150static int e740_remove(struct platform_device *pdev) 150static int e740_remove(struct platform_device *pdev)
151{ 151{
152 struct snd_soc_card *card = platform_get_drvdata(pdev);
153
154 gpio_free_array(e740_audio_gpios, ARRAY_SIZE(e740_audio_gpios)); 152 gpio_free_array(e740_audio_gpios, ARRAY_SIZE(e740_audio_gpios));
155 snd_soc_unregister_card(card);
156 return 0; 153 return 0;
157} 154}
158 155
diff --git a/sound/soc/pxa/e750_wm9705.c b/sound/soc/pxa/e750_wm9705.c
index 48f2d7c2e68c..b7eb7cd5df7d 100644
--- a/sound/soc/pxa/e750_wm9705.c
+++ b/sound/soc/pxa/e750_wm9705.c
@@ -120,7 +120,7 @@ static int e750_probe(struct platform_device *pdev)
120 120
121 card->dev = &pdev->dev; 121 card->dev = &pdev->dev;
122 122
123 ret = snd_soc_register_card(card); 123 ret = devm_snd_soc_register_card(&pdev->dev, card);
124 if (ret) { 124 if (ret) {
125 dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n", 125 dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n",
126 ret); 126 ret);
@@ -131,10 +131,7 @@ static int e750_probe(struct platform_device *pdev)
131 131
132static int e750_remove(struct platform_device *pdev) 132static int e750_remove(struct platform_device *pdev)
133{ 133{
134 struct snd_soc_card *card = platform_get_drvdata(pdev);
135
136 gpio_free_array(e750_audio_gpios, ARRAY_SIZE(e750_audio_gpios)); 134 gpio_free_array(e750_audio_gpios, ARRAY_SIZE(e750_audio_gpios));
137 snd_soc_unregister_card(card);
138 return 0; 135 return 0;
139} 136}
140 137
diff --git a/sound/soc/pxa/e800_wm9712.c b/sound/soc/pxa/e800_wm9712.c
index 45d4bd46fff6..41bf71466a7b 100644
--- a/sound/soc/pxa/e800_wm9712.c
+++ b/sound/soc/pxa/e800_wm9712.c
@@ -119,7 +119,7 @@ static int e800_probe(struct platform_device *pdev)
119 119
120 card->dev = &pdev->dev; 120 card->dev = &pdev->dev;
121 121
122 ret = snd_soc_register_card(card); 122 ret = devm_snd_soc_register_card(&pdev->dev, card);
123 if (ret) { 123 if (ret) {
124 dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n", 124 dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n",
125 ret); 125 ret);
@@ -130,10 +130,7 @@ static int e800_probe(struct platform_device *pdev)
130 130
131static int e800_remove(struct platform_device *pdev) 131static int e800_remove(struct platform_device *pdev)
132{ 132{
133 struct snd_soc_card *card = platform_get_drvdata(pdev);
134
135 gpio_free_array(e800_audio_gpios, ARRAY_SIZE(e800_audio_gpios)); 133 gpio_free_array(e800_audio_gpios, ARRAY_SIZE(e800_audio_gpios));
136 snd_soc_unregister_card(card);
137 return 0; 134 return 0;
138} 135}
139 136
diff --git a/sound/soc/pxa/hx4700.c b/sound/soc/pxa/hx4700.c
index 9f8be7cd567e..ecbf2873b7ff 100644
--- a/sound/soc/pxa/hx4700.c
+++ b/sound/soc/pxa/hx4700.c
@@ -193,7 +193,7 @@ static int hx4700_audio_probe(struct platform_device *pdev)
193 return ret; 193 return ret;
194 194
195 snd_soc_card_hx4700.dev = &pdev->dev; 195 snd_soc_card_hx4700.dev = &pdev->dev;
196 ret = snd_soc_register_card(&snd_soc_card_hx4700); 196 ret = devm_snd_soc_register_card(&pdev->dev, &snd_soc_card_hx4700);
197 if (ret) 197 if (ret)
198 gpio_free_array(hx4700_audio_gpios, 198 gpio_free_array(hx4700_audio_gpios,
199 ARRAY_SIZE(hx4700_audio_gpios)); 199 ARRAY_SIZE(hx4700_audio_gpios));
@@ -203,8 +203,6 @@ static int hx4700_audio_probe(struct platform_device *pdev)
203 203
204static int hx4700_audio_remove(struct platform_device *pdev) 204static int hx4700_audio_remove(struct platform_device *pdev)
205{ 205{
206 snd_soc_unregister_card(&snd_soc_card_hx4700);
207
208 gpio_set_value(GPIO92_HX4700_HP_DRIVER, 0); 206 gpio_set_value(GPIO92_HX4700_HP_DRIVER, 0);
209 gpio_set_value(GPIO107_HX4700_SPK_nSD, 0); 207 gpio_set_value(GPIO107_HX4700_SPK_nSD, 0);
210 208
diff --git a/sound/soc/pxa/imote2.c b/sound/soc/pxa/imote2.c
index 29fabbfd21f1..9d0e40771ef5 100644
--- a/sound/soc/pxa/imote2.c
+++ b/sound/soc/pxa/imote2.c
@@ -72,28 +72,19 @@ static int imote2_probe(struct platform_device *pdev)
72 72
73 card->dev = &pdev->dev; 73 card->dev = &pdev->dev;
74 74
75 ret = snd_soc_register_card(card); 75 ret = devm_snd_soc_register_card(&pdev->dev, card);
76 if (ret) 76 if (ret)
77 dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n", 77 dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n",
78 ret); 78 ret);
79 return ret; 79 return ret;
80} 80}
81 81
82static int imote2_remove(struct platform_device *pdev)
83{
84 struct snd_soc_card *card = platform_get_drvdata(pdev);
85
86 snd_soc_unregister_card(card);
87 return 0;
88}
89
90static struct platform_driver imote2_driver = { 82static struct platform_driver imote2_driver = {
91 .driver = { 83 .driver = {
92 .name = "imote2-audio", 84 .name = "imote2-audio",
93 .pm = &snd_soc_pm_ops, 85 .pm = &snd_soc_pm_ops,
94 }, 86 },
95 .probe = imote2_probe, 87 .probe = imote2_probe,
96 .remove = imote2_remove,
97}; 88};
98 89
99module_platform_driver(imote2_driver); 90module_platform_driver(imote2_driver);
diff --git a/sound/soc/pxa/mioa701_wm9713.c b/sound/soc/pxa/mioa701_wm9713.c
index a9615a574546..29bc60e85e92 100644
--- a/sound/soc/pxa/mioa701_wm9713.c
+++ b/sound/soc/pxa/mioa701_wm9713.c
@@ -181,7 +181,7 @@ static int mioa701_wm9713_probe(struct platform_device *pdev)
181 return -ENODEV; 181 return -ENODEV;
182 182
183 mioa701.dev = &pdev->dev; 183 mioa701.dev = &pdev->dev;
184 rc = snd_soc_register_card(&mioa701); 184 rc = devm_snd_soc_register_card(&pdev->dev, &mioa701);
185 if (!rc) 185 if (!rc)
186 dev_warn(&pdev->dev, "Be warned that incorrect mixers/muxes setup will" 186 dev_warn(&pdev->dev, "Be warned that incorrect mixers/muxes setup will"
187 "lead to overheating and possible destruction of your device." 187 "lead to overheating and possible destruction of your device."
@@ -189,17 +189,8 @@ static int mioa701_wm9713_probe(struct platform_device *pdev)
189 return rc; 189 return rc;
190} 190}
191 191
192static int mioa701_wm9713_remove(struct platform_device *pdev)
193{
194 struct snd_soc_card *card = platform_get_drvdata(pdev);
195
196 snd_soc_unregister_card(card);
197 return 0;
198}
199
200static struct platform_driver mioa701_wm9713_driver = { 192static struct platform_driver mioa701_wm9713_driver = {
201 .probe = mioa701_wm9713_probe, 193 .probe = mioa701_wm9713_probe,
202 .remove = mioa701_wm9713_remove,
203 .driver = { 194 .driver = {
204 .name = "mioa701-wm9713", 195 .name = "mioa701-wm9713",
205 .pm = &snd_soc_pm_ops, 196 .pm = &snd_soc_pm_ops,
diff --git a/sound/soc/pxa/palm27x.c b/sound/soc/pxa/palm27x.c
index c20bbc042425..4e74d9573f03 100644
--- a/sound/soc/pxa/palm27x.c
+++ b/sound/soc/pxa/palm27x.c
@@ -140,22 +140,15 @@ static int palm27x_asoc_probe(struct platform_device *pdev)
140 140
141 palm27x_asoc.dev = &pdev->dev; 141 palm27x_asoc.dev = &pdev->dev;
142 142
143 ret = snd_soc_register_card(&palm27x_asoc); 143 ret = devm_snd_soc_register_card(&pdev->dev, &palm27x_asoc);
144 if (ret) 144 if (ret)
145 dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n", 145 dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n",
146 ret); 146 ret);
147 return ret; 147 return ret;
148} 148}
149 149
150static int palm27x_asoc_remove(struct platform_device *pdev)
151{
152 snd_soc_unregister_card(&palm27x_asoc);
153 return 0;
154}
155
156static struct platform_driver palm27x_wm9712_driver = { 150static struct platform_driver palm27x_wm9712_driver = {
157 .probe = palm27x_asoc_probe, 151 .probe = palm27x_asoc_probe,
158 .remove = palm27x_asoc_remove,
159 .driver = { 152 .driver = {
160 .name = "palm27x-asoc", 153 .name = "palm27x-asoc",
161 .pm = &snd_soc_pm_ops, 154 .pm = &snd_soc_pm_ops,
diff --git a/sound/soc/pxa/poodle.c b/sound/soc/pxa/poodle.c
index 80b457ac522a..84d0e2e50808 100644
--- a/sound/soc/pxa/poodle.c
+++ b/sound/soc/pxa/poodle.c
@@ -267,28 +267,19 @@ static int poodle_probe(struct platform_device *pdev)
267 267
268 card->dev = &pdev->dev; 268 card->dev = &pdev->dev;
269 269
270 ret = snd_soc_register_card(card); 270 ret = devm_snd_soc_register_card(&pdev->dev, card);
271 if (ret) 271 if (ret)
272 dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n", 272 dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n",
273 ret); 273 ret);
274 return ret; 274 return ret;
275} 275}
276 276
277static int poodle_remove(struct platform_device *pdev)
278{
279 struct snd_soc_card *card = platform_get_drvdata(pdev);
280
281 snd_soc_unregister_card(card);
282 return 0;
283}
284
285static struct platform_driver poodle_driver = { 277static struct platform_driver poodle_driver = {
286 .driver = { 278 .driver = {
287 .name = "poodle-audio", 279 .name = "poodle-audio",
288 .pm = &snd_soc_pm_ops, 280 .pm = &snd_soc_pm_ops,
289 }, 281 },
290 .probe = poodle_probe, 282 .probe = poodle_probe,
291 .remove = poodle_remove,
292}; 283};
293 284
294module_platform_driver(poodle_driver); 285module_platform_driver(poodle_driver);
diff --git a/sound/soc/pxa/pxa-ssp.c b/sound/soc/pxa/pxa-ssp.c
index 3da485ec1de7..da03fad1b9cd 100644
--- a/sound/soc/pxa/pxa-ssp.c
+++ b/sound/soc/pxa/pxa-ssp.c
@@ -809,6 +809,7 @@ static const struct of_device_id pxa_ssp_of_ids[] = {
809 { .compatible = "mrvl,pxa-ssp-dai" }, 809 { .compatible = "mrvl,pxa-ssp-dai" },
810 {} 810 {}
811}; 811};
812MODULE_DEVICE_TABLE(of, pxa_ssp_of_ids);
812#endif 813#endif
813 814
814static int asoc_ssp_probe(struct platform_device *pdev) 815static int asoc_ssp_probe(struct platform_device *pdev)
diff --git a/sound/soc/pxa/pxa2xx-ac97.c b/sound/soc/pxa/pxa2xx-ac97.c
index 9e4b04e0fbd1..f3de615aacd7 100644
--- a/sound/soc/pxa/pxa2xx-ac97.c
+++ b/sound/soc/pxa/pxa2xx-ac97.c
@@ -15,6 +15,7 @@
15#include <linux/module.h> 15#include <linux/module.h>
16#include <linux/platform_device.h> 16#include <linux/platform_device.h>
17#include <linux/dmaengine.h> 17#include <linux/dmaengine.h>
18#include <linux/dma/pxa-dma.h>
18 19
19#include <sound/core.h> 20#include <sound/core.h>
20#include <sound/ac97_codec.h> 21#include <sound/ac97_codec.h>
@@ -49,7 +50,11 @@ static struct snd_ac97_bus_ops pxa2xx_ac97_ops = {
49 .reset = pxa2xx_ac97_cold_reset, 50 .reset = pxa2xx_ac97_cold_reset,
50}; 51};
51 52
52static unsigned long pxa2xx_ac97_pcm_stereo_in_req = 11; 53static struct pxad_param pxa2xx_ac97_pcm_stereo_in_req = {
54 .prio = PXAD_PRIO_LOWEST,
55 .drcmr = 11,
56};
57
53static struct snd_dmaengine_dai_dma_data pxa2xx_ac97_pcm_stereo_in = { 58static struct snd_dmaengine_dai_dma_data pxa2xx_ac97_pcm_stereo_in = {
54 .addr = __PREG(PCDR), 59 .addr = __PREG(PCDR),
55 .addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES, 60 .addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES,
@@ -57,7 +62,11 @@ static struct snd_dmaengine_dai_dma_data pxa2xx_ac97_pcm_stereo_in = {
57 .filter_data = &pxa2xx_ac97_pcm_stereo_in_req, 62 .filter_data = &pxa2xx_ac97_pcm_stereo_in_req,
58}; 63};
59 64
60static unsigned long pxa2xx_ac97_pcm_stereo_out_req = 12; 65static struct pxad_param pxa2xx_ac97_pcm_stereo_out_req = {
66 .prio = PXAD_PRIO_LOWEST,
67 .drcmr = 12,
68};
69
61static struct snd_dmaengine_dai_dma_data pxa2xx_ac97_pcm_stereo_out = { 70static struct snd_dmaengine_dai_dma_data pxa2xx_ac97_pcm_stereo_out = {
62 .addr = __PREG(PCDR), 71 .addr = __PREG(PCDR),
63 .addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES, 72 .addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES,
@@ -65,7 +74,10 @@ static struct snd_dmaengine_dai_dma_data pxa2xx_ac97_pcm_stereo_out = {
65 .filter_data = &pxa2xx_ac97_pcm_stereo_out_req, 74 .filter_data = &pxa2xx_ac97_pcm_stereo_out_req,
66}; 75};
67 76
68static unsigned long pxa2xx_ac97_pcm_aux_mono_out_req = 10; 77static struct pxad_param pxa2xx_ac97_pcm_aux_mono_out_req = {
78 .prio = PXAD_PRIO_LOWEST,
79 .drcmr = 10,
80};
69static struct snd_dmaengine_dai_dma_data pxa2xx_ac97_pcm_aux_mono_out = { 81static struct snd_dmaengine_dai_dma_data pxa2xx_ac97_pcm_aux_mono_out = {
70 .addr = __PREG(MODR), 82 .addr = __PREG(MODR),
71 .addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES, 83 .addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES,
@@ -73,7 +85,10 @@ static struct snd_dmaengine_dai_dma_data pxa2xx_ac97_pcm_aux_mono_out = {
73 .filter_data = &pxa2xx_ac97_pcm_aux_mono_out_req, 85 .filter_data = &pxa2xx_ac97_pcm_aux_mono_out_req,
74}; 86};
75 87
76static unsigned long pxa2xx_ac97_pcm_aux_mono_in_req = 9; 88static struct pxad_param pxa2xx_ac97_pcm_aux_mono_in_req = {
89 .prio = PXAD_PRIO_LOWEST,
90 .drcmr = 9,
91};
77static struct snd_dmaengine_dai_dma_data pxa2xx_ac97_pcm_aux_mono_in = { 92static struct snd_dmaengine_dai_dma_data pxa2xx_ac97_pcm_aux_mono_in = {
78 .addr = __PREG(MODR), 93 .addr = __PREG(MODR),
79 .addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES, 94 .addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES,
@@ -81,7 +96,10 @@ static struct snd_dmaengine_dai_dma_data pxa2xx_ac97_pcm_aux_mono_in = {
81 .filter_data = &pxa2xx_ac97_pcm_aux_mono_in_req, 96 .filter_data = &pxa2xx_ac97_pcm_aux_mono_in_req,
82}; 97};
83 98
84static unsigned long pxa2xx_ac97_pcm_aux_mic_mono_req = 8; 99static struct pxad_param pxa2xx_ac97_pcm_aux_mic_mono_req = {
100 .prio = PXAD_PRIO_LOWEST,
101 .drcmr = 8,
102};
85static struct snd_dmaengine_dai_dma_data pxa2xx_ac97_pcm_mic_mono_in = { 103static struct snd_dmaengine_dai_dma_data pxa2xx_ac97_pcm_mic_mono_in = {
86 .addr = __PREG(MCDR), 104 .addr = __PREG(MCDR),
87 .addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES, 105 .addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES,
@@ -89,9 +107,8 @@ static struct snd_dmaengine_dai_dma_data pxa2xx_ac97_pcm_mic_mono_in = {
89 .filter_data = &pxa2xx_ac97_pcm_aux_mic_mono_req, 107 .filter_data = &pxa2xx_ac97_pcm_aux_mic_mono_req,
90}; 108};
91 109
92static int pxa2xx_ac97_hw_params(struct snd_pcm_substream *substream, 110static int pxa2xx_ac97_hifi_startup(struct snd_pcm_substream *substream,
93 struct snd_pcm_hw_params *params, 111 struct snd_soc_dai *cpu_dai)
94 struct snd_soc_dai *cpu_dai)
95{ 112{
96 struct snd_dmaengine_dai_dma_data *dma_data; 113 struct snd_dmaengine_dai_dma_data *dma_data;
97 114
@@ -105,9 +122,8 @@ static int pxa2xx_ac97_hw_params(struct snd_pcm_substream *substream,
105 return 0; 122 return 0;
106} 123}
107 124
108static int pxa2xx_ac97_hw_aux_params(struct snd_pcm_substream *substream, 125static int pxa2xx_ac97_aux_startup(struct snd_pcm_substream *substream,
109 struct snd_pcm_hw_params *params, 126 struct snd_soc_dai *cpu_dai)
110 struct snd_soc_dai *cpu_dai)
111{ 127{
112 struct snd_dmaengine_dai_dma_data *dma_data; 128 struct snd_dmaengine_dai_dma_data *dma_data;
113 129
@@ -121,9 +137,8 @@ static int pxa2xx_ac97_hw_aux_params(struct snd_pcm_substream *substream,
121 return 0; 137 return 0;
122} 138}
123 139
124static int pxa2xx_ac97_hw_mic_params(struct snd_pcm_substream *substream, 140static int pxa2xx_ac97_mic_startup(struct snd_pcm_substream *substream,
125 struct snd_pcm_hw_params *params, 141 struct snd_soc_dai *cpu_dai)
126 struct snd_soc_dai *cpu_dai)
127{ 142{
128 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 143 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
129 return -ENODEV; 144 return -ENODEV;
@@ -139,15 +154,15 @@ static int pxa2xx_ac97_hw_mic_params(struct snd_pcm_substream *substream,
139 SNDRV_PCM_RATE_48000) 154 SNDRV_PCM_RATE_48000)
140 155
141static const struct snd_soc_dai_ops pxa_ac97_hifi_dai_ops = { 156static const struct snd_soc_dai_ops pxa_ac97_hifi_dai_ops = {
142 .hw_params = pxa2xx_ac97_hw_params, 157 .startup = pxa2xx_ac97_hifi_startup,
143}; 158};
144 159
145static const struct snd_soc_dai_ops pxa_ac97_aux_dai_ops = { 160static const struct snd_soc_dai_ops pxa_ac97_aux_dai_ops = {
146 .hw_params = pxa2xx_ac97_hw_aux_params, 161 .startup = pxa2xx_ac97_aux_startup,
147}; 162};
148 163
149static const struct snd_soc_dai_ops pxa_ac97_mic_dai_ops = { 164static const struct snd_soc_dai_ops pxa_ac97_mic_dai_ops = {
150 .hw_params = pxa2xx_ac97_hw_mic_params, 165 .startup = pxa2xx_ac97_mic_startup,
151}; 166};
152 167
153/* 168/*
diff --git a/sound/soc/pxa/pxa2xx-i2s.c b/sound/soc/pxa/pxa2xx-i2s.c
index 6b4e40036910..0389cf7b4b1e 100644
--- a/sound/soc/pxa/pxa2xx-i2s.c
+++ b/sound/soc/pxa/pxa2xx-i2s.c
@@ -319,6 +319,9 @@ static int pxa2xx_i2s_probe(struct snd_soc_dai *dai)
319 /* Along with FIFO servicing */ 319 /* Along with FIFO servicing */
320 SAIMR &= ~(SAIMR_RFS | SAIMR_TFS); 320 SAIMR &= ~(SAIMR_RFS | SAIMR_TFS);
321 321
322 snd_soc_dai_init_dma_data(dai, &pxa2xx_i2s_pcm_stereo_out,
323 &pxa2xx_i2s_pcm_stereo_in);
324
322 return 0; 325 return 0;
323} 326}
324 327
diff --git a/sound/soc/pxa/pxa2xx-pcm.c b/sound/soc/pxa/pxa2xx-pcm.c
index 831ee37d2e3e..9f390398d518 100644
--- a/sound/soc/pxa/pxa2xx-pcm.c
+++ b/sound/soc/pxa/pxa2xx-pcm.c
@@ -15,8 +15,6 @@
15#include <linux/dmaengine.h> 15#include <linux/dmaengine.h>
16#include <linux/of.h> 16#include <linux/of.h>
17 17
18#include <mach/dma.h>
19
20#include <sound/core.h> 18#include <sound/core.h>
21#include <sound/soc.h> 19#include <sound/soc.h>
22#include <sound/pxa2xx-lib.h> 20#include <sound/pxa2xx-lib.h>
@@ -27,11 +25,8 @@
27static int pxa2xx_pcm_hw_params(struct snd_pcm_substream *substream, 25static int pxa2xx_pcm_hw_params(struct snd_pcm_substream *substream,
28 struct snd_pcm_hw_params *params) 26 struct snd_pcm_hw_params *params)
29{ 27{
30 struct snd_pcm_runtime *runtime = substream->runtime;
31 struct pxa2xx_runtime_data *prtd = runtime->private_data;
32 struct snd_soc_pcm_runtime *rtd = substream->private_data; 28 struct snd_soc_pcm_runtime *rtd = substream->private_data;
33 struct snd_dmaengine_dai_dma_data *dma; 29 struct snd_dmaengine_dai_dma_data *dma;
34 int ret;
35 30
36 dma = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream); 31 dma = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
37 32
@@ -40,40 +35,13 @@ static int pxa2xx_pcm_hw_params(struct snd_pcm_substream *substream,
40 if (!dma) 35 if (!dma)
41 return 0; 36 return 0;
42 37
43 /* this may get called several times by oss emulation
44 * with different params */
45 if (prtd->params == NULL) {
46 prtd->params = dma;
47 ret = pxa_request_dma("name", DMA_PRIO_LOW,
48 pxa2xx_pcm_dma_irq, substream);
49 if (ret < 0)
50 return ret;
51 prtd->dma_ch = ret;
52 } else if (prtd->params != dma) {
53 pxa_free_dma(prtd->dma_ch);
54 prtd->params = dma;
55 ret = pxa_request_dma("name", DMA_PRIO_LOW,
56 pxa2xx_pcm_dma_irq, substream);
57 if (ret < 0)
58 return ret;
59 prtd->dma_ch = ret;
60 }
61
62 return __pxa2xx_pcm_hw_params(substream, params); 38 return __pxa2xx_pcm_hw_params(substream, params);
63} 39}
64 40
65static int pxa2xx_pcm_hw_free(struct snd_pcm_substream *substream) 41static int pxa2xx_pcm_hw_free(struct snd_pcm_substream *substream)
66{ 42{
67 struct pxa2xx_runtime_data *prtd = substream->runtime->private_data;
68
69 __pxa2xx_pcm_hw_free(substream); 43 __pxa2xx_pcm_hw_free(substream);
70 44
71 if (prtd->dma_ch >= 0) {
72 pxa_free_dma(prtd->dma_ch);
73 prtd->dma_ch = -1;
74 prtd->params = NULL;
75 }
76
77 return 0; 45 return 0;
78} 46}
79 47
@@ -132,6 +100,7 @@ static const struct of_device_id snd_soc_pxa_audio_match[] = {
132 { .compatible = "mrvl,pxa-pcm-audio" }, 100 { .compatible = "mrvl,pxa-pcm-audio" },
133 { } 101 { }
134}; 102};
103MODULE_DEVICE_TABLE(of, snd_soc_pxa_audio_match);
135#endif 104#endif
136 105
137static struct platform_driver pxa_pcm_driver = { 106static struct platform_driver pxa_pcm_driver = {
diff --git a/sound/soc/pxa/spitz.c b/sound/soc/pxa/spitz.c
index 461123ad5ff2..b00222620fd0 100644
--- a/sound/soc/pxa/spitz.c
+++ b/sound/soc/pxa/spitz.c
@@ -305,7 +305,7 @@ static int spitz_probe(struct platform_device *pdev)
305 305
306 card->dev = &pdev->dev; 306 card->dev = &pdev->dev;
307 307
308 ret = snd_soc_register_card(card); 308 ret = devm_snd_soc_register_card(&pdev->dev, card);
309 if (ret) { 309 if (ret) {
310 dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n", 310 dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n",
311 ret); 311 ret);
@@ -322,9 +322,6 @@ err1:
322 322
323static int spitz_remove(struct platform_device *pdev) 323static int spitz_remove(struct platform_device *pdev)
324{ 324{
325 struct snd_soc_card *card = platform_get_drvdata(pdev);
326
327 snd_soc_unregister_card(card);
328 gpio_free(spitz_mic_gpio); 325 gpio_free(spitz_mic_gpio);
329 return 0; 326 return 0;
330} 327}
diff --git a/sound/soc/pxa/tosa.c b/sound/soc/pxa/tosa.c
index f59f566551ef..49518dd642aa 100644
--- a/sound/soc/pxa/tosa.c
+++ b/sound/soc/pxa/tosa.c
@@ -233,7 +233,7 @@ static int tosa_probe(struct platform_device *pdev)
233 233
234 card->dev = &pdev->dev; 234 card->dev = &pdev->dev;
235 235
236 ret = snd_soc_register_card(card); 236 ret = devm_snd_soc_register_card(&pdev->dev, card);
237 if (ret) { 237 if (ret) {
238 dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n", 238 dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n",
239 ret); 239 ret);
@@ -244,10 +244,7 @@ static int tosa_probe(struct platform_device *pdev)
244 244
245static int tosa_remove(struct platform_device *pdev) 245static int tosa_remove(struct platform_device *pdev)
246{ 246{
247 struct snd_soc_card *card = platform_get_drvdata(pdev);
248
249 gpio_free(TOSA_GPIO_L_MUTE); 247 gpio_free(TOSA_GPIO_L_MUTE);
250 snd_soc_unregister_card(card);
251 return 0; 248 return 0;
252} 249}
253 250
diff --git a/sound/soc/pxa/ttc-dkb.c b/sound/soc/pxa/ttc-dkb.c
index 1753c7d9e760..65c20f779177 100644
--- a/sound/soc/pxa/ttc-dkb.c
+++ b/sound/soc/pxa/ttc-dkb.c
@@ -128,7 +128,7 @@ static int ttc_dkb_probe(struct platform_device *pdev)
128 128
129 card->dev = &pdev->dev; 129 card->dev = &pdev->dev;
130 130
131 ret = snd_soc_register_card(card); 131 ret = devm_snd_soc_register_card(&pdev->dev, card);
132 if (ret) 132 if (ret)
133 dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n", 133 dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n",
134 ret); 134 ret);
@@ -136,22 +136,12 @@ static int ttc_dkb_probe(struct platform_device *pdev)
136 return ret; 136 return ret;
137} 137}
138 138
139static int ttc_dkb_remove(struct platform_device *pdev)
140{
141 struct snd_soc_card *card = platform_get_drvdata(pdev);
142
143 snd_soc_unregister_card(card);
144
145 return 0;
146}
147
148static struct platform_driver ttc_dkb_driver = { 139static struct platform_driver ttc_dkb_driver = {
149 .driver = { 140 .driver = {
150 .name = "ttc-dkb-audio", 141 .name = "ttc-dkb-audio",
151 .pm = &snd_soc_pm_ops, 142 .pm = &snd_soc_pm_ops,
152 }, 143 },
153 .probe = ttc_dkb_probe, 144 .probe = ttc_dkb_probe,
154 .remove = ttc_dkb_remove,
155}; 145};
156 146
157module_platform_driver(ttc_dkb_driver); 147module_platform_driver(ttc_dkb_driver);
diff --git a/sound/soc/qcom/lpass-cpu.c b/sound/soc/qcom/lpass-cpu.c
index 97bc2023f08a..e5101e0d2d37 100644
--- a/sound/soc/qcom/lpass-cpu.c
+++ b/sound/soc/qcom/lpass-cpu.c
@@ -438,7 +438,8 @@ int asoc_qcom_lpass_cpu_platform_probe(struct platform_device *pdev)
438 if (IS_ERR(drvdata->mi2s_bit_clk[dai_id])) { 438 if (IS_ERR(drvdata->mi2s_bit_clk[dai_id])) {
439 dev_err(&pdev->dev, 439 dev_err(&pdev->dev,
440 "%s() error getting mi2s-bit-clk: %ld\n", 440 "%s() error getting mi2s-bit-clk: %ld\n",
441 __func__, PTR_ERR(drvdata->mi2s_bit_clk[i])); 441 __func__,
442 PTR_ERR(drvdata->mi2s_bit_clk[dai_id]));
442 return PTR_ERR(drvdata->mi2s_bit_clk[dai_id]); 443 return PTR_ERR(drvdata->mi2s_bit_clk[dai_id]);
443 } 444 }
444 } 445 }
diff --git a/sound/soc/rockchip/Kconfig b/sound/soc/rockchip/Kconfig
index 58bae8e2cf5f..f1e0c703e0d2 100644
--- a/sound/soc/rockchip/Kconfig
+++ b/sound/soc/rockchip/Kconfig
@@ -15,9 +15,17 @@ config SND_SOC_ROCKCHIP_I2S
15 Rockchip I2S device. The device supports upto maximum of 15 Rockchip I2S device. The device supports upto maximum of
16 8 channels each for play and record. 16 8 channels each for play and record.
17 17
18config SND_SOC_ROCKCHIP_SPDIF
19 tristate "Rockchip SPDIF Device Driver"
20 depends on CLKDEV_LOOKUP && SND_SOC_ROCKCHIP
21 select SND_SOC_GENERIC_DMAENGINE_PCM
22 help
23 Say Y or M if you want to add support for SPDIF driver for
24 Rockchip SPDIF transceiver device.
25
18config SND_SOC_ROCKCHIP_MAX98090 26config SND_SOC_ROCKCHIP_MAX98090
19 tristate "ASoC support for Rockchip boards using a MAX98090 codec" 27 tristate "ASoC support for Rockchip boards using a MAX98090 codec"
20 depends on SND_SOC_ROCKCHIP && I2C && GPIOLIB 28 depends on SND_SOC_ROCKCHIP && I2C && GPIOLIB && CLKDEV_LOOKUP
21 select SND_SOC_ROCKCHIP_I2S 29 select SND_SOC_ROCKCHIP_I2S
22 select SND_SOC_MAX98090 30 select SND_SOC_MAX98090
23 select SND_SOC_TS3A227E 31 select SND_SOC_TS3A227E
@@ -27,7 +35,7 @@ config SND_SOC_ROCKCHIP_MAX98090
27 35
28config SND_SOC_ROCKCHIP_RT5645 36config SND_SOC_ROCKCHIP_RT5645
29 tristate "ASoC support for Rockchip boards using a RT5645/RT5650 codec" 37 tristate "ASoC support for Rockchip boards using a RT5645/RT5650 codec"
30 depends on SND_SOC_ROCKCHIP && I2C && GPIOLIB 38 depends on SND_SOC_ROCKCHIP && I2C && GPIOLIB && CLKDEV_LOOKUP
31 select SND_SOC_ROCKCHIP_I2S 39 select SND_SOC_ROCKCHIP_I2S
32 select SND_SOC_RT5645 40 select SND_SOC_RT5645
33 help 41 help
diff --git a/sound/soc/rockchip/Makefile b/sound/soc/rockchip/Makefile
index 1bc1dc3c729a..c0bf560125f3 100644
--- a/sound/soc/rockchip/Makefile
+++ b/sound/soc/rockchip/Makefile
@@ -1,7 +1,9 @@
1# ROCKCHIP Platform Support 1# ROCKCHIP Platform Support
2snd-soc-i2s-objs := rockchip_i2s.o 2snd-soc-rockchip-i2s-objs := rockchip_i2s.o
3snd-soc-rockchip-spdif-objs := rockchip_spdif.o
3 4
4obj-$(CONFIG_SND_SOC_ROCKCHIP_I2S) += snd-soc-i2s.o 5obj-$(CONFIG_SND_SOC_ROCKCHIP_I2S) += snd-soc-rockchip-i2s.o
6obj-$(CONFIG_SND_SOC_ROCKCHIP_SPDIF) += snd-soc-rockchip-spdif.o
5 7
6snd-soc-rockchip-max98090-objs := rockchip_max98090.o 8snd-soc-rockchip-max98090-objs := rockchip_max98090.o
7snd-soc-rockchip-rt5645-objs := rockchip_rt5645.o 9snd-soc-rockchip-rt5645-objs := rockchip_rt5645.o
diff --git a/sound/soc/rockchip/rockchip_i2s.c b/sound/soc/rockchip/rockchip_i2s.c
index b93610212e3d..58ee64594f07 100644
--- a/sound/soc/rockchip/rockchip_i2s.c
+++ b/sound/soc/rockchip/rockchip_i2s.c
@@ -226,6 +226,7 @@ static int rockchip_i2s_hw_params(struct snd_pcm_substream *substream,
226 struct snd_soc_dai *dai) 226 struct snd_soc_dai *dai)
227{ 227{
228 struct rk_i2s_dev *i2s = to_info(dai); 228 struct rk_i2s_dev *i2s = to_info(dai);
229 struct snd_soc_pcm_runtime *rtd = substream->private_data;
229 unsigned int val = 0; 230 unsigned int val = 0;
230 231
231 switch (params_format(params)) { 232 switch (params_format(params)) {
@@ -245,13 +246,46 @@ static int rockchip_i2s_hw_params(struct snd_pcm_substream *substream,
245 return -EINVAL; 246 return -EINVAL;
246 } 247 }
247 248
248 regmap_update_bits(i2s->regmap, I2S_TXCR, I2S_TXCR_VDW_MASK, val); 249 switch (params_channels(params)) {
249 regmap_update_bits(i2s->regmap, I2S_RXCR, I2S_RXCR_VDW_MASK, val); 250 case 8:
251 val |= I2S_CHN_8;
252 break;
253 case 6:
254 val |= I2S_CHN_6;
255 break;
256 case 4:
257 val |= I2S_CHN_4;
258 break;
259 case 2:
260 val |= I2S_CHN_2;
261 break;
262 default:
263 dev_err(i2s->dev, "invalid channel: %d\n",
264 params_channels(params));
265 return -EINVAL;
266 }
267
268 if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
269 regmap_update_bits(i2s->regmap, I2S_RXCR,
270 I2S_RXCR_VDW_MASK | I2S_RXCR_CSR_MASK,
271 val);
272 else
273 regmap_update_bits(i2s->regmap, I2S_TXCR,
274 I2S_TXCR_VDW_MASK | I2S_TXCR_CSR_MASK,
275 val);
276
250 regmap_update_bits(i2s->regmap, I2S_DMACR, I2S_DMACR_TDL_MASK, 277 regmap_update_bits(i2s->regmap, I2S_DMACR, I2S_DMACR_TDL_MASK,
251 I2S_DMACR_TDL(16)); 278 I2S_DMACR_TDL(16));
252 regmap_update_bits(i2s->regmap, I2S_DMACR, I2S_DMACR_RDL_MASK, 279 regmap_update_bits(i2s->regmap, I2S_DMACR, I2S_DMACR_RDL_MASK,
253 I2S_DMACR_RDL(16)); 280 I2S_DMACR_RDL(16));
254 281
282 val = I2S_CKR_TRCM_TXRX;
283 if (dai->driver->symmetric_rates || rtd->dai_link->symmetric_rates)
284 val = I2S_CKR_TRCM_TXSHARE;
285
286 regmap_update_bits(i2s->regmap, I2S_CKR,
287 I2S_CKR_TRCM_MASK,
288 val);
255 return 0; 289 return 0;
256} 290}
257 291
@@ -415,10 +449,12 @@ static const struct regmap_config rockchip_i2s_regmap_config = {
415 449
416static int rockchip_i2s_probe(struct platform_device *pdev) 450static int rockchip_i2s_probe(struct platform_device *pdev)
417{ 451{
452 struct device_node *node = pdev->dev.of_node;
418 struct rk_i2s_dev *i2s; 453 struct rk_i2s_dev *i2s;
419 struct resource *res; 454 struct resource *res;
420 void __iomem *regs; 455 void __iomem *regs;
421 int ret; 456 int ret;
457 int val;
422 458
423 i2s = devm_kzalloc(&pdev->dev, sizeof(*i2s), GFP_KERNEL); 459 i2s = devm_kzalloc(&pdev->dev, sizeof(*i2s), GFP_KERNEL);
424 if (!i2s) { 460 if (!i2s) {
@@ -475,6 +511,14 @@ static int rockchip_i2s_probe(struct platform_device *pdev)
475 goto err_pm_disable; 511 goto err_pm_disable;
476 } 512 }
477 513
514 /* refine capture channels */
515 if (!of_property_read_u32(node, "rockchip,capture-channels", &val)) {
516 if (val >= 2 && val <= 8)
517 rockchip_i2s_dai.capture.channels_max = val;
518 else
519 rockchip_i2s_dai.capture.channels_max = 2;
520 }
521
478 ret = devm_snd_soc_register_component(&pdev->dev, 522 ret = devm_snd_soc_register_component(&pdev->dev,
479 &rockchip_i2s_component, 523 &rockchip_i2s_component,
480 &rockchip_i2s_dai, 1); 524 &rockchip_i2s_dai, 1);
diff --git a/sound/soc/rockchip/rockchip_i2s.h b/sound/soc/rockchip/rockchip_i2s.h
index 93f456f518a9..dc6e2c74d088 100644
--- a/sound/soc/rockchip/rockchip_i2s.h
+++ b/sound/soc/rockchip/rockchip_i2s.h
@@ -49,6 +49,9 @@
49 * RXCR 49 * RXCR
50 * receive operation control register 50 * receive operation control register
51*/ 51*/
52#define I2S_RXCR_CSR_SHIFT 15
53#define I2S_RXCR_CSR(x) (x << I2S_RXCR_CSR_SHIFT)
54#define I2S_RXCR_CSR_MASK (3 << I2S_RXCR_CSR_SHIFT)
52#define I2S_RXCR_HWT BIT(14) 55#define I2S_RXCR_HWT BIT(14)
53#define I2S_RXCR_SJM_SHIFT 12 56#define I2S_RXCR_SJM_SHIFT 12
54#define I2S_RXCR_SJM_R (0 << I2S_RXCR_SJM_SHIFT) 57#define I2S_RXCR_SJM_R (0 << I2S_RXCR_SJM_SHIFT)
@@ -75,6 +78,12 @@
75 * CKR 78 * CKR
76 * clock generation register 79 * clock generation register
77*/ 80*/
81#define I2S_CKR_TRCM_SHIFT 28
82#define I2S_CKR_TRCM(x) (x << I2S_CKR_TRCM_SHIFT)
83#define I2S_CKR_TRCM_TXRX (0 << I2S_CKR_TRCM_SHIFT)
84#define I2S_CKR_TRCM_TXSHARE (1 << I2S_CKR_TRCM_SHIFT)
85#define I2S_CKR_TRCM_RXSHARE (2 << I2S_CKR_TRCM_SHIFT)
86#define I2S_CKR_TRCM_MASK (3 << I2S_CKR_TRCM_SHIFT)
78#define I2S_CKR_MSS_SHIFT 27 87#define I2S_CKR_MSS_SHIFT 27
79#define I2S_CKR_MSS_MASTER (0 << I2S_CKR_MSS_SHIFT) 88#define I2S_CKR_MSS_MASTER (0 << I2S_CKR_MSS_SHIFT)
80#define I2S_CKR_MSS_SLAVE (1 << I2S_CKR_MSS_SHIFT) 89#define I2S_CKR_MSS_SLAVE (1 << I2S_CKR_MSS_SHIFT)
@@ -207,6 +216,13 @@ enum {
207 ROCKCHIP_DIV_BCLK, 216 ROCKCHIP_DIV_BCLK,
208}; 217};
209 218
219/* channel select */
220#define I2S_CSR_SHIFT 15
221#define I2S_CHN_2 (0 << I2S_CSR_SHIFT)
222#define I2S_CHN_4 (1 << I2S_CSR_SHIFT)
223#define I2S_CHN_6 (2 << I2S_CSR_SHIFT)
224#define I2S_CHN_8 (3 << I2S_CSR_SHIFT)
225
210/* I2S REGS */ 226/* I2S REGS */
211#define I2S_TXCR (0x0000) 227#define I2S_TXCR (0x0000)
212#define I2S_RXCR (0x0004) 228#define I2S_RXCR (0x0004)
diff --git a/sound/soc/rockchip/rockchip_spdif.c b/sound/soc/rockchip/rockchip_spdif.c
new file mode 100644
index 000000000000..a38a3029062c
--- /dev/null
+++ b/sound/soc/rockchip/rockchip_spdif.c
@@ -0,0 +1,405 @@
1/* sound/soc/rockchip/rk_spdif.c
2 *
3 * ALSA SoC Audio Layer - Rockchip I2S Controller driver
4 *
5 * Copyright (c) 2014 Rockchip Electronics Co. Ltd.
6 * Author: Jianqun <jay.xu@rock-chips.com>
7 * Copyright (c) 2015 Collabora Ltd.
8 * Author: Sjoerd Simons <sjoerd.simons@collabora.co.uk>
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/delay.h>
17#include <linux/of_gpio.h>
18#include <linux/clk.h>
19#include <linux/pm_runtime.h>
20#include <linux/mfd/syscon.h>
21#include <linux/regmap.h>
22#include <sound/pcm_params.h>
23#include <sound/dmaengine_pcm.h>
24
25#include "rockchip_spdif.h"
26
27enum rk_spdif_type {
28 RK_SPDIF_RK3066,
29 RK_SPDIF_RK3188,
30 RK_SPDIF_RK3288,
31};
32
33#define RK3288_GRF_SOC_CON2 0x24c
34
35struct rk_spdif_dev {
36 struct device *dev;
37
38 struct clk *mclk;
39 struct clk *hclk;
40
41 struct snd_dmaengine_dai_dma_data playback_dma_data;
42
43 struct regmap *regmap;
44};
45
46static const struct of_device_id rk_spdif_match[] = {
47 { .compatible = "rockchip,rk3066-spdif",
48 .data = (void *) RK_SPDIF_RK3066 },
49 { .compatible = "rockchip,rk3188-spdif",
50 .data = (void *) RK_SPDIF_RK3188 },
51 { .compatible = "rockchip,rk3288-spdif",
52 .data = (void *) RK_SPDIF_RK3288 },
53 {},
54};
55MODULE_DEVICE_TABLE(of, rk_spdif_match);
56
57static int rk_spdif_runtime_suspend(struct device *dev)
58{
59 struct rk_spdif_dev *spdif = dev_get_drvdata(dev);
60
61 clk_disable_unprepare(spdif->mclk);
62 clk_disable_unprepare(spdif->hclk);
63
64 return 0;
65}
66
67static int rk_spdif_runtime_resume(struct device *dev)
68{
69 struct rk_spdif_dev *spdif = dev_get_drvdata(dev);
70 int ret;
71
72 ret = clk_prepare_enable(spdif->mclk);
73 if (ret) {
74 dev_err(spdif->dev, "mclk clock enable failed %d\n", ret);
75 return ret;
76 }
77
78 ret = clk_prepare_enable(spdif->hclk);
79 if (ret) {
80 dev_err(spdif->dev, "hclk clock enable failed %d\n", ret);
81 return ret;
82 }
83
84 return 0;
85}
86
87static int rk_spdif_hw_params(struct snd_pcm_substream *substream,
88 struct snd_pcm_hw_params *params,
89 struct snd_soc_dai *dai)
90{
91 struct rk_spdif_dev *spdif = snd_soc_dai_get_drvdata(dai);
92 unsigned int val = SPDIF_CFGR_HALFWORD_ENABLE;
93 int srate, mclk;
94 int ret;
95
96 srate = params_rate(params);
97 switch (srate) {
98 case 32000:
99 case 48000:
100 case 96000:
101 mclk = 96000 * 128; /* 12288000 hz */
102 break;
103 case 44100:
104 mclk = 44100 * 256; /* 11289600 hz */
105 break;
106 case 192000:
107 mclk = 192000 * 128; /* 24576000 hz */
108 break;
109 default:
110 return -EINVAL;
111 }
112
113 switch (params_format(params)) {
114 case SNDRV_PCM_FORMAT_S16_LE:
115 val |= SPDIF_CFGR_VDW_16;
116 break;
117 case SNDRV_PCM_FORMAT_S20_3LE:
118 val |= SPDIF_CFGR_VDW_20;
119 break;
120 case SNDRV_PCM_FORMAT_S24_LE:
121 val |= SPDIF_CFGR_VDW_24;
122 break;
123 default:
124 return -EINVAL;
125 }
126
127 /* Set clock and calculate divider */
128 ret = clk_set_rate(spdif->mclk, mclk);
129 if (ret != 0) {
130 dev_err(spdif->dev, "Failed to set module clock rate: %d\n",
131 ret);
132 return ret;
133 }
134
135 val |= SPDIF_CFGR_CLK_DIV(mclk/(srate * 256));
136 ret = regmap_update_bits(spdif->regmap, SPDIF_CFGR,
137 SPDIF_CFGR_CLK_DIV_MASK | SPDIF_CFGR_HALFWORD_ENABLE |
138 SDPIF_CFGR_VDW_MASK,
139 val);
140
141 return ret;
142}
143
144static int rk_spdif_trigger(struct snd_pcm_substream *substream,
145 int cmd, struct snd_soc_dai *dai)
146{
147 struct rk_spdif_dev *spdif = snd_soc_dai_get_drvdata(dai);
148 int ret;
149
150 switch (cmd) {
151 case SNDRV_PCM_TRIGGER_START:
152 case SNDRV_PCM_TRIGGER_RESUME:
153 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
154 ret = regmap_update_bits(spdif->regmap, SPDIF_DMACR,
155 SPDIF_DMACR_TDE_ENABLE,
156 SPDIF_DMACR_TDE_ENABLE);
157
158 if (ret != 0)
159 return ret;
160
161 ret = regmap_update_bits(spdif->regmap, SPDIF_XFER,
162 SPDIF_XFER_TXS_START,
163 SPDIF_XFER_TXS_START);
164 break;
165 case SNDRV_PCM_TRIGGER_SUSPEND:
166 case SNDRV_PCM_TRIGGER_STOP:
167 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
168 ret = regmap_update_bits(spdif->regmap, SPDIF_DMACR,
169 SPDIF_DMACR_TDE_ENABLE,
170 SPDIF_DMACR_TDE_DISABLE);
171
172 if (ret != 0)
173 return ret;
174
175 ret = regmap_update_bits(spdif->regmap, SPDIF_XFER,
176 SPDIF_XFER_TXS_START,
177 SPDIF_XFER_TXS_STOP);
178 break;
179 default:
180 ret = -EINVAL;
181 break;
182 }
183
184 return ret;
185}
186
187static int rk_spdif_dai_probe(struct snd_soc_dai *dai)
188{
189 struct rk_spdif_dev *spdif = snd_soc_dai_get_drvdata(dai);
190
191 dai->playback_dma_data = &spdif->playback_dma_data;
192
193 return 0;
194}
195
196static const struct snd_soc_dai_ops rk_spdif_dai_ops = {
197 .hw_params = rk_spdif_hw_params,
198 .trigger = rk_spdif_trigger,
199};
200
201static struct snd_soc_dai_driver rk_spdif_dai = {
202 .probe = rk_spdif_dai_probe,
203 .playback = {
204 .stream_name = "Playback",
205 .channels_min = 2,
206 .channels_max = 2,
207 .rates = (SNDRV_PCM_RATE_32000 |
208 SNDRV_PCM_RATE_44100 |
209 SNDRV_PCM_RATE_48000 |
210 SNDRV_PCM_RATE_96000 |
211 SNDRV_PCM_RATE_192000),
212 .formats = (SNDRV_PCM_FMTBIT_S16_LE |
213 SNDRV_PCM_FMTBIT_S20_3LE |
214 SNDRV_PCM_FMTBIT_S24_LE),
215 },
216 .ops = &rk_spdif_dai_ops,
217};
218
219static const struct snd_soc_component_driver rk_spdif_component = {
220 .name = "rockchip-spdif",
221};
222
223static bool rk_spdif_wr_reg(struct device *dev, unsigned int reg)
224{
225 switch (reg) {
226 case SPDIF_CFGR:
227 case SPDIF_DMACR:
228 case SPDIF_INTCR:
229 case SPDIF_XFER:
230 case SPDIF_SMPDR:
231 return true;
232 default:
233 return false;
234 }
235}
236
237static bool rk_spdif_rd_reg(struct device *dev, unsigned int reg)
238{
239 switch (reg) {
240 case SPDIF_CFGR:
241 case SPDIF_SDBLR:
242 case SPDIF_INTCR:
243 case SPDIF_INTSR:
244 case SPDIF_XFER:
245 return true;
246 default:
247 return false;
248 }
249}
250
251static bool rk_spdif_volatile_reg(struct device *dev, unsigned int reg)
252{
253 switch (reg) {
254 case SPDIF_INTSR:
255 case SPDIF_SDBLR:
256 return true;
257 default:
258 return false;
259 }
260}
261
262static const struct regmap_config rk_spdif_regmap_config = {
263 .reg_bits = 32,
264 .reg_stride = 4,
265 .val_bits = 32,
266 .max_register = SPDIF_SMPDR,
267 .writeable_reg = rk_spdif_wr_reg,
268 .readable_reg = rk_spdif_rd_reg,
269 .volatile_reg = rk_spdif_volatile_reg,
270 .cache_type = REGCACHE_FLAT,
271};
272
273static int rk_spdif_probe(struct platform_device *pdev)
274{
275 struct device_node *np = pdev->dev.of_node;
276 struct rk_spdif_dev *spdif;
277 const struct of_device_id *match;
278 struct resource *res;
279 void __iomem *regs;
280 int ret;
281
282 match = of_match_node(rk_spdif_match, np);
283 if ((int) match->data == RK_SPDIF_RK3288) {
284 struct regmap *grf;
285
286 grf = syscon_regmap_lookup_by_phandle(np, "rockchip,grf");
287 if (IS_ERR(grf)) {
288 dev_err(&pdev->dev,
289 "rockchip_spdif missing 'rockchip,grf' \n");
290 return PTR_ERR(grf);
291 }
292
293 /* Select the 8 channel SPDIF solution on RK3288 as
294 * the 2 channel one does not appear to work
295 */
296 regmap_write(grf, RK3288_GRF_SOC_CON2, BIT(1) << 16);
297 }
298
299 spdif = devm_kzalloc(&pdev->dev, sizeof(*spdif), GFP_KERNEL);
300 if (!spdif)
301 return -ENOMEM;
302
303 spdif->hclk = devm_clk_get(&pdev->dev, "hclk");
304 if (IS_ERR(spdif->hclk)) {
305 dev_err(&pdev->dev, "Can't retrieve rk_spdif bus clock\n");
306 return PTR_ERR(spdif->hclk);
307 }
308 ret = clk_prepare_enable(spdif->hclk);
309 if (ret) {
310 dev_err(spdif->dev, "hclock enable failed %d\n", ret);
311 return ret;
312 }
313
314 spdif->mclk = devm_clk_get(&pdev->dev, "mclk");
315 if (IS_ERR(spdif->mclk)) {
316 dev_err(&pdev->dev, "Can't retrieve rk_spdif master clock\n");
317 return PTR_ERR(spdif->mclk);
318 }
319
320 ret = clk_prepare_enable(spdif->mclk);
321 if (ret) {
322 dev_err(spdif->dev, "clock enable failed %d\n", ret);
323 return ret;
324 }
325
326 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
327 regs = devm_ioremap_resource(&pdev->dev, res);
328 if (IS_ERR(regs))
329 return PTR_ERR(regs);
330
331 spdif->regmap = devm_regmap_init_mmio_clk(&pdev->dev, "hclk", regs,
332 &rk_spdif_regmap_config);
333 if (IS_ERR(spdif->regmap)) {
334 dev_err(&pdev->dev,
335 "Failed to initialise managed register map\n");
336 return PTR_ERR(spdif->regmap);
337 }
338
339 spdif->playback_dma_data.addr = res->start + SPDIF_SMPDR;
340 spdif->playback_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
341 spdif->playback_dma_data.maxburst = 4;
342
343 spdif->dev = &pdev->dev;
344 dev_set_drvdata(&pdev->dev, spdif);
345
346 pm_runtime_set_active(&pdev->dev);
347 pm_runtime_enable(&pdev->dev);
348 pm_request_idle(&pdev->dev);
349
350 ret = devm_snd_soc_register_component(&pdev->dev,
351 &rk_spdif_component,
352 &rk_spdif_dai, 1);
353 if (ret) {
354 dev_err(&pdev->dev, "Could not register DAI\n");
355 goto err_pm_runtime;
356 }
357
358 ret = devm_snd_dmaengine_pcm_register(&pdev->dev, NULL, 0);
359 if (ret) {
360 dev_err(&pdev->dev, "Could not register PCM\n");
361 goto err_pm_runtime;
362 }
363
364 return 0;
365
366err_pm_runtime:
367 pm_runtime_disable(&pdev->dev);
368
369 return ret;
370}
371
372static int rk_spdif_remove(struct platform_device *pdev)
373{
374 struct rk_spdif_dev *spdif = dev_get_drvdata(&pdev->dev);
375
376 pm_runtime_disable(&pdev->dev);
377 if (!pm_runtime_status_suspended(&pdev->dev))
378 rk_spdif_runtime_suspend(&pdev->dev);
379
380 clk_disable_unprepare(spdif->mclk);
381 clk_disable_unprepare(spdif->hclk);
382
383 return 0;
384}
385
386static const struct dev_pm_ops rk_spdif_pm_ops = {
387 SET_RUNTIME_PM_OPS(rk_spdif_runtime_suspend, rk_spdif_runtime_resume,
388 NULL)
389};
390
391static struct platform_driver rk_spdif_driver = {
392 .probe = rk_spdif_probe,
393 .remove = rk_spdif_remove,
394 .driver = {
395 .name = "rockchip-spdif",
396 .of_match_table = of_match_ptr(rk_spdif_match),
397 .pm = &rk_spdif_pm_ops,
398 },
399};
400module_platform_driver(rk_spdif_driver);
401
402MODULE_ALIAS("platform:rockchip-spdif");
403MODULE_DESCRIPTION("ROCKCHIP SPDIF transceiver Interface");
404MODULE_AUTHOR("Sjoerd Simons <sjoerd.simons@collabora.co.uk>");
405MODULE_LICENSE("GPL v2");
diff --git a/sound/soc/rockchip/rockchip_spdif.h b/sound/soc/rockchip/rockchip_spdif.h
new file mode 100644
index 000000000000..07f86a21046a
--- /dev/null
+++ b/sound/soc/rockchip/rockchip_spdif.h
@@ -0,0 +1,63 @@
1/*
2 * ALSA SoC Audio Layer - Rockchip SPDIF transceiver driver
3 *
4 * Copyright (c) 2015 Collabora Ltd.
5 * Author: Sjoerd Simons <sjoerd.simons@collabora.co.uk>
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 _ROCKCHIP_SPDIF_H
13#define _ROCKCHIP_SPDIF_H
14
15/*
16 * CFGR
17 * transfer configuration register
18*/
19#define SPDIF_CFGR_CLK_DIV_SHIFT (16)
20#define SPDIF_CFGR_CLK_DIV_MASK (0xff << SPDIF_CFGR_CLK_DIV_SHIFT)
21#define SPDIF_CFGR_CLK_DIV(x) (x << SPDIF_CFGR_CLK_DIV_SHIFT)
22
23#define SPDIF_CFGR_HALFWORD_SHIFT 2
24#define SPDIF_CFGR_HALFWORD_DISABLE (0 << SPDIF_CFGR_HALFWORD_SHIFT)
25#define SPDIF_CFGR_HALFWORD_ENABLE (1 << SPDIF_CFGR_HALFWORD_SHIFT)
26
27#define SPDIF_CFGR_VDW_SHIFT 0
28#define SPDIF_CFGR_VDW(x) (x << SPDIF_CFGR_VDW_SHIFT)
29#define SDPIF_CFGR_VDW_MASK (0xf << SPDIF_CFGR_VDW_SHIFT)
30
31#define SPDIF_CFGR_VDW_16 SPDIF_CFGR_VDW(0x00)
32#define SPDIF_CFGR_VDW_20 SPDIF_CFGR_VDW(0x01)
33#define SPDIF_CFGR_VDW_24 SPDIF_CFGR_VDW(0x10)
34
35/*
36 * DMACR
37 * DMA control register
38*/
39#define SPDIF_DMACR_TDE_SHIFT 5
40#define SPDIF_DMACR_TDE_DISABLE (0 << SPDIF_DMACR_TDE_SHIFT)
41#define SPDIF_DMACR_TDE_ENABLE (1 << SPDIF_DMACR_TDE_SHIFT)
42
43#define SPDIF_DMACR_TDL_SHIFT 0
44#define SPDIF_DMACR_TDL(x) ((x) << SPDIF_DMACR_TDL_SHIFT)
45#define SPDIF_DMACR_TDL_MASK (0x1f << SDPIF_DMACR_TDL_SHIFT)
46
47/*
48 * XFER
49 * Transfer control register
50*/
51#define SPDIF_XFER_TXS_SHIFT 0
52#define SPDIF_XFER_TXS_STOP (0 << SPDIF_XFER_TXS_SHIFT)
53#define SPDIF_XFER_TXS_START (1 << SPDIF_XFER_TXS_SHIFT)
54
55#define SPDIF_CFGR (0x0000)
56#define SPDIF_SDBLR (0x0004)
57#define SPDIF_DMACR (0x0008)
58#define SPDIF_INTCR (0x000c)
59#define SPDIF_INTSR (0x0010)
60#define SPDIF_XFER (0x0018)
61#define SPDIF_SMPDR (0x0020)
62
63#endif /* _ROCKCHIP_SPDIF_H */
diff --git a/sound/soc/samsung/h1940_uda1380.c b/sound/soc/samsung/h1940_uda1380.c
index c72e9fb26658..5f5825faeb2a 100644
--- a/sound/soc/samsung/h1940_uda1380.c
+++ b/sound/soc/samsung/h1940_uda1380.c
@@ -26,16 +26,15 @@
26#include <mach/gpio-samsung.h> 26#include <mach/gpio-samsung.h>
27#include "s3c24xx-i2s.h" 27#include "s3c24xx-i2s.h"
28 28
29static unsigned int rates[] = { 29static const unsigned int rates[] = {
30 11025, 30 11025,
31 22050, 31 22050,
32 44100, 32 44100,
33}; 33};
34 34
35static struct snd_pcm_hw_constraint_list hw_rates = { 35static const struct snd_pcm_hw_constraint_list hw_rates = {
36 .count = ARRAY_SIZE(rates), 36 .count = ARRAY_SIZE(rates),
37 .list = rates, 37 .list = rates,
38 .mask = 0,
39}; 38};
40 39
41static struct snd_soc_jack hp_jack; 40static struct snd_soc_jack hp_jack;
diff --git a/sound/soc/samsung/rx1950_uda1380.c b/sound/soc/samsung/rx1950_uda1380.c
index 35e37c457f1f..fa096abe9e75 100644
--- a/sound/soc/samsung/rx1950_uda1380.c
+++ b/sound/soc/samsung/rx1950_uda1380.c
@@ -38,16 +38,15 @@ static int rx1950_hw_params(struct snd_pcm_substream *substream,
38static int rx1950_spk_power(struct snd_soc_dapm_widget *w, 38static int rx1950_spk_power(struct snd_soc_dapm_widget *w,
39 struct snd_kcontrol *kcontrol, int event); 39 struct snd_kcontrol *kcontrol, int event);
40 40
41static unsigned int rates[] = { 41static const unsigned int rates[] = {
42 16000, 42 16000,
43 44100, 43 44100,
44 48000, 44 48000,
45}; 45};
46 46
47static struct snd_pcm_hw_constraint_list hw_rates = { 47static const struct snd_pcm_hw_constraint_list hw_rates = {
48 .count = ARRAY_SIZE(rates), 48 .count = ARRAY_SIZE(rates),
49 .list = rates, 49 .list = rates,
50 .mask = 0,
51}; 50};
52 51
53static struct snd_soc_jack hp_jack; 52static struct snd_soc_jack hp_jack;
diff --git a/sound/soc/sh/Kconfig b/sound/soc/sh/Kconfig
index 07114b0b0dc1..206d1edab07c 100644
--- a/sound/soc/sh/Kconfig
+++ b/sound/soc/sh/Kconfig
@@ -37,10 +37,11 @@ config SND_SOC_SH4_SIU
37config SND_SOC_RCAR 37config SND_SOC_RCAR
38 tristate "R-Car series SRU/SCU/SSIU/SSI support" 38 tristate "R-Car series SRU/SCU/SSIU/SSI support"
39 depends on DMA_OF 39 depends on DMA_OF
40 depends on COMMON_CLK
40 select SND_SIMPLE_CARD 41 select SND_SIMPLE_CARD
41 select REGMAP_MMIO 42 select REGMAP_MMIO
42 help 43 help
43 This option enables R-Car SUR/SCU/SSIU/SSI sound support 44 This option enables R-Car SRU/SCU/SSIU/SSI sound support
44 45
45config SND_SOC_RSRC_CARD 46config SND_SOC_RSRC_CARD
46 tristate "Renesas Sampling Rate Convert Sound Card" 47 tristate "Renesas Sampling Rate Convert Sound Card"
diff --git a/sound/soc/sh/rcar/adg.c b/sound/soc/sh/rcar/adg.c
index fefc881dbac2..2a5b3a293cd2 100644
--- a/sound/soc/sh/rcar/adg.c
+++ b/sound/soc/sh/rcar/adg.c
@@ -7,7 +7,7 @@
7 * License. See the file "COPYING" in the main directory of this archive 7 * License. See the file "COPYING" in the main directory of this archive
8 * for more details. 8 * for more details.
9 */ 9 */
10#include <linux/sh_clk.h> 10#include <linux/clk-provider.h>
11#include "rsnd.h" 11#include "rsnd.h"
12 12
13#define CLKA 0 13#define CLKA 0
@@ -16,12 +16,26 @@
16#define CLKI 3 16#define CLKI 3
17#define CLKMAX 4 17#define CLKMAX 4
18 18
19#define CLKOUT 0
20#define CLKOUT1 1
21#define CLKOUT2 2
22#define CLKOUT3 3
23#define CLKOUTMAX 4
24
25#define BRRx_MASK(x) (0x3FF & x)
26
27static struct rsnd_mod_ops adg_ops = {
28 .name = "adg",
29};
30
19struct rsnd_adg { 31struct rsnd_adg {
20 struct clk *clk[CLKMAX]; 32 struct clk *clk[CLKMAX];
33 struct clk *clkout[CLKOUTMAX];
34 struct clk_onecell_data onecell;
35 struct rsnd_mod mod;
21 36
22 int rbga_rate_for_441khz_div_6; /* RBGA */ 37 int rbga_rate_for_441khz; /* RBGA */
23 int rbgb_rate_for_48khz_div_6; /* RBGB */ 38 int rbgb_rate_for_48khz; /* RBGB */
24 u32 ckr;
25}; 39};
26 40
27#define for_each_rsnd_clk(pos, adg, i) \ 41#define for_each_rsnd_clk(pos, adg, i) \
@@ -29,17 +43,36 @@ struct rsnd_adg {
29 (i < CLKMAX) && \ 43 (i < CLKMAX) && \
30 ((pos) = adg->clk[i]); \ 44 ((pos) = adg->clk[i]); \
31 i++) 45 i++)
46#define for_each_rsnd_clkout(pos, adg, i) \
47 for (i = 0; \
48 (i < CLKOUTMAX) && \
49 ((pos) = adg->clkout[i]); \
50 i++)
32#define rsnd_priv_to_adg(priv) ((struct rsnd_adg *)(priv)->adg) 51#define rsnd_priv_to_adg(priv) ((struct rsnd_adg *)(priv)->adg)
33 52
53static u32 rsnd_adg_calculate_rbgx(unsigned long div)
54{
55 int i, ratio;
56
57 if (!div)
58 return 0;
59
60 for (i = 3; i >= 0; i--) {
61 ratio = 2 << (i * 2);
62 if (0 == (div % ratio))
63 return (u32)((i << 8) | ((div / ratio) - 1));
64 }
65
66 return ~0;
67}
34 68
35static u32 rsnd_adg_ssi_ws_timing_gen2(struct rsnd_dai_stream *io) 69static u32 rsnd_adg_ssi_ws_timing_gen2(struct rsnd_dai_stream *io)
36{ 70{
37 struct rsnd_mod *mod = rsnd_io_to_mod_ssi(io); 71 struct rsnd_mod *mod = rsnd_io_to_mod_ssi(io);
38 struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
39 int id = rsnd_mod_id(mod); 72 int id = rsnd_mod_id(mod);
40 int ws = id; 73 int ws = id;
41 74
42 if (rsnd_ssi_is_pin_sharing(rsnd_ssi_mod_get(priv, id))) { 75 if (rsnd_ssi_is_pin_sharing(io)) {
43 switch (id) { 76 switch (id) {
44 case 1: 77 case 1:
45 case 2: 78 case 2:
@@ -60,6 +93,9 @@ static u32 rsnd_adg_ssi_ws_timing_gen2(struct rsnd_dai_stream *io)
60int rsnd_adg_set_cmd_timsel_gen2(struct rsnd_mod *mod, 93int rsnd_adg_set_cmd_timsel_gen2(struct rsnd_mod *mod,
61 struct rsnd_dai_stream *io) 94 struct rsnd_dai_stream *io)
62{ 95{
96 struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
97 struct rsnd_adg *adg = rsnd_priv_to_adg(priv);
98 struct rsnd_mod *adg_mod = rsnd_mod_get(adg);
63 int id = rsnd_mod_id(mod); 99 int id = rsnd_mod_id(mod);
64 int shift = (id % 2) ? 16 : 0; 100 int shift = (id % 2) ? 16 : 0;
65 u32 mask, val; 101 u32 mask, val;
@@ -69,21 +105,26 @@ int rsnd_adg_set_cmd_timsel_gen2(struct rsnd_mod *mod,
69 val = val << shift; 105 val = val << shift;
70 mask = 0xffff << shift; 106 mask = 0xffff << shift;
71 107
72 rsnd_mod_bset(mod, CMDOUT_TIMSEL, mask, val); 108 rsnd_mod_bset(adg_mod, CMDOUT_TIMSEL, mask, val);
73 109
74 return 0; 110 return 0;
75} 111}
76 112
77static int rsnd_adg_set_src_timsel_gen2(struct rsnd_mod *mod, 113static int rsnd_adg_set_src_timsel_gen2(struct rsnd_mod *src_mod,
78 struct rsnd_dai_stream *io, 114 struct rsnd_dai_stream *io,
79 u32 timsel) 115 u32 timsel)
80{ 116{
117 struct rsnd_priv *priv = rsnd_mod_to_priv(src_mod);
118 struct rsnd_adg *adg = rsnd_priv_to_adg(priv);
119 struct rsnd_mod *adg_mod = rsnd_mod_get(adg);
81 int is_play = rsnd_io_is_play(io); 120 int is_play = rsnd_io_is_play(io);
82 int id = rsnd_mod_id(mod); 121 int id = rsnd_mod_id(src_mod);
83 int shift = (id % 2) ? 16 : 0; 122 int shift = (id % 2) ? 16 : 0;
84 u32 mask, ws; 123 u32 mask, ws;
85 u32 in, out; 124 u32 in, out;
86 125
126 rsnd_mod_confirm_src(src_mod);
127
87 ws = rsnd_adg_ssi_ws_timing_gen2(io); 128 ws = rsnd_adg_ssi_ws_timing_gen2(io);
88 129
89 in = (is_play) ? timsel : ws; 130 in = (is_play) ? timsel : ws;
@@ -95,37 +136,38 @@ static int rsnd_adg_set_src_timsel_gen2(struct rsnd_mod *mod,
95 136
96 switch (id / 2) { 137 switch (id / 2) {
97 case 0: 138 case 0:
98 rsnd_mod_bset(mod, SRCIN_TIMSEL0, mask, in); 139 rsnd_mod_bset(adg_mod, SRCIN_TIMSEL0, mask, in);
99 rsnd_mod_bset(mod, SRCOUT_TIMSEL0, mask, out); 140 rsnd_mod_bset(adg_mod, SRCOUT_TIMSEL0, mask, out);
100 break; 141 break;
101 case 1: 142 case 1:
102 rsnd_mod_bset(mod, SRCIN_TIMSEL1, mask, in); 143 rsnd_mod_bset(adg_mod, SRCIN_TIMSEL1, mask, in);
103 rsnd_mod_bset(mod, SRCOUT_TIMSEL1, mask, out); 144 rsnd_mod_bset(adg_mod, SRCOUT_TIMSEL1, mask, out);
104 break; 145 break;
105 case 2: 146 case 2:
106 rsnd_mod_bset(mod, SRCIN_TIMSEL2, mask, in); 147 rsnd_mod_bset(adg_mod, SRCIN_TIMSEL2, mask, in);
107 rsnd_mod_bset(mod, SRCOUT_TIMSEL2, mask, out); 148 rsnd_mod_bset(adg_mod, SRCOUT_TIMSEL2, mask, out);
108 break; 149 break;
109 case 3: 150 case 3:
110 rsnd_mod_bset(mod, SRCIN_TIMSEL3, mask, in); 151 rsnd_mod_bset(adg_mod, SRCIN_TIMSEL3, mask, in);
111 rsnd_mod_bset(mod, SRCOUT_TIMSEL3, mask, out); 152 rsnd_mod_bset(adg_mod, SRCOUT_TIMSEL3, mask, out);
112 break; 153 break;
113 case 4: 154 case 4:
114 rsnd_mod_bset(mod, SRCIN_TIMSEL4, mask, in); 155 rsnd_mod_bset(adg_mod, SRCIN_TIMSEL4, mask, in);
115 rsnd_mod_bset(mod, SRCOUT_TIMSEL4, mask, out); 156 rsnd_mod_bset(adg_mod, SRCOUT_TIMSEL4, mask, out);
116 break; 157 break;
117 } 158 }
118 159
119 return 0; 160 return 0;
120} 161}
121 162
122int rsnd_adg_set_convert_clk_gen2(struct rsnd_mod *mod, 163int rsnd_adg_set_convert_clk_gen2(struct rsnd_mod *src_mod,
123 struct rsnd_dai_stream *io, 164 struct rsnd_dai_stream *io,
124 unsigned int src_rate, 165 unsigned int src_rate,
125 unsigned int dst_rate) 166 unsigned int dst_rate)
126{ 167{
127 struct rsnd_priv *priv = rsnd_mod_to_priv(mod); 168 struct rsnd_priv *priv = rsnd_mod_to_priv(src_mod);
128 struct rsnd_adg *adg = rsnd_priv_to_adg(priv); 169 struct rsnd_adg *adg = rsnd_priv_to_adg(priv);
170 struct rsnd_mod *adg_mod = rsnd_mod_get(adg);
129 struct device *dev = rsnd_priv_to_dev(priv); 171 struct device *dev = rsnd_priv_to_dev(priv);
130 int idx, sel, div, step, ret; 172 int idx, sel, div, step, ret;
131 u32 val, en; 173 u32 val, en;
@@ -134,10 +176,12 @@ int rsnd_adg_set_convert_clk_gen2(struct rsnd_mod *mod,
134 clk_get_rate(adg->clk[CLKA]), /* 0000: CLKA */ 176 clk_get_rate(adg->clk[CLKA]), /* 0000: CLKA */
135 clk_get_rate(adg->clk[CLKB]), /* 0001: CLKB */ 177 clk_get_rate(adg->clk[CLKB]), /* 0001: CLKB */
136 clk_get_rate(adg->clk[CLKC]), /* 0010: CLKC */ 178 clk_get_rate(adg->clk[CLKC]), /* 0010: CLKC */
137 adg->rbga_rate_for_441khz_div_6,/* 0011: RBGA */ 179 adg->rbga_rate_for_441khz, /* 0011: RBGA */
138 adg->rbgb_rate_for_48khz_div_6, /* 0100: RBGB */ 180 adg->rbgb_rate_for_48khz, /* 0100: RBGB */
139 }; 181 };
140 182
183 rsnd_mod_confirm_src(src_mod);
184
141 min = ~0; 185 min = ~0;
142 val = 0; 186 val = 0;
143 en = 0; 187 en = 0;
@@ -175,25 +219,27 @@ int rsnd_adg_set_convert_clk_gen2(struct rsnd_mod *mod,
175 return -EIO; 219 return -EIO;
176 } 220 }
177 221
178 ret = rsnd_adg_set_src_timsel_gen2(mod, io, val); 222 ret = rsnd_adg_set_src_timsel_gen2(src_mod, io, val);
179 if (ret < 0) { 223 if (ret < 0) {
180 dev_err(dev, "timsel error\n"); 224 dev_err(dev, "timsel error\n");
181 return ret; 225 return ret;
182 } 226 }
183 227
184 rsnd_mod_bset(mod, DIV_EN, en, en); 228 rsnd_mod_bset(adg_mod, DIV_EN, en, en);
185 229
186 dev_dbg(dev, "convert rate %d <-> %d\n", src_rate, dst_rate); 230 dev_dbg(dev, "convert rate %d <-> %d\n", src_rate, dst_rate);
187 231
188 return 0; 232 return 0;
189} 233}
190 234
191int rsnd_adg_set_convert_timing_gen2(struct rsnd_mod *mod, 235int rsnd_adg_set_convert_timing_gen2(struct rsnd_mod *src_mod,
192 struct rsnd_dai_stream *io) 236 struct rsnd_dai_stream *io)
193{ 237{
194 u32 val = rsnd_adg_ssi_ws_timing_gen2(io); 238 u32 val = rsnd_adg_ssi_ws_timing_gen2(io);
195 239
196 return rsnd_adg_set_src_timsel_gen2(mod, io, val); 240 rsnd_mod_confirm_src(src_mod);
241
242 return rsnd_adg_set_src_timsel_gen2(src_mod, io, val);
197} 243}
198 244
199int rsnd_adg_set_convert_clk_gen1(struct rsnd_priv *priv, 245int rsnd_adg_set_convert_clk_gen1(struct rsnd_priv *priv,
@@ -202,6 +248,7 @@ int rsnd_adg_set_convert_clk_gen1(struct rsnd_priv *priv,
202 unsigned int dst_rate) 248 unsigned int dst_rate)
203{ 249{
204 struct rsnd_adg *adg = rsnd_priv_to_adg(priv); 250 struct rsnd_adg *adg = rsnd_priv_to_adg(priv);
251 struct rsnd_mod *adg_mod = rsnd_mod_get(adg);
205 struct device *dev = rsnd_priv_to_dev(priv); 252 struct device *dev = rsnd_priv_to_dev(priv);
206 int idx, sel, div, shift; 253 int idx, sel, div, shift;
207 u32 mask, val; 254 u32 mask, val;
@@ -211,8 +258,8 @@ int rsnd_adg_set_convert_clk_gen1(struct rsnd_priv *priv,
211 clk_get_rate(adg->clk[CLKB]), /* 001: CLKB */ 258 clk_get_rate(adg->clk[CLKB]), /* 001: CLKB */
212 clk_get_rate(adg->clk[CLKC]), /* 010: CLKC */ 259 clk_get_rate(adg->clk[CLKC]), /* 010: CLKC */
213 0, /* 011: MLBCLK (not used) */ 260 0, /* 011: MLBCLK (not used) */
214 adg->rbga_rate_for_441khz_div_6,/* 100: RBGA */ 261 adg->rbga_rate_for_441khz, /* 100: RBGA */
215 adg->rbgb_rate_for_48khz_div_6, /* 101: RBGB */ 262 adg->rbgb_rate_for_48khz, /* 101: RBGB */
216 }; 263 };
217 264
218 /* find div (= 1/128, 1/256, 1/512, 1/1024, 1/2048 */ 265 /* find div (= 1/128, 1/256, 1/512, 1/1024, 1/2048 */
@@ -238,13 +285,13 @@ find_rate:
238 285
239 switch (id / 4) { 286 switch (id / 4) {
240 case 0: 287 case 0:
241 rsnd_mod_bset(mod, AUDIO_CLK_SEL3, mask, val); 288 rsnd_mod_bset(adg_mod, AUDIO_CLK_SEL3, mask, val);
242 break; 289 break;
243 case 1: 290 case 1:
244 rsnd_mod_bset(mod, AUDIO_CLK_SEL4, mask, val); 291 rsnd_mod_bset(adg_mod, AUDIO_CLK_SEL4, mask, val);
245 break; 292 break;
246 case 2: 293 case 2:
247 rsnd_mod_bset(mod, AUDIO_CLK_SEL5, mask, val); 294 rsnd_mod_bset(adg_mod, AUDIO_CLK_SEL5, mask, val);
248 break; 295 break;
249 } 296 }
250 297
@@ -257,12 +304,17 @@ find_rate:
257 return 0; 304 return 0;
258} 305}
259 306
260static void rsnd_adg_set_ssi_clk(struct rsnd_mod *mod, u32 val) 307static void rsnd_adg_set_ssi_clk(struct rsnd_mod *ssi_mod, u32 val)
261{ 308{
262 int id = rsnd_mod_id(mod); 309 struct rsnd_priv *priv = rsnd_mod_to_priv(ssi_mod);
310 struct rsnd_adg *adg = rsnd_priv_to_adg(priv);
311 struct rsnd_mod *adg_mod = rsnd_mod_get(adg);
312 int id = rsnd_mod_id(ssi_mod);
263 int shift = (id % 4) * 8; 313 int shift = (id % 4) * 8;
264 u32 mask = 0xFF << shift; 314 u32 mask = 0xFF << shift;
265 315
316 rsnd_mod_confirm_ssi(ssi_mod);
317
266 val = val << shift; 318 val = val << shift;
267 319
268 /* 320 /*
@@ -274,13 +326,13 @@ static void rsnd_adg_set_ssi_clk(struct rsnd_mod *mod, u32 val)
274 326
275 switch (id / 4) { 327 switch (id / 4) {
276 case 0: 328 case 0:
277 rsnd_mod_bset(mod, AUDIO_CLK_SEL0, mask, val); 329 rsnd_mod_bset(adg_mod, AUDIO_CLK_SEL0, mask, val);
278 break; 330 break;
279 case 1: 331 case 1:
280 rsnd_mod_bset(mod, AUDIO_CLK_SEL1, mask, val); 332 rsnd_mod_bset(adg_mod, AUDIO_CLK_SEL1, mask, val);
281 break; 333 break;
282 case 2: 334 case 2:
283 rsnd_mod_bset(mod, AUDIO_CLK_SEL2, mask, val); 335 rsnd_mod_bset(adg_mod, AUDIO_CLK_SEL2, mask, val);
284 break; 336 break;
285 } 337 }
286} 338}
@@ -326,14 +378,14 @@ int rsnd_adg_ssi_clk_try_start(struct rsnd_mod *mod, unsigned int rate)
326 } 378 }
327 379
328 /* 380 /*
329 * find 1/6 clock from BRGA/BRGB 381 * find divided clock from BRGA/BRGB
330 */ 382 */
331 if (rate == adg->rbga_rate_for_441khz_div_6) { 383 if (rate == adg->rbga_rate_for_441khz) {
332 data = 0x10; 384 data = 0x10;
333 goto found_clock; 385 goto found_clock;
334 } 386 }
335 387
336 if (rate == adg->rbgb_rate_for_48khz_div_6) { 388 if (rate == adg->rbgb_rate_for_48khz) {
337 data = 0x20; 389 data = 0x20;
338 goto found_clock; 390 goto found_clock;
339 } 391 }
@@ -342,29 +394,60 @@ int rsnd_adg_ssi_clk_try_start(struct rsnd_mod *mod, unsigned int rate)
342 394
343found_clock: 395found_clock:
344 396
345 /* see rsnd_adg_ssi_clk_init() */
346 rsnd_mod_bset(mod, SSICKR, 0x00FF0000, adg->ckr);
347 rsnd_mod_write(mod, BRRA, 0x00000002); /* 1/6 */
348 rsnd_mod_write(mod, BRRB, 0x00000002); /* 1/6 */
349
350 /* 397 /*
351 * This "mod" = "ssi" here. 398 * This "mod" = "ssi" here.
352 * we can get "ssi id" from mod 399 * we can get "ssi id" from mod
353 */ 400 */
354 rsnd_adg_set_ssi_clk(mod, data); 401 rsnd_adg_set_ssi_clk(mod, data);
355 402
356 dev_dbg(dev, "ADG: ssi%d selects clk%d = %d", 403 dev_dbg(dev, "ADG: %s[%d] selects 0x%x for %d\n",
357 rsnd_mod_id(mod), i, rate); 404 rsnd_mod_name(mod), rsnd_mod_id(mod),
405 data, rate);
358 406
359 return 0; 407 return 0;
360} 408}
361 409
362static void rsnd_adg_ssi_clk_init(struct rsnd_priv *priv, struct rsnd_adg *adg) 410static void rsnd_adg_get_clkin(struct rsnd_priv *priv,
411 struct rsnd_adg *adg)
412{
413 struct device *dev = rsnd_priv_to_dev(priv);
414 struct clk *clk;
415 static const char * const clk_name[] = {
416 [CLKA] = "clk_a",
417 [CLKB] = "clk_b",
418 [CLKC] = "clk_c",
419 [CLKI] = "clk_i",
420 };
421 int i;
422
423 for (i = 0; i < CLKMAX; i++) {
424 clk = devm_clk_get(dev, clk_name[i]);
425 adg->clk[i] = IS_ERR(clk) ? NULL : clk;
426 }
427
428 for_each_rsnd_clk(clk, adg, i)
429 dev_dbg(dev, "clk %d : %p : %ld\n", i, clk, clk_get_rate(clk));
430}
431
432static void rsnd_adg_get_clkout(struct rsnd_priv *priv,
433 struct rsnd_adg *adg)
363{ 434{
364 struct clk *clk; 435 struct clk *clk;
365 unsigned long rate; 436 struct rsnd_mod *adg_mod = rsnd_mod_get(adg);
366 u32 ckr; 437 struct device *dev = rsnd_priv_to_dev(priv);
438 struct device_node *np = dev->of_node;
439 u32 ckr, rbgx, rbga, rbgb;
440 u32 rate, req_rate, div;
441 uint32_t count = 0;
442 unsigned long req_48kHz_rate, req_441kHz_rate;
367 int i; 443 int i;
444 const char *parent_clk_name = NULL;
445 static const char * const clkout_name[] = {
446 [CLKOUT] = "audio_clkout",
447 [CLKOUT1] = "audio_clkout1",
448 [CLKOUT2] = "audio_clkout2",
449 [CLKOUT3] = "audio_clkout3",
450 };
368 int brg_table[] = { 451 int brg_table[] = {
369 [CLKA] = 0x0, 452 [CLKA] = 0x0,
370 [CLKB] = 0x1, 453 [CLKB] = 0x1,
@@ -372,19 +455,34 @@ static void rsnd_adg_ssi_clk_init(struct rsnd_priv *priv, struct rsnd_adg *adg)
372 [CLKI] = 0x2, 455 [CLKI] = 0x2,
373 }; 456 };
374 457
458 of_property_read_u32(np, "#clock-cells", &count);
459
460 /*
461 * ADG supports BRRA/BRRB output only
462 * this means all clkout0/1/2/3 will be same rate
463 */
464 of_property_read_u32(np, "clock-frequency", &req_rate);
465 req_48kHz_rate = 0;
466 req_441kHz_rate = 0;
467 if (0 == (req_rate % 44100))
468 req_441kHz_rate = req_rate;
469 if (0 == (req_rate % 48000))
470 req_48kHz_rate = req_rate;
471
375 /* 472 /*
376 * This driver is assuming that AUDIO_CLKA/AUDIO_CLKB/AUDIO_CLKC 473 * This driver is assuming that AUDIO_CLKA/AUDIO_CLKB/AUDIO_CLKC
377 * have 44.1kHz or 48kHz base clocks for now. 474 * have 44.1kHz or 48kHz base clocks for now.
378 * 475 *
379 * SSI itself can divide parent clock by 1/1 - 1/16 476 * SSI itself can divide parent clock by 1/1 - 1/16
380 * So, BRGA outputs 44.1kHz base parent clock 1/32,
381 * and, BRGB outputs 48.0kHz base parent clock 1/32 here.
382 * see 477 * see
383 * rsnd_adg_ssi_clk_try_start() 478 * rsnd_adg_ssi_clk_try_start()
479 * rsnd_ssi_master_clk_start()
384 */ 480 */
385 ckr = 0; 481 ckr = 0;
386 adg->rbga_rate_for_441khz_div_6 = 0; 482 rbga = 2; /* default 1/6 */
387 adg->rbgb_rate_for_48khz_div_6 = 0; 483 rbgb = 2; /* default 1/6 */
484 adg->rbga_rate_for_441khz = 0;
485 adg->rbgb_rate_for_48khz = 0;
388 for_each_rsnd_clk(clk, adg, i) { 486 for_each_rsnd_clk(clk, adg, i) {
389 rate = clk_get_rate(clk); 487 rate = clk_get_rate(clk);
390 488
@@ -392,19 +490,86 @@ static void rsnd_adg_ssi_clk_init(struct rsnd_priv *priv, struct rsnd_adg *adg)
392 continue; 490 continue;
393 491
394 /* RBGA */ 492 /* RBGA */
395 if (!adg->rbga_rate_for_441khz_div_6 && (0 == rate % 44100)) { 493 if (!adg->rbga_rate_for_441khz && (0 == rate % 44100)) {
396 adg->rbga_rate_for_441khz_div_6 = rate / 6; 494 div = 6;
397 ckr |= brg_table[i] << 20; 495 if (req_441kHz_rate)
496 div = rate / req_441kHz_rate;
497 rbgx = rsnd_adg_calculate_rbgx(div);
498 if (BRRx_MASK(rbgx) == rbgx) {
499 rbga = rbgx;
500 adg->rbga_rate_for_441khz = rate / div;
501 ckr |= brg_table[i] << 20;
502 if (req_441kHz_rate)
503 parent_clk_name = __clk_get_name(clk);
504 }
398 } 505 }
399 506
400 /* RBGB */ 507 /* RBGB */
401 if (!adg->rbgb_rate_for_48khz_div_6 && (0 == rate % 48000)) { 508 if (!adg->rbgb_rate_for_48khz && (0 == rate % 48000)) {
402 adg->rbgb_rate_for_48khz_div_6 = rate / 6; 509 div = 6;
403 ckr |= brg_table[i] << 16; 510 if (req_48kHz_rate)
511 div = rate / req_48kHz_rate;
512 rbgx = rsnd_adg_calculate_rbgx(div);
513 if (BRRx_MASK(rbgx) == rbgx) {
514 rbgb = rbgx;
515 adg->rbgb_rate_for_48khz = rate / div;
516 ckr |= brg_table[i] << 16;
517 if (req_48kHz_rate) {
518 parent_clk_name = __clk_get_name(clk);
519 ckr |= 0x80000000;
520 }
521 }
404 } 522 }
405 } 523 }
406 524
407 adg->ckr = ckr; 525 /*
526 * ADG supports BRRA/BRRB output only.
527 * this means all clkout0/1/2/3 will be * same rate
528 */
529
530 /*
531 * for clkout
532 */
533 if (!count) {
534 clk = clk_register_fixed_rate(dev, clkout_name[CLKOUT],
535 parent_clk_name,
536 (parent_clk_name) ?
537 0 : CLK_IS_ROOT, req_rate);
538 if (!IS_ERR(clk)) {
539 adg->clkout[CLKOUT] = clk;
540 of_clk_add_provider(np, of_clk_src_simple_get, clk);
541 }
542 }
543 /*
544 * for clkout0/1/2/3
545 */
546 else {
547 for (i = 0; i < CLKOUTMAX; i++) {
548 clk = clk_register_fixed_rate(dev, clkout_name[i],
549 parent_clk_name,
550 (parent_clk_name) ?
551 0 : CLK_IS_ROOT,
552 req_rate);
553 if (!IS_ERR(clk)) {
554 adg->onecell.clks = adg->clkout;
555 adg->onecell.clk_num = CLKOUTMAX;
556
557 adg->clkout[i] = clk;
558
559 of_clk_add_provider(np, of_clk_src_onecell_get,
560 &adg->onecell);
561 }
562 }
563 }
564
565 rsnd_mod_bset(adg_mod, SSICKR, 0x00FF0000, ckr);
566 rsnd_mod_write(adg_mod, BRRA, rbga);
567 rsnd_mod_write(adg_mod, BRRB, rbgb);
568
569 for_each_rsnd_clkout(clk, adg, i)
570 dev_dbg(dev, "clkout %d : %p : %ld\n", i, clk, clk_get_rate(clk));
571 dev_dbg(dev, "SSICKR = 0x%08x, BRRA/BRRB = 0x%x/0x%x\n",
572 ckr, rbga, rbgb);
408} 573}
409 574
410int rsnd_adg_probe(struct platform_device *pdev, 575int rsnd_adg_probe(struct platform_device *pdev,
@@ -413,8 +578,6 @@ int rsnd_adg_probe(struct platform_device *pdev,
413{ 578{
414 struct rsnd_adg *adg; 579 struct rsnd_adg *adg;
415 struct device *dev = rsnd_priv_to_dev(priv); 580 struct device *dev = rsnd_priv_to_dev(priv);
416 struct clk *clk;
417 int i;
418 581
419 adg = devm_kzalloc(dev, sizeof(*adg), GFP_KERNEL); 582 adg = devm_kzalloc(dev, sizeof(*adg), GFP_KERNEL);
420 if (!adg) { 583 if (!adg) {
@@ -422,15 +585,16 @@ int rsnd_adg_probe(struct platform_device *pdev,
422 return -ENOMEM; 585 return -ENOMEM;
423 } 586 }
424 587
425 adg->clk[CLKA] = devm_clk_get(dev, "clk_a"); 588 /*
426 adg->clk[CLKB] = devm_clk_get(dev, "clk_b"); 589 * ADG is special module.
427 adg->clk[CLKC] = devm_clk_get(dev, "clk_c"); 590 * Use ADG mod without rsnd_mod_init() to make debug easy
428 adg->clk[CLKI] = devm_clk_get(dev, "clk_i"); 591 * for rsnd_write/rsnd_read
429 592 */
430 for_each_rsnd_clk(clk, adg, i) 593 adg->mod.ops = &adg_ops;
431 dev_dbg(dev, "clk %d : %p : %ld\n", i, clk, clk_get_rate(clk)); 594 adg->mod.priv = priv;
432 595
433 rsnd_adg_ssi_clk_init(priv, adg); 596 rsnd_adg_get_clkin(priv, adg);
597 rsnd_adg_get_clkout(priv, adg);
434 598
435 priv->adg = adg; 599 priv->adg = adg;
436 600
diff --git a/sound/soc/sh/rcar/core.c b/sound/soc/sh/rcar/core.c
index f3feed5ce9b6..deed48ef28b8 100644
--- a/sound/soc/sh/rcar/core.c
+++ b/sound/soc/sh/rcar/core.c
@@ -110,6 +110,7 @@ static const struct rsnd_of_data rsnd_of_data_gen2 = {
110static const struct of_device_id rsnd_of_match[] = { 110static const struct of_device_id rsnd_of_match[] = {
111 { .compatible = "renesas,rcar_sound-gen1", .data = &rsnd_of_data_gen1 }, 111 { .compatible = "renesas,rcar_sound-gen1", .data = &rsnd_of_data_gen1 },
112 { .compatible = "renesas,rcar_sound-gen2", .data = &rsnd_of_data_gen2 }, 112 { .compatible = "renesas,rcar_sound-gen2", .data = &rsnd_of_data_gen2 },
113 { .compatible = "renesas,rcar_sound-gen3", .data = &rsnd_of_data_gen2 }, /* gen2 compatible */
113 {}, 114 {},
114}; 115};
115MODULE_DEVICE_TABLE(of, rsnd_of_match); 116MODULE_DEVICE_TABLE(of, rsnd_of_match);
@@ -126,6 +127,17 @@ MODULE_DEVICE_TABLE(of, rsnd_of_match);
126#define rsnd_info_id(priv, io, name) \ 127#define rsnd_info_id(priv, io, name) \
127 ((io)->info->name - priv->info->name##_info) 128 ((io)->info->name - priv->info->name##_info)
128 129
130void rsnd_mod_make_sure(struct rsnd_mod *mod, enum rsnd_mod_type type)
131{
132 if (mod->type != type) {
133 struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
134 struct device *dev = rsnd_priv_to_dev(priv);
135
136 dev_warn(dev, "%s[%d] is not your expected module\n",
137 rsnd_mod_name(mod), rsnd_mod_id(mod));
138 }
139}
140
129/* 141/*
130 * rsnd_mod functions 142 * rsnd_mod functions
131 */ 143 */
@@ -288,7 +300,7 @@ u32 rsnd_get_dalign(struct rsnd_mod *mod, struct rsnd_dai_stream *io)
288/* 300/*
289 * rsnd_dai functions 301 * rsnd_dai functions
290 */ 302 */
291#define __rsnd_mod_call(mod, io, func, param...) \ 303#define rsnd_mod_call(mod, io, func, param...) \
292({ \ 304({ \
293 struct rsnd_priv *priv = rsnd_mod_to_priv(mod); \ 305 struct rsnd_priv *priv = rsnd_mod_to_priv(mod); \
294 struct device *dev = rsnd_priv_to_dev(priv); \ 306 struct device *dev = rsnd_priv_to_dev(priv); \
@@ -296,24 +308,17 @@ u32 rsnd_get_dalign(struct rsnd_mod *mod, struct rsnd_dai_stream *io)
296 u8 val = (mod->status >> __rsnd_mod_shift_##func) & 0xF; \ 308 u8 val = (mod->status >> __rsnd_mod_shift_##func) & 0xF; \
297 u8 add = ((val + __rsnd_mod_add_##func) & 0xF); \ 309 u8 add = ((val + __rsnd_mod_add_##func) & 0xF); \
298 int ret = 0; \ 310 int ret = 0; \
299 int called = 0; \ 311 int call = (val == __rsnd_mod_call_##func) && (mod)->ops->func; \
300 if (val == __rsnd_mod_call_##func) { \
301 called = 1; \
302 ret = (mod)->ops->func(mod, io, param); \
303 } \
304 mod->status = (mod->status & ~mask) + \ 312 mod->status = (mod->status & ~mask) + \
305 (add << __rsnd_mod_shift_##func); \ 313 (add << __rsnd_mod_shift_##func); \
306 dev_dbg(dev, "%s[%d] 0x%08x %s\n", \ 314 dev_dbg(dev, "%s[%d]\t0x%08x %s\n", \
307 rsnd_mod_name(mod), rsnd_mod_id(mod), mod->status, \ 315 rsnd_mod_name(mod), rsnd_mod_id(mod), \
308 called ? #func : ""); \ 316 mod->status, call ? #func : ""); \
317 if (call) \
318 ret = (mod)->ops->func(mod, io, param); \
309 ret; \ 319 ret; \
310}) 320})
311 321
312#define rsnd_mod_call(mod, io, func, param...) \
313 (!(mod) ? -ENODEV : \
314 !((mod)->ops->func) ? 0 : \
315 __rsnd_mod_call(mod, io, func, param))
316
317#define rsnd_dai_call(fn, io, param...) \ 322#define rsnd_dai_call(fn, io, param...) \
318({ \ 323({ \
319 struct rsnd_mod *mod; \ 324 struct rsnd_mod *mod; \
@@ -322,9 +327,7 @@ u32 rsnd_get_dalign(struct rsnd_mod *mod, struct rsnd_dai_stream *io)
322 mod = (io)->mod[i]; \ 327 mod = (io)->mod[i]; \
323 if (!mod) \ 328 if (!mod) \
324 continue; \ 329 continue; \
325 ret = rsnd_mod_call(mod, io, fn, param); \ 330 ret |= rsnd_mod_call(mod, io, fn, param); \
326 if (ret < 0) \
327 break; \
328 } \ 331 } \
329 ret; \ 332 ret; \
330}) 333})
@@ -490,16 +493,10 @@ static int rsnd_soc_dai_trigger(struct snd_pcm_substream *substream, int cmd,
490 break; 493 break;
491 case SNDRV_PCM_TRIGGER_STOP: 494 case SNDRV_PCM_TRIGGER_STOP:
492 ret = rsnd_dai_call(stop, io, priv); 495 ret = rsnd_dai_call(stop, io, priv);
493 if (ret < 0)
494 goto dai_trigger_end;
495 496
496 ret = rsnd_dai_call(quit, io, priv); 497 ret |= rsnd_dai_call(quit, io, priv);
497 if (ret < 0)
498 goto dai_trigger_end;
499 498
500 ret = rsnd_platform_call(priv, dai, stop, ssi_id); 499 ret |= rsnd_platform_call(priv, dai, stop, ssi_id);
501 if (ret < 0)
502 goto dai_trigger_end;
503 500
504 rsnd_dai_stream_quit(io); 501 rsnd_dai_stream_quit(io);
505 break; 502 break;
@@ -1224,20 +1221,11 @@ static int rsnd_probe(struct platform_device *pdev)
1224 }; 1221 };
1225 int ret, i; 1222 int ret, i;
1226 1223
1227 info = NULL; 1224 info = devm_kzalloc(&pdev->dev, sizeof(struct rcar_snd_info),
1228 of_data = NULL; 1225 GFP_KERNEL);
1229 if (of_id) { 1226 if (!info)
1230 info = devm_kzalloc(&pdev->dev, 1227 return -ENOMEM;
1231 sizeof(struct rcar_snd_info), GFP_KERNEL); 1228 of_data = of_id->data;
1232 of_data = of_id->data;
1233 } else {
1234 info = pdev->dev.platform_data;
1235 }
1236
1237 if (!info) {
1238 dev_err(dev, "driver needs R-Car sound information\n");
1239 return -ENODEV;
1240 }
1241 1229
1242 /* 1230 /*
1243 * init priv data 1231 * init priv data
diff --git a/sound/soc/sh/rcar/ctu.c b/sound/soc/sh/rcar/ctu.c
index 05498bba5874..3cb214ab848b 100644
--- a/sound/soc/sh/rcar/ctu.c
+++ b/sound/soc/sh/rcar/ctu.c
@@ -35,7 +35,7 @@ static int rsnd_ctu_init(struct rsnd_mod *mod,
35 struct rsnd_dai_stream *io, 35 struct rsnd_dai_stream *io,
36 struct rsnd_priv *priv) 36 struct rsnd_priv *priv)
37{ 37{
38 rsnd_mod_hw_start(mod); 38 rsnd_mod_power_on(mod);
39 39
40 rsnd_ctu_initialize_lock(mod); 40 rsnd_ctu_initialize_lock(mod);
41 41
@@ -50,7 +50,7 @@ static int rsnd_ctu_quit(struct rsnd_mod *mod,
50 struct rsnd_dai_stream *io, 50 struct rsnd_dai_stream *io,
51 struct rsnd_priv *priv) 51 struct rsnd_priv *priv)
52{ 52{
53 rsnd_mod_hw_stop(mod); 53 rsnd_mod_power_off(mod);
54 54
55 return 0; 55 return 0;
56} 56}
@@ -66,7 +66,7 @@ struct rsnd_mod *rsnd_ctu_mod_get(struct rsnd_priv *priv, int id)
66 if (WARN_ON(id < 0 || id >= rsnd_ctu_nr(priv))) 66 if (WARN_ON(id < 0 || id >= rsnd_ctu_nr(priv)))
67 id = 0; 67 id = 0;
68 68
69 return &((struct rsnd_ctu *)(priv->ctu) + id)->mod; 69 return rsnd_mod_get((struct rsnd_ctu *)(priv->ctu) + id);
70} 70}
71 71
72static void rsnd_of_parse_ctu(struct platform_device *pdev, 72static void rsnd_of_parse_ctu(struct platform_device *pdev,
@@ -118,10 +118,8 @@ int rsnd_ctu_probe(struct platform_device *pdev,
118 int i, nr, ret; 118 int i, nr, ret;
119 119
120 /* This driver doesn't support Gen1 at this point */ 120 /* This driver doesn't support Gen1 at this point */
121 if (rsnd_is_gen1(priv)) { 121 if (rsnd_is_gen1(priv))
122 dev_warn(dev, "CTU is not supported on Gen1\n"); 122 return 0;
123 return -EINVAL;
124 }
125 123
126 rsnd_of_parse_ctu(pdev, of_data, priv); 124 rsnd_of_parse_ctu(pdev, of_data, priv);
127 125
@@ -150,7 +148,7 @@ int rsnd_ctu_probe(struct platform_device *pdev,
150 148
151 ctu->info = &info->ctu_info[i]; 149 ctu->info = &info->ctu_info[i];
152 150
153 ret = rsnd_mod_init(priv, &ctu->mod, &rsnd_ctu_ops, 151 ret = rsnd_mod_init(priv, rsnd_mod_get(ctu), &rsnd_ctu_ops,
154 clk, RSND_MOD_CTU, i); 152 clk, RSND_MOD_CTU, i);
155 if (ret) 153 if (ret)
156 return ret; 154 return ret;
@@ -166,6 +164,6 @@ void rsnd_ctu_remove(struct platform_device *pdev,
166 int i; 164 int i;
167 165
168 for_each_rsnd_ctu(ctu, priv, i) { 166 for_each_rsnd_ctu(ctu, priv, i) {
169 rsnd_mod_quit(&ctu->mod); 167 rsnd_mod_quit(rsnd_mod_get(ctu));
170 } 168 }
171} 169}
diff --git a/sound/soc/sh/rcar/dma.c b/sound/soc/sh/rcar/dma.c
index bfbb8a5e93bd..5d084d040961 100644
--- a/sound/soc/sh/rcar/dma.c
+++ b/sound/soc/sh/rcar/dma.c
@@ -470,7 +470,7 @@ rsnd_gen2_dma_addr(struct rsnd_dai_stream *io,
470 dev_err(dev, "DVC is selected without SRC\n"); 470 dev_err(dev, "DVC is selected without SRC\n");
471 471
472 /* use SSIU or SSI ? */ 472 /* use SSIU or SSI ? */
473 if (is_ssi && rsnd_ssi_use_busif(io, mod)) 473 if (is_ssi && rsnd_ssi_use_busif(io))
474 is_ssi++; 474 is_ssi++;
475 475
476 return (is_from) ? 476 return (is_from) ?
diff --git a/sound/soc/sh/rcar/dvc.c b/sound/soc/sh/rcar/dvc.c
index 57796387d482..58f690900e6d 100644
--- a/sound/soc/sh/rcar/dvc.c
+++ b/sound/soc/sh/rcar/dvc.c
@@ -153,7 +153,7 @@ static int rsnd_dvc_init(struct rsnd_mod *mod,
153 struct rsnd_dai_stream *io, 153 struct rsnd_dai_stream *io,
154 struct rsnd_priv *priv) 154 struct rsnd_priv *priv)
155{ 155{
156 rsnd_mod_hw_start(mod); 156 rsnd_mod_power_on(mod);
157 157
158 rsnd_dvc_soft_reset(mod); 158 rsnd_dvc_soft_reset(mod);
159 159
@@ -175,7 +175,7 @@ static int rsnd_dvc_quit(struct rsnd_mod *mod,
175 struct rsnd_dai_stream *io, 175 struct rsnd_dai_stream *io,
176 struct rsnd_priv *priv) 176 struct rsnd_priv *priv)
177{ 177{
178 rsnd_mod_hw_stop(mod); 178 rsnd_mod_power_off(mod);
179 179
180 return 0; 180 return 0;
181} 181}
@@ -282,7 +282,7 @@ struct rsnd_mod *rsnd_dvc_mod_get(struct rsnd_priv *priv, int id)
282 if (WARN_ON(id < 0 || id >= rsnd_dvc_nr(priv))) 282 if (WARN_ON(id < 0 || id >= rsnd_dvc_nr(priv)))
283 id = 0; 283 id = 0;
284 284
285 return &((struct rsnd_dvc *)(priv->dvc) + id)->mod; 285 return rsnd_mod_get((struct rsnd_dvc *)(priv->dvc) + id);
286} 286}
287 287
288static void rsnd_of_parse_dvc(struct platform_device *pdev, 288static void rsnd_of_parse_dvc(struct platform_device *pdev,
@@ -333,10 +333,8 @@ int rsnd_dvc_probe(struct platform_device *pdev,
333 int i, nr, ret; 333 int i, nr, ret;
334 334
335 /* This driver doesn't support Gen1 at this point */ 335 /* This driver doesn't support Gen1 at this point */
336 if (rsnd_is_gen1(priv)) { 336 if (rsnd_is_gen1(priv))
337 dev_warn(dev, "CMD is not supported on Gen1\n"); 337 return 0;
338 return -EINVAL;
339 }
340 338
341 rsnd_of_parse_dvc(pdev, of_data, priv); 339 rsnd_of_parse_dvc(pdev, of_data, priv);
342 340
@@ -361,7 +359,7 @@ int rsnd_dvc_probe(struct platform_device *pdev,
361 359
362 dvc->info = &info->dvc_info[i]; 360 dvc->info = &info->dvc_info[i];
363 361
364 ret = rsnd_mod_init(priv, &dvc->mod, &rsnd_dvc_ops, 362 ret = rsnd_mod_init(priv, rsnd_mod_get(dvc), &rsnd_dvc_ops,
365 clk, RSND_MOD_DVC, i); 363 clk, RSND_MOD_DVC, i);
366 if (ret) 364 if (ret)
367 return ret; 365 return ret;
@@ -377,6 +375,6 @@ void rsnd_dvc_remove(struct platform_device *pdev,
377 int i; 375 int i;
378 376
379 for_each_rsnd_dvc(dvc, priv, i) { 377 for_each_rsnd_dvc(dvc, priv, i) {
380 rsnd_mod_quit(&dvc->mod); 378 rsnd_mod_quit(rsnd_mod_get(dvc));
381 } 379 }
382} 380}
diff --git a/sound/soc/sh/rcar/gen.c b/sound/soc/sh/rcar/gen.c
index f04d17bc6e3d..76da7620904c 100644
--- a/sound/soc/sh/rcar/gen.c
+++ b/sound/soc/sh/rcar/gen.c
@@ -22,13 +22,15 @@
22#include "rsnd.h" 22#include "rsnd.h"
23 23
24struct rsnd_gen { 24struct rsnd_gen {
25 void __iomem *base[RSND_BASE_MAX];
26
27 struct rsnd_gen_ops *ops; 25 struct rsnd_gen_ops *ops;
28 26
27 /* RSND_BASE_MAX base */
28 void __iomem *base[RSND_BASE_MAX];
29 phys_addr_t res[RSND_BASE_MAX];
29 struct regmap *regmap[RSND_BASE_MAX]; 30 struct regmap *regmap[RSND_BASE_MAX];
31
32 /* RSND_REG_MAX base */
30 struct regmap_field *regs[RSND_REG_MAX]; 33 struct regmap_field *regs[RSND_REG_MAX];
31 phys_addr_t res[RSND_REG_MAX];
32}; 34};
33 35
34#define rsnd_priv_to_gen(p) ((struct rsnd_gen *)(p)->gen) 36#define rsnd_priv_to_gen(p) ((struct rsnd_gen *)(p)->gen)
@@ -79,11 +81,11 @@ u32 rsnd_read(struct rsnd_priv *priv,
79 if (!rsnd_is_accessible_reg(priv, gen, reg)) 81 if (!rsnd_is_accessible_reg(priv, gen, reg))
80 return 0; 82 return 0;
81 83
84 regmap_fields_read(gen->regs[reg], rsnd_mod_id(mod), &val);
85
82 dev_dbg(dev, "r %s[%d] - %4d : %08x\n", 86 dev_dbg(dev, "r %s[%d] - %4d : %08x\n",
83 rsnd_mod_name(mod), rsnd_mod_id(mod), reg, val); 87 rsnd_mod_name(mod), rsnd_mod_id(mod), reg, val);
84 88
85 regmap_fields_read(gen->regs[reg], rsnd_mod_id(mod), &val);
86
87 return val; 89 return val;
88} 90}
89 91
@@ -182,6 +184,7 @@ static int _rsnd_gen_regmap_init(struct rsnd_priv *priv,
182 if (IS_ERR(regmap)) 184 if (IS_ERR(regmap))
183 return PTR_ERR(regmap); 185 return PTR_ERR(regmap);
184 186
187 /* RSND_BASE_MAX base */
185 gen->base[reg_id] = base; 188 gen->base[reg_id] = base;
186 gen->regmap[reg_id] = regmap; 189 gen->regmap[reg_id] = regmap;
187 gen->res[reg_id] = res->start; 190 gen->res[reg_id] = res->start;
@@ -198,6 +201,7 @@ static int _rsnd_gen_regmap_init(struct rsnd_priv *priv,
198 if (IS_ERR(regs)) 201 if (IS_ERR(regs))
199 return PTR_ERR(regs); 202 return PTR_ERR(regs);
200 203
204 /* RSND_REG_MAX base */
201 gen->regs[conf[i].idx] = regs; 205 gen->regs[conf[i].idx] = regs;
202 } 206 }
203 207
diff --git a/sound/soc/sh/rcar/mix.c b/sound/soc/sh/rcar/mix.c
index 0d5c102db6f5..953dd0be9b60 100644
--- a/sound/soc/sh/rcar/mix.c
+++ b/sound/soc/sh/rcar/mix.c
@@ -58,7 +58,7 @@ static int rsnd_mix_init(struct rsnd_mod *mod,
58 struct rsnd_dai_stream *io, 58 struct rsnd_dai_stream *io,
59 struct rsnd_priv *priv) 59 struct rsnd_priv *priv)
60{ 60{
61 rsnd_mod_hw_start(mod); 61 rsnd_mod_power_on(mod);
62 62
63 rsnd_mix_soft_reset(mod); 63 rsnd_mix_soft_reset(mod);
64 64
@@ -83,7 +83,7 @@ static int rsnd_mix_quit(struct rsnd_mod *mod,
83 struct rsnd_dai_stream *io, 83 struct rsnd_dai_stream *io,
84 struct rsnd_priv *priv) 84 struct rsnd_priv *priv)
85{ 85{
86 rsnd_mod_hw_stop(mod); 86 rsnd_mod_power_off(mod);
87 87
88 return 0; 88 return 0;
89} 89}
@@ -99,7 +99,7 @@ struct rsnd_mod *rsnd_mix_mod_get(struct rsnd_priv *priv, int id)
99 if (WARN_ON(id < 0 || id >= rsnd_mix_nr(priv))) 99 if (WARN_ON(id < 0 || id >= rsnd_mix_nr(priv)))
100 id = 0; 100 id = 0;
101 101
102 return &((struct rsnd_mix *)(priv->mix) + id)->mod; 102 return rsnd_mod_get((struct rsnd_mix *)(priv->mix) + id);
103} 103}
104 104
105static void rsnd_of_parse_mix(struct platform_device *pdev, 105static void rsnd_of_parse_mix(struct platform_device *pdev,
@@ -151,10 +151,8 @@ int rsnd_mix_probe(struct platform_device *pdev,
151 int i, nr, ret; 151 int i, nr, ret;
152 152
153 /* This driver doesn't support Gen1 at this point */ 153 /* This driver doesn't support Gen1 at this point */
154 if (rsnd_is_gen1(priv)) { 154 if (rsnd_is_gen1(priv))
155 dev_warn(dev, "MIX is not supported on Gen1\n"); 155 return 0;
156 return -EINVAL;
157 }
158 156
159 rsnd_of_parse_mix(pdev, of_data, priv); 157 rsnd_of_parse_mix(pdev, of_data, priv);
160 158
@@ -179,7 +177,7 @@ int rsnd_mix_probe(struct platform_device *pdev,
179 177
180 mix->info = &info->mix_info[i]; 178 mix->info = &info->mix_info[i];
181 179
182 ret = rsnd_mod_init(priv, &mix->mod, &rsnd_mix_ops, 180 ret = rsnd_mod_init(priv, rsnd_mod_get(mix), &rsnd_mix_ops,
183 clk, RSND_MOD_MIX, i); 181 clk, RSND_MOD_MIX, i);
184 if (ret) 182 if (ret)
185 return ret; 183 return ret;
@@ -195,6 +193,6 @@ void rsnd_mix_remove(struct platform_device *pdev,
195 int i; 193 int i;
196 194
197 for_each_rsnd_mix(mix, priv, i) { 195 for_each_rsnd_mix(mix, priv, i) {
198 rsnd_mod_quit(&mix->mod); 196 rsnd_mod_quit(rsnd_mod_get(mix));
199 } 197 }
200} 198}
diff --git a/include/sound/rcar_snd.h b/sound/soc/sh/rcar/rcar_snd.h
index bb7b2ebfee7b..d8e33d38da43 100644
--- a/include/sound/rcar_snd.h
+++ b/sound/soc/sh/rcar/rcar_snd.h
@@ -12,7 +12,6 @@
12#ifndef RCAR_SND_H 12#ifndef RCAR_SND_H
13#define RCAR_SND_H 13#define RCAR_SND_H
14 14
15#include <linux/sh_clk.h>
16 15
17#define RSND_GEN1_SRU 0 16#define RSND_GEN1_SRU 0
18#define RSND_GEN1_ADG 1 17#define RSND_GEN1_ADG 1
diff --git a/sound/soc/sh/rcar/rsnd.h b/sound/soc/sh/rcar/rsnd.h
index 7a0e52b4640a..085329878525 100644
--- a/sound/soc/sh/rcar/rsnd.h
+++ b/sound/soc/sh/rcar/rsnd.h
@@ -21,10 +21,11 @@
21#include <linux/of_irq.h> 21#include <linux/of_irq.h>
22#include <linux/sh_dma.h> 22#include <linux/sh_dma.h>
23#include <linux/workqueue.h> 23#include <linux/workqueue.h>
24#include <sound/rcar_snd.h>
25#include <sound/soc.h> 24#include <sound/soc.h>
26#include <sound/pcm_params.h> 25#include <sound/pcm_params.h>
27 26
27#include "rcar_snd.h"
28
28/* 29/*
29 * pseudo register 30 * pseudo register
30 * 31 *
@@ -214,6 +215,7 @@ struct rsnd_dma {
214}; 215};
215#define rsnd_dma_to_dmaen(dma) (&(dma)->dma.en) 216#define rsnd_dma_to_dmaen(dma) (&(dma)->dma.en)
216#define rsnd_dma_to_dmapp(dma) (&(dma)->dma.pp) 217#define rsnd_dma_to_dmapp(dma) (&(dma)->dma.pp)
218#define rsnd_dma_to_mod(_dma) container_of((_dma), struct rsnd_mod, dma)
217 219
218void rsnd_dma_start(struct rsnd_dai_stream *io, struct rsnd_dma *dma); 220void rsnd_dma_start(struct rsnd_dai_stream *io, struct rsnd_dma *dma);
219void rsnd_dma_stop(struct rsnd_dai_stream *io, struct rsnd_dma *dma); 221void rsnd_dma_stop(struct rsnd_dai_stream *io, struct rsnd_dma *dma);
@@ -225,8 +227,6 @@ int rsnd_dma_probe(struct platform_device *pdev,
225struct dma_chan *rsnd_dma_request_channel(struct device_node *of_node, 227struct dma_chan *rsnd_dma_request_channel(struct device_node *of_node,
226 struct rsnd_mod *mod, char *name); 228 struct rsnd_mod *mod, char *name);
227 229
228#define rsnd_dma_to_mod(_dma) container_of((_dma), struct rsnd_mod, dma)
229
230/* 230/*
231 * R-Car sound mod 231 * R-Car sound mod
232 */ 232 */
@@ -330,8 +330,9 @@ struct rsnd_mod {
330#define rsnd_mod_to_priv(mod) ((mod)->priv) 330#define rsnd_mod_to_priv(mod) ((mod)->priv)
331#define rsnd_mod_to_dma(mod) (&(mod)->dma) 331#define rsnd_mod_to_dma(mod) (&(mod)->dma)
332#define rsnd_mod_id(mod) ((mod) ? (mod)->id : -1) 332#define rsnd_mod_id(mod) ((mod) ? (mod)->id : -1)
333#define rsnd_mod_hw_start(mod) clk_enable((mod)->clk) 333#define rsnd_mod_power_on(mod) clk_enable((mod)->clk)
334#define rsnd_mod_hw_stop(mod) clk_disable((mod)->clk) 334#define rsnd_mod_power_off(mod) clk_disable((mod)->clk)
335#define rsnd_mod_get(ip) (&(ip)->mod)
335 336
336int rsnd_mod_init(struct rsnd_priv *priv, 337int rsnd_mod_init(struct rsnd_priv *priv,
337 struct rsnd_mod *mod, 338 struct rsnd_mod *mod,
@@ -571,9 +572,12 @@ int rsnd_ssi_probe(struct platform_device *pdev,
571void rsnd_ssi_remove(struct platform_device *pdev, 572void rsnd_ssi_remove(struct platform_device *pdev,
572 struct rsnd_priv *priv); 573 struct rsnd_priv *priv);
573struct rsnd_mod *rsnd_ssi_mod_get(struct rsnd_priv *priv, int id); 574struct rsnd_mod *rsnd_ssi_mod_get(struct rsnd_priv *priv, int id);
574int rsnd_ssi_is_pin_sharing(struct rsnd_mod *mod);
575int rsnd_ssi_is_dma_mode(struct rsnd_mod *mod); 575int rsnd_ssi_is_dma_mode(struct rsnd_mod *mod);
576int rsnd_ssi_use_busif(struct rsnd_dai_stream *io, struct rsnd_mod *mod); 576int rsnd_ssi_use_busif(struct rsnd_dai_stream *io);
577
578#define rsnd_ssi_is_pin_sharing(io) \
579 __rsnd_ssi_is_pin_sharing(rsnd_io_to_mod_ssi(io))
580int __rsnd_ssi_is_pin_sharing(struct rsnd_mod *mod);
577 581
578/* 582/*
579 * R-Car SRC 583 * R-Car SRC
@@ -627,4 +631,15 @@ void rsnd_dvc_remove(struct platform_device *pdev,
627 struct rsnd_priv *priv); 631 struct rsnd_priv *priv);
628struct rsnd_mod *rsnd_dvc_mod_get(struct rsnd_priv *priv, int id); 632struct rsnd_mod *rsnd_dvc_mod_get(struct rsnd_priv *priv, int id);
629 633
634#ifdef DEBUG
635void rsnd_mod_make_sure(struct rsnd_mod *mod, enum rsnd_mod_type type);
636#define rsnd_mod_confirm_ssi(mssi) rsnd_mod_make_sure(mssi, RSND_MOD_SSI)
637#define rsnd_mod_confirm_src(msrc) rsnd_mod_make_sure(msrc, RSND_MOD_SRC)
638#define rsnd_mod_confirm_dvc(mdvc) rsnd_mod_make_sure(mdvc, RSND_MOD_DVC)
639#else
640#define rsnd_mod_confirm_ssi(mssi)
641#define rsnd_mod_confirm_src(msrc)
642#define rsnd_mod_confirm_dvc(mdvc)
643#endif
644
630#endif 645#endif
diff --git a/sound/soc/sh/rcar/src.c b/sound/soc/sh/rcar/src.c
index 89a18e102feb..261b50217c48 100644
--- a/sound/soc/sh/rcar/src.c
+++ b/sound/soc/sh/rcar/src.c
@@ -159,7 +159,7 @@ int rsnd_src_ssiu_start(struct rsnd_mod *ssi_mod,
159 /* 159 /*
160 * SSI_MODE1 160 * SSI_MODE1
161 */ 161 */
162 if (rsnd_ssi_is_pin_sharing(ssi_mod)) { 162 if (rsnd_ssi_is_pin_sharing(io)) {
163 int shift = -1; 163 int shift = -1;
164 switch (ssi_id) { 164 switch (ssi_id) {
165 case 1: 165 case 1:
@@ -352,7 +352,7 @@ static int rsnd_src_init(struct rsnd_mod *mod,
352{ 352{
353 struct rsnd_src *src = rsnd_mod_to_src(mod); 353 struct rsnd_src *src = rsnd_mod_to_src(mod);
354 354
355 rsnd_mod_hw_start(mod); 355 rsnd_mod_power_on(mod);
356 356
357 rsnd_src_soft_reset(mod); 357 rsnd_src_soft_reset(mod);
358 358
@@ -373,7 +373,7 @@ static int rsnd_src_quit(struct rsnd_mod *mod,
373 struct rsnd_src *src = rsnd_mod_to_src(mod); 373 struct rsnd_src *src = rsnd_mod_to_src(mod);
374 struct device *dev = rsnd_priv_to_dev(priv); 374 struct device *dev = rsnd_priv_to_dev(priv);
375 375
376 rsnd_mod_hw_stop(mod); 376 rsnd_mod_power_off(mod);
377 377
378 if (src->err) 378 if (src->err)
379 dev_warn(dev, "%s[%d] under/over flow err = %d\n", 379 dev_warn(dev, "%s[%d] under/over flow err = %d\n",
@@ -918,11 +918,10 @@ static void rsnd_src_reconvert_update(struct rsnd_dai_stream *io,
918 rsnd_mod_write(mod, SRC_IFSVR, fsrate); 918 rsnd_mod_write(mod, SRC_IFSVR, fsrate);
919} 919}
920 920
921static int rsnd_src_pcm_new(struct rsnd_mod *mod, 921static int rsnd_src_pcm_new_gen2(struct rsnd_mod *mod,
922 struct rsnd_dai_stream *io, 922 struct rsnd_dai_stream *io,
923 struct snd_soc_pcm_runtime *rtd) 923 struct snd_soc_pcm_runtime *rtd)
924{ 924{
925 struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
926 struct rsnd_dai *rdai = rsnd_io_to_rdai(io); 925 struct rsnd_dai *rdai = rsnd_io_to_rdai(io);
927 struct rsnd_src *src = rsnd_mod_to_src(mod); 926 struct rsnd_src *src = rsnd_mod_to_src(mod);
928 int ret; 927 int ret;
@@ -932,12 +931,6 @@ static int rsnd_src_pcm_new(struct rsnd_mod *mod,
932 */ 931 */
933 932
934 /* 933 /*
935 * Gen1 is not supported
936 */
937 if (rsnd_is_gen1(priv))
938 return 0;
939
940 /*
941 * SRC sync convert needs clock master 934 * SRC sync convert needs clock master
942 */ 935 */
943 if (!rsnd_rdai_is_clk_master(rdai)) 936 if (!rsnd_rdai_is_clk_master(rdai))
@@ -975,7 +968,7 @@ static struct rsnd_mod_ops rsnd_src_gen2_ops = {
975 .start = rsnd_src_start_gen2, 968 .start = rsnd_src_start_gen2,
976 .stop = rsnd_src_stop_gen2, 969 .stop = rsnd_src_stop_gen2,
977 .hw_params = rsnd_src_hw_params, 970 .hw_params = rsnd_src_hw_params,
978 .pcm_new = rsnd_src_pcm_new, 971 .pcm_new = rsnd_src_pcm_new_gen2,
979}; 972};
980 973
981struct rsnd_mod *rsnd_src_mod_get(struct rsnd_priv *priv, int id) 974struct rsnd_mod *rsnd_src_mod_get(struct rsnd_priv *priv, int id)
@@ -983,7 +976,7 @@ struct rsnd_mod *rsnd_src_mod_get(struct rsnd_priv *priv, int id)
983 if (WARN_ON(id < 0 || id >= rsnd_src_nr(priv))) 976 if (WARN_ON(id < 0 || id >= rsnd_src_nr(priv)))
984 id = 0; 977 id = 0;
985 978
986 return &((struct rsnd_src *)(priv->src) + id)->mod; 979 return rsnd_mod_get((struct rsnd_src *)(priv->src) + id);
987} 980}
988 981
989static void rsnd_of_parse_src(struct platform_device *pdev, 982static void rsnd_of_parse_src(struct platform_device *pdev,
@@ -1043,8 +1036,10 @@ int rsnd_src_probe(struct platform_device *pdev,
1043 int i, nr, ret; 1036 int i, nr, ret;
1044 1037
1045 ops = NULL; 1038 ops = NULL;
1046 if (rsnd_is_gen1(priv)) 1039 if (rsnd_is_gen1(priv)) {
1047 ops = &rsnd_src_gen1_ops; 1040 ops = &rsnd_src_gen1_ops;
1041 dev_warn(dev, "Gen1 support will be removed soon\n");
1042 }
1048 if (rsnd_is_gen2(priv)) 1043 if (rsnd_is_gen2(priv))
1049 ops = &rsnd_src_gen2_ops; 1044 ops = &rsnd_src_gen2_ops;
1050 if (!ops) { 1045 if (!ops) {
@@ -1078,7 +1073,7 @@ int rsnd_src_probe(struct platform_device *pdev,
1078 1073
1079 src->info = &info->src_info[i]; 1074 src->info = &info->src_info[i];
1080 1075
1081 ret = rsnd_mod_init(priv, &src->mod, ops, clk, RSND_MOD_SRC, i); 1076 ret = rsnd_mod_init(priv, rsnd_mod_get(src), ops, clk, RSND_MOD_SRC, i);
1082 if (ret) 1077 if (ret)
1083 return ret; 1078 return ret;
1084 } 1079 }
@@ -1093,6 +1088,6 @@ void rsnd_src_remove(struct platform_device *pdev,
1093 int i; 1088 int i;
1094 1089
1095 for_each_rsnd_src(src, priv, i) { 1090 for_each_rsnd_src(src, priv, i) {
1096 rsnd_mod_quit(&src->mod); 1091 rsnd_mod_quit(rsnd_mod_get(src));
1097 } 1092 }
1098} 1093}
diff --git a/sound/soc/sh/rcar/ssi.c b/sound/soc/sh/rcar/ssi.c
index d45b9a7e324e..1427ec21bd7e 100644
--- a/sound/soc/sh/rcar/ssi.c
+++ b/sound/soc/sh/rcar/ssi.c
@@ -79,7 +79,6 @@ struct rsnd_ssi {
79 79
80#define rsnd_ssi_nr(priv) ((priv)->ssi_nr) 80#define rsnd_ssi_nr(priv) ((priv)->ssi_nr)
81#define rsnd_mod_to_ssi(_mod) container_of((_mod), struct rsnd_ssi, mod) 81#define rsnd_mod_to_ssi(_mod) container_of((_mod), struct rsnd_ssi, mod)
82#define rsnd_dma_to_ssi(dma) rsnd_mod_to_ssi(rsnd_dma_to_mod(dma))
83#define rsnd_ssi_pio_available(ssi) ((ssi)->info->irq > 0) 82#define rsnd_ssi_pio_available(ssi) ((ssi)->info->irq > 0)
84#define rsnd_ssi_parent(ssi) ((ssi)->parent) 83#define rsnd_ssi_parent(ssi) ((ssi)->parent)
85#define rsnd_ssi_mode_flags(p) ((p)->info->flags) 84#define rsnd_ssi_mode_flags(p) ((p)->info->flags)
@@ -87,8 +86,9 @@ struct rsnd_ssi {
87#define rsnd_ssi_of_node(priv) \ 86#define rsnd_ssi_of_node(priv) \
88 of_get_child_by_name(rsnd_priv_to_dev(priv)->of_node, "rcar_sound,ssi") 87 of_get_child_by_name(rsnd_priv_to_dev(priv)->of_node, "rcar_sound,ssi")
89 88
90int rsnd_ssi_use_busif(struct rsnd_dai_stream *io, struct rsnd_mod *mod) 89int rsnd_ssi_use_busif(struct rsnd_dai_stream *io)
91{ 90{
91 struct rsnd_mod *mod = rsnd_io_to_mod_ssi(io);
92 struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod); 92 struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod);
93 int use_busif = 0; 93 int use_busif = 0;
94 94
@@ -128,10 +128,8 @@ static int rsnd_ssi_master_clk_start(struct rsnd_ssi *ssi,
128 struct rsnd_priv *priv = rsnd_io_to_priv(io); 128 struct rsnd_priv *priv = rsnd_io_to_priv(io);
129 struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io); 129 struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io);
130 struct device *dev = rsnd_priv_to_dev(priv); 130 struct device *dev = rsnd_priv_to_dev(priv);
131 int i, j, ret; 131 struct rsnd_mod *mod = rsnd_mod_get(ssi);
132 int adg_clk_div_table[] = { 132 int j, ret;
133 1, 6, /* see adg.c */
134 };
135 int ssi_clk_mul_table[] = { 133 int ssi_clk_mul_table[] = {
136 1, 2, 4, 8, 16, 6, 12, 134 1, 2, 4, 8, 16, 6, 12,
137 }; 135 };
@@ -141,28 +139,25 @@ static int rsnd_ssi_master_clk_start(struct rsnd_ssi *ssi,
141 /* 139 /*
142 * Find best clock, and try to start ADG 140 * Find best clock, and try to start ADG
143 */ 141 */
144 for (i = 0; i < ARRAY_SIZE(adg_clk_div_table); i++) { 142 for (j = 0; j < ARRAY_SIZE(ssi_clk_mul_table); j++) {
145 for (j = 0; j < ARRAY_SIZE(ssi_clk_mul_table); j++) { 143
146 144 /*
147 /* 145 * this driver is assuming that
148 * this driver is assuming that 146 * system word is 64fs (= 2 x 32bit)
149 * system word is 64fs (= 2 x 32bit) 147 * see rsnd_ssi_init()
150 * see rsnd_ssi_init() 148 */
151 */ 149 main_rate = rate * 32 * 2 * ssi_clk_mul_table[j];
152 main_rate = rate / adg_clk_div_table[i] 150
153 * 32 * 2 * ssi_clk_mul_table[j]; 151 ret = rsnd_adg_ssi_clk_try_start(mod, main_rate);
154 152 if (0 == ret) {
155 ret = rsnd_adg_ssi_clk_try_start(&ssi->mod, main_rate); 153 ssi->cr_clk = FORCE | SWL_32 |
156 if (0 == ret) { 154 SCKD | SWSD | CKDV(j);
157 ssi->cr_clk = FORCE | SWL_32 | 155
158 SCKD | SWSD | CKDV(j); 156 dev_dbg(dev, "%s[%d] outputs %u Hz\n",
159 157 rsnd_mod_name(mod),
160 dev_dbg(dev, "%s[%d] outputs %u Hz\n", 158 rsnd_mod_id(mod), rate);
161 rsnd_mod_name(&ssi->mod), 159
162 rsnd_mod_id(&ssi->mod), rate); 160 return 0;
163
164 return 0;
165 }
166 } 161 }
167 } 162 }
168 163
@@ -172,8 +167,10 @@ static int rsnd_ssi_master_clk_start(struct rsnd_ssi *ssi,
172 167
173static void rsnd_ssi_master_clk_stop(struct rsnd_ssi *ssi) 168static void rsnd_ssi_master_clk_stop(struct rsnd_ssi *ssi)
174{ 169{
170 struct rsnd_mod *mod = rsnd_mod_get(ssi);
171
175 ssi->cr_clk = 0; 172 ssi->cr_clk = 0;
176 rsnd_adg_ssi_clk_stop(&ssi->mod); 173 rsnd_adg_ssi_clk_stop(mod);
177} 174}
178 175
179static void rsnd_ssi_hw_start(struct rsnd_ssi *ssi, 176static void rsnd_ssi_hw_start(struct rsnd_ssi *ssi,
@@ -182,11 +179,12 @@ static void rsnd_ssi_hw_start(struct rsnd_ssi *ssi,
182 struct rsnd_priv *priv = rsnd_io_to_priv(io); 179 struct rsnd_priv *priv = rsnd_io_to_priv(io);
183 struct rsnd_dai *rdai = rsnd_io_to_rdai(io); 180 struct rsnd_dai *rdai = rsnd_io_to_rdai(io);
184 struct device *dev = rsnd_priv_to_dev(priv); 181 struct device *dev = rsnd_priv_to_dev(priv);
182 struct rsnd_mod *mod = rsnd_mod_get(ssi);
185 u32 cr_mode; 183 u32 cr_mode;
186 u32 cr; 184 u32 cr;
187 185
188 if (0 == ssi->usrcnt) { 186 if (0 == ssi->usrcnt) {
189 rsnd_mod_hw_start(&ssi->mod); 187 rsnd_mod_power_on(mod);
190 188
191 if (rsnd_rdai_is_clk_master(rdai)) { 189 if (rsnd_rdai_is_clk_master(rdai)) {
192 struct rsnd_ssi *ssi_parent = rsnd_ssi_parent(ssi); 190 struct rsnd_ssi *ssi_parent = rsnd_ssi_parent(ssi);
@@ -198,7 +196,7 @@ static void rsnd_ssi_hw_start(struct rsnd_ssi *ssi,
198 } 196 }
199 } 197 }
200 198
201 if (rsnd_ssi_is_dma_mode(&ssi->mod)) { 199 if (rsnd_ssi_is_dma_mode(mod)) {
202 cr_mode = UIEN | OIEN | /* over/under run */ 200 cr_mode = UIEN | OIEN | /* over/under run */
203 DMEN; /* DMA : enable DMA */ 201 DMEN; /* DMA : enable DMA */
204 } else { 202 } else {
@@ -210,24 +208,25 @@ static void rsnd_ssi_hw_start(struct rsnd_ssi *ssi,
210 cr_mode | 208 cr_mode |
211 EN; 209 EN;
212 210
213 rsnd_mod_write(&ssi->mod, SSICR, cr); 211 rsnd_mod_write(mod, SSICR, cr);
214 212
215 /* enable WS continue */ 213 /* enable WS continue */
216 if (rsnd_rdai_is_clk_master(rdai)) 214 if (rsnd_rdai_is_clk_master(rdai))
217 rsnd_mod_write(&ssi->mod, SSIWSR, CONT); 215 rsnd_mod_write(mod, SSIWSR, CONT);
218 216
219 /* clear error status */ 217 /* clear error status */
220 rsnd_mod_write(&ssi->mod, SSISR, 0); 218 rsnd_mod_write(mod, SSISR, 0);
221 219
222 ssi->usrcnt++; 220 ssi->usrcnt++;
223 221
224 dev_dbg(dev, "%s[%d] hw started\n", 222 dev_dbg(dev, "%s[%d] hw started\n",
225 rsnd_mod_name(&ssi->mod), rsnd_mod_id(&ssi->mod)); 223 rsnd_mod_name(mod), rsnd_mod_id(mod));
226} 224}
227 225
228static void rsnd_ssi_hw_stop(struct rsnd_dai_stream *io, struct rsnd_ssi *ssi) 226static void rsnd_ssi_hw_stop(struct rsnd_dai_stream *io, struct rsnd_ssi *ssi)
229{ 227{
230 struct rsnd_priv *priv = rsnd_mod_to_priv(&ssi->mod); 228 struct rsnd_mod *mod = rsnd_mod_get(ssi);
229 struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
231 struct rsnd_dai *rdai = rsnd_io_to_rdai(io); 230 struct rsnd_dai *rdai = rsnd_io_to_rdai(io);
232 struct device *dev = rsnd_priv_to_dev(priv); 231 struct device *dev = rsnd_priv_to_dev(priv);
233 u32 cr; 232 u32 cr;
@@ -247,15 +246,15 @@ static void rsnd_ssi_hw_stop(struct rsnd_dai_stream *io, struct rsnd_ssi *ssi)
247 cr = ssi->cr_own | 246 cr = ssi->cr_own |
248 ssi->cr_clk; 247 ssi->cr_clk;
249 248
250 rsnd_mod_write(&ssi->mod, SSICR, cr | EN); 249 rsnd_mod_write(mod, SSICR, cr | EN);
251 rsnd_ssi_status_check(&ssi->mod, DIRQ); 250 rsnd_ssi_status_check(mod, DIRQ);
252 251
253 /* 252 /*
254 * disable SSI, 253 * disable SSI,
255 * and, wait idle state 254 * and, wait idle state
256 */ 255 */
257 rsnd_mod_write(&ssi->mod, SSICR, cr); /* disabled all */ 256 rsnd_mod_write(mod, SSICR, cr); /* disabled all */
258 rsnd_ssi_status_check(&ssi->mod, IIRQ); 257 rsnd_ssi_status_check(mod, IIRQ);
259 258
260 if (rsnd_rdai_is_clk_master(rdai)) { 259 if (rsnd_rdai_is_clk_master(rdai)) {
261 struct rsnd_ssi *ssi_parent = rsnd_ssi_parent(ssi); 260 struct rsnd_ssi *ssi_parent = rsnd_ssi_parent(ssi);
@@ -266,13 +265,13 @@ static void rsnd_ssi_hw_stop(struct rsnd_dai_stream *io, struct rsnd_ssi *ssi)
266 rsnd_ssi_master_clk_stop(ssi); 265 rsnd_ssi_master_clk_stop(ssi);
267 } 266 }
268 267
269 rsnd_mod_hw_stop(&ssi->mod); 268 rsnd_mod_power_off(mod);
270 269
271 ssi->chan = 0; 270 ssi->chan = 0;
272 } 271 }
273 272
274 dev_dbg(dev, "%s[%d] hw stopped\n", 273 dev_dbg(dev, "%s[%d] hw stopped\n",
275 rsnd_mod_name(&ssi->mod), rsnd_mod_id(&ssi->mod)); 274 rsnd_mod_name(mod), rsnd_mod_id(mod));
276} 275}
277 276
278/* 277/*
@@ -371,7 +370,7 @@ static int rsnd_ssi_hw_params(struct rsnd_mod *mod,
371 /* It will be removed on rsnd_ssi_hw_stop */ 370 /* It will be removed on rsnd_ssi_hw_stop */
372 ssi->chan = chan; 371 ssi->chan = chan;
373 if (ssi_parent) 372 if (ssi_parent)
374 return rsnd_ssi_hw_params(&ssi_parent->mod, io, 373 return rsnd_ssi_hw_params(rsnd_mod_get(ssi_parent), io,
375 substream, params); 374 substream, params);
376 375
377 return 0; 376 return 0;
@@ -379,12 +378,14 @@ static int rsnd_ssi_hw_params(struct rsnd_mod *mod,
379 378
380static void rsnd_ssi_record_error(struct rsnd_ssi *ssi, u32 status) 379static void rsnd_ssi_record_error(struct rsnd_ssi *ssi, u32 status)
381{ 380{
381 struct rsnd_mod *mod = rsnd_mod_get(ssi);
382
382 /* under/over flow error */ 383 /* under/over flow error */
383 if (status & (UIRQ | OIRQ)) { 384 if (status & (UIRQ | OIRQ)) {
384 ssi->err++; 385 ssi->err++;
385 386
386 /* clear error status */ 387 /* clear error status */
387 rsnd_mod_write(&ssi->mod, SSISR, 0); 388 rsnd_mod_write(mod, SSISR, 0);
388 } 389 }
389} 390}
390 391
@@ -394,7 +395,7 @@ static int rsnd_ssi_start(struct rsnd_mod *mod,
394{ 395{
395 struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod); 396 struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod);
396 397
397 rsnd_src_ssiu_start(mod, io, rsnd_ssi_use_busif(io, mod)); 398 rsnd_src_ssiu_start(mod, io, rsnd_ssi_use_busif(io));
398 399
399 rsnd_ssi_hw_start(ssi, io); 400 rsnd_ssi_hw_start(ssi, io);
400 401
@@ -554,7 +555,7 @@ static int rsnd_ssi_dma_remove(struct rsnd_mod *mod,
554 rsnd_dma_quit(io, rsnd_mod_to_dma(mod)); 555 rsnd_dma_quit(io, rsnd_mod_to_dma(mod));
555 556
556 /* PIO will request IRQ again */ 557 /* PIO will request IRQ again */
557 devm_free_irq(dev, irq, ssi); 558 devm_free_irq(dev, irq, mod);
558 559
559 return 0; 560 return 0;
560} 561}
@@ -613,7 +614,7 @@ static struct dma_chan *rsnd_ssi_dma_req(struct rsnd_dai_stream *io,
613 int is_play = rsnd_io_is_play(io); 614 int is_play = rsnd_io_is_play(io);
614 char *name; 615 char *name;
615 616
616 if (rsnd_ssi_use_busif(io, mod)) 617 if (rsnd_ssi_use_busif(io))
617 name = is_play ? "rxu" : "txu"; 618 name = is_play ? "rxu" : "txu";
618 else 619 else
619 name = is_play ? "rx" : "tx"; 620 name = is_play ? "rx" : "tx";
@@ -656,10 +657,10 @@ struct rsnd_mod *rsnd_ssi_mod_get(struct rsnd_priv *priv, int id)
656 if (WARN_ON(id < 0 || id >= rsnd_ssi_nr(priv))) 657 if (WARN_ON(id < 0 || id >= rsnd_ssi_nr(priv)))
657 id = 0; 658 id = 0;
658 659
659 return &((struct rsnd_ssi *)(priv->ssi) + id)->mod; 660 return rsnd_mod_get((struct rsnd_ssi *)(priv->ssi) + id);
660} 661}
661 662
662int rsnd_ssi_is_pin_sharing(struct rsnd_mod *mod) 663int __rsnd_ssi_is_pin_sharing(struct rsnd_mod *mod)
663{ 664{
664 struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod); 665 struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod);
665 666
@@ -668,10 +669,12 @@ int rsnd_ssi_is_pin_sharing(struct rsnd_mod *mod)
668 669
669static void rsnd_ssi_parent_setup(struct rsnd_priv *priv, struct rsnd_ssi *ssi) 670static void rsnd_ssi_parent_setup(struct rsnd_priv *priv, struct rsnd_ssi *ssi)
670{ 671{
671 if (!rsnd_ssi_is_pin_sharing(&ssi->mod)) 672 struct rsnd_mod *mod = rsnd_mod_get(ssi);
673
674 if (!__rsnd_ssi_is_pin_sharing(mod))
672 return; 675 return;
673 676
674 switch (rsnd_mod_id(&ssi->mod)) { 677 switch (rsnd_mod_id(mod)) {
675 case 1: 678 case 1:
676 case 2: 679 case 2:
677 ssi->parent = rsnd_mod_to_ssi(rsnd_ssi_mod_get(priv, 0)); 680 ssi->parent = rsnd_mod_to_ssi(rsnd_ssi_mod_get(priv, 0));
@@ -697,9 +700,6 @@ static void rsnd_of_parse_ssi(struct platform_device *pdev,
697 struct device *dev = &pdev->dev; 700 struct device *dev = &pdev->dev;
698 int nr, i; 701 int nr, i;
699 702
700 if (!of_data)
701 return;
702
703 node = rsnd_ssi_of_node(priv); 703 node = rsnd_ssi_of_node(priv);
704 if (!node) 704 if (!node)
705 return; 705 return;
@@ -794,7 +794,8 @@ int rsnd_ssi_probe(struct platform_device *pdev,
794 else if (rsnd_ssi_pio_available(ssi)) 794 else if (rsnd_ssi_pio_available(ssi))
795 ops = &rsnd_ssi_pio_ops; 795 ops = &rsnd_ssi_pio_ops;
796 796
797 ret = rsnd_mod_init(priv, &ssi->mod, ops, clk, RSND_MOD_SSI, i); 797 ret = rsnd_mod_init(priv, rsnd_mod_get(ssi), ops, clk,
798 RSND_MOD_SSI, i);
798 if (ret) 799 if (ret)
799 return ret; 800 return ret;
800 801
@@ -811,6 +812,6 @@ void rsnd_ssi_remove(struct platform_device *pdev,
811 int i; 812 int i;
812 813
813 for_each_rsnd_ssi(ssi, priv, i) { 814 for_each_rsnd_ssi(ssi, priv, i) {
814 rsnd_mod_quit(&ssi->mod); 815 rsnd_mod_quit(rsnd_mod_get(ssi));
815 } 816 }
816} 817}
diff --git a/sound/soc/sh/siu_dai.c b/sound/soc/sh/siu_dai.c
index abb0d956231c..76b2ab8c2b4a 100644
--- a/sound/soc/sh/siu_dai.c
+++ b/sound/soc/sh/siu_dai.c
@@ -738,7 +738,7 @@ static int siu_probe(struct platform_device *pdev)
738 struct siu_info *info; 738 struct siu_info *info;
739 int ret; 739 int ret;
740 740
741 info = kmalloc(sizeof(*info), GFP_KERNEL); 741 info = devm_kmalloc(&pdev->dev, sizeof(*info), GFP_KERNEL);
742 if (!info) 742 if (!info)
743 return -ENOMEM; 743 return -ENOMEM;
744 siu_i2s_data = info; 744 siu_i2s_data = info;
@@ -746,7 +746,7 @@ static int siu_probe(struct platform_device *pdev)
746 746
747 ret = request_firmware(&fw_entry, "siu_spb.bin", &pdev->dev); 747 ret = request_firmware(&fw_entry, "siu_spb.bin", &pdev->dev);
748 if (ret) 748 if (ret)
749 goto ereqfw; 749 return ret;
750 750
751 /* 751 /*
752 * Loaded firmware is "const" - read only, but we have to modify it in 752 * Loaded firmware is "const" - read only, but we have to modify it in
@@ -757,89 +757,52 @@ static int siu_probe(struct platform_device *pdev)
757 release_firmware(fw_entry); 757 release_firmware(fw_entry);
758 758
759 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 759 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
760 if (!res) { 760 if (!res)
761 ret = -ENODEV; 761 return -ENODEV;
762 goto egetres;
763 }
764 762
765 region = request_mem_region(res->start, resource_size(res), 763 region = devm_request_mem_region(&pdev->dev, res->start,
766 pdev->name); 764 resource_size(res), pdev->name);
767 if (!region) { 765 if (!region) {
768 dev_err(&pdev->dev, "SIU region already claimed\n"); 766 dev_err(&pdev->dev, "SIU region already claimed\n");
769 ret = -EBUSY; 767 return -EBUSY;
770 goto ereqmemreg;
771 } 768 }
772 769
773 ret = -ENOMEM; 770 info->pram = devm_ioremap(&pdev->dev, res->start, PRAM_SIZE);
774 info->pram = ioremap(res->start, PRAM_SIZE);
775 if (!info->pram) 771 if (!info->pram)
776 goto emappram; 772 return -ENOMEM;
777 info->xram = ioremap(res->start + XRAM_OFFSET, XRAM_SIZE); 773 info->xram = devm_ioremap(&pdev->dev, res->start + XRAM_OFFSET,
774 XRAM_SIZE);
778 if (!info->xram) 775 if (!info->xram)
779 goto emapxram; 776 return -ENOMEM;
780 info->yram = ioremap(res->start + YRAM_OFFSET, YRAM_SIZE); 777 info->yram = devm_ioremap(&pdev->dev, res->start + YRAM_OFFSET,
778 YRAM_SIZE);
781 if (!info->yram) 779 if (!info->yram)
782 goto emapyram; 780 return -ENOMEM;
783 info->reg = ioremap(res->start + REG_OFFSET, resource_size(res) - 781 info->reg = devm_ioremap(&pdev->dev, res->start + REG_OFFSET,
784 REG_OFFSET); 782 resource_size(res) - REG_OFFSET);
785 if (!info->reg) 783 if (!info->reg)
786 goto emapreg; 784 return -ENOMEM;
787 785
788 dev_set_drvdata(&pdev->dev, info); 786 dev_set_drvdata(&pdev->dev, info);
789 787
790 /* register using ARRAY version so we can keep dai name */ 788 /* register using ARRAY version so we can keep dai name */
791 ret = snd_soc_register_component(&pdev->dev, &siu_i2s_component, 789 ret = devm_snd_soc_register_component(&pdev->dev, &siu_i2s_component,
792 &siu_i2s_dai, 1); 790 &siu_i2s_dai, 1);
793 if (ret < 0) 791 if (ret < 0)
794 goto edaiinit; 792 return ret;
795 793
796 ret = snd_soc_register_platform(&pdev->dev, &siu_platform); 794 ret = devm_snd_soc_register_platform(&pdev->dev, &siu_platform);
797 if (ret < 0) 795 if (ret < 0)
798 goto esocregp; 796 return ret;
799 797
800 pm_runtime_enable(&pdev->dev); 798 pm_runtime_enable(&pdev->dev);
801 799
802 return ret; 800 return 0;
803
804esocregp:
805 snd_soc_unregister_component(&pdev->dev);
806edaiinit:
807 iounmap(info->reg);
808emapreg:
809 iounmap(info->yram);
810emapyram:
811 iounmap(info->xram);
812emapxram:
813 iounmap(info->pram);
814emappram:
815 release_mem_region(res->start, resource_size(res));
816ereqmemreg:
817egetres:
818ereqfw:
819 kfree(info);
820
821 return ret;
822} 801}
823 802
824static int siu_remove(struct platform_device *pdev) 803static int siu_remove(struct platform_device *pdev)
825{ 804{
826 struct siu_info *info = dev_get_drvdata(&pdev->dev);
827 struct resource *res;
828
829 pm_runtime_disable(&pdev->dev); 805 pm_runtime_disable(&pdev->dev);
830
831 snd_soc_unregister_platform(&pdev->dev);
832 snd_soc_unregister_component(&pdev->dev);
833
834 iounmap(info->reg);
835 iounmap(info->yram);
836 iounmap(info->xram);
837 iounmap(info->pram);
838 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
839 if (res)
840 release_mem_region(res->start, resource_size(res));
841 kfree(info);
842
843 return 0; 806 return 0;
844} 807}
845 808
diff --git a/sound/soc/soc-compress.c b/sound/soc/soc-compress.c
index 025c38fbe3c0..12a9820feac1 100644
--- a/sound/soc/soc-compress.c
+++ b/sound/soc/soc-compress.c
@@ -612,8 +612,15 @@ static struct snd_compr_ops soc_compr_dyn_ops = {
612 .get_codec_caps = soc_compr_get_codec_caps 612 .get_codec_caps = soc_compr_get_codec_caps
613}; 613};
614 614
615/* create a new compress */ 615/**
616int soc_new_compress(struct snd_soc_pcm_runtime *rtd, int num) 616 * snd_soc_new_compress - create a new compress.
617 *
618 * @rtd: The runtime for which we will create compress
619 * @num: the device index number (zero based - shared with normal PCMs)
620 *
621 * Return: 0 for success, else error.
622 */
623int snd_soc_new_compress(struct snd_soc_pcm_runtime *rtd, int num)
617{ 624{
618 struct snd_soc_codec *codec = rtd->codec; 625 struct snd_soc_codec *codec = rtd->codec;
619 struct snd_soc_platform *platform = rtd->platform; 626 struct snd_soc_platform *platform = rtd->platform;
@@ -703,3 +710,4 @@ compr_err:
703 kfree(compr); 710 kfree(compr);
704 return ret; 711 return ret;
705} 712}
713EXPORT_SYMBOL_GPL(snd_soc_new_compress);
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index 6173d15236c3..24b096066a07 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -1370,9 +1370,9 @@ static int soc_probe_link_dais(struct snd_soc_card *card, int num, int order)
1370 soc_dpcm_debugfs_add(rtd); 1370 soc_dpcm_debugfs_add(rtd);
1371#endif 1371#endif
1372 1372
1373 if (cpu_dai->driver->compress_dai) { 1373 if (cpu_dai->driver->compress_new) {
1374 /*create compress_device"*/ 1374 /*create compress_device"*/
1375 ret = soc_new_compress(rtd, num); 1375 ret = cpu_dai->driver->compress_new(rtd, num);
1376 if (ret < 0) { 1376 if (ret < 0) {
1377 dev_err(card->dev, "ASoC: can't create compress %s\n", 1377 dev_err(card->dev, "ASoC: can't create compress %s\n",
1378 dai_link->stream_name); 1378 dai_link->stream_name);
@@ -3291,13 +3291,38 @@ int snd_soc_of_parse_audio_simple_widgets(struct snd_soc_card *card,
3291} 3291}
3292EXPORT_SYMBOL_GPL(snd_soc_of_parse_audio_simple_widgets); 3292EXPORT_SYMBOL_GPL(snd_soc_of_parse_audio_simple_widgets);
3293 3293
3294static int snd_soc_of_get_slot_mask(struct device_node *np,
3295 const char *prop_name,
3296 unsigned int *mask)
3297{
3298 u32 val;
3299 const __be32 *of_slot_mask = of_get_property(np, prop_name, &val);
3300 int i;
3301
3302 if (!of_slot_mask)
3303 return 0;
3304 val /= sizeof(u32);
3305 for (i = 0; i < val; i++)
3306 if (be32_to_cpup(&of_slot_mask[i]))
3307 *mask |= (1 << i);
3308
3309 return val;
3310}
3311
3294int snd_soc_of_parse_tdm_slot(struct device_node *np, 3312int snd_soc_of_parse_tdm_slot(struct device_node *np,
3313 unsigned int *tx_mask,
3314 unsigned int *rx_mask,
3295 unsigned int *slots, 3315 unsigned int *slots,
3296 unsigned int *slot_width) 3316 unsigned int *slot_width)
3297{ 3317{
3298 u32 val; 3318 u32 val;
3299 int ret; 3319 int ret;
3300 3320
3321 if (tx_mask)
3322 snd_soc_of_get_slot_mask(np, "dai-tdm-slot-tx-mask", tx_mask);
3323 if (rx_mask)
3324 snd_soc_of_get_slot_mask(np, "dai-tdm-slot-rx-mask", rx_mask);
3325
3301 if (of_property_read_bool(np, "dai-tdm-slot-num")) { 3326 if (of_property_read_bool(np, "dai-tdm-slot-num")) {
3302 ret = of_property_read_u32(np, "dai-tdm-slot-num", &val); 3327 ret = of_property_read_u32(np, "dai-tdm-slot-num", &val);
3303 if (ret) 3328 if (ret)
diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c
index ff8bda471b25..016eba10b1ec 100644
--- a/sound/soc/soc-dapm.c
+++ b/sound/soc/soc-dapm.c
@@ -509,6 +509,18 @@ static bool dapm_kcontrol_set_value(const struct snd_kcontrol *kcontrol,
509} 509}
510 510
511/** 511/**
512 * snd_soc_dapm_kcontrol_widget() - Returns the widget associated to a
513 * kcontrol
514 * @kcontrol: The kcontrol
515 */
516struct snd_soc_dapm_widget *snd_soc_dapm_kcontrol_widget(
517 struct snd_kcontrol *kcontrol)
518{
519 return dapm_kcontrol_get_wlist(kcontrol)->widgets[0];
520}
521EXPORT_SYMBOL_GPL(snd_soc_dapm_kcontrol_widget);
522
523/**
512 * snd_soc_dapm_kcontrol_dapm() - Returns the dapm context associated to a 524 * snd_soc_dapm_kcontrol_dapm() - Returns the dapm context associated to a
513 * kcontrol 525 * kcontrol
514 * @kcontrol: The kcontrol 526 * @kcontrol: The kcontrol
@@ -779,7 +791,7 @@ static int dapm_is_shared_kcontrol(struct snd_soc_dapm_context *dapm,
779 * Determine if a kcontrol is shared. If it is, look it up. If it isn't, 791 * Determine if a kcontrol is shared. If it is, look it up. If it isn't,
780 * create it. Either way, add the widget into the control's widget list 792 * create it. Either way, add the widget into the control's widget list
781 */ 793 */
782static int dapm_create_or_share_mixmux_kcontrol(struct snd_soc_dapm_widget *w, 794static int dapm_create_or_share_kcontrol(struct snd_soc_dapm_widget *w,
783 int kci) 795 int kci)
784{ 796{
785 struct snd_soc_dapm_context *dapm = w->dapm; 797 struct snd_soc_dapm_context *dapm = w->dapm;
@@ -810,6 +822,7 @@ static int dapm_create_or_share_mixmux_kcontrol(struct snd_soc_dapm_widget *w,
810 switch (w->id) { 822 switch (w->id) {
811 case snd_soc_dapm_switch: 823 case snd_soc_dapm_switch:
812 case snd_soc_dapm_mixer: 824 case snd_soc_dapm_mixer:
825 case snd_soc_dapm_pga:
813 wname_in_long_name = true; 826 wname_in_long_name = true;
814 kcname_in_long_name = true; 827 kcname_in_long_name = true;
815 break; 828 break;
@@ -899,7 +912,7 @@ static int dapm_new_mixer(struct snd_soc_dapm_widget *w)
899 continue; 912 continue;
900 913
901 if (!w->kcontrols[i]) { 914 if (!w->kcontrols[i]) {
902 ret = dapm_create_or_share_mixmux_kcontrol(w, i); 915 ret = dapm_create_or_share_kcontrol(w, i);
903 if (ret < 0) 916 if (ret < 0)
904 return ret; 917 return ret;
905 } 918 }
@@ -952,7 +965,7 @@ static int dapm_new_mux(struct snd_soc_dapm_widget *w)
952 return -EINVAL; 965 return -EINVAL;
953 } 966 }
954 967
955 ret = dapm_create_or_share_mixmux_kcontrol(w, 0); 968 ret = dapm_create_or_share_kcontrol(w, 0);
956 if (ret < 0) 969 if (ret < 0)
957 return ret; 970 return ret;
958 971
@@ -967,9 +980,13 @@ static int dapm_new_mux(struct snd_soc_dapm_widget *w)
967/* create new dapm volume control */ 980/* create new dapm volume control */
968static int dapm_new_pga(struct snd_soc_dapm_widget *w) 981static int dapm_new_pga(struct snd_soc_dapm_widget *w)
969{ 982{
970 if (w->num_kcontrols) 983 int i, ret;
971 dev_err(w->dapm->dev, 984
972 "ASoC: PGA controls not supported: '%s'\n", w->name); 985 for (i = 0; i < w->num_kcontrols; i++) {
986 ret = dapm_create_or_share_kcontrol(w, i);
987 if (ret < 0)
988 return ret;
989 }
973 990
974 return 0; 991 return 0;
975} 992}
@@ -3473,11 +3490,29 @@ static int snd_soc_dai_link_event(struct snd_soc_dapm_widget *w,
3473 switch (event) { 3490 switch (event) {
3474 case SND_SOC_DAPM_PRE_PMU: 3491 case SND_SOC_DAPM_PRE_PMU:
3475 substream.stream = SNDRV_PCM_STREAM_CAPTURE; 3492 substream.stream = SNDRV_PCM_STREAM_CAPTURE;
3493 if (source->driver->ops && source->driver->ops->startup) {
3494 ret = source->driver->ops->startup(&substream, source);
3495 if (ret < 0) {
3496 dev_err(source->dev,
3497 "ASoC: startup() failed: %d\n", ret);
3498 goto out;
3499 }
3500 source->active++;
3501 }
3476 ret = soc_dai_hw_params(&substream, params, source); 3502 ret = soc_dai_hw_params(&substream, params, source);
3477 if (ret < 0) 3503 if (ret < 0)
3478 goto out; 3504 goto out;
3479 3505
3480 substream.stream = SNDRV_PCM_STREAM_PLAYBACK; 3506 substream.stream = SNDRV_PCM_STREAM_PLAYBACK;
3507 if (sink->driver->ops && sink->driver->ops->startup) {
3508 ret = sink->driver->ops->startup(&substream, sink);
3509 if (ret < 0) {
3510 dev_err(sink->dev,
3511 "ASoC: startup() failed: %d\n", ret);
3512 goto out;
3513 }
3514 sink->active++;
3515 }
3481 ret = soc_dai_hw_params(&substream, params, sink); 3516 ret = soc_dai_hw_params(&substream, params, sink);
3482 if (ret < 0) 3517 if (ret < 0)
3483 goto out; 3518 goto out;
@@ -3497,6 +3532,18 @@ static int snd_soc_dai_link_event(struct snd_soc_dapm_widget *w,
3497 if (ret != 0 && ret != -ENOTSUPP) 3532 if (ret != 0 && ret != -ENOTSUPP)
3498 dev_warn(sink->dev, "ASoC: Failed to mute: %d\n", ret); 3533 dev_warn(sink->dev, "ASoC: Failed to mute: %d\n", ret);
3499 ret = 0; 3534 ret = 0;
3535
3536 source->active--;
3537 if (source->driver->ops && source->driver->ops->shutdown) {
3538 substream.stream = SNDRV_PCM_STREAM_CAPTURE;
3539 source->driver->ops->shutdown(&substream, source);
3540 }
3541
3542 sink->active--;
3543 if (sink->driver->ops && sink->driver->ops->shutdown) {
3544 substream.stream = SNDRV_PCM_STREAM_PLAYBACK;
3545 sink->driver->ops->shutdown(&substream, sink);
3546 }
3500 break; 3547 break;
3501 3548
3502 default: 3549 default:
diff --git a/sound/soc/soc-ops.c b/sound/soc/soc-ops.c
index 05977ae1ff2a..ecd38e52285a 100644
--- a/sound/soc/soc-ops.c
+++ b/sound/soc/soc-ops.c
@@ -588,16 +588,16 @@ EXPORT_SYMBOL_GPL(snd_soc_get_volsw_range);
588/** 588/**
589 * snd_soc_limit_volume - Set new limit to an existing volume control. 589 * snd_soc_limit_volume - Set new limit to an existing volume control.
590 * 590 *
591 * @codec: where to look for the control 591 * @card: where to look for the control
592 * @name: Name of the control 592 * @name: Name of the control
593 * @max: new maximum limit 593 * @max: new maximum limit
594 * 594 *
595 * Return 0 for success, else error. 595 * Return 0 for success, else error.
596 */ 596 */
597int snd_soc_limit_volume(struct snd_soc_codec *codec, 597int snd_soc_limit_volume(struct snd_soc_card *card,
598 const char *name, int max) 598 const char *name, int max)
599{ 599{
600 struct snd_card *card = codec->component.card->snd_card; 600 struct snd_card *snd_card = card->snd_card;
601 struct snd_kcontrol *kctl; 601 struct snd_kcontrol *kctl;
602 struct soc_mixer_control *mc; 602 struct soc_mixer_control *mc;
603 int found = 0; 603 int found = 0;
@@ -607,7 +607,7 @@ int snd_soc_limit_volume(struct snd_soc_codec *codec,
607 if (unlikely(!name || max <= 0)) 607 if (unlikely(!name || max <= 0))
608 return -EINVAL; 608 return -EINVAL;
609 609
610 list_for_each_entry(kctl, &card->controls, list) { 610 list_for_each_entry(kctl, &snd_card->controls, list) {
611 if (!strncmp(kctl->id.name, name, sizeof(kctl->id.name))) { 611 if (!strncmp(kctl->id.name, name, sizeof(kctl->id.name))) {
612 found = 1; 612 found = 1;
613 break; 613 break;
diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c
index 70e4b9d8bdcd..c86dc96e8986 100644
--- a/sound/soc/soc-pcm.c
+++ b/sound/soc/soc-pcm.c
@@ -34,6 +34,24 @@
34 34
35#define DPCM_MAX_BE_USERS 8 35#define DPCM_MAX_BE_USERS 8
36 36
37/*
38 * snd_soc_dai_stream_valid() - check if a DAI supports the given stream
39 *
40 * Returns true if the DAI supports the indicated stream type.
41 */
42static bool snd_soc_dai_stream_valid(struct snd_soc_dai *dai, int stream)
43{
44 struct snd_soc_pcm_stream *codec_stream;
45
46 if (stream == SNDRV_PCM_STREAM_PLAYBACK)
47 codec_stream = &dai->driver->playback;
48 else
49 codec_stream = &dai->driver->capture;
50
51 /* If the codec specifies any rate at all, it supports the stream. */
52 return codec_stream->rates;
53}
54
37/** 55/**
38 * snd_soc_runtime_activate() - Increment active count for PCM runtime components 56 * snd_soc_runtime_activate() - Increment active count for PCM runtime components
39 * @rtd: ASoC PCM runtime that is activated 57 * @rtd: ASoC PCM runtime that is activated
@@ -182,9 +200,9 @@ static int soc_pcm_apply_symmetry(struct snd_pcm_substream *substream,
182 dev_dbg(soc_dai->dev, "ASoC: Symmetry forces %dHz rate\n", 200 dev_dbg(soc_dai->dev, "ASoC: Symmetry forces %dHz rate\n",
183 soc_dai->rate); 201 soc_dai->rate);
184 202
185 ret = snd_pcm_hw_constraint_minmax(substream->runtime, 203 ret = snd_pcm_hw_constraint_single(substream->runtime,
186 SNDRV_PCM_HW_PARAM_RATE, 204 SNDRV_PCM_HW_PARAM_RATE,
187 soc_dai->rate, soc_dai->rate); 205 soc_dai->rate);
188 if (ret < 0) { 206 if (ret < 0) {
189 dev_err(soc_dai->dev, 207 dev_err(soc_dai->dev,
190 "ASoC: Unable to apply rate constraint: %d\n", 208 "ASoC: Unable to apply rate constraint: %d\n",
@@ -198,9 +216,8 @@ static int soc_pcm_apply_symmetry(struct snd_pcm_substream *substream,
198 dev_dbg(soc_dai->dev, "ASoC: Symmetry forces %d channel(s)\n", 216 dev_dbg(soc_dai->dev, "ASoC: Symmetry forces %d channel(s)\n",
199 soc_dai->channels); 217 soc_dai->channels);
200 218
201 ret = snd_pcm_hw_constraint_minmax(substream->runtime, 219 ret = snd_pcm_hw_constraint_single(substream->runtime,
202 SNDRV_PCM_HW_PARAM_CHANNELS, 220 SNDRV_PCM_HW_PARAM_CHANNELS,
203 soc_dai->channels,
204 soc_dai->channels); 221 soc_dai->channels);
205 if (ret < 0) { 222 if (ret < 0) {
206 dev_err(soc_dai->dev, 223 dev_err(soc_dai->dev,
@@ -215,9 +232,8 @@ static int soc_pcm_apply_symmetry(struct snd_pcm_substream *substream,
215 dev_dbg(soc_dai->dev, "ASoC: Symmetry forces %d sample bits\n", 232 dev_dbg(soc_dai->dev, "ASoC: Symmetry forces %d sample bits\n",
216 soc_dai->sample_bits); 233 soc_dai->sample_bits);
217 234
218 ret = snd_pcm_hw_constraint_minmax(substream->runtime, 235 ret = snd_pcm_hw_constraint_single(substream->runtime,
219 SNDRV_PCM_HW_PARAM_SAMPLE_BITS, 236 SNDRV_PCM_HW_PARAM_SAMPLE_BITS,
220 soc_dai->sample_bits,
221 soc_dai->sample_bits); 237 soc_dai->sample_bits);
222 if (ret < 0) { 238 if (ret < 0) {
223 dev_err(soc_dai->dev, 239 dev_err(soc_dai->dev,
@@ -371,6 +387,20 @@ static void soc_pcm_init_runtime_hw(struct snd_pcm_substream *substream)
371 387
372 /* first calculate min/max only for CODECs in the DAI link */ 388 /* first calculate min/max only for CODECs in the DAI link */
373 for (i = 0; i < rtd->num_codecs; i++) { 389 for (i = 0; i < rtd->num_codecs; i++) {
390
391 /*
392 * Skip CODECs which don't support the current stream type.
393 * Otherwise, since the rate, channel, and format values will
394 * zero in that case, we would have no usable settings left,
395 * causing the resulting setup to fail.
396 * At least one CODEC should match, otherwise we should have
397 * bailed out on a higher level, since there would be no
398 * CODEC to support the transfer direction in that case.
399 */
400 if (!snd_soc_dai_stream_valid(rtd->codec_dais[i],
401 substream->stream))
402 continue;
403
374 codec_dai_drv = rtd->codec_dais[i]->driver; 404 codec_dai_drv = rtd->codec_dais[i]->driver;
375 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 405 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
376 codec_stream = &codec_dai_drv->playback; 406 codec_stream = &codec_dai_drv->playback;
@@ -827,6 +857,23 @@ static int soc_pcm_hw_params(struct snd_pcm_substream *substream,
827 struct snd_soc_dai *codec_dai = rtd->codec_dais[i]; 857 struct snd_soc_dai *codec_dai = rtd->codec_dais[i];
828 struct snd_pcm_hw_params codec_params; 858 struct snd_pcm_hw_params codec_params;
829 859
860 /*
861 * Skip CODECs which don't support the current stream type,
862 * the idea being that if a CODEC is not used for the currently
863 * set up transfer direction, it should not need to be
864 * configured, especially since the configuration used might
865 * not even be supported by that CODEC. There may be cases
866 * however where a CODEC needs to be set up although it is
867 * actually not being used for the transfer, e.g. if a
868 * capture-only CODEC is acting as an LRCLK and/or BCLK master
869 * for the DAI link including a playback-only CODEC.
870 * If this becomes necessary, we will have to augment the
871 * machine driver setup with information on how to act, so
872 * we can do the right thing here.
873 */
874 if (!snd_soc_dai_stream_valid(codec_dai, substream->stream))
875 continue;
876
830 /* copy params for each codec */ 877 /* copy params for each codec */
831 codec_params = *params; 878 codec_params = *params;
832 879
diff --git a/sound/soc/soc-topology.c b/sound/soc/soc-topology.c
index 69d01cd925ce..8d7ec80af51b 100644
--- a/sound/soc/soc-topology.c
+++ b/sound/soc/soc-topology.c
@@ -1558,7 +1558,7 @@ static int soc_tplg_pcm_dai_elems_load(struct soc_tplg *tplg,
1558 pcm_dai = (struct snd_soc_tplg_pcm_dai *)tplg->pos; 1558 pcm_dai = (struct snd_soc_tplg_pcm_dai *)tplg->pos;
1559 1559
1560 if (soc_tplg_check_elem_count(tplg, 1560 if (soc_tplg_check_elem_count(tplg,
1561 sizeof(struct snd_soc_tplg_pcm_dai), count, 1561 sizeof(struct snd_soc_tplg_pcm), count,
1562 hdr->payload_size, "PCM DAI")) { 1562 hdr->payload_size, "PCM DAI")) {
1563 dev_err(tplg->dev, "ASoC: invalid count %d for PCM DAI elems\n", 1563 dev_err(tplg->dev, "ASoC: invalid count %d for PCM DAI elems\n",
1564 count); 1564 count);
@@ -1566,7 +1566,7 @@ static int soc_tplg_pcm_dai_elems_load(struct soc_tplg *tplg,
1566 } 1566 }
1567 1567
1568 dev_dbg(tplg->dev, "ASoC: adding %d PCM DAIs\n", count); 1568 dev_dbg(tplg->dev, "ASoC: adding %d PCM DAIs\n", count);
1569 tplg->pos += sizeof(struct snd_soc_tplg_pcm_dai) * count; 1569 tplg->pos += sizeof(struct snd_soc_tplg_pcm) * count;
1570 1570
1571 dobj = kzalloc(sizeof(struct snd_soc_dobj), GFP_KERNEL); 1571 dobj = kzalloc(sizeof(struct snd_soc_dobj), GFP_KERNEL);
1572 if (dobj == NULL) 1572 if (dobj == NULL)
diff --git a/sound/soc/sunxi/Kconfig b/sound/soc/sunxi/Kconfig
new file mode 100644
index 000000000000..84c72ec6ad73
--- /dev/null
+++ b/sound/soc/sunxi/Kconfig
@@ -0,0 +1,11 @@
1menu "Allwinner SoC Audio support"
2
3config SND_SUN4I_CODEC
4 tristate "Allwinner A10 Codec Support"
5 select SND_SOC_GENERIC_DMAENGINE_PCM
6 select REGMAP_MMIO
7 help
8 Select Y or M to add support for the Codec embedded in the Allwinner
9 A10 and affiliated SoCs.
10
11endmenu
diff --git a/sound/soc/sunxi/Makefile b/sound/soc/sunxi/Makefile
new file mode 100644
index 000000000000..ea8a08c881d6
--- /dev/null
+++ b/sound/soc/sunxi/Makefile
@@ -0,0 +1,2 @@
1obj-$(CONFIG_SND_SUN4I_CODEC) += sun4i-codec.o
2
diff --git a/sound/soc/sunxi/sun4i-codec.c b/sound/soc/sunxi/sun4i-codec.c
new file mode 100644
index 000000000000..bcbf4da168b6
--- /dev/null
+++ b/sound/soc/sunxi/sun4i-codec.c
@@ -0,0 +1,712 @@
1/*
2 * Copyright 2014 Emilio López <emilio@elopez.com.ar>
3 * Copyright 2014 Jon Smirl <jonsmirl@gmail.com>
4 * Copyright 2015 Maxime Ripard <maxime.ripard@free-electrons.com>
5 *
6 * Based on the Allwinner SDK driver, released under the GPL.
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 as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 */
18
19#include <linux/init.h>
20#include <linux/kernel.h>
21#include <linux/module.h>
22#include <linux/platform_device.h>
23#include <linux/delay.h>
24#include <linux/slab.h>
25#include <linux/of.h>
26#include <linux/of_platform.h>
27#include <linux/of_address.h>
28#include <linux/clk.h>
29#include <linux/regmap.h>
30
31#include <sound/core.h>
32#include <sound/pcm.h>
33#include <sound/pcm_params.h>
34#include <sound/soc.h>
35#include <sound/tlv.h>
36#include <sound/initval.h>
37#include <sound/dmaengine_pcm.h>
38
39/* Codec DAC register offsets and bit fields */
40#define SUN4I_CODEC_DAC_DPC (0x00)
41#define SUN4I_CODEC_DAC_DPC_EN_DA (31)
42#define SUN4I_CODEC_DAC_DPC_DVOL (12)
43#define SUN4I_CODEC_DAC_FIFOC (0x04)
44#define SUN4I_CODEC_DAC_FIFOC_DAC_FS (29)
45#define SUN4I_CODEC_DAC_FIFOC_FIR_VERSION (28)
46#define SUN4I_CODEC_DAC_FIFOC_SEND_LASAT (26)
47#define SUN4I_CODEC_DAC_FIFOC_TX_FIFO_MODE (24)
48#define SUN4I_CODEC_DAC_FIFOC_DRQ_CLR_CNT (21)
49#define SUN4I_CODEC_DAC_FIFOC_TX_TRIG_LEVEL (8)
50#define SUN4I_CODEC_DAC_FIFOC_MONO_EN (6)
51#define SUN4I_CODEC_DAC_FIFOC_TX_SAMPLE_BITS (5)
52#define SUN4I_CODEC_DAC_FIFOC_DAC_DRQ_EN (4)
53#define SUN4I_CODEC_DAC_FIFOC_FIFO_FLUSH (0)
54#define SUN4I_CODEC_DAC_FIFOS (0x08)
55#define SUN4I_CODEC_DAC_TXDATA (0x0c)
56#define SUN4I_CODEC_DAC_ACTL (0x10)
57#define SUN4I_CODEC_DAC_ACTL_DACAENR (31)
58#define SUN4I_CODEC_DAC_ACTL_DACAENL (30)
59#define SUN4I_CODEC_DAC_ACTL_MIXEN (29)
60#define SUN4I_CODEC_DAC_ACTL_LDACLMIXS (15)
61#define SUN4I_CODEC_DAC_ACTL_RDACRMIXS (14)
62#define SUN4I_CODEC_DAC_ACTL_LDACRMIXS (13)
63#define SUN4I_CODEC_DAC_ACTL_DACPAS (8)
64#define SUN4I_CODEC_DAC_ACTL_MIXPAS (7)
65#define SUN4I_CODEC_DAC_ACTL_PA_MUTE (6)
66#define SUN4I_CODEC_DAC_ACTL_PA_VOL (0)
67#define SUN4I_CODEC_DAC_TUNE (0x14)
68#define SUN4I_CODEC_DAC_DEBUG (0x18)
69
70/* Codec ADC register offsets and bit fields */
71#define SUN4I_CODEC_ADC_FIFOC (0x1c)
72#define SUN4I_CODEC_ADC_FIFOC_EN_AD (28)
73#define SUN4I_CODEC_ADC_FIFOC_RX_FIFO_MODE (24)
74#define SUN4I_CODEC_ADC_FIFOC_RX_TRIG_LEVEL (8)
75#define SUN4I_CODEC_ADC_FIFOC_MONO_EN (7)
76#define SUN4I_CODEC_ADC_FIFOC_RX_SAMPLE_BITS (6)
77#define SUN4I_CODEC_ADC_FIFOC_ADC_DRQ_EN (4)
78#define SUN4I_CODEC_ADC_FIFOC_FIFO_FLUSH (0)
79#define SUN4I_CODEC_ADC_FIFOS (0x20)
80#define SUN4I_CODEC_ADC_RXDATA (0x24)
81#define SUN4I_CODEC_ADC_ACTL (0x28)
82#define SUN4I_CODEC_ADC_ACTL_ADC_R_EN (31)
83#define SUN4I_CODEC_ADC_ACTL_ADC_L_EN (30)
84#define SUN4I_CODEC_ADC_ACTL_PREG1EN (29)
85#define SUN4I_CODEC_ADC_ACTL_PREG2EN (28)
86#define SUN4I_CODEC_ADC_ACTL_VMICEN (27)
87#define SUN4I_CODEC_ADC_ACTL_VADCG (20)
88#define SUN4I_CODEC_ADC_ACTL_ADCIS (17)
89#define SUN4I_CODEC_ADC_ACTL_PA_EN (4)
90#define SUN4I_CODEC_ADC_ACTL_DDE (3)
91#define SUN4I_CODEC_ADC_DEBUG (0x2c)
92
93/* Other various ADC registers */
94#define SUN4I_CODEC_DAC_TXCNT (0x30)
95#define SUN4I_CODEC_ADC_RXCNT (0x34)
96#define SUN4I_CODEC_AC_SYS_VERI (0x38)
97#define SUN4I_CODEC_AC_MIC_PHONE_CAL (0x3c)
98
99struct sun4i_codec {
100 struct device *dev;
101 struct regmap *regmap;
102 struct clk *clk_apb;
103 struct clk *clk_module;
104
105 struct snd_dmaengine_dai_dma_data playback_dma_data;
106};
107
108static void sun4i_codec_start_playback(struct sun4i_codec *scodec)
109{
110 /*
111 * FIXME: according to the BSP, we might need to drive a PA
112 * GPIO high here on some boards
113 */
114
115 /* Flush TX FIFO */
116 regmap_update_bits(scodec->regmap, SUN4I_CODEC_DAC_FIFOC,
117 BIT(SUN4I_CODEC_DAC_FIFOC_FIFO_FLUSH),
118 BIT(SUN4I_CODEC_DAC_FIFOC_FIFO_FLUSH));
119
120 /* Enable DAC DRQ */
121 regmap_update_bits(scodec->regmap, SUN4I_CODEC_DAC_FIFOC,
122 BIT(SUN4I_CODEC_DAC_FIFOC_DAC_DRQ_EN),
123 BIT(SUN4I_CODEC_DAC_FIFOC_DAC_DRQ_EN));
124}
125
126static void sun4i_codec_stop_playback(struct sun4i_codec *scodec)
127{
128 /*
129 * FIXME: according to the BSP, we might need to drive a PA
130 * GPIO low here on some boards
131 */
132
133 /* Disable DAC DRQ */
134 regmap_update_bits(scodec->regmap, SUN4I_CODEC_DAC_FIFOC,
135 BIT(SUN4I_CODEC_DAC_FIFOC_DAC_DRQ_EN),
136 0);
137}
138
139static int sun4i_codec_trigger(struct snd_pcm_substream *substream, int cmd,
140 struct snd_soc_dai *dai)
141{
142 struct snd_soc_pcm_runtime *rtd = substream->private_data;
143 struct sun4i_codec *scodec = snd_soc_card_get_drvdata(rtd->card);
144
145 if (substream->stream != SNDRV_PCM_STREAM_PLAYBACK)
146 return -ENOTSUPP;
147
148 switch (cmd) {
149 case SNDRV_PCM_TRIGGER_START:
150 case SNDRV_PCM_TRIGGER_RESUME:
151 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
152 sun4i_codec_start_playback(scodec);
153 break;
154
155 case SNDRV_PCM_TRIGGER_STOP:
156 case SNDRV_PCM_TRIGGER_SUSPEND:
157 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
158 sun4i_codec_stop_playback(scodec);
159 break;
160
161 default:
162 return -EINVAL;
163 }
164
165 return 0;
166}
167
168static int sun4i_codec_prepare(struct snd_pcm_substream *substream,
169 struct snd_soc_dai *dai)
170{
171 struct snd_soc_pcm_runtime *rtd = substream->private_data;
172 struct sun4i_codec *scodec = snd_soc_card_get_drvdata(rtd->card);
173 u32 val;
174
175 if (substream->stream != SNDRV_PCM_STREAM_PLAYBACK)
176 return -ENOTSUPP;
177
178 /* Flush the TX FIFO */
179 regmap_update_bits(scodec->regmap, SUN4I_CODEC_DAC_FIFOC,
180 BIT(SUN4I_CODEC_DAC_FIFOC_FIFO_FLUSH),
181 BIT(SUN4I_CODEC_DAC_FIFOC_FIFO_FLUSH));
182
183 /* Set TX FIFO Empty Trigger Level */
184 regmap_update_bits(scodec->regmap, SUN4I_CODEC_DAC_FIFOC,
185 0x3f << SUN4I_CODEC_DAC_FIFOC_TX_TRIG_LEVEL,
186 0xf << SUN4I_CODEC_DAC_FIFOC_TX_TRIG_LEVEL);
187
188 if (substream->runtime->rate > 32000)
189 /* Use 64 bits FIR filter */
190 val = 0;
191 else
192 /* Use 32 bits FIR filter */
193 val = BIT(SUN4I_CODEC_DAC_FIFOC_FIR_VERSION);
194
195 regmap_update_bits(scodec->regmap, SUN4I_CODEC_DAC_FIFOC,
196 BIT(SUN4I_CODEC_DAC_FIFOC_FIR_VERSION),
197 val);
198
199 /* Send zeros when we have an underrun */
200 regmap_update_bits(scodec->regmap, SUN4I_CODEC_DAC_FIFOC,
201 BIT(SUN4I_CODEC_DAC_FIFOC_SEND_LASAT),
202 0);
203
204 return 0;
205}
206
207static unsigned long sun4i_codec_get_mod_freq(struct snd_pcm_hw_params *params)
208{
209 unsigned int rate = params_rate(params);
210
211 switch (rate) {
212 case 176400:
213 case 88200:
214 case 44100:
215 case 33075:
216 case 22050:
217 case 14700:
218 case 11025:
219 case 7350:
220 return 22579200;
221
222 case 192000:
223 case 96000:
224 case 48000:
225 case 32000:
226 case 24000:
227 case 16000:
228 case 12000:
229 case 8000:
230 return 24576000;
231
232 default:
233 return 0;
234 }
235}
236
237static int sun4i_codec_get_hw_rate(struct snd_pcm_hw_params *params)
238{
239 unsigned int rate = params_rate(params);
240
241 switch (rate) {
242 case 192000:
243 case 176400:
244 return 6;
245
246 case 96000:
247 case 88200:
248 return 7;
249
250 case 48000:
251 case 44100:
252 return 0;
253
254 case 32000:
255 case 33075:
256 return 1;
257
258 case 24000:
259 case 22050:
260 return 2;
261
262 case 16000:
263 case 14700:
264 return 3;
265
266 case 12000:
267 case 11025:
268 return 4;
269
270 case 8000:
271 case 7350:
272 return 5;
273
274 default:
275 return -EINVAL;
276 }
277}
278
279static int sun4i_codec_hw_params(struct snd_pcm_substream *substream,
280 struct snd_pcm_hw_params *params,
281 struct snd_soc_dai *dai)
282{
283 struct snd_soc_pcm_runtime *rtd = substream->private_data;
284 struct sun4i_codec *scodec = snd_soc_card_get_drvdata(rtd->card);
285 unsigned long clk_freq;
286 int ret, hwrate;
287 u32 val;
288
289 if (substream->stream != SNDRV_PCM_STREAM_PLAYBACK)
290 return -ENOTSUPP;
291
292 clk_freq = sun4i_codec_get_mod_freq(params);
293 if (!clk_freq)
294 return -EINVAL;
295
296 ret = clk_set_rate(scodec->clk_module, clk_freq);
297 if (ret)
298 return ret;
299
300 hwrate = sun4i_codec_get_hw_rate(params);
301 if (hwrate < 0)
302 return hwrate;
303
304 /* Set DAC sample rate */
305 regmap_update_bits(scodec->regmap, SUN4I_CODEC_DAC_FIFOC,
306 7 << SUN4I_CODEC_DAC_FIFOC_DAC_FS,
307 hwrate << SUN4I_CODEC_DAC_FIFOC_DAC_FS);
308
309 /* Set the number of channels we want to use */
310 if (params_channels(params) == 1)
311 val = BIT(SUN4I_CODEC_DAC_FIFOC_MONO_EN);
312 else
313 val = 0;
314
315 regmap_update_bits(scodec->regmap, SUN4I_CODEC_DAC_FIFOC,
316 BIT(SUN4I_CODEC_DAC_FIFOC_MONO_EN),
317 val);
318
319 /* Set the number of sample bits to either 16 or 24 bits */
320 if (hw_param_interval(params, SNDRV_PCM_HW_PARAM_SAMPLE_BITS)->min == 32) {
321 regmap_update_bits(scodec->regmap, SUN4I_CODEC_DAC_FIFOC,
322 BIT(SUN4I_CODEC_DAC_FIFOC_TX_SAMPLE_BITS),
323 BIT(SUN4I_CODEC_DAC_FIFOC_TX_SAMPLE_BITS));
324
325 /* Set TX FIFO mode to padding the LSBs with 0 */
326 regmap_update_bits(scodec->regmap, SUN4I_CODEC_DAC_FIFOC,
327 BIT(SUN4I_CODEC_DAC_FIFOC_TX_FIFO_MODE),
328 0);
329
330 scodec->playback_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
331 } else {
332 regmap_update_bits(scodec->regmap, SUN4I_CODEC_DAC_FIFOC,
333 BIT(SUN4I_CODEC_DAC_FIFOC_TX_SAMPLE_BITS),
334 0);
335
336 /* Set TX FIFO mode to repeat the MSB */
337 regmap_update_bits(scodec->regmap, SUN4I_CODEC_DAC_FIFOC,
338 BIT(SUN4I_CODEC_DAC_FIFOC_TX_FIFO_MODE),
339 BIT(SUN4I_CODEC_DAC_FIFOC_TX_FIFO_MODE));
340
341 scodec->playback_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES;
342 }
343
344 return 0;
345}
346
347static int sun4i_codec_startup(struct snd_pcm_substream *substream,
348 struct snd_soc_dai *dai)
349{
350 struct snd_soc_pcm_runtime *rtd = substream->private_data;
351 struct sun4i_codec *scodec = snd_soc_card_get_drvdata(rtd->card);
352
353 /*
354 * Stop issuing DRQ when we have room for less than 16 samples
355 * in our TX FIFO
356 */
357 regmap_update_bits(scodec->regmap, SUN4I_CODEC_DAC_FIFOC,
358 3 << SUN4I_CODEC_DAC_FIFOC_DRQ_CLR_CNT,
359 3 << SUN4I_CODEC_DAC_FIFOC_DRQ_CLR_CNT);
360
361 return clk_prepare_enable(scodec->clk_module);
362}
363
364static void sun4i_codec_shutdown(struct snd_pcm_substream *substream,
365 struct snd_soc_dai *dai)
366{
367 struct snd_soc_pcm_runtime *rtd = substream->private_data;
368 struct sun4i_codec *scodec = snd_soc_card_get_drvdata(rtd->card);
369
370 clk_disable_unprepare(scodec->clk_module);
371}
372
373static const struct snd_soc_dai_ops sun4i_codec_dai_ops = {
374 .startup = sun4i_codec_startup,
375 .shutdown = sun4i_codec_shutdown,
376 .trigger = sun4i_codec_trigger,
377 .hw_params = sun4i_codec_hw_params,
378 .prepare = sun4i_codec_prepare,
379};
380
381static struct snd_soc_dai_driver sun4i_codec_dai = {
382 .name = "Codec",
383 .ops = &sun4i_codec_dai_ops,
384 .playback = {
385 .stream_name = "Codec Playback",
386 .channels_min = 1,
387 .channels_max = 2,
388 .rate_min = 8000,
389 .rate_max = 192000,
390 .rates = SNDRV_PCM_RATE_8000_48000 |
391 SNDRV_PCM_RATE_96000 |
392 SNDRV_PCM_RATE_192000,
393 .formats = SNDRV_PCM_FMTBIT_S16_LE |
394 SNDRV_PCM_FMTBIT_S32_LE,
395 .sig_bits = 24,
396 },
397};
398
399/*** Codec ***/
400static const struct snd_kcontrol_new sun4i_codec_pa_mute =
401 SOC_DAPM_SINGLE("Switch", SUN4I_CODEC_DAC_ACTL,
402 SUN4I_CODEC_DAC_ACTL_PA_MUTE, 1, 0);
403
404static DECLARE_TLV_DB_SCALE(sun4i_codec_pa_volume_scale, -6300, 100, 1);
405
406static const struct snd_kcontrol_new sun4i_codec_widgets[] = {
407 SOC_SINGLE_TLV("PA Volume", SUN4I_CODEC_DAC_ACTL,
408 SUN4I_CODEC_DAC_ACTL_PA_VOL, 0x3F, 0,
409 sun4i_codec_pa_volume_scale),
410};
411
412static const struct snd_kcontrol_new sun4i_codec_left_mixer_controls[] = {
413 SOC_DAPM_SINGLE("Left DAC Playback Switch", SUN4I_CODEC_DAC_ACTL,
414 SUN4I_CODEC_DAC_ACTL_LDACLMIXS, 1, 0),
415};
416
417static const struct snd_kcontrol_new sun4i_codec_right_mixer_controls[] = {
418 SOC_DAPM_SINGLE("Right DAC Playback Switch", SUN4I_CODEC_DAC_ACTL,
419 SUN4I_CODEC_DAC_ACTL_RDACRMIXS, 1, 0),
420 SOC_DAPM_SINGLE("Left DAC Playback Switch", SUN4I_CODEC_DAC_ACTL,
421 SUN4I_CODEC_DAC_ACTL_LDACRMIXS, 1, 0),
422};
423
424static const struct snd_kcontrol_new sun4i_codec_pa_mixer_controls[] = {
425 SOC_DAPM_SINGLE("DAC Playback Switch", SUN4I_CODEC_DAC_ACTL,
426 SUN4I_CODEC_DAC_ACTL_DACPAS, 1, 0),
427 SOC_DAPM_SINGLE("Mixer Playback Switch", SUN4I_CODEC_DAC_ACTL,
428 SUN4I_CODEC_DAC_ACTL_MIXPAS, 1, 0),
429};
430
431static const struct snd_soc_dapm_widget sun4i_codec_dapm_widgets[] = {
432 /* Digital parts of the DACs */
433 SND_SOC_DAPM_SUPPLY("DAC", SUN4I_CODEC_DAC_DPC,
434 SUN4I_CODEC_DAC_DPC_EN_DA, 0,
435 NULL, 0),
436
437 /* Analog parts of the DACs */
438 SND_SOC_DAPM_DAC("Left DAC", "Codec Playback", SUN4I_CODEC_DAC_ACTL,
439 SUN4I_CODEC_DAC_ACTL_DACAENL, 0),
440 SND_SOC_DAPM_DAC("Right DAC", "Codec Playback", SUN4I_CODEC_DAC_ACTL,
441 SUN4I_CODEC_DAC_ACTL_DACAENR, 0),
442
443 /* Mixers */
444 SND_SOC_DAPM_MIXER("Left Mixer", SND_SOC_NOPM, 0, 0,
445 sun4i_codec_left_mixer_controls,
446 ARRAY_SIZE(sun4i_codec_left_mixer_controls)),
447 SND_SOC_DAPM_MIXER("Right Mixer", SND_SOC_NOPM, 0, 0,
448 sun4i_codec_right_mixer_controls,
449 ARRAY_SIZE(sun4i_codec_right_mixer_controls)),
450
451 /* Global Mixer Enable */
452 SND_SOC_DAPM_SUPPLY("Mixer Enable", SUN4I_CODEC_DAC_ACTL,
453 SUN4I_CODEC_DAC_ACTL_MIXEN, 0, NULL, 0),
454
455 /* Pre-Amplifier */
456 SND_SOC_DAPM_MIXER("Pre-Amplifier", SUN4I_CODEC_ADC_ACTL,
457 SUN4I_CODEC_ADC_ACTL_PA_EN, 0,
458 sun4i_codec_pa_mixer_controls,
459 ARRAY_SIZE(sun4i_codec_pa_mixer_controls)),
460 SND_SOC_DAPM_SWITCH("Pre-Amplifier Mute", SND_SOC_NOPM, 0, 0,
461 &sun4i_codec_pa_mute),
462
463 SND_SOC_DAPM_OUTPUT("HP Right"),
464 SND_SOC_DAPM_OUTPUT("HP Left"),
465};
466
467static const struct snd_soc_dapm_route sun4i_codec_dapm_routes[] = {
468 /* Left DAC Routes */
469 { "Left DAC", NULL, "DAC" },
470
471 /* Right DAC Routes */
472 { "Right DAC", NULL, "DAC" },
473
474 /* Right Mixer Routes */
475 { "Right Mixer", NULL, "Mixer Enable" },
476 { "Right Mixer", "Left DAC Playback Switch", "Left DAC" },
477 { "Right Mixer", "Right DAC Playback Switch", "Right DAC" },
478
479 /* Left Mixer Routes */
480 { "Left Mixer", NULL, "Mixer Enable" },
481 { "Left Mixer", "Left DAC Playback Switch", "Left DAC" },
482
483 /* Pre-Amplifier Mixer Routes */
484 { "Pre-Amplifier", "Mixer Playback Switch", "Left Mixer" },
485 { "Pre-Amplifier", "Mixer Playback Switch", "Right Mixer" },
486 { "Pre-Amplifier", "DAC Playback Switch", "Left DAC" },
487 { "Pre-Amplifier", "DAC Playback Switch", "Right DAC" },
488
489 /* PA -> HP path */
490 { "Pre-Amplifier Mute", "Switch", "Pre-Amplifier" },
491 { "HP Right", NULL, "Pre-Amplifier Mute" },
492 { "HP Left", NULL, "Pre-Amplifier Mute" },
493};
494
495static struct snd_soc_codec_driver sun4i_codec_codec = {
496 .controls = sun4i_codec_widgets,
497 .num_controls = ARRAY_SIZE(sun4i_codec_widgets),
498 .dapm_widgets = sun4i_codec_dapm_widgets,
499 .num_dapm_widgets = ARRAY_SIZE(sun4i_codec_dapm_widgets),
500 .dapm_routes = sun4i_codec_dapm_routes,
501 .num_dapm_routes = ARRAY_SIZE(sun4i_codec_dapm_routes),
502};
503
504static const struct snd_soc_component_driver sun4i_codec_component = {
505 .name = "sun4i-codec",
506};
507
508#define SUN4I_CODEC_RATES SNDRV_PCM_RATE_8000_192000
509#define SUN4I_CODEC_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | \
510 SNDRV_PCM_FMTBIT_S32_LE)
511
512static int sun4i_codec_dai_probe(struct snd_soc_dai *dai)
513{
514 struct snd_soc_card *card = snd_soc_dai_get_drvdata(dai);
515 struct sun4i_codec *scodec = snd_soc_card_get_drvdata(card);
516
517 snd_soc_dai_init_dma_data(dai, &scodec->playback_dma_data,
518 NULL);
519
520 return 0;
521}
522
523static struct snd_soc_dai_driver dummy_cpu_dai = {
524 .name = "sun4i-codec-cpu-dai",
525 .probe = sun4i_codec_dai_probe,
526 .playback = {
527 .stream_name = "Playback",
528 .channels_min = 1,
529 .channels_max = 2,
530 .rates = SUN4I_CODEC_RATES,
531 .formats = SUN4I_CODEC_FORMATS,
532 .sig_bits = 24,
533 },
534};
535
536static const struct regmap_config sun4i_codec_regmap_config = {
537 .reg_bits = 32,
538 .reg_stride = 4,
539 .val_bits = 32,
540 .max_register = SUN4I_CODEC_AC_MIC_PHONE_CAL,
541};
542
543static const struct of_device_id sun4i_codec_of_match[] = {
544 { .compatible = "allwinner,sun4i-a10-codec" },
545 { .compatible = "allwinner,sun7i-a20-codec" },
546 {}
547};
548MODULE_DEVICE_TABLE(of, sun4i_codec_of_match);
549
550static struct snd_soc_dai_link *sun4i_codec_create_link(struct device *dev,
551 int *num_links)
552{
553 struct snd_soc_dai_link *link = devm_kzalloc(dev, sizeof(*link),
554 GFP_KERNEL);
555 if (!link)
556 return NULL;
557
558 link->name = "cdc";
559 link->stream_name = "CDC PCM";
560 link->codec_dai_name = "Codec";
561 link->cpu_dai_name = dev_name(dev);
562 link->codec_name = dev_name(dev);
563 link->platform_name = dev_name(dev);
564 link->dai_fmt = SND_SOC_DAIFMT_I2S;
565
566 *num_links = 1;
567
568 return link;
569};
570
571static struct snd_soc_card *sun4i_codec_create_card(struct device *dev)
572{
573 struct snd_soc_card *card;
574
575 card = devm_kzalloc(dev, sizeof(*card), GFP_KERNEL);
576 if (!card)
577 return NULL;
578
579 card->dai_link = sun4i_codec_create_link(dev, &card->num_links);
580 if (!card->dai_link)
581 return NULL;
582
583 card->dev = dev;
584 card->name = "sun4i-codec";
585
586 return card;
587};
588
589static int sun4i_codec_probe(struct platform_device *pdev)
590{
591 struct snd_soc_card *card;
592 struct sun4i_codec *scodec;
593 struct resource *res;
594 void __iomem *base;
595 int ret;
596
597 scodec = devm_kzalloc(&pdev->dev, sizeof(*scodec), GFP_KERNEL);
598 if (!scodec)
599 return -ENOMEM;
600
601 scodec->dev = &pdev->dev;
602
603 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
604 base = devm_ioremap_resource(&pdev->dev, res);
605 if (IS_ERR(base)) {
606 dev_err(&pdev->dev, "Failed to map the registers\n");
607 return PTR_ERR(base);
608 }
609
610 scodec->regmap = devm_regmap_init_mmio(&pdev->dev, base,
611 &sun4i_codec_regmap_config);
612 if (IS_ERR(scodec->regmap)) {
613 dev_err(&pdev->dev, "Failed to create our regmap\n");
614 return PTR_ERR(scodec->regmap);
615 }
616
617 /* Get the clocks from the DT */
618 scodec->clk_apb = devm_clk_get(&pdev->dev, "apb");
619 if (IS_ERR(scodec->clk_apb)) {
620 dev_err(&pdev->dev, "Failed to get the APB clock\n");
621 return PTR_ERR(scodec->clk_apb);
622 }
623
624 scodec->clk_module = devm_clk_get(&pdev->dev, "codec");
625 if (IS_ERR(scodec->clk_module)) {
626 dev_err(&pdev->dev, "Failed to get the module clock\n");
627 return PTR_ERR(scodec->clk_module);
628 }
629
630 /* Enable the bus clock */
631 if (clk_prepare_enable(scodec->clk_apb)) {
632 dev_err(&pdev->dev, "Failed to enable the APB clock\n");
633 return -EINVAL;
634 }
635
636 /* DMA configuration for TX FIFO */
637 scodec->playback_dma_data.addr = res->start + SUN4I_CODEC_DAC_TXDATA;
638 scodec->playback_dma_data.maxburst = 4;
639 scodec->playback_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES;
640
641 ret = snd_soc_register_codec(&pdev->dev, &sun4i_codec_codec,
642 &sun4i_codec_dai, 1);
643 if (ret) {
644 dev_err(&pdev->dev, "Failed to register our codec\n");
645 goto err_clk_disable;
646 }
647
648 ret = devm_snd_soc_register_component(&pdev->dev,
649 &sun4i_codec_component,
650 &dummy_cpu_dai, 1);
651 if (ret) {
652 dev_err(&pdev->dev, "Failed to register our DAI\n");
653 goto err_unregister_codec;
654 }
655
656 ret = devm_snd_dmaengine_pcm_register(&pdev->dev, NULL, 0);
657 if (ret) {
658 dev_err(&pdev->dev, "Failed to register against DMAEngine\n");
659 goto err_unregister_codec;
660 }
661
662 card = sun4i_codec_create_card(&pdev->dev);
663 if (!card) {
664 dev_err(&pdev->dev, "Failed to create our card\n");
665 goto err_unregister_codec;
666 }
667
668 platform_set_drvdata(pdev, card);
669 snd_soc_card_set_drvdata(card, scodec);
670
671 ret = snd_soc_register_card(card);
672 if (ret) {
673 dev_err(&pdev->dev, "Failed to register our card\n");
674 goto err_unregister_codec;
675 }
676
677 return 0;
678
679err_unregister_codec:
680 snd_soc_unregister_codec(&pdev->dev);
681err_clk_disable:
682 clk_disable_unprepare(scodec->clk_apb);
683 return ret;
684}
685
686static int sun4i_codec_remove(struct platform_device *pdev)
687{
688 struct snd_soc_card *card = platform_get_drvdata(pdev);
689 struct sun4i_codec *scodec = snd_soc_card_get_drvdata(card);
690
691 snd_soc_unregister_card(card);
692 snd_soc_unregister_codec(&pdev->dev);
693 clk_disable_unprepare(scodec->clk_apb);
694
695 return 0;
696}
697
698static struct platform_driver sun4i_codec_driver = {
699 .driver = {
700 .name = "sun4i-codec",
701 .of_match_table = sun4i_codec_of_match,
702 },
703 .probe = sun4i_codec_probe,
704 .remove = sun4i_codec_remove,
705};
706module_platform_driver(sun4i_codec_driver);
707
708MODULE_DESCRIPTION("Allwinner A10 codec driver");
709MODULE_AUTHOR("Emilio López <emilio@elopez.com.ar>");
710MODULE_AUTHOR("Jon Smirl <jonsmirl@gmail.com>");
711MODULE_AUTHOR("Maxime Ripard <maxime.ripard@free-electrons.com>");
712MODULE_LICENSE("GPL");
diff --git a/sound/soc/ux500/mop500.c b/sound/soc/ux500/mop500.c
index 4e0c0e502ade..ba9fc099cf67 100644
--- a/sound/soc/ux500/mop500.c
+++ b/sound/soc/ux500/mop500.c
@@ -152,6 +152,7 @@ static const struct of_device_id snd_soc_mop500_match[] = {
152 { .compatible = "stericsson,snd-soc-mop500", }, 152 { .compatible = "stericsson,snd-soc-mop500", },
153 {}, 153 {},
154}; 154};
155MODULE_DEVICE_TABLE(of, snd_soc_mop500_match);
155 156
156static struct platform_driver snd_soc_mop500_driver = { 157static struct platform_driver snd_soc_mop500_driver = {
157 .driver = { 158 .driver = {
diff --git a/sound/soc/ux500/ux500_msp_dai.c b/sound/soc/ux500/ux500_msp_dai.c
index f5df08ded770..6d5698b25bd4 100644
--- a/sound/soc/ux500/ux500_msp_dai.c
+++ b/sound/soc/ux500/ux500_msp_dai.c
@@ -522,9 +522,9 @@ static int ux500_msp_dai_hw_params(struct snd_pcm_substream *substream,
522 slots_active = hweight32(mask); 522 slots_active = hweight32(mask);
523 dev_dbg(dai->dev, "TDM-slots active: %d", slots_active); 523 dev_dbg(dai->dev, "TDM-slots active: %d", slots_active);
524 524
525 snd_pcm_hw_constraint_minmax(runtime, 525 snd_pcm_hw_constraint_single(runtime,
526 SNDRV_PCM_HW_PARAM_CHANNELS, 526 SNDRV_PCM_HW_PARAM_CHANNELS,
527 slots_active, slots_active); 527 slots_active);
528 break; 528 break;
529 529
530 default: 530 default:
@@ -843,6 +843,7 @@ static const struct of_device_id ux500_msp_i2s_match[] = {
843 { .compatible = "stericsson,ux500-msp-i2s", }, 843 { .compatible = "stericsson,ux500-msp-i2s", },
844 {}, 844 {},
845}; 845};
846MODULE_DEVICE_TABLE(of, ux500_msp_i2s_match);
846 847
847static struct platform_driver msp_i2s_driver = { 848static struct platform_driver msp_i2s_driver = {
848 .driver = { 849 .driver = {
diff --git a/sound/usb/card.h b/sound/usb/card.h
index ef580b43f1e3..71778ca4b26a 100644
--- a/sound/usb/card.h
+++ b/sound/usb/card.h
@@ -122,6 +122,7 @@ struct snd_usb_substream {
122 unsigned int buffer_periods; /* current periods per buffer */ 122 unsigned int buffer_periods; /* current periods per buffer */
123 unsigned int altset_idx; /* USB data format: index of alternate setting */ 123 unsigned int altset_idx; /* USB data format: index of alternate setting */
124 unsigned int txfr_quirk:1; /* allow sub-frame alignment */ 124 unsigned int txfr_quirk:1; /* allow sub-frame alignment */
125 unsigned int tx_length_quirk:1; /* add length specifier to transfers */
125 unsigned int fmt_type; /* USB audio format type (1-3) */ 126 unsigned int fmt_type; /* USB audio format type (1-3) */
126 unsigned int pkt_offset_adj; /* Bytes to drop from beginning of packets (for non-compliant devices) */ 127 unsigned int pkt_offset_adj; /* Bytes to drop from beginning of packets (for non-compliant devices) */
127 128
diff --git a/sound/usb/endpoint.c b/sound/usb/endpoint.c
index e6f71894ecdc..7b1cb365ffab 100644
--- a/sound/usb/endpoint.c
+++ b/sound/usb/endpoint.c
@@ -183,13 +183,53 @@ static void retire_inbound_urb(struct snd_usb_endpoint *ep,
183 ep->retire_data_urb(ep->data_subs, urb); 183 ep->retire_data_urb(ep->data_subs, urb);
184} 184}
185 185
186static void prepare_silent_urb(struct snd_usb_endpoint *ep,
187 struct snd_urb_ctx *ctx)
188{
189 struct urb *urb = ctx->urb;
190 unsigned int offs = 0;
191 unsigned int extra = 0;
192 __le32 packet_length;
193 int i;
194
195 /* For tx_length_quirk, put packet length at start of packet */
196 if (ep->chip->tx_length_quirk)
197 extra = sizeof(packet_length);
198
199 for (i = 0; i < ctx->packets; ++i) {
200 unsigned int offset;
201 unsigned int length;
202 int counts;
203
204 if (ctx->packet_size[i])
205 counts = ctx->packet_size[i];
206 else
207 counts = snd_usb_endpoint_next_packet_size(ep);
208
209 length = counts * ep->stride; /* number of silent bytes */
210 offset = offs * ep->stride + extra * i;
211 urb->iso_frame_desc[i].offset = offset;
212 urb->iso_frame_desc[i].length = length + extra;
213 if (extra) {
214 packet_length = cpu_to_le32(length);
215 memcpy(urb->transfer_buffer + offset,
216 &packet_length, sizeof(packet_length));
217 }
218 memset(urb->transfer_buffer + offset + extra,
219 ep->silence_value, length);
220 offs += counts;
221 }
222
223 urb->number_of_packets = ctx->packets;
224 urb->transfer_buffer_length = offs * ep->stride + ctx->packets * extra;
225}
226
186/* 227/*
187 * Prepare a PLAYBACK urb for submission to the bus. 228 * Prepare a PLAYBACK urb for submission to the bus.
188 */ 229 */
189static void prepare_outbound_urb(struct snd_usb_endpoint *ep, 230static void prepare_outbound_urb(struct snd_usb_endpoint *ep,
190 struct snd_urb_ctx *ctx) 231 struct snd_urb_ctx *ctx)
191{ 232{
192 int i;
193 struct urb *urb = ctx->urb; 233 struct urb *urb = ctx->urb;
194 unsigned char *cp = urb->transfer_buffer; 234 unsigned char *cp = urb->transfer_buffer;
195 235
@@ -201,24 +241,7 @@ static void prepare_outbound_urb(struct snd_usb_endpoint *ep,
201 ep->prepare_data_urb(ep->data_subs, urb); 241 ep->prepare_data_urb(ep->data_subs, urb);
202 } else { 242 } else {
203 /* no data provider, so send silence */ 243 /* no data provider, so send silence */
204 unsigned int offs = 0; 244 prepare_silent_urb(ep, ctx);
205 for (i = 0; i < ctx->packets; ++i) {
206 int counts;
207
208 if (ctx->packet_size[i])
209 counts = ctx->packet_size[i];
210 else
211 counts = snd_usb_endpoint_next_packet_size(ep);
212
213 urb->iso_frame_desc[i].offset = offs * ep->stride;
214 urb->iso_frame_desc[i].length = counts * ep->stride;
215 offs += counts;
216 }
217
218 urb->number_of_packets = ctx->packets;
219 urb->transfer_buffer_length = offs * ep->stride;
220 memset(urb->transfer_buffer, ep->silence_value,
221 offs * ep->stride);
222 } 245 }
223 break; 246 break;
224 247
@@ -594,6 +617,8 @@ static int data_ep_set_params(struct snd_usb_endpoint *ep,
594 unsigned int max_packs_per_period, urbs_per_period, urb_packs; 617 unsigned int max_packs_per_period, urbs_per_period, urb_packs;
595 unsigned int max_urbs, i; 618 unsigned int max_urbs, i;
596 int frame_bits = snd_pcm_format_physical_width(pcm_format) * channels; 619 int frame_bits = snd_pcm_format_physical_width(pcm_format) * channels;
620 int tx_length_quirk = (ep->chip->tx_length_quirk &&
621 usb_pipeout(ep->pipe));
597 622
598 if (pcm_format == SNDRV_PCM_FORMAT_DSD_U16_LE && fmt->dsd_dop) { 623 if (pcm_format == SNDRV_PCM_FORMAT_DSD_U16_LE && fmt->dsd_dop) {
599 /* 624 /*
@@ -610,13 +635,34 @@ static int data_ep_set_params(struct snd_usb_endpoint *ep,
610 635
611 /* assume max. frequency is 25% higher than nominal */ 636 /* assume max. frequency is 25% higher than nominal */
612 ep->freqmax = ep->freqn + (ep->freqn >> 2); 637 ep->freqmax = ep->freqn + (ep->freqn >> 2);
613 maxsize = ((ep->freqmax + 0xffff) * (frame_bits >> 3)) 638 /* Round up freqmax to nearest integer in order to calculate maximum
614 >> (16 - ep->datainterval); 639 * packet size, which must represent a whole number of frames.
640 * This is accomplished by adding 0x0.ffff before converting the
641 * Q16.16 format into integer.
642 * In order to accurately calculate the maximum packet size when
643 * the data interval is more than 1 (i.e. ep->datainterval > 0),
644 * multiply by the data interval prior to rounding. For instance,
645 * a freqmax of 41 kHz will result in a max packet size of 6 (5.125)
646 * frames with a data interval of 1, but 11 (10.25) frames with a
647 * data interval of 2.
648 * (ep->freqmax << ep->datainterval overflows at 8.192 MHz for the
649 * maximum datainterval value of 3, at USB full speed, higher for
650 * USB high speed, noting that ep->freqmax is in units of
651 * frames per packet in Q16.16 format.)
652 */
653 maxsize = (((ep->freqmax << ep->datainterval) + 0xffff) >> 16) *
654 (frame_bits >> 3);
655 if (tx_length_quirk)
656 maxsize += sizeof(__le32); /* Space for length descriptor */
615 /* but wMaxPacketSize might reduce this */ 657 /* but wMaxPacketSize might reduce this */
616 if (ep->maxpacksize && ep->maxpacksize < maxsize) { 658 if (ep->maxpacksize && ep->maxpacksize < maxsize) {
617 /* whatever fits into a max. size packet */ 659 /* whatever fits into a max. size packet */
618 maxsize = ep->maxpacksize; 660 unsigned int data_maxsize = maxsize = ep->maxpacksize;
619 ep->freqmax = (maxsize / (frame_bits >> 3)) 661
662 if (tx_length_quirk)
663 /* Need to remove the length descriptor to calc freq */
664 data_maxsize -= sizeof(__le32);
665 ep->freqmax = (data_maxsize / (frame_bits >> 3))
620 << (16 - ep->datainterval); 666 << (16 - ep->datainterval);
621 } 667 }
622 668
diff --git a/sound/usb/midi.c b/sound/usb/midi.c
index 417ebb11cf48..7661616f3636 100644
--- a/sound/usb/midi.c
+++ b/sound/usb/midi.c
@@ -1903,11 +1903,14 @@ static void snd_usbmidi_switch_roland_altsetting(struct snd_usb_midi *umidi)
1903 1903
1904 hostif = &intf->altsetting[1]; 1904 hostif = &intf->altsetting[1];
1905 intfd = get_iface_desc(hostif); 1905 intfd = get_iface_desc(hostif);
1906 /* If either or both of the endpoints support interrupt transfer,
1907 * then use the alternate setting
1908 */
1906 if (intfd->bNumEndpoints != 2 || 1909 if (intfd->bNumEndpoints != 2 ||
1907 (get_endpoint(hostif, 0)->bmAttributes & 1910 !((get_endpoint(hostif, 0)->bmAttributes &
1908 USB_ENDPOINT_XFERTYPE_MASK) != USB_ENDPOINT_XFER_BULK || 1911 USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_INT ||
1909 (get_endpoint(hostif, 1)->bmAttributes & 1912 (get_endpoint(hostif, 1)->bmAttributes &
1910 USB_ENDPOINT_XFERTYPE_MASK) != USB_ENDPOINT_XFER_INT) 1913 USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_INT))
1911 return; 1914 return;
1912 1915
1913 dev_dbg(&umidi->dev->dev, "switching to altsetting %d with int ep\n", 1916 dev_dbg(&umidi->dev->dev, "switching to altsetting %d with int ep\n",
diff --git a/sound/usb/mixer_quirks.c b/sound/usb/mixer_quirks.c
index d3608c0a29f3..fe91184ce832 100644
--- a/sound/usb/mixer_quirks.c
+++ b/sound/usb/mixer_quirks.c
@@ -338,7 +338,7 @@ static int snd_audigy2nx_led_put(struct snd_kcontrol *kcontrol,
338 struct usb_mixer_elem_list *list = snd_kcontrol_chip(kcontrol); 338 struct usb_mixer_elem_list *list = snd_kcontrol_chip(kcontrol);
339 struct usb_mixer_interface *mixer = list->mixer; 339 struct usb_mixer_interface *mixer = list->mixer;
340 int index = kcontrol->private_value & 0xff; 340 int index = kcontrol->private_value & 0xff;
341 int value = ucontrol->value.integer.value[0]; 341 unsigned int value = ucontrol->value.integer.value[0];
342 int old_value = kcontrol->private_value >> 8; 342 int old_value = kcontrol->private_value >> 8;
343 int err; 343 int err;
344 344
diff --git a/sound/usb/pcm.c b/sound/usb/pcm.c
index cdac5179db3f..9245f52d43bd 100644
--- a/sound/usb/pcm.c
+++ b/sound/usb/pcm.c
@@ -1383,6 +1383,56 @@ static inline void fill_playback_urb_dsd_dop(struct snd_usb_substream *subs,
1383 subs->hwptr_done++; 1383 subs->hwptr_done++;
1384 } 1384 }
1385 } 1385 }
1386 if (subs->hwptr_done >= runtime->buffer_size * stride)
1387 subs->hwptr_done -= runtime->buffer_size * stride;
1388}
1389
1390static void copy_to_urb(struct snd_usb_substream *subs, struct urb *urb,
1391 int offset, int stride, unsigned int bytes)
1392{
1393 struct snd_pcm_runtime *runtime = subs->pcm_substream->runtime;
1394
1395 if (subs->hwptr_done + bytes > runtime->buffer_size * stride) {
1396 /* err, the transferred area goes over buffer boundary. */
1397 unsigned int bytes1 =
1398 runtime->buffer_size * stride - subs->hwptr_done;
1399 memcpy(urb->transfer_buffer + offset,
1400 runtime->dma_area + subs->hwptr_done, bytes1);
1401 memcpy(urb->transfer_buffer + offset + bytes1,
1402 runtime->dma_area, bytes - bytes1);
1403 } else {
1404 memcpy(urb->transfer_buffer + offset,
1405 runtime->dma_area + subs->hwptr_done, bytes);
1406 }
1407 subs->hwptr_done += bytes;
1408 if (subs->hwptr_done >= runtime->buffer_size * stride)
1409 subs->hwptr_done -= runtime->buffer_size * stride;
1410}
1411
1412static unsigned int copy_to_urb_quirk(struct snd_usb_substream *subs,
1413 struct urb *urb, int stride,
1414 unsigned int bytes)
1415{
1416 __le32 packet_length;
1417 int i;
1418
1419 /* Put __le32 length descriptor at start of each packet. */
1420 for (i = 0; i < urb->number_of_packets; i++) {
1421 unsigned int length = urb->iso_frame_desc[i].length;
1422 unsigned int offset = urb->iso_frame_desc[i].offset;
1423
1424 packet_length = cpu_to_le32(length);
1425 offset += i * sizeof(packet_length);
1426 urb->iso_frame_desc[i].offset = offset;
1427 urb->iso_frame_desc[i].length += sizeof(packet_length);
1428 memcpy(urb->transfer_buffer + offset,
1429 &packet_length, sizeof(packet_length));
1430 copy_to_urb(subs, urb, offset + sizeof(packet_length),
1431 stride, length);
1432 }
1433 /* Adjust transfer size accordingly. */
1434 bytes += urb->number_of_packets * sizeof(packet_length);
1435 return bytes;
1386} 1436}
1387 1437
1388static void prepare_playback_urb(struct snd_usb_substream *subs, 1438static void prepare_playback_urb(struct snd_usb_substream *subs,
@@ -1460,27 +1510,17 @@ static void prepare_playback_urb(struct snd_usb_substream *subs,
1460 } 1510 }
1461 1511
1462 subs->hwptr_done += bytes; 1512 subs->hwptr_done += bytes;
1513 if (subs->hwptr_done >= runtime->buffer_size * stride)
1514 subs->hwptr_done -= runtime->buffer_size * stride;
1463 } else { 1515 } else {
1464 /* usual PCM */ 1516 /* usual PCM */
1465 if (subs->hwptr_done + bytes > runtime->buffer_size * stride) { 1517 if (!subs->tx_length_quirk)
1466 /* err, the transferred area goes over buffer boundary. */ 1518 copy_to_urb(subs, urb, 0, stride, bytes);
1467 unsigned int bytes1 = 1519 else
1468 runtime->buffer_size * stride - subs->hwptr_done; 1520 bytes = copy_to_urb_quirk(subs, urb, stride, bytes);
1469 memcpy(urb->transfer_buffer, 1521 /* bytes is now amount of outgoing data */
1470 runtime->dma_area + subs->hwptr_done, bytes1);
1471 memcpy(urb->transfer_buffer + bytes1,
1472 runtime->dma_area, bytes - bytes1);
1473 } else {
1474 memcpy(urb->transfer_buffer,
1475 runtime->dma_area + subs->hwptr_done, bytes);
1476 }
1477
1478 subs->hwptr_done += bytes;
1479 } 1522 }
1480 1523
1481 if (subs->hwptr_done >= runtime->buffer_size * stride)
1482 subs->hwptr_done -= runtime->buffer_size * stride;
1483
1484 /* update delay with exact number of samples queued */ 1524 /* update delay with exact number of samples queued */
1485 runtime->delay = subs->last_delay; 1525 runtime->delay = subs->last_delay;
1486 runtime->delay += frames; 1526 runtime->delay += frames;
diff --git a/sound/usb/quirks-table.h b/sound/usb/quirks-table.h
index e4756651a52c..1a1e2e4df35e 100644
--- a/sound/usb/quirks-table.h
+++ b/sound/usb/quirks-table.h
@@ -2664,6 +2664,15 @@ YAMAHA_DEVICE(0x7010, "UB99"),
2664 } 2664 }
2665}, 2665},
2666{ 2666{
2667 USB_DEVICE(0x1235, 0x000a),
2668 .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
2669 /* .vendor_name = "Novation", */
2670 /* .product_name = "Nocturn", */
2671 .ifnum = 0,
2672 .type = QUIRK_MIDI_RAW_BYTES
2673 }
2674},
2675{
2667 USB_DEVICE(0x1235, 0x000e), 2676 USB_DEVICE(0x1235, 0x000e),
2668 .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) { 2677 .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
2669 /* .vendor_name = "Novation", */ 2678 /* .vendor_name = "Novation", */
@@ -3182,10 +3191,9 @@ AU0828_DEVICE(0x2040, 0x7270, "Hauppauge", "HVR-950Q"),
3182{ 3191{
3183 /* 3192 /*
3184 * ZOOM R16/24 in audio interface mode. 3193 * ZOOM R16/24 in audio interface mode.
3185 * Mixer descriptors are garbage, further quirks will be needed 3194 * Playback requires an extra four byte LE length indicator
3186 * to make any of it functional, thus disabled for now. 3195 * at the start of each isochronous packet. This quirk is
3187 * Playback stream appears to start and run fine but no sound 3196 * enabled in create_standard_audio_quirk().
3188 * is produced, so also disabled for now.
3189 */ 3197 */
3190 USB_DEVICE(0x1686, 0x00dd), 3198 USB_DEVICE(0x1686, 0x00dd),
3191 .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) { 3199 .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
@@ -3193,14 +3201,9 @@ AU0828_DEVICE(0x2040, 0x7270, "Hauppauge", "HVR-950Q"),
3193 .type = QUIRK_COMPOSITE, 3201 .type = QUIRK_COMPOSITE,
3194 .data = (const struct snd_usb_audio_quirk[]) { 3202 .data = (const struct snd_usb_audio_quirk[]) {
3195 { 3203 {
3196 /* Mixer */
3197 .ifnum = 0,
3198 .type = QUIRK_IGNORE_INTERFACE,
3199 },
3200 {
3201 /* Playback */ 3204 /* Playback */
3202 .ifnum = 1, 3205 .ifnum = 1,
3203 .type = QUIRK_IGNORE_INTERFACE, 3206 .type = QUIRK_AUDIO_STANDARD_INTERFACE,
3204 }, 3207 },
3205 { 3208 {
3206 /* Capture */ 3209 /* Capture */
diff --git a/sound/usb/quirks.c b/sound/usb/quirks.c
index 00ebc0ca008e..4897ea171194 100644
--- a/sound/usb/quirks.c
+++ b/sound/usb/quirks.c
@@ -115,6 +115,9 @@ static int create_standard_audio_quirk(struct snd_usb_audio *chip,
115 struct usb_interface_descriptor *altsd; 115 struct usb_interface_descriptor *altsd;
116 int err; 116 int err;
117 117
118 if (chip->usb_id == USB_ID(0x1686, 0x00dd)) /* Zoom R16/24 */
119 chip->tx_length_quirk = 1;
120
118 alts = &iface->altsetting[0]; 121 alts = &iface->altsetting[0];
119 altsd = get_iface_desc(alts); 122 altsd = get_iface_desc(alts);
120 err = snd_usb_parse_audio_interface(chip, altsd->bInterfaceNumber); 123 err = snd_usb_parse_audio_interface(chip, altsd->bInterfaceNumber);
diff --git a/sound/usb/stream.c b/sound/usb/stream.c
index 970086015cde..8ee14f2365e7 100644
--- a/sound/usb/stream.c
+++ b/sound/usb/stream.c
@@ -92,6 +92,7 @@ static void snd_usb_init_substream(struct snd_usb_stream *as,
92 subs->direction = stream; 92 subs->direction = stream;
93 subs->dev = as->chip->dev; 93 subs->dev = as->chip->dev;
94 subs->txfr_quirk = as->chip->txfr_quirk; 94 subs->txfr_quirk = as->chip->txfr_quirk;
95 subs->tx_length_quirk = as->chip->tx_length_quirk;
95 subs->speed = snd_usb_get_speed(subs->dev); 96 subs->speed = snd_usb_get_speed(subs->dev);
96 subs->pkt_offset_adj = 0; 97 subs->pkt_offset_adj = 0;
97 98
diff --git a/sound/usb/usbaudio.h b/sound/usb/usbaudio.h
index 33a176437e2e..15a12715bd05 100644
--- a/sound/usb/usbaudio.h
+++ b/sound/usb/usbaudio.h
@@ -43,6 +43,7 @@ struct snd_usb_audio {
43 atomic_t usage_count; 43 atomic_t usage_count;
44 wait_queue_head_t shutdown_wait; 44 wait_queue_head_t shutdown_wait;
45 unsigned int txfr_quirk:1; /* Subframe boundaries on transfers */ 45 unsigned int txfr_quirk:1; /* Subframe boundaries on transfers */
46 unsigned int tx_length_quirk:1; /* Put length specifier in transfers */
46 47
47 int num_interfaces; 48 int num_interfaces;
48 int num_suspended_intf; 49 int num_suspended_intf;