aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/devicetree/bindings/sound/nau8810.txt16
-rw-r--r--Documentation/devicetree/bindings/sound/nvidia,tegra-audio-sgtl5000.txt42
-rw-r--r--Documentation/devicetree/bindings/sound/qcom,apq8016-sbc.txt30
-rw-r--r--Documentation/devicetree/bindings/sound/renesas,rsrc-card.txt75
-rw-r--r--Documentation/devicetree/bindings/sound/rockchip,rk3399-gru-sound.txt22
-rw-r--r--Documentation/devicetree/bindings/sound/rt5659.txt3
-rw-r--r--Documentation/devicetree/bindings/sound/rt5660.txt47
-rw-r--r--Documentation/devicetree/bindings/sound/rt5663.txt30
-rw-r--r--Documentation/devicetree/bindings/sound/simple-card.txt37
-rw-r--r--Documentation/devicetree/bindings/sound/simple-scu-card.txt110
-rw-r--r--Documentation/devicetree/bindings/sound/st,sti-asoc-card.txt52
-rw-r--r--Documentation/devicetree/bindings/sound/sunxi,sun4i-spdif.txt3
-rw-r--r--Documentation/devicetree/bindings/sound/tlv320aic31xx.txt9
-rw-r--r--arch/arm/mach-s3c24xx/mach-mini2440.c19
-rw-r--r--include/sound/da7219.h2
-rw-r--r--include/sound/hda_register.h36
-rw-r--r--include/sound/hdaudio.h13
-rw-r--r--include/sound/hdaudio_ext.h12
-rw-r--r--include/sound/l3.h15
-rw-r--r--include/sound/rt5660.h31
-rw-r--r--include/sound/s3c24xx_uda134x.h1
-rw-r--r--include/sound/simple_card_utils.h35
-rw-r--r--include/sound/soc.h19
-rw-r--r--include/sound/tlv.h78
-rw-r--r--include/uapi/sound/Kbuild1
-rw-r--r--include/uapi/sound/asoc.h35
-rw-r--r--include/uapi/sound/asound.h3
-rw-r--r--include/uapi/sound/snd_sst_tokens.h214
-rw-r--r--include/uapi/sound/tlv.h69
-rw-r--r--sound/aoa/fabrics/layout.c15
-rw-r--r--sound/aoa/soundbus/i2sbus/core.c2
-rw-r--r--sound/core/compress_offload.c14
-rw-r--r--sound/core/pcm_native.c4
-rw-r--r--sound/core/seq/seq_clientmgr.c722
-rw-r--r--sound/core/seq/seq_compat.c7
-rw-r--r--sound/firewire/bebob/Makefile5
-rw-r--r--sound/firewire/bebob/bebob.c8
-rw-r--r--sound/firewire/bebob/bebob.h3
-rw-r--r--sound/firewire/bebob/bebob_terratec.c31
-rw-r--r--sound/firewire/bebob/bebob_yamaha_terratec.c (renamed from sound/firewire/bebob/bebob_yamaha.c)9
-rw-r--r--sound/firewire/dice/dice-pcm.c4
-rw-r--r--sound/firewire/digi00x/digi00x-pcm.c4
-rw-r--r--sound/firewire/oxfw/oxfw-pcm.c4
-rw-r--r--sound/firewire/tascam/tascam-pcm.c4
-rw-r--r--sound/hda/ext/hdac_ext_controller.c91
-rw-r--r--sound/hda/ext/hdac_ext_stream.c56
-rw-r--r--sound/hda/hdac_controller.c75
-rw-r--r--sound/pci/ad1889.c4
-rw-r--r--sound/pci/ali5451/ali5451.c2
-rw-r--r--sound/pci/als300.c4
-rw-r--r--sound/pci/als4000.c4
-rw-r--r--sound/pci/asihpi/asihpi.c4
-rw-r--r--sound/pci/asihpi/hpifunc.c7
-rw-r--r--sound/pci/atiixp.c6
-rw-r--r--sound/pci/atiixp_modem.c4
-rw-r--r--sound/pci/au88x0/au88x0_core.c2
-rw-r--r--sound/pci/aw2/aw2-alsa.c4
-rw-r--r--sound/pci/azt3328.c6
-rw-r--r--sound/pci/bt87x.c2
-rw-r--r--sound/pci/ca0106/ca0106_main.c16
-rw-r--r--sound/pci/cmipci.c10
-rw-r--r--sound/pci/cs4281.c4
-rw-r--r--sound/pci/cs46xx/cs46xx_lib.c4
-rw-r--r--sound/pci/cs46xx/dsp_spos.c2
-rw-r--r--sound/pci/cs5535audio/cs5535audio_pcm.c4
-rw-r--r--sound/pci/ctxfi/ctatc.c2
-rw-r--r--sound/pci/ctxfi/ctpcm.c4
-rw-r--r--sound/pci/ctxfi/ctvmem.c6
-rw-r--r--sound/pci/emu10k1/emu10k1x.c4
-rw-r--r--sound/pci/emu10k1/emupcm.c12
-rw-r--r--sound/pci/emu10k1/p16v.c20
-rw-r--r--sound/pci/ens1370.c6
-rw-r--r--sound/pci/es1938.c4
-rw-r--r--sound/pci/es1968.c4
-rw-r--r--sound/pci/fm801.c4
-rw-r--r--sound/pci/hda/hda_controller.c205
-rw-r--r--sound/pci/hda/hda_controller.h3
-rw-r--r--sound/pci/hda/hda_intel.c17
-rw-r--r--sound/pci/hda/patch_ca0132.c10
-rw-r--r--sound/pci/hda/patch_conexant.c10
-rw-r--r--sound/pci/hda/patch_realtek.c19
-rw-r--r--sound/pci/ice1712/ice1712.c10
-rw-r--r--sound/pci/ice1712/ice1724.c14
-rw-r--r--sound/pci/korg1212/korg1212.c4
-rw-r--r--sound/pci/lola/lola_pcm.c2
-rw-r--r--sound/pci/lx6464es/lx6464es.c4
-rw-r--r--sound/pci/maestro3.c4
-rw-r--r--sound/pci/mixart/mixart.c4
-rw-r--r--sound/pci/nm256/nm256.c4
-rw-r--r--sound/pci/oxygen/oxygen_pcm.c12
-rw-r--r--sound/pci/pcxhr/pcxhr.c2
-rw-r--r--sound/pci/riptide/riptide.c6
-rw-r--r--sound/pci/rme32.c16
-rw-r--r--sound/pci/rme96.c8
-rw-r--r--sound/pci/rme9652/hdsp.c4
-rw-r--r--sound/pci/rme9652/hdspm.c4
-rw-r--r--sound/pci/rme9652/rme9652.c4
-rw-r--r--sound/pci/sonicvibes.c4
-rw-r--r--sound/pci/trident/trident_main.c12
-rw-r--r--sound/pci/via82xx.c10
-rw-r--r--sound/pci/via82xx_modem.c4
-rw-r--r--sound/pci/ymfpci/ymfpci_main.c10
-rw-r--r--sound/ppc/snd_ps3.c4
-rw-r--r--sound/soc/amd/acp-pcm-dma.c2
-rw-r--r--sound/soc/atmel/atmel-classd.c6
-rw-r--r--sound/soc/atmel/atmel-pcm-pdc.c2
-rw-r--r--sound/soc/atmel/atmel-pdmic.c20
-rw-r--r--sound/soc/codecs/88pm860x-codec.c14
-rw-r--r--sound/soc/codecs/Kconfig18
-rw-r--r--sound/soc/codecs/Makefile6
-rw-r--r--sound/soc/codecs/ab8500-codec.c24
-rw-r--r--sound/soc/codecs/ac97.c10
-rw-r--r--sound/soc/codecs/ad1836.c14
-rw-r--r--sound/soc/codecs/ad193x.c14
-rw-r--r--sound/soc/codecs/ad1980.c14
-rw-r--r--sound/soc/codecs/ad73311.c10
-rw-r--r--sound/soc/codecs/adau1373.c14
-rw-r--r--sound/soc/codecs/adau1701.c15
-rw-r--r--sound/soc/codecs/adau1761.c14
-rw-r--r--sound/soc/codecs/adau1781.c14
-rw-r--r--sound/soc/codecs/adau1977.c14
-rw-r--r--sound/soc/codecs/adau7002.c10
-rw-r--r--sound/soc/codecs/adav80x.c14
-rw-r--r--sound/soc/codecs/ads117x.c10
-rw-r--r--sound/soc/codecs/ak4104.c15
-rw-r--r--sound/soc/codecs/ak4535.c14
-rw-r--r--sound/soc/codecs/ak4554.c10
-rw-r--r--sound/soc/codecs/ak4613.c14
-rw-r--r--sound/soc/codecs/ak4641.c14
-rw-r--r--sound/soc/codecs/ak4642.c14
-rw-r--r--sound/soc/codecs/ak4671.c14
-rw-r--r--sound/soc/codecs/ak5386.c10
-rw-r--r--sound/soc/codecs/alc5632.c14
-rw-r--r--sound/soc/codecs/arizona.c78
-rw-r--r--sound/soc/codecs/arizona.h17
-rw-r--r--sound/soc/codecs/bt-sco.c10
-rw-r--r--sound/soc/codecs/cq93vc.c6
-rw-r--r--sound/soc/codecs/cs35l32.c15
-rw-r--r--sound/soc/codecs/cs35l33.c15
-rw-r--r--sound/soc/codecs/cs4265.c15
-rw-r--r--sound/soc/codecs/cs4270.c14
-rw-r--r--sound/soc/codecs/cs4271.c14
-rw-r--r--sound/soc/codecs/cs42l51.c14
-rw-r--r--sound/soc/codecs/cs42l52.c15
-rw-r--r--sound/soc/codecs/cs42l56.c15
-rw-r--r--sound/soc/codecs/cs42l73.c19
-rw-r--r--sound/soc/codecs/cs42xx8.c14
-rw-r--r--sound/soc/codecs/cs4349.c15
-rw-r--r--sound/soc/codecs/cs47l24.c26
-rw-r--r--sound/soc/codecs/cs53l30.c23
-rw-r--r--sound/soc/codecs/cx20442.c10
-rw-r--r--sound/soc/codecs/da7210.c15
-rw-r--r--sound/soc/codecs/da7213.c145
-rw-r--r--sound/soc/codecs/da7213.h12
-rw-r--r--sound/soc/codecs/da7218.c49
-rw-r--r--sound/soc/codecs/da7218.h2
-rw-r--r--sound/soc/codecs/da7219-aad.c108
-rw-r--r--sound/soc/codecs/da7219-aad.h11
-rw-r--r--sound/soc/codecs/da7219.c95
-rw-r--r--sound/soc/codecs/da7219.h8
-rw-r--r--sound/soc/codecs/da732x.c14
-rw-r--r--sound/soc/codecs/da9055.c15
-rw-r--r--sound/soc/codecs/dmic.c10
-rw-r--r--sound/soc/codecs/es8328.c14
-rw-r--r--sound/soc/codecs/gtm601.c10
-rw-r--r--sound/soc/codecs/hdac_hdmi.c2
-rw-r--r--sound/soc/codecs/hdmi-codec.c79
-rw-r--r--sound/soc/codecs/inno_rk3036.c14
-rw-r--r--sound/soc/codecs/isabelle.c14
-rw-r--r--sound/soc/codecs/jz4740.c14
-rw-r--r--sound/soc/codecs/l3.c71
-rw-r--r--sound/soc/codecs/lm49453.c14
-rw-r--r--sound/soc/codecs/max98088.c14
-rw-r--r--sound/soc/codecs/max98095.c14
-rw-r--r--sound/soc/codecs/max98357a.c10
-rw-r--r--sound/soc/codecs/max98371.c1
-rw-r--r--sound/soc/codecs/max9850.c14
-rw-r--r--sound/soc/codecs/max9860.c14
-rw-r--r--sound/soc/codecs/max9867.c19
-rw-r--r--sound/soc/codecs/max98925.c14
-rw-r--r--sound/soc/codecs/max98926.c20
-rw-r--r--sound/soc/codecs/mc13783.c14
-rw-r--r--sound/soc/codecs/ml26124.c14
-rw-r--r--sound/soc/codecs/nau8810.c884
-rw-r--r--sound/soc/codecs/nau8810.h281
-rw-r--r--sound/soc/codecs/nau8825.c16
-rw-r--r--sound/soc/codecs/pcm1681.c14
-rw-r--r--sound/soc/codecs/pcm179x.c14
-rw-r--r--sound/soc/codecs/pcm3008.c10
-rw-r--r--sound/soc/codecs/pcm3168a.c14
-rw-r--r--sound/soc/codecs/pcm512x.c14
-rw-r--r--sound/soc/codecs/rt286.c14
-rw-r--r--sound/soc/codecs/rt298.c14
-rw-r--r--sound/soc/codecs/rt5514-spi.c2
-rw-r--r--sound/soc/codecs/rt5514.c20
-rw-r--r--sound/soc/codecs/rt5514.h4
-rw-r--r--sound/soc/codecs/rt5616.c23
-rw-r--r--sound/soc/codecs/rt5631.c14
-rw-r--r--sound/soc/codecs/rt5640.c17
-rw-r--r--sound/soc/codecs/rt5640.h1
-rw-r--r--sound/soc/codecs/rt5645.c14
-rw-r--r--sound/soc/codecs/rt5651.c14
-rw-r--r--sound/soc/codecs/rt5659.c41
-rw-r--r--sound/soc/codecs/rt5659.h7
-rw-r--r--sound/soc/codecs/rt5660.c1353
-rw-r--r--sound/soc/codecs/rt5660.h847
-rw-r--r--sound/soc/codecs/rt5663.c3218
-rw-r--r--sound/soc/codecs/rt5663.h1121
-rw-r--r--sound/soc/codecs/rt5670.c14
-rw-r--r--sound/soc/codecs/rt5677.c69
-rw-r--r--sound/soc/codecs/sgtl5000.c17
-rw-r--r--sound/soc/codecs/si476x.c10
-rw-r--r--sound/soc/codecs/sn95031.c14
-rw-r--r--sound/soc/codecs/spdif_receiver.c10
-rw-r--r--sound/soc/codecs/spdif_transmitter.c10
-rw-r--r--sound/soc/codecs/ssm2518.c14
-rw-r--r--sound/soc/codecs/ssm2602.c14
-rw-r--r--sound/soc/codecs/ssm4567.c14
-rw-r--r--sound/soc/codecs/sta32x.c14
-rw-r--r--sound/soc/codecs/sta350.c14
-rw-r--r--sound/soc/codecs/sta529.c6
-rw-r--r--sound/soc/codecs/stac9766.c14
-rw-r--r--sound/soc/codecs/sti-sas.c8
-rw-r--r--sound/soc/codecs/tas2552.c14
-rw-r--r--sound/soc/codecs/tas5086.c16
-rw-r--r--sound/soc/codecs/tas571x.c14
-rw-r--r--sound/soc/codecs/tas5720.c14
-rw-r--r--sound/soc/codecs/tfa9879.c15
-rw-r--r--sound/soc/codecs/tlv320aic23.c14
-rw-r--r--sound/soc/codecs/tlv320aic26.c14
-rw-r--r--sound/soc/codecs/tlv320aic31xx.c218
-rw-r--r--sound/soc/codecs/tlv320aic31xx.h2
-rw-r--r--sound/soc/codecs/tlv320aic32x4.c14
-rw-r--r--sound/soc/codecs/tlv320aic3x.c14
-rw-r--r--sound/soc/codecs/tlv320dac33.c31
-rw-r--r--sound/soc/codecs/tpa6130a2.c49
-rw-r--r--sound/soc/codecs/twl4030.c14
-rw-r--r--sound/soc/codecs/twl6040.c14
-rw-r--r--sound/soc/codecs/uda134x.c17
-rw-r--r--sound/soc/codecs/uda1380.c14
-rw-r--r--sound/soc/codecs/wl1273.c14
-rw-r--r--sound/soc/codecs/wm0010.c12
-rw-r--r--sound/soc/codecs/wm1250-ev1.c13
-rw-r--r--sound/soc/codecs/wm2000.c16
-rw-r--r--sound/soc/codecs/wm2200.c16
-rw-r--r--sound/soc/codecs/wm5100.c18
-rw-r--r--sound/soc/codecs/wm5102.c27
-rw-r--r--sound/soc/codecs/wm5110.c28
-rw-r--r--sound/soc/codecs/wm8350.c16
-rw-r--r--sound/soc/codecs/wm8400.c16
-rw-r--r--sound/soc/codecs/wm8510.c16
-rw-r--r--sound/soc/codecs/wm8523.c16
-rw-r--r--sound/soc/codecs/wm8580.c16
-rw-r--r--sound/soc/codecs/wm8711.c16
-rw-r--r--sound/soc/codecs/wm8727.c12
-rw-r--r--sound/soc/codecs/wm8728.c16
-rw-r--r--sound/soc/codecs/wm8731.c16
-rw-r--r--sound/soc/codecs/wm8737.c16
-rw-r--r--sound/soc/codecs/wm8741.c12
-rw-r--r--sound/soc/codecs/wm8750.c16
-rw-r--r--sound/soc/codecs/wm8753.c16
-rw-r--r--sound/soc/codecs/wm8770.c16
-rw-r--r--sound/soc/codecs/wm8776.c16
-rw-r--r--sound/soc/codecs/wm8782.c12
-rw-r--r--sound/soc/codecs/wm8804.c10
-rw-r--r--sound/soc/codecs/wm8900.c16
-rw-r--r--sound/soc/codecs/wm8903.c18
-rw-r--r--sound/soc/codecs/wm8904.c2
-rw-r--r--sound/soc/codecs/wm8940.c16
-rw-r--r--sound/soc/codecs/wm8955.c16
-rw-r--r--sound/soc/codecs/wm8960.c7
-rw-r--r--sound/soc/codecs/wm8961.c16
-rw-r--r--sound/soc/codecs/wm8962.c6
-rw-r--r--sound/soc/codecs/wm8971.c16
-rw-r--r--sound/soc/codecs/wm8974.c16
-rw-r--r--sound/soc/codecs/wm8978.c16
-rw-r--r--sound/soc/codecs/wm8983.c16
-rw-r--r--sound/soc/codecs/wm8985.c16
-rw-r--r--sound/soc/codecs/wm8988.c14
-rw-r--r--sound/soc/codecs/wm8990.c16
-rw-r--r--sound/soc/codecs/wm8991.c44
-rw-r--r--sound/soc/codecs/wm8993.c2
-rw-r--r--sound/soc/codecs/wm8994.c2
-rw-r--r--sound/soc/codecs/wm8995.c14
-rw-r--r--sound/soc/codecs/wm8996.c18
-rw-r--r--sound/soc/codecs/wm8997.c16
-rw-r--r--sound/soc/codecs/wm8998.c26
-rw-r--r--sound/soc/codecs/wm9081.c16
-rw-r--r--sound/soc/codecs/wm9090.c2
-rw-r--r--sound/soc/codecs/wm9705.c16
-rw-r--r--sound/soc/codecs/wm9712.c16
-rw-r--r--sound/soc/codecs/wm9713.c16
-rw-r--r--sound/soc/codecs/wm_adsp.c88
-rw-r--r--sound/soc/codecs/wm_adsp.h7
-rw-r--r--sound/soc/davinci/davinci-mcasp.c2
-rw-r--r--sound/soc/dwc/designware_i2s.c2
-rw-r--r--sound/soc/fsl/fsl_asrc.c12
-rw-r--r--sound/soc/fsl/fsl_asrc_dma.c2
-rw-r--r--sound/soc/fsl/fsl_esai.c8
-rw-r--r--sound/soc/fsl/fsl_sai.c6
-rw-r--r--sound/soc/fsl/fsl_spdif.c2
-rw-r--r--sound/soc/fsl/fsl_ssi.c2
-rw-r--r--sound/soc/generic/Kconfig8
-rw-r--r--sound/soc/generic/Makefile2
-rw-r--r--sound/soc/generic/simple-card-utils.c141
-rw-r--r--sound/soc/generic/simple-card.c305
-rw-r--r--sound/soc/generic/simple-scu-card.c345
-rw-r--r--sound/soc/img/pistachio-internal-dac.c14
-rw-r--r--sound/soc/intel/Kconfig12
-rw-r--r--sound/soc/intel/atom/sst-atom-controls.c32
-rw-r--r--sound/soc/intel/atom/sst-atom-controls.h6
-rw-r--r--sound/soc/intel/atom/sst-mfld-platform-pcm.c2
-rw-r--r--sound/soc/intel/atom/sst/sst.c5
-rw-r--r--sound/soc/intel/atom/sst/sst_acpi.c97
-rw-r--r--sound/soc/intel/atom/sst/sst_ipc.c3
-rw-r--r--sound/soc/intel/atom/sst/sst_pvt.c14
-rw-r--r--sound/soc/intel/baytrail/sst-baytrail-ipc.c12
-rw-r--r--sound/soc/intel/boards/Makefile2
-rw-r--r--sound/soc/intel/boards/bdw-rt5677.c347
-rw-r--r--sound/soc/intel/boards/bxt_da7219_max98357a.c75
-rw-r--r--sound/soc/intel/boards/bxt_rt298.c14
-rw-r--r--sound/soc/intel/boards/bytcr_rt5640.c507
-rw-r--r--sound/soc/intel/common/sst-acpi.c1
-rw-r--r--sound/soc/intel/haswell/sst-haswell-pcm.c2
-rw-r--r--sound/soc/intel/skylake/bxt-sst.c118
-rw-r--r--sound/soc/intel/skylake/skl-messages.c67
-rw-r--r--sound/soc/intel/skylake/skl-pcm.c60
-rw-r--r--sound/soc/intel/skylake/skl-sst-cldma.c4
-rw-r--r--sound/soc/intel/skylake/skl-sst-dsp.h18
-rw-r--r--sound/soc/intel/skylake/skl-sst-ipc.c41
-rw-r--r--sound/soc/intel/skylake/skl-sst-ipc.h12
-rw-r--r--sound/soc/intel/skylake/skl-sst-utils.c176
-rw-r--r--sound/soc/intel/skylake/skl-sst.c49
-rw-r--r--sound/soc/intel/skylake/skl-topology.c918
-rw-r--r--sound/soc/intel/skylake/skl-topology.h15
-rw-r--r--sound/soc/intel/skylake/skl-tplg-interface.h95
-rw-r--r--sound/soc/intel/skylake/skl.c6
-rw-r--r--sound/soc/intel/skylake/skl.h2
-rw-r--r--sound/soc/kirkwood/kirkwood-dma.c2
-rw-r--r--sound/soc/mediatek/common/mtk-afe-fe-dai.c5
-rw-r--r--sound/soc/omap/mcbsp.c3
-rw-r--r--sound/soc/omap/omap-abe-twl6040.c14
-rw-r--r--sound/soc/omap/omap-pcm.c2
-rw-r--r--sound/soc/qcom/apq8016_sbc.c20
-rw-r--r--sound/soc/qcom/lpass-platform.c16
-rw-r--r--sound/soc/qcom/lpass.h2
-rw-r--r--sound/soc/rockchip/Kconfig12
-rw-r--r--sound/soc/rockchip/Makefile2
-rw-r--r--sound/soc/rockchip/rk3399_gru_sound.c397
-rw-r--r--sound/soc/rockchip/rockchip_i2s.c10
-rw-r--r--sound/soc/rockchip/rockchip_spdif.c12
-rw-r--r--sound/soc/samsung/Kconfig57
-rw-r--r--sound/soc/samsung/ac97.c34
-rw-r--r--sound/soc/samsung/dma.h20
-rw-r--r--sound/soc/samsung/dmaengine.c31
-rw-r--r--sound/soc/samsung/i2s.c56
-rw-r--r--sound/soc/samsung/idma.c1
-rw-r--r--sound/soc/samsung/pcm.c26
-rw-r--r--sound/soc/samsung/s3c-i2s-v2.c3
-rw-r--r--sound/soc/samsung/s3c-i2s-v2.h4
-rw-r--r--sound/soc/samsung/s3c2412-i2s.c24
-rw-r--r--sound/soc/samsung/s3c24xx-i2s.c24
-rw-r--r--sound/soc/samsung/s3c24xx_uda134x.c134
-rw-r--r--sound/soc/samsung/smdk_wm8580pcm.c1
-rw-r--r--sound/soc/samsung/smdk_wm8994pcm.c1
-rw-r--r--sound/soc/samsung/spdif.c12
-rw-r--r--sound/soc/sh/Kconfig6
-rw-r--r--sound/soc/sh/rcar/Makefile3
-rw-r--r--sound/soc/sh/rcar/core.c4
-rw-r--r--sound/soc/sh/rcar/rsrc-card.c486
-rw-r--r--sound/soc/sh/rcar/ssi.c2
-rw-r--r--sound/soc/soc-ac97.c2
-rw-r--r--sound/soc/soc-core.c15
-rw-r--r--sound/soc/soc-dapm.c23
-rw-r--r--sound/soc/soc-ops.c2
-rw-r--r--sound/soc/soc-pcm.c13
-rw-r--r--sound/soc/soc-topology.c115
-rw-r--r--sound/soc/soc-utils.c2
-rw-r--r--sound/soc/sti/sti_uniperif.c130
-rw-r--r--sound/soc/sti/uniperif.h28
-rw-r--r--sound/soc/sti/uniperif_player.c83
-rw-r--r--sound/soc/sti/uniperif_reader.c46
-rw-r--r--sound/soc/sunxi/Kconfig1
-rw-r--r--sound/soc/sunxi/sun4i-codec.c60
-rw-r--r--sound/soc/sunxi/sun4i-spdif.c17
-rw-r--r--sound/soc/tegra/Kconfig11
-rw-r--r--sound/soc/tegra/Makefile2
-rw-r--r--sound/soc/tegra/tegra_rt5640.c2
-rw-r--r--sound/soc/tegra/tegra_sgtl5000.c212
-rw-r--r--sound/soc/ux500/ux500_msp_dai.c6
-rw-r--r--sound/usb/caiaq/audio.c1
-rw-r--r--sound/usb/card.h2
-rw-r--r--sound/usb/endpoint.c13
-rw-r--r--sound/usb/format.c4
-rw-r--r--sound/usb/line6/Kconfig5
-rw-r--r--sound/usb/line6/capture.c50
-rw-r--r--sound/usb/line6/driver.c269
-rw-r--r--sound/usb/line6/driver.h59
-rw-r--r--sound/usb/line6/midi.c2
-rw-r--r--sound/usb/line6/pcm.c83
-rw-r--r--sound/usb/line6/pcm.h20
-rw-r--r--sound/usb/line6/playback.c37
-rw-r--r--sound/usb/line6/pod.c12
-rw-r--r--sound/usb/line6/podhd.c300
-rw-r--r--sound/usb/line6/toneport.c6
-rw-r--r--sound/usb/line6/variax.c6
-rw-r--r--sound/usb/mixer_quirks.c22
-rw-r--r--sound/usb/quirks.c6
408 files changed, 16518 insertions, 3986 deletions
diff --git a/Documentation/devicetree/bindings/sound/nau8810.txt b/Documentation/devicetree/bindings/sound/nau8810.txt
new file mode 100644
index 000000000000..05830e477acd
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/nau8810.txt
@@ -0,0 +1,16 @@
1NAU8810 audio CODEC
2
3This device supports I2C only.
4
5Required properties:
6
7 - compatible : "nuvoton,nau8810"
8
9 - reg : the I2C address of the device.
10
11Example:
12
13codec: nau8810@1a {
14 compatible = "nuvoton,nau8810";
15 reg = <0x1a>;
16};
diff --git a/Documentation/devicetree/bindings/sound/nvidia,tegra-audio-sgtl5000.txt b/Documentation/devicetree/bindings/sound/nvidia,tegra-audio-sgtl5000.txt
new file mode 100644
index 000000000000..5da7da4ea07a
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/nvidia,tegra-audio-sgtl5000.txt
@@ -0,0 +1,42 @@
1NVIDIA Tegra audio complex, with SGTL5000 CODEC
2
3Required properties:
4- compatible : "nvidia,tegra-audio-sgtl5000"
5- clocks : Must contain an entry for each entry in clock-names.
6 See ../clocks/clock-bindings.txt for details.
7- clock-names : Must include the following entries:
8 - pll_a
9 - pll_a_out0
10 - mclk (The Tegra cdev1/extern1 clock, which feeds the CODEC's mclk)
11- nvidia,model : The user-visible name of this sound complex.
12- nvidia,audio-routing : A list of the connections between audio components.
13 Each entry is a pair of strings, the first being the connection's sink,
14 the second being the connection's source. Valid names for sources and
15 sinks are the SGTL5000's pins (as documented in its binding), and the jacks
16 on the board:
17
18 * Headphone Jack
19 * Line In Jack
20 * Mic Jack
21
22- nvidia,i2s-controller : The phandle of the Tegra I2S controller that's
23 connected to the CODEC.
24- nvidia,audio-codec : The phandle of the SGTL5000 audio codec.
25
26Example:
27
28sound {
29 compatible = "toradex,tegra-audio-sgtl5000-apalis_t30",
30 "nvidia,tegra-audio-sgtl5000";
31 nvidia,model = "Toradex Apalis T30";
32 nvidia,audio-routing =
33 "Headphone Jack", "HP_OUT",
34 "LINE_IN", "Line In Jack",
35 "MIC_IN", "Mic Jack";
36 nvidia,i2s-controller = <&tegra_i2s2>;
37 nvidia,audio-codec = <&sgtl5000>;
38 clocks = <&tegra_car TEGRA30_CLK_PLL_A>,
39 <&tegra_car TEGRA30_CLK_PLL_A_OUT0>,
40 <&tegra_car TEGRA30_CLK_EXTERN1>;
41 clock-names = "pll_a", "pll_a_out0", "mclk";
42};
diff --git a/Documentation/devicetree/bindings/sound/qcom,apq8016-sbc.txt b/Documentation/devicetree/bindings/sound/qcom,apq8016-sbc.txt
index 48129368d4d9..d9d8635ff94c 100644
--- a/Documentation/devicetree/bindings/sound/qcom,apq8016-sbc.txt
+++ b/Documentation/devicetree/bindings/sound/qcom,apq8016-sbc.txt
@@ -16,6 +16,24 @@ Required properties:
16 * "spkr-iomux" 16 * "spkr-iomux"
17- qcom,model : Name of the sound card. 17- qcom,model : Name of the sound card.
18 18
19- qcom,audio-routing : A list of the connections between audio components.
20 Each entry is a pair of strings, the first being the
21 connection's sink, the second being the connection's
22 source. Valid names could be power supplies, MicBias
23 of msm8x16_wcd codec and the jacks on the board:
24
25 Power supplies:
26 * MIC BIAS External1
27 * MIC BIAS External2
28 * MIC BIAS Internal1
29 * MIC BIAS Internal2
30
31 Board connectors:
32 * Headset Mic
33 * Secondary Mic",
34 * DMIC
35 * Ext Spk
36
19Dai-link subnode properties and subnodes: 37Dai-link subnode properties and subnodes:
20 38
21Required dai-link subnodes: 39Required dai-link subnodes:
@@ -37,6 +55,18 @@ sound: sound {
37 reg-names = "mic-iomux", "spkr-iomux"; 55 reg-names = "mic-iomux", "spkr-iomux";
38 qcom,model = "DB410c"; 56 qcom,model = "DB410c";
39 57
58 qcom,audio-routing =
59 "MIC BIAS External1", "Handset Mic",
60 "MIC BIAS Internal2", "Headset Mic",
61 "MIC BIAS External1", "Secondary Mic",
62 "AMIC1", "MIC BIAS External1",
63 "AMIC2", "MIC BIAS Internal2",
64 "AMIC3", "MIC BIAS External1",
65 "DMIC1", "MIC BIAS Internal1",
66 "MIC BIAS Internal1", "Digital Mic1",
67 "DMIC2", "MIC BIAS Internal1",
68 "MIC BIAS Internal1", "Digital Mic2";
69
40 /* I2S - Internal codec */ 70 /* I2S - Internal codec */
41 internal-dai-link@0 { 71 internal-dai-link@0 {
42 cpu { /* PRIMARY */ 72 cpu { /* PRIMARY */
diff --git a/Documentation/devicetree/bindings/sound/renesas,rsrc-card.txt b/Documentation/devicetree/bindings/sound/renesas,rsrc-card.txt
deleted file mode 100644
index 255ece3043ad..000000000000
--- a/Documentation/devicetree/bindings/sound/renesas,rsrc-card.txt
+++ /dev/null
@@ -1,75 +0,0 @@
1Renesas Sampling Rate Convert Sound Card:
2
3Renesas Sampling Rate Convert Sound Card specifies audio DAI connections of SoC <-> codec.
4
5Required properties:
6
7- compatible : "renesas,rsrc-card{,<board>}"
8 Examples with boards are:
9 - "renesas,rsrc-card"
10 - "renesas,rsrc-card,lager"
11 - "renesas,rsrc-card,koelsch"
12Optional properties:
13
14- card_name : User specified audio sound card name, one string
15 property.
16- cpu : CPU sub-node
17- codec : CODEC sub-node
18
19Optional subnode properties:
20
21- format : CPU/CODEC common audio format.
22 "i2s", "right_j", "left_j" , "dsp_a"
23 "dsp_b", "ac97", "pdm", "msb", "lsb"
24- frame-master : Indicates dai-link frame master.
25 phandle to a cpu or codec subnode.
26- bitclock-master : Indicates dai-link bit clock master.
27 phandle to a cpu or codec subnode.
28- bitclock-inversion : bool property. Add this if the
29 dai-link uses bit clock inversion.
30- frame-inversion : bool property. Add this if the
31 dai-link uses frame clock inversion.
32- convert-rate : platform specified sampling rate convert
33- convert-channels : platform specified converted channel size (2 - 8 ch)
34- audio-prefix : see audio-routing
35- audio-routing : A list of the connections between audio components.
36 Each entry is a pair of strings, the first being the connection's sink,
37 the second being the connection's source. Valid names for sources.
38 use audio-prefix if some components is using same sink/sources naming.
39 it can be used if compatible was "renesas,rsrc-card";
40
41Required CPU/CODEC subnodes properties:
42
43- sound-dai : phandle and port of CPU/CODEC
44
45Optional CPU/CODEC subnodes properties:
46
47- clocks / system-clock-frequency : specify subnode's clock if needed.
48 it can be specified via "clocks" if system has
49 clock node (= common clock), or "system-clock-frequency"
50 (if system doens't support common clock)
51 If a clock is specified, it is
52 enabled with clk_prepare_enable()
53 in dai startup() and disabled with
54 clk_disable_unprepare() in dai
55 shutdown().
56
57Example
58
59sound {
60 compatible = "renesas,rsrc-card,lager";
61
62 card-name = "rsnd-ak4643";
63 format = "left_j";
64 bitclock-master = <&sndcodec>;
65 frame-master = <&sndcodec>;
66
67 sndcpu: cpu {
68 sound-dai = <&rcar_sound>;
69 };
70
71 sndcodec: codec {
72 sound-dai = <&ak4643>;
73 system-clock-frequency = <11289600>;
74 };
75};
diff --git a/Documentation/devicetree/bindings/sound/rockchip,rk3399-gru-sound.txt b/Documentation/devicetree/bindings/sound/rockchip,rk3399-gru-sound.txt
new file mode 100644
index 000000000000..eac91db07178
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/rockchip,rk3399-gru-sound.txt
@@ -0,0 +1,22 @@
1ROCKCHIP with MAX98357A/RT5514/DA7219 codecs on GRU boards
2
3Required properties:
4- compatible: "rockchip,rk3399-gru-sound"
5- rockchip,cpu: The phandle of the Rockchip I2S controller that's
6 connected to the codecs
7- rockchip,codec: The phandle of the MAX98357A/RT5514/DA7219 codecs
8
9Optional properties:
10- dmic-wakeup-delay-ms : specify delay time (ms) for DMIC ready.
11 If this option is specified, which means it's required dmic need
12 delay for DMIC to ready so that rt5514 can avoid recording before
13 DMIC send valid data
14
15Example:
16
17sound {
18 compatible = "rockchip,rk3399-gru-sound";
19 rockchip,cpu = <&i2s0>;
20 rockchip,codec = <&max98357a &rt5514 &da7219>;
21 dmic-wakeup-delay-ms = <20>;
22};
diff --git a/Documentation/devicetree/bindings/sound/rt5659.txt b/Documentation/devicetree/bindings/sound/rt5659.txt
index 5f79e7fde032..1766e0543fc5 100644
--- a/Documentation/devicetree/bindings/sound/rt5659.txt
+++ b/Documentation/devicetree/bindings/sound/rt5659.txt
@@ -12,6 +12,9 @@ Required properties:
12 12
13Optional properties: 13Optional properties:
14 14
15- clocks: The phandle of the master clock to the CODEC
16- clock-names: Should be "mclk"
17
15- realtek,in1-differential 18- realtek,in1-differential
16- realtek,in3-differential 19- realtek,in3-differential
17- realtek,in4-differential 20- realtek,in4-differential
diff --git a/Documentation/devicetree/bindings/sound/rt5660.txt b/Documentation/devicetree/bindings/sound/rt5660.txt
new file mode 100644
index 000000000000..30be5f921930
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/rt5660.txt
@@ -0,0 +1,47 @@
1RT5660 audio CODEC
2
3This device supports I2C only.
4
5Required properties:
6
7- compatible : "realtek,rt5660".
8
9- reg : The I2C address of the device.
10
11Optional properties:
12
13- clocks: The phandle of the master clock to the CODEC
14- clock-names: Should be "mclk"
15
16- realtek,in1-differential
17- realtek,in3-differential
18 Boolean. Indicate MIC1/3 input are differential, rather than single-ended.
19
20- realtek,poweroff-in-suspend
21 Boolean. If the codec will be powered off in suspend, the resume should be
22 added delay time for waiting codec power ready.
23
24- realtek,dmic1-data-pin
25 0: dmic1 is not used
26 1: using GPIO2 pin as dmic1 data pin
27 2: using IN1P pin as dmic1 data pin
28
29Pins on the device (for linking into audio routes) for RT5660:
30
31 * DMIC L1
32 * DMIC R1
33 * IN1P
34 * IN1N
35 * IN2P
36 * IN3P
37 * IN3N
38 * SPO
39 * LOUTL
40 * LOUTR
41
42Example:
43
44rt5660 {
45 compatible = "realtek,rt5660";
46 reg = <0x1c>;
47};
diff --git a/Documentation/devicetree/bindings/sound/rt5663.txt b/Documentation/devicetree/bindings/sound/rt5663.txt
new file mode 100644
index 000000000000..7d3c974c6e2e
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/rt5663.txt
@@ -0,0 +1,30 @@
1RT5663/RT5668 audio CODEC
2
3This device supports I2C only.
4
5Required properties:
6
7- compatible : One of "realtek,rt5663" or "realtek,rt5668".
8
9- reg : The I2C address of the device.
10
11- interrupts : The CODEC's interrupt output.
12
13Optional properties:
14
15Pins on the device (for linking into audio routes) for RT5663/RT5668:
16
17 * IN1P
18 * IN1N
19 * IN2P
20 * IN2N
21 * HPOL
22 * HPOR
23
24Example:
25
26codec: rt5663@12 {
27 compatible = "realtek,rt5663";
28 reg = <0x12>;
29 interrupts = <7 IRQ_TYPE_EDGE_FALLING>;
30};
diff --git a/Documentation/devicetree/bindings/sound/simple-card.txt b/Documentation/devicetree/bindings/sound/simple-card.txt
index 59d862801e59..c7a93931fad2 100644
--- a/Documentation/devicetree/bindings/sound/simple-card.txt
+++ b/Documentation/devicetree/bindings/sound/simple-card.txt
@@ -22,6 +22,8 @@ Optional properties:
22 headphones are attached. 22 headphones are attached.
23- simple-audio-card,mic-det-gpio : Reference to GPIO that signals when 23- simple-audio-card,mic-det-gpio : Reference to GPIO that signals when
24 a microphone is attached. 24 a microphone is attached.
25- simple-audio-card,aux-devs : List of phandles pointing to auxiliary devices, such
26 as amplifiers, to be added to the sound card.
25 27
26Optional subnodes: 28Optional subnodes:
27 29
@@ -162,3 +164,38 @@ sound {
162 }; 164 };
163 }; 165 };
164}; 166};
167
168Example 3 - route audio from IMX6 SSI2 through TLV320DAC3100 codec
169through TPA6130A2 amplifier to headphones:
170
171&i2c0 {
172 codec: tlv320dac3100@18 {
173 compatible = "ti,tlv320dac3100";
174 ...
175 }
176
177 amp: tpa6130a2@60 {
178 compatible = "ti,tpa6130a2";
179 ...
180 }
181}
182
183sound {
184 compatible = "simple-audio-card";
185 ...
186 simple-audio-card,widgets =
187 "Headphone", "Headphone Jack";
188 simple-audio-card,routing =
189 "Headphone Jack", "HPLEFT",
190 "Headphone Jack", "HPRIGHT",
191 "LEFTIN", "HPL",
192 "RIGHTIN", "HPR";
193 simple-audio-card,aux-devs = <&amp>;
194 simple-audio-card,cpu {
195 sound-dai = <&ssi2>;
196 };
197 simple-audio-card,codec {
198 sound-dai = <&codec>;
199 clocks = ...
200 };
201};
diff --git a/Documentation/devicetree/bindings/sound/simple-scu-card.txt b/Documentation/devicetree/bindings/sound/simple-scu-card.txt
new file mode 100644
index 000000000000..d6fe47ed09af
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/simple-scu-card.txt
@@ -0,0 +1,110 @@
1ASoC simple SCU Sound Card
2
3Simple-Card specifies audio DAI connections of SoC <-> codec.
4
5Required properties:
6
7- compatible : "simple-scu-audio-card"
8 "renesas,rsrc-card"
9
10Optional properties:
11
12- simple-audio-card,name : User specified audio sound card name, one string
13 property.
14- simple-audio-card,cpu : CPU sub-node
15- simple-audio-card,codec : CODEC sub-node
16
17Optional subnode properties:
18
19- simple-audio-card,format : CPU/CODEC common audio format.
20 "i2s", "right_j", "left_j" , "dsp_a"
21 "dsp_b", "ac97", "pdm", "msb", "lsb"
22- simple-audio-card,frame-master : Indicates dai-link frame master.
23 phandle to a cpu or codec subnode.
24- simple-audio-card,bitclock-master : Indicates dai-link bit clock master.
25 phandle to a cpu or codec subnode.
26- simple-audio-card,bitclock-inversion : bool property. Add this if the
27 dai-link uses bit clock inversion.
28- simple-audio-card,frame-inversion : bool property. Add this if the
29 dai-link uses frame clock inversion.
30- simple-audio-card,convert-rate : platform specified sampling rate convert
31- simple-audio-card,convert-channels : platform specified converted channel size (2 - 8 ch)
32- simple-audio-card,prefix : see audio-routing
33- simple-audio-card,routing : A list of the connections between audio components.
34 Each entry is a pair of strings, the first being the connection's sink,
35 the second being the connection's source. Valid names for sources.
36 use audio-prefix if some components is using same sink/sources naming.
37 it can be used if compatible was "renesas,rsrc-card";
38
39Required CPU/CODEC subnodes properties:
40
41- sound-dai : phandle and port of CPU/CODEC
42
43Optional CPU/CODEC subnodes properties:
44
45- clocks / system-clock-frequency : specify subnode's clock if needed.
46 it can be specified via "clocks" if system has
47 clock node (= common clock), or "system-clock-frequency"
48 (if system doens't support common clock)
49 If a clock is specified, it is
50 enabled with clk_prepare_enable()
51 in dai startup() and disabled with
52 clk_disable_unprepare() in dai
53 shutdown().
54
55Example 1. Sampling Rate Covert
56
57sound {
58 compatible = "simple-scu-audio-card";
59
60 simple-audio-card,name = "rsnd-ak4643";
61 simple-audio-card,format = "left_j";
62 simple-audio-card,format = "left_j";
63 simple-audio-card,bitclock-master = <&sndcodec>;
64 simple-audio-card,frame-master = <&sndcodec>;
65
66 simple-audio-card,convert-rate = <48000>; /* see audio_clk_a */
67
68 simple-audio-card,prefix = "ak4642";
69 simple-audio-card,routing = "ak4642 Playback", "DAI0 Playback",
70 "DAI0 Capture", "ak4642 Capture";
71
72 sndcpu: simple-audio-card,cpu {
73 sound-dai = <&rcar_sound>;
74 };
75
76 sndcodec: simple-audio-card,codec {
77 sound-dai = <&ak4643>;
78 system-clock-frequency = <11289600>;
79 };
80};
81
82Example 2. 2 CPU 1 Codec
83
84sound {
85 compatible = "renesas,rsrc-card";
86
87 card-name = "rsnd-ak4643";
88 format = "left_j";
89 bitclock-master = <&dpcmcpu>;
90 frame-master = <&dpcmcpu>;
91
92 convert-rate = <48000>; /* see audio_clk_a */
93
94 audio-prefix = "ak4642";
95 audio-routing = "ak4642 Playback", "DAI0 Playback",
96 "ak4642 Playback", "DAI1 Playback";
97
98 dpcmcpu: cpu@0 {
99 sound-dai = <&rcar_sound 0>;
100 };
101
102 cpu@1 {
103 sound-dai = <&rcar_sound 1>;
104 };
105
106 codec {
107 sound-dai = <&ak4643>;
108 clocks = <&audio_clock>;
109 };
110};
diff --git a/Documentation/devicetree/bindings/sound/st,sti-asoc-card.txt b/Documentation/devicetree/bindings/sound/st,sti-asoc-card.txt
index 16bcdfb6760e..745dc62f76ea 100644
--- a/Documentation/devicetree/bindings/sound/st,sti-asoc-card.txt
+++ b/Documentation/devicetree/bindings/sound/st,sti-asoc-card.txt
@@ -11,7 +11,9 @@ Documentation/devicetree/bindings/sound/simple-card.txt.
11--------------------------------------- 11---------------------------------------
12 12
13Required properties: 13Required properties:
14 - compatible: "st,sti-uni-player" or "st,sti-uni-reader" 14 - compatible: "st,stih407-uni-player-hdmi", "st,stih407-uni-player-pcm-out",
15 "st,stih407-uni-player-dac", "st,stih407-uni-player-spdif",
16 "st,stih407-uni-reader-pcm_in", "st,stih407-uni-reader-hdmi",
15 17
16 - st,syscfg: phandle to boot-device system configuration registers 18 - st,syscfg: phandle to boot-device system configuration registers
17 19
@@ -33,32 +35,24 @@ Required properties:
33 "tx" for "st,sti-uni-player" compatibility 35 "tx" for "st,sti-uni-player" compatibility
34 "rx" for "st,sti-uni-reader" compatibility 36 "rx" for "st,sti-uni-reader" compatibility
35 37
36 - st,version: IP version integrated in SOC.
37
38 - dai-name: DAI name that describes the IP.
39
40 - st,mode: IP working mode depending on associated codec.
41 "HDMI" connected to HDMI codec and support IEC HDMI formats (player only).
42 "SPDIF" connected to SPDIF codec and support SPDIF formats (player only).
43 "PCM" PCM standard mode for I2S or TDM bus.
44 "TDM" TDM mode for TDM bus.
45
46Required properties ("st,sti-uni-player" compatibility only): 38Required properties ("st,sti-uni-player" compatibility only):
47 - clocks: CPU_DAI IP clock source, listed in the same order than the 39 - clocks: CPU_DAI IP clock source, listed in the same order than the
48 CPU_DAI properties. 40 CPU_DAI properties.
49 41
50 - st,uniperiph-id: internal SOC IP instance ID.
51
52Optional properties: 42Optional properties:
53 - pinctrl-0: defined for CPU_DAI@1 and CPU_DAI@4 to describe I2S PIOs for 43 - pinctrl-0: defined for CPU_DAI@1 and CPU_DAI@4 to describe I2S PIOs for
54 external codecs connection. 44 external codecs connection.
55 45
56 - pinctrl-names: should contain only one value - "default". 46 - pinctrl-names: should contain only one value - "default".
57 47
48 - st,tdm-mode: to declare to set TDM mode for unireader and uniplayer IPs.
49 Only compartible with IPs in charge of the external I2S/TDM bus.
50 Should be declared depending on associated codec.
51
58Example: 52Example:
59 53
60 sti_uni_player1: sti-uni-player@1 { 54 sti_uni_player1: sti-uni-player@0x8D81000 {
61 compatible = "st,sti-uni-player"; 55 compatible = "st,stih407-uni-player-hdmi";
62 status = "okay"; 56 status = "okay";
63 #sound-dai-cells = <0>; 57 #sound-dai-cells = <0>;
64 st,syscfg = <&syscfg_core>; 58 st,syscfg = <&syscfg_core>;
@@ -66,15 +60,12 @@ Example:
66 reg = <0x8D81000 0x158>; 60 reg = <0x8D81000 0x158>;
67 interrupts = <GIC_SPI 85 IRQ_TYPE_NONE>; 61 interrupts = <GIC_SPI 85 IRQ_TYPE_NONE>;
68 dmas = <&fdma0 3 0 1>; 62 dmas = <&fdma0 3 0 1>;
69 st,dai-name = "Uni Player #1 (I2S)";
70 dma-names = "tx"; 63 dma-names = "tx";
71 st,uniperiph-id = <1>; 64 st,tdm-mode = <1>;
72 st,version = <5>;
73 st,mode = "TDM";
74 }; 65 };
75 66
76 sti_uni_player2: sti-uni-player@2 { 67 sti_uni_player2: sti-uni-player@0x8D82000 {
77 compatible = "st,sti-uni-player"; 68 compatible = "st,stih407-uni-player-pcm-out";
78 status = "okay"; 69 status = "okay";
79 #sound-dai-cells = <0>; 70 #sound-dai-cells = <0>;
80 st,syscfg = <&syscfg_core>; 71 st,syscfg = <&syscfg_core>;
@@ -82,15 +73,11 @@ Example:
82 reg = <0x8D82000 0x158>; 73 reg = <0x8D82000 0x158>;
83 interrupts = <GIC_SPI 86 IRQ_TYPE_NONE>; 74 interrupts = <GIC_SPI 86 IRQ_TYPE_NONE>;
84 dmas = <&fdma0 4 0 1>; 75 dmas = <&fdma0 4 0 1>;
85 dai-name = "Uni Player #2 (DAC)";
86 dma-names = "tx"; 76 dma-names = "tx";
87 st,uniperiph-id = <2>;
88 st,version = <5>;
89 st,mode = "PCM";
90 }; 77 };
91 78
92 sti_uni_player3: sti-uni-player@3 { 79 sti_uni_player3: sti-uni-player@0x8D85000 {
93 compatible = "st,sti-uni-player"; 80 compatible = "st,stih407-uni-player-spdif";
94 status = "okay"; 81 status = "okay";
95 #sound-dai-cells = <0>; 82 #sound-dai-cells = <0>;
96 st,syscfg = <&syscfg_core>; 83 st,syscfg = <&syscfg_core>;
@@ -99,14 +86,10 @@ Example:
99 interrupts = <GIC_SPI 89 IRQ_TYPE_NONE>; 86 interrupts = <GIC_SPI 89 IRQ_TYPE_NONE>;
100 dmas = <&fdma0 7 0 1>; 87 dmas = <&fdma0 7 0 1>;
101 dma-names = "tx"; 88 dma-names = "tx";
102 dai-name = "Uni Player #3 (SPDIF)";
103 st,uniperiph-id = <3>;
104 st,version = <5>;
105 st,mode = "SPDIF";
106 }; 89 };
107 90
108 sti_uni_reader1: sti-uni-reader@1 { 91 sti_uni_reader1: sti-uni-reader@0x8D84000 {
109 compatible = "st,sti-uni-reader"; 92 compatible = "st,stih407-uni-reader-hdmi";
110 status = "disabled"; 93 status = "disabled";
111 #sound-dai-cells = <0>; 94 #sound-dai-cells = <0>;
112 st,syscfg = <&syscfg_core>; 95 st,syscfg = <&syscfg_core>;
@@ -114,9 +97,6 @@ Example:
114 interrupts = <GIC_SPI 88 IRQ_TYPE_NONE>; 97 interrupts = <GIC_SPI 88 IRQ_TYPE_NONE>;
115 dmas = <&fdma0 6 0 1>; 98 dmas = <&fdma0 6 0 1>;
116 dma-names = "rx"; 99 dma-names = "rx";
117 dai-name = "Uni Reader #1 (HDMI RX)";
118 st,version = <3>;
119 st,mode = "PCM";
120 }; 100 };
121 101
1222) sti-sas-codec: internal audio codec IPs driver 1022) sti-sas-codec: internal audio codec IPs driver
diff --git a/Documentation/devicetree/bindings/sound/sunxi,sun4i-spdif.txt b/Documentation/devicetree/bindings/sound/sunxi,sun4i-spdif.txt
index 13503aa505a9..0230c4d20506 100644
--- a/Documentation/devicetree/bindings/sound/sunxi,sun4i-spdif.txt
+++ b/Documentation/devicetree/bindings/sound/sunxi,sun4i-spdif.txt
@@ -9,6 +9,7 @@ Required properties:
9 9
10 - compatible : should be one of the following: 10 - compatible : should be one of the following:
11 - "allwinner,sun4i-a10-spdif": for the Allwinner A10 SoC 11 - "allwinner,sun4i-a10-spdif": for the Allwinner A10 SoC
12 - "allwinner,sun6i-a31-spdif": for the Allwinner A31 SoC
12 13
13 - reg : Offset and length of the register set for the device. 14 - reg : Offset and length of the register set for the device.
14 15
@@ -25,6 +26,8 @@ Required properties:
25 "apb" clock for the spdif bus. 26 "apb" clock for the spdif bus.
26 "spdif" clock for spdif controller. 27 "spdif" clock for spdif controller.
27 28
29 - resets : reset specifier for the ahb reset (A31 and newer only)
30
28Example: 31Example:
29 32
30spdif: spdif@01c21000 { 33spdif: spdif@01c21000 {
diff --git a/Documentation/devicetree/bindings/sound/tlv320aic31xx.txt b/Documentation/devicetree/bindings/sound/tlv320aic31xx.txt
index eff12be5e789..9340d2ddcc54 100644
--- a/Documentation/devicetree/bindings/sound/tlv320aic31xx.txt
+++ b/Documentation/devicetree/bindings/sound/tlv320aic31xx.txt
@@ -11,6 +11,7 @@ Required properties:
11 "ti,tlv320aic3110" - TLV320AIC3110 (stereo speaker amp, no MiniDSP) 11 "ti,tlv320aic3110" - TLV320AIC3110 (stereo speaker amp, no MiniDSP)
12 "ti,tlv320aic3120" - TLV320AIC3120 (mono speaker amp, MiniDSP) 12 "ti,tlv320aic3120" - TLV320AIC3120 (mono speaker amp, MiniDSP)
13 "ti,tlv320aic3111" - TLV320AIC3111 (stereo speaker amp, MiniDSP) 13 "ti,tlv320aic3111" - TLV320AIC3111 (stereo speaker amp, MiniDSP)
14 "ti,tlv320dac3100" - TLV320DAC3100 (no ADC, mono speaker amp, no MiniDSP)
14 15
15- reg - <int> - I2C slave address 16- reg - <int> - I2C slave address
16- HPVDD-supply, SPRVDD-supply, SPLVDD-supply, AVDD-supply, IOVDD-supply, 17- HPVDD-supply, SPRVDD-supply, SPLVDD-supply, AVDD-supply, IOVDD-supply,
@@ -37,9 +38,11 @@ CODEC output pins:
37 * MICBIAS 38 * MICBIAS
38 39
39CODEC input pins: 40CODEC input pins:
40 * MIC1LP 41 * MIC1LP, devices with ADC
41 * MIC1RP 42 * MIC1RP, devices with ADC
42 * MIC1LM 43 * MIC1LM, devices with ADC
44 * AIN1, devices without ADC
45 * AIN2, devices without ADC
43 46
44The pins can be used in referring sound node's audio-routing property. 47The pins can be used in referring sound node's audio-routing property.
45 48
diff --git a/arch/arm/mach-s3c24xx/mach-mini2440.c b/arch/arm/mach-s3c24xx/mach-mini2440.c
index a8521684a7f5..13999c1c46cf 100644
--- a/arch/arm/mach-s3c24xx/mach-mini2440.c
+++ b/arch/arm/mach-s3c24xx/mach-mini2440.c
@@ -497,9 +497,28 @@ static struct i2c_board_info mini2440_i2c_devs[] __initdata = {
497 }, 497 },
498}; 498};
499 499
500static struct uda134x_platform_data s3c24xx_uda134x = {
501 .l3 = {
502 .gpio_clk = S3C2410_GPB(4),
503 .gpio_data = S3C2410_GPB(3),
504 .gpio_mode = S3C2410_GPB(2),
505 .use_gpios = 1,
506 .data_hold = 1,
507 .data_setup = 1,
508 .clock_high = 1,
509 .mode_hold = 1,
510 .mode = 1,
511 .mode_setup = 1,
512 },
513 .model = UDA134X_UDA1341,
514};
515
500static struct platform_device uda1340_codec = { 516static struct platform_device uda1340_codec = {
501 .name = "uda134x-codec", 517 .name = "uda134x-codec",
502 .id = -1, 518 .id = -1,
519 .dev = {
520 .platform_data = &s3c24xx_uda134x,
521 },
503}; 522};
504 523
505static struct platform_device *mini2440_devices[] __initdata = { 524static struct platform_device *mini2440_devices[] __initdata = {
diff --git a/include/sound/da7219.h b/include/sound/da7219.h
index 02876acdc840..409ef1397fd3 100644
--- a/include/sound/da7219.h
+++ b/include/sound/da7219.h
@@ -34,6 +34,8 @@ enum da7219_mic_amp_in_sel {
34struct da7219_aad_pdata; 34struct da7219_aad_pdata;
35 35
36struct da7219_pdata { 36struct da7219_pdata {
37 bool wakeup_source;
38
37 /* Mic */ 39 /* Mic */
38 enum da7219_micbias_voltage micbias_lvl; 40 enum da7219_micbias_voltage micbias_lvl;
39 enum da7219_mic_amp_in_sel mic_amp_in_sel; 41 enum da7219_mic_amp_in_sel mic_amp_in_sel;
diff --git a/include/sound/hda_register.h b/include/sound/hda_register.h
index ff1aecf325e8..0013063db7f2 100644
--- a/include/sound/hda_register.h
+++ b/include/sound/hda_register.h
@@ -89,6 +89,19 @@ enum { SDI0, SDI1, SDI2, SDI3, SDO0, SDO1, SDO2, SDO3 };
89#define AZX_REG_SD_BDLPL 0x18 89#define AZX_REG_SD_BDLPL 0x18
90#define AZX_REG_SD_BDLPU 0x1c 90#define AZX_REG_SD_BDLPU 0x1c
91 91
92/* GTS registers */
93#define AZX_REG_LLCH 0x14
94
95#define AZX_REG_GTS_BASE 0x520
96
97#define AZX_REG_GTSCC (AZX_REG_GTS_BASE + 0x00)
98#define AZX_REG_WALFCC (AZX_REG_GTS_BASE + 0x04)
99#define AZX_REG_TSCCL (AZX_REG_GTS_BASE + 0x08)
100#define AZX_REG_TSCCU (AZX_REG_GTS_BASE + 0x0C)
101#define AZX_REG_LLPFOC (AZX_REG_GTS_BASE + 0x14)
102#define AZX_REG_LLPCL (AZX_REG_GTS_BASE + 0x18)
103#define AZX_REG_LLPCU (AZX_REG_GTS_BASE + 0x1C)
104
92/* Haswell/Broadwell display HD-A controller Extended Mode registers */ 105/* Haswell/Broadwell display HD-A controller Extended Mode registers */
93#define AZX_REG_HSW_EM4 0x100c 106#define AZX_REG_HSW_EM4 0x100c
94#define AZX_REG_HSW_EM5 0x1010 107#define AZX_REG_HSW_EM5 0x1010
@@ -242,6 +255,29 @@ enum { SDI0, SDI1, SDI2, SDI3, SDO0, SDO1, SDO2, SDO3 };
242/* Interval used to calculate the iterating register offset */ 255/* Interval used to calculate the iterating register offset */
243#define AZX_DRSM_INTERVAL 0x08 256#define AZX_DRSM_INTERVAL 0x08
244 257
258/* Global time synchronization registers */
259#define GTSCC_TSCCD_MASK 0x80000000
260#define GTSCC_TSCCD_SHIFT BIT(31)
261#define GTSCC_TSCCI_MASK 0x20
262#define GTSCC_CDMAS_DMA_DIR_SHIFT 4
263
264#define WALFCC_CIF_MASK 0x1FF
265#define WALFCC_FN_SHIFT 9
266#define HDA_CLK_CYCLES_PER_FRAME 512
267
268/*
269 * An error occurs near frame "rollover". The clocks in frame value indicates
270 * whether this error may have occurred. Here we use the value of 10. Please
271 * see the errata for the right number [<10]
272 */
273#define HDA_MAX_CYCLE_VALUE 499
274#define HDA_MAX_CYCLE_OFFSET 10
275#define HDA_MAX_CYCLE_READ_RETRY 10
276
277#define TSCCU_CCU_SHIFT 32
278#define LLPC_CCU_SHIFT 32
279
280
245/* 281/*
246 * helpers to read the stream position 282 * helpers to read the stream position
247 */ 283 */
diff --git a/include/sound/hdaudio.h b/include/sound/hdaudio.h
index 93e63c56f48f..56004ec8d441 100644
--- a/include/sound/hdaudio.h
+++ b/include/sound/hdaudio.h
@@ -245,6 +245,12 @@ struct hdac_rb {
245 245
246/* 246/*
247 * HD-audio bus base driver 247 * HD-audio bus base driver
248 *
249 * @ppcap: pp capabilities pointer
250 * @spbcap: SPIB capabilities pointer
251 * @mlcap: MultiLink capabilities pointer
252 * @gtscap: gts capabilities pointer
253 * @drsmcap: dma resume capabilities pointer
248 */ 254 */
249struct hdac_bus { 255struct hdac_bus {
250 struct device *dev; 256 struct device *dev;
@@ -256,6 +262,12 @@ struct hdac_bus {
256 void __iomem *remap_addr; 262 void __iomem *remap_addr;
257 int irq; 263 int irq;
258 264
265 void __iomem *ppcap;
266 void __iomem *spbcap;
267 void __iomem *mlcap;
268 void __iomem *gtscap;
269 void __iomem *drsmcap;
270
259 /* codec linked list */ 271 /* codec linked list */
260 struct list_head codec_list; 272 struct list_head codec_list;
261 unsigned int num_codecs; 273 unsigned int num_codecs;
@@ -335,6 +347,7 @@ static inline void snd_hdac_codec_link_down(struct hdac_device *codec)
335int snd_hdac_bus_send_cmd(struct hdac_bus *bus, unsigned int val); 347int snd_hdac_bus_send_cmd(struct hdac_bus *bus, unsigned int val);
336int snd_hdac_bus_get_response(struct hdac_bus *bus, unsigned int addr, 348int snd_hdac_bus_get_response(struct hdac_bus *bus, unsigned int addr,
337 unsigned int *res); 349 unsigned int *res);
350int snd_hdac_bus_parse_capabilities(struct hdac_bus *bus);
338int snd_hdac_link_power(struct hdac_device *codec, bool enable); 351int snd_hdac_link_power(struct hdac_device *codec, bool enable);
339 352
340bool snd_hdac_bus_init_chip(struct hdac_bus *bus, bool full_reset); 353bool snd_hdac_bus_init_chip(struct hdac_bus *bus, bool full_reset);
diff --git a/include/sound/hdaudio_ext.h b/include/sound/hdaudio_ext.h
index b9593b201599..8660a7f10851 100644
--- a/include/sound/hdaudio_ext.h
+++ b/include/sound/hdaudio_ext.h
@@ -8,11 +8,6 @@
8 * 8 *
9 * @bus: hdac bus 9 * @bus: hdac bus
10 * @num_streams: streams supported 10 * @num_streams: streams supported
11 * @ppcap: pp capabilities pointer
12 * @spbcap: SPIB capabilities pointer
13 * @mlcap: MultiLink capabilities pointer
14 * @gtscap: gts capabilities pointer
15 * @drsmcap: dma resume capabilities pointer
16 * @hlink_list: link list of HDA links 11 * @hlink_list: link list of HDA links
17 * @lock: lock for link mgmt 12 * @lock: lock for link mgmt
18 * @cmd_dma_state: state of cmd DMAs: CORB and RIRB 13 * @cmd_dma_state: state of cmd DMAs: CORB and RIRB
@@ -22,12 +17,6 @@ struct hdac_ext_bus {
22 int num_streams; 17 int num_streams;
23 int idx; 18 int idx;
24 19
25 void __iomem *ppcap;
26 void __iomem *spbcap;
27 void __iomem *mlcap;
28 void __iomem *gtscap;
29 void __iomem *drsmcap;
30
31 struct list_head hlink_list; 20 struct list_head hlink_list;
32 21
33 struct mutex lock; 22 struct mutex lock;
@@ -54,7 +43,6 @@ void snd_hdac_ext_bus_device_remove(struct hdac_ext_bus *ebus);
54#define HDA_CODEC_EXT_ENTRY(_vid, _revid, _name, _drv_data) \ 43#define HDA_CODEC_EXT_ENTRY(_vid, _revid, _name, _drv_data) \
55 HDA_CODEC_REV_EXT_ENTRY(_vid, _revid, _name, _drv_data) 44 HDA_CODEC_REV_EXT_ENTRY(_vid, _revid, _name, _drv_data)
56 45
57int snd_hdac_ext_bus_parse_capabilities(struct hdac_ext_bus *sbus);
58void snd_hdac_ext_bus_ppcap_enable(struct hdac_ext_bus *chip, bool enable); 46void snd_hdac_ext_bus_ppcap_enable(struct hdac_ext_bus *chip, bool enable);
59void snd_hdac_ext_bus_ppcap_int_enable(struct hdac_ext_bus *chip, bool enable); 47void snd_hdac_ext_bus_ppcap_int_enable(struct hdac_ext_bus *chip, bool enable);
60 48
diff --git a/include/sound/l3.h b/include/sound/l3.h
index 423a08f0f1b0..1471da22adad 100644
--- a/include/sound/l3.h
+++ b/include/sound/l3.h
@@ -2,9 +2,15 @@
2#define _L3_H_ 1 2#define _L3_H_ 1
3 3
4struct l3_pins { 4struct l3_pins {
5 void (*setdat)(int); 5 void (*setdat)(struct l3_pins *, int);
6 void (*setclk)(int); 6 void (*setclk)(struct l3_pins *, int);
7 void (*setmode)(int); 7 void (*setmode)(struct l3_pins *, int);
8
9 int gpio_data;
10 int gpio_clk;
11 int gpio_mode;
12 int use_gpios;
13
8 int data_hold; 14 int data_hold;
9 int data_setup; 15 int data_setup;
10 int clock_high; 16 int clock_high;
@@ -13,6 +19,9 @@ struct l3_pins {
13 int mode_setup; 19 int mode_setup;
14}; 20};
15 21
22struct device;
23
16int l3_write(struct l3_pins *adap, u8 addr, u8 *data, int len); 24int l3_write(struct l3_pins *adap, u8 addr, u8 *data, int len);
25int l3_set_gpio_ops(struct device *dev, struct l3_pins *adap);
17 26
18#endif 27#endif
diff --git a/include/sound/rt5660.h b/include/sound/rt5660.h
new file mode 100644
index 000000000000..065f83a24db6
--- /dev/null
+++ b/include/sound/rt5660.h
@@ -0,0 +1,31 @@
1/*
2 * linux/sound/rt5660.h -- Platform data for RT5660
3 *
4 * Copyright 2016 Realtek Semiconductor Corp.
5 * Author: Oder Chiou <oder_chiou@realtek.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11
12#ifndef __LINUX_SND_RT5660_H
13#define __LINUX_SND_RT5660_H
14
15enum rt5660_dmic1_data_pin {
16 RT5660_DMIC1_NULL,
17 RT5660_DMIC1_DATA_GPIO2,
18 RT5660_DMIC1_DATA_IN1P,
19};
20
21struct rt5660_platform_data {
22 /* IN1 & IN3 can optionally be differential */
23 bool in1_diff;
24 bool in3_diff;
25 bool use_ldo2;
26 bool poweroff_codec_in_suspend;
27
28 enum rt5660_dmic1_data_pin dmic1_data_pin;
29};
30
31#endif
diff --git a/include/sound/s3c24xx_uda134x.h b/include/sound/s3c24xx_uda134x.h
index 33df4cb909d3..ffaf1f098c8e 100644
--- a/include/sound/s3c24xx_uda134x.h
+++ b/include/sound/s3c24xx_uda134x.h
@@ -7,7 +7,6 @@ struct s3c24xx_uda134x_platform_data {
7 int l3_clk; 7 int l3_clk;
8 int l3_mode; 8 int l3_mode;
9 int l3_data; 9 int l3_data;
10 void (*power) (int);
11 int model; 10 int model;
12}; 11};
13 12
diff --git a/include/sound/simple_card_utils.h b/include/sound/simple_card_utils.h
index 86088aed9002..fd6412551145 100644
--- a/include/sound/simple_card_utils.h
+++ b/include/sound/simple_card_utils.h
@@ -27,10 +27,45 @@ int asoc_simple_card_parse_daifmt(struct device *dev,
27 struct device_node *codec, 27 struct device_node *codec,
28 char *prefix, 28 char *prefix,
29 unsigned int *retfmt); 29 unsigned int *retfmt);
30__printf(3, 4)
30int asoc_simple_card_set_dailink_name(struct device *dev, 31int asoc_simple_card_set_dailink_name(struct device *dev,
31 struct snd_soc_dai_link *dai_link, 32 struct snd_soc_dai_link *dai_link,
32 const char *fmt, ...); 33 const char *fmt, ...);
33int asoc_simple_card_parse_card_name(struct snd_soc_card *card, 34int asoc_simple_card_parse_card_name(struct snd_soc_card *card,
34 char *prefix); 35 char *prefix);
35 36
37#define asoc_simple_card_parse_clk_cpu(node, dai_link, simple_dai) \
38 asoc_simple_card_parse_clk(node, dai_link->cpu_of_node, simple_dai)
39#define asoc_simple_card_parse_clk_codec(node, dai_link, simple_dai) \
40 asoc_simple_card_parse_clk(node, dai_link->codec_of_node, simple_dai)
41int asoc_simple_card_parse_clk(struct device_node *node,
42 struct device_node *dai_of_node,
43 struct asoc_simple_dai *simple_dai);
44
45#define asoc_simple_card_parse_cpu(node, dai_link, \
46 list_name, cells_name, is_single_link) \
47 asoc_simple_card_parse_dai(node, &dai_link->cpu_of_node, \
48 &dai_link->cpu_dai_name, list_name, cells_name, is_single_link)
49#define asoc_simple_card_parse_codec(node, dai_link, list_name, cells_name) \
50 asoc_simple_card_parse_dai(node, &dai_link->codec_of_node, \
51 &dai_link->codec_dai_name, list_name, cells_name, NULL)
52#define asoc_simple_card_parse_platform(node, dai_link, list_name, cells_name) \
53 asoc_simple_card_parse_dai(node, &dai_link->platform_of_node, \
54 NULL, list_name, cells_name, NULL)
55int asoc_simple_card_parse_dai(struct device_node *node,
56 struct device_node **endpoint_np,
57 const char **dai_name,
58 const char *list_name,
59 const char *cells_name,
60 int *is_single_links);
61
62int asoc_simple_card_init_dai(struct snd_soc_dai *dai,
63 struct asoc_simple_dai *simple_dai);
64
65int asoc_simple_card_canonicalize_dailink(struct snd_soc_dai_link *dai_link);
66void asoc_simple_card_canonicalize_cpu(struct snd_soc_dai_link *dai_link,
67 int is_single_links);
68
69int asoc_simple_card_clean_reference(struct snd_soc_card *card);
70
36#endif /* __SIMPLE_CARD_CORE_H */ 71#endif /* __SIMPLE_CARD_CORE_H */
diff --git a/include/sound/soc.h b/include/sound/soc.h
index 6144882cc96a..4f1c784e44f6 100644
--- a/include/sound/soc.h
+++ b/include/sound/soc.h
@@ -898,14 +898,6 @@ struct snd_soc_codec_driver {
898 int (*resume)(struct snd_soc_codec *); 898 int (*resume)(struct snd_soc_codec *);
899 struct snd_soc_component_driver component_driver; 899 struct snd_soc_component_driver component_driver;
900 900
901 /* Default control and setup, added after probe() is run */
902 const struct snd_kcontrol_new *controls;
903 int num_controls;
904 const struct snd_soc_dapm_widget *dapm_widgets;
905 int num_dapm_widgets;
906 const struct snd_soc_dapm_route *dapm_routes;
907 int num_dapm_routes;
908
909 /* codec wide operations */ 901 /* codec wide operations */
910 int (*set_sysclk)(struct snd_soc_codec *codec, 902 int (*set_sysclk)(struct snd_soc_codec *codec,
911 int clk_id, int source, unsigned int freq, int dir); 903 int clk_id, int source, unsigned int freq, int dir);
@@ -1547,17 +1539,6 @@ static inline void *snd_soc_platform_get_drvdata(struct snd_soc_platform *platfo
1547 return snd_soc_component_get_drvdata(&platform->component); 1539 return snd_soc_component_get_drvdata(&platform->component);
1548} 1540}
1549 1541
1550static inline void snd_soc_pcm_set_drvdata(struct snd_soc_pcm_runtime *rtd,
1551 void *data)
1552{
1553 dev_set_drvdata(rtd->dev, data);
1554}
1555
1556static inline void *snd_soc_pcm_get_drvdata(struct snd_soc_pcm_runtime *rtd)
1557{
1558 return dev_get_drvdata(rtd->dev);
1559}
1560
1561static inline void snd_soc_initialize_card_lists(struct snd_soc_card *card) 1542static inline void snd_soc_initialize_card_lists(struct snd_soc_card *card)
1562{ 1543{
1563 INIT_LIST_HEAD(&card->codec_dev_list); 1544 INIT_LIST_HEAD(&card->codec_dev_list);
diff --git a/include/sound/tlv.h b/include/sound/tlv.h
index df97d1966468..3677ebb928d5 100644
--- a/include/sound/tlv.h
+++ b/include/sound/tlv.h
@@ -22,67 +22,39 @@
22 * 22 *
23 */ 23 */
24 24
25/*
26 * TLV structure is right behind the struct snd_ctl_tlv:
27 * unsigned int type - see SNDRV_CTL_TLVT_*
28 * unsigned int length
29 * .... data aligned to sizeof(unsigned int), use
30 * block_length = (length + (sizeof(unsigned int) - 1)) &
31 * ~(sizeof(unsigned int) - 1)) ....
32 */
33
34#include <uapi/sound/tlv.h> 25#include <uapi/sound/tlv.h>
35 26
36#define TLV_ITEM(type, ...) \ 27/* For historical reasons, these macros are aliases to the ones in UAPI. */
37 (type), TLV_LENGTH(__VA_ARGS__), __VA_ARGS__ 28#define TLV_ITEM SNDRV_CTL_TLVD_ITEM
38#define TLV_LENGTH(...) \ 29#define TLV_LENGTH SNDRV_CTL_TLVD_LENGTH
39 ((unsigned int)sizeof((const unsigned int[]) { __VA_ARGS__ })) 30
31#define TLV_CONTAINER_ITEM SNDRV_CTL_TLVD_CONTAINER_ITEM
32#define DECLARE_TLV_CONTAINER SNDRV_CTL_TLVD_DECLARE_CONTAINER
40 33
41#define TLV_CONTAINER_ITEM(...) \ 34#define TLV_DB_SCALE_MASK SNDRV_CTL_TLVD_DB_SCALE_MASK
42 TLV_ITEM(SNDRV_CTL_TLVT_CONTAINER, __VA_ARGS__) 35#define TLV_DB_SCALE_MUTE SNDRV_CTL_TLVD_DB_SCALE_MUTE
43#define DECLARE_TLV_CONTAINER(name, ...) \ 36#define TLV_DB_SCALE_ITEM SNDRV_CTL_TLVD_DB_SCALE_ITEM
44 unsigned int name[] = { TLV_CONTAINER_ITEM(__VA_ARGS__) } 37#define DECLARE_TLV_DB_SCALE SNDRV_CTL_TLVD_DECLARE_DB_SCALE
45 38
46#define TLV_DB_SCALE_MASK 0xffff 39#define TLV_DB_MINMAX_ITEM SNDRV_CTL_TLVD_DB_MINMAX_ITEM
47#define TLV_DB_SCALE_MUTE 0x10000 40#define TLV_DB_MINMAX_MUTE_ITEM SNDRV_CTL_TLVD_DB_MINMAX_MUTE_ITEM
48#define TLV_DB_SCALE_ITEM(min, step, mute) \ 41#define DECLARE_TLV_DB_MINMAX SNDRV_CTL_TLVD_DECLARE_DB_MINMAX
49 TLV_ITEM(SNDRV_CTL_TLVT_DB_SCALE, \ 42#define DECLARE_TLV_DB_MINMAX_MUTE SNDRV_CTL_TLVD_DECLARE_DB_MINMAX_MUTE
50 (min), \
51 ((step) & TLV_DB_SCALE_MASK) | \
52 ((mute) ? TLV_DB_SCALE_MUTE : 0))
53#define DECLARE_TLV_DB_SCALE(name, min, step, mute) \
54 unsigned int name[] = { TLV_DB_SCALE_ITEM(min, step, mute) }
55 43
56/* dB scale specified with min/max values instead of step */ 44#define TLV_DB_LINEAR_ITEM SNDRV_CTL_TLVD_DB_LINEAR_ITEM
57#define TLV_DB_MINMAX_ITEM(min_dB, max_dB) \ 45#define DECLARE_TLV_DB_LINEAR SNDRV_CTL_TLVD_DECLARE_DB_LINEAR
58 TLV_ITEM(SNDRV_CTL_TLVT_DB_MINMAX, (min_dB), (max_dB))
59#define TLV_DB_MINMAX_MUTE_ITEM(min_dB, max_dB) \
60 TLV_ITEM(SNDRV_CTL_TLVT_DB_MINMAX_MUTE, (min_dB), (max_dB))
61#define DECLARE_TLV_DB_MINMAX(name, min_dB, max_dB) \
62 unsigned int name[] = { TLV_DB_MINMAX_ITEM(min_dB, max_dB) }
63#define DECLARE_TLV_DB_MINMAX_MUTE(name, min_dB, max_dB) \
64 unsigned int name[] = { TLV_DB_MINMAX_MUTE_ITEM(min_dB, max_dB) }
65 46
66/* linear volume between min_dB and max_dB (.01dB unit) */ 47#define TLV_DB_RANGE_ITEM SNDRV_CTL_TLVD_DB_RANGE_ITEM
67#define TLV_DB_LINEAR_ITEM(min_dB, max_dB) \ 48#define DECLARE_TLV_DB_RANGE SNDRV_CTL_TLVD_DECLARE_DB_RANGE
68 TLV_ITEM(SNDRV_CTL_TLVT_DB_LINEAR, (min_dB), (max_dB))
69#define DECLARE_TLV_DB_LINEAR(name, min_dB, max_dB) \
70 unsigned int name[] = { TLV_DB_LINEAR_ITEM(min_dB, max_dB) }
71 49
72/* dB range container: 50#define TLV_DB_GAIN_MUTE SNDRV_CTL_TLVD_DB_GAIN_MUTE
73 * Items in dB range container must be ordered by their values and by their 51
74 * dB values. This implies that larger values must correspond with larger 52/*
75 * dB values (which is also required for all other mixer controls). 53 * The below assumes that each item TLV is 4 words like DB_SCALE or LINEAR.
54 * This is an old fasion and obsoleted by commit bf1d1c9b6179("ALSA: tlv: add
55 * DECLARE_TLV_DB_RANGE()").
76 */ 56 */
77/* Each item is: <min> <max> <TLV> */ 57#define TLV_DB_RANGE_HEAD(num) \
78#define TLV_DB_RANGE_ITEM(...) \
79 TLV_ITEM(SNDRV_CTL_TLVT_DB_RANGE, __VA_ARGS__)
80#define DECLARE_TLV_DB_RANGE(name, ...) \
81 unsigned int name[] = { TLV_DB_RANGE_ITEM(__VA_ARGS__) }
82/* The below assumes that each item TLV is 4 words like DB_SCALE or LINEAR */
83#define TLV_DB_RANGE_HEAD(num) \
84 SNDRV_CTL_TLVT_DB_RANGE, 6 * (num) * sizeof(unsigned int) 58 SNDRV_CTL_TLVT_DB_RANGE, 6 * (num) * sizeof(unsigned int)
85 59
86#define TLV_DB_GAIN_MUTE -9999999
87
88#endif /* __SOUND_TLV_H */ 60#endif /* __SOUND_TLV_H */
diff --git a/include/uapi/sound/Kbuild b/include/uapi/sound/Kbuild
index 691984cb0b91..9578d8bdbf31 100644
--- a/include/uapi/sound/Kbuild
+++ b/include/uapi/sound/Kbuild
@@ -13,3 +13,4 @@ header-y += sb16_csp.h
13header-y += sfnt_info.h 13header-y += sfnt_info.h
14header-y += tlv.h 14header-y += tlv.h
15header-y += usb_stream.h 15header-y += usb_stream.h
16header-y += snd_sst_tokens.h
diff --git a/include/uapi/sound/asoc.h b/include/uapi/sound/asoc.h
index e4701a3c6331..33d00a4ce656 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 0x4 86#define SND_SOC_TPLG_ABI_VERSION 0x5
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
@@ -105,7 +105,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_BACKEND_LINK 10 106#define SND_SOC_TPLG_TYPE_BACKEND_LINK 10
107#define SND_SOC_TPLG_TYPE_PDATA 11 107#define SND_SOC_TPLG_TYPE_PDATA 11
108#define SND_SOC_TPLG_TYPE_MAX SND_SOC_TPLG_TYPE_PDATA 108#define SND_SOC_TPLG_TYPE_BE_DAI 12
109#define SND_SOC_TPLG_TYPE_MAX SND_SOC_TPLG_TYPE_BE_DAI
109 110
110/* vendor block IDs - please add new vendor types to end */ 111/* vendor block IDs - please add new vendor types to end */
111#define SND_SOC_TPLG_TYPE_VENDOR_FW 1000 112#define SND_SOC_TPLG_TYPE_VENDOR_FW 1000
@@ -124,6 +125,11 @@
124#define SND_SOC_TPLG_TUPLE_TYPE_WORD 4 125#define SND_SOC_TPLG_TUPLE_TYPE_WORD 4
125#define SND_SOC_TPLG_TUPLE_TYPE_SHORT 5 126#define SND_SOC_TPLG_TUPLE_TYPE_SHORT 5
126 127
128/* BE DAI flags */
129#define SND_SOC_TPLG_DAI_FLGBIT_SYMMETRIC_RATES (1 << 0)
130#define SND_SOC_TPLG_DAI_FLGBIT_SYMMETRIC_CHANNELS (1 << 1)
131#define SND_SOC_TPLG_DAI_FLGBIT_SYMMETRIC_SAMPLEBITS (1 << 2)
132
127/* 133/*
128 * Block Header. 134 * Block Header.
129 * This header precedes all object and object arrays below. 135 * This header precedes all object and object arrays below.
@@ -251,6 +257,7 @@ struct snd_soc_tplg_stream_caps {
251 __le32 period_size_max; /* max period size bytes */ 257 __le32 period_size_max; /* max period size bytes */
252 __le32 buffer_size_min; /* min buffer size bytes */ 258 __le32 buffer_size_min; /* min buffer size bytes */
253 __le32 buffer_size_max; /* max buffer size bytes */ 259 __le32 buffer_size_max; /* max buffer size bytes */
260 __le32 sig_bits; /* number of bits of content */
254} __attribute__((packed)); 261} __attribute__((packed));
255 262
256/* 263/*
@@ -285,6 +292,8 @@ struct snd_soc_tplg_manifest {
285 __le32 graph_elems; /* number of graph elements */ 292 __le32 graph_elems; /* number of graph elements */
286 __le32 pcm_elems; /* number of PCM elements */ 293 __le32 pcm_elems; /* number of PCM elements */
287 __le32 dai_link_elems; /* number of DAI link elements */ 294 __le32 dai_link_elems; /* number of DAI link elements */
295 __le32 be_dai_elems; /* number of BE DAI elements */
296 __le32 reserved[20]; /* reserved for new ABI element types */
288 struct snd_soc_tplg_private priv; 297 struct snd_soc_tplg_private priv;
289} __attribute__((packed)); 298} __attribute__((packed));
290 299
@@ -450,4 +459,26 @@ struct snd_soc_tplg_link_config {
450 struct snd_soc_tplg_stream stream[SND_SOC_TPLG_STREAM_CONFIG_MAX]; /* supported configs playback and captrure */ 459 struct snd_soc_tplg_stream stream[SND_SOC_TPLG_STREAM_CONFIG_MAX]; /* supported configs playback and captrure */
451 __le32 num_streams; /* number of streams */ 460 __le32 num_streams; /* number of streams */
452} __attribute__((packed)); 461} __attribute__((packed));
462
463/*
464 * Describes SW/FW specific features of BE DAI.
465 *
466 * File block representation for BE DAI :-
467 * +-----------------------------------+-----+
468 * | struct snd_soc_tplg_hdr | 1 |
469 * +-----------------------------------+-----+
470 * | struct snd_soc_tplg_be_dai | N |
471 * +-----------------------------------+-----+
472 */
473struct snd_soc_tplg_be_dai {
474 __le32 size; /* in bytes of this structure */
475 char dai_name[SNDRV_CTL_ELEM_ID_NAME_MAXLEN]; /* name - used to match */
476 __le32 dai_id; /* unique ID - used to match */
477 __le32 playback; /* supports playback mode */
478 __le32 capture; /* supports capture mode */
479 struct snd_soc_tplg_stream_caps caps[2]; /* playback and capture for DAI */
480 __le32 flag_mask; /* bitmask of flags to configure */
481 __le32 flags; /* SND_SOC_TPLG_DAI_FLGBIT_* */
482 struct snd_soc_tplg_private priv;
483} __attribute__((packed));
453#endif 484#endif
diff --git a/include/uapi/sound/asound.h b/include/uapi/sound/asound.h
index 609cadb8739d..be353a78c303 100644
--- a/include/uapi/sound/asound.h
+++ b/include/uapi/sound/asound.h
@@ -106,9 +106,10 @@ enum {
106 SNDRV_HWDEP_IFACE_FW_OXFW, /* Oxford OXFW970/971 based device */ 106 SNDRV_HWDEP_IFACE_FW_OXFW, /* Oxford OXFW970/971 based device */
107 SNDRV_HWDEP_IFACE_FW_DIGI00X, /* Digidesign Digi 002/003 family */ 107 SNDRV_HWDEP_IFACE_FW_DIGI00X, /* Digidesign Digi 002/003 family */
108 SNDRV_HWDEP_IFACE_FW_TASCAM, /* TASCAM FireWire series */ 108 SNDRV_HWDEP_IFACE_FW_TASCAM, /* TASCAM FireWire series */
109 SNDRV_HWDEP_IFACE_LINE6, /* Line6 USB processors */
109 110
110 /* Don't forget to change the following: */ 111 /* Don't forget to change the following: */
111 SNDRV_HWDEP_IFACE_LAST = SNDRV_HWDEP_IFACE_FW_TASCAM 112 SNDRV_HWDEP_IFACE_LAST = SNDRV_HWDEP_IFACE_LINE6
112}; 113};
113 114
114struct snd_hwdep_info { 115struct snd_hwdep_info {
diff --git a/include/uapi/sound/snd_sst_tokens.h b/include/uapi/sound/snd_sst_tokens.h
new file mode 100644
index 000000000000..1ee2e943d66a
--- /dev/null
+++ b/include/uapi/sound/snd_sst_tokens.h
@@ -0,0 +1,214 @@
1/*
2 * snd_sst_tokens.h - Intel SST tokens definition
3 *
4 * Copyright (C) 2016 Intel Corp
5 * Author: Shreyas NC <shreyas.nc@intel.com>
6 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
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 version 2, as
10 * published by the Free Software Foundation.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 */
17#ifndef __SND_SST_TOKENS_H__
18#define __SND_SST_TOKENS_H__
19
20/**
21 * %SKL_TKN_UUID: Module UUID
22 *
23 * %SKL_TKN_U8_BLOCK_TYPE: Type of the private data block.Can be:
24 * tuples, bytes, short and words
25 *
26 * %SKL_TKN_U8_IN_PIN_TYPE: Input pin type,
27 * homogenous=0, heterogenous=1
28 *
29 * %SKL_TKN_U8_OUT_PIN_TYPE: Output pin type,
30 * homogenous=0, heterogenous=1
31 * %SKL_TKN_U8_DYN_IN_PIN: Configure Input pin dynamically
32 * if true
33 *
34 * %SKL_TKN_U8_DYN_OUT_PIN: Configure Output pin dynamically
35 * if true
36 *
37 * %SKL_TKN_U8_IN_QUEUE_COUNT: Store the number of Input pins
38 *
39 * %SKL_TKN_U8_OUT_QUEUE_COUNT: Store the number of Output pins
40 *
41 * %SKL_TKN_U8_TIME_SLOT: TDM slot number
42 *
43 * %SKL_TKN_U8_CORE_ID: Stores module affinity value.Can take
44 * the values:
45 * SKL_AFFINITY_CORE_0 = 0,
46 * SKL_AFFINITY_CORE_1,
47 * SKL_AFFINITY_CORE_MAX
48 *
49 * %SKL_TKN_U8_MOD_TYPE: Module type value.
50 *
51 * %SKL_TKN_U8_CONN_TYPE: Module connection type can be a FE,
52 * BE or NONE as defined :
53 * SKL_PIPE_CONN_TYPE_NONE = 0,
54 * SKL_PIPE_CONN_TYPE_FE = 1 (HOST_DMA)
55 * SKL_PIPE_CONN_TYPE_BE = 2 (LINK_DMA)
56 *
57 * %SKL_TKN_U8_DEV_TYPE: Type of device to which the module is
58 * connected
59 * Can take the values:
60 * SKL_DEVICE_BT = 0x0,
61 * SKL_DEVICE_DMIC = 0x1,
62 * SKL_DEVICE_I2S = 0x2,
63 * SKL_DEVICE_SLIMBUS = 0x3,
64 * SKL_DEVICE_HDALINK = 0x4,
65 * SKL_DEVICE_HDAHOST = 0x5,
66 * SKL_DEVICE_NONE
67 *
68 * %SKL_TKN_U8_HW_CONN_TYPE: Connection type of the HW to which the
69 * module is connected
70 * SKL_CONN_NONE = 0,
71 * SKL_CONN_SOURCE = 1,
72 * SKL_CONN_SINK = 2
73 *
74 * %SKL_TKN_U16_PIN_INST_ID: Stores the pin instance id
75 *
76 * %SKL_TKN_U16_MOD_INST_ID: Stores the mdule instance id
77 *
78 * %SKL_TKN_U32_MAX_MCPS: Module max mcps value
79 *
80 * %SKL_TKN_U32_MEM_PAGES: Module resource pages
81 *
82 * %SKL_TKN_U32_OBS: Stores Output Buffer size
83 *
84 * %SKL_TKN_U32_IBS: Stores input buffer size
85 *
86 * %SKL_TKN_U32_VBUS_ID: Module VBUS_ID. PDM=0, SSP0=0,
87 * SSP1=1,SSP2=2,
88 * SSP3=3, SSP4=4,
89 * SSP5=5, SSP6=6,INVALID
90 *
91 * %SKL_TKN_U32_PARAMS_FIXUP: Module Params fixup mask
92 * %SKL_TKN_U32_CONVERTER: Module params converter mask
93 * %SKL_TKN_U32_PIPE_ID: Stores the pipe id
94 *
95 * %SKL_TKN_U32_PIPE_CONN_TYPE: Type of the token to which the pipe is
96 * connected to. It can be
97 * SKL_PIPE_CONN_TYPE_NONE = 0,
98 * SKL_PIPE_CONN_TYPE_FE = 1 (HOST_DMA),
99 * SKL_PIPE_CONN_TYPE_BE = 2 (LINK_DMA),
100 *
101 * %SKL_TKN_U32_PIPE_PRIORITY: Pipe priority value
102 * %SKL_TKN_U32_PIPE_MEM_PGS: Pipe resource pages
103 *
104 * %SKL_TKN_U32_DIR_PIN_COUNT: Value for the direction to set input/output
105 * formats and the pin count.
106 * The first 4 bits have the direction
107 * value and the next 4 have
108 * the pin count value.
109 * SKL_DIR_IN = 0, SKL_DIR_OUT = 1.
110 * The input and output formats
111 * share the same set of tokens
112 * with the distinction between input
113 * and output made by reading direction
114 * token.
115 *
116 * %SKL_TKN_U32_FMT_CH: Supported channel count
117 *
118 * %SKL_TKN_U32_FMT_FREQ: Supported frequency/sample rate
119 *
120 * %SKL_TKN_U32_FMT_BIT_DEPTH: Supported container size
121 *
122 * %SKL_TKN_U32_FMT_SAMPLE_SIZE:Number of samples in the container
123 *
124 * %SKL_TKN_U32_FMT_CH_CONFIG: Supported channel configurations for the
125 * input/output.
126 *
127 * %SKL_TKN_U32_FMT_INTERLEAVE: Interleaving style which can be per
128 * channel or per sample. The values can be :
129 * SKL_INTERLEAVING_PER_CHANNEL = 0,
130 * SKL_INTERLEAVING_PER_SAMPLE = 1,
131 *
132 * %SKL_TKN_U32_FMT_SAMPLE_TYPE:
133 * Specifies the sample type. Can take the
134 * values: SKL_SAMPLE_TYPE_INT_MSB = 0,
135 * SKL_SAMPLE_TYPE_INT_LSB = 1,
136 * SKL_SAMPLE_TYPE_INT_SIGNED = 2,
137 * SKL_SAMPLE_TYPE_INT_UNSIGNED = 3,
138 * SKL_SAMPLE_TYPE_FLOAT = 4
139 *
140 * %SKL_TKN_U32_CH_MAP: Channel map values
141 * %SKL_TKN_U32_MOD_SET_PARAMS: It can take these values:
142 * SKL_PARAM_DEFAULT, SKL_PARAM_INIT,
143 * SKL_PARAM_SET, SKL_PARAM_BIND
144 *
145 * %SKL_TKN_U32_MOD_PARAM_ID: ID of the module params
146 *
147 * %SKL_TKN_U32_CAPS_SET_PARAMS:
148 * Set params value
149 *
150 * %SKL_TKN_U32_CAPS_PARAMS_ID: Params ID
151 *
152 * %SKL_TKN_U32_CAPS_SIZE: Caps size
153 *
154 * %SKL_TKN_U32_PROC_DOMAIN: Specify processing domain
155 *
156 * %SKL_TKN_U32_LIB_COUNT: Specifies the number of libraries
157 *
158 * %SKL_TKN_STR_LIB_NAME: Specifies the library name
159 *
160 * module_id and loadable flags dont have tokens as these values will be
161 * read from the DSP FW manifest
162 */
163enum SKL_TKNS {
164 SKL_TKN_UUID = 1,
165 SKL_TKN_U8_NUM_BLOCKS,
166 SKL_TKN_U8_BLOCK_TYPE,
167 SKL_TKN_U8_IN_PIN_TYPE,
168 SKL_TKN_U8_OUT_PIN_TYPE,
169 SKL_TKN_U8_DYN_IN_PIN,
170 SKL_TKN_U8_DYN_OUT_PIN,
171 SKL_TKN_U8_IN_QUEUE_COUNT,
172 SKL_TKN_U8_OUT_QUEUE_COUNT,
173 SKL_TKN_U8_TIME_SLOT,
174 SKL_TKN_U8_CORE_ID,
175 SKL_TKN_U8_MOD_TYPE,
176 SKL_TKN_U8_CONN_TYPE,
177 SKL_TKN_U8_DEV_TYPE,
178 SKL_TKN_U8_HW_CONN_TYPE,
179 SKL_TKN_U16_MOD_INST_ID,
180 SKL_TKN_U16_BLOCK_SIZE,
181 SKL_TKN_U32_MAX_MCPS,
182 SKL_TKN_U32_MEM_PAGES,
183 SKL_TKN_U32_OBS,
184 SKL_TKN_U32_IBS,
185 SKL_TKN_U32_VBUS_ID,
186 SKL_TKN_U32_PARAMS_FIXUP,
187 SKL_TKN_U32_CONVERTER,
188 SKL_TKN_U32_PIPE_ID,
189 SKL_TKN_U32_PIPE_CONN_TYPE,
190 SKL_TKN_U32_PIPE_PRIORITY,
191 SKL_TKN_U32_PIPE_MEM_PGS,
192 SKL_TKN_U32_DIR_PIN_COUNT,
193 SKL_TKN_U32_FMT_CH,
194 SKL_TKN_U32_FMT_FREQ,
195 SKL_TKN_U32_FMT_BIT_DEPTH,
196 SKL_TKN_U32_FMT_SAMPLE_SIZE,
197 SKL_TKN_U32_FMT_CH_CONFIG,
198 SKL_TKN_U32_FMT_INTERLEAVE,
199 SKL_TKN_U32_FMT_SAMPLE_TYPE,
200 SKL_TKN_U32_FMT_CH_MAP,
201 SKL_TKN_U32_PIN_MOD_ID,
202 SKL_TKN_U32_PIN_INST_ID,
203 SKL_TKN_U32_MOD_SET_PARAMS,
204 SKL_TKN_U32_MOD_PARAM_ID,
205 SKL_TKN_U32_CAPS_SET_PARAMS,
206 SKL_TKN_U32_CAPS_PARAMS_ID,
207 SKL_TKN_U32_CAPS_SIZE,
208 SKL_TKN_U32_PROC_DOMAIN,
209 SKL_TKN_U32_LIB_COUNT,
210 SKL_TKN_STR_LIB_NAME,
211 SKL_TKN_MAX = SKL_TKN_STR_LIB_NAME,
212};
213
214#endif
diff --git a/include/uapi/sound/tlv.h b/include/uapi/sound/tlv.h
index ffc4f203146c..b4df440c015b 100644
--- a/include/uapi/sound/tlv.h
+++ b/include/uapi/sound/tlv.h
@@ -28,4 +28,73 @@
28#define SNDRV_CTL_TLVT_CHMAP_VAR 0x102 /* channels freely swappable */ 28#define SNDRV_CTL_TLVT_CHMAP_VAR 0x102 /* channels freely swappable */
29#define SNDRV_CTL_TLVT_CHMAP_PAIRED 0x103 /* pair-wise swappable */ 29#define SNDRV_CTL_TLVT_CHMAP_PAIRED 0x103 /* pair-wise swappable */
30 30
31/*
32 * TLV structure is right behind the struct snd_ctl_tlv:
33 * unsigned int type - see SNDRV_CTL_TLVT_*
34 * unsigned int length
35 * .... data aligned to sizeof(unsigned int), use
36 * block_length = (length + (sizeof(unsigned int) - 1)) &
37 * ~(sizeof(unsigned int) - 1)) ....
38 */
39#define SNDRV_CTL_TLVD_ITEM(type, ...) \
40 (type), SNDRV_CTL_TLVD_LENGTH(__VA_ARGS__), __VA_ARGS__
41#define SNDRV_CTL_TLVD_LENGTH(...) \
42 ((unsigned int)sizeof((const unsigned int[]) { __VA_ARGS__ }))
43
44#define SNDRV_CTL_TLVD_CONTAINER_ITEM(...) \
45 SNDRV_CTL_TLVD_ITEM(SNDRV_CTL_TLVT_CONTAINER, __VA_ARGS__)
46#define SNDRV_CTL_TLVD_DECLARE_CONTAINER(name, ...) \
47 unsigned int name[] = { \
48 SNDRV_CTL_TLVD_CONTAINER_ITEM(__VA_ARGS__) \
49 }
50
51#define SNDRV_CTL_TLVD_DB_SCALE_MASK 0xffff
52#define SNDRV_CTL_TLVD_DB_SCALE_MUTE 0x10000
53#define SNDRV_CTL_TLVD_DB_SCALE_ITEM(min, step, mute) \
54 SNDRV_CTL_TLVD_ITEM(SNDRV_CTL_TLVT_DB_SCALE, \
55 (min), \
56 ((step) & SNDRV_CTL_TLVD_DB_SCALE_MASK) | \
57 ((mute) ? SNDRV_CTL_TLVD_DB_SCALE_MUTE : 0))
58#define SNDRV_CTL_TLVD_DECLARE_DB_SCALE(name, min, step, mute) \
59 unsigned int name[] = { \
60 SNDRV_CTL_TLVD_DB_SCALE_ITEM(min, step, mute) \
61 }
62
63/* dB scale specified with min/max values instead of step */
64#define SNDRV_CTL_TLVD_DB_MINMAX_ITEM(min_dB, max_dB) \
65 SNDRV_CTL_TLVD_ITEM(SNDRV_CTL_TLVT_DB_MINMAX, (min_dB), (max_dB))
66#define SNDRV_CTL_TLVD_DB_MINMAX_MUTE_ITEM(min_dB, max_dB) \
67 SNDRV_CTL_TLVD_ITEM(SNDRV_CTL_TLVT_DB_MINMAX_MUTE, (min_dB), (max_dB))
68#define SNDRV_CTL_TLVD_DECLARE_DB_MINMAX(name, min_dB, max_dB) \
69 unsigned int name[] = { \
70 SNDRV_CTL_TLVD_DB_MINMAX_ITEM(min_dB, max_dB) \
71 }
72#define SNDRV_CTL_TLVD_DECLARE_DB_MINMAX_MUTE(name, min_dB, max_dB) \
73 unsigned int name[] = { \
74 SNDRV_CTL_TLVD_DB_MINMAX_MUTE_ITEM(min_dB, max_dB) \
75 }
76
77/* linear volume between min_dB and max_dB (.01dB unit) */
78#define SNDRV_CTL_TLVD_DB_LINEAR_ITEM(min_dB, max_dB) \
79 SNDRV_CTL_TLVD_ITEM(SNDRV_CTL_TLVT_DB_LINEAR, (min_dB), (max_dB))
80#define SNDRV_CTL_TLVD_DECLARE_DB_LINEAR(name, min_dB, max_dB) \
81 unsigned int name[] = { \
82 SNDRV_CTL_TLVD_DB_LINEAR_ITEM(min_dB, max_dB) \
83 }
84
85/* dB range container:
86 * Items in dB range container must be ordered by their values and by their
87 * dB values. This implies that larger values must correspond with larger
88 * dB values (which is also required for all other mixer controls).
89 */
90/* Each item is: <min> <max> <TLV> */
91#define SNDRV_CTL_TLVD_DB_RANGE_ITEM(...) \
92 SNDRV_CTL_TLVD_ITEM(SNDRV_CTL_TLVT_DB_RANGE, __VA_ARGS__)
93#define SNDRV_CTL_TLVD_DECLARE_DB_RANGE(name, ...) \
94 unsigned int name[] = { \
95 SNDRV_CTL_TLVD_DB_RANGE_ITEM(__VA_ARGS__) \
96 }
97
98#define SNDRV_CTL_TLVD_DB_GAIN_MUTE -9999999
99
31#endif 100#endif
diff --git a/sound/aoa/fabrics/layout.c b/sound/aoa/fabrics/layout.c
index 8f71f7e4d966..a0c4a5de809c 100644
--- a/sound/aoa/fabrics/layout.c
+++ b/sound/aoa/fabrics/layout.c
@@ -112,6 +112,7 @@ MODULE_ALIAS("sound-layout-100");
112 112
113MODULE_ALIAS("aoa-device-id-14"); 113MODULE_ALIAS("aoa-device-id-14");
114MODULE_ALIAS("aoa-device-id-22"); 114MODULE_ALIAS("aoa-device-id-22");
115MODULE_ALIAS("aoa-device-id-31");
115MODULE_ALIAS("aoa-device-id-35"); 116MODULE_ALIAS("aoa-device-id-35");
116MODULE_ALIAS("aoa-device-id-44"); 117MODULE_ALIAS("aoa-device-id-44");
117 118
@@ -362,6 +363,13 @@ static struct layout layouts[] = {
362 .connections = tas_connections_nolineout, 363 .connections = tas_connections_nolineout,
363 }, 364 },
364 }, 365 },
366 /* PowerBook6,1 */
367 { .device_id = 31,
368 .codecs[0] = {
369 .name = "tas",
370 .connections = tas_connections_nolineout,
371 },
372 },
365 /* PowerBook6,5 */ 373 /* PowerBook6,5 */
366 { .device_id = 44, 374 { .device_id = 44,
367 .codecs[0] = { 375 .codecs[0] = {
@@ -1161,12 +1169,7 @@ static struct soundbus_driver aoa_soundbus_driver = {
1161 1169
1162static int __init aoa_fabric_layout_init(void) 1170static int __init aoa_fabric_layout_init(void)
1163{ 1171{
1164 int err; 1172 return soundbus_register_driver(&aoa_soundbus_driver);
1165
1166 err = soundbus_register_driver(&aoa_soundbus_driver);
1167 if (err)
1168 return err;
1169 return 0;
1170} 1173}
1171 1174
1172static void __exit aoa_fabric_layout_exit(void) 1175static void __exit aoa_fabric_layout_exit(void)
diff --git a/sound/aoa/soundbus/i2sbus/core.c b/sound/aoa/soundbus/i2sbus/core.c
index 1cbf210080a1..000b58522106 100644
--- a/sound/aoa/soundbus/i2sbus/core.c
+++ b/sound/aoa/soundbus/i2sbus/core.c
@@ -197,7 +197,7 @@ static int i2sbus_add_dev(struct macio_dev *macio,
197 * so restrict to those we do handle for now. 197 * so restrict to those we do handle for now.
198 */ 198 */
199 if (id && (*id == 22 || *id == 14 || *id == 35 || 199 if (id && (*id == 22 || *id == 14 || *id == 35 ||
200 *id == 44)) { 200 *id == 31 || *id == 44)) {
201 snprintf(dev->sound.modalias, 32, 201 snprintf(dev->sound.modalias, 32,
202 "aoa-device-id-%d", *id); 202 "aoa-device-id-%d", *id);
203 ok = 1; 203 ok = 1;
diff --git a/sound/core/compress_offload.c b/sound/core/compress_offload.c
index 2c498488af6c..fec1dfdb14ad 100644
--- a/sound/core/compress_offload.c
+++ b/sound/core/compress_offload.c
@@ -553,13 +553,9 @@ snd_compr_set_params(struct snd_compr_stream *stream, unsigned long arg)
553 * we should allow parameter change only when stream has been 553 * we should allow parameter change only when stream has been
554 * opened not in other cases 554 * opened not in other cases
555 */ 555 */
556 params = kmalloc(sizeof(*params), GFP_KERNEL); 556 params = memdup_user((void __user *)arg, sizeof(*params));
557 if (!params) 557 if (IS_ERR(params))
558 return -ENOMEM; 558 return PTR_ERR(params);
559 if (copy_from_user(params, (void __user *)arg, sizeof(*params))) {
560 retval = -EFAULT;
561 goto out;
562 }
563 559
564 retval = snd_compress_check_input(params); 560 retval = snd_compress_check_input(params);
565 if (retval) 561 if (retval)
@@ -784,7 +780,7 @@ static int snd_compress_wait_for_drain(struct snd_compr_stream *stream)
784 ret = wait_event_interruptible(stream->runtime->sleep, 780 ret = wait_event_interruptible(stream->runtime->sleep,
785 (stream->runtime->state != SNDRV_PCM_STATE_DRAINING)); 781 (stream->runtime->state != SNDRV_PCM_STATE_DRAINING));
786 if (ret == -ERESTARTSYS) 782 if (ret == -ERESTARTSYS)
787 pr_debug("wait aborted by a signal"); 783 pr_debug("wait aborted by a signal\n");
788 else if (ret) 784 else if (ret)
789 pr_debug("wait for drain failed with %d\n", ret); 785 pr_debug("wait for drain failed with %d\n", ret);
790 786
@@ -966,7 +962,7 @@ static int snd_compress_dev_register(struct snd_device *device)
966 compr->card, compr->device, 962 compr->card, compr->device,
967 &snd_compr_file_ops, compr, &compr->dev); 963 &snd_compr_file_ops, compr, &compr->dev);
968 if (ret < 0) { 964 if (ret < 0) {
969 pr_err("snd_register_device failed\n %d", ret); 965 pr_err("snd_register_device failed %d\n", ret);
970 return ret; 966 return ret;
971 } 967 }
972 return ret; 968 return ret;
diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c
index c61fd50f771f..9d33c1e85c79 100644
--- a/sound/core/pcm_native.c
+++ b/sound/core/pcm_native.c
@@ -2637,9 +2637,11 @@ static int snd_pcm_hwsync(struct snd_pcm_substream *substream)
2637 break; 2637 break;
2638 /* Fall through */ 2638 /* Fall through */
2639 case SNDRV_PCM_STATE_PREPARED: 2639 case SNDRV_PCM_STATE_PREPARED:
2640 case SNDRV_PCM_STATE_SUSPENDED:
2641 err = 0; 2640 err = 0;
2642 break; 2641 break;
2642 case SNDRV_PCM_STATE_SUSPENDED:
2643 err = -ESTRPIPE;
2644 break;
2643 case SNDRV_PCM_STATE_XRUN: 2645 case SNDRV_PCM_STATE_XRUN:
2644 err = -EPIPE; 2646 err = -EPIPE;
2645 break; 2647 break;
diff --git a/sound/core/seq/seq_clientmgr.c b/sound/core/seq/seq_clientmgr.c
index d6d9419d8bac..4c935202ce23 100644
--- a/sound/core/seq/seq_clientmgr.c
+++ b/sound/core/seq/seq_clientmgr.c
@@ -87,21 +87,6 @@ static int snd_seq_deliver_single_event(struct snd_seq_client *client,
87 87
88/* 88/*
89 */ 89 */
90
91static inline mm_segment_t snd_enter_user(void)
92{
93 mm_segment_t fs = get_fs();
94 set_fs(get_ds());
95 return fs;
96}
97
98static inline void snd_leave_user(mm_segment_t fs)
99{
100 set_fs(fs);
101}
102
103/*
104 */
105static inline unsigned short snd_seq_file_flags(struct file *file) 90static inline unsigned short snd_seq_file_flags(struct file *file)
106{ 91{
107 switch (file->f_mode & (FMODE_READ | FMODE_WRITE)) { 92 switch (file->f_mode & (FMODE_READ | FMODE_WRITE)) {
@@ -1128,59 +1113,69 @@ static unsigned int snd_seq_poll(struct file *file, poll_table * wait)
1128 1113
1129/*-----------------------------------------------------*/ 1114/*-----------------------------------------------------*/
1130 1115
1116static int snd_seq_ioctl_pversion(struct snd_seq_client *client, void *arg)
1117{
1118 int *pversion = arg;
1119
1120 *pversion = SNDRV_SEQ_VERSION;
1121 return 0;
1122}
1123
1124static int snd_seq_ioctl_client_id(struct snd_seq_client *client, void *arg)
1125{
1126 int *client_id = arg;
1127
1128 *client_id = client->number;
1129 return 0;
1130}
1131 1131
1132/* SYSTEM_INFO ioctl() */ 1132/* SYSTEM_INFO ioctl() */
1133static int snd_seq_ioctl_system_info(struct snd_seq_client *client, void __user *arg) 1133static int snd_seq_ioctl_system_info(struct snd_seq_client *client, void *arg)
1134{ 1134{
1135 struct snd_seq_system_info info; 1135 struct snd_seq_system_info *info = arg;
1136 1136
1137 memset(&info, 0, sizeof(info)); 1137 memset(info, 0, sizeof(*info));
1138 /* fill the info fields */ 1138 /* fill the info fields */
1139 info.queues = SNDRV_SEQ_MAX_QUEUES; 1139 info->queues = SNDRV_SEQ_MAX_QUEUES;
1140 info.clients = SNDRV_SEQ_MAX_CLIENTS; 1140 info->clients = SNDRV_SEQ_MAX_CLIENTS;
1141 info.ports = SNDRV_SEQ_MAX_PORTS; 1141 info->ports = SNDRV_SEQ_MAX_PORTS;
1142 info.channels = 256; /* fixed limit */ 1142 info->channels = 256; /* fixed limit */
1143 info.cur_clients = client_usage.cur; 1143 info->cur_clients = client_usage.cur;
1144 info.cur_queues = snd_seq_queue_get_cur_queues(); 1144 info->cur_queues = snd_seq_queue_get_cur_queues();
1145 1145
1146 if (copy_to_user(arg, &info, sizeof(info)))
1147 return -EFAULT;
1148 return 0; 1146 return 0;
1149} 1147}
1150 1148
1151 1149
1152/* RUNNING_MODE ioctl() */ 1150/* RUNNING_MODE ioctl() */
1153static int snd_seq_ioctl_running_mode(struct snd_seq_client *client, void __user *arg) 1151static int snd_seq_ioctl_running_mode(struct snd_seq_client *client, void *arg)
1154{ 1152{
1155 struct snd_seq_running_info info; 1153 struct snd_seq_running_info *info = arg;
1156 struct snd_seq_client *cptr; 1154 struct snd_seq_client *cptr;
1157 int err = 0; 1155 int err = 0;
1158 1156
1159 if (copy_from_user(&info, arg, sizeof(info)))
1160 return -EFAULT;
1161
1162 /* requested client number */ 1157 /* requested client number */
1163 cptr = snd_seq_client_use_ptr(info.client); 1158 cptr = snd_seq_client_use_ptr(info->client);
1164 if (cptr == NULL) 1159 if (cptr == NULL)
1165 return -ENOENT; /* don't change !!! */ 1160 return -ENOENT; /* don't change !!! */
1166 1161
1167#ifdef SNDRV_BIG_ENDIAN 1162#ifdef SNDRV_BIG_ENDIAN
1168 if (! info.big_endian) { 1163 if (!info->big_endian) {
1169 err = -EINVAL; 1164 err = -EINVAL;
1170 goto __err; 1165 goto __err;
1171 } 1166 }
1172#else 1167#else
1173 if (info.big_endian) { 1168 if (info->big_endian) {
1174 err = -EINVAL; 1169 err = -EINVAL;
1175 goto __err; 1170 goto __err;
1176 } 1171 }
1177 1172
1178#endif 1173#endif
1179 if (info.cpu_mode > sizeof(long)) { 1174 if (info->cpu_mode > sizeof(long)) {
1180 err = -EINVAL; 1175 err = -EINVAL;
1181 goto __err; 1176 goto __err;
1182 } 1177 }
1183 cptr->convert32 = (info.cpu_mode < sizeof(long)); 1178 cptr->convert32 = (info->cpu_mode < sizeof(long));
1184 __err: 1179 __err:
1185 snd_seq_client_unlock(cptr); 1180 snd_seq_client_unlock(cptr);
1186 return err; 1181 return err;
@@ -1214,51 +1209,43 @@ static void get_client_info(struct snd_seq_client *cptr,
1214} 1209}
1215 1210
1216static int snd_seq_ioctl_get_client_info(struct snd_seq_client *client, 1211static int snd_seq_ioctl_get_client_info(struct snd_seq_client *client,
1217 void __user *arg) 1212 void *arg)
1218{ 1213{
1214 struct snd_seq_client_info *client_info = arg;
1219 struct snd_seq_client *cptr; 1215 struct snd_seq_client *cptr;
1220 struct snd_seq_client_info client_info;
1221
1222 if (copy_from_user(&client_info, arg, sizeof(client_info)))
1223 return -EFAULT;
1224 1216
1225 /* requested client number */ 1217 /* requested client number */
1226 cptr = snd_seq_client_use_ptr(client_info.client); 1218 cptr = snd_seq_client_use_ptr(client_info->client);
1227 if (cptr == NULL) 1219 if (cptr == NULL)
1228 return -ENOENT; /* don't change !!! */ 1220 return -ENOENT; /* don't change !!! */
1229 1221
1230 get_client_info(cptr, &client_info); 1222 get_client_info(cptr, client_info);
1231 snd_seq_client_unlock(cptr); 1223 snd_seq_client_unlock(cptr);
1232 1224
1233 if (copy_to_user(arg, &client_info, sizeof(client_info)))
1234 return -EFAULT;
1235 return 0; 1225 return 0;
1236} 1226}
1237 1227
1238 1228
1239/* CLIENT_INFO ioctl() */ 1229/* CLIENT_INFO ioctl() */
1240static int snd_seq_ioctl_set_client_info(struct snd_seq_client *client, 1230static int snd_seq_ioctl_set_client_info(struct snd_seq_client *client,
1241 void __user *arg) 1231 void *arg)
1242{ 1232{
1243 struct snd_seq_client_info client_info; 1233 struct snd_seq_client_info *client_info = arg;
1244
1245 if (copy_from_user(&client_info, arg, sizeof(client_info)))
1246 return -EFAULT;
1247 1234
1248 /* it is not allowed to set the info fields for an another client */ 1235 /* it is not allowed to set the info fields for an another client */
1249 if (client->number != client_info.client) 1236 if (client->number != client_info->client)
1250 return -EPERM; 1237 return -EPERM;
1251 /* also client type must be set now */ 1238 /* also client type must be set now */
1252 if (client->type != client_info.type) 1239 if (client->type != client_info->type)
1253 return -EINVAL; 1240 return -EINVAL;
1254 1241
1255 /* fill the info fields */ 1242 /* fill the info fields */
1256 if (client_info.name[0]) 1243 if (client_info->name[0])
1257 strlcpy(client->name, client_info.name, sizeof(client->name)); 1244 strlcpy(client->name, client_info->name, sizeof(client->name));
1258 1245
1259 client->filter = client_info.filter; 1246 client->filter = client_info->filter;
1260 client->event_lost = client_info.event_lost; 1247 client->event_lost = client_info->event_lost;
1261 memcpy(client->event_filter, client_info.event_filter, 32); 1248 memcpy(client->event_filter, client_info->event_filter, 32);
1262 1249
1263 return 0; 1250 return 0;
1264} 1251}
@@ -1267,30 +1254,26 @@ static int snd_seq_ioctl_set_client_info(struct snd_seq_client *client,
1267/* 1254/*
1268 * CREATE PORT ioctl() 1255 * CREATE PORT ioctl()
1269 */ 1256 */
1270static int snd_seq_ioctl_create_port(struct snd_seq_client *client, 1257static int snd_seq_ioctl_create_port(struct snd_seq_client *client, void *arg)
1271 void __user *arg)
1272{ 1258{
1259 struct snd_seq_port_info *info = arg;
1273 struct snd_seq_client_port *port; 1260 struct snd_seq_client_port *port;
1274 struct snd_seq_port_info info;
1275 struct snd_seq_port_callback *callback; 1261 struct snd_seq_port_callback *callback;
1276 1262
1277 if (copy_from_user(&info, arg, sizeof(info)))
1278 return -EFAULT;
1279
1280 /* it is not allowed to create the port for an another client */ 1263 /* it is not allowed to create the port for an another client */
1281 if (info.addr.client != client->number) 1264 if (info->addr.client != client->number)
1282 return -EPERM; 1265 return -EPERM;
1283 1266
1284 port = snd_seq_create_port(client, (info.flags & SNDRV_SEQ_PORT_FLG_GIVEN_PORT) ? info.addr.port : -1); 1267 port = snd_seq_create_port(client, (info->flags & SNDRV_SEQ_PORT_FLG_GIVEN_PORT) ? info->addr.port : -1);
1285 if (port == NULL) 1268 if (port == NULL)
1286 return -ENOMEM; 1269 return -ENOMEM;
1287 1270
1288 if (client->type == USER_CLIENT && info.kernel) { 1271 if (client->type == USER_CLIENT && info->kernel) {
1289 snd_seq_delete_port(client, port->addr.port); 1272 snd_seq_delete_port(client, port->addr.port);
1290 return -EINVAL; 1273 return -EINVAL;
1291 } 1274 }
1292 if (client->type == KERNEL_CLIENT) { 1275 if (client->type == KERNEL_CLIENT) {
1293 if ((callback = info.kernel) != NULL) { 1276 if ((callback = info->kernel) != NULL) {
1294 if (callback->owner) 1277 if (callback->owner)
1295 port->owner = callback->owner; 1278 port->owner = callback->owner;
1296 port->private_data = callback->private_data; 1279 port->private_data = callback->private_data;
@@ -1303,37 +1286,29 @@ static int snd_seq_ioctl_create_port(struct snd_seq_client *client,
1303 } 1286 }
1304 } 1287 }
1305 1288
1306 info.addr = port->addr; 1289 info->addr = port->addr;
1307 1290
1308 snd_seq_set_port_info(port, &info); 1291 snd_seq_set_port_info(port, info);
1309 snd_seq_system_client_ev_port_start(port->addr.client, port->addr.port); 1292 snd_seq_system_client_ev_port_start(port->addr.client, port->addr.port);
1310 1293
1311 if (copy_to_user(arg, &info, sizeof(info)))
1312 return -EFAULT;
1313
1314 return 0; 1294 return 0;
1315} 1295}
1316 1296
1317/* 1297/*
1318 * DELETE PORT ioctl() 1298 * DELETE PORT ioctl()
1319 */ 1299 */
1320static int snd_seq_ioctl_delete_port(struct snd_seq_client *client, 1300static int snd_seq_ioctl_delete_port(struct snd_seq_client *client, void *arg)
1321 void __user *arg)
1322{ 1301{
1323 struct snd_seq_port_info info; 1302 struct snd_seq_port_info *info = arg;
1324 int err; 1303 int err;
1325 1304
1326 /* set passed parameters */
1327 if (copy_from_user(&info, arg, sizeof(info)))
1328 return -EFAULT;
1329
1330 /* it is not allowed to remove the port for an another client */ 1305 /* it is not allowed to remove the port for an another client */
1331 if (info.addr.client != client->number) 1306 if (info->addr.client != client->number)
1332 return -EPERM; 1307 return -EPERM;
1333 1308
1334 err = snd_seq_delete_port(client, info.addr.port); 1309 err = snd_seq_delete_port(client, info->addr.port);
1335 if (err >= 0) 1310 if (err >= 0)
1336 snd_seq_system_client_ev_port_exit(client->number, info.addr.port); 1311 snd_seq_system_client_ev_port_exit(client->number, info->addr.port);
1337 return err; 1312 return err;
1338} 1313}
1339 1314
@@ -1341,32 +1316,27 @@ static int snd_seq_ioctl_delete_port(struct snd_seq_client *client,
1341/* 1316/*
1342 * GET_PORT_INFO ioctl() (on any client) 1317 * GET_PORT_INFO ioctl() (on any client)
1343 */ 1318 */
1344static int snd_seq_ioctl_get_port_info(struct snd_seq_client *client, 1319static int snd_seq_ioctl_get_port_info(struct snd_seq_client *client, void *arg)
1345 void __user *arg)
1346{ 1320{
1321 struct snd_seq_port_info *info = arg;
1347 struct snd_seq_client *cptr; 1322 struct snd_seq_client *cptr;
1348 struct snd_seq_client_port *port; 1323 struct snd_seq_client_port *port;
1349 struct snd_seq_port_info info;
1350 1324
1351 if (copy_from_user(&info, arg, sizeof(info))) 1325 cptr = snd_seq_client_use_ptr(info->addr.client);
1352 return -EFAULT;
1353 cptr = snd_seq_client_use_ptr(info.addr.client);
1354 if (cptr == NULL) 1326 if (cptr == NULL)
1355 return -ENXIO; 1327 return -ENXIO;
1356 1328
1357 port = snd_seq_port_use_ptr(cptr, info.addr.port); 1329 port = snd_seq_port_use_ptr(cptr, info->addr.port);
1358 if (port == NULL) { 1330 if (port == NULL) {
1359 snd_seq_client_unlock(cptr); 1331 snd_seq_client_unlock(cptr);
1360 return -ENOENT; /* don't change */ 1332 return -ENOENT; /* don't change */
1361 } 1333 }
1362 1334
1363 /* get port info */ 1335 /* get port info */
1364 snd_seq_get_port_info(port, &info); 1336 snd_seq_get_port_info(port, info);
1365 snd_seq_port_unlock(port); 1337 snd_seq_port_unlock(port);
1366 snd_seq_client_unlock(cptr); 1338 snd_seq_client_unlock(cptr);
1367 1339
1368 if (copy_to_user(arg, &info, sizeof(info)))
1369 return -EFAULT;
1370 return 0; 1340 return 0;
1371} 1341}
1372 1342
@@ -1374,20 +1344,16 @@ static int snd_seq_ioctl_get_port_info(struct snd_seq_client *client,
1374/* 1344/*
1375 * SET_PORT_INFO ioctl() (only ports on this/own client) 1345 * SET_PORT_INFO ioctl() (only ports on this/own client)
1376 */ 1346 */
1377static int snd_seq_ioctl_set_port_info(struct snd_seq_client *client, 1347static int snd_seq_ioctl_set_port_info(struct snd_seq_client *client, void *arg)
1378 void __user *arg)
1379{ 1348{
1349 struct snd_seq_port_info *info = arg;
1380 struct snd_seq_client_port *port; 1350 struct snd_seq_client_port *port;
1381 struct snd_seq_port_info info;
1382
1383 if (copy_from_user(&info, arg, sizeof(info)))
1384 return -EFAULT;
1385 1351
1386 if (info.addr.client != client->number) /* only set our own ports ! */ 1352 if (info->addr.client != client->number) /* only set our own ports ! */
1387 return -EPERM; 1353 return -EPERM;
1388 port = snd_seq_port_use_ptr(client, info.addr.port); 1354 port = snd_seq_port_use_ptr(client, info->addr.port);
1389 if (port) { 1355 if (port) {
1390 snd_seq_set_port_info(port, &info); 1356 snd_seq_set_port_info(port, info);
1391 snd_seq_port_unlock(port); 1357 snd_seq_port_unlock(port);
1392 } 1358 }
1393 return 0; 1359 return 0;
@@ -1453,34 +1419,31 @@ int snd_seq_client_notify_subscription(int client, int port,
1453 * add to port's subscription list IOCTL interface 1419 * add to port's subscription list IOCTL interface
1454 */ 1420 */
1455static int snd_seq_ioctl_subscribe_port(struct snd_seq_client *client, 1421static int snd_seq_ioctl_subscribe_port(struct snd_seq_client *client,
1456 void __user *arg) 1422 void *arg)
1457{ 1423{
1424 struct snd_seq_port_subscribe *subs = arg;
1458 int result = -EINVAL; 1425 int result = -EINVAL;
1459 struct snd_seq_client *receiver = NULL, *sender = NULL; 1426 struct snd_seq_client *receiver = NULL, *sender = NULL;
1460 struct snd_seq_client_port *sport = NULL, *dport = NULL; 1427 struct snd_seq_client_port *sport = NULL, *dport = NULL;
1461 struct snd_seq_port_subscribe subs;
1462
1463 if (copy_from_user(&subs, arg, sizeof(subs)))
1464 return -EFAULT;
1465 1428
1466 if ((receiver = snd_seq_client_use_ptr(subs.dest.client)) == NULL) 1429 if ((receiver = snd_seq_client_use_ptr(subs->dest.client)) == NULL)
1467 goto __end; 1430 goto __end;
1468 if ((sender = snd_seq_client_use_ptr(subs.sender.client)) == NULL) 1431 if ((sender = snd_seq_client_use_ptr(subs->sender.client)) == NULL)
1469 goto __end; 1432 goto __end;
1470 if ((sport = snd_seq_port_use_ptr(sender, subs.sender.port)) == NULL) 1433 if ((sport = snd_seq_port_use_ptr(sender, subs->sender.port)) == NULL)
1471 goto __end; 1434 goto __end;
1472 if ((dport = snd_seq_port_use_ptr(receiver, subs.dest.port)) == NULL) 1435 if ((dport = snd_seq_port_use_ptr(receiver, subs->dest.port)) == NULL)
1473 goto __end; 1436 goto __end;
1474 1437
1475 result = check_subscription_permission(client, sport, dport, &subs); 1438 result = check_subscription_permission(client, sport, dport, subs);
1476 if (result < 0) 1439 if (result < 0)
1477 goto __end; 1440 goto __end;
1478 1441
1479 /* connect them */ 1442 /* connect them */
1480 result = snd_seq_port_connect(client, sender, sport, receiver, dport, &subs); 1443 result = snd_seq_port_connect(client, sender, sport, receiver, dport, subs);
1481 if (! result) /* broadcast announce */ 1444 if (! result) /* broadcast announce */
1482 snd_seq_client_notify_subscription(SNDRV_SEQ_ADDRESS_SUBSCRIBERS, 0, 1445 snd_seq_client_notify_subscription(SNDRV_SEQ_ADDRESS_SUBSCRIBERS, 0,
1483 &subs, SNDRV_SEQ_EVENT_PORT_SUBSCRIBED); 1446 subs, SNDRV_SEQ_EVENT_PORT_SUBSCRIBED);
1484 __end: 1447 __end:
1485 if (sport) 1448 if (sport)
1486 snd_seq_port_unlock(sport); 1449 snd_seq_port_unlock(sport);
@@ -1498,33 +1461,30 @@ static int snd_seq_ioctl_subscribe_port(struct snd_seq_client *client,
1498 * remove from port's subscription list 1461 * remove from port's subscription list
1499 */ 1462 */
1500static int snd_seq_ioctl_unsubscribe_port(struct snd_seq_client *client, 1463static int snd_seq_ioctl_unsubscribe_port(struct snd_seq_client *client,
1501 void __user *arg) 1464 void *arg)
1502{ 1465{
1466 struct snd_seq_port_subscribe *subs = arg;
1503 int result = -ENXIO; 1467 int result = -ENXIO;
1504 struct snd_seq_client *receiver = NULL, *sender = NULL; 1468 struct snd_seq_client *receiver = NULL, *sender = NULL;
1505 struct snd_seq_client_port *sport = NULL, *dport = NULL; 1469 struct snd_seq_client_port *sport = NULL, *dport = NULL;
1506 struct snd_seq_port_subscribe subs;
1507
1508 if (copy_from_user(&subs, arg, sizeof(subs)))
1509 return -EFAULT;
1510 1470
1511 if ((receiver = snd_seq_client_use_ptr(subs.dest.client)) == NULL) 1471 if ((receiver = snd_seq_client_use_ptr(subs->dest.client)) == NULL)
1512 goto __end; 1472 goto __end;
1513 if ((sender = snd_seq_client_use_ptr(subs.sender.client)) == NULL) 1473 if ((sender = snd_seq_client_use_ptr(subs->sender.client)) == NULL)
1514 goto __end; 1474 goto __end;
1515 if ((sport = snd_seq_port_use_ptr(sender, subs.sender.port)) == NULL) 1475 if ((sport = snd_seq_port_use_ptr(sender, subs->sender.port)) == NULL)
1516 goto __end; 1476 goto __end;
1517 if ((dport = snd_seq_port_use_ptr(receiver, subs.dest.port)) == NULL) 1477 if ((dport = snd_seq_port_use_ptr(receiver, subs->dest.port)) == NULL)
1518 goto __end; 1478 goto __end;
1519 1479
1520 result = check_subscription_permission(client, sport, dport, &subs); 1480 result = check_subscription_permission(client, sport, dport, subs);
1521 if (result < 0) 1481 if (result < 0)
1522 goto __end; 1482 goto __end;
1523 1483
1524 result = snd_seq_port_disconnect(client, sender, sport, receiver, dport, &subs); 1484 result = snd_seq_port_disconnect(client, sender, sport, receiver, dport, subs);
1525 if (! result) /* broadcast announce */ 1485 if (! result) /* broadcast announce */
1526 snd_seq_client_notify_subscription(SNDRV_SEQ_ADDRESS_SUBSCRIBERS, 0, 1486 snd_seq_client_notify_subscription(SNDRV_SEQ_ADDRESS_SUBSCRIBERS, 0,
1527 &subs, SNDRV_SEQ_EVENT_PORT_UNSUBSCRIBED); 1487 subs, SNDRV_SEQ_EVENT_PORT_UNSUBSCRIBED);
1528 __end: 1488 __end:
1529 if (sport) 1489 if (sport)
1530 snd_seq_port_unlock(sport); 1490 snd_seq_port_unlock(sport);
@@ -1539,17 +1499,13 @@ static int snd_seq_ioctl_unsubscribe_port(struct snd_seq_client *client,
1539 1499
1540 1500
1541/* CREATE_QUEUE ioctl() */ 1501/* CREATE_QUEUE ioctl() */
1542static int snd_seq_ioctl_create_queue(struct snd_seq_client *client, 1502static int snd_seq_ioctl_create_queue(struct snd_seq_client *client, void *arg)
1543 void __user *arg)
1544{ 1503{
1545 struct snd_seq_queue_info info; 1504 struct snd_seq_queue_info *info = arg;
1546 int result; 1505 int result;
1547 struct snd_seq_queue *q; 1506 struct snd_seq_queue *q;
1548 1507
1549 if (copy_from_user(&info, arg, sizeof(info))) 1508 result = snd_seq_queue_alloc(client->number, info->locked, info->flags);
1550 return -EFAULT;
1551
1552 result = snd_seq_queue_alloc(client->number, info.locked, info.flags);
1553 if (result < 0) 1509 if (result < 0)
1554 return result; 1510 return result;
1555 1511
@@ -1557,181 +1513,150 @@ static int snd_seq_ioctl_create_queue(struct snd_seq_client *client,
1557 if (q == NULL) 1513 if (q == NULL)
1558 return -EINVAL; 1514 return -EINVAL;
1559 1515
1560 info.queue = q->queue; 1516 info->queue = q->queue;
1561 info.locked = q->locked; 1517 info->locked = q->locked;
1562 info.owner = q->owner; 1518 info->owner = q->owner;
1563 1519
1564 /* set queue name */ 1520 /* set queue name */
1565 if (! info.name[0]) 1521 if (!info->name[0])
1566 snprintf(info.name, sizeof(info.name), "Queue-%d", q->queue); 1522 snprintf(info->name, sizeof(info->name), "Queue-%d", q->queue);
1567 strlcpy(q->name, info.name, sizeof(q->name)); 1523 strlcpy(q->name, info->name, sizeof(q->name));
1568 queuefree(q); 1524 queuefree(q);
1569 1525
1570 if (copy_to_user(arg, &info, sizeof(info)))
1571 return -EFAULT;
1572
1573 return 0; 1526 return 0;
1574} 1527}
1575 1528
1576/* DELETE_QUEUE ioctl() */ 1529/* DELETE_QUEUE ioctl() */
1577static int snd_seq_ioctl_delete_queue(struct snd_seq_client *client, 1530static int snd_seq_ioctl_delete_queue(struct snd_seq_client *client, void *arg)
1578 void __user *arg)
1579{ 1531{
1580 struct snd_seq_queue_info info; 1532 struct snd_seq_queue_info *info = arg;
1581
1582 if (copy_from_user(&info, arg, sizeof(info)))
1583 return -EFAULT;
1584 1533
1585 return snd_seq_queue_delete(client->number, info.queue); 1534 return snd_seq_queue_delete(client->number, info->queue);
1586} 1535}
1587 1536
1588/* GET_QUEUE_INFO ioctl() */ 1537/* GET_QUEUE_INFO ioctl() */
1589static int snd_seq_ioctl_get_queue_info(struct snd_seq_client *client, 1538static int snd_seq_ioctl_get_queue_info(struct snd_seq_client *client,
1590 void __user *arg) 1539 void *arg)
1591{ 1540{
1592 struct snd_seq_queue_info info; 1541 struct snd_seq_queue_info *info = arg;
1593 struct snd_seq_queue *q; 1542 struct snd_seq_queue *q;
1594 1543
1595 if (copy_from_user(&info, arg, sizeof(info))) 1544 q = queueptr(info->queue);
1596 return -EFAULT;
1597
1598 q = queueptr(info.queue);
1599 if (q == NULL) 1545 if (q == NULL)
1600 return -EINVAL; 1546 return -EINVAL;
1601 1547
1602 memset(&info, 0, sizeof(info)); 1548 memset(info, 0, sizeof(*info));
1603 info.queue = q->queue; 1549 info->queue = q->queue;
1604 info.owner = q->owner; 1550 info->owner = q->owner;
1605 info.locked = q->locked; 1551 info->locked = q->locked;
1606 strlcpy(info.name, q->name, sizeof(info.name)); 1552 strlcpy(info->name, q->name, sizeof(info->name));
1607 queuefree(q); 1553 queuefree(q);
1608 1554
1609 if (copy_to_user(arg, &info, sizeof(info)))
1610 return -EFAULT;
1611
1612 return 0; 1555 return 0;
1613} 1556}
1614 1557
1615/* SET_QUEUE_INFO ioctl() */ 1558/* SET_QUEUE_INFO ioctl() */
1616static int snd_seq_ioctl_set_queue_info(struct snd_seq_client *client, 1559static int snd_seq_ioctl_set_queue_info(struct snd_seq_client *client,
1617 void __user *arg) 1560 void *arg)
1618{ 1561{
1619 struct snd_seq_queue_info info; 1562 struct snd_seq_queue_info *info = arg;
1620 struct snd_seq_queue *q; 1563 struct snd_seq_queue *q;
1621 1564
1622 if (copy_from_user(&info, arg, sizeof(info))) 1565 if (info->owner != client->number)
1623 return -EFAULT;
1624
1625 if (info.owner != client->number)
1626 return -EINVAL; 1566 return -EINVAL;
1627 1567
1628 /* change owner/locked permission */ 1568 /* change owner/locked permission */
1629 if (snd_seq_queue_check_access(info.queue, client->number)) { 1569 if (snd_seq_queue_check_access(info->queue, client->number)) {
1630 if (snd_seq_queue_set_owner(info.queue, client->number, info.locked) < 0) 1570 if (snd_seq_queue_set_owner(info->queue, client->number, info->locked) < 0)
1631 return -EPERM; 1571 return -EPERM;
1632 if (info.locked) 1572 if (info->locked)
1633 snd_seq_queue_use(info.queue, client->number, 1); 1573 snd_seq_queue_use(info->queue, client->number, 1);
1634 } else { 1574 } else {
1635 return -EPERM; 1575 return -EPERM;
1636 } 1576 }
1637 1577
1638 q = queueptr(info.queue); 1578 q = queueptr(info->queue);
1639 if (! q) 1579 if (! q)
1640 return -EINVAL; 1580 return -EINVAL;
1641 if (q->owner != client->number) { 1581 if (q->owner != client->number) {
1642 queuefree(q); 1582 queuefree(q);
1643 return -EPERM; 1583 return -EPERM;
1644 } 1584 }
1645 strlcpy(q->name, info.name, sizeof(q->name)); 1585 strlcpy(q->name, info->name, sizeof(q->name));
1646 queuefree(q); 1586 queuefree(q);
1647 1587
1648 return 0; 1588 return 0;
1649} 1589}
1650 1590
1651/* GET_NAMED_QUEUE ioctl() */ 1591/* GET_NAMED_QUEUE ioctl() */
1652static int snd_seq_ioctl_get_named_queue(struct snd_seq_client *client, void __user *arg) 1592static int snd_seq_ioctl_get_named_queue(struct snd_seq_client *client,
1593 void *arg)
1653{ 1594{
1654 struct snd_seq_queue_info info; 1595 struct snd_seq_queue_info *info = arg;
1655 struct snd_seq_queue *q; 1596 struct snd_seq_queue *q;
1656 1597
1657 if (copy_from_user(&info, arg, sizeof(info))) 1598 q = snd_seq_queue_find_name(info->name);
1658 return -EFAULT;
1659
1660 q = snd_seq_queue_find_name(info.name);
1661 if (q == NULL) 1599 if (q == NULL)
1662 return -EINVAL; 1600 return -EINVAL;
1663 info.queue = q->queue; 1601 info->queue = q->queue;
1664 info.owner = q->owner; 1602 info->owner = q->owner;
1665 info.locked = q->locked; 1603 info->locked = q->locked;
1666 queuefree(q); 1604 queuefree(q);
1667 1605
1668 if (copy_to_user(arg, &info, sizeof(info)))
1669 return -EFAULT;
1670
1671 return 0; 1606 return 0;
1672} 1607}
1673 1608
1674/* GET_QUEUE_STATUS ioctl() */ 1609/* GET_QUEUE_STATUS ioctl() */
1675static int snd_seq_ioctl_get_queue_status(struct snd_seq_client *client, 1610static int snd_seq_ioctl_get_queue_status(struct snd_seq_client *client,
1676 void __user *arg) 1611 void *arg)
1677{ 1612{
1678 struct snd_seq_queue_status status; 1613 struct snd_seq_queue_status *status = arg;
1679 struct snd_seq_queue *queue; 1614 struct snd_seq_queue *queue;
1680 struct snd_seq_timer *tmr; 1615 struct snd_seq_timer *tmr;
1681 1616
1682 if (copy_from_user(&status, arg, sizeof(status))) 1617 queue = queueptr(status->queue);
1683 return -EFAULT;
1684
1685 queue = queueptr(status.queue);
1686 if (queue == NULL) 1618 if (queue == NULL)
1687 return -EINVAL; 1619 return -EINVAL;
1688 memset(&status, 0, sizeof(status)); 1620 memset(status, 0, sizeof(*status));
1689 status.queue = queue->queue; 1621 status->queue = queue->queue;
1690 1622
1691 tmr = queue->timer; 1623 tmr = queue->timer;
1692 status.events = queue->tickq->cells + queue->timeq->cells; 1624 status->events = queue->tickq->cells + queue->timeq->cells;
1693 1625
1694 status.time = snd_seq_timer_get_cur_time(tmr); 1626 status->time = snd_seq_timer_get_cur_time(tmr);
1695 status.tick = snd_seq_timer_get_cur_tick(tmr); 1627 status->tick = snd_seq_timer_get_cur_tick(tmr);
1696 1628
1697 status.running = tmr->running; 1629 status->running = tmr->running;
1698 1630
1699 status.flags = queue->flags; 1631 status->flags = queue->flags;
1700 queuefree(queue); 1632 queuefree(queue);
1701 1633
1702 if (copy_to_user(arg, &status, sizeof(status)))
1703 return -EFAULT;
1704 return 0; 1634 return 0;
1705} 1635}
1706 1636
1707 1637
1708/* GET_QUEUE_TEMPO ioctl() */ 1638/* GET_QUEUE_TEMPO ioctl() */
1709static int snd_seq_ioctl_get_queue_tempo(struct snd_seq_client *client, 1639static int snd_seq_ioctl_get_queue_tempo(struct snd_seq_client *client,
1710 void __user *arg) 1640 void *arg)
1711{ 1641{
1712 struct snd_seq_queue_tempo tempo; 1642 struct snd_seq_queue_tempo *tempo = arg;
1713 struct snd_seq_queue *queue; 1643 struct snd_seq_queue *queue;
1714 struct snd_seq_timer *tmr; 1644 struct snd_seq_timer *tmr;
1715 1645
1716 if (copy_from_user(&tempo, arg, sizeof(tempo))) 1646 queue = queueptr(tempo->queue);
1717 return -EFAULT;
1718
1719 queue = queueptr(tempo.queue);
1720 if (queue == NULL) 1647 if (queue == NULL)
1721 return -EINVAL; 1648 return -EINVAL;
1722 memset(&tempo, 0, sizeof(tempo)); 1649 memset(tempo, 0, sizeof(*tempo));
1723 tempo.queue = queue->queue; 1650 tempo->queue = queue->queue;
1724 1651
1725 tmr = queue->timer; 1652 tmr = queue->timer;
1726 1653
1727 tempo.tempo = tmr->tempo; 1654 tempo->tempo = tmr->tempo;
1728 tempo.ppq = tmr->ppq; 1655 tempo->ppq = tmr->ppq;
1729 tempo.skew_value = tmr->skew; 1656 tempo->skew_value = tmr->skew;
1730 tempo.skew_base = tmr->skew_base; 1657 tempo->skew_base = tmr->skew_base;
1731 queuefree(queue); 1658 queuefree(queue);
1732 1659
1733 if (copy_to_user(arg, &tempo, sizeof(tempo)))
1734 return -EFAULT;
1735 return 0; 1660 return 0;
1736} 1661}
1737 1662
@@ -1747,31 +1672,25 @@ int snd_seq_set_queue_tempo(int client, struct snd_seq_queue_tempo *tempo)
1747EXPORT_SYMBOL(snd_seq_set_queue_tempo); 1672EXPORT_SYMBOL(snd_seq_set_queue_tempo);
1748 1673
1749static int snd_seq_ioctl_set_queue_tempo(struct snd_seq_client *client, 1674static int snd_seq_ioctl_set_queue_tempo(struct snd_seq_client *client,
1750 void __user *arg) 1675 void *arg)
1751{ 1676{
1677 struct snd_seq_queue_tempo *tempo = arg;
1752 int result; 1678 int result;
1753 struct snd_seq_queue_tempo tempo;
1754
1755 if (copy_from_user(&tempo, arg, sizeof(tempo)))
1756 return -EFAULT;
1757 1679
1758 result = snd_seq_set_queue_tempo(client->number, &tempo); 1680 result = snd_seq_set_queue_tempo(client->number, tempo);
1759 return result < 0 ? result : 0; 1681 return result < 0 ? result : 0;
1760} 1682}
1761 1683
1762 1684
1763/* GET_QUEUE_TIMER ioctl() */ 1685/* GET_QUEUE_TIMER ioctl() */
1764static int snd_seq_ioctl_get_queue_timer(struct snd_seq_client *client, 1686static int snd_seq_ioctl_get_queue_timer(struct snd_seq_client *client,
1765 void __user *arg) 1687 void *arg)
1766{ 1688{
1767 struct snd_seq_queue_timer timer; 1689 struct snd_seq_queue_timer *timer = arg;
1768 struct snd_seq_queue *queue; 1690 struct snd_seq_queue *queue;
1769 struct snd_seq_timer *tmr; 1691 struct snd_seq_timer *tmr;
1770 1692
1771 if (copy_from_user(&timer, arg, sizeof(timer))) 1693 queue = queueptr(timer->queue);
1772 return -EFAULT;
1773
1774 queue = queueptr(timer.queue);
1775 if (queue == NULL) 1694 if (queue == NULL)
1776 return -EINVAL; 1695 return -EINVAL;
1777 1696
@@ -1780,41 +1699,36 @@ static int snd_seq_ioctl_get_queue_timer(struct snd_seq_client *client,
1780 return -ERESTARTSYS; 1699 return -ERESTARTSYS;
1781 } 1700 }
1782 tmr = queue->timer; 1701 tmr = queue->timer;
1783 memset(&timer, 0, sizeof(timer)); 1702 memset(timer, 0, sizeof(*timer));
1784 timer.queue = queue->queue; 1703 timer->queue = queue->queue;
1785 1704
1786 timer.type = tmr->type; 1705 timer->type = tmr->type;
1787 if (tmr->type == SNDRV_SEQ_TIMER_ALSA) { 1706 if (tmr->type == SNDRV_SEQ_TIMER_ALSA) {
1788 timer.u.alsa.id = tmr->alsa_id; 1707 timer->u.alsa.id = tmr->alsa_id;
1789 timer.u.alsa.resolution = tmr->preferred_resolution; 1708 timer->u.alsa.resolution = tmr->preferred_resolution;
1790 } 1709 }
1791 mutex_unlock(&queue->timer_mutex); 1710 mutex_unlock(&queue->timer_mutex);
1792 queuefree(queue); 1711 queuefree(queue);
1793 1712
1794 if (copy_to_user(arg, &timer, sizeof(timer)))
1795 return -EFAULT;
1796 return 0; 1713 return 0;
1797} 1714}
1798 1715
1799 1716
1800/* SET_QUEUE_TIMER ioctl() */ 1717/* SET_QUEUE_TIMER ioctl() */
1801static int snd_seq_ioctl_set_queue_timer(struct snd_seq_client *client, 1718static int snd_seq_ioctl_set_queue_timer(struct snd_seq_client *client,
1802 void __user *arg) 1719 void *arg)
1803{ 1720{
1721 struct snd_seq_queue_timer *timer = arg;
1804 int result = 0; 1722 int result = 0;
1805 struct snd_seq_queue_timer timer;
1806
1807 if (copy_from_user(&timer, arg, sizeof(timer)))
1808 return -EFAULT;
1809 1723
1810 if (timer.type != SNDRV_SEQ_TIMER_ALSA) 1724 if (timer->type != SNDRV_SEQ_TIMER_ALSA)
1811 return -EINVAL; 1725 return -EINVAL;
1812 1726
1813 if (snd_seq_queue_check_access(timer.queue, client->number)) { 1727 if (snd_seq_queue_check_access(timer->queue, client->number)) {
1814 struct snd_seq_queue *q; 1728 struct snd_seq_queue *q;
1815 struct snd_seq_timer *tmr; 1729 struct snd_seq_timer *tmr;
1816 1730
1817 q = queueptr(timer.queue); 1731 q = queueptr(timer->queue);
1818 if (q == NULL) 1732 if (q == NULL)
1819 return -ENXIO; 1733 return -ENXIO;
1820 if (mutex_lock_interruptible(&q->timer_mutex)) { 1734 if (mutex_lock_interruptible(&q->timer_mutex)) {
@@ -1822,13 +1736,13 @@ static int snd_seq_ioctl_set_queue_timer(struct snd_seq_client *client,
1822 return -ERESTARTSYS; 1736 return -ERESTARTSYS;
1823 } 1737 }
1824 tmr = q->timer; 1738 tmr = q->timer;
1825 snd_seq_queue_timer_close(timer.queue); 1739 snd_seq_queue_timer_close(timer->queue);
1826 tmr->type = timer.type; 1740 tmr->type = timer->type;
1827 if (tmr->type == SNDRV_SEQ_TIMER_ALSA) { 1741 if (tmr->type == SNDRV_SEQ_TIMER_ALSA) {
1828 tmr->alsa_id = timer.u.alsa.id; 1742 tmr->alsa_id = timer->u.alsa.id;
1829 tmr->preferred_resolution = timer.u.alsa.resolution; 1743 tmr->preferred_resolution = timer->u.alsa.resolution;
1830 } 1744 }
1831 result = snd_seq_queue_timer_open(timer.queue); 1745 result = snd_seq_queue_timer_open(timer->queue);
1832 mutex_unlock(&q->timer_mutex); 1746 mutex_unlock(&q->timer_mutex);
1833 queuefree(q); 1747 queuefree(q);
1834 } else { 1748 } else {
@@ -1841,38 +1755,30 @@ static int snd_seq_ioctl_set_queue_timer(struct snd_seq_client *client,
1841 1755
1842/* GET_QUEUE_CLIENT ioctl() */ 1756/* GET_QUEUE_CLIENT ioctl() */
1843static int snd_seq_ioctl_get_queue_client(struct snd_seq_client *client, 1757static int snd_seq_ioctl_get_queue_client(struct snd_seq_client *client,
1844 void __user *arg) 1758 void *arg)
1845{ 1759{
1846 struct snd_seq_queue_client info; 1760 struct snd_seq_queue_client *info = arg;
1847 int used; 1761 int used;
1848 1762
1849 if (copy_from_user(&info, arg, sizeof(info))) 1763 used = snd_seq_queue_is_used(info->queue, client->number);
1850 return -EFAULT;
1851
1852 used = snd_seq_queue_is_used(info.queue, client->number);
1853 if (used < 0) 1764 if (used < 0)
1854 return -EINVAL; 1765 return -EINVAL;
1855 info.used = used; 1766 info->used = used;
1856 info.client = client->number; 1767 info->client = client->number;
1857 1768
1858 if (copy_to_user(arg, &info, sizeof(info)))
1859 return -EFAULT;
1860 return 0; 1769 return 0;
1861} 1770}
1862 1771
1863 1772
1864/* SET_QUEUE_CLIENT ioctl() */ 1773/* SET_QUEUE_CLIENT ioctl() */
1865static int snd_seq_ioctl_set_queue_client(struct snd_seq_client *client, 1774static int snd_seq_ioctl_set_queue_client(struct snd_seq_client *client,
1866 void __user *arg) 1775 void *arg)
1867{ 1776{
1777 struct snd_seq_queue_client *info = arg;
1868 int err; 1778 int err;
1869 struct snd_seq_queue_client info;
1870
1871 if (copy_from_user(&info, arg, sizeof(info)))
1872 return -EFAULT;
1873 1779
1874 if (info.used >= 0) { 1780 if (info->used >= 0) {
1875 err = snd_seq_queue_use(info.queue, client->number, info.used); 1781 err = snd_seq_queue_use(info->queue, client->number, info->used);
1876 if (err < 0) 1782 if (err < 0)
1877 return err; 1783 return err;
1878 } 1784 }
@@ -1883,78 +1789,70 @@ static int snd_seq_ioctl_set_queue_client(struct snd_seq_client *client,
1883 1789
1884/* GET_CLIENT_POOL ioctl() */ 1790/* GET_CLIENT_POOL ioctl() */
1885static int snd_seq_ioctl_get_client_pool(struct snd_seq_client *client, 1791static int snd_seq_ioctl_get_client_pool(struct snd_seq_client *client,
1886 void __user *arg) 1792 void *arg)
1887{ 1793{
1888 struct snd_seq_client_pool info; 1794 struct snd_seq_client_pool *info = arg;
1889 struct snd_seq_client *cptr; 1795 struct snd_seq_client *cptr;
1890 1796
1891 if (copy_from_user(&info, arg, sizeof(info))) 1797 cptr = snd_seq_client_use_ptr(info->client);
1892 return -EFAULT;
1893
1894 cptr = snd_seq_client_use_ptr(info.client);
1895 if (cptr == NULL) 1798 if (cptr == NULL)
1896 return -ENOENT; 1799 return -ENOENT;
1897 memset(&info, 0, sizeof(info)); 1800 memset(info, 0, sizeof(*info));
1898 info.client = cptr->number; 1801 info->client = cptr->number;
1899 info.output_pool = cptr->pool->size; 1802 info->output_pool = cptr->pool->size;
1900 info.output_room = cptr->pool->room; 1803 info->output_room = cptr->pool->room;
1901 info.output_free = info.output_pool; 1804 info->output_free = info->output_pool;
1902 info.output_free = snd_seq_unused_cells(cptr->pool); 1805 info->output_free = snd_seq_unused_cells(cptr->pool);
1903 if (cptr->type == USER_CLIENT) { 1806 if (cptr->type == USER_CLIENT) {
1904 info.input_pool = cptr->data.user.fifo_pool_size; 1807 info->input_pool = cptr->data.user.fifo_pool_size;
1905 info.input_free = info.input_pool; 1808 info->input_free = info->input_pool;
1906 if (cptr->data.user.fifo) 1809 if (cptr->data.user.fifo)
1907 info.input_free = snd_seq_unused_cells(cptr->data.user.fifo->pool); 1810 info->input_free = snd_seq_unused_cells(cptr->data.user.fifo->pool);
1908 } else { 1811 } else {
1909 info.input_pool = 0; 1812 info->input_pool = 0;
1910 info.input_free = 0; 1813 info->input_free = 0;
1911 } 1814 }
1912 snd_seq_client_unlock(cptr); 1815 snd_seq_client_unlock(cptr);
1913 1816
1914 if (copy_to_user(arg, &info, sizeof(info)))
1915 return -EFAULT;
1916 return 0; 1817 return 0;
1917} 1818}
1918 1819
1919/* SET_CLIENT_POOL ioctl() */ 1820/* SET_CLIENT_POOL ioctl() */
1920static int snd_seq_ioctl_set_client_pool(struct snd_seq_client *client, 1821static int snd_seq_ioctl_set_client_pool(struct snd_seq_client *client,
1921 void __user *arg) 1822 void *arg)
1922{ 1823{
1923 struct snd_seq_client_pool info; 1824 struct snd_seq_client_pool *info = arg;
1924 int rc; 1825 int rc;
1925 1826
1926 if (copy_from_user(&info, arg, sizeof(info))) 1827 if (client->number != info->client)
1927 return -EFAULT;
1928
1929 if (client->number != info.client)
1930 return -EINVAL; /* can't change other clients */ 1828 return -EINVAL; /* can't change other clients */
1931 1829
1932 if (info.output_pool >= 1 && info.output_pool <= SNDRV_SEQ_MAX_EVENTS && 1830 if (info->output_pool >= 1 && info->output_pool <= SNDRV_SEQ_MAX_EVENTS &&
1933 (! snd_seq_write_pool_allocated(client) || 1831 (! snd_seq_write_pool_allocated(client) ||
1934 info.output_pool != client->pool->size)) { 1832 info->output_pool != client->pool->size)) {
1935 if (snd_seq_write_pool_allocated(client)) { 1833 if (snd_seq_write_pool_allocated(client)) {
1936 /* remove all existing cells */ 1834 /* remove all existing cells */
1937 snd_seq_queue_client_leave_cells(client->number); 1835 snd_seq_queue_client_leave_cells(client->number);
1938 snd_seq_pool_done(client->pool); 1836 snd_seq_pool_done(client->pool);
1939 } 1837 }
1940 client->pool->size = info.output_pool; 1838 client->pool->size = info->output_pool;
1941 rc = snd_seq_pool_init(client->pool); 1839 rc = snd_seq_pool_init(client->pool);
1942 if (rc < 0) 1840 if (rc < 0)
1943 return rc; 1841 return rc;
1944 } 1842 }
1945 if (client->type == USER_CLIENT && client->data.user.fifo != NULL && 1843 if (client->type == USER_CLIENT && client->data.user.fifo != NULL &&
1946 info.input_pool >= 1 && 1844 info->input_pool >= 1 &&
1947 info.input_pool <= SNDRV_SEQ_MAX_CLIENT_EVENTS && 1845 info->input_pool <= SNDRV_SEQ_MAX_CLIENT_EVENTS &&
1948 info.input_pool != client->data.user.fifo_pool_size) { 1846 info->input_pool != client->data.user.fifo_pool_size) {
1949 /* change pool size */ 1847 /* change pool size */
1950 rc = snd_seq_fifo_resize(client->data.user.fifo, info.input_pool); 1848 rc = snd_seq_fifo_resize(client->data.user.fifo, info->input_pool);
1951 if (rc < 0) 1849 if (rc < 0)
1952 return rc; 1850 return rc;
1953 client->data.user.fifo_pool_size = info.input_pool; 1851 client->data.user.fifo_pool_size = info->input_pool;
1954 } 1852 }
1955 if (info.output_room >= 1 && 1853 if (info->output_room >= 1 &&
1956 info.output_room <= client->pool->size) { 1854 info->output_room <= client->pool->size) {
1957 client->pool->room = info.output_room; 1855 client->pool->room = info->output_room;
1958 } 1856 }
1959 1857
1960 return snd_seq_ioctl_get_client_pool(client, arg); 1858 return snd_seq_ioctl_get_client_pool(client, arg);
@@ -1963,17 +1861,14 @@ static int snd_seq_ioctl_set_client_pool(struct snd_seq_client *client,
1963 1861
1964/* REMOVE_EVENTS ioctl() */ 1862/* REMOVE_EVENTS ioctl() */
1965static int snd_seq_ioctl_remove_events(struct snd_seq_client *client, 1863static int snd_seq_ioctl_remove_events(struct snd_seq_client *client,
1966 void __user *arg) 1864 void *arg)
1967{ 1865{
1968 struct snd_seq_remove_events info; 1866 struct snd_seq_remove_events *info = arg;
1969
1970 if (copy_from_user(&info, arg, sizeof(info)))
1971 return -EFAULT;
1972 1867
1973 /* 1868 /*
1974 * Input mostly not implemented XXX. 1869 * Input mostly not implemented XXX.
1975 */ 1870 */
1976 if (info.remove_mode & SNDRV_SEQ_REMOVE_INPUT) { 1871 if (info->remove_mode & SNDRV_SEQ_REMOVE_INPUT) {
1977 /* 1872 /*
1978 * No restrictions so for a user client we can clear 1873 * No restrictions so for a user client we can clear
1979 * the whole fifo 1874 * the whole fifo
@@ -1982,8 +1877,8 @@ static int snd_seq_ioctl_remove_events(struct snd_seq_client *client,
1982 snd_seq_fifo_clear(client->data.user.fifo); 1877 snd_seq_fifo_clear(client->data.user.fifo);
1983 } 1878 }
1984 1879
1985 if (info.remove_mode & SNDRV_SEQ_REMOVE_OUTPUT) 1880 if (info->remove_mode & SNDRV_SEQ_REMOVE_OUTPUT)
1986 snd_seq_queue_remove_cells(client->number, &info); 1881 snd_seq_queue_remove_cells(client->number, info);
1987 1882
1988 return 0; 1883 return 0;
1989} 1884}
@@ -1993,26 +1888,23 @@ static int snd_seq_ioctl_remove_events(struct snd_seq_client *client,
1993 * get subscription info 1888 * get subscription info
1994 */ 1889 */
1995static int snd_seq_ioctl_get_subscription(struct snd_seq_client *client, 1890static int snd_seq_ioctl_get_subscription(struct snd_seq_client *client,
1996 void __user *arg) 1891 void *arg)
1997{ 1892{
1893 struct snd_seq_port_subscribe *subs = arg;
1998 int result; 1894 int result;
1999 struct snd_seq_client *sender = NULL; 1895 struct snd_seq_client *sender = NULL;
2000 struct snd_seq_client_port *sport = NULL; 1896 struct snd_seq_client_port *sport = NULL;
2001 struct snd_seq_port_subscribe subs;
2002 struct snd_seq_subscribers *p; 1897 struct snd_seq_subscribers *p;
2003 1898
2004 if (copy_from_user(&subs, arg, sizeof(subs)))
2005 return -EFAULT;
2006
2007 result = -EINVAL; 1899 result = -EINVAL;
2008 if ((sender = snd_seq_client_use_ptr(subs.sender.client)) == NULL) 1900 if ((sender = snd_seq_client_use_ptr(subs->sender.client)) == NULL)
2009 goto __end; 1901 goto __end;
2010 if ((sport = snd_seq_port_use_ptr(sender, subs.sender.port)) == NULL) 1902 if ((sport = snd_seq_port_use_ptr(sender, subs->sender.port)) == NULL)
2011 goto __end; 1903 goto __end;
2012 p = snd_seq_port_get_subscription(&sport->c_src, &subs.dest); 1904 p = snd_seq_port_get_subscription(&sport->c_src, &subs->dest);
2013 if (p) { 1905 if (p) {
2014 result = 0; 1906 result = 0;
2015 subs = p->info; 1907 *subs = p->info;
2016 } else 1908 } else
2017 result = -ENOENT; 1909 result = -ENOENT;
2018 1910
@@ -2021,10 +1913,7 @@ static int snd_seq_ioctl_get_subscription(struct snd_seq_client *client,
2021 snd_seq_port_unlock(sport); 1913 snd_seq_port_unlock(sport);
2022 if (sender) 1914 if (sender)
2023 snd_seq_client_unlock(sender); 1915 snd_seq_client_unlock(sender);
2024 if (result >= 0) { 1916
2025 if (copy_to_user(arg, &subs, sizeof(subs)))
2026 return -EFAULT;
2027 }
2028 return result; 1917 return result;
2029} 1918}
2030 1919
@@ -2032,26 +1921,22 @@ static int snd_seq_ioctl_get_subscription(struct snd_seq_client *client,
2032/* 1921/*
2033 * get subscription info - check only its presence 1922 * get subscription info - check only its presence
2034 */ 1923 */
2035static int snd_seq_ioctl_query_subs(struct snd_seq_client *client, 1924static int snd_seq_ioctl_query_subs(struct snd_seq_client *client, void *arg)
2036 void __user *arg)
2037{ 1925{
1926 struct snd_seq_query_subs *subs = arg;
2038 int result = -ENXIO; 1927 int result = -ENXIO;
2039 struct snd_seq_client *cptr = NULL; 1928 struct snd_seq_client *cptr = NULL;
2040 struct snd_seq_client_port *port = NULL; 1929 struct snd_seq_client_port *port = NULL;
2041 struct snd_seq_query_subs subs;
2042 struct snd_seq_port_subs_info *group; 1930 struct snd_seq_port_subs_info *group;
2043 struct list_head *p; 1931 struct list_head *p;
2044 int i; 1932 int i;
2045 1933
2046 if (copy_from_user(&subs, arg, sizeof(subs))) 1934 if ((cptr = snd_seq_client_use_ptr(subs->root.client)) == NULL)
2047 return -EFAULT;
2048
2049 if ((cptr = snd_seq_client_use_ptr(subs.root.client)) == NULL)
2050 goto __end; 1935 goto __end;
2051 if ((port = snd_seq_port_use_ptr(cptr, subs.root.port)) == NULL) 1936 if ((port = snd_seq_port_use_ptr(cptr, subs->root.port)) == NULL)
2052 goto __end; 1937 goto __end;
2053 1938
2054 switch (subs.type) { 1939 switch (subs->type) {
2055 case SNDRV_SEQ_QUERY_SUBS_READ: 1940 case SNDRV_SEQ_QUERY_SUBS_READ:
2056 group = &port->c_src; 1941 group = &port->c_src;
2057 break; 1942 break;
@@ -2064,22 +1949,22 @@ static int snd_seq_ioctl_query_subs(struct snd_seq_client *client,
2064 1949
2065 down_read(&group->list_mutex); 1950 down_read(&group->list_mutex);
2066 /* search for the subscriber */ 1951 /* search for the subscriber */
2067 subs.num_subs = group->count; 1952 subs->num_subs = group->count;
2068 i = 0; 1953 i = 0;
2069 result = -ENOENT; 1954 result = -ENOENT;
2070 list_for_each(p, &group->list_head) { 1955 list_for_each(p, &group->list_head) {
2071 if (i++ == subs.index) { 1956 if (i++ == subs->index) {
2072 /* found! */ 1957 /* found! */
2073 struct snd_seq_subscribers *s; 1958 struct snd_seq_subscribers *s;
2074 if (subs.type == SNDRV_SEQ_QUERY_SUBS_READ) { 1959 if (subs->type == SNDRV_SEQ_QUERY_SUBS_READ) {
2075 s = list_entry(p, struct snd_seq_subscribers, src_list); 1960 s = list_entry(p, struct snd_seq_subscribers, src_list);
2076 subs.addr = s->info.dest; 1961 subs->addr = s->info.dest;
2077 } else { 1962 } else {
2078 s = list_entry(p, struct snd_seq_subscribers, dest_list); 1963 s = list_entry(p, struct snd_seq_subscribers, dest_list);
2079 subs.addr = s->info.sender; 1964 subs->addr = s->info.sender;
2080 } 1965 }
2081 subs.flags = s->info.flags; 1966 subs->flags = s->info.flags;
2082 subs.queue = s->info.queue; 1967 subs->queue = s->info.queue;
2083 result = 0; 1968 result = 0;
2084 break; 1969 break;
2085 } 1970 }
@@ -2091,10 +1976,7 @@ static int snd_seq_ioctl_query_subs(struct snd_seq_client *client,
2091 snd_seq_port_unlock(port); 1976 snd_seq_port_unlock(port);
2092 if (cptr) 1977 if (cptr)
2093 snd_seq_client_unlock(cptr); 1978 snd_seq_client_unlock(cptr);
2094 if (result >= 0) { 1979
2095 if (copy_to_user(arg, &subs, sizeof(subs)))
2096 return -EFAULT;
2097 }
2098 return result; 1980 return result;
2099} 1981}
2100 1982
@@ -2103,31 +1985,26 @@ static int snd_seq_ioctl_query_subs(struct snd_seq_client *client,
2103 * query next client 1985 * query next client
2104 */ 1986 */
2105static int snd_seq_ioctl_query_next_client(struct snd_seq_client *client, 1987static int snd_seq_ioctl_query_next_client(struct snd_seq_client *client,
2106 void __user *arg) 1988 void *arg)
2107{ 1989{
1990 struct snd_seq_client_info *info = arg;
2108 struct snd_seq_client *cptr = NULL; 1991 struct snd_seq_client *cptr = NULL;
2109 struct snd_seq_client_info info;
2110
2111 if (copy_from_user(&info, arg, sizeof(info)))
2112 return -EFAULT;
2113 1992
2114 /* search for next client */ 1993 /* search for next client */
2115 info.client++; 1994 info->client++;
2116 if (info.client < 0) 1995 if (info->client < 0)
2117 info.client = 0; 1996 info->client = 0;
2118 for (; info.client < SNDRV_SEQ_MAX_CLIENTS; info.client++) { 1997 for (; info->client < SNDRV_SEQ_MAX_CLIENTS; info->client++) {
2119 cptr = snd_seq_client_use_ptr(info.client); 1998 cptr = snd_seq_client_use_ptr(info->client);
2120 if (cptr) 1999 if (cptr)
2121 break; /* found */ 2000 break; /* found */
2122 } 2001 }
2123 if (cptr == NULL) 2002 if (cptr == NULL)
2124 return -ENOENT; 2003 return -ENOENT;
2125 2004
2126 get_client_info(cptr, &info); 2005 get_client_info(cptr, info);
2127 snd_seq_client_unlock(cptr); 2006 snd_seq_client_unlock(cptr);
2128 2007
2129 if (copy_to_user(arg, &info, sizeof(info)))
2130 return -EFAULT;
2131 return 0; 2008 return 0;
2132} 2009}
2133 2010
@@ -2135,43 +2012,41 @@ static int snd_seq_ioctl_query_next_client(struct snd_seq_client *client,
2135 * query next port 2012 * query next port
2136 */ 2013 */
2137static int snd_seq_ioctl_query_next_port(struct snd_seq_client *client, 2014static int snd_seq_ioctl_query_next_port(struct snd_seq_client *client,
2138 void __user *arg) 2015 void *arg)
2139{ 2016{
2017 struct snd_seq_port_info *info = arg;
2140 struct snd_seq_client *cptr; 2018 struct snd_seq_client *cptr;
2141 struct snd_seq_client_port *port = NULL; 2019 struct snd_seq_client_port *port = NULL;
2142 struct snd_seq_port_info info;
2143 2020
2144 if (copy_from_user(&info, arg, sizeof(info))) 2021 cptr = snd_seq_client_use_ptr(info->addr.client);
2145 return -EFAULT;
2146 cptr = snd_seq_client_use_ptr(info.addr.client);
2147 if (cptr == NULL) 2022 if (cptr == NULL)
2148 return -ENXIO; 2023 return -ENXIO;
2149 2024
2150 /* search for next port */ 2025 /* search for next port */
2151 info.addr.port++; 2026 info->addr.port++;
2152 port = snd_seq_port_query_nearest(cptr, &info); 2027 port = snd_seq_port_query_nearest(cptr, info);
2153 if (port == NULL) { 2028 if (port == NULL) {
2154 snd_seq_client_unlock(cptr); 2029 snd_seq_client_unlock(cptr);
2155 return -ENOENT; 2030 return -ENOENT;
2156 } 2031 }
2157 2032
2158 /* get port info */ 2033 /* get port info */
2159 info.addr = port->addr; 2034 info->addr = port->addr;
2160 snd_seq_get_port_info(port, &info); 2035 snd_seq_get_port_info(port, info);
2161 snd_seq_port_unlock(port); 2036 snd_seq_port_unlock(port);
2162 snd_seq_client_unlock(cptr); 2037 snd_seq_client_unlock(cptr);
2163 2038
2164 if (copy_to_user(arg, &info, sizeof(info)))
2165 return -EFAULT;
2166 return 0; 2039 return 0;
2167} 2040}
2168 2041
2169/* -------------------------------------------------------- */ 2042/* -------------------------------------------------------- */
2170 2043
2171static struct seq_ioctl_table { 2044static const struct ioctl_handler {
2172 unsigned int cmd; 2045 unsigned int cmd;
2173 int (*func)(struct snd_seq_client *client, void __user * arg); 2046 int (*func)(struct snd_seq_client *client, void *arg);
2174} ioctl_tables[] = { 2047} ioctl_handlers[] = {
2048 { SNDRV_SEQ_IOCTL_PVERSION, snd_seq_ioctl_pversion },
2049 { SNDRV_SEQ_IOCTL_CLIENT_ID, snd_seq_ioctl_client_id },
2175 { SNDRV_SEQ_IOCTL_SYSTEM_INFO, snd_seq_ioctl_system_info }, 2050 { SNDRV_SEQ_IOCTL_SYSTEM_INFO, snd_seq_ioctl_system_info },
2176 { SNDRV_SEQ_IOCTL_RUNNING_MODE, snd_seq_ioctl_running_mode }, 2051 { SNDRV_SEQ_IOCTL_RUNNING_MODE, snd_seq_ioctl_running_mode },
2177 { SNDRV_SEQ_IOCTL_GET_CLIENT_INFO, snd_seq_ioctl_get_client_info }, 2052 { SNDRV_SEQ_IOCTL_GET_CLIENT_INFO, snd_seq_ioctl_get_client_info },
@@ -2204,40 +2079,65 @@ static struct seq_ioctl_table {
2204 { 0, NULL }, 2079 { 0, NULL },
2205}; 2080};
2206 2081
2207static int snd_seq_do_ioctl(struct snd_seq_client *client, unsigned int cmd, 2082static long snd_seq_ioctl(struct file *file, unsigned int cmd,
2208 void __user *arg) 2083 unsigned long arg)
2209{ 2084{
2210 struct seq_ioctl_table *p; 2085 struct snd_seq_client *client = file->private_data;
2086 /* To use kernel stack for ioctl data. */
2087 union {
2088 int pversion;
2089 int client_id;
2090 struct snd_seq_system_info system_info;
2091 struct snd_seq_running_info running_info;
2092 struct snd_seq_client_info client_info;
2093 struct snd_seq_port_info port_info;
2094 struct snd_seq_port_subscribe port_subscribe;
2095 struct snd_seq_queue_info queue_info;
2096 struct snd_seq_queue_status queue_status;
2097 struct snd_seq_queue_tempo tempo;
2098 struct snd_seq_queue_timer queue_timer;
2099 struct snd_seq_queue_client queue_client;
2100 struct snd_seq_client_pool client_pool;
2101 struct snd_seq_remove_events remove_events;
2102 struct snd_seq_query_subs query_subs;
2103 } buf;
2104 const struct ioctl_handler *handler;
2105 unsigned long size;
2106 int err;
2211 2107
2212 switch (cmd) { 2108 if (snd_BUG_ON(!client))
2213 case SNDRV_SEQ_IOCTL_PVERSION: 2109 return -ENXIO;
2214 /* return sequencer version number */
2215 return put_user(SNDRV_SEQ_VERSION, (int __user *)arg) ? -EFAULT : 0;
2216 case SNDRV_SEQ_IOCTL_CLIENT_ID:
2217 /* return the id of this client */
2218 return put_user(client->number, (int __user *)arg) ? -EFAULT : 0;
2219 }
2220 2110
2221 if (! arg) 2111 for (handler = ioctl_handlers; handler->cmd > 0; ++handler) {
2222 return -EFAULT; 2112 if (handler->cmd == cmd)
2223 for (p = ioctl_tables; p->cmd; p++) { 2113 break;
2224 if (p->cmd == cmd)
2225 return p->func(client, arg);
2226 } 2114 }
2227 pr_debug("ALSA: seq unknown ioctl() 0x%x (type='%c', number=0x%02x)\n", 2115 if (handler->cmd == 0)
2228 cmd, _IOC_TYPE(cmd), _IOC_NR(cmd)); 2116 return -ENOTTY;
2229 return -ENOTTY;
2230}
2231 2117
2118 memset(&buf, 0, sizeof(buf));
2232 2119
2233static long snd_seq_ioctl(struct file *file, unsigned int cmd, unsigned long arg) 2120 /*
2234{ 2121 * All of ioctl commands for ALSA sequencer get an argument of size
2235 struct snd_seq_client *client = file->private_data; 2122 * within 13 bits. We can safely pick up the size from the command.
2123 */
2124 size = _IOC_SIZE(handler->cmd);
2125 if (handler->cmd & IOC_IN) {
2126 if (copy_from_user(&buf, (const void __user *)arg, size))
2127 return -EFAULT;
2128 }
2236 2129
2237 if (snd_BUG_ON(!client)) 2130 err = handler->func(client, &buf);
2238 return -ENXIO; 2131 if (err >= 0) {
2239 2132 /* Some commands includes a bug in 'dir' field. */
2240 return snd_seq_do_ioctl(client, cmd, (void __user *) arg); 2133 if (handler->cmd == SNDRV_SEQ_IOCTL_SET_QUEUE_CLIENT ||
2134 handler->cmd == SNDRV_SEQ_IOCTL_SET_CLIENT_POOL ||
2135 (handler->cmd & IOC_OUT))
2136 if (copy_to_user((void __user *)arg, &buf, size))
2137 return -EFAULT;
2138 }
2139
2140 return err;
2241} 2141}
2242 2142
2243#ifdef CONFIG_COMPAT 2143#ifdef CONFIG_COMPAT
@@ -2423,23 +2323,35 @@ int snd_seq_kernel_client_dispatch(int client, struct snd_seq_event * ev,
2423 2323
2424EXPORT_SYMBOL(snd_seq_kernel_client_dispatch); 2324EXPORT_SYMBOL(snd_seq_kernel_client_dispatch);
2425 2325
2426/* 2326/**
2427 * exported, called by kernel clients to perform same functions as with 2327 * snd_seq_kernel_client_ctl - operate a command for a client with data in
2428 * userland ioctl() 2328 * kernel space.
2329 * @clientid: A numerical ID for a client.
2330 * @cmd: An ioctl(2) command for ALSA sequencer operation.
2331 * @arg: A pointer to data in kernel space.
2332 *
2333 * Against its name, both kernel/application client can be handled by this
2334 * kernel API. A pointer of 'arg' argument should be in kernel space.
2335 *
2336 * Return: 0 at success. Negative error code at failure.
2429 */ 2337 */
2430int snd_seq_kernel_client_ctl(int clientid, unsigned int cmd, void *arg) 2338int snd_seq_kernel_client_ctl(int clientid, unsigned int cmd, void *arg)
2431{ 2339{
2340 const struct ioctl_handler *handler;
2432 struct snd_seq_client *client; 2341 struct snd_seq_client *client;
2433 mm_segment_t fs;
2434 int result;
2435 2342
2436 client = clientptr(clientid); 2343 client = clientptr(clientid);
2437 if (client == NULL) 2344 if (client == NULL)
2438 return -ENXIO; 2345 return -ENXIO;
2439 fs = snd_enter_user(); 2346
2440 result = snd_seq_do_ioctl(client, cmd, (void __force __user *)arg); 2347 for (handler = ioctl_handlers; handler->cmd > 0; ++handler) {
2441 snd_leave_user(fs); 2348 if (handler->cmd == cmd)
2442 return result; 2349 return handler->func(client, arg);
2350 }
2351
2352 pr_debug("ALSA: seq unknown ioctl() 0x%x (type='%c', number=0x%02x)\n",
2353 cmd, _IOC_TYPE(cmd), _IOC_NR(cmd));
2354 return -ENOTTY;
2443} 2355}
2444 2356
2445EXPORT_SYMBOL(snd_seq_kernel_client_ctl); 2357EXPORT_SYMBOL(snd_seq_kernel_client_ctl);
diff --git a/sound/core/seq/seq_compat.c b/sound/core/seq/seq_compat.c
index 65175902a68a..fce5697e4261 100644
--- a/sound/core/seq/seq_compat.c
+++ b/sound/core/seq/seq_compat.c
@@ -47,7 +47,6 @@ static int snd_seq_call_port_info_ioctl(struct snd_seq_client *client, unsigned
47{ 47{
48 int err = -EFAULT; 48 int err = -EFAULT;
49 struct snd_seq_port_info *data; 49 struct snd_seq_port_info *data;
50 mm_segment_t fs;
51 50
52 data = kmalloc(sizeof(*data), GFP_KERNEL); 51 data = kmalloc(sizeof(*data), GFP_KERNEL);
53 if (!data) 52 if (!data)
@@ -59,9 +58,7 @@ static int snd_seq_call_port_info_ioctl(struct snd_seq_client *client, unsigned
59 goto error; 58 goto error;
60 data->kernel = NULL; 59 data->kernel = NULL;
61 60
62 fs = snd_enter_user(); 61 err = snd_seq_kernel_client_ctl(client->number, cmd, &data);
63 err = snd_seq_do_ioctl(client, cmd, data);
64 snd_leave_user(fs);
65 if (err < 0) 62 if (err < 0)
66 goto error; 63 goto error;
67 64
@@ -123,7 +120,7 @@ static long snd_seq_ioctl_compat(struct file *file, unsigned int cmd, unsigned l
123 case SNDRV_SEQ_IOCTL_GET_SUBSCRIPTION: 120 case SNDRV_SEQ_IOCTL_GET_SUBSCRIPTION:
124 case SNDRV_SEQ_IOCTL_QUERY_NEXT_CLIENT: 121 case SNDRV_SEQ_IOCTL_QUERY_NEXT_CLIENT:
125 case SNDRV_SEQ_IOCTL_RUNNING_MODE: 122 case SNDRV_SEQ_IOCTL_RUNNING_MODE:
126 return snd_seq_do_ioctl(client, cmd, argp); 123 return snd_seq_ioctl(file, cmd, arg);
127 case SNDRV_SEQ_IOCTL_CREATE_PORT32: 124 case SNDRV_SEQ_IOCTL_CREATE_PORT32:
128 return snd_seq_call_port_info_ioctl(client, SNDRV_SEQ_IOCTL_CREATE_PORT, argp); 125 return snd_seq_call_port_info_ioctl(client, SNDRV_SEQ_IOCTL_CREATE_PORT, argp);
129 case SNDRV_SEQ_IOCTL_DELETE_PORT32: 126 case SNDRV_SEQ_IOCTL_DELETE_PORT32:
diff --git a/sound/firewire/bebob/Makefile b/sound/firewire/bebob/Makefile
index af7ed6643266..dd454867240d 100644
--- a/sound/firewire/bebob/Makefile
+++ b/sound/firewire/bebob/Makefile
@@ -1,4 +1,5 @@
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 \
3 bebob_focusrite.o bebob_maudio.o bebob.o 3 bebob_yamaha_terratec.o bebob_focusrite.o bebob_maudio.o \
4 bebob.o
4obj-$(CONFIG_SND_BEBOB) += snd-bebob.o 5obj-$(CONFIG_SND_BEBOB) += snd-bebob.o
diff --git a/sound/firewire/bebob/bebob.c b/sound/firewire/bebob/bebob.c
index f7e2cbd2a313..3469ac14c89c 100644
--- a/sound/firewire/bebob/bebob.c
+++ b/sound/firewire/bebob/bebob.c
@@ -458,17 +458,17 @@ static const struct ieee1394_device_id bebob_id_table[] = {
458 /* TerraTec Electronic GmbH, PHASE 88 Rack FW */ 458 /* TerraTec Electronic GmbH, PHASE 88 Rack FW */
459 SND_BEBOB_DEV_ENTRY(VEN_TERRATEC, 0x00000003, &phase88_rack_spec), 459 SND_BEBOB_DEV_ENTRY(VEN_TERRATEC, 0x00000003, &phase88_rack_spec),
460 /* TerraTec Electronic GmbH, PHASE 24 FW */ 460 /* TerraTec Electronic GmbH, PHASE 24 FW */
461 SND_BEBOB_DEV_ENTRY(VEN_TERRATEC, 0x00000004, &phase24_series_spec), 461 SND_BEBOB_DEV_ENTRY(VEN_TERRATEC, 0x00000004, &yamaha_terratec_spec),
462 /* TerraTec Electronic GmbH, Phase X24 FW */ 462 /* TerraTec Electronic GmbH, Phase X24 FW */
463 SND_BEBOB_DEV_ENTRY(VEN_TERRATEC, 0x00000007, &phase24_series_spec), 463 SND_BEBOB_DEV_ENTRY(VEN_TERRATEC, 0x00000007, &yamaha_terratec_spec),
464 /* TerraTec Electronic GmbH, EWS MIC2/MIC8 */ 464 /* TerraTec Electronic GmbH, EWS MIC2/MIC8 */
465 SND_BEBOB_DEV_ENTRY(VEN_TERRATEC, 0x00000005, &spec_normal), 465 SND_BEBOB_DEV_ENTRY(VEN_TERRATEC, 0x00000005, &spec_normal),
466 /* Terratec Electronic GmbH, Aureon 7.1 Firewire */ 466 /* Terratec Electronic GmbH, Aureon 7.1 Firewire */
467 SND_BEBOB_DEV_ENTRY(VEN_TERRATEC, 0x00000002, &spec_normal), 467 SND_BEBOB_DEV_ENTRY(VEN_TERRATEC, 0x00000002, &spec_normal),
468 /* Yamaha, GO44 */ 468 /* Yamaha, GO44 */
469 SND_BEBOB_DEV_ENTRY(VEN_YAMAHA, 0x0010000b, &yamaha_go_spec), 469 SND_BEBOB_DEV_ENTRY(VEN_YAMAHA, 0x0010000b, &yamaha_terratec_spec),
470 /* YAMAHA, GO46 */ 470 /* YAMAHA, GO46 */
471 SND_BEBOB_DEV_ENTRY(VEN_YAMAHA, 0x0010000c, &yamaha_go_spec), 471 SND_BEBOB_DEV_ENTRY(VEN_YAMAHA, 0x0010000c, &yamaha_terratec_spec),
472 /* Focusrite, SaffirePro 26 I/O */ 472 /* Focusrite, SaffirePro 26 I/O */
473 SND_BEBOB_DEV_ENTRY(VEN_FOCUSRITE, 0x00000003, &saffirepro_26_spec), 473 SND_BEBOB_DEV_ENTRY(VEN_FOCUSRITE, 0x00000003, &saffirepro_26_spec),
474 /* Focusrite, SaffirePro 10 I/O */ 474 /* Focusrite, SaffirePro 10 I/O */
diff --git a/sound/firewire/bebob/bebob.h b/sound/firewire/bebob/bebob.h
index e7f1bb925b12..175da875162d 100644
--- a/sound/firewire/bebob/bebob.h
+++ b/sound/firewire/bebob/bebob.h
@@ -235,8 +235,7 @@ int snd_bebob_create_hwdep_device(struct snd_bebob *bebob);
235 235
236/* model specific operations */ 236/* model specific operations */
237extern const struct snd_bebob_spec phase88_rack_spec; 237extern const struct snd_bebob_spec phase88_rack_spec;
238extern const struct snd_bebob_spec phase24_series_spec; 238extern const struct snd_bebob_spec yamaha_terratec_spec;
239extern const struct snd_bebob_spec yamaha_go_spec;
240extern const struct snd_bebob_spec saffirepro_26_spec; 239extern const struct snd_bebob_spec saffirepro_26_spec;
241extern const struct snd_bebob_spec saffirepro_10_spec; 240extern const struct snd_bebob_spec saffirepro_10_spec;
242extern const struct snd_bebob_spec saffire_le_spec; 241extern const struct snd_bebob_spec saffire_le_spec;
diff --git a/sound/firewire/bebob/bebob_terratec.c b/sound/firewire/bebob/bebob_terratec.c
index c38358b82ada..2fdaf93e7a8d 100644
--- a/sound/firewire/bebob/bebob_terratec.c
+++ b/sound/firewire/bebob/bebob_terratec.c
@@ -36,25 +36,6 @@ end:
36 return err; 36 return err;
37} 37}
38 38
39static enum snd_bebob_clock_type phase24_series_clk_src_types[] = {
40 SND_BEBOB_CLOCK_TYPE_INTERNAL,
41 SND_BEBOB_CLOCK_TYPE_EXTERNAL, /* S/PDIF */
42};
43static int
44phase24_series_clk_src_get(struct snd_bebob *bebob, unsigned int *id)
45{
46 int err;
47
48 err = avc_audio_get_selector(bebob->unit, 0, 4, id);
49 if (err < 0)
50 return err;
51
52 if (*id >= ARRAY_SIZE(phase24_series_clk_src_types))
53 return -EIO;
54
55 return 0;
56}
57
58static const struct snd_bebob_rate_spec phase_series_rate_spec = { 39static const struct snd_bebob_rate_spec phase_series_rate_spec = {
59 .get = &snd_bebob_stream_get_rate, 40 .get = &snd_bebob_stream_get_rate,
60 .set = &snd_bebob_stream_set_rate, 41 .set = &snd_bebob_stream_set_rate,
@@ -71,15 +52,3 @@ const struct snd_bebob_spec phase88_rack_spec = {
71 .rate = &phase_series_rate_spec, 52 .rate = &phase_series_rate_spec,
72 .meter = NULL 53 .meter = NULL
73}; 54};
74
75/* 'PHASE 24 FW' and 'PHASE X24 FW' */
76static const struct snd_bebob_clock_spec phase24_series_clk = {
77 .num = ARRAY_SIZE(phase24_series_clk_src_types),
78 .types = phase24_series_clk_src_types,
79 .get = &phase24_series_clk_src_get,
80};
81const struct snd_bebob_spec phase24_series_spec = {
82 .clock = &phase24_series_clk,
83 .rate = &phase_series_rate_spec,
84 .meter = NULL
85};
diff --git a/sound/firewire/bebob/bebob_yamaha.c b/sound/firewire/bebob/bebob_yamaha_terratec.c
index 90d4404f77ce..a6be3e7138e0 100644
--- a/sound/firewire/bebob/bebob_yamaha.c
+++ b/sound/firewire/bebob/bebob_yamaha_terratec.c
@@ -14,7 +14,7 @@
14 * must be accompanied. If changing the state, a LED on the device starts to 14 * must be accompanied. If changing the state, a LED on the device starts to
15 * blink and its sync status is false. In this state, the device sounds nothing 15 * blink and its sync status is false. In this state, the device sounds nothing
16 * even if streaming. To start streaming at the current sampling rate is only 16 * even if streaming. To start streaming at the current sampling rate is only
17 * way to revocer this state. GO46 is better for stand-alone mixer. 17 * way to recover this state. GO46 is better for stand-alone mixer.
18 * 18 *
19 * Both of them have a capability to change its sampling rate up to 192.0kHz. 19 * Both of them have a capability to change its sampling rate up to 192.0kHz.
20 * At 192.0kHz, the device reports 4 PCM-in, 1 MIDI-in, 6 PCM-out, 1 MIDI-out. 20 * At 192.0kHz, the device reports 4 PCM-in, 1 MIDI-in, 6 PCM-out, 1 MIDI-out.
@@ -25,7 +25,10 @@
25 * streaming with many asynchronous transactions brings sounds with noises. 25 * streaming with many asynchronous transactions brings sounds with noises.
26 * Unfortunately current 'ffado-mixer' generated many asynchronous transaction 26 * Unfortunately current 'ffado-mixer' generated many asynchronous transaction
27 * to observe device's state, mainly check cmp connection and signal format. I 27 * to observe device's state, mainly check cmp connection and signal format. I
28 * reccomend users to close ffado-mixer at 192.0kHz if mixer is needless. 28 * recommend users to close ffado-mixer at 192.0kHz if mixer is needless.
29 *
30 * Terratec PHASE 24 FW and PHASE X24 FW are internally the same as
31 * Yamaha GO 44 and GO 46. Yamaha and Terratec had cooperated for these models.
29 */ 32 */
30 33
31static enum snd_bebob_clock_type clk_src_types[] = { 34static enum snd_bebob_clock_type clk_src_types[] = {
@@ -55,7 +58,7 @@ static const struct snd_bebob_rate_spec rate_spec = {
55 .get = &snd_bebob_stream_get_rate, 58 .get = &snd_bebob_stream_get_rate,
56 .set = &snd_bebob_stream_set_rate, 59 .set = &snd_bebob_stream_set_rate,
57}; 60};
58const struct snd_bebob_spec yamaha_go_spec = { 61const struct snd_bebob_spec yamaha_terratec_spec = {
59 .clock = &clock_spec, 62 .clock = &clock_spec,
60 .rate = &rate_spec, 63 .rate = &rate_spec,
61 .meter = NULL 64 .meter = NULL
diff --git a/sound/firewire/dice/dice-pcm.c b/sound/firewire/dice/dice-pcm.c
index 4aa0249826fd..6074fe1f00f7 100644
--- a/sound/firewire/dice/dice-pcm.c
+++ b/sound/firewire/dice/dice-pcm.c
@@ -302,7 +302,7 @@ static snd_pcm_uframes_t playback_pointer(struct snd_pcm_substream *substream)
302 302
303int snd_dice_create_pcm(struct snd_dice *dice) 303int snd_dice_create_pcm(struct snd_dice *dice)
304{ 304{
305 static struct snd_pcm_ops capture_ops = { 305 static const struct snd_pcm_ops capture_ops = {
306 .open = pcm_open, 306 .open = pcm_open,
307 .close = pcm_close, 307 .close = pcm_close,
308 .ioctl = snd_pcm_lib_ioctl, 308 .ioctl = snd_pcm_lib_ioctl,
@@ -314,7 +314,7 @@ int snd_dice_create_pcm(struct snd_dice *dice)
314 .page = snd_pcm_lib_get_vmalloc_page, 314 .page = snd_pcm_lib_get_vmalloc_page,
315 .mmap = snd_pcm_lib_mmap_vmalloc, 315 .mmap = snd_pcm_lib_mmap_vmalloc,
316 }; 316 };
317 static struct snd_pcm_ops playback_ops = { 317 static const struct snd_pcm_ops playback_ops = {
318 .open = pcm_open, 318 .open = pcm_open,
319 .close = pcm_close, 319 .close = pcm_close,
320 .ioctl = snd_pcm_lib_ioctl, 320 .ioctl = snd_pcm_lib_ioctl,
diff --git a/sound/firewire/digi00x/digi00x-pcm.c b/sound/firewire/digi00x/digi00x-pcm.c
index cac28f70aef7..613f05872770 100644
--- a/sound/firewire/digi00x/digi00x-pcm.c
+++ b/sound/firewire/digi00x/digi00x-pcm.c
@@ -329,7 +329,7 @@ static snd_pcm_uframes_t pcm_playback_pointer(struct snd_pcm_substream *sbstrm)
329 return amdtp_stream_pcm_pointer(&dg00x->rx_stream); 329 return amdtp_stream_pcm_pointer(&dg00x->rx_stream);
330} 330}
331 331
332static struct snd_pcm_ops pcm_capture_ops = { 332static const struct snd_pcm_ops pcm_capture_ops = {
333 .open = pcm_open, 333 .open = pcm_open,
334 .close = pcm_close, 334 .close = pcm_close,
335 .ioctl = snd_pcm_lib_ioctl, 335 .ioctl = snd_pcm_lib_ioctl,
@@ -341,7 +341,7 @@ static struct snd_pcm_ops pcm_capture_ops = {
341 .page = snd_pcm_lib_get_vmalloc_page, 341 .page = snd_pcm_lib_get_vmalloc_page,
342}; 342};
343 343
344static struct snd_pcm_ops pcm_playback_ops = { 344static const struct snd_pcm_ops pcm_playback_ops = {
345 .open = pcm_open, 345 .open = pcm_open,
346 .close = pcm_close, 346 .close = pcm_close,
347 .ioctl = snd_pcm_lib_ioctl, 347 .ioctl = snd_pcm_lib_ioctl,
diff --git a/sound/firewire/oxfw/oxfw-pcm.c b/sound/firewire/oxfw/oxfw-pcm.c
index 8d233417695d..f3530f89a025 100644
--- a/sound/firewire/oxfw/oxfw-pcm.c
+++ b/sound/firewire/oxfw/oxfw-pcm.c
@@ -388,7 +388,7 @@ static snd_pcm_uframes_t pcm_playback_pointer(struct snd_pcm_substream *sbstm)
388 388
389int snd_oxfw_create_pcm(struct snd_oxfw *oxfw) 389int snd_oxfw_create_pcm(struct snd_oxfw *oxfw)
390{ 390{
391 static struct snd_pcm_ops capture_ops = { 391 static const struct snd_pcm_ops capture_ops = {
392 .open = pcm_open, 392 .open = pcm_open,
393 .close = pcm_close, 393 .close = pcm_close,
394 .ioctl = snd_pcm_lib_ioctl, 394 .ioctl = snd_pcm_lib_ioctl,
@@ -400,7 +400,7 @@ int snd_oxfw_create_pcm(struct snd_oxfw *oxfw)
400 .page = snd_pcm_lib_get_vmalloc_page, 400 .page = snd_pcm_lib_get_vmalloc_page,
401 .mmap = snd_pcm_lib_mmap_vmalloc, 401 .mmap = snd_pcm_lib_mmap_vmalloc,
402 }; 402 };
403 static struct snd_pcm_ops playback_ops = { 403 static const struct snd_pcm_ops playback_ops = {
404 .open = pcm_open, 404 .open = pcm_open,
405 .close = pcm_close, 405 .close = pcm_close,
406 .ioctl = snd_pcm_lib_ioctl, 406 .ioctl = snd_pcm_lib_ioctl,
diff --git a/sound/firewire/tascam/tascam-pcm.c b/sound/firewire/tascam/tascam-pcm.c
index 380d3db969a5..79db1b651f5c 100644
--- a/sound/firewire/tascam/tascam-pcm.c
+++ b/sound/firewire/tascam/tascam-pcm.c
@@ -268,7 +268,7 @@ static snd_pcm_uframes_t pcm_playback_pointer(struct snd_pcm_substream *sbstrm)
268 return amdtp_stream_pcm_pointer(&tscm->rx_stream); 268 return amdtp_stream_pcm_pointer(&tscm->rx_stream);
269} 269}
270 270
271static struct snd_pcm_ops pcm_capture_ops = { 271static const struct snd_pcm_ops pcm_capture_ops = {
272 .open = pcm_open, 272 .open = pcm_open,
273 .close = pcm_close, 273 .close = pcm_close,
274 .ioctl = snd_pcm_lib_ioctl, 274 .ioctl = snd_pcm_lib_ioctl,
@@ -280,7 +280,7 @@ static struct snd_pcm_ops pcm_capture_ops = {
280 .page = snd_pcm_lib_get_vmalloc_page, 280 .page = snd_pcm_lib_get_vmalloc_page,
281}; 281};
282 282
283static struct snd_pcm_ops pcm_playback_ops = { 283static const struct snd_pcm_ops pcm_playback_ops = {
284 .open = pcm_open, 284 .open = pcm_open,
285 .close = pcm_close, 285 .close = pcm_close,
286 .ioctl = snd_pcm_lib_ioctl, 286 .ioctl = snd_pcm_lib_ioctl,
diff --git a/sound/hda/ext/hdac_ext_controller.c b/sound/hda/ext/hdac_ext_controller.c
index 860f8cad6602..261469188566 100644
--- a/sound/hda/ext/hdac_ext_controller.c
+++ b/sound/hda/ext/hdac_ext_controller.c
@@ -29,81 +29,6 @@
29 */ 29 */
30#define HDAC_MAX_CAPS 10 30#define HDAC_MAX_CAPS 10
31 31
32/**
33 * snd_hdac_ext_bus_parse_capabilities - parse capablity structure
34 * @ebus: the pointer to extended bus object
35 *
36 * Returns 0 if successful, or a negative error code.
37 */
38int snd_hdac_ext_bus_parse_capabilities(struct hdac_ext_bus *ebus)
39{
40 unsigned int cur_cap;
41 unsigned int offset;
42 struct hdac_bus *bus = &ebus->bus;
43 unsigned int counter = 0;
44
45 offset = snd_hdac_chip_readl(bus, LLCH);
46
47 /* Lets walk the linked capabilities list */
48 do {
49 cur_cap = _snd_hdac_chip_read(l, bus, offset);
50
51 dev_dbg(bus->dev, "Capability version: 0x%x\n",
52 ((cur_cap & AZX_CAP_HDR_VER_MASK) >> AZX_CAP_HDR_VER_OFF));
53
54 dev_dbg(bus->dev, "HDA capability ID: 0x%x\n",
55 (cur_cap & AZX_CAP_HDR_ID_MASK) >> AZX_CAP_HDR_ID_OFF);
56
57 switch ((cur_cap & AZX_CAP_HDR_ID_MASK) >> AZX_CAP_HDR_ID_OFF) {
58 case AZX_ML_CAP_ID:
59 dev_dbg(bus->dev, "Found ML capability\n");
60 ebus->mlcap = bus->remap_addr + offset;
61 break;
62
63 case AZX_GTS_CAP_ID:
64 dev_dbg(bus->dev, "Found GTS capability offset=%x\n", offset);
65 ebus->gtscap = bus->remap_addr + offset;
66 break;
67
68 case AZX_PP_CAP_ID:
69 /* PP capability found, the Audio DSP is present */
70 dev_dbg(bus->dev, "Found PP capability offset=%x\n", offset);
71 ebus->ppcap = bus->remap_addr + offset;
72 break;
73
74 case AZX_SPB_CAP_ID:
75 /* SPIB capability found, handler function */
76 dev_dbg(bus->dev, "Found SPB capability\n");
77 ebus->spbcap = bus->remap_addr + offset;
78 break;
79
80 case AZX_DRSM_CAP_ID:
81 /* DMA resume capability found, handler function */
82 dev_dbg(bus->dev, "Found DRSM capability\n");
83 ebus->drsmcap = bus->remap_addr + offset;
84 break;
85
86 default:
87 dev_dbg(bus->dev, "Unknown capability %d\n", cur_cap);
88 break;
89 }
90
91 counter++;
92
93 if (counter > HDAC_MAX_CAPS) {
94 dev_err(bus->dev, "We exceeded HDAC Ext capablities!!!\n");
95 break;
96 }
97
98 /* read the offset of next capabiity */
99 offset = cur_cap & AZX_CAP_HDR_NXT_PTR_MASK;
100
101 } while (offset);
102
103 return 0;
104}
105EXPORT_SYMBOL_GPL(snd_hdac_ext_bus_parse_capabilities);
106
107/* 32/*
108 * processing pipe helpers - these helpers are useful for dealing with HDA 33 * processing pipe helpers - these helpers are useful for dealing with HDA
109 * new capability of processing pipelines 34 * new capability of processing pipelines
@@ -118,15 +43,15 @@ void snd_hdac_ext_bus_ppcap_enable(struct hdac_ext_bus *ebus, bool enable)
118{ 43{
119 struct hdac_bus *bus = &ebus->bus; 44 struct hdac_bus *bus = &ebus->bus;
120 45
121 if (!ebus->ppcap) { 46 if (!bus->ppcap) {
122 dev_err(bus->dev, "Address of PP capability is NULL"); 47 dev_err(bus->dev, "Address of PP capability is NULL");
123 return; 48 return;
124 } 49 }
125 50
126 if (enable) 51 if (enable)
127 snd_hdac_updatel(ebus->ppcap, AZX_REG_PP_PPCTL, 0, AZX_PPCTL_GPROCEN); 52 snd_hdac_updatel(bus->ppcap, AZX_REG_PP_PPCTL, 0, AZX_PPCTL_GPROCEN);
128 else 53 else
129 snd_hdac_updatel(ebus->ppcap, AZX_REG_PP_PPCTL, AZX_PPCTL_GPROCEN, 0); 54 snd_hdac_updatel(bus->ppcap, AZX_REG_PP_PPCTL, AZX_PPCTL_GPROCEN, 0);
130} 55}
131EXPORT_SYMBOL_GPL(snd_hdac_ext_bus_ppcap_enable); 56EXPORT_SYMBOL_GPL(snd_hdac_ext_bus_ppcap_enable);
132 57
@@ -139,15 +64,15 @@ void snd_hdac_ext_bus_ppcap_int_enable(struct hdac_ext_bus *ebus, bool enable)
139{ 64{
140 struct hdac_bus *bus = &ebus->bus; 65 struct hdac_bus *bus = &ebus->bus;
141 66
142 if (!ebus->ppcap) { 67 if (!bus->ppcap) {
143 dev_err(bus->dev, "Address of PP capability is NULL\n"); 68 dev_err(bus->dev, "Address of PP capability is NULL\n");
144 return; 69 return;
145 } 70 }
146 71
147 if (enable) 72 if (enable)
148 snd_hdac_updatel(ebus->ppcap, AZX_REG_PP_PPCTL, 0, AZX_PPCTL_PIE); 73 snd_hdac_updatel(bus->ppcap, AZX_REG_PP_PPCTL, 0, AZX_PPCTL_PIE);
149 else 74 else
150 snd_hdac_updatel(ebus->ppcap, AZX_REG_PP_PPCTL, AZX_PPCTL_PIE, 0); 75 snd_hdac_updatel(bus->ppcap, AZX_REG_PP_PPCTL, AZX_PPCTL_PIE, 0);
151} 76}
152EXPORT_SYMBOL_GPL(snd_hdac_ext_bus_ppcap_int_enable); 77EXPORT_SYMBOL_GPL(snd_hdac_ext_bus_ppcap_int_enable);
153 78
@@ -171,7 +96,7 @@ int snd_hdac_ext_bus_get_ml_capabilities(struct hdac_ext_bus *ebus)
171 struct hdac_ext_link *hlink; 96 struct hdac_ext_link *hlink;
172 struct hdac_bus *bus = &ebus->bus; 97 struct hdac_bus *bus = &ebus->bus;
173 98
174 link_count = readl(ebus->mlcap + AZX_REG_ML_MLCD) + 1; 99 link_count = readl(bus->mlcap + AZX_REG_ML_MLCD) + 1;
175 100
176 dev_dbg(bus->dev, "In %s Link count: %d\n", __func__, link_count); 101 dev_dbg(bus->dev, "In %s Link count: %d\n", __func__, link_count);
177 102
@@ -181,7 +106,7 @@ int snd_hdac_ext_bus_get_ml_capabilities(struct hdac_ext_bus *ebus)
181 return -ENOMEM; 106 return -ENOMEM;
182 hlink->index = idx; 107 hlink->index = idx;
183 hlink->bus = bus; 108 hlink->bus = bus;
184 hlink->ml_addr = ebus->mlcap + AZX_ML_BASE + 109 hlink->ml_addr = bus->mlcap + AZX_ML_BASE +
185 (AZX_ML_INTERVAL * idx); 110 (AZX_ML_INTERVAL * idx);
186 hlink->lcaps = readl(hlink->ml_addr + AZX_REG_ML_LCAP); 111 hlink->lcaps = readl(hlink->ml_addr + AZX_REG_ML_LCAP);
187 hlink->lsdiid = readw(hlink->ml_addr + AZX_REG_ML_LSDIID); 112 hlink->lsdiid = readw(hlink->ml_addr + AZX_REG_ML_LSDIID);
diff --git a/sound/hda/ext/hdac_ext_stream.c b/sound/hda/ext/hdac_ext_stream.c
index 626f3bb24c55..3be051ab5533 100644
--- a/sound/hda/ext/hdac_ext_stream.c
+++ b/sound/hda/ext/hdac_ext_stream.c
@@ -40,27 +40,27 @@ void snd_hdac_ext_stream_init(struct hdac_ext_bus *ebus,
40{ 40{
41 struct hdac_bus *bus = &ebus->bus; 41 struct hdac_bus *bus = &ebus->bus;
42 42
43 if (ebus->ppcap) { 43 if (bus->ppcap) {
44 stream->pphc_addr = ebus->ppcap + AZX_PPHC_BASE + 44 stream->pphc_addr = bus->ppcap + AZX_PPHC_BASE +
45 AZX_PPHC_INTERVAL * idx; 45 AZX_PPHC_INTERVAL * idx;
46 46
47 stream->pplc_addr = ebus->ppcap + AZX_PPLC_BASE + 47 stream->pplc_addr = bus->ppcap + AZX_PPLC_BASE +
48 AZX_PPLC_MULTI * ebus->num_streams + 48 AZX_PPLC_MULTI * ebus->num_streams +
49 AZX_PPLC_INTERVAL * idx; 49 AZX_PPLC_INTERVAL * idx;
50 } 50 }
51 51
52 if (ebus->spbcap) { 52 if (bus->spbcap) {
53 stream->spib_addr = ebus->spbcap + AZX_SPB_BASE + 53 stream->spib_addr = bus->spbcap + AZX_SPB_BASE +
54 AZX_SPB_INTERVAL * idx + 54 AZX_SPB_INTERVAL * idx +
55 AZX_SPB_SPIB; 55 AZX_SPB_SPIB;
56 56
57 stream->fifo_addr = ebus->spbcap + AZX_SPB_BASE + 57 stream->fifo_addr = bus->spbcap + AZX_SPB_BASE +
58 AZX_SPB_INTERVAL * idx + 58 AZX_SPB_INTERVAL * idx +
59 AZX_SPB_MAXFIFO; 59 AZX_SPB_MAXFIFO;
60 } 60 }
61 61
62 if (ebus->drsmcap) 62 if (bus->drsmcap)
63 stream->dpibr_addr = ebus->drsmcap + AZX_DRSM_BASE + 63 stream->dpibr_addr = bus->drsmcap + AZX_DRSM_BASE +
64 AZX_DRSM_INTERVAL * idx; 64 AZX_DRSM_INTERVAL * idx;
65 65
66 stream->decoupled = false; 66 stream->decoupled = false;
@@ -131,10 +131,10 @@ void snd_hdac_ext_stream_decouple(struct hdac_ext_bus *ebus,
131 131
132 spin_lock_irq(&bus->reg_lock); 132 spin_lock_irq(&bus->reg_lock);
133 if (decouple) 133 if (decouple)
134 snd_hdac_updatel(ebus->ppcap, AZX_REG_PP_PPCTL, 0, 134 snd_hdac_updatel(bus->ppcap, AZX_REG_PP_PPCTL, 0,
135 AZX_PPCTL_PROCEN(hstream->index)); 135 AZX_PPCTL_PROCEN(hstream->index));
136 else 136 else
137 snd_hdac_updatel(ebus->ppcap, AZX_REG_PP_PPCTL, 137 snd_hdac_updatel(bus->ppcap, AZX_REG_PP_PPCTL,
138 AZX_PPCTL_PROCEN(hstream->index), 0); 138 AZX_PPCTL_PROCEN(hstream->index), 0);
139 stream->decoupled = decouple; 139 stream->decoupled = decouple;
140 spin_unlock_irq(&bus->reg_lock); 140 spin_unlock_irq(&bus->reg_lock);
@@ -255,7 +255,7 @@ hdac_ext_link_stream_assign(struct hdac_ext_bus *ebus,
255 struct hdac_stream *stream = NULL; 255 struct hdac_stream *stream = NULL;
256 struct hdac_bus *hbus = &ebus->bus; 256 struct hdac_bus *hbus = &ebus->bus;
257 257
258 if (!ebus->ppcap) { 258 if (!hbus->ppcap) {
259 dev_err(hbus->dev, "stream type not supported\n"); 259 dev_err(hbus->dev, "stream type not supported\n");
260 return NULL; 260 return NULL;
261 } 261 }
@@ -296,7 +296,7 @@ hdac_ext_host_stream_assign(struct hdac_ext_bus *ebus,
296 struct hdac_stream *stream = NULL; 296 struct hdac_stream *stream = NULL;
297 struct hdac_bus *hbus = &ebus->bus; 297 struct hdac_bus *hbus = &ebus->bus;
298 298
299 if (!ebus->ppcap) { 299 if (!hbus->ppcap) {
300 dev_err(hbus->dev, "stream type not supported\n"); 300 dev_err(hbus->dev, "stream type not supported\n");
301 return NULL; 301 return NULL;
302 } 302 }
@@ -423,21 +423,21 @@ void snd_hdac_ext_stream_spbcap_enable(struct hdac_ext_bus *ebus,
423 u32 register_mask = 0; 423 u32 register_mask = 0;
424 struct hdac_bus *bus = &ebus->bus; 424 struct hdac_bus *bus = &ebus->bus;
425 425
426 if (!ebus->spbcap) { 426 if (!bus->spbcap) {
427 dev_err(bus->dev, "Address of SPB capability is NULL"); 427 dev_err(bus->dev, "Address of SPB capability is NULL\n");
428 return; 428 return;
429 } 429 }
430 430
431 mask |= (1 << index); 431 mask |= (1 << index);
432 432
433 register_mask = readl(ebus->spbcap + AZX_REG_SPB_SPBFCCTL); 433 register_mask = readl(bus->spbcap + AZX_REG_SPB_SPBFCCTL);
434 434
435 mask |= register_mask; 435 mask |= register_mask;
436 436
437 if (enable) 437 if (enable)
438 snd_hdac_updatel(ebus->spbcap, AZX_REG_SPB_SPBFCCTL, 0, mask); 438 snd_hdac_updatel(bus->spbcap, AZX_REG_SPB_SPBFCCTL, 0, mask);
439 else 439 else
440 snd_hdac_updatel(ebus->spbcap, AZX_REG_SPB_SPBFCCTL, mask, 0); 440 snd_hdac_updatel(bus->spbcap, AZX_REG_SPB_SPBFCCTL, mask, 0);
441} 441}
442EXPORT_SYMBOL_GPL(snd_hdac_ext_stream_spbcap_enable); 442EXPORT_SYMBOL_GPL(snd_hdac_ext_stream_spbcap_enable);
443 443
@@ -452,8 +452,8 @@ int snd_hdac_ext_stream_set_spib(struct hdac_ext_bus *ebus,
452{ 452{
453 struct hdac_bus *bus = &ebus->bus; 453 struct hdac_bus *bus = &ebus->bus;
454 454
455 if (!ebus->spbcap) { 455 if (!bus->spbcap) {
456 dev_err(bus->dev, "Address of SPB capability is NULL"); 456 dev_err(bus->dev, "Address of SPB capability is NULL\n");
457 return -EINVAL; 457 return -EINVAL;
458 } 458 }
459 459
@@ -475,8 +475,8 @@ int snd_hdac_ext_stream_get_spbmaxfifo(struct hdac_ext_bus *ebus,
475{ 475{
476 struct hdac_bus *bus = &ebus->bus; 476 struct hdac_bus *bus = &ebus->bus;
477 477
478 if (!ebus->spbcap) { 478 if (!bus->spbcap) {
479 dev_err(bus->dev, "Address of SPB capability is NULL"); 479 dev_err(bus->dev, "Address of SPB capability is NULL\n");
480 return -EINVAL; 480 return -EINVAL;
481 } 481 }
482 482
@@ -515,21 +515,21 @@ void snd_hdac_ext_stream_drsm_enable(struct hdac_ext_bus *ebus,
515 u32 register_mask = 0; 515 u32 register_mask = 0;
516 struct hdac_bus *bus = &ebus->bus; 516 struct hdac_bus *bus = &ebus->bus;
517 517
518 if (!ebus->drsmcap) { 518 if (!bus->drsmcap) {
519 dev_err(bus->dev, "Address of DRSM capability is NULL"); 519 dev_err(bus->dev, "Address of DRSM capability is NULL\n");
520 return; 520 return;
521 } 521 }
522 522
523 mask |= (1 << index); 523 mask |= (1 << index);
524 524
525 register_mask = readl(ebus->drsmcap + AZX_REG_SPB_SPBFCCTL); 525 register_mask = readl(bus->drsmcap + AZX_REG_SPB_SPBFCCTL);
526 526
527 mask |= register_mask; 527 mask |= register_mask;
528 528
529 if (enable) 529 if (enable)
530 snd_hdac_updatel(ebus->drsmcap, AZX_REG_DRSM_CTL, 0, mask); 530 snd_hdac_updatel(bus->drsmcap, AZX_REG_DRSM_CTL, 0, mask);
531 else 531 else
532 snd_hdac_updatel(ebus->drsmcap, AZX_REG_DRSM_CTL, mask, 0); 532 snd_hdac_updatel(bus->drsmcap, AZX_REG_DRSM_CTL, mask, 0);
533} 533}
534EXPORT_SYMBOL_GPL(snd_hdac_ext_stream_drsm_enable); 534EXPORT_SYMBOL_GPL(snd_hdac_ext_stream_drsm_enable);
535 535
@@ -544,8 +544,8 @@ int snd_hdac_ext_stream_set_dpibr(struct hdac_ext_bus *ebus,
544{ 544{
545 struct hdac_bus *bus = &ebus->bus; 545 struct hdac_bus *bus = &ebus->bus;
546 546
547 if (!ebus->drsmcap) { 547 if (!bus->drsmcap) {
548 dev_err(bus->dev, "Address of DRSM capability is NULL"); 548 dev_err(bus->dev, "Address of DRSM capability is NULL\n");
549 return -EINVAL; 549 return -EINVAL;
550 } 550 }
551 551
diff --git a/sound/hda/hdac_controller.c b/sound/hda/hdac_controller.c
index 9fee464e5d49..043065867656 100644
--- a/sound/hda/hdac_controller.c
+++ b/sound/hda/hdac_controller.c
@@ -255,6 +255,81 @@ int snd_hdac_bus_get_response(struct hdac_bus *bus, unsigned int addr,
255} 255}
256EXPORT_SYMBOL_GPL(snd_hdac_bus_get_response); 256EXPORT_SYMBOL_GPL(snd_hdac_bus_get_response);
257 257
258#define HDAC_MAX_CAPS 10
259/**
260 * snd_hdac_bus_parse_capabilities - parse capability structure
261 * @bus: the pointer to bus object
262 *
263 * Returns 0 if successful, or a negative error code.
264 */
265int snd_hdac_bus_parse_capabilities(struct hdac_bus *bus)
266{
267 unsigned int cur_cap;
268 unsigned int offset;
269 unsigned int counter = 0;
270
271 offset = snd_hdac_chip_readl(bus, LLCH);
272
273 /* Lets walk the linked capabilities list */
274 do {
275 cur_cap = _snd_hdac_chip_read(l, bus, offset);
276
277 dev_dbg(bus->dev, "Capability version: 0x%x\n",
278 (cur_cap & AZX_CAP_HDR_VER_MASK) >> AZX_CAP_HDR_VER_OFF);
279
280 dev_dbg(bus->dev, "HDA capability ID: 0x%x\n",
281 (cur_cap & AZX_CAP_HDR_ID_MASK) >> AZX_CAP_HDR_ID_OFF);
282
283 switch ((cur_cap & AZX_CAP_HDR_ID_MASK) >> AZX_CAP_HDR_ID_OFF) {
284 case AZX_ML_CAP_ID:
285 dev_dbg(bus->dev, "Found ML capability\n");
286 bus->mlcap = bus->remap_addr + offset;
287 break;
288
289 case AZX_GTS_CAP_ID:
290 dev_dbg(bus->dev, "Found GTS capability offset=%x\n", offset);
291 bus->gtscap = bus->remap_addr + offset;
292 break;
293
294 case AZX_PP_CAP_ID:
295 /* PP capability found, the Audio DSP is present */
296 dev_dbg(bus->dev, "Found PP capability offset=%x\n", offset);
297 bus->ppcap = bus->remap_addr + offset;
298 break;
299
300 case AZX_SPB_CAP_ID:
301 /* SPIB capability found, handler function */
302 dev_dbg(bus->dev, "Found SPB capability\n");
303 bus->spbcap = bus->remap_addr + offset;
304 break;
305
306 case AZX_DRSM_CAP_ID:
307 /* DMA resume capability found, handler function */
308 dev_dbg(bus->dev, "Found DRSM capability\n");
309 bus->drsmcap = bus->remap_addr + offset;
310 break;
311
312 default:
313 dev_dbg(bus->dev, "Unknown capability %d\n", cur_cap);
314 break;
315 }
316
317 counter++;
318
319 if (counter > HDAC_MAX_CAPS) {
320 dev_err(bus->dev, "We exceeded HDAC capabilities!!!\n");
321 break;
322 }
323
324 /* read the offset of next capability */
325 offset = cur_cap & AZX_CAP_HDR_NXT_PTR_MASK;
326
327 } while (offset);
328
329 return 0;
330}
331EXPORT_SYMBOL_GPL(snd_hdac_bus_parse_capabilities);
332
258/* 333/*
259 * Lowlevel interface 334 * Lowlevel interface
260 */ 335 */
diff --git a/sound/pci/ad1889.c b/sound/pci/ad1889.c
index 1fc6d8bc09e5..8c36990e26f6 100644
--- a/sound/pci/ad1889.c
+++ b/sound/pci/ad1889.c
@@ -571,7 +571,7 @@ snd_ad1889_capture_pointer(struct snd_pcm_substream *ss)
571 return bytes_to_frames(ss->runtime, ptr); 571 return bytes_to_frames(ss->runtime, ptr);
572} 572}
573 573
574static struct snd_pcm_ops snd_ad1889_playback_ops = { 574static const struct snd_pcm_ops snd_ad1889_playback_ops = {
575 .open = snd_ad1889_playback_open, 575 .open = snd_ad1889_playback_open,
576 .close = snd_ad1889_playback_close, 576 .close = snd_ad1889_playback_close,
577 .ioctl = snd_pcm_lib_ioctl, 577 .ioctl = snd_pcm_lib_ioctl,
@@ -582,7 +582,7 @@ static struct snd_pcm_ops snd_ad1889_playback_ops = {
582 .pointer = snd_ad1889_playback_pointer, 582 .pointer = snd_ad1889_playback_pointer,
583}; 583};
584 584
585static struct snd_pcm_ops snd_ad1889_capture_ops = { 585static const struct snd_pcm_ops snd_ad1889_capture_ops = {
586 .open = snd_ad1889_capture_open, 586 .open = snd_ad1889_capture_open,
587 .close = snd_ad1889_capture_close, 587 .close = snd_ad1889_capture_close,
588 .ioctl = snd_pcm_lib_ioctl, 588 .ioctl = snd_pcm_lib_ioctl,
diff --git a/sound/pci/ali5451/ali5451.c b/sound/pci/ali5451/ali5451.c
index 36470af7eda7..92b819e4f729 100644
--- a/sound/pci/ali5451/ali5451.c
+++ b/sound/pci/ali5451/ali5451.c
@@ -1408,6 +1408,7 @@ snd_ali_playback_pointer(struct snd_pcm_substream *substream)
1408 spin_unlock(&codec->reg_lock); 1408 spin_unlock(&codec->reg_lock);
1409 dev_dbg(codec->card->dev, "playback pointer returned cso=%xh.\n", cso); 1409 dev_dbg(codec->card->dev, "playback pointer returned cso=%xh.\n", cso);
1410 1410
1411 cso %= runtime->buffer_size;
1411 return cso; 1412 return cso;
1412} 1413}
1413 1414
@@ -1428,6 +1429,7 @@ static snd_pcm_uframes_t snd_ali_pointer(struct snd_pcm_substream *substream)
1428 cso = inw(ALI_REG(codec, ALI_CSO_ALPHA_FMS + 2)); 1429 cso = inw(ALI_REG(codec, ALI_CSO_ALPHA_FMS + 2));
1429 spin_unlock(&codec->reg_lock); 1430 spin_unlock(&codec->reg_lock);
1430 1431
1432 cso %= runtime->buffer_size;
1431 return cso; 1433 return cso;
1432} 1434}
1433 1435
diff --git a/sound/pci/als300.c b/sound/pci/als300.c
index add3176398d3..ab75601d7c2c 100644
--- a/sound/pci/als300.c
+++ b/sound/pci/als300.c
@@ -563,7 +563,7 @@ static snd_pcm_uframes_t snd_als300_pointer(struct snd_pcm_substream *substream)
563 return bytes_to_frames(substream->runtime, current_ptr); 563 return bytes_to_frames(substream->runtime, current_ptr);
564} 564}
565 565
566static struct snd_pcm_ops snd_als300_playback_ops = { 566static const struct snd_pcm_ops snd_als300_playback_ops = {
567 .open = snd_als300_playback_open, 567 .open = snd_als300_playback_open,
568 .close = snd_als300_playback_close, 568 .close = snd_als300_playback_close,
569 .ioctl = snd_pcm_lib_ioctl, 569 .ioctl = snd_pcm_lib_ioctl,
@@ -574,7 +574,7 @@ static struct snd_pcm_ops snd_als300_playback_ops = {
574 .pointer = snd_als300_pointer, 574 .pointer = snd_als300_pointer,
575}; 575};
576 576
577static struct snd_pcm_ops snd_als300_capture_ops = { 577static const struct snd_pcm_ops snd_als300_capture_ops = {
578 .open = snd_als300_capture_open, 578 .open = snd_als300_capture_open,
579 .close = snd_als300_capture_close, 579 .close = snd_als300_capture_close,
580 .ioctl = snd_pcm_lib_ioctl, 580 .ioctl = snd_pcm_lib_ioctl,
diff --git a/sound/pci/als4000.c b/sound/pci/als4000.c
index ff39a0c7277b..edabe1371660 100644
--- a/sound/pci/als4000.c
+++ b/sound/pci/als4000.c
@@ -672,7 +672,7 @@ static int snd_als4000_capture_close(struct snd_pcm_substream *substream)
672 672
673/******************************************************************/ 673/******************************************************************/
674 674
675static struct snd_pcm_ops snd_als4000_playback_ops = { 675static const struct snd_pcm_ops snd_als4000_playback_ops = {
676 .open = snd_als4000_playback_open, 676 .open = snd_als4000_playback_open,
677 .close = snd_als4000_playback_close, 677 .close = snd_als4000_playback_close,
678 .ioctl = snd_pcm_lib_ioctl, 678 .ioctl = snd_pcm_lib_ioctl,
@@ -683,7 +683,7 @@ static struct snd_pcm_ops snd_als4000_playback_ops = {
683 .pointer = snd_als4000_playback_pointer 683 .pointer = snd_als4000_playback_pointer
684}; 684};
685 685
686static struct snd_pcm_ops snd_als4000_capture_ops = { 686static const struct snd_pcm_ops snd_als4000_capture_ops = {
687 .open = snd_als4000_capture_open, 687 .open = snd_als4000_capture_open,
688 .close = snd_als4000_capture_close, 688 .close = snd_als4000_capture_close,
689 .ioctl = snd_pcm_lib_ioctl, 689 .ioctl = snd_pcm_lib_ioctl,
diff --git a/sound/pci/asihpi/asihpi.c b/sound/pci/asihpi/asihpi.c
index 1039eccbb895..976a3d23557e 100644
--- a/sound/pci/asihpi/asihpi.c
+++ b/sound/pci/asihpi/asihpi.c
@@ -1138,7 +1138,7 @@ static int snd_card_asihpi_playback_close(struct snd_pcm_substream *substream)
1138 return 0; 1138 return 0;
1139} 1139}
1140 1140
1141static struct snd_pcm_ops snd_card_asihpi_playback_mmap_ops = { 1141static const struct snd_pcm_ops snd_card_asihpi_playback_mmap_ops = {
1142 .open = snd_card_asihpi_playback_open, 1142 .open = snd_card_asihpi_playback_open,
1143 .close = snd_card_asihpi_playback_close, 1143 .close = snd_card_asihpi_playback_close,
1144 .ioctl = snd_card_asihpi_playback_ioctl, 1144 .ioctl = snd_card_asihpi_playback_ioctl,
@@ -1305,7 +1305,7 @@ static int snd_card_asihpi_capture_close(struct snd_pcm_substream *substream)
1305 return 0; 1305 return 0;
1306} 1306}
1307 1307
1308static struct snd_pcm_ops snd_card_asihpi_capture_mmap_ops = { 1308static const struct snd_pcm_ops snd_card_asihpi_capture_mmap_ops = {
1309 .open = snd_card_asihpi_capture_open, 1309 .open = snd_card_asihpi_capture_open,
1310 .close = snd_card_asihpi_capture_close, 1310 .close = snd_card_asihpi_capture_close,
1311 .ioctl = snd_card_asihpi_capture_ioctl, 1311 .ioctl = snd_card_asihpi_capture_ioctl,
diff --git a/sound/pci/asihpi/hpifunc.c b/sound/pci/asihpi/hpifunc.c
index 510e56cffd31..f9b57647b319 100644
--- a/sound/pci/asihpi/hpifunc.c
+++ b/sound/pci/asihpi/hpifunc.c
@@ -2323,11 +2323,8 @@ u16 hpi_sample_clock_get_source_index(u32 h_control, u16 *pw_source_index)
2323u16 hpi_sample_clock_query_local_rate(const u32 h_clock, const u32 index, 2323u16 hpi_sample_clock_query_local_rate(const u32 h_clock, const u32 index,
2324 u32 *prate) 2324 u32 *prate)
2325{ 2325{
2326 u16 err; 2326 return hpi_control_query(h_clock, HPI_SAMPLECLOCK_LOCAL_SAMPLERATE,
2327 err = hpi_control_query(h_clock, HPI_SAMPLECLOCK_LOCAL_SAMPLERATE, 2327 index, 0, prate);
2328 index, 0, prate);
2329
2330 return err;
2331} 2328}
2332 2329
2333u16 hpi_sample_clock_set_local_rate(u32 h_control, u32 sample_rate) 2330u16 hpi_sample_clock_set_local_rate(u32 h_control, u32 sample_rate)
diff --git a/sound/pci/atiixp.c b/sound/pci/atiixp.c
index 2ce0022dbc46..a40c918c8dff 100644
--- a/sound/pci/atiixp.c
+++ b/sound/pci/atiixp.c
@@ -1148,7 +1148,7 @@ static int snd_atiixp_spdif_close(struct snd_pcm_substream *substream)
1148} 1148}
1149 1149
1150/* AC97 playback */ 1150/* AC97 playback */
1151static struct snd_pcm_ops snd_atiixp_playback_ops = { 1151static const struct snd_pcm_ops snd_atiixp_playback_ops = {
1152 .open = snd_atiixp_playback_open, 1152 .open = snd_atiixp_playback_open,
1153 .close = snd_atiixp_playback_close, 1153 .close = snd_atiixp_playback_close,
1154 .ioctl = snd_pcm_lib_ioctl, 1154 .ioctl = snd_pcm_lib_ioctl,
@@ -1160,7 +1160,7 @@ static struct snd_pcm_ops snd_atiixp_playback_ops = {
1160}; 1160};
1161 1161
1162/* AC97 capture */ 1162/* AC97 capture */
1163static struct snd_pcm_ops snd_atiixp_capture_ops = { 1163static const struct snd_pcm_ops snd_atiixp_capture_ops = {
1164 .open = snd_atiixp_capture_open, 1164 .open = snd_atiixp_capture_open,
1165 .close = snd_atiixp_capture_close, 1165 .close = snd_atiixp_capture_close,
1166 .ioctl = snd_pcm_lib_ioctl, 1166 .ioctl = snd_pcm_lib_ioctl,
@@ -1172,7 +1172,7 @@ static struct snd_pcm_ops snd_atiixp_capture_ops = {
1172}; 1172};
1173 1173
1174/* SPDIF playback */ 1174/* SPDIF playback */
1175static struct snd_pcm_ops snd_atiixp_spdif_ops = { 1175static const struct snd_pcm_ops snd_atiixp_spdif_ops = {
1176 .open = snd_atiixp_spdif_open, 1176 .open = snd_atiixp_spdif_open,
1177 .close = snd_atiixp_spdif_close, 1177 .close = snd_atiixp_spdif_close,
1178 .ioctl = snd_pcm_lib_ioctl, 1178 .ioctl = snd_pcm_lib_ioctl,
diff --git a/sound/pci/atiixp_modem.c b/sound/pci/atiixp_modem.c
index c534552963e7..40152feef1e7 100644
--- a/sound/pci/atiixp_modem.c
+++ b/sound/pci/atiixp_modem.c
@@ -947,7 +947,7 @@ static int snd_atiixp_capture_close(struct snd_pcm_substream *substream)
947 947
948 948
949/* AC97 playback */ 949/* AC97 playback */
950static struct snd_pcm_ops snd_atiixp_playback_ops = { 950static const struct snd_pcm_ops snd_atiixp_playback_ops = {
951 .open = snd_atiixp_playback_open, 951 .open = snd_atiixp_playback_open,
952 .close = snd_atiixp_playback_close, 952 .close = snd_atiixp_playback_close,
953 .ioctl = snd_pcm_lib_ioctl, 953 .ioctl = snd_pcm_lib_ioctl,
@@ -959,7 +959,7 @@ static struct snd_pcm_ops snd_atiixp_playback_ops = {
959}; 959};
960 960
961/* AC97 capture */ 961/* AC97 capture */
962static struct snd_pcm_ops snd_atiixp_capture_ops = { 962static const struct snd_pcm_ops snd_atiixp_capture_ops = {
963 .open = snd_atiixp_capture_open, 963 .open = snd_atiixp_capture_open,
964 .close = snd_atiixp_capture_close, 964 .close = snd_atiixp_capture_close,
965 .ioctl = snd_pcm_lib_ioctl, 965 .ioctl = snd_pcm_lib_ioctl,
diff --git a/sound/pci/au88x0/au88x0_core.c b/sound/pci/au88x0/au88x0_core.c
index d3125c169684..e1af24f87566 100644
--- a/sound/pci/au88x0/au88x0_core.c
+++ b/sound/pci/au88x0/au88x0_core.c
@@ -1043,7 +1043,7 @@ static void vortex_fifo_init(vortex_t * vortex)
1043 for (x = NR_ADB - 1; x >= 0; x--) { 1043 for (x = NR_ADB - 1; x >= 0; x--) {
1044 hwwrite(vortex->mmio, addr, (FIFO_U0 | FIFO_U1)); 1044 hwwrite(vortex->mmio, addr, (FIFO_U0 | FIFO_U1));
1045 if (hwread(vortex->mmio, addr) != (FIFO_U0 | FIFO_U1)) 1045 if (hwread(vortex->mmio, addr) != (FIFO_U0 | FIFO_U1))
1046 dev_err(vortex->card->dev, "bad adb fifo reset!"); 1046 dev_err(vortex->card->dev, "bad adb fifo reset!\n");
1047 vortex_fifo_clearadbdata(vortex, x, FIFO_SIZE); 1047 vortex_fifo_clearadbdata(vortex, x, FIFO_SIZE);
1048 addr -= 4; 1048 addr -= 4;
1049 } 1049 }
diff --git a/sound/pci/aw2/aw2-alsa.c b/sound/pci/aw2/aw2-alsa.c
index 167714303070..57bbb87d0c62 100644
--- a/sound/pci/aw2/aw2-alsa.c
+++ b/sound/pci/aw2/aw2-alsa.c
@@ -179,7 +179,7 @@ static struct pci_driver aw2_driver = {
179module_pci_driver(aw2_driver); 179module_pci_driver(aw2_driver);
180 180
181/* operators for playback PCM alsa interface */ 181/* operators for playback PCM alsa interface */
182static struct snd_pcm_ops snd_aw2_playback_ops = { 182static const struct snd_pcm_ops snd_aw2_playback_ops = {
183 .open = snd_aw2_pcm_playback_open, 183 .open = snd_aw2_pcm_playback_open,
184 .close = snd_aw2_pcm_playback_close, 184 .close = snd_aw2_pcm_playback_close,
185 .ioctl = snd_pcm_lib_ioctl, 185 .ioctl = snd_pcm_lib_ioctl,
@@ -191,7 +191,7 @@ static struct snd_pcm_ops snd_aw2_playback_ops = {
191}; 191};
192 192
193/* operators for capture PCM alsa interface */ 193/* operators for capture PCM alsa interface */
194static struct snd_pcm_ops snd_aw2_capture_ops = { 194static const struct snd_pcm_ops snd_aw2_capture_ops = {
195 .open = snd_aw2_pcm_capture_open, 195 .open = snd_aw2_pcm_capture_open,
196 .close = snd_aw2_pcm_capture_close, 196 .close = snd_aw2_pcm_capture_close,
197 .ioctl = snd_pcm_lib_ioctl, 197 .ioctl = snd_pcm_lib_ioctl,
diff --git a/sound/pci/azt3328.c b/sound/pci/azt3328.c
index 5e2ef0bb7057..80c4a4456197 100644
--- a/sound/pci/azt3328.c
+++ b/sound/pci/azt3328.c
@@ -2090,7 +2090,7 @@ snd_azf3328_pcm_close(struct snd_pcm_substream *substream
2090 2090
2091/******************************************************************/ 2091/******************************************************************/
2092 2092
2093static struct snd_pcm_ops snd_azf3328_playback_ops = { 2093static const struct snd_pcm_ops snd_azf3328_playback_ops = {
2094 .open = snd_azf3328_pcm_playback_open, 2094 .open = snd_azf3328_pcm_playback_open,
2095 .close = snd_azf3328_pcm_close, 2095 .close = snd_azf3328_pcm_close,
2096 .ioctl = snd_pcm_lib_ioctl, 2096 .ioctl = snd_pcm_lib_ioctl,
@@ -2101,7 +2101,7 @@ static struct snd_pcm_ops snd_azf3328_playback_ops = {
2101 .pointer = snd_azf3328_pcm_pointer 2101 .pointer = snd_azf3328_pcm_pointer
2102}; 2102};
2103 2103
2104static struct snd_pcm_ops snd_azf3328_capture_ops = { 2104static const struct snd_pcm_ops snd_azf3328_capture_ops = {
2105 .open = snd_azf3328_pcm_capture_open, 2105 .open = snd_azf3328_pcm_capture_open,
2106 .close = snd_azf3328_pcm_close, 2106 .close = snd_azf3328_pcm_close,
2107 .ioctl = snd_pcm_lib_ioctl, 2107 .ioctl = snd_pcm_lib_ioctl,
@@ -2112,7 +2112,7 @@ static struct snd_pcm_ops snd_azf3328_capture_ops = {
2112 .pointer = snd_azf3328_pcm_pointer 2112 .pointer = snd_azf3328_pcm_pointer
2113}; 2113};
2114 2114
2115static struct snd_pcm_ops snd_azf3328_i2s_out_ops = { 2115static const struct snd_pcm_ops snd_azf3328_i2s_out_ops = {
2116 .open = snd_azf3328_pcm_i2s_out_open, 2116 .open = snd_azf3328_pcm_i2s_out_open,
2117 .close = snd_azf3328_pcm_close, 2117 .close = snd_azf3328_pcm_close,
2118 .ioctl = snd_pcm_lib_ioctl, 2118 .ioctl = snd_pcm_lib_ioctl,
diff --git a/sound/pci/bt87x.c b/sound/pci/bt87x.c
index 5925b7170e25..f2c0709d7441 100644
--- a/sound/pci/bt87x.c
+++ b/sound/pci/bt87x.c
@@ -550,7 +550,7 @@ static snd_pcm_uframes_t snd_bt87x_pointer(struct snd_pcm_substream *substream)
550 return (snd_pcm_uframes_t)bytes_to_frames(runtime, chip->current_line * chip->line_bytes); 550 return (snd_pcm_uframes_t)bytes_to_frames(runtime, chip->current_line * chip->line_bytes);
551} 551}
552 552
553static struct snd_pcm_ops snd_bt87x_pcm_ops = { 553static const struct snd_pcm_ops snd_bt87x_pcm_ops = {
554 .open = snd_bt87x_pcm_open, 554 .open = snd_bt87x_pcm_open,
555 .close = snd_bt87x_close, 555 .close = snd_bt87x_close,
556 .ioctl = snd_pcm_lib_ioctl, 556 .ioctl = snd_pcm_lib_ioctl,
diff --git a/sound/pci/ca0106/ca0106_main.c b/sound/pci/ca0106/ca0106_main.c
index d3cd95633ee2..6165a57a94ae 100644
--- a/sound/pci/ca0106/ca0106_main.c
+++ b/sound/pci/ca0106/ca0106_main.c
@@ -1109,7 +1109,7 @@ snd_ca0106_pcm_pointer_capture(struct snd_pcm_substream *substream)
1109} 1109}
1110 1110
1111/* operators */ 1111/* operators */
1112static struct snd_pcm_ops snd_ca0106_playback_front_ops = { 1112static const struct snd_pcm_ops snd_ca0106_playback_front_ops = {
1113 .open = snd_ca0106_pcm_open_playback_front, 1113 .open = snd_ca0106_pcm_open_playback_front,
1114 .close = snd_ca0106_pcm_close_playback, 1114 .close = snd_ca0106_pcm_close_playback,
1115 .ioctl = snd_pcm_lib_ioctl, 1115 .ioctl = snd_pcm_lib_ioctl,
@@ -1120,7 +1120,7 @@ static struct snd_pcm_ops snd_ca0106_playback_front_ops = {
1120 .pointer = snd_ca0106_pcm_pointer_playback, 1120 .pointer = snd_ca0106_pcm_pointer_playback,
1121}; 1121};
1122 1122
1123static struct snd_pcm_ops snd_ca0106_capture_0_ops = { 1123static const struct snd_pcm_ops snd_ca0106_capture_0_ops = {
1124 .open = snd_ca0106_pcm_open_0_capture, 1124 .open = snd_ca0106_pcm_open_0_capture,
1125 .close = snd_ca0106_pcm_close_capture, 1125 .close = snd_ca0106_pcm_close_capture,
1126 .ioctl = snd_pcm_lib_ioctl, 1126 .ioctl = snd_pcm_lib_ioctl,
@@ -1131,7 +1131,7 @@ static struct snd_pcm_ops snd_ca0106_capture_0_ops = {
1131 .pointer = snd_ca0106_pcm_pointer_capture, 1131 .pointer = snd_ca0106_pcm_pointer_capture,
1132}; 1132};
1133 1133
1134static struct snd_pcm_ops snd_ca0106_capture_1_ops = { 1134static const struct snd_pcm_ops snd_ca0106_capture_1_ops = {
1135 .open = snd_ca0106_pcm_open_1_capture, 1135 .open = snd_ca0106_pcm_open_1_capture,
1136 .close = snd_ca0106_pcm_close_capture, 1136 .close = snd_ca0106_pcm_close_capture,
1137 .ioctl = snd_pcm_lib_ioctl, 1137 .ioctl = snd_pcm_lib_ioctl,
@@ -1142,7 +1142,7 @@ static struct snd_pcm_ops snd_ca0106_capture_1_ops = {
1142 .pointer = snd_ca0106_pcm_pointer_capture, 1142 .pointer = snd_ca0106_pcm_pointer_capture,
1143}; 1143};
1144 1144
1145static struct snd_pcm_ops snd_ca0106_capture_2_ops = { 1145static const struct snd_pcm_ops snd_ca0106_capture_2_ops = {
1146 .open = snd_ca0106_pcm_open_2_capture, 1146 .open = snd_ca0106_pcm_open_2_capture,
1147 .close = snd_ca0106_pcm_close_capture, 1147 .close = snd_ca0106_pcm_close_capture,
1148 .ioctl = snd_pcm_lib_ioctl, 1148 .ioctl = snd_pcm_lib_ioctl,
@@ -1153,7 +1153,7 @@ static struct snd_pcm_ops snd_ca0106_capture_2_ops = {
1153 .pointer = snd_ca0106_pcm_pointer_capture, 1153 .pointer = snd_ca0106_pcm_pointer_capture,
1154}; 1154};
1155 1155
1156static struct snd_pcm_ops snd_ca0106_capture_3_ops = { 1156static const struct snd_pcm_ops snd_ca0106_capture_3_ops = {
1157 .open = snd_ca0106_pcm_open_3_capture, 1157 .open = snd_ca0106_pcm_open_3_capture,
1158 .close = snd_ca0106_pcm_close_capture, 1158 .close = snd_ca0106_pcm_close_capture,
1159 .ioctl = snd_pcm_lib_ioctl, 1159 .ioctl = snd_pcm_lib_ioctl,
@@ -1164,7 +1164,7 @@ static struct snd_pcm_ops snd_ca0106_capture_3_ops = {
1164 .pointer = snd_ca0106_pcm_pointer_capture, 1164 .pointer = snd_ca0106_pcm_pointer_capture,
1165}; 1165};
1166 1166
1167static struct snd_pcm_ops snd_ca0106_playback_center_lfe_ops = { 1167static const struct snd_pcm_ops snd_ca0106_playback_center_lfe_ops = {
1168 .open = snd_ca0106_pcm_open_playback_center_lfe, 1168 .open = snd_ca0106_pcm_open_playback_center_lfe,
1169 .close = snd_ca0106_pcm_close_playback, 1169 .close = snd_ca0106_pcm_close_playback,
1170 .ioctl = snd_pcm_lib_ioctl, 1170 .ioctl = snd_pcm_lib_ioctl,
@@ -1175,7 +1175,7 @@ static struct snd_pcm_ops snd_ca0106_playback_center_lfe_ops = {
1175 .pointer = snd_ca0106_pcm_pointer_playback, 1175 .pointer = snd_ca0106_pcm_pointer_playback,
1176}; 1176};
1177 1177
1178static struct snd_pcm_ops snd_ca0106_playback_unknown_ops = { 1178static const struct snd_pcm_ops snd_ca0106_playback_unknown_ops = {
1179 .open = snd_ca0106_pcm_open_playback_unknown, 1179 .open = snd_ca0106_pcm_open_playback_unknown,
1180 .close = snd_ca0106_pcm_close_playback, 1180 .close = snd_ca0106_pcm_close_playback,
1181 .ioctl = snd_pcm_lib_ioctl, 1181 .ioctl = snd_pcm_lib_ioctl,
@@ -1186,7 +1186,7 @@ static struct snd_pcm_ops snd_ca0106_playback_unknown_ops = {
1186 .pointer = snd_ca0106_pcm_pointer_playback, 1186 .pointer = snd_ca0106_pcm_pointer_playback,
1187}; 1187};
1188 1188
1189static struct snd_pcm_ops snd_ca0106_playback_rear_ops = { 1189static const struct snd_pcm_ops snd_ca0106_playback_rear_ops = {
1190 .open = snd_ca0106_pcm_open_playback_rear, 1190 .open = snd_ca0106_pcm_open_playback_rear,
1191 .close = snd_ca0106_pcm_close_playback, 1191 .close = snd_ca0106_pcm_close_playback,
1192 .ioctl = snd_pcm_lib_ioctl, 1192 .ioctl = snd_pcm_lib_ioctl,
diff --git a/sound/pci/cmipci.c b/sound/pci/cmipci.c
index 24cdcba06d27..73f593526b2d 100644
--- a/sound/pci/cmipci.c
+++ b/sound/pci/cmipci.c
@@ -1838,7 +1838,7 @@ static int snd_cmipci_capture_spdif_close(struct snd_pcm_substream *substream)
1838/* 1838/*
1839 */ 1839 */
1840 1840
1841static struct snd_pcm_ops snd_cmipci_playback_ops = { 1841static const struct snd_pcm_ops snd_cmipci_playback_ops = {
1842 .open = snd_cmipci_playback_open, 1842 .open = snd_cmipci_playback_open,
1843 .close = snd_cmipci_playback_close, 1843 .close = snd_cmipci_playback_close,
1844 .ioctl = snd_pcm_lib_ioctl, 1844 .ioctl = snd_pcm_lib_ioctl,
@@ -1849,7 +1849,7 @@ static struct snd_pcm_ops snd_cmipci_playback_ops = {
1849 .pointer = snd_cmipci_playback_pointer, 1849 .pointer = snd_cmipci_playback_pointer,
1850}; 1850};
1851 1851
1852static struct snd_pcm_ops snd_cmipci_capture_ops = { 1852static const struct snd_pcm_ops snd_cmipci_capture_ops = {
1853 .open = snd_cmipci_capture_open, 1853 .open = snd_cmipci_capture_open,
1854 .close = snd_cmipci_capture_close, 1854 .close = snd_cmipci_capture_close,
1855 .ioctl = snd_pcm_lib_ioctl, 1855 .ioctl = snd_pcm_lib_ioctl,
@@ -1860,7 +1860,7 @@ static struct snd_pcm_ops snd_cmipci_capture_ops = {
1860 .pointer = snd_cmipci_capture_pointer, 1860 .pointer = snd_cmipci_capture_pointer,
1861}; 1861};
1862 1862
1863static struct snd_pcm_ops snd_cmipci_playback2_ops = { 1863static const struct snd_pcm_ops snd_cmipci_playback2_ops = {
1864 .open = snd_cmipci_playback2_open, 1864 .open = snd_cmipci_playback2_open,
1865 .close = snd_cmipci_playback2_close, 1865 .close = snd_cmipci_playback2_close,
1866 .ioctl = snd_pcm_lib_ioctl, 1866 .ioctl = snd_pcm_lib_ioctl,
@@ -1871,7 +1871,7 @@ static struct snd_pcm_ops snd_cmipci_playback2_ops = {
1871 .pointer = snd_cmipci_capture_pointer, /* channel B */ 1871 .pointer = snd_cmipci_capture_pointer, /* channel B */
1872}; 1872};
1873 1873
1874static struct snd_pcm_ops snd_cmipci_playback_spdif_ops = { 1874static const struct snd_pcm_ops snd_cmipci_playback_spdif_ops = {
1875 .open = snd_cmipci_playback_spdif_open, 1875 .open = snd_cmipci_playback_spdif_open,
1876 .close = snd_cmipci_playback_spdif_close, 1876 .close = snd_cmipci_playback_spdif_close,
1877 .ioctl = snd_pcm_lib_ioctl, 1877 .ioctl = snd_pcm_lib_ioctl,
@@ -1882,7 +1882,7 @@ static struct snd_pcm_ops snd_cmipci_playback_spdif_ops = {
1882 .pointer = snd_cmipci_playback_pointer, 1882 .pointer = snd_cmipci_playback_pointer,
1883}; 1883};
1884 1884
1885static struct snd_pcm_ops snd_cmipci_capture_spdif_ops = { 1885static const struct snd_pcm_ops snd_cmipci_capture_spdif_ops = {
1886 .open = snd_cmipci_capture_spdif_open, 1886 .open = snd_cmipci_capture_spdif_open,
1887 .close = snd_cmipci_capture_spdif_close, 1887 .close = snd_cmipci_capture_spdif_close,
1888 .ioctl = snd_pcm_lib_ioctl, 1888 .ioctl = snd_pcm_lib_ioctl,
diff --git a/sound/pci/cs4281.c b/sound/pci/cs4281.c
index c296fd0dbc9c..615d8a99d8c8 100644
--- a/sound/pci/cs4281.c
+++ b/sound/pci/cs4281.c
@@ -951,7 +951,7 @@ static int snd_cs4281_capture_close(struct snd_pcm_substream *substream)
951 return 0; 951 return 0;
952} 952}
953 953
954static struct snd_pcm_ops snd_cs4281_playback_ops = { 954static const struct snd_pcm_ops snd_cs4281_playback_ops = {
955 .open = snd_cs4281_playback_open, 955 .open = snd_cs4281_playback_open,
956 .close = snd_cs4281_playback_close, 956 .close = snd_cs4281_playback_close,
957 .ioctl = snd_pcm_lib_ioctl, 957 .ioctl = snd_pcm_lib_ioctl,
@@ -962,7 +962,7 @@ static struct snd_pcm_ops snd_cs4281_playback_ops = {
962 .pointer = snd_cs4281_pointer, 962 .pointer = snd_cs4281_pointer,
963}; 963};
964 964
965static struct snd_pcm_ops snd_cs4281_capture_ops = { 965static const struct snd_pcm_ops snd_cs4281_capture_ops = {
966 .open = snd_cs4281_capture_open, 966 .open = snd_cs4281_capture_open,
967 .close = snd_cs4281_capture_close, 967 .close = snd_cs4281_capture_close,
968 .ioctl = snd_pcm_lib_ioctl, 968 .ioctl = snd_pcm_lib_ioctl,
diff --git a/sound/pci/cs46xx/cs46xx_lib.c b/sound/pci/cs46xx/cs46xx_lib.c
index 2706f271a83b..528102cc2d5d 100644
--- a/sound/pci/cs46xx/cs46xx_lib.c
+++ b/sound/pci/cs46xx/cs46xx_lib.c
@@ -2460,7 +2460,7 @@ static int cs46xx_detect_codec(struct snd_cs46xx *chip, int codec)
2460 udelay(10); 2460 udelay(10);
2461 if (snd_cs46xx_codec_read(chip, AC97_RESET, codec) & 0x8000) { 2461 if (snd_cs46xx_codec_read(chip, AC97_RESET, codec) & 0x8000) {
2462 dev_dbg(chip->card->dev, 2462 dev_dbg(chip->card->dev,
2463 "seconadry codec not present\n"); 2463 "secondary codec not present\n");
2464 return -ENXIO; 2464 return -ENXIO;
2465 } 2465 }
2466 } 2466 }
@@ -2503,7 +2503,7 @@ int snd_cs46xx_mixer(struct snd_cs46xx *chip, int spdif_device)
2503 chip->nr_ac97_codecs = 1; 2503 chip->nr_ac97_codecs = 1;
2504 2504
2505#ifdef CONFIG_SND_CS46XX_NEW_DSP 2505#ifdef CONFIG_SND_CS46XX_NEW_DSP
2506 dev_dbg(chip->card->dev, "detecting seconadry codec\n"); 2506 dev_dbg(chip->card->dev, "detecting secondary codec\n");
2507 /* try detect a secondary codec */ 2507 /* try detect a secondary codec */
2508 if (! cs46xx_detect_codec(chip, CS46XX_SECONDARY_CODEC_INDEX)) 2508 if (! cs46xx_detect_codec(chip, CS46XX_SECONDARY_CODEC_INDEX))
2509 chip->nr_ac97_codecs = 2; 2509 chip->nr_ac97_codecs = 2;
diff --git a/sound/pci/cs46xx/dsp_spos.c b/sound/pci/cs46xx/dsp_spos.c
index d2951ed4bf71..4a0cbd2241d8 100644
--- a/sound/pci/cs46xx/dsp_spos.c
+++ b/sound/pci/cs46xx/dsp_spos.c
@@ -1441,7 +1441,7 @@ int cs46xx_dsp_scb_and_task_init (struct snd_cs46xx *chip)
1441 1441
1442 if (chip->nr_ac97_codecs == 2) { 1442 if (chip->nr_ac97_codecs == 2) {
1443 /* create CODEC tasklet for rear Center/LFE output 1443 /* create CODEC tasklet for rear Center/LFE output
1444 slot 6 and 9 on seconadry CODEC */ 1444 slot 6 and 9 on secondary CODEC */
1445 clfe_codec_out_scb = cs46xx_dsp_create_codec_out_scb(chip,"CodecOutSCB_CLFE",0x0030,0x0030, 1445 clfe_codec_out_scb = cs46xx_dsp_create_codec_out_scb(chip,"CodecOutSCB_CLFE",0x0030,0x0030,
1446 CLFE_MIXER_SCB_ADDR, 1446 CLFE_MIXER_SCB_ADDR,
1447 CLFE_CODEC_SCB_ADDR, 1447 CLFE_CODEC_SCB_ADDR,
diff --git a/sound/pci/cs5535audio/cs5535audio_pcm.c b/sound/pci/cs5535audio/cs5535audio_pcm.c
index 27fa57da8dc4..c208c1d8dbb2 100644
--- a/sound/pci/cs5535audio/cs5535audio_pcm.c
+++ b/sound/pci/cs5535audio/cs5535audio_pcm.c
@@ -380,7 +380,7 @@ static int snd_cs5535audio_capture_prepare(struct snd_pcm_substream *substream)
380 substream->runtime->rate); 380 substream->runtime->rate);
381} 381}
382 382
383static struct snd_pcm_ops snd_cs5535audio_playback_ops = { 383static const struct snd_pcm_ops snd_cs5535audio_playback_ops = {
384 .open = snd_cs5535audio_playback_open, 384 .open = snd_cs5535audio_playback_open,
385 .close = snd_cs5535audio_playback_close, 385 .close = snd_cs5535audio_playback_close,
386 .ioctl = snd_pcm_lib_ioctl, 386 .ioctl = snd_pcm_lib_ioctl,
@@ -391,7 +391,7 @@ static struct snd_pcm_ops snd_cs5535audio_playback_ops = {
391 .pointer = snd_cs5535audio_pcm_pointer, 391 .pointer = snd_cs5535audio_pcm_pointer,
392}; 392};
393 393
394static struct snd_pcm_ops snd_cs5535audio_capture_ops = { 394static const struct snd_pcm_ops snd_cs5535audio_capture_ops = {
395 .open = snd_cs5535audio_capture_open, 395 .open = snd_cs5535audio_capture_open,
396 .close = snd_cs5535audio_capture_close, 396 .close = snd_cs5535audio_capture_close,
397 .ioctl = snd_pcm_lib_ioctl, 397 .ioctl = snd_pcm_lib_ioctl,
diff --git a/sound/pci/ctxfi/ctatc.c b/sound/pci/ctxfi/ctatc.c
index 977a59855fa6..908658a00377 100644
--- a/sound/pci/ctxfi/ctatc.c
+++ b/sound/pci/ctxfi/ctatc.c
@@ -1623,7 +1623,7 @@ static int atc_resume(struct ct_atc *atc)
1623} 1623}
1624#endif 1624#endif
1625 1625
1626static struct ct_atc atc_preset = { 1626static const struct ct_atc atc_preset = {
1627 .map_audio_buffer = ct_map_audio_buffer, 1627 .map_audio_buffer = ct_map_audio_buffer,
1628 .unmap_audio_buffer = ct_unmap_audio_buffer, 1628 .unmap_audio_buffer = ct_unmap_audio_buffer,
1629 .pcm_playback_prepare = atc_pcm_playback_prepare, 1629 .pcm_playback_prepare = atc_pcm_playback_prepare,
diff --git a/sound/pci/ctxfi/ctpcm.c b/sound/pci/ctxfi/ctpcm.c
index d86c474ca5b6..974978041558 100644
--- a/sound/pci/ctxfi/ctpcm.c
+++ b/sound/pci/ctxfi/ctpcm.c
@@ -372,7 +372,7 @@ ct_pcm_capture_pointer(struct snd_pcm_substream *substream)
372} 372}
373 373
374/* PCM operators for playback */ 374/* PCM operators for playback */
375static struct snd_pcm_ops ct_pcm_playback_ops = { 375static const struct snd_pcm_ops ct_pcm_playback_ops = {
376 .open = ct_pcm_playback_open, 376 .open = ct_pcm_playback_open,
377 .close = ct_pcm_playback_close, 377 .close = ct_pcm_playback_close,
378 .ioctl = snd_pcm_lib_ioctl, 378 .ioctl = snd_pcm_lib_ioctl,
@@ -385,7 +385,7 @@ static struct snd_pcm_ops ct_pcm_playback_ops = {
385}; 385};
386 386
387/* PCM operators for capture */ 387/* PCM operators for capture */
388static struct snd_pcm_ops ct_pcm_capture_ops = { 388static const struct snd_pcm_ops ct_pcm_capture_ops = {
389 .open = ct_pcm_capture_open, 389 .open = ct_pcm_capture_open,
390 .close = ct_pcm_capture_close, 390 .close = ct_pcm_capture_close,
391 .ioctl = snd_pcm_lib_ioctl, 391 .ioctl = snd_pcm_lib_ioctl,
diff --git a/sound/pci/ctxfi/ctvmem.c b/sound/pci/ctxfi/ctvmem.c
index 419306ef825f..520e19bc649f 100644
--- a/sound/pci/ctxfi/ctvmem.c
+++ b/sound/pci/ctxfi/ctvmem.c
@@ -166,11 +166,7 @@ static void ct_vm_unmap(struct ct_vm *vm, struct ct_vm_block *block)
166static dma_addr_t 166static dma_addr_t
167ct_get_ptp_phys(struct ct_vm *vm, int index) 167ct_get_ptp_phys(struct ct_vm *vm, int index)
168{ 168{
169 dma_addr_t addr; 169 return (index >= CT_PTP_NUM) ? ~0UL : vm->ptp[index].addr;
170
171 addr = (index >= CT_PTP_NUM) ? ~0UL : vm->ptp[index].addr;
172
173 return addr;
174} 170}
175 171
176int ct_vm_create(struct ct_vm **rvm, struct pci_dev *pci) 172int ct_vm_create(struct ct_vm **rvm, struct pci_dev *pci)
diff --git a/sound/pci/emu10k1/emu10k1x.c b/sound/pci/emu10k1/emu10k1x.c
index 6d1b98d14327..921037ed8468 100644
--- a/sound/pci/emu10k1/emu10k1x.c
+++ b/sound/pci/emu10k1/emu10k1x.c
@@ -548,7 +548,7 @@ snd_emu10k1x_pcm_pointer(struct snd_pcm_substream *substream)
548} 548}
549 549
550/* operators */ 550/* operators */
551static struct snd_pcm_ops snd_emu10k1x_playback_ops = { 551static const struct snd_pcm_ops snd_emu10k1x_playback_ops = {
552 .open = snd_emu10k1x_playback_open, 552 .open = snd_emu10k1x_playback_open,
553 .close = snd_emu10k1x_playback_close, 553 .close = snd_emu10k1x_playback_close,
554 .ioctl = snd_pcm_lib_ioctl, 554 .ioctl = snd_pcm_lib_ioctl,
@@ -694,7 +694,7 @@ snd_emu10k1x_pcm_pointer_capture(struct snd_pcm_substream *substream)
694 return ptr; 694 return ptr;
695} 695}
696 696
697static struct snd_pcm_ops snd_emu10k1x_capture_ops = { 697static const struct snd_pcm_ops snd_emu10k1x_capture_ops = {
698 .open = snd_emu10k1x_pcm_open_capture, 698 .open = snd_emu10k1x_pcm_open_capture,
699 .close = snd_emu10k1x_pcm_close_capture, 699 .close = snd_emu10k1x_pcm_close_capture,
700 .ioctl = snd_pcm_lib_ioctl, 700 .ioctl = snd_pcm_lib_ioctl,
diff --git a/sound/pci/emu10k1/emupcm.c b/sound/pci/emu10k1/emupcm.c
index 14a305bd8a98..37be1e14d756 100644
--- a/sound/pci/emu10k1/emupcm.c
+++ b/sound/pci/emu10k1/emupcm.c
@@ -1364,7 +1364,7 @@ static int snd_emu10k1_capture_efx_close(struct snd_pcm_substream *substream)
1364 return 0; 1364 return 0;
1365} 1365}
1366 1366
1367static struct snd_pcm_ops snd_emu10k1_playback_ops = { 1367static const struct snd_pcm_ops snd_emu10k1_playback_ops = {
1368 .open = snd_emu10k1_playback_open, 1368 .open = snd_emu10k1_playback_open,
1369 .close = snd_emu10k1_playback_close, 1369 .close = snd_emu10k1_playback_close,
1370 .ioctl = snd_pcm_lib_ioctl, 1370 .ioctl = snd_pcm_lib_ioctl,
@@ -1376,7 +1376,7 @@ static struct snd_pcm_ops snd_emu10k1_playback_ops = {
1376 .page = snd_pcm_sgbuf_ops_page, 1376 .page = snd_pcm_sgbuf_ops_page,
1377}; 1377};
1378 1378
1379static struct snd_pcm_ops snd_emu10k1_capture_ops = { 1379static const struct snd_pcm_ops snd_emu10k1_capture_ops = {
1380 .open = snd_emu10k1_capture_open, 1380 .open = snd_emu10k1_capture_open,
1381 .close = snd_emu10k1_capture_close, 1381 .close = snd_emu10k1_capture_close,
1382 .ioctl = snd_pcm_lib_ioctl, 1382 .ioctl = snd_pcm_lib_ioctl,
@@ -1388,7 +1388,7 @@ static struct snd_pcm_ops snd_emu10k1_capture_ops = {
1388}; 1388};
1389 1389
1390/* EFX playback */ 1390/* EFX playback */
1391static struct snd_pcm_ops snd_emu10k1_efx_playback_ops = { 1391static const struct snd_pcm_ops snd_emu10k1_efx_playback_ops = {
1392 .open = snd_emu10k1_efx_playback_open, 1392 .open = snd_emu10k1_efx_playback_open,
1393 .close = snd_emu10k1_efx_playback_close, 1393 .close = snd_emu10k1_efx_playback_close,
1394 .ioctl = snd_pcm_lib_ioctl, 1394 .ioctl = snd_pcm_lib_ioctl,
@@ -1455,7 +1455,7 @@ int snd_emu10k1_pcm_multi(struct snd_emu10k1 *emu, int device)
1455} 1455}
1456 1456
1457 1457
1458static struct snd_pcm_ops snd_emu10k1_capture_mic_ops = { 1458static const struct snd_pcm_ops snd_emu10k1_capture_mic_ops = {
1459 .open = snd_emu10k1_capture_mic_open, 1459 .open = snd_emu10k1_capture_mic_open,
1460 .close = snd_emu10k1_capture_mic_close, 1460 .close = snd_emu10k1_capture_mic_close,
1461 .ioctl = snd_pcm_lib_ioctl, 1461 .ioctl = snd_pcm_lib_ioctl,
@@ -1550,7 +1550,7 @@ static struct snd_kcontrol_new snd_emu10k1_pcm_efx_voices_mask = {
1550 .put = snd_emu10k1_pcm_efx_voices_mask_put 1550 .put = snd_emu10k1_pcm_efx_voices_mask_put
1551}; 1551};
1552 1552
1553static struct snd_pcm_ops snd_emu10k1_capture_efx_ops = { 1553static const struct snd_pcm_ops snd_emu10k1_capture_efx_ops = {
1554 .open = snd_emu10k1_capture_efx_open, 1554 .open = snd_emu10k1_capture_efx_open,
1555 .close = snd_emu10k1_capture_efx_close, 1555 .close = snd_emu10k1_capture_efx_close,
1556 .ioctl = snd_pcm_lib_ioctl, 1556 .ioctl = snd_pcm_lib_ioctl,
@@ -1791,7 +1791,7 @@ static int snd_emu10k1_fx8010_playback_close(struct snd_pcm_substream *substream
1791 return 0; 1791 return 0;
1792} 1792}
1793 1793
1794static struct snd_pcm_ops snd_emu10k1_fx8010_playback_ops = { 1794static const struct snd_pcm_ops snd_emu10k1_fx8010_playback_ops = {
1795 .open = snd_emu10k1_fx8010_playback_open, 1795 .open = snd_emu10k1_fx8010_playback_open,
1796 .close = snd_emu10k1_fx8010_playback_close, 1796 .close = snd_emu10k1_fx8010_playback_close,
1797 .ioctl = snd_pcm_lib_ioctl, 1797 .ioctl = snd_pcm_lib_ioctl,
diff --git a/sound/pci/emu10k1/p16v.c b/sound/pci/emu10k1/p16v.c
index 3c60b433de9f..c11f1a29f35d 100644
--- a/sound/pci/emu10k1/p16v.c
+++ b/sound/pci/emu10k1/p16v.c
@@ -300,37 +300,29 @@ static int snd_p16v_pcm_open_capture(struct snd_pcm_substream *substream)
300static int snd_p16v_pcm_hw_params_playback(struct snd_pcm_substream *substream, 300static int snd_p16v_pcm_hw_params_playback(struct snd_pcm_substream *substream,
301 struct snd_pcm_hw_params *hw_params) 301 struct snd_pcm_hw_params *hw_params)
302{ 302{
303 int result; 303 return snd_pcm_lib_malloc_pages(substream,
304 result = snd_pcm_lib_malloc_pages(substream,
305 params_buffer_bytes(hw_params)); 304 params_buffer_bytes(hw_params));
306 return result;
307} 305}
308 306
309/* hw_params callback */ 307/* hw_params callback */
310static int snd_p16v_pcm_hw_params_capture(struct snd_pcm_substream *substream, 308static int snd_p16v_pcm_hw_params_capture(struct snd_pcm_substream *substream,
311 struct snd_pcm_hw_params *hw_params) 309 struct snd_pcm_hw_params *hw_params)
312{ 310{
313 int result; 311 return snd_pcm_lib_malloc_pages(substream,
314 result = snd_pcm_lib_malloc_pages(substream,
315 params_buffer_bytes(hw_params)); 312 params_buffer_bytes(hw_params));
316 return result;
317} 313}
318 314
319 315
320/* hw_free callback */ 316/* hw_free callback */
321static int snd_p16v_pcm_hw_free_playback(struct snd_pcm_substream *substream) 317static int snd_p16v_pcm_hw_free_playback(struct snd_pcm_substream *substream)
322{ 318{
323 int result; 319 return snd_pcm_lib_free_pages(substream);
324 result = snd_pcm_lib_free_pages(substream);
325 return result;
326} 320}
327 321
328/* hw_free callback */ 322/* hw_free callback */
329static int snd_p16v_pcm_hw_free_capture(struct snd_pcm_substream *substream) 323static int snd_p16v_pcm_hw_free_capture(struct snd_pcm_substream *substream)
330{ 324{
331 int result; 325 return snd_pcm_lib_free_pages(substream);
332 result = snd_pcm_lib_free_pages(substream);
333 return result;
334} 326}
335 327
336 328
@@ -601,7 +593,7 @@ snd_p16v_pcm_pointer_capture(struct snd_pcm_substream *substream)
601} 593}
602 594
603/* operators */ 595/* operators */
604static struct snd_pcm_ops snd_p16v_playback_front_ops = { 596static const struct snd_pcm_ops snd_p16v_playback_front_ops = {
605 .open = snd_p16v_pcm_open_playback_front, 597 .open = snd_p16v_pcm_open_playback_front,
606 .close = snd_p16v_pcm_close_playback, 598 .close = snd_p16v_pcm_close_playback,
607 .ioctl = snd_pcm_lib_ioctl, 599 .ioctl = snd_pcm_lib_ioctl,
@@ -612,7 +604,7 @@ static struct snd_pcm_ops snd_p16v_playback_front_ops = {
612 .pointer = snd_p16v_pcm_pointer_playback, 604 .pointer = snd_p16v_pcm_pointer_playback,
613}; 605};
614 606
615static struct snd_pcm_ops snd_p16v_capture_ops = { 607static const struct snd_pcm_ops snd_p16v_capture_ops = {
616 .open = snd_p16v_pcm_open_capture, 608 .open = snd_p16v_pcm_open_capture,
617 .close = snd_p16v_pcm_close_capture, 609 .close = snd_p16v_pcm_close_capture,
618 .ioctl = snd_pcm_lib_ioctl, 610 .ioctl = snd_pcm_lib_ioctl,
diff --git a/sound/pci/ens1370.c b/sound/pci/ens1370.c
index 626cd2167d29..7e760fed0728 100644
--- a/sound/pci/ens1370.c
+++ b/sound/pci/ens1370.c
@@ -1227,7 +1227,7 @@ static int snd_ensoniq_capture_close(struct snd_pcm_substream *substream)
1227 return 0; 1227 return 0;
1228} 1228}
1229 1229
1230static struct snd_pcm_ops snd_ensoniq_playback1_ops = { 1230static const struct snd_pcm_ops snd_ensoniq_playback1_ops = {
1231 .open = snd_ensoniq_playback1_open, 1231 .open = snd_ensoniq_playback1_open,
1232 .close = snd_ensoniq_playback1_close, 1232 .close = snd_ensoniq_playback1_close,
1233 .ioctl = snd_pcm_lib_ioctl, 1233 .ioctl = snd_pcm_lib_ioctl,
@@ -1238,7 +1238,7 @@ static struct snd_pcm_ops snd_ensoniq_playback1_ops = {
1238 .pointer = snd_ensoniq_playback1_pointer, 1238 .pointer = snd_ensoniq_playback1_pointer,
1239}; 1239};
1240 1240
1241static struct snd_pcm_ops snd_ensoniq_playback2_ops = { 1241static const struct snd_pcm_ops snd_ensoniq_playback2_ops = {
1242 .open = snd_ensoniq_playback2_open, 1242 .open = snd_ensoniq_playback2_open,
1243 .close = snd_ensoniq_playback2_close, 1243 .close = snd_ensoniq_playback2_close,
1244 .ioctl = snd_pcm_lib_ioctl, 1244 .ioctl = snd_pcm_lib_ioctl,
@@ -1249,7 +1249,7 @@ static struct snd_pcm_ops snd_ensoniq_playback2_ops = {
1249 .pointer = snd_ensoniq_playback2_pointer, 1249 .pointer = snd_ensoniq_playback2_pointer,
1250}; 1250};
1251 1251
1252static struct snd_pcm_ops snd_ensoniq_capture_ops = { 1252static const struct snd_pcm_ops snd_ensoniq_capture_ops = {
1253 .open = snd_ensoniq_capture_open, 1253 .open = snd_ensoniq_capture_open,
1254 .close = snd_ensoniq_capture_close, 1254 .close = snd_ensoniq_capture_close,
1255 .ioctl = snd_pcm_lib_ioctl, 1255 .ioctl = snd_pcm_lib_ioctl,
diff --git a/sound/pci/es1938.c b/sound/pci/es1938.c
index 8963d7688fb0..681355829484 100644
--- a/sound/pci/es1938.c
+++ b/sound/pci/es1938.c
@@ -992,7 +992,7 @@ static int snd_es1938_playback_close(struct snd_pcm_substream *substream)
992 return 0; 992 return 0;
993} 993}
994 994
995static struct snd_pcm_ops snd_es1938_playback_ops = { 995static const struct snd_pcm_ops snd_es1938_playback_ops = {
996 .open = snd_es1938_playback_open, 996 .open = snd_es1938_playback_open,
997 .close = snd_es1938_playback_close, 997 .close = snd_es1938_playback_close,
998 .ioctl = snd_pcm_lib_ioctl, 998 .ioctl = snd_pcm_lib_ioctl,
@@ -1003,7 +1003,7 @@ static struct snd_pcm_ops snd_es1938_playback_ops = {
1003 .pointer = snd_es1938_playback_pointer, 1003 .pointer = snd_es1938_playback_pointer,
1004}; 1004};
1005 1005
1006static struct snd_pcm_ops snd_es1938_capture_ops = { 1006static const struct snd_pcm_ops snd_es1938_capture_ops = {
1007 .open = snd_es1938_capture_open, 1007 .open = snd_es1938_capture_open,
1008 .close = snd_es1938_capture_close, 1008 .close = snd_es1938_capture_close,
1009 .ioctl = snd_pcm_lib_ioctl, 1009 .ioctl = snd_pcm_lib_ioctl,
diff --git a/sound/pci/es1968.c b/sound/pci/es1968.c
index 514f2604086e..8146fb76a4ad 100644
--- a/sound/pci/es1968.c
+++ b/sound/pci/es1968.c
@@ -1677,7 +1677,7 @@ static int snd_es1968_capture_close(struct snd_pcm_substream *substream)
1677 return 0; 1677 return 0;
1678} 1678}
1679 1679
1680static struct snd_pcm_ops snd_es1968_playback_ops = { 1680static const struct snd_pcm_ops snd_es1968_playback_ops = {
1681 .open = snd_es1968_playback_open, 1681 .open = snd_es1968_playback_open,
1682 .close = snd_es1968_playback_close, 1682 .close = snd_es1968_playback_close,
1683 .ioctl = snd_pcm_lib_ioctl, 1683 .ioctl = snd_pcm_lib_ioctl,
@@ -1688,7 +1688,7 @@ static struct snd_pcm_ops snd_es1968_playback_ops = {
1688 .pointer = snd_es1968_pcm_pointer, 1688 .pointer = snd_es1968_pcm_pointer,
1689}; 1689};
1690 1690
1691static struct snd_pcm_ops snd_es1968_capture_ops = { 1691static const struct snd_pcm_ops snd_es1968_capture_ops = {
1692 .open = snd_es1968_capture_open, 1692 .open = snd_es1968_capture_open,
1693 .close = snd_es1968_capture_close, 1693 .close = snd_es1968_capture_close,
1694 .ioctl = snd_pcm_lib_ioctl, 1694 .ioctl = snd_pcm_lib_ioctl,
diff --git a/sound/pci/fm801.c b/sound/pci/fm801.c
index bade9b907b92..c47287d79306 100644
--- a/sound/pci/fm801.c
+++ b/sound/pci/fm801.c
@@ -691,7 +691,7 @@ static int snd_fm801_capture_close(struct snd_pcm_substream *substream)
691 return 0; 691 return 0;
692} 692}
693 693
694static struct snd_pcm_ops snd_fm801_playback_ops = { 694static const struct snd_pcm_ops snd_fm801_playback_ops = {
695 .open = snd_fm801_playback_open, 695 .open = snd_fm801_playback_open,
696 .close = snd_fm801_playback_close, 696 .close = snd_fm801_playback_close,
697 .ioctl = snd_pcm_lib_ioctl, 697 .ioctl = snd_pcm_lib_ioctl,
@@ -702,7 +702,7 @@ static struct snd_pcm_ops snd_fm801_playback_ops = {
702 .pointer = snd_fm801_playback_pointer, 702 .pointer = snd_fm801_playback_pointer,
703}; 703};
704 704
705static struct snd_pcm_ops snd_fm801_capture_ops = { 705static const struct snd_pcm_ops snd_fm801_capture_ops = {
706 .open = snd_fm801_capture_open, 706 .open = snd_fm801_capture_open,
707 .close = snd_fm801_capture_close, 707 .close = snd_fm801_capture_close,
708 .ioctl = snd_pcm_lib_ioctl, 708 .ioctl = snd_pcm_lib_ioctl,
diff --git a/sound/pci/hda/hda_controller.c b/sound/pci/hda/hda_controller.c
index 27de8015717d..500878556578 100644
--- a/sound/pci/hda/hda_controller.c
+++ b/sound/pci/hda/hda_controller.c
@@ -27,6 +27,12 @@
27#include <linux/module.h> 27#include <linux/module.h>
28#include <linux/pm_runtime.h> 28#include <linux/pm_runtime.h>
29#include <linux/slab.h> 29#include <linux/slab.h>
30
31#ifdef CONFIG_X86
32/* for art-tsc conversion */
33#include <asm/tsc.h>
34#endif
35
30#include <sound/core.h> 36#include <sound/core.h>
31#include <sound/initval.h> 37#include <sound/initval.h>
32#include "hda_controller.h" 38#include "hda_controller.h"
@@ -337,12 +343,173 @@ static snd_pcm_uframes_t azx_pcm_pointer(struct snd_pcm_substream *substream)
337 azx_get_position(chip, azx_dev)); 343 azx_get_position(chip, azx_dev));
338} 344}
339 345
346/*
347 * azx_scale64: Scale base by mult/div while not overflowing sanely
348 *
349 * Derived from scale64_check_overflow in kernel/time/timekeeping.c
350 *
351 * The tmestamps for a 48Khz stream can overflow after (2^64/10^9)/48K which
352 * is about 384307 ie ~4.5 days.
353 *
354 * This scales the calculation so that overflow will happen but after 2^64 /
355 * 48000 secs, which is pretty large!
356 *
357 * In caln below:
358 * base may overflow, but since there isn’t any additional division
359 * performed on base it’s OK
360 * rem can’t overflow because both are 32-bit values
361 */
362
363#ifdef CONFIG_X86
364static u64 azx_scale64(u64 base, u32 num, u32 den)
365{
366 u64 rem;
367
368 rem = do_div(base, den);
369
370 base *= num;
371 rem *= num;
372
373 do_div(rem, den);
374
375 return base + rem;
376}
377
378static int azx_get_sync_time(ktime_t *device,
379 struct system_counterval_t *system, void *ctx)
380{
381 struct snd_pcm_substream *substream = ctx;
382 struct azx_dev *azx_dev = get_azx_dev(substream);
383 struct azx_pcm *apcm = snd_pcm_substream_chip(substream);
384 struct azx *chip = apcm->chip;
385 struct snd_pcm_runtime *runtime;
386 u64 ll_counter, ll_counter_l, ll_counter_h;
387 u64 tsc_counter, tsc_counter_l, tsc_counter_h;
388 u32 wallclk_ctr, wallclk_cycles;
389 bool direction;
390 u32 dma_select;
391 u32 timeout = 200;
392 u32 retry_count = 0;
393
394 runtime = substream->runtime;
395
396 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
397 direction = 1;
398 else
399 direction = 0;
400
401 /* 0th stream tag is not used, so DMA ch 0 is for 1st stream tag */
402 do {
403 timeout = 100;
404 dma_select = (direction << GTSCC_CDMAS_DMA_DIR_SHIFT) |
405 (azx_dev->core.stream_tag - 1);
406 snd_hdac_chip_writel(azx_bus(chip), GTSCC, dma_select);
407
408 /* Enable the capture */
409 snd_hdac_chip_updatel(azx_bus(chip), GTSCC, 0, GTSCC_TSCCI_MASK);
410
411 while (timeout) {
412 if (snd_hdac_chip_readl(azx_bus(chip), GTSCC) &
413 GTSCC_TSCCD_MASK)
414 break;
415
416 timeout--;
417 }
418
419 if (!timeout) {
420 dev_err(chip->card->dev, "GTSCC capture Timedout!\n");
421 return -EIO;
422 }
423
424 /* Read wall clock counter */
425 wallclk_ctr = snd_hdac_chip_readl(azx_bus(chip), WALFCC);
426
427 /* Read TSC counter */
428 tsc_counter_l = snd_hdac_chip_readl(azx_bus(chip), TSCCL);
429 tsc_counter_h = snd_hdac_chip_readl(azx_bus(chip), TSCCU);
430
431 /* Read Link counter */
432 ll_counter_l = snd_hdac_chip_readl(azx_bus(chip), LLPCL);
433 ll_counter_h = snd_hdac_chip_readl(azx_bus(chip), LLPCU);
434
435 /* Ack: registers read done */
436 snd_hdac_chip_writel(azx_bus(chip), GTSCC, GTSCC_TSCCD_SHIFT);
437
438 tsc_counter = (tsc_counter_h << TSCCU_CCU_SHIFT) |
439 tsc_counter_l;
440
441 ll_counter = (ll_counter_h << LLPC_CCU_SHIFT) | ll_counter_l;
442 wallclk_cycles = wallclk_ctr & WALFCC_CIF_MASK;
443
444 /*
445 * An error occurs near frame "rollover". The clocks in
446 * frame value indicates whether this error may have
447 * occurred. Here we use the value of 10 i.e.,
448 * HDA_MAX_CYCLE_OFFSET
449 */
450 if (wallclk_cycles < HDA_MAX_CYCLE_VALUE - HDA_MAX_CYCLE_OFFSET
451 && wallclk_cycles > HDA_MAX_CYCLE_OFFSET)
452 break;
453
454 /*
455 * Sleep before we read again, else we may again get
456 * value near to MAX_CYCLE. Try to sleep for different
457 * amount of time so we dont hit the same number again
458 */
459 udelay(retry_count++);
460
461 } while (retry_count != HDA_MAX_CYCLE_READ_RETRY);
462
463 if (retry_count == HDA_MAX_CYCLE_READ_RETRY) {
464 dev_err_ratelimited(chip->card->dev,
465 "Error in WALFCC cycle count\n");
466 return -EIO;
467 }
468
469 *device = ns_to_ktime(azx_scale64(ll_counter,
470 NSEC_PER_SEC, runtime->rate));
471 *device = ktime_add_ns(*device, (wallclk_cycles * NSEC_PER_SEC) /
472 ((HDA_MAX_CYCLE_VALUE + 1) * runtime->rate));
473
474 *system = convert_art_to_tsc(tsc_counter);
475
476 return 0;
477}
478
479#else
480static int azx_get_sync_time(ktime_t *device,
481 struct system_counterval_t *system, void *ctx)
482{
483 return -ENXIO;
484}
485#endif
486
487static int azx_get_crosststamp(struct snd_pcm_substream *substream,
488 struct system_device_crosststamp *xtstamp)
489{
490 return get_device_system_crosststamp(azx_get_sync_time,
491 substream, NULL, xtstamp);
492}
493
494static inline bool is_link_time_supported(struct snd_pcm_runtime *runtime,
495 struct snd_pcm_audio_tstamp_config *ts)
496{
497 if (runtime->hw.info & SNDRV_PCM_INFO_HAS_LINK_SYNCHRONIZED_ATIME)
498 if (ts->type_requested == SNDRV_PCM_AUDIO_TSTAMP_TYPE_LINK_SYNCHRONIZED)
499 return true;
500
501 return false;
502}
503
340static int azx_get_time_info(struct snd_pcm_substream *substream, 504static int azx_get_time_info(struct snd_pcm_substream *substream,
341 struct timespec *system_ts, struct timespec *audio_ts, 505 struct timespec *system_ts, struct timespec *audio_ts,
342 struct snd_pcm_audio_tstamp_config *audio_tstamp_config, 506 struct snd_pcm_audio_tstamp_config *audio_tstamp_config,
343 struct snd_pcm_audio_tstamp_report *audio_tstamp_report) 507 struct snd_pcm_audio_tstamp_report *audio_tstamp_report)
344{ 508{
345 struct azx_dev *azx_dev = get_azx_dev(substream); 509 struct azx_dev *azx_dev = get_azx_dev(substream);
510 struct snd_pcm_runtime *runtime = substream->runtime;
511 struct system_device_crosststamp xtstamp;
512 int ret;
346 u64 nsec; 513 u64 nsec;
347 514
348 if ((substream->runtime->hw.info & SNDRV_PCM_INFO_HAS_LINK_ATIME) && 515 if ((substream->runtime->hw.info & SNDRV_PCM_INFO_HAS_LINK_ATIME) &&
@@ -361,8 +528,37 @@ static int azx_get_time_info(struct snd_pcm_substream *substream,
361 audio_tstamp_report->accuracy_report = 1; /* rest of structure is valid */ 528 audio_tstamp_report->accuracy_report = 1; /* rest of structure is valid */
362 audio_tstamp_report->accuracy = 42; /* 24 MHz WallClock == 42ns resolution */ 529 audio_tstamp_report->accuracy = 42; /* 24 MHz WallClock == 42ns resolution */
363 530
364 } else 531 } else if (is_link_time_supported(runtime, audio_tstamp_config)) {
532
533 ret = azx_get_crosststamp(substream, &xtstamp);
534 if (ret)
535 return ret;
536
537 switch (runtime->tstamp_type) {
538 case SNDRV_PCM_TSTAMP_TYPE_MONOTONIC:
539 return -EINVAL;
540
541 case SNDRV_PCM_TSTAMP_TYPE_MONOTONIC_RAW:
542 *system_ts = ktime_to_timespec(xtstamp.sys_monoraw);
543 break;
544
545 default:
546 *system_ts = ktime_to_timespec(xtstamp.sys_realtime);
547 break;
548
549 }
550
551 *audio_ts = ktime_to_timespec(xtstamp.device);
552
553 audio_tstamp_report->actual_type =
554 SNDRV_PCM_AUDIO_TSTAMP_TYPE_LINK_SYNCHRONIZED;
555 audio_tstamp_report->accuracy_report = 1;
556 /* 24 MHz WallClock == 42ns resolution */
557 audio_tstamp_report->accuracy = 42;
558
559 } else {
365 audio_tstamp_report->actual_type = SNDRV_PCM_AUDIO_TSTAMP_TYPE_DEFAULT; 560 audio_tstamp_report->actual_type = SNDRV_PCM_AUDIO_TSTAMP_TYPE_DEFAULT;
561 }
366 562
367 return 0; 563 return 0;
368} 564}
@@ -412,6 +608,11 @@ static int azx_pcm_open(struct snd_pcm_substream *substream)
412 goto unlock; 608 goto unlock;
413 } 609 }
414 runtime->private_data = azx_dev; 610 runtime->private_data = azx_dev;
611
612 if (chip->gts_present)
613 azx_pcm_hw.info = azx_pcm_hw.info |
614 SNDRV_PCM_INFO_HAS_LINK_SYNCHRONIZED_ATIME;
615
415 runtime->hw = azx_pcm_hw; 616 runtime->hw = azx_pcm_hw;
416 runtime->hw.channels_min = hinfo->channels_min; 617 runtime->hw.channels_min = hinfo->channels_min;
417 runtime->hw.channels_max = hinfo->channels_max; 618 runtime->hw.channels_max = hinfo->channels_max;
@@ -495,7 +696,7 @@ static int azx_pcm_mmap(struct snd_pcm_substream *substream,
495 return snd_pcm_lib_default_mmap(substream, area); 696 return snd_pcm_lib_default_mmap(substream, area);
496} 697}
497 698
498static struct snd_pcm_ops azx_pcm_ops = { 699static const struct snd_pcm_ops azx_pcm_ops = {
499 .open = azx_pcm_open, 700 .open = azx_pcm_open,
500 .close = azx_pcm_close, 701 .close = azx_pcm_close,
501 .ioctl = snd_pcm_lib_ioctl, 702 .ioctl = snd_pcm_lib_ioctl,
diff --git a/sound/pci/hda/hda_controller.h b/sound/pci/hda/hda_controller.h
index ec63bbf1ec6d..a50e0532622a 100644
--- a/sound/pci/hda/hda_controller.h
+++ b/sound/pci/hda/hda_controller.h
@@ -159,6 +159,9 @@ struct azx {
159 unsigned int region_requested:1; 159 unsigned int region_requested:1;
160 unsigned int disabled:1; /* disabled by vga_switcheroo */ 160 unsigned int disabled:1; /* disabled by vga_switcheroo */
161 161
162 /* GTS present */
163 unsigned int gts_present:1;
164
162#ifdef CONFIG_SND_HDA_DSP_LOADER 165#ifdef CONFIG_SND_HDA_DSP_LOADER
163 struct azx_dev saved_azx_dev; 166 struct azx_dev saved_azx_dev;
164#endif 167#endif
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c
index 160c7f713722..c3469f756ec2 100644
--- a/sound/pci/hda/hda_intel.c
+++ b/sound/pci/hda/hda_intel.c
@@ -54,6 +54,7 @@
54/* for snoop control */ 54/* for snoop control */
55#include <asm/pgtable.h> 55#include <asm/pgtable.h>
56#include <asm/cacheflush.h> 56#include <asm/cacheflush.h>
57#include <asm/cpufeature.h>
57#endif 58#endif
58#include <sound/core.h> 59#include <sound/core.h>
59#include <sound/initval.h> 60#include <sound/initval.h>
@@ -1663,6 +1664,22 @@ static int azx_first_init(struct azx *chip)
1663 return -ENXIO; 1664 return -ENXIO;
1664 } 1665 }
1665 1666
1667 if (IS_SKL_PLUS(pci))
1668 snd_hdac_bus_parse_capabilities(bus);
1669
1670 /*
1671 * Some Intel CPUs has always running timer (ART) feature and
1672 * controller may have Global time sync reporting capability, so
1673 * check both of these before declaring synchronized time reporting
1674 * capability SNDRV_PCM_INFO_HAS_LINK_SYNCHRONIZED_ATIME
1675 */
1676 chip->gts_present = false;
1677
1678#ifdef CONFIG_X86
1679 if (bus->ppcap && boot_cpu_has(X86_FEATURE_ART))
1680 chip->gts_present = true;
1681#endif
1682
1666 if (chip->msi) { 1683 if (chip->msi) {
1667 if (chip->driver_caps & AZX_DCAPS_NO_MSI64) { 1684 if (chip->driver_caps & AZX_DCAPS_NO_MSI64) {
1668 dev_dbg(card->dev, "Disabling 64bit MSI\n"); 1685 dev_dbg(card->dev, "Disabling 64bit MSI\n");
diff --git a/sound/pci/hda/patch_ca0132.c b/sound/pci/hda/patch_ca0132.c
index 9ceb2bc36e68..ad06866d7c69 100644
--- a/sound/pci/hda/patch_ca0132.c
+++ b/sound/pci/hda/patch_ca0132.c
@@ -4018,7 +4018,7 @@ static int ca0132_build_controls(struct hda_codec *codec)
4018/* 4018/*
4019 * PCM 4019 * PCM
4020 */ 4020 */
4021static struct hda_pcm_stream ca0132_pcm_analog_playback = { 4021static const struct hda_pcm_stream ca0132_pcm_analog_playback = {
4022 .substreams = 1, 4022 .substreams = 1,
4023 .channels_min = 2, 4023 .channels_min = 2,
4024 .channels_max = 6, 4024 .channels_max = 6,
@@ -4029,7 +4029,7 @@ static struct hda_pcm_stream ca0132_pcm_analog_playback = {
4029 }, 4029 },
4030}; 4030};
4031 4031
4032static struct hda_pcm_stream ca0132_pcm_analog_capture = { 4032static const struct hda_pcm_stream ca0132_pcm_analog_capture = {
4033 .substreams = 1, 4033 .substreams = 1,
4034 .channels_min = 2, 4034 .channels_min = 2,
4035 .channels_max = 2, 4035 .channels_max = 2,
@@ -4040,7 +4040,7 @@ static struct hda_pcm_stream ca0132_pcm_analog_capture = {
4040 }, 4040 },
4041}; 4041};
4042 4042
4043static struct hda_pcm_stream ca0132_pcm_digital_playback = { 4043static const struct hda_pcm_stream ca0132_pcm_digital_playback = {
4044 .substreams = 1, 4044 .substreams = 1,
4045 .channels_min = 2, 4045 .channels_min = 2,
4046 .channels_max = 2, 4046 .channels_max = 2,
@@ -4052,7 +4052,7 @@ static struct hda_pcm_stream ca0132_pcm_digital_playback = {
4052 }, 4052 },
4053}; 4053};
4054 4054
4055static struct hda_pcm_stream ca0132_pcm_digital_capture = { 4055static const struct hda_pcm_stream ca0132_pcm_digital_capture = {
4056 .substreams = 1, 4056 .substreams = 1,
4057 .channels_min = 2, 4057 .channels_min = 2,
4058 .channels_max = 2, 4058 .channels_max = 2,
@@ -4614,7 +4614,7 @@ static void ca0132_free(struct hda_codec *codec)
4614 kfree(codec->spec); 4614 kfree(codec->spec);
4615} 4615}
4616 4616
4617static struct hda_codec_ops ca0132_patch_ops = { 4617static const struct hda_codec_ops ca0132_patch_ops = {
4618 .build_controls = ca0132_build_controls, 4618 .build_controls = ca0132_build_controls,
4619 .build_pcms = ca0132_build_pcms, 4619 .build_pcms = ca0132_build_pcms,
4620 .init = ca0132_init, 4620 .init = ca0132_init,
diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c
index 56fefbd85782..ed62748a6d55 100644
--- a/sound/pci/hda/patch_conexant.c
+++ b/sound/pci/hda/patch_conexant.c
@@ -261,6 +261,7 @@ enum {
261 CXT_FIXUP_HP_530, 261 CXT_FIXUP_HP_530,
262 CXT_FIXUP_CAP_MIX_AMP_5047, 262 CXT_FIXUP_CAP_MIX_AMP_5047,
263 CXT_FIXUP_MUTE_LED_EAPD, 263 CXT_FIXUP_MUTE_LED_EAPD,
264 CXT_FIXUP_HP_SPECTRE,
264}; 265};
265 266
266/* for hda_fixup_thinkpad_acpi() */ 267/* for hda_fixup_thinkpad_acpi() */
@@ -765,6 +766,14 @@ static const struct hda_fixup cxt_fixups[] = {
765 .type = HDA_FIXUP_FUNC, 766 .type = HDA_FIXUP_FUNC,
766 .v.func = cxt_fixup_mute_led_eapd, 767 .v.func = cxt_fixup_mute_led_eapd,
767 }, 768 },
769 [CXT_FIXUP_HP_SPECTRE] = {
770 .type = HDA_FIXUP_PINS,
771 .v.pins = (const struct hda_pintbl[]) {
772 /* enable NID 0x1d for the speaker on top */
773 { 0x1d, 0x91170111 },
774 { }
775 }
776 },
768}; 777};
769 778
770static const struct snd_pci_quirk cxt5045_fixups[] = { 779static const struct snd_pci_quirk cxt5045_fixups[] = {
@@ -814,6 +823,7 @@ static const struct snd_pci_quirk cxt5066_fixups[] = {
814 SND_PCI_QUIRK(0x1025, 0x0543, "Acer Aspire One 522", CXT_FIXUP_STEREO_DMIC), 823 SND_PCI_QUIRK(0x1025, 0x0543, "Acer Aspire One 522", CXT_FIXUP_STEREO_DMIC),
815 SND_PCI_QUIRK(0x1025, 0x054c, "Acer Aspire 3830TG", CXT_FIXUP_ASPIRE_DMIC), 824 SND_PCI_QUIRK(0x1025, 0x054c, "Acer Aspire 3830TG", CXT_FIXUP_ASPIRE_DMIC),
816 SND_PCI_QUIRK(0x1025, 0x054f, "Acer Aspire 4830T", CXT_FIXUP_ASPIRE_DMIC), 825 SND_PCI_QUIRK(0x1025, 0x054f, "Acer Aspire 4830T", CXT_FIXUP_ASPIRE_DMIC),
826 SND_PCI_QUIRK(0x103c, 0x8174, "HP Spectre x360", CXT_FIXUP_HP_SPECTRE),
817 SND_PCI_QUIRK(0x1043, 0x138d, "Asus", CXT_FIXUP_HEADPHONE_MIC_PIN), 827 SND_PCI_QUIRK(0x1043, 0x138d, "Asus", CXT_FIXUP_HEADPHONE_MIC_PIN),
818 SND_PCI_QUIRK(0x152d, 0x0833, "OLPC XO-1.5", CXT_FIXUP_OLPC_XO), 828 SND_PCI_QUIRK(0x152d, 0x0833, "OLPC XO-1.5", CXT_FIXUP_OLPC_XO),
819 SND_PCI_QUIRK(0x17aa, 0x20f2, "Lenovo T400", CXT_PINCFG_LENOVO_TP410), 829 SND_PCI_QUIRK(0x17aa, 0x20f2, "Lenovo T400", CXT_PINCFG_LENOVO_TP410),
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index 575cefd8cc4a..b58e8c76346a 100644
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -5264,6 +5264,8 @@ static const struct hda_fixup alc269_fixups[] = {
5264 [ALC269_FIXUP_THINKPAD_ACPI] = { 5264 [ALC269_FIXUP_THINKPAD_ACPI] = {
5265 .type = HDA_FIXUP_FUNC, 5265 .type = HDA_FIXUP_FUNC,
5266 .v.func = hda_fixup_thinkpad_acpi, 5266 .v.func = hda_fixup_thinkpad_acpi,
5267 .chained = true,
5268 .chain_id = ALC269_FIXUP_SKU_IGNORE,
5267 }, 5269 },
5268 [ALC269_FIXUP_DMIC_THINKPAD_ACPI] = { 5270 [ALC269_FIXUP_DMIC_THINKPAD_ACPI] = {
5269 .type = HDA_FIXUP_FUNC, 5271 .type = HDA_FIXUP_FUNC,
@@ -5806,6 +5808,13 @@ static const struct hda_model_fixup alc269_fixup_models[] = {
5806 {0x14, 0x90170110}, \ 5808 {0x14, 0x90170110}, \
5807 {0x15, 0x0221401f} 5809 {0x15, 0x0221401f}
5808 5810
5811#define ALC295_STANDARD_PINS \
5812 {0x12, 0xb7a60130}, \
5813 {0x14, 0x90170110}, \
5814 {0x17, 0x21014020}, \
5815 {0x18, 0x21a19030}, \
5816 {0x21, 0x04211020}
5817
5809#define ALC298_STANDARD_PINS \ 5818#define ALC298_STANDARD_PINS \
5810 {0x12, 0x90a60130}, \ 5819 {0x12, 0x90a60130}, \
5811 {0x21, 0x03211020} 5820 {0x21, 0x03211020}
@@ -5846,6 +5855,10 @@ static const struct snd_hda_pin_quirk alc269_pin_fixup_tbl[] = {
5846 {0x14, 0x90170120}, 5855 {0x14, 0x90170120},
5847 {0x21, 0x02211030}), 5856 {0x21, 0x02211030}),
5848 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE, 5857 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
5858 {0x14, 0x90170110},
5859 {0x1b, 0x02011020},
5860 {0x21, 0x0221101f}),
5861 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
5849 {0x14, 0x90170130}, 5862 {0x14, 0x90170130},
5850 {0x1b, 0x01014020}, 5863 {0x1b, 0x01014020},
5851 {0x21, 0x0221103f}), 5864 {0x21, 0x0221103f}),
@@ -5911,6 +5924,10 @@ static const struct snd_hda_pin_quirk alc269_pin_fixup_tbl[] = {
5911 {0x14, 0x90170120}, 5924 {0x14, 0x90170120},
5912 {0x21, 0x02211030}), 5925 {0x21, 0x02211030}),
5913 SND_HDA_PIN_QUIRK(0x10ec0256, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE, 5926 SND_HDA_PIN_QUIRK(0x10ec0256, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
5927 {0x12, 0xb7a60130},
5928 {0x14, 0x90170110},
5929 {0x21, 0x02211020}),
5930 SND_HDA_PIN_QUIRK(0x10ec0256, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
5914 ALC256_STANDARD_PINS), 5931 ALC256_STANDARD_PINS),
5915 SND_HDA_PIN_QUIRK(0x10ec0280, 0x103c, "HP", ALC280_FIXUP_HP_GPIO4, 5932 SND_HDA_PIN_QUIRK(0x10ec0280, 0x103c, "HP", ALC280_FIXUP_HP_GPIO4,
5916 {0x12, 0x90a60130}, 5933 {0x12, 0x90a60130},
@@ -6021,6 +6038,8 @@ static const struct snd_hda_pin_quirk alc269_pin_fixup_tbl[] = {
6021 SND_HDA_PIN_QUIRK(0x10ec0293, 0x1028, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE, 6038 SND_HDA_PIN_QUIRK(0x10ec0293, 0x1028, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE,
6022 ALC292_STANDARD_PINS, 6039 ALC292_STANDARD_PINS,
6023 {0x13, 0x90a60140}), 6040 {0x13, 0x90a60140}),
6041 SND_HDA_PIN_QUIRK(0x10ec0295, 0x1028, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE,
6042 ALC295_STANDARD_PINS),
6024 SND_HDA_PIN_QUIRK(0x10ec0298, 0x1028, "Dell", ALC298_FIXUP_DELL1_MIC_NO_PRESENCE, 6043 SND_HDA_PIN_QUIRK(0x10ec0298, 0x1028, "Dell", ALC298_FIXUP_DELL1_MIC_NO_PRESENCE,
6025 ALC298_STANDARD_PINS, 6044 ALC298_STANDARD_PINS,
6026 {0x17, 0x90170110}), 6045 {0x17, 0x90170110}),
diff --git a/sound/pci/ice1712/ice1712.c b/sound/pci/ice1712/ice1712.c
index 8ae3bb7975d1..b4aa4c1370a8 100644
--- a/sound/pci/ice1712/ice1712.c
+++ b/sound/pci/ice1712/ice1712.c
@@ -847,7 +847,7 @@ static int snd_ice1712_capture_close(struct snd_pcm_substream *substream)
847 return 0; 847 return 0;
848} 848}
849 849
850static struct snd_pcm_ops snd_ice1712_playback_ops = { 850static const struct snd_pcm_ops snd_ice1712_playback_ops = {
851 .open = snd_ice1712_playback_open, 851 .open = snd_ice1712_playback_open,
852 .close = snd_ice1712_playback_close, 852 .close = snd_ice1712_playback_close,
853 .ioctl = snd_pcm_lib_ioctl, 853 .ioctl = snd_pcm_lib_ioctl,
@@ -858,7 +858,7 @@ static struct snd_pcm_ops snd_ice1712_playback_ops = {
858 .pointer = snd_ice1712_playback_pointer, 858 .pointer = snd_ice1712_playback_pointer,
859}; 859};
860 860
861static struct snd_pcm_ops snd_ice1712_playback_ds_ops = { 861static const struct snd_pcm_ops snd_ice1712_playback_ds_ops = {
862 .open = snd_ice1712_playback_ds_open, 862 .open = snd_ice1712_playback_ds_open,
863 .close = snd_ice1712_playback_ds_close, 863 .close = snd_ice1712_playback_ds_close,
864 .ioctl = snd_pcm_lib_ioctl, 864 .ioctl = snd_pcm_lib_ioctl,
@@ -869,7 +869,7 @@ static struct snd_pcm_ops snd_ice1712_playback_ds_ops = {
869 .pointer = snd_ice1712_playback_ds_pointer, 869 .pointer = snd_ice1712_playback_ds_pointer,
870}; 870};
871 871
872static struct snd_pcm_ops snd_ice1712_capture_ops = { 872static const struct snd_pcm_ops snd_ice1712_capture_ops = {
873 .open = snd_ice1712_capture_open, 873 .open = snd_ice1712_capture_open,
874 .close = snd_ice1712_capture_close, 874 .close = snd_ice1712_capture_close,
875 .ioctl = snd_pcm_lib_ioctl, 875 .ioctl = snd_pcm_lib_ioctl,
@@ -1228,7 +1228,7 @@ static int snd_ice1712_capture_pro_close(struct snd_pcm_substream *substream)
1228 return 0; 1228 return 0;
1229} 1229}
1230 1230
1231static struct snd_pcm_ops snd_ice1712_playback_pro_ops = { 1231static const struct snd_pcm_ops snd_ice1712_playback_pro_ops = {
1232 .open = snd_ice1712_playback_pro_open, 1232 .open = snd_ice1712_playback_pro_open,
1233 .close = snd_ice1712_playback_pro_close, 1233 .close = snd_ice1712_playback_pro_close,
1234 .ioctl = snd_pcm_lib_ioctl, 1234 .ioctl = snd_pcm_lib_ioctl,
@@ -1239,7 +1239,7 @@ static struct snd_pcm_ops snd_ice1712_playback_pro_ops = {
1239 .pointer = snd_ice1712_playback_pro_pointer, 1239 .pointer = snd_ice1712_playback_pro_pointer,
1240}; 1240};
1241 1241
1242static struct snd_pcm_ops snd_ice1712_capture_pro_ops = { 1242static const struct snd_pcm_ops snd_ice1712_capture_pro_ops = {
1243 .open = snd_ice1712_capture_pro_open, 1243 .open = snd_ice1712_capture_pro_open,
1244 .close = snd_ice1712_capture_pro_close, 1244 .close = snd_ice1712_capture_pro_close,
1245 .ioctl = snd_pcm_lib_ioctl, 1245 .ioctl = snd_pcm_lib_ioctl,
diff --git a/sound/pci/ice1712/ice1724.c b/sound/pci/ice1712/ice1724.c
index 0b22c00642bb..e5c52ed9b674 100644
--- a/sound/pci/ice1712/ice1724.c
+++ b/sound/pci/ice1712/ice1724.c
@@ -620,9 +620,7 @@ static const unsigned int stdclock_rate_list[16] = {
620 620
621static unsigned int stdclock_get_rate(struct snd_ice1712 *ice) 621static unsigned int stdclock_get_rate(struct snd_ice1712 *ice)
622{ 622{
623 unsigned int rate; 623 return stdclock_rate_list[inb(ICEMT1724(ice, RATE)) & 15];
624 rate = stdclock_rate_list[inb(ICEMT1724(ice, RATE)) & 15];
625 return rate;
626} 624}
627 625
628static void stdclock_set_rate(struct snd_ice1712 *ice, unsigned int rate) 626static void stdclock_set_rate(struct snd_ice1712 *ice, unsigned int rate)
@@ -1113,7 +1111,7 @@ static int snd_vt1724_capture_pro_close(struct snd_pcm_substream *substream)
1113 return 0; 1111 return 0;
1114} 1112}
1115 1113
1116static struct snd_pcm_ops snd_vt1724_playback_pro_ops = { 1114static const struct snd_pcm_ops snd_vt1724_playback_pro_ops = {
1117 .open = snd_vt1724_playback_pro_open, 1115 .open = snd_vt1724_playback_pro_open,
1118 .close = snd_vt1724_playback_pro_close, 1116 .close = snd_vt1724_playback_pro_close,
1119 .ioctl = snd_pcm_lib_ioctl, 1117 .ioctl = snd_pcm_lib_ioctl,
@@ -1124,7 +1122,7 @@ static struct snd_pcm_ops snd_vt1724_playback_pro_ops = {
1124 .pointer = snd_vt1724_playback_pro_pointer, 1122 .pointer = snd_vt1724_playback_pro_pointer,
1125}; 1123};
1126 1124
1127static struct snd_pcm_ops snd_vt1724_capture_pro_ops = { 1125static const struct snd_pcm_ops snd_vt1724_capture_pro_ops = {
1128 .open = snd_vt1724_capture_pro_open, 1126 .open = snd_vt1724_capture_pro_open,
1129 .close = snd_vt1724_capture_pro_close, 1127 .close = snd_vt1724_capture_pro_close,
1130 .ioctl = snd_pcm_lib_ioctl, 1128 .ioctl = snd_pcm_lib_ioctl,
@@ -1292,7 +1290,7 @@ static int snd_vt1724_capture_spdif_close(struct snd_pcm_substream *substream)
1292 return 0; 1290 return 0;
1293} 1291}
1294 1292
1295static struct snd_pcm_ops snd_vt1724_playback_spdif_ops = { 1293static const struct snd_pcm_ops snd_vt1724_playback_spdif_ops = {
1296 .open = snd_vt1724_playback_spdif_open, 1294 .open = snd_vt1724_playback_spdif_open,
1297 .close = snd_vt1724_playback_spdif_close, 1295 .close = snd_vt1724_playback_spdif_close,
1298 .ioctl = snd_pcm_lib_ioctl, 1296 .ioctl = snd_pcm_lib_ioctl,
@@ -1303,7 +1301,7 @@ static struct snd_pcm_ops snd_vt1724_playback_spdif_ops = {
1303 .pointer = snd_vt1724_pcm_pointer, 1301 .pointer = snd_vt1724_pcm_pointer,
1304}; 1302};
1305 1303
1306static struct snd_pcm_ops snd_vt1724_capture_spdif_ops = { 1304static const struct snd_pcm_ops snd_vt1724_capture_spdif_ops = {
1307 .open = snd_vt1724_capture_spdif_open, 1305 .open = snd_vt1724_capture_spdif_open,
1308 .close = snd_vt1724_capture_spdif_close, 1306 .close = snd_vt1724_capture_spdif_close,
1309 .ioctl = snd_pcm_lib_ioctl, 1307 .ioctl = snd_pcm_lib_ioctl,
@@ -1437,7 +1435,7 @@ static int snd_vt1724_playback_indep_close(struct snd_pcm_substream *substream)
1437 return 0; 1435 return 0;
1438} 1436}
1439 1437
1440static struct snd_pcm_ops snd_vt1724_playback_indep_ops = { 1438static const struct snd_pcm_ops snd_vt1724_playback_indep_ops = {
1441 .open = snd_vt1724_playback_indep_open, 1439 .open = snd_vt1724_playback_indep_open,
1442 .close = snd_vt1724_playback_indep_close, 1440 .close = snd_vt1724_playback_indep_close,
1443 .ioctl = snd_pcm_lib_ioctl, 1441 .ioctl = snd_pcm_lib_ioctl,
diff --git a/sound/pci/korg1212/korg1212.c b/sound/pci/korg1212/korg1212.c
index 9e1ad119a3ce..565f7f55c3ca 100644
--- a/sound/pci/korg1212/korg1212.c
+++ b/sound/pci/korg1212/korg1212.c
@@ -1681,7 +1681,7 @@ static int snd_korg1212_capture_copy(struct snd_pcm_substream *substream,
1681 return snd_korg1212_copy_to(korg1212, dst, pos, count, 0, korg1212->channels * 2); 1681 return snd_korg1212_copy_to(korg1212, dst, pos, count, 0, korg1212->channels * 2);
1682} 1682}
1683 1683
1684static struct snd_pcm_ops snd_korg1212_playback_ops = { 1684static const struct snd_pcm_ops snd_korg1212_playback_ops = {
1685 .open = snd_korg1212_playback_open, 1685 .open = snd_korg1212_playback_open,
1686 .close = snd_korg1212_playback_close, 1686 .close = snd_korg1212_playback_close,
1687 .ioctl = snd_korg1212_ioctl, 1687 .ioctl = snd_korg1212_ioctl,
@@ -1693,7 +1693,7 @@ static struct snd_pcm_ops snd_korg1212_playback_ops = {
1693 .silence = snd_korg1212_playback_silence, 1693 .silence = snd_korg1212_playback_silence,
1694}; 1694};
1695 1695
1696static struct snd_pcm_ops snd_korg1212_capture_ops = { 1696static const struct snd_pcm_ops snd_korg1212_capture_ops = {
1697 .open = snd_korg1212_capture_open, 1697 .open = snd_korg1212_capture_open,
1698 .close = snd_korg1212_capture_close, 1698 .close = snd_korg1212_capture_close,
1699 .ioctl = snd_korg1212_ioctl, 1699 .ioctl = snd_korg1212_ioctl,
diff --git a/sound/pci/lola/lola_pcm.c b/sound/pci/lola/lola_pcm.c
index 3bd6985430e8..1268ba329016 100644
--- a/sound/pci/lola/lola_pcm.c
+++ b/sound/pci/lola/lola_pcm.c
@@ -586,7 +586,7 @@ void lola_pcm_update(struct lola *chip, struct lola_pcm *pcm, unsigned int bits)
586 } 586 }
587} 587}
588 588
589static struct snd_pcm_ops lola_pcm_ops = { 589static const struct snd_pcm_ops lola_pcm_ops = {
590 .open = lola_pcm_open, 590 .open = lola_pcm_open,
591 .close = lola_pcm_close, 591 .close = lola_pcm_close,
592 .ioctl = snd_pcm_lib_ioctl, 592 .ioctl = snd_pcm_lib_ioctl,
diff --git a/sound/pci/lx6464es/lx6464es.c b/sound/pci/lx6464es/lx6464es.c
index 8b8e2e54fba3..c0f0c349c3ec 100644
--- a/sound/pci/lx6464es/lx6464es.c
+++ b/sound/pci/lx6464es/lx6464es.c
@@ -804,7 +804,7 @@ mac_ready:
804 return err; 804 return err;
805} 805}
806 806
807static struct snd_pcm_ops lx_ops_playback = { 807static const struct snd_pcm_ops lx_ops_playback = {
808 .open = lx_pcm_open, 808 .open = lx_pcm_open,
809 .close = lx_pcm_close, 809 .close = lx_pcm_close,
810 .ioctl = snd_pcm_lib_ioctl, 810 .ioctl = snd_pcm_lib_ioctl,
@@ -815,7 +815,7 @@ static struct snd_pcm_ops lx_ops_playback = {
815 .pointer = lx_pcm_stream_pointer, 815 .pointer = lx_pcm_stream_pointer,
816}; 816};
817 817
818static struct snd_pcm_ops lx_ops_capture = { 818static const struct snd_pcm_ops lx_ops_capture = {
819 .open = lx_pcm_open, 819 .open = lx_pcm_open,
820 .close = lx_pcm_close, 820 .close = lx_pcm_close,
821 .ioctl = snd_pcm_lib_ioctl, 821 .ioctl = snd_pcm_lib_ioctl,
diff --git a/sound/pci/maestro3.c b/sound/pci/maestro3.c
index 17ae92613de4..cafea6dc5c01 100644
--- a/sound/pci/maestro3.c
+++ b/sound/pci/maestro3.c
@@ -1834,7 +1834,7 @@ snd_m3_capture_close(struct snd_pcm_substream *subs)
1834 * create pcm instance 1834 * create pcm instance
1835 */ 1835 */
1836 1836
1837static struct snd_pcm_ops snd_m3_playback_ops = { 1837static const struct snd_pcm_ops snd_m3_playback_ops = {
1838 .open = snd_m3_playback_open, 1838 .open = snd_m3_playback_open,
1839 .close = snd_m3_playback_close, 1839 .close = snd_m3_playback_close,
1840 .ioctl = snd_pcm_lib_ioctl, 1840 .ioctl = snd_pcm_lib_ioctl,
@@ -1845,7 +1845,7 @@ static struct snd_pcm_ops snd_m3_playback_ops = {
1845 .pointer = snd_m3_pcm_pointer, 1845 .pointer = snd_m3_pcm_pointer,
1846}; 1846};
1847 1847
1848static struct snd_pcm_ops snd_m3_capture_ops = { 1848static const struct snd_pcm_ops snd_m3_capture_ops = {
1849 .open = snd_m3_capture_open, 1849 .open = snd_m3_capture_open,
1850 .close = snd_m3_capture_close, 1850 .close = snd_m3_capture_close,
1851 .ioctl = snd_pcm_lib_ioctl, 1851 .ioctl = snd_pcm_lib_ioctl,
diff --git a/sound/pci/mixart/mixart.c b/sound/pci/mixart/mixart.c
index 25c0ddd3a53b..80d439944cb5 100644
--- a/sound/pci/mixart/mixart.c
+++ b/sound/pci/mixart/mixart.c
@@ -922,7 +922,7 @@ static snd_pcm_uframes_t snd_mixart_stream_pointer(struct snd_pcm_substream *sub
922 922
923 923
924 924
925static struct snd_pcm_ops snd_mixart_playback_ops = { 925static const struct snd_pcm_ops snd_mixart_playback_ops = {
926 .open = snd_mixart_playback_open, 926 .open = snd_mixart_playback_open,
927 .close = snd_mixart_close, 927 .close = snd_mixart_close,
928 .ioctl = snd_pcm_lib_ioctl, 928 .ioctl = snd_pcm_lib_ioctl,
@@ -933,7 +933,7 @@ static struct snd_pcm_ops snd_mixart_playback_ops = {
933 .pointer = snd_mixart_stream_pointer, 933 .pointer = snd_mixart_stream_pointer,
934}; 934};
935 935
936static struct snd_pcm_ops snd_mixart_capture_ops = { 936static const struct snd_pcm_ops snd_mixart_capture_ops = {
937 .open = snd_mixart_capture_open, 937 .open = snd_mixart_capture_open,
938 .close = snd_mixart_close, 938 .close = snd_mixart_close,
939 .ioctl = snd_pcm_lib_ioctl, 939 .ioctl = snd_pcm_lib_ioctl,
diff --git a/sound/pci/nm256/nm256.c b/sound/pci/nm256/nm256.c
index 4735e27cc773..103fe311e5a9 100644
--- a/sound/pci/nm256/nm256.c
+++ b/sound/pci/nm256/nm256.c
@@ -902,7 +902,7 @@ snd_nm256_capture_close(struct snd_pcm_substream *substream)
902/* 902/*
903 * create a pcm instance 903 * create a pcm instance
904 */ 904 */
905static struct snd_pcm_ops snd_nm256_playback_ops = { 905static const struct snd_pcm_ops snd_nm256_playback_ops = {
906 .open = snd_nm256_playback_open, 906 .open = snd_nm256_playback_open,
907 .close = snd_nm256_playback_close, 907 .close = snd_nm256_playback_close,
908 .ioctl = snd_pcm_lib_ioctl, 908 .ioctl = snd_pcm_lib_ioctl,
@@ -917,7 +917,7 @@ static struct snd_pcm_ops snd_nm256_playback_ops = {
917 .mmap = snd_pcm_lib_mmap_iomem, 917 .mmap = snd_pcm_lib_mmap_iomem,
918}; 918};
919 919
920static struct snd_pcm_ops snd_nm256_capture_ops = { 920static const struct snd_pcm_ops snd_nm256_capture_ops = {
921 .open = snd_nm256_capture_open, 921 .open = snd_nm256_capture_open,
922 .close = snd_nm256_capture_close, 922 .close = snd_nm256_capture_close,
923 .ioctl = snd_pcm_lib_ioctl, 923 .ioctl = snd_pcm_lib_ioctl,
diff --git a/sound/pci/oxygen/oxygen_pcm.c b/sound/pci/oxygen/oxygen_pcm.c
index aa2ebd1d6d12..042a2439fea5 100644
--- a/sound/pci/oxygen/oxygen_pcm.c
+++ b/sound/pci/oxygen/oxygen_pcm.c
@@ -631,7 +631,7 @@ static snd_pcm_uframes_t oxygen_pointer(struct snd_pcm_substream *substream)
631 return bytes_to_frames(runtime, curr_addr - (u32)runtime->dma_addr); 631 return bytes_to_frames(runtime, curr_addr - (u32)runtime->dma_addr);
632} 632}
633 633
634static struct snd_pcm_ops oxygen_rec_a_ops = { 634static const struct snd_pcm_ops oxygen_rec_a_ops = {
635 .open = oxygen_rec_a_open, 635 .open = oxygen_rec_a_open,
636 .close = oxygen_close, 636 .close = oxygen_close,
637 .ioctl = snd_pcm_lib_ioctl, 637 .ioctl = snd_pcm_lib_ioctl,
@@ -642,7 +642,7 @@ static struct snd_pcm_ops oxygen_rec_a_ops = {
642 .pointer = oxygen_pointer, 642 .pointer = oxygen_pointer,
643}; 643};
644 644
645static struct snd_pcm_ops oxygen_rec_b_ops = { 645static const struct snd_pcm_ops oxygen_rec_b_ops = {
646 .open = oxygen_rec_b_open, 646 .open = oxygen_rec_b_open,
647 .close = oxygen_close, 647 .close = oxygen_close,
648 .ioctl = snd_pcm_lib_ioctl, 648 .ioctl = snd_pcm_lib_ioctl,
@@ -653,7 +653,7 @@ static struct snd_pcm_ops oxygen_rec_b_ops = {
653 .pointer = oxygen_pointer, 653 .pointer = oxygen_pointer,
654}; 654};
655 655
656static struct snd_pcm_ops oxygen_rec_c_ops = { 656static const struct snd_pcm_ops oxygen_rec_c_ops = {
657 .open = oxygen_rec_c_open, 657 .open = oxygen_rec_c_open,
658 .close = oxygen_close, 658 .close = oxygen_close,
659 .ioctl = snd_pcm_lib_ioctl, 659 .ioctl = snd_pcm_lib_ioctl,
@@ -664,7 +664,7 @@ static struct snd_pcm_ops oxygen_rec_c_ops = {
664 .pointer = oxygen_pointer, 664 .pointer = oxygen_pointer,
665}; 665};
666 666
667static struct snd_pcm_ops oxygen_spdif_ops = { 667static const struct snd_pcm_ops oxygen_spdif_ops = {
668 .open = oxygen_spdif_open, 668 .open = oxygen_spdif_open,
669 .close = oxygen_close, 669 .close = oxygen_close,
670 .ioctl = snd_pcm_lib_ioctl, 670 .ioctl = snd_pcm_lib_ioctl,
@@ -675,7 +675,7 @@ static struct snd_pcm_ops oxygen_spdif_ops = {
675 .pointer = oxygen_pointer, 675 .pointer = oxygen_pointer,
676}; 676};
677 677
678static struct snd_pcm_ops oxygen_multich_ops = { 678static const struct snd_pcm_ops oxygen_multich_ops = {
679 .open = oxygen_multich_open, 679 .open = oxygen_multich_open,
680 .close = oxygen_close, 680 .close = oxygen_close,
681 .ioctl = snd_pcm_lib_ioctl, 681 .ioctl = snd_pcm_lib_ioctl,
@@ -686,7 +686,7 @@ static struct snd_pcm_ops oxygen_multich_ops = {
686 .pointer = oxygen_pointer, 686 .pointer = oxygen_pointer,
687}; 687};
688 688
689static struct snd_pcm_ops oxygen_ac97_ops = { 689static const struct snd_pcm_ops oxygen_ac97_ops = {
690 .open = oxygen_ac97_open, 690 .open = oxygen_ac97_open,
691 .close = oxygen_close, 691 .close = oxygen_close,
692 .ioctl = snd_pcm_lib_ioctl, 692 .ioctl = snd_pcm_lib_ioctl,
diff --git a/sound/pci/pcxhr/pcxhr.c b/sound/pci/pcxhr/pcxhr.c
index 9293235281dc..bb7eee9d0c2b 100644
--- a/sound/pci/pcxhr/pcxhr.c
+++ b/sound/pci/pcxhr/pcxhr.c
@@ -1146,7 +1146,7 @@ static snd_pcm_uframes_t pcxhr_stream_pointer(struct snd_pcm_substream *subs)
1146} 1146}
1147 1147
1148 1148
1149static struct snd_pcm_ops pcxhr_ops = { 1149static const struct snd_pcm_ops pcxhr_ops = {
1150 .open = pcxhr_open, 1150 .open = pcxhr_open,
1151 .close = pcxhr_close, 1151 .close = pcxhr_close,
1152 .ioctl = snd_pcm_lib_ioctl, 1152 .ioctl = snd_pcm_lib_ioctl,
diff --git a/sound/pci/riptide/riptide.c b/sound/pci/riptide/riptide.c
index 067a91207d8e..ada5f01d479c 100644
--- a/sound/pci/riptide/riptide.c
+++ b/sound/pci/riptide/riptide.c
@@ -644,7 +644,7 @@ static struct lbuspath lbus_play_paths[] = {
644 .mono = lbus_play_mono3, 644 .mono = lbus_play_mono3,
645 }, 645 },
646}; 646};
647static struct lbuspath lbus_rec_path = { 647static const struct lbuspath lbus_rec_path = {
648 .noconv = lbus_rec_noconv1, 648 .noconv = lbus_rec_noconv1,
649 .stereo = lbus_rec_stereo1, 649 .stereo = lbus_rec_stereo1,
650 .mono = lbus_rec_mono1, 650 .mono = lbus_rec_mono1,
@@ -1669,7 +1669,7 @@ static int snd_riptide_capture_close(struct snd_pcm_substream *substream)
1669 return 0; 1669 return 0;
1670} 1670}
1671 1671
1672static struct snd_pcm_ops snd_riptide_playback_ops = { 1672static const struct snd_pcm_ops snd_riptide_playback_ops = {
1673 .open = snd_riptide_playback_open, 1673 .open = snd_riptide_playback_open,
1674 .close = snd_riptide_playback_close, 1674 .close = snd_riptide_playback_close,
1675 .ioctl = snd_pcm_lib_ioctl, 1675 .ioctl = snd_pcm_lib_ioctl,
@@ -1680,7 +1680,7 @@ static struct snd_pcm_ops snd_riptide_playback_ops = {
1680 .trigger = snd_riptide_trigger, 1680 .trigger = snd_riptide_trigger,
1681 .pointer = snd_riptide_pointer, 1681 .pointer = snd_riptide_pointer,
1682}; 1682};
1683static struct snd_pcm_ops snd_riptide_capture_ops = { 1683static const struct snd_pcm_ops snd_riptide_capture_ops = {
1684 .open = snd_riptide_capture_open, 1684 .open = snd_riptide_capture_open,
1685 .close = snd_riptide_capture_close, 1685 .close = snd_riptide_capture_close,
1686 .ioctl = snd_pcm_lib_ioctl, 1686 .ioctl = snd_pcm_lib_ioctl,
diff --git a/sound/pci/rme32.c b/sound/pci/rme32.c
index cd94ac548ba3..96d15db65dfd 100644
--- a/sound/pci/rme32.c
+++ b/sound/pci/rme32.c
@@ -1196,7 +1196,7 @@ snd_rme32_capture_fd_pointer(struct snd_pcm_substream *substream)
1196} 1196}
1197 1197
1198/* for halfduplex mode */ 1198/* for halfduplex mode */
1199static struct snd_pcm_ops snd_rme32_playback_spdif_ops = { 1199static const struct snd_pcm_ops snd_rme32_playback_spdif_ops = {
1200 .open = snd_rme32_playback_spdif_open, 1200 .open = snd_rme32_playback_spdif_open,
1201 .close = snd_rme32_playback_close, 1201 .close = snd_rme32_playback_close,
1202 .ioctl = snd_pcm_lib_ioctl, 1202 .ioctl = snd_pcm_lib_ioctl,
@@ -1210,7 +1210,7 @@ static struct snd_pcm_ops snd_rme32_playback_spdif_ops = {
1210 .mmap = snd_pcm_lib_mmap_iomem, 1210 .mmap = snd_pcm_lib_mmap_iomem,
1211}; 1211};
1212 1212
1213static struct snd_pcm_ops snd_rme32_capture_spdif_ops = { 1213static const struct snd_pcm_ops snd_rme32_capture_spdif_ops = {
1214 .open = snd_rme32_capture_spdif_open, 1214 .open = snd_rme32_capture_spdif_open,
1215 .close = snd_rme32_capture_close, 1215 .close = snd_rme32_capture_close,
1216 .ioctl = snd_pcm_lib_ioctl, 1216 .ioctl = snd_pcm_lib_ioctl,
@@ -1223,7 +1223,7 @@ static struct snd_pcm_ops snd_rme32_capture_spdif_ops = {
1223 .mmap = snd_pcm_lib_mmap_iomem, 1223 .mmap = snd_pcm_lib_mmap_iomem,
1224}; 1224};
1225 1225
1226static struct snd_pcm_ops snd_rme32_playback_adat_ops = { 1226static const struct snd_pcm_ops snd_rme32_playback_adat_ops = {
1227 .open = snd_rme32_playback_adat_open, 1227 .open = snd_rme32_playback_adat_open,
1228 .close = snd_rme32_playback_close, 1228 .close = snd_rme32_playback_close,
1229 .ioctl = snd_pcm_lib_ioctl, 1229 .ioctl = snd_pcm_lib_ioctl,
@@ -1236,7 +1236,7 @@ static struct snd_pcm_ops snd_rme32_playback_adat_ops = {
1236 .mmap = snd_pcm_lib_mmap_iomem, 1236 .mmap = snd_pcm_lib_mmap_iomem,
1237}; 1237};
1238 1238
1239static struct snd_pcm_ops snd_rme32_capture_adat_ops = { 1239static const struct snd_pcm_ops snd_rme32_capture_adat_ops = {
1240 .open = snd_rme32_capture_adat_open, 1240 .open = snd_rme32_capture_adat_open,
1241 .close = snd_rme32_capture_close, 1241 .close = snd_rme32_capture_close,
1242 .ioctl = snd_pcm_lib_ioctl, 1242 .ioctl = snd_pcm_lib_ioctl,
@@ -1249,7 +1249,7 @@ static struct snd_pcm_ops snd_rme32_capture_adat_ops = {
1249}; 1249};
1250 1250
1251/* for fullduplex mode */ 1251/* for fullduplex mode */
1252static struct snd_pcm_ops snd_rme32_playback_spdif_fd_ops = { 1252static const struct snd_pcm_ops snd_rme32_playback_spdif_fd_ops = {
1253 .open = snd_rme32_playback_spdif_open, 1253 .open = snd_rme32_playback_spdif_open,
1254 .close = snd_rme32_playback_close, 1254 .close = snd_rme32_playback_close,
1255 .ioctl = snd_pcm_lib_ioctl, 1255 .ioctl = snd_pcm_lib_ioctl,
@@ -1261,7 +1261,7 @@ static struct snd_pcm_ops snd_rme32_playback_spdif_fd_ops = {
1261 .ack = snd_rme32_playback_fd_ack, 1261 .ack = snd_rme32_playback_fd_ack,
1262}; 1262};
1263 1263
1264static struct snd_pcm_ops snd_rme32_capture_spdif_fd_ops = { 1264static const struct snd_pcm_ops snd_rme32_capture_spdif_fd_ops = {
1265 .open = snd_rme32_capture_spdif_open, 1265 .open = snd_rme32_capture_spdif_open,
1266 .close = snd_rme32_capture_close, 1266 .close = snd_rme32_capture_close,
1267 .ioctl = snd_pcm_lib_ioctl, 1267 .ioctl = snd_pcm_lib_ioctl,
@@ -1273,7 +1273,7 @@ static struct snd_pcm_ops snd_rme32_capture_spdif_fd_ops = {
1273 .ack = snd_rme32_capture_fd_ack, 1273 .ack = snd_rme32_capture_fd_ack,
1274}; 1274};
1275 1275
1276static struct snd_pcm_ops snd_rme32_playback_adat_fd_ops = { 1276static const struct snd_pcm_ops snd_rme32_playback_adat_fd_ops = {
1277 .open = snd_rme32_playback_adat_open, 1277 .open = snd_rme32_playback_adat_open,
1278 .close = snd_rme32_playback_close, 1278 .close = snd_rme32_playback_close,
1279 .ioctl = snd_pcm_lib_ioctl, 1279 .ioctl = snd_pcm_lib_ioctl,
@@ -1284,7 +1284,7 @@ static struct snd_pcm_ops snd_rme32_playback_adat_fd_ops = {
1284 .ack = snd_rme32_playback_fd_ack, 1284 .ack = snd_rme32_playback_fd_ack,
1285}; 1285};
1286 1286
1287static struct snd_pcm_ops snd_rme32_capture_adat_fd_ops = { 1287static const struct snd_pcm_ops snd_rme32_capture_adat_fd_ops = {
1288 .open = snd_rme32_capture_adat_open, 1288 .open = snd_rme32_capture_adat_open,
1289 .close = snd_rme32_capture_close, 1289 .close = snd_rme32_capture_close,
1290 .ioctl = snd_pcm_lib_ioctl, 1290 .ioctl = snd_pcm_lib_ioctl,
diff --git a/sound/pci/rme96.c b/sound/pci/rme96.c
index 41c31db65039..05b9da30990d 100644
--- a/sound/pci/rme96.c
+++ b/sound/pci/rme96.c
@@ -1505,7 +1505,7 @@ snd_rme96_capture_pointer(struct snd_pcm_substream *substream)
1505 return snd_rme96_capture_ptr(rme96); 1505 return snd_rme96_capture_ptr(rme96);
1506} 1506}
1507 1507
1508static struct snd_pcm_ops snd_rme96_playback_spdif_ops = { 1508static const struct snd_pcm_ops snd_rme96_playback_spdif_ops = {
1509 .open = snd_rme96_playback_spdif_open, 1509 .open = snd_rme96_playback_spdif_open,
1510 .close = snd_rme96_playback_close, 1510 .close = snd_rme96_playback_close,
1511 .ioctl = snd_pcm_lib_ioctl, 1511 .ioctl = snd_pcm_lib_ioctl,
@@ -1518,7 +1518,7 @@ static struct snd_pcm_ops snd_rme96_playback_spdif_ops = {
1518 .mmap = snd_pcm_lib_mmap_iomem, 1518 .mmap = snd_pcm_lib_mmap_iomem,
1519}; 1519};
1520 1520
1521static struct snd_pcm_ops snd_rme96_capture_spdif_ops = { 1521static const struct snd_pcm_ops snd_rme96_capture_spdif_ops = {
1522 .open = snd_rme96_capture_spdif_open, 1522 .open = snd_rme96_capture_spdif_open,
1523 .close = snd_rme96_capture_close, 1523 .close = snd_rme96_capture_close,
1524 .ioctl = snd_pcm_lib_ioctl, 1524 .ioctl = snd_pcm_lib_ioctl,
@@ -1530,7 +1530,7 @@ static struct snd_pcm_ops snd_rme96_capture_spdif_ops = {
1530 .mmap = snd_pcm_lib_mmap_iomem, 1530 .mmap = snd_pcm_lib_mmap_iomem,
1531}; 1531};
1532 1532
1533static struct snd_pcm_ops snd_rme96_playback_adat_ops = { 1533static const struct snd_pcm_ops snd_rme96_playback_adat_ops = {
1534 .open = snd_rme96_playback_adat_open, 1534 .open = snd_rme96_playback_adat_open,
1535 .close = snd_rme96_playback_close, 1535 .close = snd_rme96_playback_close,
1536 .ioctl = snd_pcm_lib_ioctl, 1536 .ioctl = snd_pcm_lib_ioctl,
@@ -1543,7 +1543,7 @@ static struct snd_pcm_ops snd_rme96_playback_adat_ops = {
1543 .mmap = snd_pcm_lib_mmap_iomem, 1543 .mmap = snd_pcm_lib_mmap_iomem,
1544}; 1544};
1545 1545
1546static struct snd_pcm_ops snd_rme96_capture_adat_ops = { 1546static const struct snd_pcm_ops snd_rme96_capture_adat_ops = {
1547 .open = snd_rme96_capture_adat_open, 1547 .open = snd_rme96_capture_adat_open,
1548 .close = snd_rme96_capture_close, 1548 .close = snd_rme96_capture_close,
1549 .ioctl = snd_pcm_lib_ioctl, 1549 .ioctl = snd_pcm_lib_ioctl,
diff --git a/sound/pci/rme9652/hdsp.c b/sound/pci/rme9652/hdsp.c
index 7c8941b8b2de..b94fc6357139 100644
--- a/sound/pci/rme9652/hdsp.c
+++ b/sound/pci/rme9652/hdsp.c
@@ -4861,7 +4861,7 @@ static int snd_hdsp_hwdep_ioctl(struct snd_hwdep *hw, struct file *file, unsigne
4861 return 0; 4861 return 0;
4862} 4862}
4863 4863
4864static struct snd_pcm_ops snd_hdsp_playback_ops = { 4864static const struct snd_pcm_ops snd_hdsp_playback_ops = {
4865 .open = snd_hdsp_playback_open, 4865 .open = snd_hdsp_playback_open,
4866 .close = snd_hdsp_playback_release, 4866 .close = snd_hdsp_playback_release,
4867 .ioctl = snd_hdsp_ioctl, 4867 .ioctl = snd_hdsp_ioctl,
@@ -4873,7 +4873,7 @@ static struct snd_pcm_ops snd_hdsp_playback_ops = {
4873 .silence = snd_hdsp_hw_silence, 4873 .silence = snd_hdsp_hw_silence,
4874}; 4874};
4875 4875
4876static struct snd_pcm_ops snd_hdsp_capture_ops = { 4876static const struct snd_pcm_ops snd_hdsp_capture_ops = {
4877 .open = snd_hdsp_capture_open, 4877 .open = snd_hdsp_capture_open,
4878 .close = snd_hdsp_capture_release, 4878 .close = snd_hdsp_capture_release,
4879 .ioctl = snd_hdsp_ioctl, 4879 .ioctl = snd_hdsp_ioctl,
diff --git a/sound/pci/rme9652/hdspm.c b/sound/pci/rme9652/hdspm.c
index a4a999a0317e..14bbf55c1ef9 100644
--- a/sound/pci/rme9652/hdspm.c
+++ b/sound/pci/rme9652/hdspm.c
@@ -1666,7 +1666,7 @@ static int hdspm_set_rate(struct hdspm * hdspm, int rate, int called_internally)
1666 HDSPM_AUTOSYNC_FROM_NONE) { 1666 HDSPM_AUTOSYNC_FROM_NONE) {
1667 1667
1668 dev_warn(hdspm->card->dev, 1668 dev_warn(hdspm->card->dev,
1669 "Detected no Externel Sync\n"); 1669 "Detected no External Sync\n");
1670 not_set = 1; 1670 not_set = 1;
1671 1671
1672 } else if (rate != external_freq) { 1672 } else if (rate != external_freq) {
@@ -6361,7 +6361,7 @@ static int snd_hdspm_hwdep_ioctl(struct snd_hwdep *hw, struct file *file,
6361 return 0; 6361 return 0;
6362} 6362}
6363 6363
6364static struct snd_pcm_ops snd_hdspm_ops = { 6364static const struct snd_pcm_ops snd_hdspm_ops = {
6365 .open = snd_hdspm_open, 6365 .open = snd_hdspm_open,
6366 .close = snd_hdspm_release, 6366 .close = snd_hdspm_release,
6367 .ioctl = snd_hdspm_ioctl, 6367 .ioctl = snd_hdspm_ioctl,
diff --git a/sound/pci/rme9652/rme9652.c b/sound/pci/rme9652/rme9652.c
index fdbc0aa2776a..55172c689991 100644
--- a/sound/pci/rme9652/rme9652.c
+++ b/sound/pci/rme9652/rme9652.c
@@ -2368,7 +2368,7 @@ static int snd_rme9652_capture_release(struct snd_pcm_substream *substream)
2368 return 0; 2368 return 0;
2369} 2369}
2370 2370
2371static struct snd_pcm_ops snd_rme9652_playback_ops = { 2371static const struct snd_pcm_ops snd_rme9652_playback_ops = {
2372 .open = snd_rme9652_playback_open, 2372 .open = snd_rme9652_playback_open,
2373 .close = snd_rme9652_playback_release, 2373 .close = snd_rme9652_playback_release,
2374 .ioctl = snd_rme9652_ioctl, 2374 .ioctl = snd_rme9652_ioctl,
@@ -2380,7 +2380,7 @@ static struct snd_pcm_ops snd_rme9652_playback_ops = {
2380 .silence = snd_rme9652_hw_silence, 2380 .silence = snd_rme9652_hw_silence,
2381}; 2381};
2382 2382
2383static struct snd_pcm_ops snd_rme9652_capture_ops = { 2383static const struct snd_pcm_ops snd_rme9652_capture_ops = {
2384 .open = snd_rme9652_capture_open, 2384 .open = snd_rme9652_capture_open,
2385 .close = snd_rme9652_capture_release, 2385 .close = snd_rme9652_capture_release,
2386 .ioctl = snd_rme9652_ioctl, 2386 .ioctl = snd_rme9652_ioctl,
diff --git a/sound/pci/sonicvibes.c b/sound/pci/sonicvibes.c
index 1b6fad7d4d56..e1a13870bb80 100644
--- a/sound/pci/sonicvibes.c
+++ b/sound/pci/sonicvibes.c
@@ -857,7 +857,7 @@ static int snd_sonicvibes_capture_close(struct snd_pcm_substream *substream)
857 return 0; 857 return 0;
858} 858}
859 859
860static struct snd_pcm_ops snd_sonicvibes_playback_ops = { 860static const struct snd_pcm_ops snd_sonicvibes_playback_ops = {
861 .open = snd_sonicvibes_playback_open, 861 .open = snd_sonicvibes_playback_open,
862 .close = snd_sonicvibes_playback_close, 862 .close = snd_sonicvibes_playback_close,
863 .ioctl = snd_pcm_lib_ioctl, 863 .ioctl = snd_pcm_lib_ioctl,
@@ -868,7 +868,7 @@ static struct snd_pcm_ops snd_sonicvibes_playback_ops = {
868 .pointer = snd_sonicvibes_playback_pointer, 868 .pointer = snd_sonicvibes_playback_pointer,
869}; 869};
870 870
871static struct snd_pcm_ops snd_sonicvibes_capture_ops = { 871static const struct snd_pcm_ops snd_sonicvibes_capture_ops = {
872 .open = snd_sonicvibes_capture_open, 872 .open = snd_sonicvibes_capture_open,
873 .close = snd_sonicvibes_capture_close, 873 .close = snd_sonicvibes_capture_close,
874 .ioctl = snd_pcm_lib_ioctl, 874 .ioctl = snd_pcm_lib_ioctl,
diff --git a/sound/pci/trident/trident_main.c b/sound/pci/trident/trident_main.c
index 599d2b7eb5b8..27f0ed840979 100644
--- a/sound/pci/trident/trident_main.c
+++ b/sound/pci/trident/trident_main.c
@@ -2070,7 +2070,7 @@ static int snd_trident_foldback_close(struct snd_pcm_substream *substream)
2070 PCM operations 2070 PCM operations
2071 ---------------------------------------------------------------------------*/ 2071 ---------------------------------------------------------------------------*/
2072 2072
2073static struct snd_pcm_ops snd_trident_playback_ops = { 2073static const struct snd_pcm_ops snd_trident_playback_ops = {
2074 .open = snd_trident_playback_open, 2074 .open = snd_trident_playback_open,
2075 .close = snd_trident_playback_close, 2075 .close = snd_trident_playback_close,
2076 .ioctl = snd_trident_ioctl, 2076 .ioctl = snd_trident_ioctl,
@@ -2081,7 +2081,7 @@ static struct snd_pcm_ops snd_trident_playback_ops = {
2081 .pointer = snd_trident_playback_pointer, 2081 .pointer = snd_trident_playback_pointer,
2082}; 2082};
2083 2083
2084static struct snd_pcm_ops snd_trident_nx_playback_ops = { 2084static const struct snd_pcm_ops snd_trident_nx_playback_ops = {
2085 .open = snd_trident_playback_open, 2085 .open = snd_trident_playback_open,
2086 .close = snd_trident_playback_close, 2086 .close = snd_trident_playback_close,
2087 .ioctl = snd_trident_ioctl, 2087 .ioctl = snd_trident_ioctl,
@@ -2115,7 +2115,7 @@ static struct snd_pcm_ops snd_trident_si7018_capture_ops = {
2115 .pointer = snd_trident_playback_pointer, 2115 .pointer = snd_trident_playback_pointer,
2116}; 2116};
2117 2117
2118static struct snd_pcm_ops snd_trident_foldback_ops = { 2118static const struct snd_pcm_ops snd_trident_foldback_ops = {
2119 .open = snd_trident_foldback_open, 2119 .open = snd_trident_foldback_open,
2120 .close = snd_trident_foldback_close, 2120 .close = snd_trident_foldback_close,
2121 .ioctl = snd_trident_ioctl, 2121 .ioctl = snd_trident_ioctl,
@@ -2126,7 +2126,7 @@ static struct snd_pcm_ops snd_trident_foldback_ops = {
2126 .pointer = snd_trident_playback_pointer, 2126 .pointer = snd_trident_playback_pointer,
2127}; 2127};
2128 2128
2129static struct snd_pcm_ops snd_trident_nx_foldback_ops = { 2129static const struct snd_pcm_ops snd_trident_nx_foldback_ops = {
2130 .open = snd_trident_foldback_open, 2130 .open = snd_trident_foldback_open,
2131 .close = snd_trident_foldback_close, 2131 .close = snd_trident_foldback_close,
2132 .ioctl = snd_trident_ioctl, 2132 .ioctl = snd_trident_ioctl,
@@ -2138,7 +2138,7 @@ static struct snd_pcm_ops snd_trident_nx_foldback_ops = {
2138 .page = snd_pcm_sgbuf_ops_page, 2138 .page = snd_pcm_sgbuf_ops_page,
2139}; 2139};
2140 2140
2141static struct snd_pcm_ops snd_trident_spdif_ops = { 2141static const struct snd_pcm_ops snd_trident_spdif_ops = {
2142 .open = snd_trident_spdif_open, 2142 .open = snd_trident_spdif_open,
2143 .close = snd_trident_spdif_close, 2143 .close = snd_trident_spdif_close,
2144 .ioctl = snd_trident_ioctl, 2144 .ioctl = snd_trident_ioctl,
@@ -2149,7 +2149,7 @@ static struct snd_pcm_ops snd_trident_spdif_ops = {
2149 .pointer = snd_trident_spdif_pointer, 2149 .pointer = snd_trident_spdif_pointer,
2150}; 2150};
2151 2151
2152static struct snd_pcm_ops snd_trident_spdif_7018_ops = { 2152static const struct snd_pcm_ops snd_trident_spdif_7018_ops = {
2153 .open = snd_trident_spdif_open, 2153 .open = snd_trident_spdif_open,
2154 .close = snd_trident_spdif_close, 2154 .close = snd_trident_spdif_close,
2155 .ioctl = snd_trident_ioctl, 2155 .ioctl = snd_trident_ioctl,
diff --git a/sound/pci/via82xx.c b/sound/pci/via82xx.c
index 3dd038bdb204..38a17b4342a6 100644
--- a/sound/pci/via82xx.c
+++ b/sound/pci/via82xx.c
@@ -1366,7 +1366,7 @@ static int snd_via8233_playback_close(struct snd_pcm_substream *substream)
1366 1366
1367 1367
1368/* via686 playback callbacks */ 1368/* via686 playback callbacks */
1369static struct snd_pcm_ops snd_via686_playback_ops = { 1369static const struct snd_pcm_ops snd_via686_playback_ops = {
1370 .open = snd_via686_playback_open, 1370 .open = snd_via686_playback_open,
1371 .close = snd_via82xx_pcm_close, 1371 .close = snd_via82xx_pcm_close,
1372 .ioctl = snd_pcm_lib_ioctl, 1372 .ioctl = snd_pcm_lib_ioctl,
@@ -1379,7 +1379,7 @@ static struct snd_pcm_ops snd_via686_playback_ops = {
1379}; 1379};
1380 1380
1381/* via686 capture callbacks */ 1381/* via686 capture callbacks */
1382static struct snd_pcm_ops snd_via686_capture_ops = { 1382static const struct snd_pcm_ops snd_via686_capture_ops = {
1383 .open = snd_via82xx_capture_open, 1383 .open = snd_via82xx_capture_open,
1384 .close = snd_via82xx_pcm_close, 1384 .close = snd_via82xx_pcm_close,
1385 .ioctl = snd_pcm_lib_ioctl, 1385 .ioctl = snd_pcm_lib_ioctl,
@@ -1392,7 +1392,7 @@ static struct snd_pcm_ops snd_via686_capture_ops = {
1392}; 1392};
1393 1393
1394/* via823x DSX playback callbacks */ 1394/* via823x DSX playback callbacks */
1395static struct snd_pcm_ops snd_via8233_playback_ops = { 1395static const struct snd_pcm_ops snd_via8233_playback_ops = {
1396 .open = snd_via8233_playback_open, 1396 .open = snd_via8233_playback_open,
1397 .close = snd_via8233_playback_close, 1397 .close = snd_via8233_playback_close,
1398 .ioctl = snd_pcm_lib_ioctl, 1398 .ioctl = snd_pcm_lib_ioctl,
@@ -1405,7 +1405,7 @@ static struct snd_pcm_ops snd_via8233_playback_ops = {
1405}; 1405};
1406 1406
1407/* via823x multi-channel playback callbacks */ 1407/* via823x multi-channel playback callbacks */
1408static struct snd_pcm_ops snd_via8233_multi_ops = { 1408static const struct snd_pcm_ops snd_via8233_multi_ops = {
1409 .open = snd_via8233_multi_open, 1409 .open = snd_via8233_multi_open,
1410 .close = snd_via82xx_pcm_close, 1410 .close = snd_via82xx_pcm_close,
1411 .ioctl = snd_pcm_lib_ioctl, 1411 .ioctl = snd_pcm_lib_ioctl,
@@ -1418,7 +1418,7 @@ static struct snd_pcm_ops snd_via8233_multi_ops = {
1418}; 1418};
1419 1419
1420/* via823x capture callbacks */ 1420/* via823x capture callbacks */
1421static struct snd_pcm_ops snd_via8233_capture_ops = { 1421static const struct snd_pcm_ops snd_via8233_capture_ops = {
1422 .open = snd_via82xx_capture_open, 1422 .open = snd_via82xx_capture_open,
1423 .close = snd_via82xx_pcm_close, 1423 .close = snd_via82xx_pcm_close,
1424 .ioctl = snd_pcm_lib_ioctl, 1424 .ioctl = snd_pcm_lib_ioctl,
diff --git a/sound/pci/via82xx_modem.c b/sound/pci/via82xx_modem.c
index 99b9137bc677..2f6d40f10618 100644
--- a/sound/pci/via82xx_modem.c
+++ b/sound/pci/via82xx_modem.c
@@ -804,7 +804,7 @@ static int snd_via82xx_pcm_close(struct snd_pcm_substream *substream)
804 804
805 805
806/* via686 playback callbacks */ 806/* via686 playback callbacks */
807static struct snd_pcm_ops snd_via686_playback_ops = { 807static const struct snd_pcm_ops snd_via686_playback_ops = {
808 .open = snd_via82xx_playback_open, 808 .open = snd_via82xx_playback_open,
809 .close = snd_via82xx_pcm_close, 809 .close = snd_via82xx_pcm_close,
810 .ioctl = snd_pcm_lib_ioctl, 810 .ioctl = snd_pcm_lib_ioctl,
@@ -817,7 +817,7 @@ static struct snd_pcm_ops snd_via686_playback_ops = {
817}; 817};
818 818
819/* via686 capture callbacks */ 819/* via686 capture callbacks */
820static struct snd_pcm_ops snd_via686_capture_ops = { 820static const struct snd_pcm_ops snd_via686_capture_ops = {
821 .open = snd_via82xx_capture_open, 821 .open = snd_via82xx_capture_open,
822 .close = snd_via82xx_pcm_close, 822 .close = snd_via82xx_pcm_close,
823 .ioctl = snd_pcm_lib_ioctl, 823 .ioctl = snd_pcm_lib_ioctl,
diff --git a/sound/pci/ymfpci/ymfpci_main.c b/sound/pci/ymfpci/ymfpci_main.c
index 4c26076dbf78..ffee284898b3 100644
--- a/sound/pci/ymfpci/ymfpci_main.c
+++ b/sound/pci/ymfpci/ymfpci_main.c
@@ -1123,7 +1123,7 @@ static int snd_ymfpci_capture_close(struct snd_pcm_substream *substream)
1123 return 0; 1123 return 0;
1124} 1124}
1125 1125
1126static struct snd_pcm_ops snd_ymfpci_playback_ops = { 1126static const struct snd_pcm_ops snd_ymfpci_playback_ops = {
1127 .open = snd_ymfpci_playback_open, 1127 .open = snd_ymfpci_playback_open,
1128 .close = snd_ymfpci_playback_close, 1128 .close = snd_ymfpci_playback_close,
1129 .ioctl = snd_pcm_lib_ioctl, 1129 .ioctl = snd_pcm_lib_ioctl,
@@ -1134,7 +1134,7 @@ static struct snd_pcm_ops snd_ymfpci_playback_ops = {
1134 .pointer = snd_ymfpci_playback_pointer, 1134 .pointer = snd_ymfpci_playback_pointer,
1135}; 1135};
1136 1136
1137static struct snd_pcm_ops snd_ymfpci_capture_rec_ops = { 1137static const struct snd_pcm_ops snd_ymfpci_capture_rec_ops = {
1138 .open = snd_ymfpci_capture_rec_open, 1138 .open = snd_ymfpci_capture_rec_open,
1139 .close = snd_ymfpci_capture_close, 1139 .close = snd_ymfpci_capture_close,
1140 .ioctl = snd_pcm_lib_ioctl, 1140 .ioctl = snd_pcm_lib_ioctl,
@@ -1169,7 +1169,7 @@ int snd_ymfpci_pcm(struct snd_ymfpci *chip, int device)
1169 snd_pcm_std_chmaps, 2, 0, NULL); 1169 snd_pcm_std_chmaps, 2, 0, NULL);
1170} 1170}
1171 1171
1172static struct snd_pcm_ops snd_ymfpci_capture_ac97_ops = { 1172static const struct snd_pcm_ops snd_ymfpci_capture_ac97_ops = {
1173 .open = snd_ymfpci_capture_ac97_open, 1173 .open = snd_ymfpci_capture_ac97_open,
1174 .close = snd_ymfpci_capture_close, 1174 .close = snd_ymfpci_capture_close,
1175 .ioctl = snd_pcm_lib_ioctl, 1175 .ioctl = snd_pcm_lib_ioctl,
@@ -1203,7 +1203,7 @@ int snd_ymfpci_pcm2(struct snd_ymfpci *chip, int device)
1203 return 0; 1203 return 0;
1204} 1204}
1205 1205
1206static struct snd_pcm_ops snd_ymfpci_playback_spdif_ops = { 1206static const struct snd_pcm_ops snd_ymfpci_playback_spdif_ops = {
1207 .open = snd_ymfpci_playback_spdif_open, 1207 .open = snd_ymfpci_playback_spdif_open,
1208 .close = snd_ymfpci_playback_spdif_close, 1208 .close = snd_ymfpci_playback_spdif_close,
1209 .ioctl = snd_pcm_lib_ioctl, 1209 .ioctl = snd_pcm_lib_ioctl,
@@ -1236,7 +1236,7 @@ int snd_ymfpci_pcm_spdif(struct snd_ymfpci *chip, int device)
1236 return 0; 1236 return 0;
1237} 1237}
1238 1238
1239static struct snd_pcm_ops snd_ymfpci_playback_4ch_ops = { 1239static const struct snd_pcm_ops snd_ymfpci_playback_4ch_ops = {
1240 .open = snd_ymfpci_playback_4ch_open, 1240 .open = snd_ymfpci_playback_4ch_open,
1241 .close = snd_ymfpci_playback_4ch_close, 1241 .close = snd_ymfpci_playback_4ch_close,
1242 .ioctl = snd_pcm_lib_ioctl, 1242 .ioctl = snd_pcm_lib_ioctl,
diff --git a/sound/ppc/snd_ps3.c b/sound/ppc/snd_ps3.c
index 368242519279..b84d7d34f188 100644
--- a/sound/ppc/snd_ps3.c
+++ b/sound/ppc/snd_ps3.c
@@ -564,9 +564,7 @@ static int snd_ps3_pcm_hw_params(struct snd_pcm_substream *substream,
564 564
565static int snd_ps3_pcm_hw_free(struct snd_pcm_substream *substream) 565static int snd_ps3_pcm_hw_free(struct snd_pcm_substream *substream)
566{ 566{
567 int ret; 567 return snd_pcm_lib_free_pages(substream);
568 ret = snd_pcm_lib_free_pages(substream);
569 return ret;
570}; 568};
571 569
572static int snd_ps3_delay_to_bytes(struct snd_pcm_substream *substream, 570static int snd_ps3_delay_to_bytes(struct snd_pcm_substream *substream,
diff --git a/sound/soc/amd/acp-pcm-dma.c b/sound/soc/amd/acp-pcm-dma.c
index d1fb035f44db..504c7cd7f58a 100644
--- a/sound/soc/amd/acp-pcm-dma.c
+++ b/sound/soc/amd/acp-pcm-dma.c
@@ -897,7 +897,7 @@ static int acp_dma_close(struct snd_pcm_substream *substream)
897 return 0; 897 return 0;
898} 898}
899 899
900static struct snd_pcm_ops acp_dma_ops = { 900static const struct snd_pcm_ops acp_dma_ops = {
901 .open = acp_dma_open, 901 .open = acp_dma_open,
902 .close = acp_dma_close, 902 .close = acp_dma_close,
903 .ioctl = snd_pcm_lib_ioctl, 903 .ioctl = snd_pcm_lib_ioctl,
diff --git a/sound/soc/atmel/atmel-classd.c b/sound/soc/atmel/atmel-classd.c
index 6d9b8b44e2da..89ac5f5a93eb 100644
--- a/sound/soc/atmel/atmel-classd.c
+++ b/sound/soc/atmel/atmel-classd.c
@@ -308,9 +308,11 @@ static struct regmap *atmel_classd_codec_get_remap(struct device *dev)
308 308
309static struct snd_soc_codec_driver soc_codec_dev_classd = { 309static struct snd_soc_codec_driver soc_codec_dev_classd = {
310 .probe = atmel_classd_codec_probe, 310 .probe = atmel_classd_codec_probe,
311 .controls = atmel_classd_snd_controls,
312 .num_controls = ARRAY_SIZE(atmel_classd_snd_controls),
313 .get_regmap = atmel_classd_codec_get_remap, 311 .get_regmap = atmel_classd_codec_get_remap,
312 .component_driver = {
313 .controls = atmel_classd_snd_controls,
314 .num_controls = ARRAY_SIZE(atmel_classd_snd_controls),
315 },
314}; 316};
315 317
316/* codec dai component */ 318/* codec dai component */
diff --git a/sound/soc/atmel/atmel-pcm-pdc.c b/sound/soc/atmel/atmel-pcm-pdc.c
index da861b44413f..91b7069c3499 100644
--- a/sound/soc/atmel/atmel-pcm-pdc.c
+++ b/sound/soc/atmel/atmel-pcm-pdc.c
@@ -381,7 +381,7 @@ static int atmel_pcm_close(struct snd_pcm_substream *substream)
381 return 0; 381 return 0;
382} 382}
383 383
384static struct snd_pcm_ops atmel_pcm_ops = { 384static const struct snd_pcm_ops atmel_pcm_ops = {
385 .open = atmel_pcm_open, 385 .open = atmel_pcm_open,
386 .close = atmel_pcm_close, 386 .close = atmel_pcm_close,
387 .ioctl = snd_pcm_lib_ioctl, 387 .ioctl = snd_pcm_lib_ioctl,
diff --git a/sound/soc/atmel/atmel-pdmic.c b/sound/soc/atmel/atmel-pdmic.c
index 5f56da60c92f..c917df7715d1 100644
--- a/sound/soc/atmel/atmel-pdmic.c
+++ b/sound/soc/atmel/atmel-pdmic.c
@@ -80,7 +80,7 @@ static struct atmel_pdmic_pdata *atmel_pdmic_dt_init(struct device *dev)
80 80
81 if (pdata->mic_max_freq < pdata->mic_min_freq) { 81 if (pdata->mic_max_freq < pdata->mic_min_freq) {
82 dev_err(dev, 82 dev_err(dev,
83 "mic-max-freq should not less than mic-min-freq\n"); 83 "mic-max-freq should not be less than mic-min-freq\n");
84 return ERR_PTR(-EINVAL); 84 return ERR_PTR(-EINVAL);
85 } 85 }
86 86
@@ -115,8 +115,10 @@ static int atmel_pdmic_cpu_dai_startup(struct snd_pcm_substream *substream,
115 return ret; 115 return ret;
116 116
117 ret = clk_prepare_enable(dd->pclk); 117 ret = clk_prepare_enable(dd->pclk);
118 if (ret) 118 if (ret) {
119 clk_disable_unprepare(dd->gclk);
119 return ret; 120 return ret;
121 }
120 122
121 /* Clear all bits in the Control Register(PDMIC_CR) */ 123 /* Clear all bits in the Control Register(PDMIC_CR) */
122 regmap_write(dd->regmap, PDMIC_CR, 0); 124 regmap_write(dd->regmap, PDMIC_CR, 0);
@@ -283,7 +285,7 @@ static const DECLARE_TLV_DB_RANGE(mic_gain_tlv,
283 8, ARRAY_SIZE(mic_gain_table)-1, TLV_DB_SCALE_ITEM(-6500, 100, 0), 285 8, ARRAY_SIZE(mic_gain_table)-1, TLV_DB_SCALE_ITEM(-6500, 100, 0),
284); 286);
285 287
286int pdmic_get_mic_volsw(struct snd_kcontrol *kcontrol, 288static int pdmic_get_mic_volsw(struct snd_kcontrol *kcontrol,
287 struct snd_ctl_elem_value *ucontrol) 289 struct snd_ctl_elem_value *ucontrol)
288{ 290{
289 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); 291 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
@@ -357,8 +359,10 @@ static int atmel_pdmic_codec_probe(struct snd_soc_codec *codec)
357 359
358static struct snd_soc_codec_driver soc_codec_dev_pdmic = { 360static struct snd_soc_codec_driver soc_codec_dev_pdmic = {
359 .probe = atmel_pdmic_codec_probe, 361 .probe = atmel_pdmic_codec_probe,
360 .controls = atmel_pdmic_snd_controls, 362 .component_driver = {
361 .num_controls = ARRAY_SIZE(atmel_pdmic_snd_controls), 363 .controls = atmel_pdmic_snd_controls,
364 .num_controls = ARRAY_SIZE(atmel_pdmic_snd_controls),
365 },
362}; 366};
363 367
364/* codec dai component */ 368/* codec dai component */
@@ -596,7 +600,7 @@ static int atmel_pdmic_probe(struct platform_device *pdev)
596 dd->irq = platform_get_irq(pdev, 0); 600 dd->irq = platform_get_irq(pdev, 0);
597 if (dd->irq < 0) { 601 if (dd->irq < 0) {
598 ret = dd->irq; 602 ret = dd->irq;
599 dev_err(dev, "failed to could not get irq: %d\n", ret); 603 dev_err(dev, "failed to get irq: %d\n", ret);
600 return ret; 604 return ret;
601 } 605 }
602 606
@@ -614,7 +618,7 @@ static int atmel_pdmic_probe(struct platform_device *pdev)
614 return ret; 618 return ret;
615 } 619 }
616 620
617 /* The gclk clock frequency must always be tree times 621 /* The gclk clock frequency must always be three times
618 * lower than the pclk clock frequency 622 * lower than the pclk clock frequency
619 */ 623 */
620 ret = clk_set_rate(dd->gclk, clk_get_rate(dd->pclk)/3); 624 ret = clk_set_rate(dd->gclk, clk_get_rate(dd->pclk)/3);
@@ -649,7 +653,7 @@ static int atmel_pdmic_probe(struct platform_device *pdev)
649 return ret; 653 return ret;
650 } 654 }
651 655
652 /* Get the minimal and maximal sample rate that micphone supports */ 656 /* Get the minimal and maximal sample rate that the microphone supports */
653 atmel_pdmic_get_sample_rate(dd, &rate_min, &rate_max); 657 atmel_pdmic_get_sample_rate(dd, &rate_min, &rate_max);
654 658
655 /* register cpu dai */ 659 /* register cpu dai */
diff --git a/sound/soc/codecs/88pm860x-codec.c b/sound/soc/codecs/88pm860x-codec.c
index e8bed6b0c9db..b013a4c62b63 100644
--- a/sound/soc/codecs/88pm860x-codec.c
+++ b/sound/soc/codecs/88pm860x-codec.c
@@ -1361,12 +1361,14 @@ static struct snd_soc_codec_driver soc_codec_dev_pm860x = {
1361 .set_bias_level = pm860x_set_bias_level, 1361 .set_bias_level = pm860x_set_bias_level,
1362 .get_regmap = pm860x_get_regmap, 1362 .get_regmap = pm860x_get_regmap,
1363 1363
1364 .controls = pm860x_snd_controls, 1364 .component_driver = {
1365 .num_controls = ARRAY_SIZE(pm860x_snd_controls), 1365 .controls = pm860x_snd_controls,
1366 .dapm_widgets = pm860x_dapm_widgets, 1366 .num_controls = ARRAY_SIZE(pm860x_snd_controls),
1367 .num_dapm_widgets = ARRAY_SIZE(pm860x_dapm_widgets), 1367 .dapm_widgets = pm860x_dapm_widgets,
1368 .dapm_routes = pm860x_dapm_routes, 1368 .num_dapm_widgets = ARRAY_SIZE(pm860x_dapm_widgets),
1369 .num_dapm_routes = ARRAY_SIZE(pm860x_dapm_routes), 1369 .dapm_routes = pm860x_dapm_routes,
1370 .num_dapm_routes = ARRAY_SIZE(pm860x_dapm_routes),
1371 },
1370}; 1372};
1371 1373
1372static int pm860x_codec_probe(struct platform_device *pdev) 1374static int pm860x_codec_probe(struct platform_device *pdev)
diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig
index 1cd6ab344d67..c67667bb970f 100644
--- a/sound/soc/codecs/Kconfig
+++ b/sound/soc/codecs/Kconfig
@@ -92,6 +92,7 @@ config SND_SOC_ALL_CODECS
92 select SND_SOC_MAX9877 if I2C 92 select SND_SOC_MAX9877 if I2C
93 select SND_SOC_MC13783 if MFD_MC13XXX 93 select SND_SOC_MC13783 if MFD_MC13XXX
94 select SND_SOC_ML26124 if I2C 94 select SND_SOC_ML26124 if I2C
95 select SND_SOC_NAU8810 if I2C
95 select SND_SOC_NAU8825 if I2C 96 select SND_SOC_NAU8825 if I2C
96 select SND_SOC_HDMI_CODEC 97 select SND_SOC_HDMI_CODEC
97 select SND_SOC_PCM1681 if I2C 98 select SND_SOC_PCM1681 if I2C
@@ -112,6 +113,8 @@ config SND_SOC_ALL_CODECS
112 select SND_SOC_RT5645 if I2C 113 select SND_SOC_RT5645 if I2C
113 select SND_SOC_RT5651 if I2C 114 select SND_SOC_RT5651 if I2C
114 select SND_SOC_RT5659 if I2C 115 select SND_SOC_RT5659 if I2C
116 select SND_SOC_RT5660 if I2C
117 select SND_SOC_RT5663 if I2C
115 select SND_SOC_RT5670 if I2C 118 select SND_SOC_RT5670 if I2C
116 select SND_SOC_RT5677 if I2C && SPI_MASTER 119 select SND_SOC_RT5677 if I2C && SPI_MASTER
117 select SND_SOC_SGTL5000 if I2C 120 select SND_SOC_SGTL5000 if I2C
@@ -645,6 +648,8 @@ config SND_SOC_RL6231
645 default y if SND_SOC_RT5645=y 648 default y if SND_SOC_RT5645=y
646 default y if SND_SOC_RT5651=y 649 default y if SND_SOC_RT5651=y
647 default y if SND_SOC_RT5659=y 650 default y if SND_SOC_RT5659=y
651 default y if SND_SOC_RT5660=y
652 default y if SND_SOC_RT5663=y
648 default y if SND_SOC_RT5670=y 653 default y if SND_SOC_RT5670=y
649 default y if SND_SOC_RT5677=y 654 default y if SND_SOC_RT5677=y
650 default m if SND_SOC_RT5514=m 655 default m if SND_SOC_RT5514=m
@@ -653,6 +658,8 @@ config SND_SOC_RL6231
653 default m if SND_SOC_RT5645=m 658 default m if SND_SOC_RT5645=m
654 default m if SND_SOC_RT5651=m 659 default m if SND_SOC_RT5651=m
655 default m if SND_SOC_RT5659=m 660 default m if SND_SOC_RT5659=m
661 default m if SND_SOC_RT5660=m
662 default m if SND_SOC_RT5663=m
656 default m if SND_SOC_RT5670=m 663 default m if SND_SOC_RT5670=m
657 default m if SND_SOC_RT5677=m 664 default m if SND_SOC_RT5677=m
658 665
@@ -665,6 +672,7 @@ config SND_SOC_RL6347A
665 672
666config SND_SOC_RT286 673config SND_SOC_RT286
667 tristate 674 tristate
675 select SND_SOC_RT5663
668 depends on I2C 676 depends on I2C
669 677
670config SND_SOC_RT298 678config SND_SOC_RT298
@@ -697,6 +705,12 @@ config SND_SOC_RT5651
697config SND_SOC_RT5659 705config SND_SOC_RT5659
698 tristate 706 tristate
699 707
708config SND_SOC_RT5660
709 tristate
710
711config SND_SOC_RT5663
712 tristate
713
700config SND_SOC_RT5670 714config SND_SOC_RT5670
701 tristate 715 tristate
702 716
@@ -1064,6 +1078,10 @@ config SND_SOC_MC13783
1064config SND_SOC_ML26124 1078config SND_SOC_ML26124
1065 tristate 1079 tristate
1066 1080
1081config SND_SOC_NAU8810
1082 tristate "Nuvoton Technology Corporation NAU88C10 CODEC"
1083 depends on I2C
1084
1067config SND_SOC_NAU8825 1085config SND_SOC_NAU8825
1068 tristate 1086 tristate
1069 1087
diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile
index 58036af2c7d9..958cd4912fbc 100644
--- a/sound/soc/codecs/Makefile
+++ b/sound/soc/codecs/Makefile
@@ -86,6 +86,7 @@ snd-soc-max9850-objs := max9850.o
86snd-soc-max9860-objs := max9860.o 86snd-soc-max9860-objs := max9860.o
87snd-soc-mc13783-objs := mc13783.o 87snd-soc-mc13783-objs := mc13783.o
88snd-soc-ml26124-objs := ml26124.o 88snd-soc-ml26124-objs := ml26124.o
89snd-soc-nau8810-objs := nau8810.o
89snd-soc-nau8825-objs := nau8825.o 90snd-soc-nau8825-objs := nau8825.o
90snd-soc-hdmi-codec-objs := hdmi-codec.o 91snd-soc-hdmi-codec-objs := hdmi-codec.o
91snd-soc-pcm1681-objs := pcm1681.o 92snd-soc-pcm1681-objs := pcm1681.o
@@ -112,6 +113,8 @@ snd-soc-rt5640-objs := rt5640.o
112snd-soc-rt5645-objs := rt5645.o 113snd-soc-rt5645-objs := rt5645.o
113snd-soc-rt5651-objs := rt5651.o 114snd-soc-rt5651-objs := rt5651.o
114snd-soc-rt5659-objs := rt5659.o 115snd-soc-rt5659-objs := rt5659.o
116snd-soc-rt5660-objs := rt5660.o
117snd-soc-rt5663-objs := rt5663.o
115snd-soc-rt5670-objs := rt5670.o 118snd-soc-rt5670-objs := rt5670.o
116snd-soc-rt5677-objs := rt5677.o 119snd-soc-rt5677-objs := rt5677.o
117snd-soc-rt5677-spi-objs := rt5677-spi.o 120snd-soc-rt5677-spi-objs := rt5677-spi.o
@@ -307,6 +310,7 @@ obj-$(CONFIG_SND_SOC_MAX9850) += snd-soc-max9850.o
307obj-$(CONFIG_SND_SOC_MAX9860) += snd-soc-max9860.o 310obj-$(CONFIG_SND_SOC_MAX9860) += snd-soc-max9860.o
308obj-$(CONFIG_SND_SOC_MC13783) += snd-soc-mc13783.o 311obj-$(CONFIG_SND_SOC_MC13783) += snd-soc-mc13783.o
309obj-$(CONFIG_SND_SOC_ML26124) += snd-soc-ml26124.o 312obj-$(CONFIG_SND_SOC_ML26124) += snd-soc-ml26124.o
313obj-$(CONFIG_SND_SOC_NAU8810) += snd-soc-nau8810.o
310obj-$(CONFIG_SND_SOC_NAU8825) += snd-soc-nau8825.o 314obj-$(CONFIG_SND_SOC_NAU8825) += snd-soc-nau8825.o
311obj-$(CONFIG_SND_SOC_HDMI_CODEC) += snd-soc-hdmi-codec.o 315obj-$(CONFIG_SND_SOC_HDMI_CODEC) += snd-soc-hdmi-codec.o
312obj-$(CONFIG_SND_SOC_PCM1681) += snd-soc-pcm1681.o 316obj-$(CONFIG_SND_SOC_PCM1681) += snd-soc-pcm1681.o
@@ -333,6 +337,8 @@ obj-$(CONFIG_SND_SOC_RT5640) += snd-soc-rt5640.o
333obj-$(CONFIG_SND_SOC_RT5645) += snd-soc-rt5645.o 337obj-$(CONFIG_SND_SOC_RT5645) += snd-soc-rt5645.o
334obj-$(CONFIG_SND_SOC_RT5651) += snd-soc-rt5651.o 338obj-$(CONFIG_SND_SOC_RT5651) += snd-soc-rt5651.o
335obj-$(CONFIG_SND_SOC_RT5659) += snd-soc-rt5659.o 339obj-$(CONFIG_SND_SOC_RT5659) += snd-soc-rt5659.o
340obj-$(CONFIG_SND_SOC_RT5660) += snd-soc-rt5660.o
341obj-$(CONFIG_SND_SOC_RT5663) += snd-soc-rt5663.o
336obj-$(CONFIG_SND_SOC_RT5670) += snd-soc-rt5670.o 342obj-$(CONFIG_SND_SOC_RT5670) += snd-soc-rt5670.o
337obj-$(CONFIG_SND_SOC_RT5677) += snd-soc-rt5677.o 343obj-$(CONFIG_SND_SOC_RT5677) += snd-soc-rt5677.o
338obj-$(CONFIG_SND_SOC_RT5677_SPI) += snd-soc-rt5677-spi.o 344obj-$(CONFIG_SND_SOC_RT5677_SPI) += snd-soc-rt5677-spi.o
diff --git a/sound/soc/codecs/ab8500-codec.c b/sound/soc/codecs/ab8500-codec.c
index 2fc89155f14a..935ff7cb71c5 100644
--- a/sound/soc/codecs/ab8500-codec.c
+++ b/sound/soc/codecs/ab8500-codec.c
@@ -2408,28 +2408,28 @@ static void ab8500_codec_of_probe(struct device *dev, struct device_node *np,
2408{ 2408{
2409 u32 value; 2409 u32 value;
2410 2410
2411 if (of_get_property(np, "stericsson,amic1-type-single-ended", NULL)) 2411 if (of_property_read_bool(np, "stericsson,amic1-type-single-ended"))
2412 codec->amics.mic1_type = AMIC_TYPE_SINGLE_ENDED; 2412 codec->amics.mic1_type = AMIC_TYPE_SINGLE_ENDED;
2413 else 2413 else
2414 codec->amics.mic1_type = AMIC_TYPE_DIFFERENTIAL; 2414 codec->amics.mic1_type = AMIC_TYPE_DIFFERENTIAL;
2415 2415
2416 if (of_get_property(np, "stericsson,amic2-type-single-ended", NULL)) 2416 if (of_property_read_bool(np, "stericsson,amic2-type-single-ended"))
2417 codec->amics.mic2_type = AMIC_TYPE_SINGLE_ENDED; 2417 codec->amics.mic2_type = AMIC_TYPE_SINGLE_ENDED;
2418 else 2418 else
2419 codec->amics.mic2_type = AMIC_TYPE_DIFFERENTIAL; 2419 codec->amics.mic2_type = AMIC_TYPE_DIFFERENTIAL;
2420 2420
2421 /* Has a non-standard Vamic been requested? */ 2421 /* Has a non-standard Vamic been requested? */
2422 if (of_get_property(np, "stericsson,amic1a-bias-vamic2", NULL)) 2422 if (of_property_read_bool(np, "stericsson,amic1a-bias-vamic2"))
2423 codec->amics.mic1a_micbias = AMIC_MICBIAS_VAMIC2; 2423 codec->amics.mic1a_micbias = AMIC_MICBIAS_VAMIC2;
2424 else 2424 else
2425 codec->amics.mic1a_micbias = AMIC_MICBIAS_VAMIC1; 2425 codec->amics.mic1a_micbias = AMIC_MICBIAS_VAMIC1;
2426 2426
2427 if (of_get_property(np, "stericsson,amic1b-bias-vamic2", NULL)) 2427 if (of_property_read_bool(np, "stericsson,amic1b-bias-vamic2"))
2428 codec->amics.mic1b_micbias = AMIC_MICBIAS_VAMIC2; 2428 codec->amics.mic1b_micbias = AMIC_MICBIAS_VAMIC2;
2429 else 2429 else
2430 codec->amics.mic1b_micbias = AMIC_MICBIAS_VAMIC1; 2430 codec->amics.mic1b_micbias = AMIC_MICBIAS_VAMIC1;
2431 2431
2432 if (of_get_property(np, "stericsson,amic2-bias-vamic1", NULL)) 2432 if (of_property_read_bool(np, "stericsson,amic2-bias-vamic1"))
2433 codec->amics.mic2_micbias = AMIC_MICBIAS_VAMIC1; 2433 codec->amics.mic2_micbias = AMIC_MICBIAS_VAMIC1;
2434 else 2434 else
2435 codec->amics.mic2_micbias = AMIC_MICBIAS_VAMIC2; 2435 codec->amics.mic2_micbias = AMIC_MICBIAS_VAMIC2;
@@ -2525,12 +2525,14 @@ static int ab8500_codec_probe(struct snd_soc_codec *codec)
2525 2525
2526static struct snd_soc_codec_driver ab8500_codec_driver = { 2526static struct snd_soc_codec_driver ab8500_codec_driver = {
2527 .probe = ab8500_codec_probe, 2527 .probe = ab8500_codec_probe,
2528 .controls = ab8500_ctrls, 2528 .component_driver = {
2529 .num_controls = ARRAY_SIZE(ab8500_ctrls), 2529 .controls = ab8500_ctrls,
2530 .dapm_widgets = ab8500_dapm_widgets, 2530 .num_controls = ARRAY_SIZE(ab8500_ctrls),
2531 .num_dapm_widgets = ARRAY_SIZE(ab8500_dapm_widgets), 2531 .dapm_widgets = ab8500_dapm_widgets,
2532 .dapm_routes = ab8500_dapm_routes, 2532 .num_dapm_widgets = ARRAY_SIZE(ab8500_dapm_widgets),
2533 .num_dapm_routes = ARRAY_SIZE(ab8500_dapm_routes), 2533 .dapm_routes = ab8500_dapm_routes,
2534 .num_dapm_routes = ARRAY_SIZE(ab8500_dapm_routes),
2535 },
2534}; 2536};
2535 2537
2536static int ab8500_codec_driver_probe(struct platform_device *pdev) 2538static int ab8500_codec_driver_probe(struct platform_device *pdev)
diff --git a/sound/soc/codecs/ac97.c b/sound/soc/codecs/ac97.c
index 5b3224c63943..f7f04c6be01e 100644
--- a/sound/soc/codecs/ac97.c
+++ b/sound/soc/codecs/ac97.c
@@ -117,10 +117,12 @@ static struct snd_soc_codec_driver soc_codec_dev_ac97 = {
117 .suspend = ac97_soc_suspend, 117 .suspend = ac97_soc_suspend,
118 .resume = ac97_soc_resume, 118 .resume = ac97_soc_resume,
119 119
120 .dapm_widgets = ac97_widgets, 120 .component_driver = {
121 .num_dapm_widgets = ARRAY_SIZE(ac97_widgets), 121 .dapm_widgets = ac97_widgets,
122 .dapm_routes = ac97_routes, 122 .num_dapm_widgets = ARRAY_SIZE(ac97_widgets),
123 .num_dapm_routes = ARRAY_SIZE(ac97_routes), 123 .dapm_routes = ac97_routes,
124 .num_dapm_routes = ARRAY_SIZE(ac97_routes),
125 },
124}; 126};
125 127
126static int ac97_probe(struct platform_device *pdev) 128static int ac97_probe(struct platform_device *pdev)
diff --git a/sound/soc/codecs/ad1836.c b/sound/soc/codecs/ad1836.c
index e2ce6c4d7ece..a478239aadac 100644
--- a/sound/soc/codecs/ad1836.c
+++ b/sound/soc/codecs/ad1836.c
@@ -327,12 +327,14 @@ static struct snd_soc_codec_driver soc_codec_dev_ad1836 = {
327 .suspend = ad1836_suspend, 327 .suspend = ad1836_suspend,
328 .resume = ad1836_resume, 328 .resume = ad1836_resume,
329 329
330 .controls = ad183x_controls, 330 .component_driver = {
331 .num_controls = ARRAY_SIZE(ad183x_controls), 331 .controls = ad183x_controls,
332 .dapm_widgets = ad183x_dapm_widgets, 332 .num_controls = ARRAY_SIZE(ad183x_controls),
333 .num_dapm_widgets = ARRAY_SIZE(ad183x_dapm_widgets), 333 .dapm_widgets = ad183x_dapm_widgets,
334 .dapm_routes = ad183x_dapm_routes, 334 .num_dapm_widgets = ARRAY_SIZE(ad183x_dapm_widgets),
335 .num_dapm_routes = ARRAY_SIZE(ad183x_dapm_routes), 335 .dapm_routes = ad183x_dapm_routes,
336 .num_dapm_routes = ARRAY_SIZE(ad183x_dapm_routes),
337 },
336}; 338};
337 339
338static const struct reg_default ad1836_reg_defaults[] = { 340static const struct reg_default ad1836_reg_defaults[] = {
diff --git a/sound/soc/codecs/ad193x.c b/sound/soc/codecs/ad193x.c
index 3a3f3f2343d7..d643557d89a7 100644
--- a/sound/soc/codecs/ad193x.c
+++ b/sound/soc/codecs/ad193x.c
@@ -410,12 +410,14 @@ static int ad193x_codec_probe(struct snd_soc_codec *codec)
410 410
411static struct snd_soc_codec_driver soc_codec_dev_ad193x = { 411static struct snd_soc_codec_driver soc_codec_dev_ad193x = {
412 .probe = ad193x_codec_probe, 412 .probe = ad193x_codec_probe,
413 .controls = ad193x_snd_controls, 413 .component_driver = {
414 .num_controls = ARRAY_SIZE(ad193x_snd_controls), 414 .controls = ad193x_snd_controls,
415 .dapm_widgets = ad193x_dapm_widgets, 415 .num_controls = ARRAY_SIZE(ad193x_snd_controls),
416 .num_dapm_widgets = ARRAY_SIZE(ad193x_dapm_widgets), 416 .dapm_widgets = ad193x_dapm_widgets,
417 .dapm_routes = audio_paths, 417 .num_dapm_widgets = ARRAY_SIZE(ad193x_dapm_widgets),
418 .num_dapm_routes = ARRAY_SIZE(audio_paths), 418 .dapm_routes = audio_paths,
419 .num_dapm_routes = ARRAY_SIZE(audio_paths),
420 },
419}; 421};
420 422
421const struct regmap_config ad193x_regmap_config = { 423const struct regmap_config ad193x_regmap_config = {
diff --git a/sound/soc/codecs/ad1980.c b/sound/soc/codecs/ad1980.c
index 9ef20dbccbe3..b7c1b9f4bf5f 100644
--- a/sound/soc/codecs/ad1980.c
+++ b/sound/soc/codecs/ad1980.c
@@ -299,12 +299,14 @@ static struct snd_soc_codec_driver soc_codec_dev_ad1980 = {
299 .probe = ad1980_soc_probe, 299 .probe = ad1980_soc_probe,
300 .remove = ad1980_soc_remove, 300 .remove = ad1980_soc_remove,
301 301
302 .controls = ad1980_snd_ac97_controls, 302 .component_driver = {
303 .num_controls = ARRAY_SIZE(ad1980_snd_ac97_controls), 303 .controls = ad1980_snd_ac97_controls,
304 .dapm_widgets = ad1980_dapm_widgets, 304 .num_controls = ARRAY_SIZE(ad1980_snd_ac97_controls),
305 .num_dapm_widgets = ARRAY_SIZE(ad1980_dapm_widgets), 305 .dapm_widgets = ad1980_dapm_widgets,
306 .dapm_routes = ad1980_dapm_routes, 306 .num_dapm_widgets = ARRAY_SIZE(ad1980_dapm_widgets),
307 .num_dapm_routes = ARRAY_SIZE(ad1980_dapm_routes), 307 .dapm_routes = ad1980_dapm_routes,
308 .num_dapm_routes = ARRAY_SIZE(ad1980_dapm_routes),
309 },
308}; 310};
309 311
310static int ad1980_probe(struct platform_device *pdev) 312static int ad1980_probe(struct platform_device *pdev)
diff --git a/sound/soc/codecs/ad73311.c b/sound/soc/codecs/ad73311.c
index a9400aef60b5..3e358a49442d 100644
--- a/sound/soc/codecs/ad73311.c
+++ b/sound/soc/codecs/ad73311.c
@@ -55,10 +55,12 @@ static struct snd_soc_dai_driver ad73311_dai = {
55}; 55};
56 56
57static struct snd_soc_codec_driver soc_codec_dev_ad73311 = { 57static struct snd_soc_codec_driver soc_codec_dev_ad73311 = {
58 .dapm_widgets = ad73311_dapm_widgets, 58 .component_driver = {
59 .num_dapm_widgets = ARRAY_SIZE(ad73311_dapm_widgets), 59 .dapm_widgets = ad73311_dapm_widgets,
60 .dapm_routes = ad73311_dapm_routes, 60 .num_dapm_widgets = ARRAY_SIZE(ad73311_dapm_widgets),
61 .num_dapm_routes = ARRAY_SIZE(ad73311_dapm_routes), 61 .dapm_routes = ad73311_dapm_routes,
62 .num_dapm_routes = ARRAY_SIZE(ad73311_dapm_routes),
63 },
62}; 64};
63 65
64static int ad73311_probe(struct platform_device *pdev) 66static int ad73311_probe(struct platform_device *pdev)
diff --git a/sound/soc/codecs/adau1373.c b/sound/soc/codecs/adau1373.c
index 1556b360fa15..8fa9045571ff 100644
--- a/sound/soc/codecs/adau1373.c
+++ b/sound/soc/codecs/adau1373.c
@@ -1466,12 +1466,14 @@ static struct snd_soc_codec_driver adau1373_codec_driver = {
1466 1466
1467 .set_pll = adau1373_set_pll, 1467 .set_pll = adau1373_set_pll,
1468 1468
1469 .controls = adau1373_controls, 1469 .component_driver = {
1470 .num_controls = ARRAY_SIZE(adau1373_controls), 1470 .controls = adau1373_controls,
1471 .dapm_widgets = adau1373_dapm_widgets, 1471 .num_controls = ARRAY_SIZE(adau1373_controls),
1472 .num_dapm_widgets = ARRAY_SIZE(adau1373_dapm_widgets), 1472 .dapm_widgets = adau1373_dapm_widgets,
1473 .dapm_routes = adau1373_dapm_routes, 1473 .num_dapm_widgets = ARRAY_SIZE(adau1373_dapm_widgets),
1474 .num_dapm_routes = ARRAY_SIZE(adau1373_dapm_routes), 1474 .dapm_routes = adau1373_dapm_routes,
1475 .num_dapm_routes = ARRAY_SIZE(adau1373_dapm_routes),
1476 },
1475}; 1477};
1476 1478
1477static int adau1373_i2c_probe(struct i2c_client *client, 1479static int adau1373_i2c_probe(struct i2c_client *client,
diff --git a/sound/soc/codecs/adau1701.c b/sound/soc/codecs/adau1701.c
index de53c0d7bf10..3bad1bc8c00a 100644
--- a/sound/soc/codecs/adau1701.c
+++ b/sound/soc/codecs/adau1701.c
@@ -765,13 +765,14 @@ static struct snd_soc_codec_driver adau1701_codec_drv = {
765 .set_bias_level = adau1701_set_bias_level, 765 .set_bias_level = adau1701_set_bias_level,
766 .idle_bias_off = true, 766 .idle_bias_off = true,
767 767
768 .controls = adau1701_controls, 768 .component_driver = {
769 .num_controls = ARRAY_SIZE(adau1701_controls), 769 .controls = adau1701_controls,
770 .dapm_widgets = adau1701_dapm_widgets, 770 .num_controls = ARRAY_SIZE(adau1701_controls),
771 .num_dapm_widgets = ARRAY_SIZE(adau1701_dapm_widgets), 771 .dapm_widgets = adau1701_dapm_widgets,
772 .dapm_routes = adau1701_dapm_routes, 772 .num_dapm_widgets = ARRAY_SIZE(adau1701_dapm_widgets),
773 .num_dapm_routes = ARRAY_SIZE(adau1701_dapm_routes), 773 .dapm_routes = adau1701_dapm_routes,
774 774 .num_dapm_routes = ARRAY_SIZE(adau1701_dapm_routes),
775 },
775 .set_sysclk = adau1701_set_sysclk, 776 .set_sysclk = adau1701_set_sysclk,
776}; 777};
777 778
diff --git a/sound/soc/codecs/adau1761.c b/sound/soc/codecs/adau1761.c
index b95d29dbd13d..3bc3cc559dde 100644
--- a/sound/soc/codecs/adau1761.c
+++ b/sound/soc/codecs/adau1761.c
@@ -719,12 +719,14 @@ static const struct snd_soc_codec_driver adau1761_codec_driver = {
719 .set_bias_level = adau1761_set_bias_level, 719 .set_bias_level = adau1761_set_bias_level,
720 .suspend_bias_off = true, 720 .suspend_bias_off = true,
721 721
722 .controls = adau1761_controls, 722 .component_driver = {
723 .num_controls = ARRAY_SIZE(adau1761_controls), 723 .controls = adau1761_controls,
724 .dapm_widgets = adau1x61_dapm_widgets, 724 .num_controls = ARRAY_SIZE(adau1761_controls),
725 .num_dapm_widgets = ARRAY_SIZE(adau1x61_dapm_widgets), 725 .dapm_widgets = adau1x61_dapm_widgets,
726 .dapm_routes = adau1x61_dapm_routes, 726 .num_dapm_widgets = ARRAY_SIZE(adau1x61_dapm_widgets),
727 .num_dapm_routes = ARRAY_SIZE(adau1x61_dapm_routes), 727 .dapm_routes = adau1x61_dapm_routes,
728 .num_dapm_routes = ARRAY_SIZE(adau1x61_dapm_routes),
729 },
728}; 730};
729 731
730#define ADAU1761_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE | \ 732#define ADAU1761_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE | \
diff --git a/sound/soc/codecs/adau1781.c b/sound/soc/codecs/adau1781.c
index bc1bb56dae63..546071c6c0d0 100644
--- a/sound/soc/codecs/adau1781.c
+++ b/sound/soc/codecs/adau1781.c
@@ -432,12 +432,14 @@ static const struct snd_soc_codec_driver adau1781_codec_driver = {
432 .set_bias_level = adau1781_set_bias_level, 432 .set_bias_level = adau1781_set_bias_level,
433 .suspend_bias_off = true, 433 .suspend_bias_off = true,
434 434
435 .controls = adau1781_controls, 435 .component_driver = {
436 .num_controls = ARRAY_SIZE(adau1781_controls), 436 .controls = adau1781_controls,
437 .dapm_widgets = adau1781_dapm_widgets, 437 .num_controls = ARRAY_SIZE(adau1781_controls),
438 .num_dapm_widgets = ARRAY_SIZE(adau1781_dapm_widgets), 438 .dapm_widgets = adau1781_dapm_widgets,
439 .dapm_routes = adau1781_dapm_routes, 439 .num_dapm_widgets = ARRAY_SIZE(adau1781_dapm_widgets),
440 .num_dapm_routes = ARRAY_SIZE(adau1781_dapm_routes), 440 .dapm_routes = adau1781_dapm_routes,
441 .num_dapm_routes = ARRAY_SIZE(adau1781_dapm_routes),
442 },
441}; 443};
442 444
443#define ADAU1781_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE | \ 445#define ADAU1781_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE | \
diff --git a/sound/soc/codecs/adau1977.c b/sound/soc/codecs/adau1977.c
index 9bdd15f408c1..b319db6a69f8 100644
--- a/sound/soc/codecs/adau1977.c
+++ b/sound/soc/codecs/adau1977.c
@@ -873,12 +873,14 @@ static struct snd_soc_codec_driver adau1977_codec_driver = {
873 .set_sysclk = adau1977_set_sysclk, 873 .set_sysclk = adau1977_set_sysclk,
874 .idle_bias_off = true, 874 .idle_bias_off = true,
875 875
876 .controls = adau1977_snd_controls, 876 .component_driver = {
877 .num_controls = ARRAY_SIZE(adau1977_snd_controls), 877 .controls = adau1977_snd_controls,
878 .dapm_widgets = adau1977_dapm_widgets, 878 .num_controls = ARRAY_SIZE(adau1977_snd_controls),
879 .num_dapm_widgets = ARRAY_SIZE(adau1977_dapm_widgets), 879 .dapm_widgets = adau1977_dapm_widgets,
880 .dapm_routes = adau1977_dapm_routes, 880 .num_dapm_widgets = ARRAY_SIZE(adau1977_dapm_widgets),
881 .num_dapm_routes = ARRAY_SIZE(adau1977_dapm_routes), 881 .dapm_routes = adau1977_dapm_routes,
882 .num_dapm_routes = ARRAY_SIZE(adau1977_dapm_routes),
883 },
882}; 884};
883 885
884static int adau1977_setup_micbias(struct adau1977 *adau1977) 886static int adau1977_setup_micbias(struct adau1977 *adau1977)
diff --git a/sound/soc/codecs/adau7002.c b/sound/soc/codecs/adau7002.c
index 9df72c6adcca..6384c5491de8 100644
--- a/sound/soc/codecs/adau7002.c
+++ b/sound/soc/codecs/adau7002.c
@@ -39,10 +39,12 @@ static struct snd_soc_dai_driver adau7002_dai = {
39}; 39};
40 40
41static const struct snd_soc_codec_driver adau7002_codec_driver = { 41static const struct snd_soc_codec_driver adau7002_codec_driver = {
42 .dapm_widgets = adau7002_widgets, 42 .component_driver = {
43 .num_dapm_widgets = ARRAY_SIZE(adau7002_widgets), 43 .dapm_widgets = adau7002_widgets,
44 .dapm_routes = adau7002_routes, 44 .num_dapm_widgets = ARRAY_SIZE(adau7002_widgets),
45 .num_dapm_routes = ARRAY_SIZE(adau7002_routes), 45 .dapm_routes = adau7002_routes,
46 .num_dapm_routes = ARRAY_SIZE(adau7002_routes),
47 },
46}; 48};
47 49
48static int adau7002_probe(struct platform_device *pdev) 50static int adau7002_probe(struct platform_device *pdev)
diff --git a/sound/soc/codecs/adav80x.c b/sound/soc/codecs/adav80x.c
index acff8d62059c..6e793ebb5883 100644
--- a/sound/soc/codecs/adav80x.c
+++ b/sound/soc/codecs/adav80x.c
@@ -834,12 +834,14 @@ static struct snd_soc_codec_driver adav80x_codec_driver = {
834 .set_pll = adav80x_set_pll, 834 .set_pll = adav80x_set_pll,
835 .set_sysclk = adav80x_set_sysclk, 835 .set_sysclk = adav80x_set_sysclk,
836 836
837 .controls = adav80x_controls, 837 .component_driver = {
838 .num_controls = ARRAY_SIZE(adav80x_controls), 838 .controls = adav80x_controls,
839 .dapm_widgets = adav80x_dapm_widgets, 839 .num_controls = ARRAY_SIZE(adav80x_controls),
840 .num_dapm_widgets = ARRAY_SIZE(adav80x_dapm_widgets), 840 .dapm_widgets = adav80x_dapm_widgets,
841 .dapm_routes = adav80x_dapm_routes, 841 .num_dapm_widgets = ARRAY_SIZE(adav80x_dapm_widgets),
842 .num_dapm_routes = ARRAY_SIZE(adav80x_dapm_routes), 842 .dapm_routes = adav80x_dapm_routes,
843 .num_dapm_routes = ARRAY_SIZE(adav80x_dapm_routes),
844 },
843}; 845};
844 846
845int adav80x_bus_probe(struct device *dev, struct regmap *regmap) 847int adav80x_bus_probe(struct device *dev, struct regmap *regmap)
diff --git a/sound/soc/codecs/ads117x.c b/sound/soc/codecs/ads117x.c
index c5be1bdc2c9a..90c756d183b4 100644
--- a/sound/soc/codecs/ads117x.c
+++ b/sound/soc/codecs/ads117x.c
@@ -59,10 +59,12 @@ static struct snd_soc_dai_driver ads117x_dai = {
59}; 59};
60 60
61static struct snd_soc_codec_driver soc_codec_dev_ads117x = { 61static struct snd_soc_codec_driver soc_codec_dev_ads117x = {
62 .dapm_widgets = ads117x_dapm_widgets, 62 .component_driver = {
63 .num_dapm_widgets = ARRAY_SIZE(ads117x_dapm_widgets), 63 .dapm_widgets = ads117x_dapm_widgets,
64 .dapm_routes = ads117x_dapm_routes, 64 .num_dapm_widgets = ARRAY_SIZE(ads117x_dapm_widgets),
65 .num_dapm_routes = ARRAY_SIZE(ads117x_dapm_routes), 65 .dapm_routes = ads117x_dapm_routes,
66 .num_dapm_routes = ARRAY_SIZE(ads117x_dapm_routes),
67 },
66}; 68};
67 69
68static int ads117x_probe(struct platform_device *pdev) 70static int ads117x_probe(struct platform_device *pdev)
diff --git a/sound/soc/codecs/ak4104.c b/sound/soc/codecs/ak4104.c
index 595d02d7602c..1a9d233c94d0 100644
--- a/sound/soc/codecs/ak4104.c
+++ b/sound/soc/codecs/ak4104.c
@@ -163,7 +163,10 @@ static struct snd_soc_dai_driver ak4104_dai = {
163 .stream_name = "Playback", 163 .stream_name = "Playback",
164 .channels_min = 2, 164 .channels_min = 2,
165 .channels_max = 2, 165 .channels_max = 2,
166 .rates = SNDRV_PCM_RATE_8000_192000, 166 .rates = SNDRV_PCM_RATE_22050 | SNDRV_PCM_RATE_32000 |
167 SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 |
168 SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000 |
169 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_192000,
167 .formats = SNDRV_PCM_FMTBIT_S16_LE | 170 .formats = SNDRV_PCM_FMTBIT_S16_LE |
168 SNDRV_PCM_FMTBIT_S24_3LE | 171 SNDRV_PCM_FMTBIT_S24_3LE |
169 SNDRV_PCM_FMTBIT_S24_LE 172 SNDRV_PCM_FMTBIT_S24_LE
@@ -245,10 +248,12 @@ static struct snd_soc_codec_driver soc_codec_device_ak4104 = {
245 .suspend = ak4104_soc_suspend, 248 .suspend = ak4104_soc_suspend,
246 .resume = ak4104_soc_resume, 249 .resume = ak4104_soc_resume,
247 250
248 .dapm_widgets = ak4104_dapm_widgets, 251 .component_driver = {
249 .num_dapm_widgets = ARRAY_SIZE(ak4104_dapm_widgets), 252 .dapm_widgets = ak4104_dapm_widgets,
250 .dapm_routes = ak4104_dapm_routes, 253 .num_dapm_widgets = ARRAY_SIZE(ak4104_dapm_widgets),
251 .num_dapm_routes = ARRAY_SIZE(ak4104_dapm_routes), 254 .dapm_routes = ak4104_dapm_routes,
255 .num_dapm_routes = ARRAY_SIZE(ak4104_dapm_routes),
256 }
252}; 257};
253 258
254static const struct regmap_config ak4104_regmap = { 259static const struct regmap_config ak4104_regmap = {
diff --git a/sound/soc/codecs/ak4535.c b/sound/soc/codecs/ak4535.c
index 54428c64387b..66cfffde9a12 100644
--- a/sound/soc/codecs/ak4535.c
+++ b/sound/soc/codecs/ak4535.c
@@ -395,12 +395,14 @@ static struct snd_soc_codec_driver soc_codec_dev_ak4535 = {
395 .set_bias_level = ak4535_set_bias_level, 395 .set_bias_level = ak4535_set_bias_level,
396 .suspend_bias_off = true, 396 .suspend_bias_off = true,
397 397
398 .controls = ak4535_snd_controls, 398 .component_driver = {
399 .num_controls = ARRAY_SIZE(ak4535_snd_controls), 399 .controls = ak4535_snd_controls,
400 .dapm_widgets = ak4535_dapm_widgets, 400 .num_controls = ARRAY_SIZE(ak4535_snd_controls),
401 .num_dapm_widgets = ARRAY_SIZE(ak4535_dapm_widgets), 401 .dapm_widgets = ak4535_dapm_widgets,
402 .dapm_routes = ak4535_audio_map, 402 .num_dapm_widgets = ARRAY_SIZE(ak4535_dapm_widgets),
403 .num_dapm_routes = ARRAY_SIZE(ak4535_audio_map), 403 .dapm_routes = ak4535_audio_map,
404 .num_dapm_routes = ARRAY_SIZE(ak4535_audio_map),
405 },
404}; 406};
405 407
406static int ak4535_i2c_probe(struct i2c_client *i2c, 408static int ak4535_i2c_probe(struct i2c_client *i2c,
diff --git a/sound/soc/codecs/ak4554.c b/sound/soc/codecs/ak4554.c
index 298dedc05140..b92c548b9d29 100644
--- a/sound/soc/codecs/ak4554.c
+++ b/sound/soc/codecs/ak4554.c
@@ -65,10 +65,12 @@ static struct snd_soc_dai_driver ak4554_dai = {
65}; 65};
66 66
67static struct snd_soc_codec_driver soc_codec_dev_ak4554 = { 67static struct snd_soc_codec_driver soc_codec_dev_ak4554 = {
68 .dapm_widgets = ak4554_dapm_widgets, 68 .component_driver = {
69 .num_dapm_widgets = ARRAY_SIZE(ak4554_dapm_widgets), 69 .dapm_widgets = ak4554_dapm_widgets,
70 .dapm_routes = ak4554_dapm_routes, 70 .num_dapm_widgets = ARRAY_SIZE(ak4554_dapm_widgets),
71 .num_dapm_routes = ARRAY_SIZE(ak4554_dapm_routes), 71 .dapm_routes = ak4554_dapm_routes,
72 .num_dapm_routes = ARRAY_SIZE(ak4554_dapm_routes),
73 },
72}; 74};
73 75
74static int ak4554_soc_probe(struct platform_device *pdev) 76static int ak4554_soc_probe(struct platform_device *pdev)
diff --git a/sound/soc/codecs/ak4613.c b/sound/soc/codecs/ak4613.c
index 97798d250f08..e819dd8c82fd 100644
--- a/sound/soc/codecs/ak4613.c
+++ b/sound/soc/codecs/ak4613.c
@@ -458,12 +458,14 @@ static struct snd_soc_codec_driver soc_codec_dev_ak4613 = {
458 .suspend = ak4613_suspend, 458 .suspend = ak4613_suspend,
459 .resume = ak4613_resume, 459 .resume = ak4613_resume,
460 .set_bias_level = ak4613_set_bias_level, 460 .set_bias_level = ak4613_set_bias_level,
461 .controls = ak4613_snd_controls, 461 .component_driver = {
462 .num_controls = ARRAY_SIZE(ak4613_snd_controls), 462 .controls = ak4613_snd_controls,
463 .dapm_widgets = ak4613_dapm_widgets, 463 .num_controls = ARRAY_SIZE(ak4613_snd_controls),
464 .num_dapm_widgets = ARRAY_SIZE(ak4613_dapm_widgets), 464 .dapm_widgets = ak4613_dapm_widgets,
465 .dapm_routes = ak4613_intercon, 465 .num_dapm_widgets = ARRAY_SIZE(ak4613_dapm_widgets),
466 .num_dapm_routes = ARRAY_SIZE(ak4613_intercon), 466 .dapm_routes = ak4613_intercon,
467 .num_dapm_routes = ARRAY_SIZE(ak4613_intercon),
468 },
467}; 469};
468 470
469static void ak4613_parse_of(struct ak4613_priv *priv, 471static void ak4613_parse_of(struct ak4613_priv *priv,
diff --git a/sound/soc/codecs/ak4641.c b/sound/soc/codecs/ak4641.c
index b14176f8d884..c91717d08513 100644
--- a/sound/soc/codecs/ak4641.c
+++ b/sound/soc/codecs/ak4641.c
@@ -505,12 +505,14 @@ static struct snd_soc_dai_driver ak4641_dai[] = {
505}; 505};
506 506
507static struct snd_soc_codec_driver soc_codec_dev_ak4641 = { 507static struct snd_soc_codec_driver soc_codec_dev_ak4641 = {
508 .controls = ak4641_snd_controls, 508 .component_driver = {
509 .num_controls = ARRAY_SIZE(ak4641_snd_controls), 509 .controls = ak4641_snd_controls,
510 .dapm_widgets = ak4641_dapm_widgets, 510 .num_controls = ARRAY_SIZE(ak4641_snd_controls),
511 .num_dapm_widgets = ARRAY_SIZE(ak4641_dapm_widgets), 511 .dapm_widgets = ak4641_dapm_widgets,
512 .dapm_routes = ak4641_audio_map, 512 .num_dapm_widgets = ARRAY_SIZE(ak4641_dapm_widgets),
513 .num_dapm_routes = ARRAY_SIZE(ak4641_audio_map), 513 .dapm_routes = ak4641_audio_map,
514 .num_dapm_routes = ARRAY_SIZE(ak4641_audio_map),
515 },
514 .set_bias_level = ak4641_set_bias_level, 516 .set_bias_level = ak4641_set_bias_level,
515 .suspend_bias_off = true, 517 .suspend_bias_off = true,
516}; 518};
diff --git a/sound/soc/codecs/ak4642.c b/sound/soc/codecs/ak4642.c
index cc941d66ec3d..2609f95b7d19 100644
--- a/sound/soc/codecs/ak4642.c
+++ b/sound/soc/codecs/ak4642.c
@@ -555,12 +555,14 @@ static struct snd_soc_codec_driver soc_codec_dev_ak4642 = {
555 .suspend = ak4642_suspend, 555 .suspend = ak4642_suspend,
556 .resume = ak4642_resume, 556 .resume = ak4642_resume,
557 .set_bias_level = ak4642_set_bias_level, 557 .set_bias_level = ak4642_set_bias_level,
558 .controls = ak4642_snd_controls, 558 .component_driver = {
559 .num_controls = ARRAY_SIZE(ak4642_snd_controls), 559 .controls = ak4642_snd_controls,
560 .dapm_widgets = ak4642_dapm_widgets, 560 .num_controls = ARRAY_SIZE(ak4642_snd_controls),
561 .num_dapm_widgets = ARRAY_SIZE(ak4642_dapm_widgets), 561 .dapm_widgets = ak4642_dapm_widgets,
562 .dapm_routes = ak4642_intercon, 562 .num_dapm_widgets = ARRAY_SIZE(ak4642_dapm_widgets),
563 .num_dapm_routes = ARRAY_SIZE(ak4642_intercon), 563 .dapm_routes = ak4642_intercon,
564 .num_dapm_routes = ARRAY_SIZE(ak4642_intercon),
565 },
564}; 566};
565 567
566static const struct regmap_config ak4642_regmap = { 568static const struct regmap_config ak4642_regmap = {
diff --git a/sound/soc/codecs/ak4671.c b/sound/soc/codecs/ak4671.c
index c73a9f6914b6..6088afaabf62 100644
--- a/sound/soc/codecs/ak4671.c
+++ b/sound/soc/codecs/ak4671.c
@@ -612,12 +612,14 @@ static struct snd_soc_dai_driver ak4671_dai = {
612 612
613static struct snd_soc_codec_driver soc_codec_dev_ak4671 = { 613static struct snd_soc_codec_driver soc_codec_dev_ak4671 = {
614 .set_bias_level = ak4671_set_bias_level, 614 .set_bias_level = ak4671_set_bias_level,
615 .controls = ak4671_snd_controls, 615 .component_driver = {
616 .num_controls = ARRAY_SIZE(ak4671_snd_controls), 616 .controls = ak4671_snd_controls,
617 .dapm_widgets = ak4671_dapm_widgets, 617 .num_controls = ARRAY_SIZE(ak4671_snd_controls),
618 .num_dapm_widgets = ARRAY_SIZE(ak4671_dapm_widgets), 618 .dapm_widgets = ak4671_dapm_widgets,
619 .dapm_routes = ak4671_intercon, 619 .num_dapm_widgets = ARRAY_SIZE(ak4671_dapm_widgets),
620 .num_dapm_routes = ARRAY_SIZE(ak4671_intercon), 620 .dapm_routes = ak4671_intercon,
621 .num_dapm_routes = ARRAY_SIZE(ak4671_intercon),
622 },
621}; 623};
622 624
623static const struct regmap_config ak4671_regmap = { 625static const struct regmap_config ak4671_regmap = {
diff --git a/sound/soc/codecs/ak5386.c b/sound/soc/codecs/ak5386.c
index afa95360826d..0ef2df223336 100644
--- a/sound/soc/codecs/ak5386.c
+++ b/sound/soc/codecs/ak5386.c
@@ -74,10 +74,12 @@ static struct snd_soc_codec_driver soc_codec_ak5386 = {
74 .remove = ak5386_soc_remove, 74 .remove = ak5386_soc_remove,
75 .suspend = ak5386_soc_suspend, 75 .suspend = ak5386_soc_suspend,
76 .resume = ak5386_soc_resume, 76 .resume = ak5386_soc_resume,
77 .dapm_widgets = ak5386_dapm_widgets, 77 .component_driver = {
78 .num_dapm_widgets = ARRAY_SIZE(ak5386_dapm_widgets), 78 .dapm_widgets = ak5386_dapm_widgets,
79 .dapm_routes = ak5386_dapm_routes, 79 .num_dapm_widgets = ARRAY_SIZE(ak5386_dapm_widgets),
80 .num_dapm_routes = ARRAY_SIZE(ak5386_dapm_routes), 80 .dapm_routes = ak5386_dapm_routes,
81 .num_dapm_routes = ARRAY_SIZE(ak5386_dapm_routes),
82 },
81}; 83};
82 84
83static int ak5386_set_dai_fmt(struct snd_soc_dai *codec_dai, 85static int ak5386_set_dai_fmt(struct snd_soc_dai *codec_dai,
diff --git a/sound/soc/codecs/alc5632.c b/sound/soc/codecs/alc5632.c
index 4d3ba33eb6f9..adb80d8719bd 100644
--- a/sound/soc/codecs/alc5632.c
+++ b/sound/soc/codecs/alc5632.c
@@ -1072,12 +1072,14 @@ static const struct snd_soc_codec_driver soc_codec_device_alc5632 = {
1072 .set_bias_level = alc5632_set_bias_level, 1072 .set_bias_level = alc5632_set_bias_level,
1073 .suspend_bias_off = true, 1073 .suspend_bias_off = true,
1074 1074
1075 .controls = alc5632_snd_controls, 1075 .component_driver = {
1076 .num_controls = ARRAY_SIZE(alc5632_snd_controls), 1076 .controls = alc5632_snd_controls,
1077 .dapm_widgets = alc5632_dapm_widgets, 1077 .num_controls = ARRAY_SIZE(alc5632_snd_controls),
1078 .num_dapm_widgets = ARRAY_SIZE(alc5632_dapm_widgets), 1078 .dapm_widgets = alc5632_dapm_widgets,
1079 .dapm_routes = alc5632_dapm_routes, 1079 .num_dapm_widgets = ARRAY_SIZE(alc5632_dapm_widgets),
1080 .num_dapm_routes = ARRAY_SIZE(alc5632_dapm_routes), 1080 .dapm_routes = alc5632_dapm_routes,
1081 .num_dapm_routes = ARRAY_SIZE(alc5632_dapm_routes),
1082 },
1081}; 1083};
1082 1084
1083static const struct regmap_config alc5632_regmap = { 1085static const struct regmap_config alc5632_regmap = {
diff --git a/sound/soc/codecs/arizona.c b/sound/soc/codecs/arizona.c
index ecfdbfcae366..846ca079845f 100644
--- a/sound/soc/codecs/arizona.c
+++ b/sound/soc/codecs/arizona.c
@@ -109,7 +109,7 @@ static int arizona_spk_ev(struct snd_soc_dapm_widget *w,
109 break; 109 break;
110 } 110 }
111 111
112 return 0; 112 return arizona_out_ev(w, kcontrol, event);
113} 113}
114 114
115static irqreturn_t arizona_thermal_warn(int irq, void *data) 115static irqreturn_t arizona_thermal_warn(int irq, void *data)
@@ -159,12 +159,14 @@ static irqreturn_t arizona_thermal_shutdown(int irq, void *data)
159static const struct snd_soc_dapm_widget arizona_spkl = 159static const struct snd_soc_dapm_widget arizona_spkl =
160 SND_SOC_DAPM_PGA_E("OUT4L", SND_SOC_NOPM, 160 SND_SOC_DAPM_PGA_E("OUT4L", SND_SOC_NOPM,
161 ARIZONA_OUT4L_ENA_SHIFT, 0, NULL, 0, arizona_spk_ev, 161 ARIZONA_OUT4L_ENA_SHIFT, 0, NULL, 0, arizona_spk_ev,
162 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU); 162 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
163 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD);
163 164
164static const struct snd_soc_dapm_widget arizona_spkr = 165static const struct snd_soc_dapm_widget arizona_spkr =
165 SND_SOC_DAPM_PGA_E("OUT4R", SND_SOC_NOPM, 166 SND_SOC_DAPM_PGA_E("OUT4R", SND_SOC_NOPM,
166 ARIZONA_OUT4R_ENA_SHIFT, 0, NULL, 0, arizona_spk_ev, 167 ARIZONA_OUT4R_ENA_SHIFT, 0, NULL, 0, arizona_spk_ev,
167 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU); 168 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
169 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD);
168 170
169int arizona_init_spk(struct snd_soc_codec *codec) 171int arizona_init_spk(struct snd_soc_codec *codec)
170{ 172{
@@ -864,6 +866,7 @@ int arizona_out_ev(struct snd_soc_dapm_widget *w,
864{ 866{
865 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); 867 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
866 struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec); 868 struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
869 struct arizona *arizona = priv->arizona;
867 870
868 switch (event) { 871 switch (event) {
869 case SND_SOC_DAPM_PRE_PMU: 872 case SND_SOC_DAPM_PRE_PMU:
@@ -877,6 +880,18 @@ int arizona_out_ev(struct snd_soc_dapm_widget *w,
877 priv->out_up_pending++; 880 priv->out_up_pending++;
878 priv->out_up_delay += 17; 881 priv->out_up_delay += 17;
879 break; 882 break;
883 case ARIZONA_OUT4L_ENA_SHIFT:
884 case ARIZONA_OUT4R_ENA_SHIFT:
885 priv->out_up_pending++;
886 switch (arizona->type) {
887 case WM5102:
888 case WM8997:
889 break;
890 default:
891 priv->out_up_delay += 10;
892 break;
893 }
894 break;
880 default: 895 default:
881 break; 896 break;
882 } 897 }
@@ -889,8 +904,12 @@ int arizona_out_ev(struct snd_soc_dapm_widget *w,
889 case ARIZONA_OUT2R_ENA_SHIFT: 904 case ARIZONA_OUT2R_ENA_SHIFT:
890 case ARIZONA_OUT3L_ENA_SHIFT: 905 case ARIZONA_OUT3L_ENA_SHIFT:
891 case ARIZONA_OUT3R_ENA_SHIFT: 906 case ARIZONA_OUT3R_ENA_SHIFT:
907 case ARIZONA_OUT4L_ENA_SHIFT:
908 case ARIZONA_OUT4R_ENA_SHIFT:
892 priv->out_up_pending--; 909 priv->out_up_pending--;
893 if (!priv->out_up_pending) { 910 if (!priv->out_up_pending && priv->out_up_delay) {
911 dev_dbg(codec->dev, "Power up delay: %d\n",
912 priv->out_up_delay);
894 msleep(priv->out_up_delay); 913 msleep(priv->out_up_delay);
895 priv->out_up_delay = 0; 914 priv->out_up_delay = 0;
896 } 915 }
@@ -911,6 +930,21 @@ int arizona_out_ev(struct snd_soc_dapm_widget *w,
911 priv->out_down_pending++; 930 priv->out_down_pending++;
912 priv->out_down_delay++; 931 priv->out_down_delay++;
913 break; 932 break;
933 case ARIZONA_OUT4L_ENA_SHIFT:
934 case ARIZONA_OUT4R_ENA_SHIFT:
935 priv->out_down_pending++;
936 switch (arizona->type) {
937 case WM5102:
938 case WM8997:
939 break;
940 case WM8998:
941 case WM1814:
942 priv->out_down_delay += 5;
943 break;
944 default:
945 priv->out_down_delay++;
946 break;
947 }
914 default: 948 default:
915 break; 949 break;
916 } 950 }
@@ -923,8 +957,12 @@ int arizona_out_ev(struct snd_soc_dapm_widget *w,
923 case ARIZONA_OUT2R_ENA_SHIFT: 957 case ARIZONA_OUT2R_ENA_SHIFT:
924 case ARIZONA_OUT3L_ENA_SHIFT: 958 case ARIZONA_OUT3L_ENA_SHIFT:
925 case ARIZONA_OUT3R_ENA_SHIFT: 959 case ARIZONA_OUT3R_ENA_SHIFT:
960 case ARIZONA_OUT4L_ENA_SHIFT:
961 case ARIZONA_OUT4R_ENA_SHIFT:
926 priv->out_down_pending--; 962 priv->out_down_pending--;
927 if (!priv->out_down_pending) { 963 if (!priv->out_down_pending && priv->out_down_delay) {
964 dev_dbg(codec->dev, "Power down delay: %d\n",
965 priv->out_down_delay);
928 msleep(priv->out_down_delay); 966 msleep(priv->out_down_delay);
929 priv->out_down_delay = 0; 967 priv->out_down_delay = 0;
930 } 968 }
@@ -1920,8 +1958,8 @@ static struct {
1920 1958
1921struct arizona_fll_cfg { 1959struct arizona_fll_cfg {
1922 int n; 1960 int n;
1923 int theta; 1961 unsigned int theta;
1924 int lambda; 1962 unsigned int lambda;
1925 int refdiv; 1963 int refdiv;
1926 int outdiv; 1964 int outdiv;
1927 int fratio; 1965 int fratio;
@@ -2188,13 +2226,13 @@ static void arizona_apply_fll(struct arizona *arizona, unsigned int base,
2188 ARIZONA_FLL1_CTRL_UPD | cfg->n); 2226 ARIZONA_FLL1_CTRL_UPD | cfg->n);
2189} 2227}
2190 2228
2191static int arizona_is_enabled_fll(struct arizona_fll *fll) 2229static int arizona_is_enabled_fll(struct arizona_fll *fll, int base)
2192{ 2230{
2193 struct arizona *arizona = fll->arizona; 2231 struct arizona *arizona = fll->arizona;
2194 unsigned int reg; 2232 unsigned int reg;
2195 int ret; 2233 int ret;
2196 2234
2197 ret = regmap_read(arizona->regmap, fll->base + 1, &reg); 2235 ret = regmap_read(arizona->regmap, base + 1, &reg);
2198 if (ret != 0) { 2236 if (ret != 0) {
2199 arizona_fll_err(fll, "Failed to read current state: %d\n", 2237 arizona_fll_err(fll, "Failed to read current state: %d\n",
2200 ret); 2238 ret);
@@ -2208,21 +2246,24 @@ static int arizona_enable_fll(struct arizona_fll *fll)
2208{ 2246{
2209 struct arizona *arizona = fll->arizona; 2247 struct arizona *arizona = fll->arizona;
2210 bool use_sync = false; 2248 bool use_sync = false;
2211 int already_enabled = arizona_is_enabled_fll(fll); 2249 int already_enabled = arizona_is_enabled_fll(fll, fll->base);
2250 int sync_enabled = arizona_is_enabled_fll(fll, fll->base + 0x10);
2212 struct arizona_fll_cfg cfg; 2251 struct arizona_fll_cfg cfg;
2213 int i; 2252 int i;
2214 unsigned int val; 2253 unsigned int val;
2215 2254
2216 if (already_enabled < 0) 2255 if (already_enabled < 0)
2217 return already_enabled; 2256 return already_enabled;
2257 if (sync_enabled < 0)
2258 return sync_enabled;
2218 2259
2219 if (already_enabled) { 2260 if (already_enabled) {
2220 /* Facilitate smooth refclk across the transition */ 2261 /* Facilitate smooth refclk across the transition */
2221 regmap_update_bits_async(fll->arizona->regmap, fll->base + 0x9,
2222 ARIZONA_FLL1_GAIN_MASK, 0);
2223 regmap_update_bits(fll->arizona->regmap, fll->base + 1, 2262 regmap_update_bits(fll->arizona->regmap, fll->base + 1,
2224 ARIZONA_FLL1_FREERUN, ARIZONA_FLL1_FREERUN); 2263 ARIZONA_FLL1_FREERUN, ARIZONA_FLL1_FREERUN);
2225 udelay(32); 2264 udelay(32);
2265 regmap_update_bits_async(fll->arizona->regmap, fll->base + 0x9,
2266 ARIZONA_FLL1_GAIN_MASK, 0);
2226 } 2267 }
2227 2268
2228 /* 2269 /*
@@ -2233,6 +2274,10 @@ static int arizona_enable_fll(struct arizona_fll *fll)
2233 fll->ref_src != fll->sync_src) { 2274 fll->ref_src != fll->sync_src) {
2234 arizona_calc_fll(fll, &cfg, fll->ref_freq, false); 2275 arizona_calc_fll(fll, &cfg, fll->ref_freq, false);
2235 2276
2277 /* Ref path hardcodes lambda to 65536 when sync is on */
2278 if (fll->sync_src >= 0 && cfg.lambda)
2279 cfg.theta = (cfg.theta * (1 << 16)) / cfg.lambda;
2280
2236 arizona_apply_fll(arizona, fll->base, &cfg, fll->ref_src, 2281 arizona_apply_fll(arizona, fll->base, &cfg, fll->ref_src,
2237 false); 2282 false);
2238 if (fll->sync_src >= 0) { 2283 if (fll->sync_src >= 0) {
@@ -2255,6 +2300,9 @@ static int arizona_enable_fll(struct arizona_fll *fll)
2255 return -EINVAL; 2300 return -EINVAL;
2256 } 2301 }
2257 2302
2303 if (already_enabled && !!sync_enabled != use_sync)
2304 arizona_fll_warn(fll, "Synchroniser changed on active FLL\n");
2305
2258 /* 2306 /*
2259 * Increase the bandwidth if we're not using a low frequency 2307 * Increase the bandwidth if we're not using a low frequency
2260 * sync source. 2308 * sync source.
@@ -2268,14 +2316,14 @@ static int arizona_enable_fll(struct arizona_fll *fll)
2268 ARIZONA_FLL1_SYNC_BW); 2316 ARIZONA_FLL1_SYNC_BW);
2269 2317
2270 if (!already_enabled) 2318 if (!already_enabled)
2271 pm_runtime_get(arizona->dev); 2319 pm_runtime_get_sync(arizona->dev);
2272 2320
2273 regmap_update_bits_async(arizona->regmap, fll->base + 1,
2274 ARIZONA_FLL1_ENA, ARIZONA_FLL1_ENA);
2275 if (use_sync) 2321 if (use_sync)
2276 regmap_update_bits_async(arizona->regmap, fll->base + 0x11, 2322 regmap_update_bits_async(arizona->regmap, fll->base + 0x11,
2277 ARIZONA_FLL1_SYNC_ENA, 2323 ARIZONA_FLL1_SYNC_ENA,
2278 ARIZONA_FLL1_SYNC_ENA); 2324 ARIZONA_FLL1_SYNC_ENA);
2325 regmap_update_bits_async(arizona->regmap, fll->base + 1,
2326 ARIZONA_FLL1_ENA, ARIZONA_FLL1_ENA);
2279 2327
2280 if (already_enabled) 2328 if (already_enabled)
2281 regmap_update_bits_async(arizona->regmap, fll->base + 1, 2329 regmap_update_bits_async(arizona->regmap, fll->base + 1,
diff --git a/sound/soc/codecs/arizona.h b/sound/soc/codecs/arizona.h
index 69da1ef3a17c..850aa338ba29 100644
--- a/sound/soc/codecs/arizona.h
+++ b/sound/soc/codecs/arizona.h
@@ -190,20 +190,21 @@ extern unsigned int arizona_mixer_values[ARIZONA_NUM_MIXER_INPUTS];
190 190
191#define ARIZONA_DSP_ROUTES(name) \ 191#define ARIZONA_DSP_ROUTES(name) \
192 { name, NULL, name " Preloader"}, \ 192 { name, NULL, name " Preloader"}, \
193 { name " Preloader", NULL, name " Aux 1" }, \ 193 { name " Preloader", NULL, "SYSCLK" }, \
194 { name " Preloader", NULL, name " Aux 2" }, \ 194 { name, NULL, name " Aux 1" }, \
195 { name " Preloader", NULL, name " Aux 3" }, \ 195 { name, NULL, name " Aux 2" }, \
196 { name " Preloader", NULL, name " Aux 4" }, \ 196 { name, NULL, name " Aux 3" }, \
197 { name " Preloader", NULL, name " Aux 5" }, \ 197 { name, NULL, name " Aux 4" }, \
198 { name " Preloader", NULL, name " Aux 6" }, \ 198 { name, NULL, name " Aux 5" }, \
199 { name, NULL, name " Aux 6" }, \
199 ARIZONA_MIXER_INPUT_ROUTES(name " Aux 1"), \ 200 ARIZONA_MIXER_INPUT_ROUTES(name " Aux 1"), \
200 ARIZONA_MIXER_INPUT_ROUTES(name " Aux 2"), \ 201 ARIZONA_MIXER_INPUT_ROUTES(name " Aux 2"), \
201 ARIZONA_MIXER_INPUT_ROUTES(name " Aux 3"), \ 202 ARIZONA_MIXER_INPUT_ROUTES(name " Aux 3"), \
202 ARIZONA_MIXER_INPUT_ROUTES(name " Aux 4"), \ 203 ARIZONA_MIXER_INPUT_ROUTES(name " Aux 4"), \
203 ARIZONA_MIXER_INPUT_ROUTES(name " Aux 5"), \ 204 ARIZONA_MIXER_INPUT_ROUTES(name " Aux 5"), \
204 ARIZONA_MIXER_INPUT_ROUTES(name " Aux 6"), \ 205 ARIZONA_MIXER_INPUT_ROUTES(name " Aux 6"), \
205 ARIZONA_MIXER_ROUTES(name " Preloader", name "L"), \ 206 ARIZONA_MIXER_ROUTES(name, name "L"), \
206 ARIZONA_MIXER_ROUTES(name " Preloader", name "R") 207 ARIZONA_MIXER_ROUTES(name, name "R")
207 208
208#define ARIZONA_EQ_CONTROL(xname, xbase) \ 209#define ARIZONA_EQ_CONTROL(xname, xbase) \
209{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \ 210{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
diff --git a/sound/soc/codecs/bt-sco.c b/sound/soc/codecs/bt-sco.c
index 2a8d0ee141d4..8014e697d540 100644
--- a/sound/soc/codecs/bt-sco.c
+++ b/sound/soc/codecs/bt-sco.c
@@ -63,10 +63,12 @@ static struct snd_soc_dai_driver bt_sco_dai[] = {
63}; 63};
64 64
65static struct snd_soc_codec_driver soc_codec_dev_bt_sco = { 65static struct snd_soc_codec_driver soc_codec_dev_bt_sco = {
66 .dapm_widgets = bt_sco_widgets, 66 .component_driver = {
67 .num_dapm_widgets = ARRAY_SIZE(bt_sco_widgets), 67 .dapm_widgets = bt_sco_widgets,
68 .dapm_routes = bt_sco_routes, 68 .num_dapm_widgets = ARRAY_SIZE(bt_sco_widgets),
69 .num_dapm_routes = ARRAY_SIZE(bt_sco_routes), 69 .dapm_routes = bt_sco_routes,
70 .num_dapm_routes = ARRAY_SIZE(bt_sco_routes),
71 },
70}; 72};
71 73
72static int bt_sco_probe(struct platform_device *pdev) 74static int bt_sco_probe(struct platform_device *pdev)
diff --git a/sound/soc/codecs/cq93vc.c b/sound/soc/codecs/cq93vc.c
index 1c895a53001d..7a2d9a2ee427 100644
--- a/sound/soc/codecs/cq93vc.c
+++ b/sound/soc/codecs/cq93vc.c
@@ -131,8 +131,10 @@ static struct regmap *cq93vc_get_regmap(struct device *dev)
131static struct snd_soc_codec_driver soc_codec_dev_cq93vc = { 131static struct snd_soc_codec_driver soc_codec_dev_cq93vc = {
132 .set_bias_level = cq93vc_set_bias_level, 132 .set_bias_level = cq93vc_set_bias_level,
133 .get_regmap = cq93vc_get_regmap, 133 .get_regmap = cq93vc_get_regmap,
134 .controls = cq93vc_snd_controls, 134 .component_driver = {
135 .num_controls = ARRAY_SIZE(cq93vc_snd_controls), 135 .controls = cq93vc_snd_controls,
136 .num_controls = ARRAY_SIZE(cq93vc_snd_controls),
137 },
136}; 138};
137 139
138static int cq93vc_platform_probe(struct platform_device *pdev) 140static int cq93vc_platform_probe(struct platform_device *pdev)
diff --git a/sound/soc/codecs/cs35l32.c b/sound/soc/codecs/cs35l32.c
index 287d13740be4..7e9806206648 100644
--- a/sound/soc/codecs/cs35l32.c
+++ b/sound/soc/codecs/cs35l32.c
@@ -231,13 +231,14 @@ static int cs35l32_codec_set_sysclk(struct snd_soc_codec *codec,
231static const struct snd_soc_codec_driver soc_codec_dev_cs35l32 = { 231static const struct snd_soc_codec_driver soc_codec_dev_cs35l32 = {
232 .set_sysclk = cs35l32_codec_set_sysclk, 232 .set_sysclk = cs35l32_codec_set_sysclk,
233 233
234 .dapm_widgets = cs35l32_dapm_widgets, 234 .component_driver = {
235 .num_dapm_widgets = ARRAY_SIZE(cs35l32_dapm_widgets), 235 .controls = cs35l32_snd_controls,
236 .dapm_routes = cs35l32_audio_map, 236 .num_controls = ARRAY_SIZE(cs35l32_snd_controls),
237 .num_dapm_routes = ARRAY_SIZE(cs35l32_audio_map), 237 .dapm_widgets = cs35l32_dapm_widgets,
238 238 .num_dapm_widgets = ARRAY_SIZE(cs35l32_dapm_widgets),
239 .controls = cs35l32_snd_controls, 239 .dapm_routes = cs35l32_audio_map,
240 .num_controls = ARRAY_SIZE(cs35l32_snd_controls), 240 .num_dapm_routes = ARRAY_SIZE(cs35l32_audio_map),
241 },
241}; 242};
242 243
243/* Current and threshold powerup sequence Pg37 in datasheet */ 244/* Current and threshold powerup sequence Pg37 in datasheet */
diff --git a/sound/soc/codecs/cs35l33.c b/sound/soc/codecs/cs35l33.c
index 6f9c1addcd7f..6df29fa30fb9 100644
--- a/sound/soc/codecs/cs35l33.c
+++ b/sound/soc/codecs/cs35l33.c
@@ -837,13 +837,14 @@ static struct snd_soc_codec_driver soc_codec_dev_cs35l33 = {
837 .set_bias_level = cs35l33_set_bias_level, 837 .set_bias_level = cs35l33_set_bias_level,
838 .set_sysclk = cs35l33_codec_set_sysclk, 838 .set_sysclk = cs35l33_codec_set_sysclk,
839 839
840 .dapm_widgets = cs35l33_dapm_widgets, 840 .component_driver = {
841 .num_dapm_widgets = ARRAY_SIZE(cs35l33_dapm_widgets), 841 .controls = cs35l33_snd_controls,
842 .dapm_routes = cs35l33_audio_map, 842 .num_controls = ARRAY_SIZE(cs35l33_snd_controls),
843 .num_dapm_routes = ARRAY_SIZE(cs35l33_audio_map), 843 .dapm_widgets = cs35l33_dapm_widgets,
844 .controls = cs35l33_snd_controls, 844 .num_dapm_widgets = ARRAY_SIZE(cs35l33_dapm_widgets),
845 .num_controls = ARRAY_SIZE(cs35l33_snd_controls), 845 .dapm_routes = cs35l33_audio_map,
846 846 .num_dapm_routes = ARRAY_SIZE(cs35l33_audio_map),
847 },
847 .idle_bias_off = true, 848 .idle_bias_off = true,
848}; 849};
849 850
diff --git a/sound/soc/codecs/cs4265.c b/sound/soc/codecs/cs4265.c
index 55db19ddc5ff..fd966bb851cb 100644
--- a/sound/soc/codecs/cs4265.c
+++ b/sound/soc/codecs/cs4265.c
@@ -547,13 +547,14 @@ static struct snd_soc_dai_driver cs4265_dai[] = {
547static const struct snd_soc_codec_driver soc_codec_cs4265 = { 547static const struct snd_soc_codec_driver soc_codec_cs4265 = {
548 .set_bias_level = cs4265_set_bias_level, 548 .set_bias_level = cs4265_set_bias_level,
549 549
550 .dapm_widgets = cs4265_dapm_widgets, 550 .component_driver = {
551 .num_dapm_widgets = ARRAY_SIZE(cs4265_dapm_widgets), 551 .controls = cs4265_snd_controls,
552 .dapm_routes = cs4265_audio_map, 552 .num_controls = ARRAY_SIZE(cs4265_snd_controls),
553 .num_dapm_routes = ARRAY_SIZE(cs4265_audio_map), 553 .dapm_widgets = cs4265_dapm_widgets,
554 554 .num_dapm_widgets = ARRAY_SIZE(cs4265_dapm_widgets),
555 .controls = cs4265_snd_controls, 555 .dapm_routes = cs4265_audio_map,
556 .num_controls = ARRAY_SIZE(cs4265_snd_controls), 556 .num_dapm_routes = ARRAY_SIZE(cs4265_audio_map),
557 },
557}; 558};
558 559
559static const struct regmap_config cs4265_regmap = { 560static const struct regmap_config cs4265_regmap = {
diff --git a/sound/soc/codecs/cs4270.c b/sound/soc/codecs/cs4270.c
index e07807d96b68..18baea2f7d65 100644
--- a/sound/soc/codecs/cs4270.c
+++ b/sound/soc/codecs/cs4270.c
@@ -617,12 +617,14 @@ static const struct snd_soc_codec_driver soc_codec_device_cs4270 = {
617 .suspend = cs4270_soc_suspend, 617 .suspend = cs4270_soc_suspend,
618 .resume = cs4270_soc_resume, 618 .resume = cs4270_soc_resume,
619 619
620 .controls = cs4270_snd_controls, 620 .component_driver = {
621 .num_controls = ARRAY_SIZE(cs4270_snd_controls), 621 .controls = cs4270_snd_controls,
622 .dapm_widgets = cs4270_dapm_widgets, 622 .num_controls = ARRAY_SIZE(cs4270_snd_controls),
623 .num_dapm_widgets = ARRAY_SIZE(cs4270_dapm_widgets), 623 .dapm_widgets = cs4270_dapm_widgets,
624 .dapm_routes = cs4270_dapm_routes, 624 .num_dapm_widgets = ARRAY_SIZE(cs4270_dapm_widgets),
625 .num_dapm_routes = ARRAY_SIZE(cs4270_dapm_routes), 625 .dapm_routes = cs4270_dapm_routes,
626 .num_dapm_routes = ARRAY_SIZE(cs4270_dapm_routes),
627 },
626}; 628};
627 629
628/* 630/*
diff --git a/sound/soc/codecs/cs4271.c b/sound/soc/codecs/cs4271.c
index 0c0010b25421..8c0f3b89b5bc 100644
--- a/sound/soc/codecs/cs4271.c
+++ b/sound/soc/codecs/cs4271.c
@@ -645,12 +645,14 @@ static struct snd_soc_codec_driver soc_codec_dev_cs4271 = {
645 .suspend = cs4271_soc_suspend, 645 .suspend = cs4271_soc_suspend,
646 .resume = cs4271_soc_resume, 646 .resume = cs4271_soc_resume,
647 647
648 .controls = cs4271_snd_controls, 648 .component_driver = {
649 .num_controls = ARRAY_SIZE(cs4271_snd_controls), 649 .controls = cs4271_snd_controls,
650 .dapm_widgets = cs4271_dapm_widgets, 650 .num_controls = ARRAY_SIZE(cs4271_snd_controls),
651 .num_dapm_widgets = ARRAY_SIZE(cs4271_dapm_widgets), 651 .dapm_widgets = cs4271_dapm_widgets,
652 .dapm_routes = cs4271_dapm_routes, 652 .num_dapm_widgets = ARRAY_SIZE(cs4271_dapm_widgets),
653 .num_dapm_routes = ARRAY_SIZE(cs4271_dapm_routes), 653 .dapm_routes = cs4271_dapm_routes,
654 .num_dapm_routes = ARRAY_SIZE(cs4271_dapm_routes),
655 },
654}; 656};
655 657
656static int cs4271_common_probe(struct device *dev, 658static int cs4271_common_probe(struct device *dev,
diff --git a/sound/soc/codecs/cs42l51.c b/sound/soc/codecs/cs42l51.c
index 35488f14e237..96cfe38943cd 100644
--- a/sound/soc/codecs/cs42l51.c
+++ b/sound/soc/codecs/cs42l51.c
@@ -507,12 +507,14 @@ static int cs42l51_codec_probe(struct snd_soc_codec *codec)
507static struct snd_soc_codec_driver soc_codec_device_cs42l51 = { 507static struct snd_soc_codec_driver soc_codec_device_cs42l51 = {
508 .probe = cs42l51_codec_probe, 508 .probe = cs42l51_codec_probe,
509 509
510 .controls = cs42l51_snd_controls, 510 .component_driver = {
511 .num_controls = ARRAY_SIZE(cs42l51_snd_controls), 511 .controls = cs42l51_snd_controls,
512 .dapm_widgets = cs42l51_dapm_widgets, 512 .num_controls = ARRAY_SIZE(cs42l51_snd_controls),
513 .num_dapm_widgets = ARRAY_SIZE(cs42l51_dapm_widgets), 513 .dapm_widgets = cs42l51_dapm_widgets,
514 .dapm_routes = cs42l51_routes, 514 .num_dapm_widgets = ARRAY_SIZE(cs42l51_dapm_widgets),
515 .num_dapm_routes = ARRAY_SIZE(cs42l51_routes), 515 .dapm_routes = cs42l51_routes,
516 .num_dapm_routes = ARRAY_SIZE(cs42l51_routes),
517 },
516}; 518};
517 519
518const struct regmap_config cs42l51_regmap = { 520const struct regmap_config cs42l51_regmap = {
diff --git a/sound/soc/codecs/cs42l52.c b/sound/soc/codecs/cs42l52.c
index 47b97fcefb0b..0d9c4a57301b 100644
--- a/sound/soc/codecs/cs42l52.c
+++ b/sound/soc/codecs/cs42l52.c
@@ -1056,13 +1056,14 @@ static const struct snd_soc_codec_driver soc_codec_dev_cs42l52 = {
1056 .set_bias_level = cs42l52_set_bias_level, 1056 .set_bias_level = cs42l52_set_bias_level,
1057 .suspend_bias_off = true, 1057 .suspend_bias_off = true,
1058 1058
1059 .dapm_widgets = cs42l52_dapm_widgets, 1059 .component_driver = {
1060 .num_dapm_widgets = ARRAY_SIZE(cs42l52_dapm_widgets), 1060 .controls = cs42l52_snd_controls,
1061 .dapm_routes = cs42l52_audio_map, 1061 .num_controls = ARRAY_SIZE(cs42l52_snd_controls),
1062 .num_dapm_routes = ARRAY_SIZE(cs42l52_audio_map), 1062 .dapm_widgets = cs42l52_dapm_widgets,
1063 1063 .num_dapm_widgets = ARRAY_SIZE(cs42l52_dapm_widgets),
1064 .controls = cs42l52_snd_controls, 1064 .dapm_routes = cs42l52_audio_map,
1065 .num_controls = ARRAY_SIZE(cs42l52_snd_controls), 1065 .num_dapm_routes = ARRAY_SIZE(cs42l52_audio_map),
1066 },
1066}; 1067};
1067 1068
1068/* Current and threshold powerup sequence Pg37 */ 1069/* Current and threshold powerup sequence Pg37 */
diff --git a/sound/soc/codecs/cs42l56.c b/sound/soc/codecs/cs42l56.c
index eec1ff853b98..54c1768bc818 100644
--- a/sound/soc/codecs/cs42l56.c
+++ b/sound/soc/codecs/cs42l56.c
@@ -1121,13 +1121,14 @@ static const struct snd_soc_codec_driver soc_codec_dev_cs42l56 = {
1121 .set_bias_level = cs42l56_set_bias_level, 1121 .set_bias_level = cs42l56_set_bias_level,
1122 .suspend_bias_off = true, 1122 .suspend_bias_off = true,
1123 1123
1124 .dapm_widgets = cs42l56_dapm_widgets, 1124 .component_driver = {
1125 .num_dapm_widgets = ARRAY_SIZE(cs42l56_dapm_widgets), 1125 .controls = cs42l56_snd_controls,
1126 .dapm_routes = cs42l56_audio_map, 1126 .num_controls = ARRAY_SIZE(cs42l56_snd_controls),
1127 .num_dapm_routes = ARRAY_SIZE(cs42l56_audio_map), 1127 .dapm_widgets = cs42l56_dapm_widgets,
1128 1128 .num_dapm_widgets = ARRAY_SIZE(cs42l56_dapm_widgets),
1129 .controls = cs42l56_snd_controls, 1129 .dapm_routes = cs42l56_audio_map,
1130 .num_controls = ARRAY_SIZE(cs42l56_snd_controls), 1130 .num_dapm_routes = ARRAY_SIZE(cs42l56_audio_map),
1131 },
1131}; 1132};
1132 1133
1133static const struct regmap_config cs42l56_regmap = { 1134static const struct regmap_config cs42l56_regmap = {
diff --git a/sound/soc/codecs/cs42l73.c b/sound/soc/codecs/cs42l73.c
index 42a8fd4e1f9b..71ba5605495f 100644
--- a/sound/soc/codecs/cs42l73.c
+++ b/sound/soc/codecs/cs42l73.c
@@ -794,7 +794,7 @@ struct cs42l73_mclk_div {
794 u8 mmcc; 794 u8 mmcc;
795}; 795};
796 796
797static struct cs42l73_mclk_div cs42l73_mclk_coeffs[] = { 797static const struct cs42l73_mclk_div cs42l73_mclk_coeffs[] = {
798 /* MCLK, Sample Rate, xMMCC[5:0] */ 798 /* MCLK, Sample Rate, xMMCC[5:0] */
799 {5644800, 11025, 0x30}, 799 {5644800, 11025, 0x30},
800 {5644800, 22050, 0x20}, 800 {5644800, 22050, 0x20},
@@ -844,7 +844,7 @@ struct cs42l73_mclkx_div {
844 u8 mclkdiv; 844 u8 mclkdiv;
845}; 845};
846 846
847static struct cs42l73_mclkx_div cs42l73_mclkx_coeffs[] = { 847static const struct cs42l73_mclkx_div cs42l73_mclkx_coeffs[] = {
848 {5644800, 1, 0}, /* 5644800 */ 848 {5644800, 1, 0}, /* 5644800 */
849 {6000000, 1, 0}, /* 6000000 */ 849 {6000000, 1, 0}, /* 6000000 */
850 {6144000, 1, 0}, /* 6144000 */ 850 {6144000, 1, 0}, /* 6144000 */
@@ -1257,13 +1257,14 @@ static const struct snd_soc_codec_driver soc_codec_dev_cs42l73 = {
1257 .set_bias_level = cs42l73_set_bias_level, 1257 .set_bias_level = cs42l73_set_bias_level,
1258 .suspend_bias_off = true, 1258 .suspend_bias_off = true,
1259 1259
1260 .dapm_widgets = cs42l73_dapm_widgets, 1260 .component_driver = {
1261 .num_dapm_widgets = ARRAY_SIZE(cs42l73_dapm_widgets), 1261 .controls = cs42l73_snd_controls,
1262 .dapm_routes = cs42l73_audio_map, 1262 .num_controls = ARRAY_SIZE(cs42l73_snd_controls),
1263 .num_dapm_routes = ARRAY_SIZE(cs42l73_audio_map), 1263 .dapm_widgets = cs42l73_dapm_widgets,
1264 1264 .num_dapm_widgets = ARRAY_SIZE(cs42l73_dapm_widgets),
1265 .controls = cs42l73_snd_controls, 1265 .dapm_routes = cs42l73_audio_map,
1266 .num_controls = ARRAY_SIZE(cs42l73_snd_controls), 1266 .num_dapm_routes = ARRAY_SIZE(cs42l73_audio_map),
1267 },
1267}; 1268};
1268 1269
1269static const struct regmap_config cs42l73_regmap = { 1270static const struct regmap_config cs42l73_regmap = {
diff --git a/sound/soc/codecs/cs42xx8.c b/sound/soc/codecs/cs42xx8.c
index 1179101b2b05..b4d87379d2bc 100644
--- a/sound/soc/codecs/cs42xx8.c
+++ b/sound/soc/codecs/cs42xx8.c
@@ -411,12 +411,14 @@ static const struct snd_soc_codec_driver cs42xx8_driver = {
411 .probe = cs42xx8_codec_probe, 411 .probe = cs42xx8_codec_probe,
412 .idle_bias_off = true, 412 .idle_bias_off = true,
413 413
414 .controls = cs42xx8_snd_controls, 414 .component_driver = {
415 .num_controls = ARRAY_SIZE(cs42xx8_snd_controls), 415 .controls = cs42xx8_snd_controls,
416 .dapm_widgets = cs42xx8_dapm_widgets, 416 .num_controls = ARRAY_SIZE(cs42xx8_snd_controls),
417 .num_dapm_widgets = ARRAY_SIZE(cs42xx8_dapm_widgets), 417 .dapm_widgets = cs42xx8_dapm_widgets,
418 .dapm_routes = cs42xx8_dapm_routes, 418 .num_dapm_widgets = ARRAY_SIZE(cs42xx8_dapm_widgets),
419 .num_dapm_routes = ARRAY_SIZE(cs42xx8_dapm_routes), 419 .dapm_routes = cs42xx8_dapm_routes,
420 .num_dapm_routes = ARRAY_SIZE(cs42xx8_dapm_routes),
421 },
420}; 422};
421 423
422const struct cs42xx8_driver_data cs42448_data = { 424const struct cs42xx8_driver_data cs42448_data = {
diff --git a/sound/soc/codecs/cs4349.c b/sound/soc/codecs/cs4349.c
index 0ac8fc5ed4ae..231ca935cdf3 100644
--- a/sound/soc/codecs/cs4349.c
+++ b/sound/soc/codecs/cs4349.c
@@ -256,13 +256,14 @@ static struct snd_soc_dai_driver cs4349_dai = {
256}; 256};
257 257
258static struct snd_soc_codec_driver soc_codec_dev_cs4349 = { 258static struct snd_soc_codec_driver soc_codec_dev_cs4349 = {
259 .controls = cs4349_snd_controls, 259 .component_driver = {
260 .num_controls = ARRAY_SIZE(cs4349_snd_controls), 260 .controls = cs4349_snd_controls,
261 261 .num_controls = ARRAY_SIZE(cs4349_snd_controls),
262 .dapm_widgets = cs4349_dapm_widgets, 262 .dapm_widgets = cs4349_dapm_widgets,
263 .num_dapm_widgets = ARRAY_SIZE(cs4349_dapm_widgets), 263 .num_dapm_widgets = ARRAY_SIZE(cs4349_dapm_widgets),
264 .dapm_routes = cs4349_routes, 264 .dapm_routes = cs4349_routes,
265 .num_dapm_routes = ARRAY_SIZE(cs4349_routes), 265 .num_dapm_routes = ARRAY_SIZE(cs4349_routes),
266 },
266}; 267};
267 268
268static const struct regmap_config cs4349_regmap = { 269static const struct regmap_config cs4349_regmap = {
diff --git a/sound/soc/codecs/cs47l24.c b/sound/soc/codecs/cs47l24.c
index 954a4f5d3338..5b22564f037c 100644
--- a/sound/soc/codecs/cs47l24.c
+++ b/sound/soc/codecs/cs47l24.c
@@ -746,6 +746,16 @@ static const struct snd_soc_dapm_route cs47l24_dapm_routes[] = {
746 { "IN2L", NULL, "SYSCLK" }, 746 { "IN2L", NULL, "SYSCLK" },
747 { "IN2R", NULL, "SYSCLK" }, 747 { "IN2R", NULL, "SYSCLK" },
748 748
749 { "ASRC1L", NULL, "SYSCLK" },
750 { "ASRC1R", NULL, "SYSCLK" },
751 { "ASRC2L", NULL, "SYSCLK" },
752 { "ASRC2R", NULL, "SYSCLK" },
753
754 { "ASRC1L", NULL, "ASYNCCLK" },
755 { "ASRC1R", NULL, "ASYNCCLK" },
756 { "ASRC2L", NULL, "ASYNCCLK" },
757 { "ASRC2R", NULL, "ASYNCCLK" },
758
749 { "MICBIAS1", NULL, "MICVDD" }, 759 { "MICBIAS1", NULL, "MICVDD" },
750 { "MICBIAS2", NULL, "MICVDD" }, 760 { "MICBIAS2", NULL, "MICVDD" },
751 761
@@ -804,7 +814,6 @@ static const struct snd_soc_dapm_route cs47l24_dapm_routes[] = {
804 { "AIF3 Capture", NULL, "SYSCLK" }, 814 { "AIF3 Capture", NULL, "SYSCLK" },
805 815
806 { "Voice Control DSP", NULL, "DSP3" }, 816 { "Voice Control DSP", NULL, "DSP3" },
807 { "Voice Control DSP", NULL, "SYSCLK" },
808 817
809 { "IN1L PGA", NULL, "IN1L" }, 818 { "IN1L PGA", NULL, "IN1L" },
810 { "IN1R PGA", NULL, "IN1R" }, 819 { "IN1R PGA", NULL, "IN1R" },
@@ -813,7 +822,6 @@ static const struct snd_soc_dapm_route cs47l24_dapm_routes[] = {
813 { "IN2R PGA", NULL, "IN2R" }, 822 { "IN2R PGA", NULL, "IN2R" },
814 823
815 { "Audio Trace DSP", NULL, "DSP2" }, 824 { "Audio Trace DSP", NULL, "DSP2" },
816 { "Audio Trace DSP", NULL, "SYSCLK" },
817 825
818 ARIZONA_MIXER_ROUTES("OUT1L", "HPOUT1L"), 826 ARIZONA_MIXER_ROUTES("OUT1L", "HPOUT1L"),
819 ARIZONA_MIXER_ROUTES("OUT1R", "HPOUT1R"), 827 ARIZONA_MIXER_ROUTES("OUT1R", "HPOUT1R"),
@@ -1190,12 +1198,14 @@ static struct snd_soc_codec_driver soc_codec_dev_cs47l24 = {
1190 .set_sysclk = arizona_set_sysclk, 1198 .set_sysclk = arizona_set_sysclk,
1191 .set_pll = cs47l24_set_fll, 1199 .set_pll = cs47l24_set_fll,
1192 1200
1193 .controls = cs47l24_snd_controls, 1201 .component_driver = {
1194 .num_controls = ARRAY_SIZE(cs47l24_snd_controls), 1202 .controls = cs47l24_snd_controls,
1195 .dapm_widgets = cs47l24_dapm_widgets, 1203 .num_controls = ARRAY_SIZE(cs47l24_snd_controls),
1196 .num_dapm_widgets = ARRAY_SIZE(cs47l24_dapm_widgets), 1204 .dapm_widgets = cs47l24_dapm_widgets,
1197 .dapm_routes = cs47l24_dapm_routes, 1205 .num_dapm_widgets = ARRAY_SIZE(cs47l24_dapm_widgets),
1198 .num_dapm_routes = ARRAY_SIZE(cs47l24_dapm_routes), 1206 .dapm_routes = cs47l24_dapm_routes,
1207 .num_dapm_routes = ARRAY_SIZE(cs47l24_dapm_routes),
1208 },
1199}; 1209};
1200 1210
1201static struct snd_compr_ops cs47l24_compr_ops = { 1211static struct snd_compr_ops cs47l24_compr_ops = {
diff --git a/sound/soc/codecs/cs53l30.c b/sound/soc/codecs/cs53l30.c
index 2c0d9c430a8c..cb47fb595ff4 100644
--- a/sound/soc/codecs/cs53l30.c
+++ b/sound/soc/codecs/cs53l30.c
@@ -466,7 +466,7 @@ struct cs53l30_mclk_div {
466 u8 mclk_int_scale; 466 u8 mclk_int_scale;
467}; 467};
468 468
469static struct cs53l30_mclk_div cs53l30_mclk_coeffs[] = { 469static const struct cs53l30_mclk_div cs53l30_mclk_coeffs[] = {
470 /* NOTE: Enable MCLK_INT_SCALE to save power. */ 470 /* NOTE: Enable MCLK_INT_SCALE to save power. */
471 471
472 /* MCLK, Sample Rate, asp_rate, internal_fs_ratio, mclk_int_scale */ 472 /* MCLK, Sample Rate, asp_rate, internal_fs_ratio, mclk_int_scale */
@@ -511,7 +511,7 @@ struct cs53l30_mclkx_div {
511 u8 mclkdiv; 511 u8 mclkdiv;
512}; 512};
513 513
514static struct cs53l30_mclkx_div cs53l30_mclkx_coeffs[] = { 514static const struct cs53l30_mclkx_div cs53l30_mclkx_coeffs[] = {
515 {5644800, 1, CS53L30_MCLK_DIV_BY_1}, 515 {5644800, 1, CS53L30_MCLK_DIV_BY_1},
516 {6000000, 1, CS53L30_MCLK_DIV_BY_1}, 516 {6000000, 1, CS53L30_MCLK_DIV_BY_1},
517 {6144000, 1, CS53L30_MCLK_DIV_BY_1}, 517 {6144000, 1, CS53L30_MCLK_DIV_BY_1},
@@ -897,13 +897,14 @@ static struct snd_soc_codec_driver cs53l30_driver = {
897 .set_bias_level = cs53l30_set_bias_level, 897 .set_bias_level = cs53l30_set_bias_level,
898 .idle_bias_off = true, 898 .idle_bias_off = true,
899 899
900 .dapm_widgets = cs53l30_dapm_widgets, 900 .component_driver = {
901 .num_dapm_widgets = ARRAY_SIZE(cs53l30_dapm_widgets), 901 .controls = cs53l30_snd_controls,
902 .dapm_routes = cs53l30_dapm_routes, 902 .num_controls = ARRAY_SIZE(cs53l30_snd_controls),
903 .num_dapm_routes = ARRAY_SIZE(cs53l30_dapm_routes), 903 .dapm_widgets = cs53l30_dapm_widgets,
904 904 .num_dapm_widgets = ARRAY_SIZE(cs53l30_dapm_widgets),
905 .controls = cs53l30_snd_controls, 905 .dapm_routes = cs53l30_dapm_routes,
906 .num_controls = ARRAY_SIZE(cs53l30_snd_controls), 906 .num_dapm_routes = ARRAY_SIZE(cs53l30_dapm_routes),
907 },
907}; 908};
908 909
909static struct regmap_config cs53l30_regmap = { 910static struct regmap_config cs53l30_regmap = {
@@ -999,8 +1000,8 @@ static int cs53l30_i2c_probe(struct i2c_client *client,
999 /* Check if MCLK provided */ 1000 /* Check if MCLK provided */
1000 cs53l30->mclk = devm_clk_get(dev, "mclk"); 1001 cs53l30->mclk = devm_clk_get(dev, "mclk");
1001 if (IS_ERR(cs53l30->mclk)) { 1002 if (IS_ERR(cs53l30->mclk)) {
1002 if (PTR_ERR(cs53l30->mclk) == -EPROBE_DEFER) { 1003 if (PTR_ERR(cs53l30->mclk) != -ENOENT) {
1003 ret = -EPROBE_DEFER; 1004 ret = PTR_ERR(cs53l30->mclk);
1004 goto error; 1005 goto error;
1005 } 1006 }
1006 /* Otherwise mark the mclk pointer to NULL */ 1007 /* Otherwise mark the mclk pointer to NULL */
diff --git a/sound/soc/codecs/cx20442.c b/sound/soc/codecs/cx20442.c
index fb3885fe0afb..2c12471e42a6 100644
--- a/sound/soc/codecs/cx20442.c
+++ b/sound/soc/codecs/cx20442.c
@@ -407,10 +407,12 @@ static struct snd_soc_codec_driver cx20442_codec_dev = {
407 .reg_word_size = sizeof(u8), 407 .reg_word_size = sizeof(u8),
408 .read = cx20442_read_reg_cache, 408 .read = cx20442_read_reg_cache,
409 .write = cx20442_write, 409 .write = cx20442_write,
410 .dapm_widgets = cx20442_dapm_widgets, 410 .component_driver = {
411 .num_dapm_widgets = ARRAY_SIZE(cx20442_dapm_widgets), 411 .dapm_widgets = cx20442_dapm_widgets,
412 .dapm_routes = cx20442_audio_map, 412 .num_dapm_widgets = ARRAY_SIZE(cx20442_dapm_widgets),
413 .num_dapm_routes = ARRAY_SIZE(cx20442_audio_map), 413 .dapm_routes = cx20442_audio_map,
414 .num_dapm_routes = ARRAY_SIZE(cx20442_audio_map),
415 },
414}; 416};
415 417
416static int cx20442_platform_probe(struct platform_device *pdev) 418static int cx20442_platform_probe(struct platform_device *pdev)
diff --git a/sound/soc/codecs/da7210.c b/sound/soc/codecs/da7210.c
index af23a61b7b28..17053dfc94cf 100644
--- a/sound/soc/codecs/da7210.c
+++ b/sound/soc/codecs/da7210.c
@@ -1167,13 +1167,14 @@ static int da7210_probe(struct snd_soc_codec *codec)
1167static struct snd_soc_codec_driver soc_codec_dev_da7210 = { 1167static struct snd_soc_codec_driver soc_codec_dev_da7210 = {
1168 .probe = da7210_probe, 1168 .probe = da7210_probe,
1169 1169
1170 .controls = da7210_snd_controls, 1170 .component_driver = {
1171 .num_controls = ARRAY_SIZE(da7210_snd_controls), 1171 .controls = da7210_snd_controls,
1172 1172 .num_controls = ARRAY_SIZE(da7210_snd_controls),
1173 .dapm_widgets = da7210_dapm_widgets, 1173 .dapm_widgets = da7210_dapm_widgets,
1174 .num_dapm_widgets = ARRAY_SIZE(da7210_dapm_widgets), 1174 .num_dapm_widgets = ARRAY_SIZE(da7210_dapm_widgets),
1175 .dapm_routes = da7210_audio_map, 1175 .dapm_routes = da7210_audio_map,
1176 .num_dapm_routes = ARRAY_SIZE(da7210_audio_map), 1176 .num_dapm_routes = ARRAY_SIZE(da7210_audio_map),
1177 },
1177}; 1178};
1178 1179
1179#if IS_ENABLED(CONFIG_I2C) 1180#if IS_ENABLED(CONFIG_I2C)
diff --git a/sound/soc/codecs/da7213.c b/sound/soc/codecs/da7213.c
index bcf1834c5648..12da55882c06 100644
--- a/sound/soc/codecs/da7213.c
+++ b/sound/soc/codecs/da7213.c
@@ -750,11 +750,18 @@ static int da7213_dai_event(struct snd_soc_dapm_widget *w,
750 snd_soc_update_bits(codec, DA7213_PC_COUNT, 750 snd_soc_update_bits(codec, DA7213_PC_COUNT,
751 DA7213_PC_FREERUN_MASK, 0); 751 DA7213_PC_FREERUN_MASK, 0);
752 752
753 /* Slave mode, if SRM not enabled no need for status checks */ 753 /* If SRM not enabled then nothing more to do */
754 pll_ctrl = snd_soc_read(codec, DA7213_PLL_CTRL); 754 pll_ctrl = snd_soc_read(codec, DA7213_PLL_CTRL);
755 if (!(pll_ctrl & DA7213_PLL_SRM_EN)) 755 if (!(pll_ctrl & DA7213_PLL_SRM_EN))
756 return 0; 756 return 0;
757 757
758 /* Assist 32KHz mode PLL lock */
759 if (pll_ctrl & DA7213_PLL_32K_MODE) {
760 snd_soc_write(codec, 0xF0, 0x8B);
761 snd_soc_write(codec, 0xF2, 0x03);
762 snd_soc_write(codec, 0xF0, 0x00);
763 }
764
758 /* Check SRM has locked */ 765 /* Check SRM has locked */
759 do { 766 do {
760 pll_status = snd_soc_read(codec, DA7213_PLL_STATUS); 767 pll_status = snd_soc_read(codec, DA7213_PLL_STATUS);
@@ -771,6 +778,14 @@ static int da7213_dai_event(struct snd_soc_dapm_widget *w,
771 778
772 return 0; 779 return 0;
773 case SND_SOC_DAPM_POST_PMD: 780 case SND_SOC_DAPM_POST_PMD:
781 /* Revert 32KHz PLL lock udpates if applied previously */
782 pll_ctrl = snd_soc_read(codec, DA7213_PLL_CTRL);
783 if (pll_ctrl & DA7213_PLL_32K_MODE) {
784 snd_soc_write(codec, 0xF0, 0x8B);
785 snd_soc_write(codec, 0xF2, 0x01);
786 snd_soc_write(codec, 0xF0, 0x00);
787 }
788
774 /* PC free-running */ 789 /* PC free-running */
775 snd_soc_update_bits(codec, DA7213_PC_COUNT, 790 snd_soc_update_bits(codec, DA7213_PC_COUNT,
776 DA7213_PC_FREERUN_MASK, 791 DA7213_PC_FREERUN_MASK,
@@ -1297,10 +1312,13 @@ static int da7213_set_dai_sysclk(struct snd_soc_dai *codec_dai,
1297 1312
1298 switch (clk_id) { 1313 switch (clk_id) {
1299 case DA7213_CLKSRC_MCLK: 1314 case DA7213_CLKSRC_MCLK:
1300 da7213->mclk_squarer_en = false; 1315 snd_soc_update_bits(codec, DA7213_PLL_CTRL,
1316 DA7213_PLL_MCLK_SQR_EN, 0);
1301 break; 1317 break;
1302 case DA7213_CLKSRC_MCLK_SQR: 1318 case DA7213_CLKSRC_MCLK_SQR:
1303 da7213->mclk_squarer_en = true; 1319 snd_soc_update_bits(codec, DA7213_PLL_CTRL,
1320 DA7213_PLL_MCLK_SQR_EN,
1321 DA7213_PLL_MCLK_SQR_EN);
1304 break; 1322 break;
1305 default: 1323 default:
1306 dev_err(codec_dai->dev, "Unknown clock source %d\n", clk_id); 1324 dev_err(codec_dai->dev, "Unknown clock source %d\n", clk_id);
@@ -1324,7 +1342,7 @@ static int da7213_set_dai_sysclk(struct snd_soc_dai *codec_dai,
1324 return 0; 1342 return 0;
1325} 1343}
1326 1344
1327/* Supported PLL input frequencies are 5MHz - 54MHz. */ 1345/* Supported PLL input frequencies are 32KHz, 5MHz - 54MHz. */
1328static int da7213_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id, 1346static int da7213_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
1329 int source, unsigned int fref, unsigned int fout) 1347 int source, unsigned int fref, unsigned int fout)
1330{ 1348{
@@ -1336,22 +1354,26 @@ static int da7213_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
1336 u32 freq_ref; 1354 u32 freq_ref;
1337 u64 frac_div; 1355 u64 frac_div;
1338 1356
1339 /* Reset PLL configuration */
1340 snd_soc_write(codec, DA7213_PLL_CTRL, 0);
1341
1342 pll_ctrl = 0;
1343
1344 /* Workout input divider based on MCLK rate */ 1357 /* Workout input divider based on MCLK rate */
1345 if (da7213->mclk_rate == 32768) { 1358 if (da7213->mclk_rate == 32768) {
1359 if (!da7213->master) {
1360 dev_err(codec->dev,
1361 "32KHz only valid if codec is clock master\n");
1362 return -EINVAL;
1363 }
1364
1346 /* 32KHz PLL Mode */ 1365 /* 32KHz PLL Mode */
1347 indiv_bits = DA7213_PLL_INDIV_9_TO_18_MHZ; 1366 indiv_bits = DA7213_PLL_INDIV_9_TO_18_MHZ;
1348 indiv = DA7213_PLL_INDIV_9_TO_18_MHZ_VAL; 1367 indiv = DA7213_PLL_INDIV_9_TO_18_MHZ_VAL;
1368 source = DA7213_SYSCLK_PLL_32KHZ;
1349 freq_ref = 3750000; 1369 freq_ref = 3750000;
1350 pll_ctrl |= DA7213_PLL_32K_MODE; 1370
1351 } else { 1371 } else {
1352 /* 5 - 54MHz MCLK */
1353 if (da7213->mclk_rate < 5000000) { 1372 if (da7213->mclk_rate < 5000000) {
1354 goto pll_err; 1373 dev_err(codec->dev,
1374 "PLL input clock %d below valid range\n",
1375 da7213->mclk_rate);
1376 return -EINVAL;
1355 } else if (da7213->mclk_rate <= 9000000) { 1377 } else if (da7213->mclk_rate <= 9000000) {
1356 indiv_bits = DA7213_PLL_INDIV_5_TO_9_MHZ; 1378 indiv_bits = DA7213_PLL_INDIV_5_TO_9_MHZ;
1357 indiv = DA7213_PLL_INDIV_5_TO_9_MHZ_VAL; 1379 indiv = DA7213_PLL_INDIV_5_TO_9_MHZ_VAL;
@@ -1365,32 +1387,44 @@ static int da7213_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
1365 indiv_bits = DA7213_PLL_INDIV_36_TO_54_MHZ; 1387 indiv_bits = DA7213_PLL_INDIV_36_TO_54_MHZ;
1366 indiv = DA7213_PLL_INDIV_36_TO_54_MHZ_VAL; 1388 indiv = DA7213_PLL_INDIV_36_TO_54_MHZ_VAL;
1367 } else { 1389 } else {
1368 goto pll_err; 1390 dev_err(codec->dev,
1391 "PLL input clock %d above valid range\n",
1392 da7213->mclk_rate);
1393 return -EINVAL;
1369 } 1394 }
1370 freq_ref = (da7213->mclk_rate / indiv); 1395 freq_ref = (da7213->mclk_rate / indiv);
1371 } 1396 }
1372 1397
1373 pll_ctrl |= indiv_bits; 1398 pll_ctrl = indiv_bits;
1374 1399
1375 /* PLL Bypass mode */ 1400 /* Configure PLL */
1376 if (source == DA7213_SYSCLK_MCLK) { 1401 switch (source) {
1377 snd_soc_write(codec, DA7213_PLL_CTRL, pll_ctrl); 1402 case DA7213_SYSCLK_MCLK:
1403 snd_soc_update_bits(codec, DA7213_PLL_CTRL,
1404 DA7213_PLL_INDIV_MASK |
1405 DA7213_PLL_MODE_MASK, pll_ctrl);
1378 return 0; 1406 return 0;
1379 } 1407 case DA7213_SYSCLK_PLL:
1408 break;
1409 case DA7213_SYSCLK_PLL_SRM:
1410 pll_ctrl |= DA7213_PLL_SRM_EN;
1411 fout = DA7213_PLL_FREQ_OUT_94310400;
1412 break;
1413 case DA7213_SYSCLK_PLL_32KHZ:
1414 if (da7213->mclk_rate != 32768) {
1415 dev_err(codec->dev,
1416 "32KHz mode only valid with 32KHz MCLK\n");
1417 return -EINVAL;
1418 }
1380 1419
1381 /* 1420 pll_ctrl |= DA7213_PLL_32K_MODE | DA7213_PLL_SRM_EN;
1382 * If Codec is slave and SRM enabled,
1383 * freq_out is (98304000 + 90316800)/2 = 94310400
1384 */
1385 if (!da7213->master && da7213->srm_en) {
1386 fout = DA7213_PLL_FREQ_OUT_94310400; 1421 fout = DA7213_PLL_FREQ_OUT_94310400;
1387 pll_ctrl |= DA7213_PLL_SRM_EN; 1422 break;
1423 default:
1424 dev_err(codec->dev, "Invalid PLL config\n");
1425 return -EINVAL;
1388 } 1426 }
1389 1427
1390 /* Enable MCLK squarer if required */
1391 if (da7213->mclk_squarer_en)
1392 pll_ctrl |= DA7213_PLL_MCLK_SQR_EN;
1393
1394 /* Calculate dividers for PLL */ 1428 /* Calculate dividers for PLL */
1395 pll_integer = fout / freq_ref; 1429 pll_integer = fout / freq_ref;
1396 frac_div = (u64)(fout % freq_ref) * 8192ULL; 1430 frac_div = (u64)(fout % freq_ref) * 8192ULL;
@@ -1405,14 +1439,19 @@ static int da7213_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
1405 1439
1406 /* Enable PLL */ 1440 /* Enable PLL */
1407 pll_ctrl |= DA7213_PLL_EN; 1441 pll_ctrl |= DA7213_PLL_EN;
1408 snd_soc_write(codec, DA7213_PLL_CTRL, pll_ctrl); 1442 snd_soc_update_bits(codec, DA7213_PLL_CTRL,
1443 DA7213_PLL_INDIV_MASK | DA7213_PLL_MODE_MASK,
1444 pll_ctrl);
1445
1446 /* Assist 32KHz mode PLL lock */
1447 if (source == DA7213_SYSCLK_PLL_32KHZ) {
1448 snd_soc_write(codec, 0xF0, 0x8B);
1449 snd_soc_write(codec, 0xF1, 0x03);
1450 snd_soc_write(codec, 0xF1, 0x01);
1451 snd_soc_write(codec, 0xF0, 0x00);
1452 }
1409 1453
1410 return 0; 1454 return 0;
1411
1412pll_err:
1413 dev_err(codec_dai->dev, "Unsupported PLL input frequency %d\n",
1414 da7213->mclk_rate);
1415 return -EINVAL;
1416} 1455}
1417 1456
1418/* DAI operations */ 1457/* DAI operations */
@@ -1454,11 +1493,10 @@ static int da7213_set_bias_level(struct snd_soc_codec *codec,
1454 1493
1455 switch (level) { 1494 switch (level) {
1456 case SND_SOC_BIAS_ON: 1495 case SND_SOC_BIAS_ON:
1457 case SND_SOC_BIAS_PREPARE:
1458 break; 1496 break;
1459 case SND_SOC_BIAS_STANDBY: 1497 case SND_SOC_BIAS_PREPARE:
1460 if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF) { 1498 /* Enable MCLK for transition to ON state */
1461 /* MCLK */ 1499 if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_STANDBY) {
1462 if (da7213->mclk) { 1500 if (da7213->mclk) {
1463 ret = clk_prepare_enable(da7213->mclk); 1501 ret = clk_prepare_enable(da7213->mclk);
1464 if (ret) { 1502 if (ret) {
@@ -1467,21 +1505,24 @@ static int da7213_set_bias_level(struct snd_soc_codec *codec,
1467 return ret; 1505 return ret;
1468 } 1506 }
1469 } 1507 }
1470 1508 }
1509 break;
1510 case SND_SOC_BIAS_STANDBY:
1511 if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF) {
1471 /* Enable VMID reference & master bias */ 1512 /* Enable VMID reference & master bias */
1472 snd_soc_update_bits(codec, DA7213_REFERENCES, 1513 snd_soc_update_bits(codec, DA7213_REFERENCES,
1473 DA7213_VMID_EN | DA7213_BIAS_EN, 1514 DA7213_VMID_EN | DA7213_BIAS_EN,
1474 DA7213_VMID_EN | DA7213_BIAS_EN); 1515 DA7213_VMID_EN | DA7213_BIAS_EN);
1516 } else {
1517 /* Remove MCLK */
1518 if (da7213->mclk)
1519 clk_disable_unprepare(da7213->mclk);
1475 } 1520 }
1476 break; 1521 break;
1477 case SND_SOC_BIAS_OFF: 1522 case SND_SOC_BIAS_OFF:
1478 /* Disable VMID reference & master bias */ 1523 /* Disable VMID reference & master bias */
1479 snd_soc_update_bits(codec, DA7213_REFERENCES, 1524 snd_soc_update_bits(codec, DA7213_REFERENCES,
1480 DA7213_VMID_EN | DA7213_BIAS_EN, 0); 1525 DA7213_VMID_EN | DA7213_BIAS_EN, 0);
1481
1482 /* MCLK */
1483 if (da7213->mclk)
1484 clk_disable_unprepare(da7213->mclk);
1485 break; 1526 break;
1486 } 1527 }
1487 return 0; 1528 return 0;
@@ -1605,9 +1646,6 @@ static int da7213_probe(struct snd_soc_codec *codec)
1605 DA7213_ALC_CALIB_MODE_MAN, 0); 1646 DA7213_ALC_CALIB_MODE_MAN, 0);
1606 da7213->alc_calib_auto = true; 1647 da7213->alc_calib_auto = true;
1607 1648
1608 /* Default to using SRM for slave mode */
1609 da7213->srm_en = true;
1610
1611 /* Default PC counter to free-running */ 1649 /* Default PC counter to free-running */
1612 snd_soc_update_bits(codec, DA7213_PC_COUNT, DA7213_PC_FREERUN_MASK, 1650 snd_soc_update_bits(codec, DA7213_PC_COUNT, DA7213_PC_FREERUN_MASK,
1613 DA7213_PC_FREERUN_MASK); 1651 DA7213_PC_FREERUN_MASK);
@@ -1740,13 +1778,14 @@ static struct snd_soc_codec_driver soc_codec_dev_da7213 = {
1740 .probe = da7213_probe, 1778 .probe = da7213_probe,
1741 .set_bias_level = da7213_set_bias_level, 1779 .set_bias_level = da7213_set_bias_level,
1742 1780
1743 .controls = da7213_snd_controls, 1781 .component_driver = {
1744 .num_controls = ARRAY_SIZE(da7213_snd_controls), 1782 .controls = da7213_snd_controls,
1745 1783 .num_controls = ARRAY_SIZE(da7213_snd_controls),
1746 .dapm_widgets = da7213_dapm_widgets, 1784 .dapm_widgets = da7213_dapm_widgets,
1747 .num_dapm_widgets = ARRAY_SIZE(da7213_dapm_widgets), 1785 .num_dapm_widgets = ARRAY_SIZE(da7213_dapm_widgets),
1748 .dapm_routes = da7213_audio_map, 1786 .dapm_routes = da7213_audio_map,
1749 .num_dapm_routes = ARRAY_SIZE(da7213_audio_map), 1787 .num_dapm_routes = ARRAY_SIZE(da7213_audio_map),
1788 },
1750}; 1789};
1751 1790
1752static const struct regmap_config da7213_regmap_config = { 1791static const struct regmap_config da7213_regmap_config = {
diff --git a/sound/soc/codecs/da7213.h b/sound/soc/codecs/da7213.h
index fbb7a356a501..16ef56f77cd4 100644
--- a/sound/soc/codecs/da7213.h
+++ b/sound/soc/codecs/da7213.h
@@ -172,6 +172,7 @@
172#define DA7213_PLL_32K_MODE (0x1 << 5) 172#define DA7213_PLL_32K_MODE (0x1 << 5)
173#define DA7213_PLL_SRM_EN (0x1 << 6) 173#define DA7213_PLL_SRM_EN (0x1 << 6)
174#define DA7213_PLL_EN (0x1 << 7) 174#define DA7213_PLL_EN (0x1 << 7)
175#define DA7213_PLL_MODE_MASK (0x7 << 5)
175 176
176/* DA7213_DAI_CLK_MODE = 0x28 */ 177/* DA7213_DAI_CLK_MODE = 0x28 */
177#define DA7213_DAI_BCLKS_PER_WCLK_32 (0x0 << 0) 178#define DA7213_DAI_BCLKS_PER_WCLK_32 (0x0 << 0)
@@ -499,8 +500,6 @@
499#define DA7213_ALC_AVG_ITERATIONS 5 500#define DA7213_ALC_AVG_ITERATIONS 5
500 501
501/* PLL related */ 502/* PLL related */
502#define DA7213_SYSCLK_MCLK 0
503#define DA7213_SYSCLK_PLL 1
504#define DA7213_PLL_FREQ_OUT_90316800 90316800 503#define DA7213_PLL_FREQ_OUT_90316800 90316800
505#define DA7213_PLL_FREQ_OUT_98304000 98304000 504#define DA7213_PLL_FREQ_OUT_98304000 98304000
506#define DA7213_PLL_FREQ_OUT_94310400 94310400 505#define DA7213_PLL_FREQ_OUT_94310400 94310400
@@ -515,6 +514,13 @@ enum da7213_clk_src {
515 DA7213_CLKSRC_MCLK_SQR, 514 DA7213_CLKSRC_MCLK_SQR,
516}; 515};
517 516
517enum da7213_sys_clk {
518 DA7213_SYSCLK_MCLK = 0,
519 DA7213_SYSCLK_PLL,
520 DA7213_SYSCLK_PLL_SRM,
521 DA7213_SYSCLK_PLL_32KHZ
522};
523
518/* Codec private data */ 524/* Codec private data */
519struct da7213_priv { 525struct da7213_priv {
520 struct regmap *regmap; 526 struct regmap *regmap;
@@ -522,8 +528,6 @@ struct da7213_priv {
522 unsigned int mclk_rate; 528 unsigned int mclk_rate;
523 int clk_src; 529 int clk_src;
524 bool master; 530 bool master;
525 bool mclk_squarer_en;
526 bool srm_en;
527 bool alc_calib_auto; 531 bool alc_calib_auto;
528 bool alc_en; 532 bool alc_en;
529 struct da7213_platform_data *pdata; 533 struct da7213_platform_data *pdata;
diff --git a/sound/soc/codecs/da7218.c b/sound/soc/codecs/da7218.c
index 99ce23e113bf..c69e97654fc6 100644
--- a/sound/soc/codecs/da7218.c
+++ b/sound/soc/codecs/da7218.c
@@ -1819,7 +1819,7 @@ static int da7218_set_dai_sysclk(struct snd_soc_dai *codec_dai,
1819 if (da7218->mclk_rate == freq) 1819 if (da7218->mclk_rate == freq)
1820 return 0; 1820 return 0;
1821 1821
1822 if (((freq < 2000000) && (freq != 32768)) || (freq > 54000000)) { 1822 if ((freq < 2000000) || (freq > 54000000)) {
1823 dev_err(codec_dai->dev, "Unsupported MCLK value %d\n", 1823 dev_err(codec_dai->dev, "Unsupported MCLK value %d\n",
1824 freq); 1824 freq);
1825 return -EINVAL; 1825 return -EINVAL;
@@ -1866,11 +1866,8 @@ static int da7218_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
1866 u32 freq_ref; 1866 u32 freq_ref;
1867 u64 frac_div; 1867 u64 frac_div;
1868 1868
1869 /* Verify 32KHz, 2MHz - 54MHz MCLK provided, and set input divider */ 1869 /* Verify 2MHz - 54MHz MCLK provided, and set input divider */
1870 if (da7218->mclk_rate == 32768) { 1870 if (da7218->mclk_rate < 2000000) {
1871 indiv_bits = DA7218_PLL_INDIV_9_TO_18_MHZ;
1872 indiv = DA7218_PLL_INDIV_9_TO_18_MHZ_VAL;
1873 } else if (da7218->mclk_rate < 2000000) {
1874 dev_err(codec->dev, "PLL input clock %d below valid range\n", 1871 dev_err(codec->dev, "PLL input clock %d below valid range\n",
1875 da7218->mclk_rate); 1872 da7218->mclk_rate);
1876 return -EINVAL; 1873 return -EINVAL;
@@ -1911,9 +1908,6 @@ static int da7218_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
1911 case DA7218_SYSCLK_PLL_SRM: 1908 case DA7218_SYSCLK_PLL_SRM:
1912 pll_ctrl |= DA7218_PLL_MODE_SRM; 1909 pll_ctrl |= DA7218_PLL_MODE_SRM;
1913 break; 1910 break;
1914 case DA7218_SYSCLK_PLL_32KHZ:
1915 pll_ctrl |= DA7218_PLL_MODE_32KHZ;
1916 break;
1917 default: 1911 default:
1918 dev_err(codec->dev, "Invalid PLL config\n"); 1912 dev_err(codec->dev, "Invalid PLL config\n");
1919 return -EINVAL; 1913 return -EINVAL;
@@ -2589,20 +2583,22 @@ static int da7218_set_bias_level(struct snd_soc_codec *codec,
2589 2583
2590 switch (level) { 2584 switch (level) {
2591 case SND_SOC_BIAS_ON: 2585 case SND_SOC_BIAS_ON:
2592 case SND_SOC_BIAS_PREPARE:
2593 break; 2586 break;
2594 case SND_SOC_BIAS_STANDBY: 2587 case SND_SOC_BIAS_PREPARE:
2595 if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF) { 2588 /* Enable MCLK for transition to ON state */
2596 /* MCLK */ 2589 if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_STANDBY) {
2597 if (da7218->mclk) { 2590 if (da7218->mclk) {
2598 ret = clk_prepare_enable(da7218->mclk); 2591 ret = clk_prepare_enable(da7218->mclk);
2599 if (ret) { 2592 if (ret) {
2600 dev_err(codec->dev, 2593 dev_err(codec->dev, "Failed to enable mclk\n");
2601 "Failed to enable mclk\n");
2602 return ret; 2594 return ret;
2603 } 2595 }
2604 } 2596 }
2597 }
2605 2598
2599 break;
2600 case SND_SOC_BIAS_STANDBY:
2601 if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF) {
2606 /* Master bias */ 2602 /* Master bias */
2607 snd_soc_update_bits(codec, DA7218_REFERENCES, 2603 snd_soc_update_bits(codec, DA7218_REFERENCES,
2608 DA7218_BIAS_EN_MASK, 2604 DA7218_BIAS_EN_MASK,
@@ -2612,6 +2608,10 @@ static int da7218_set_bias_level(struct snd_soc_codec *codec,
2612 snd_soc_update_bits(codec, DA7218_LDO_CTRL, 2608 snd_soc_update_bits(codec, DA7218_LDO_CTRL,
2613 DA7218_LDO_EN_MASK, 2609 DA7218_LDO_EN_MASK,
2614 DA7218_LDO_EN_MASK); 2610 DA7218_LDO_EN_MASK);
2611 } else {
2612 /* Remove MCLK */
2613 if (da7218->mclk)
2614 clk_disable_unprepare(da7218->mclk);
2615 } 2615 }
2616 break; 2616 break;
2617 case SND_SOC_BIAS_OFF: 2617 case SND_SOC_BIAS_OFF:
@@ -2625,10 +2625,6 @@ static int da7218_set_bias_level(struct snd_soc_codec *codec,
2625 snd_soc_update_bits(codec, DA7218_REFERENCES, 2625 snd_soc_update_bits(codec, DA7218_REFERENCES,
2626 DA7218_BIAS_EN_MASK, 0); 2626 DA7218_BIAS_EN_MASK, 0);
2627 } 2627 }
2628
2629 /* MCLK */
2630 if (da7218->mclk)
2631 clk_disable_unprepare(da7218->mclk);
2632 break; 2628 break;
2633 } 2629 }
2634 2630
@@ -3045,13 +3041,14 @@ static struct snd_soc_codec_driver soc_codec_dev_da7218 = {
3045 .resume = da7218_resume, 3041 .resume = da7218_resume,
3046 .set_bias_level = da7218_set_bias_level, 3042 .set_bias_level = da7218_set_bias_level,
3047 3043
3048 .controls = da7218_snd_controls, 3044 .component_driver = {
3049 .num_controls = ARRAY_SIZE(da7218_snd_controls), 3045 .controls = da7218_snd_controls,
3050 3046 .num_controls = ARRAY_SIZE(da7218_snd_controls),
3051 .dapm_widgets = da7218_dapm_widgets, 3047 .dapm_widgets = da7218_dapm_widgets,
3052 .num_dapm_widgets = ARRAY_SIZE(da7218_dapm_widgets), 3048 .num_dapm_widgets = ARRAY_SIZE(da7218_dapm_widgets),
3053 .dapm_routes = da7218_audio_map, 3049 .dapm_routes = da7218_audio_map,
3054 .num_dapm_routes = ARRAY_SIZE(da7218_audio_map), 3050 .num_dapm_routes = ARRAY_SIZE(da7218_audio_map),
3051 },
3055}; 3052};
3056 3053
3057 3054
diff --git a/sound/soc/codecs/da7218.h b/sound/soc/codecs/da7218.h
index 477cd37723cf..4f7ec21069a4 100644
--- a/sound/soc/codecs/da7218.h
+++ b/sound/soc/codecs/da7218.h
@@ -888,7 +888,6 @@
888#define DA7218_PLL_MODE_BYPASS (0x0 << 6) 888#define DA7218_PLL_MODE_BYPASS (0x0 << 6)
889#define DA7218_PLL_MODE_NORMAL (0x1 << 6) 889#define DA7218_PLL_MODE_NORMAL (0x1 << 6)
890#define DA7218_PLL_MODE_SRM (0x2 << 6) 890#define DA7218_PLL_MODE_SRM (0x2 << 6)
891#define DA7218_PLL_MODE_32KHZ (0x3 << 6)
892 891
893/* DA7218_PLL_FRAC_TOP = 0x92 */ 892/* DA7218_PLL_FRAC_TOP = 0x92 */
894#define DA7218_PLL_FBDIV_FRAC_TOP_SHIFT 0 893#define DA7218_PLL_FBDIV_FRAC_TOP_SHIFT 0
@@ -1371,7 +1370,6 @@ enum da7218_sys_clk {
1371 DA7218_SYSCLK_MCLK = 0, 1370 DA7218_SYSCLK_MCLK = 0,
1372 DA7218_SYSCLK_PLL, 1371 DA7218_SYSCLK_PLL,
1373 DA7218_SYSCLK_PLL_SRM, 1372 DA7218_SYSCLK_PLL_SRM,
1374 DA7218_SYSCLK_PLL_32KHZ
1375}; 1373};
1376 1374
1377enum da7218_dev_id { 1375enum da7218_dev_id {
diff --git a/sound/soc/codecs/da7219-aad.c b/sound/soc/codecs/da7219-aad.c
index f0057cd223a4..2b8914dd5990 100644
--- a/sound/soc/codecs/da7219-aad.c
+++ b/sound/soc/codecs/da7219-aad.c
@@ -13,6 +13,7 @@
13 13
14#include <linux/module.h> 14#include <linux/module.h>
15#include <linux/platform_device.h> 15#include <linux/platform_device.h>
16#include <linux/clk.h>
16#include <linux/i2c.h> 17#include <linux/i2c.h>
17#include <linux/property.h> 18#include <linux/property.h>
18#include <linux/pm_wakeirq.h> 19#include <linux/pm_wakeirq.h>
@@ -114,13 +115,38 @@ static void da7219_aad_hptest_work(struct work_struct *work)
114 struct da7219_priv *da7219 = snd_soc_codec_get_drvdata(codec); 115 struct da7219_priv *da7219 = snd_soc_codec_get_drvdata(codec);
115 116
116 u16 tonegen_freq_hptest; 117 u16 tonegen_freq_hptest;
117 u8 accdet_cfg8; 118 u8 pll_srm_sts, gain_ramp_ctrl, accdet_cfg8;
118 int report = 0; 119 int report = 0, ret = 0;
119 120
120 /* Lock DAPM and any Kcontrols that are affected by this test */ 121 /* Lock DAPM and any Kcontrols that are affected by this test */
121 snd_soc_dapm_mutex_lock(dapm); 122 snd_soc_dapm_mutex_lock(dapm);
122 mutex_lock(&da7219->lock); 123 mutex_lock(&da7219->lock);
123 124
125 /* Ensure MCLK is available for HP test procedure */
126 if (da7219->mclk) {
127 ret = clk_prepare_enable(da7219->mclk);
128 if (ret) {
129 dev_err(codec->dev, "Failed to enable mclk - %d\n", ret);
130 mutex_unlock(&da7219->lock);
131 snd_soc_dapm_mutex_unlock(dapm);
132 return;
133 }
134 }
135
136 /*
137 * If MCLK not present, then we're using the internal oscillator and
138 * require different frequency settings to achieve the same result.
139 */
140 pll_srm_sts = snd_soc_read(codec, DA7219_PLL_SRM_STS);
141 if (pll_srm_sts & DA7219_PLL_SRM_STS_MCLK)
142 tonegen_freq_hptest = cpu_to_le16(DA7219_AAD_HPTEST_RAMP_FREQ);
143 else
144 tonegen_freq_hptest = cpu_to_le16(DA7219_AAD_HPTEST_RAMP_FREQ_INT_OSC);
145
146 /* Ensure gain ramping at fastest rate */
147 gain_ramp_ctrl = snd_soc_read(codec, DA7219_GAIN_RAMP_CTRL);
148 snd_soc_write(codec, DA7219_GAIN_RAMP_CTRL, DA7219_GAIN_RAMP_RATE_X8);
149
124 /* Bypass cache so it saves current settings */ 150 /* Bypass cache so it saves current settings */
125 regcache_cache_bypass(da7219->regmap, true); 151 regcache_cache_bypass(da7219->regmap, true);
126 152
@@ -183,9 +209,15 @@ static void da7219_aad_hptest_work(struct work_struct *work)
183 snd_soc_write(codec, DA7219_HP_R_CTRL, 209 snd_soc_write(codec, DA7219_HP_R_CTRL,
184 DA7219_HP_R_AMP_OE_MASK | DA7219_HP_R_AMP_EN_MASK); 210 DA7219_HP_R_AMP_OE_MASK | DA7219_HP_R_AMP_EN_MASK);
185 211
212 /*
213 * If we're running from the internal oscillator then give audio paths
214 * time to settle before running test.
215 */
216 if (!(pll_srm_sts & DA7219_PLL_SRM_STS_MCLK))
217 msleep(DA7219_AAD_HPTEST_INT_OSC_PATH_DELAY);
218
186 /* Configure & start Tone Generator */ 219 /* Configure & start Tone Generator */
187 snd_soc_write(codec, DA7219_TONE_GEN_ON_PER, DA7219_BEEP_ON_PER_MASK); 220 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, 221 regmap_raw_write(da7219->regmap, DA7219_TONE_GEN_FREQ1_L,
190 &tonegen_freq_hptest, sizeof(tonegen_freq_hptest)); 222 &tonegen_freq_hptest, sizeof(tonegen_freq_hptest));
191 snd_soc_update_bits(codec, DA7219_TONE_GEN_CFG2, 223 snd_soc_update_bits(codec, DA7219_TONE_GEN_CFG2,
@@ -244,12 +276,26 @@ static void da7219_aad_hptest_work(struct work_struct *work)
244 snd_soc_update_bits(codec, DA7219_ACCDET_CONFIG_8, 276 snd_soc_update_bits(codec, DA7219_ACCDET_CONFIG_8,
245 DA7219_HPTEST_EN_MASK, 0); 277 DA7219_HPTEST_EN_MASK, 0);
246 278
279 /*
280 * If we're running from the internal oscillator then give audio paths
281 * time to settle before allowing headphones to be driven as required.
282 */
283 if (!(pll_srm_sts & DA7219_PLL_SRM_STS_MCLK))
284 msleep(DA7219_AAD_HPTEST_INT_OSC_PATH_DELAY);
285
286 /* Restore gain ramping rate */
287 snd_soc_write(codec, DA7219_GAIN_RAMP_CTRL, gain_ramp_ctrl);
288
247 /* Drive Headphones/lineout */ 289 /* Drive Headphones/lineout */
248 snd_soc_update_bits(codec, DA7219_HP_L_CTRL, DA7219_HP_L_AMP_OE_MASK, 290 snd_soc_update_bits(codec, DA7219_HP_L_CTRL, DA7219_HP_L_AMP_OE_MASK,
249 DA7219_HP_L_AMP_OE_MASK); 291 DA7219_HP_L_AMP_OE_MASK);
250 snd_soc_update_bits(codec, DA7219_HP_R_CTRL, DA7219_HP_R_AMP_OE_MASK, 292 snd_soc_update_bits(codec, DA7219_HP_R_CTRL, DA7219_HP_R_AMP_OE_MASK,
251 DA7219_HP_R_AMP_OE_MASK); 293 DA7219_HP_R_AMP_OE_MASK);
252 294
295 /* Remove MCLK, if previously enabled */
296 if (da7219->mclk)
297 clk_disable_unprepare(da7219->mclk);
298
253 mutex_unlock(&da7219->lock); 299 mutex_unlock(&da7219->lock);
254 snd_soc_dapm_mutex_unlock(dapm); 300 snd_soc_dapm_mutex_unlock(dapm);
255 301
@@ -751,6 +797,62 @@ static void da7219_aad_handle_pdata(struct snd_soc_codec *codec)
751 797
752 798
753/* 799/*
800 * Suspend/Resume
801 */
802
803void da7219_aad_suspend(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 struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
808 u8 micbias_ctrl;
809
810 if (da7219_aad->jack) {
811 /* Disable jack detection during suspend */
812 snd_soc_update_bits(codec, DA7219_ACCDET_CONFIG_1,
813 DA7219_ACCDET_EN_MASK, 0);
814
815 /*
816 * If we have a 4-pole jack inserted, then micbias will be
817 * enabled. We can disable micbias here, and keep a note to
818 * re-enable it on resume. If jack removal occurred during
819 * suspend then this will be dealt with through the IRQ handler.
820 */
821 if (da7219_aad->jack_inserted) {
822 micbias_ctrl = snd_soc_read(codec, DA7219_MICBIAS_CTRL);
823 if (micbias_ctrl & DA7219_MICBIAS1_EN_MASK) {
824 snd_soc_dapm_disable_pin(dapm, "Mic Bias");
825 snd_soc_dapm_sync(dapm);
826 da7219_aad->micbias_resume_enable = true;
827 }
828 }
829 }
830}
831
832void da7219_aad_resume(struct snd_soc_codec *codec)
833{
834 struct da7219_priv *da7219 = snd_soc_codec_get_drvdata(codec);
835 struct da7219_aad_priv *da7219_aad = da7219->aad;
836 struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
837
838 if (da7219_aad->jack) {
839 /* Re-enable micbias if previously enabled for 4-pole jack */
840 if (da7219_aad->jack_inserted &&
841 da7219_aad->micbias_resume_enable) {
842 snd_soc_dapm_force_enable_pin(dapm, "Mic Bias");
843 snd_soc_dapm_sync(dapm);
844 da7219_aad->micbias_resume_enable = false;
845 }
846
847 /* Re-enable jack detection */
848 snd_soc_update_bits(codec, DA7219_ACCDET_CONFIG_1,
849 DA7219_ACCDET_EN_MASK,
850 DA7219_ACCDET_EN_MASK);
851 }
852}
853
854
855/*
754 * Init/Exit 856 * Init/Exit
755 */ 857 */
756 858
diff --git a/sound/soc/codecs/da7219-aad.h b/sound/soc/codecs/da7219-aad.h
index 4fccf677cd06..117a3d7ccd31 100644
--- a/sound/soc/codecs/da7219-aad.h
+++ b/sound/soc/codecs/da7219-aad.h
@@ -176,8 +176,10 @@
176#define DA7219_AAD_MICBIAS_CHK_DELAY 10 176#define DA7219_AAD_MICBIAS_CHK_DELAY 10
177#define DA7219_AAD_MICBIAS_CHK_RETRIES 5 177#define DA7219_AAD_MICBIAS_CHK_RETRIES 5
178 178
179#define DA7219_AAD_HPTEST_RAMP_FREQ 0x28 179#define DA7219_AAD_HPTEST_RAMP_FREQ 0x28
180#define DA7219_AAD_HPTEST_PERIOD 65 180#define DA7219_AAD_HPTEST_RAMP_FREQ_INT_OSC 0x4D
181#define DA7219_AAD_HPTEST_PERIOD 65
182#define DA7219_AAD_HPTEST_INT_OSC_PATH_DELAY 20
181 183
182enum da7219_aad_event_regs { 184enum da7219_aad_event_regs {
183 DA7219_AAD_IRQ_REG_A = 0, 185 DA7219_AAD_IRQ_REG_A = 0,
@@ -199,12 +201,17 @@ struct da7219_aad_priv {
199 struct work_struct hptest_work; 201 struct work_struct hptest_work;
200 202
201 struct snd_soc_jack *jack; 203 struct snd_soc_jack *jack;
204 bool micbias_resume_enable;
202 bool jack_inserted; 205 bool jack_inserted;
203}; 206};
204 207
205/* AAD control */ 208/* AAD control */
206void da7219_aad_jack_det(struct snd_soc_codec *codec, struct snd_soc_jack *jack); 209void da7219_aad_jack_det(struct snd_soc_codec *codec, struct snd_soc_jack *jack);
207 210
211/* Suspend/Resume */
212void da7219_aad_suspend(struct snd_soc_codec *codec);
213void da7219_aad_resume(struct snd_soc_codec *codec);
214
208/* Init/Exit */ 215/* Init/Exit */
209int da7219_aad_init(struct snd_soc_codec *codec); 216int da7219_aad_init(struct snd_soc_codec *codec);
210void da7219_aad_exit(struct snd_soc_codec *codec); 217void da7219_aad_exit(struct snd_soc_codec *codec);
diff --git a/sound/soc/codecs/da7219.c b/sound/soc/codecs/da7219.c
index 50ea94317cb3..1152aa5e7c39 100644
--- a/sound/soc/codecs/da7219.c
+++ b/sound/soc/codecs/da7219.c
@@ -801,7 +801,7 @@ static int da7219_dai_event(struct snd_soc_dapm_widget *w,
801 ++i; 801 ++i;
802 msleep(50); 802 msleep(50);
803 } 803 }
804 } while ((i < DA7219_SRM_CHECK_RETRIES) & (!srm_lock)); 804 } while ((i < DA7219_SRM_CHECK_RETRIES) && (!srm_lock));
805 805
806 if (!srm_lock) 806 if (!srm_lock)
807 dev_warn(codec->dev, "SRM failed to lock\n"); 807 dev_warn(codec->dev, "SRM failed to lock\n");
@@ -1482,6 +1482,8 @@ static struct da7219_pdata *da7219_fw_to_pdata(struct snd_soc_codec *codec)
1482 if (!pdata) 1482 if (!pdata)
1483 return NULL; 1483 return NULL;
1484 1484
1485 pdata->wakeup_source = device_property_read_bool(dev, "wakeup-source");
1486
1485 if (device_property_read_u32(dev, "dlg,micbias-lvl", &of_val32) >= 0) 1487 if (device_property_read_u32(dev, "dlg,micbias-lvl", &of_val32) >= 0)
1486 pdata->micbias_lvl = da7219_fw_micbias_lvl(dev, of_val32); 1488 pdata->micbias_lvl = da7219_fw_micbias_lvl(dev, of_val32);
1487 else 1489 else
@@ -1508,11 +1510,10 @@ static int da7219_set_bias_level(struct snd_soc_codec *codec,
1508 1510
1509 switch (level) { 1511 switch (level) {
1510 case SND_SOC_BIAS_ON: 1512 case SND_SOC_BIAS_ON:
1511 case SND_SOC_BIAS_PREPARE:
1512 break; 1513 break;
1513 case SND_SOC_BIAS_STANDBY: 1514 case SND_SOC_BIAS_PREPARE:
1514 if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF) { 1515 /* Enable MCLK for transition to ON state */
1515 /* MCLK */ 1516 if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_STANDBY) {
1516 if (da7219->mclk) { 1517 if (da7219->mclk) {
1517 ret = clk_prepare_enable(da7219->mclk); 1518 ret = clk_prepare_enable(da7219->mclk);
1518 if (ret) { 1519 if (ret) {
@@ -1521,22 +1522,28 @@ static int da7219_set_bias_level(struct snd_soc_codec *codec,
1521 return ret; 1522 return ret;
1522 } 1523 }
1523 } 1524 }
1525 }
1524 1526
1527 break;
1528 case SND_SOC_BIAS_STANDBY:
1529 if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF)
1525 /* Master bias */ 1530 /* Master bias */
1526 snd_soc_update_bits(codec, DA7219_REFERENCES, 1531 snd_soc_update_bits(codec, DA7219_REFERENCES,
1527 DA7219_BIAS_EN_MASK, 1532 DA7219_BIAS_EN_MASK,
1528 DA7219_BIAS_EN_MASK); 1533 DA7219_BIAS_EN_MASK);
1534
1535 if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_PREPARE) {
1536 /* Remove MCLK */
1537 if (da7219->mclk)
1538 clk_disable_unprepare(da7219->mclk);
1529 } 1539 }
1530 break; 1540 break;
1531 case SND_SOC_BIAS_OFF: 1541 case SND_SOC_BIAS_OFF:
1532 /* Only disable master bias if jack detection not active */ 1542 /* Only disable master bias if we're not a wake-up source */
1533 if (!da7219->aad->jack) 1543 if (!da7219->wakeup_source)
1534 snd_soc_update_bits(codec, DA7219_REFERENCES, 1544 snd_soc_update_bits(codec, DA7219_REFERENCES,
1535 DA7219_BIAS_EN_MASK, 0); 1545 DA7219_BIAS_EN_MASK, 0);
1536 1546
1537 /* MCLK */
1538 if (da7219->mclk)
1539 clk_disable_unprepare(da7219->mclk);
1540 break; 1547 break;
1541 } 1548 }
1542 1549
@@ -1599,6 +1606,8 @@ static void da7219_handle_pdata(struct snd_soc_codec *codec)
1599 if (pdata) { 1606 if (pdata) {
1600 u8 micbias_lvl = 0; 1607 u8 micbias_lvl = 0;
1601 1608
1609 da7219->wakeup_source = pdata->wakeup_source;
1610
1602 /* Mic Bias voltages */ 1611 /* Mic Bias voltages */
1603 switch (pdata->micbias_lvl) { 1612 switch (pdata->micbias_lvl) {
1604 case DA7219_MICBIAS_1_6V: 1613 case DA7219_MICBIAS_1_6V:
@@ -1733,11 +1742,11 @@ static int da7219_suspend(struct snd_soc_codec *codec)
1733{ 1742{
1734 struct da7219_priv *da7219 = snd_soc_codec_get_drvdata(codec); 1743 struct da7219_priv *da7219 = snd_soc_codec_get_drvdata(codec);
1735 1744
1736 snd_soc_codec_force_bias_level(codec, SND_SOC_BIAS_OFF); 1745 /* Suspend AAD if we're not a wake-up source */
1746 if (!da7219->wakeup_source)
1747 da7219_aad_suspend(codec);
1737 1748
1738 /* Put device into standby mode if jack detection disabled */ 1749 snd_soc_codec_force_bias_level(codec, SND_SOC_BIAS_OFF);
1739 if (!da7219->aad->jack)
1740 snd_soc_write(codec, DA7219_SYSTEM_ACTIVE, 0);
1741 1750
1742 return 0; 1751 return 0;
1743} 1752}
@@ -1746,13 +1755,12 @@ static int da7219_resume(struct snd_soc_codec *codec)
1746{ 1755{
1747 struct da7219_priv *da7219 = snd_soc_codec_get_drvdata(codec); 1756 struct da7219_priv *da7219 = snd_soc_codec_get_drvdata(codec);
1748 1757
1749 /* Put device into active mode if previously pushed to standby */
1750 if (!da7219->aad->jack)
1751 snd_soc_write(codec, DA7219_SYSTEM_ACTIVE,
1752 DA7219_SYSTEM_ACTIVE_MASK);
1753
1754 snd_soc_codec_force_bias_level(codec, SND_SOC_BIAS_STANDBY); 1758 snd_soc_codec_force_bias_level(codec, SND_SOC_BIAS_STANDBY);
1755 1759
1760 /* Resume AAD if previously suspended */
1761 if (!da7219->wakeup_source)
1762 da7219_aad_resume(codec);
1763
1756 return 0; 1764 return 0;
1757} 1765}
1758#else 1766#else
@@ -1767,13 +1775,14 @@ static struct snd_soc_codec_driver soc_codec_dev_da7219 = {
1767 .resume = da7219_resume, 1775 .resume = da7219_resume,
1768 .set_bias_level = da7219_set_bias_level, 1776 .set_bias_level = da7219_set_bias_level,
1769 1777
1770 .controls = da7219_snd_controls, 1778 .component_driver = {
1771 .num_controls = ARRAY_SIZE(da7219_snd_controls), 1779 .controls = da7219_snd_controls,
1772 1780 .num_controls = ARRAY_SIZE(da7219_snd_controls),
1773 .dapm_widgets = da7219_dapm_widgets, 1781 .dapm_widgets = da7219_dapm_widgets,
1774 .num_dapm_widgets = ARRAY_SIZE(da7219_dapm_widgets), 1782 .num_dapm_widgets = ARRAY_SIZE(da7219_dapm_widgets),
1775 .dapm_routes = da7219_audio_map, 1783 .dapm_routes = da7219_audio_map,
1776 .num_dapm_routes = ARRAY_SIZE(da7219_audio_map), 1784 .num_dapm_routes = ARRAY_SIZE(da7219_audio_map),
1785 },
1777}; 1786};
1778 1787
1779 1788
@@ -1921,7 +1930,8 @@ static int da7219_i2c_probe(struct i2c_client *i2c,
1921 const struct i2c_device_id *id) 1930 const struct i2c_device_id *id)
1922{ 1931{
1923 struct da7219_priv *da7219; 1932 struct da7219_priv *da7219;
1924 int ret; 1933 unsigned int system_active, system_status;
1934 int i, ret;
1925 1935
1926 da7219 = devm_kzalloc(&i2c->dev, sizeof(struct da7219_priv), 1936 da7219 = devm_kzalloc(&i2c->dev, sizeof(struct da7219_priv),
1927 GFP_KERNEL); 1937 GFP_KERNEL);
@@ -1937,6 +1947,37 @@ static int da7219_i2c_probe(struct i2c_client *i2c,
1937 return ret; 1947 return ret;
1938 } 1948 }
1939 1949
1950 regcache_cache_bypass(da7219->regmap, true);
1951
1952 /* Disable audio paths if still active from previous start */
1953 regmap_read(da7219->regmap, DA7219_SYSTEM_ACTIVE, &system_active);
1954 if (system_active) {
1955 regmap_write(da7219->regmap, DA7219_GAIN_RAMP_CTRL,
1956 DA7219_GAIN_RAMP_RATE_NOMINAL);
1957 regmap_write(da7219->regmap, DA7219_SYSTEM_MODES_INPUT, 0x00);
1958 regmap_write(da7219->regmap, DA7219_SYSTEM_MODES_OUTPUT, 0x01);
1959
1960 for (i = 0; i < DA7219_SYS_STAT_CHECK_RETRIES; ++i) {
1961 regmap_read(da7219->regmap, DA7219_SYSTEM_STATUS,
1962 &system_status);
1963 if (!system_status)
1964 break;
1965
1966 msleep(DA7219_SYS_STAT_CHECK_DELAY);
1967 }
1968 }
1969
1970 /* Soft reset codec */
1971 regmap_write_bits(da7219->regmap, DA7219_ACCDET_CONFIG_1,
1972 DA7219_ACCDET_EN_MASK, 0);
1973 regmap_write_bits(da7219->regmap, DA7219_CIF_CTRL,
1974 DA7219_CIF_REG_SOFT_RESET_MASK,
1975 DA7219_CIF_REG_SOFT_RESET_MASK);
1976 regmap_write_bits(da7219->regmap, DA7219_SYSTEM_ACTIVE,
1977 DA7219_SYSTEM_ACTIVE_MASK, 0);
1978
1979 regcache_cache_bypass(da7219->regmap, false);
1980
1940 ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_da7219, 1981 ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_da7219,
1941 &da7219_dai, 1); 1982 &da7219_dai, 1);
1942 if (ret < 0) { 1983 if (ret < 0) {
diff --git a/sound/soc/codecs/da7219.h b/sound/soc/codecs/da7219.h
index ff2a2f02ce40..66d3bad86739 100644
--- a/sound/soc/codecs/da7219.h
+++ b/sound/soc/codecs/da7219.h
@@ -224,6 +224,7 @@
224#define DA7219_PLL_SRM_STATE_MASK (0xF << 0) 224#define DA7219_PLL_SRM_STATE_MASK (0xF << 0)
225#define DA7219_PLL_SRM_STATUS_SHIFT 4 225#define DA7219_PLL_SRM_STATUS_SHIFT 4
226#define DA7219_PLL_SRM_STATUS_MASK (0xF << 4) 226#define DA7219_PLL_SRM_STATUS_MASK (0xF << 4)
227#define DA7219_PLL_SRM_STS_MCLK (0x1 << 4)
227#define DA7219_PLL_SRM_STS_SRM_LOCK (0x1 << 7) 228#define DA7219_PLL_SRM_STS_SRM_LOCK (0x1 << 7)
228 229
229/* DA7219_DIG_ROUTING_DAI = 0x2A */ 230/* DA7219_DIG_ROUTING_DAI = 0x2A */
@@ -576,6 +577,8 @@
576/* DA7219_GAIN_RAMP_CTRL = 0x92 */ 577/* DA7219_GAIN_RAMP_CTRL = 0x92 */
577#define DA7219_GAIN_RAMP_RATE_SHIFT 0 578#define DA7219_GAIN_RAMP_RATE_SHIFT 0
578#define DA7219_GAIN_RAMP_RATE_MASK (0x3 << 0) 579#define DA7219_GAIN_RAMP_RATE_MASK (0x3 << 0)
580#define DA7219_GAIN_RAMP_RATE_X8 (0x0 << 0)
581#define DA7219_GAIN_RAMP_RATE_NOMINAL (0x1 << 0)
579#define DA7219_GAIN_RAMP_RATE_MAX 4 582#define DA7219_GAIN_RAMP_RATE_MAX 4
580 583
581/* DA7219_PC_COUNT = 0x94 */ 584/* DA7219_PC_COUNT = 0x94 */
@@ -770,6 +773,10 @@
770/* SRM */ 773/* SRM */
771#define DA7219_SRM_CHECK_RETRIES 8 774#define DA7219_SRM_CHECK_RETRIES 8
772 775
776/* System Controller */
777#define DA7219_SYS_STAT_CHECK_RETRIES 6
778#define DA7219_SYS_STAT_CHECK_DELAY 50
779
773enum da7219_clk_src { 780enum da7219_clk_src {
774 DA7219_CLKSRC_MCLK = 0, 781 DA7219_CLKSRC_MCLK = 0,
775 DA7219_CLKSRC_MCLK_SQR, 782 DA7219_CLKSRC_MCLK_SQR,
@@ -796,6 +803,7 @@ struct da7219_priv {
796 struct da7219_aad_priv *aad; 803 struct da7219_aad_priv *aad;
797 struct da7219_pdata *pdata; 804 struct da7219_pdata *pdata;
798 805
806 bool wakeup_source;
799 struct regulator_bulk_data supplies[DA7219_NUM_SUPPLIES]; 807 struct regulator_bulk_data supplies[DA7219_NUM_SUPPLIES];
800 struct regmap *regmap; 808 struct regmap *regmap;
801 struct mutex lock; 809 struct mutex lock;
diff --git a/sound/soc/codecs/da732x.c b/sound/soc/codecs/da732x.c
index 461506a4ca6a..c1cc1c1c28f2 100644
--- a/sound/soc/codecs/da732x.c
+++ b/sound/soc/codecs/da732x.c
@@ -1501,12 +1501,14 @@ static int da732x_set_bias_level(struct snd_soc_codec *codec,
1501 1501
1502static struct snd_soc_codec_driver soc_codec_dev_da732x = { 1502static struct snd_soc_codec_driver soc_codec_dev_da732x = {
1503 .set_bias_level = da732x_set_bias_level, 1503 .set_bias_level = da732x_set_bias_level,
1504 .controls = da732x_snd_controls, 1504 .component_driver = {
1505 .num_controls = ARRAY_SIZE(da732x_snd_controls), 1505 .controls = da732x_snd_controls,
1506 .dapm_widgets = da732x_dapm_widgets, 1506 .num_controls = ARRAY_SIZE(da732x_snd_controls),
1507 .num_dapm_widgets = ARRAY_SIZE(da732x_dapm_widgets), 1507 .dapm_widgets = da732x_dapm_widgets,
1508 .dapm_routes = da732x_dapm_routes, 1508 .num_dapm_widgets = ARRAY_SIZE(da732x_dapm_widgets),
1509 .num_dapm_routes = ARRAY_SIZE(da732x_dapm_routes), 1509 .dapm_routes = da732x_dapm_routes,
1510 .num_dapm_routes = ARRAY_SIZE(da732x_dapm_routes),
1511 },
1510 .set_pll = da732x_set_dai_pll, 1512 .set_pll = da732x_set_dai_pll,
1511}; 1513};
1512 1514
diff --git a/sound/soc/codecs/da9055.c b/sound/soc/codecs/da9055.c
index 0b2ede8db978..4efb5f897a0c 100644
--- a/sound/soc/codecs/da9055.c
+++ b/sound/soc/codecs/da9055.c
@@ -1455,13 +1455,14 @@ static struct snd_soc_codec_driver soc_codec_dev_da9055 = {
1455 .probe = da9055_probe, 1455 .probe = da9055_probe,
1456 .set_bias_level = da9055_set_bias_level, 1456 .set_bias_level = da9055_set_bias_level,
1457 1457
1458 .controls = da9055_snd_controls, 1458 .component_driver = {
1459 .num_controls = ARRAY_SIZE(da9055_snd_controls), 1459 .controls = da9055_snd_controls,
1460 1460 .num_controls = ARRAY_SIZE(da9055_snd_controls),
1461 .dapm_widgets = da9055_dapm_widgets, 1461 .dapm_widgets = da9055_dapm_widgets,
1462 .num_dapm_widgets = ARRAY_SIZE(da9055_dapm_widgets), 1462 .num_dapm_widgets = ARRAY_SIZE(da9055_dapm_widgets),
1463 .dapm_routes = da9055_audio_map, 1463 .dapm_routes = da9055_audio_map,
1464 .num_dapm_routes = ARRAY_SIZE(da9055_audio_map), 1464 .num_dapm_routes = ARRAY_SIZE(da9055_audio_map),
1465 },
1465}; 1466};
1466 1467
1467static const struct regmap_config da9055_regmap_config = { 1468static const struct regmap_config da9055_regmap_config = {
diff --git a/sound/soc/codecs/dmic.c b/sound/soc/codecs/dmic.c
index fde53251c047..c82b9dc41e9a 100644
--- a/sound/soc/codecs/dmic.c
+++ b/sound/soc/codecs/dmic.c
@@ -51,10 +51,12 @@ static const struct snd_soc_dapm_route intercon[] = {
51}; 51};
52 52
53static struct snd_soc_codec_driver soc_dmic = { 53static struct snd_soc_codec_driver soc_dmic = {
54 .dapm_widgets = dmic_dapm_widgets, 54 .component_driver = {
55 .num_dapm_widgets = ARRAY_SIZE(dmic_dapm_widgets), 55 .dapm_widgets = dmic_dapm_widgets,
56 .dapm_routes = intercon, 56 .num_dapm_widgets = ARRAY_SIZE(dmic_dapm_widgets),
57 .num_dapm_routes = ARRAY_SIZE(intercon), 57 .dapm_routes = intercon,
58 .num_dapm_routes = ARRAY_SIZE(intercon),
59 },
58}; 60};
59 61
60static int dmic_dev_probe(struct platform_device *pdev) 62static int dmic_dev_probe(struct platform_device *pdev)
diff --git a/sound/soc/codecs/es8328.c b/sound/soc/codecs/es8328.c
index 2086d7107622..37722194b107 100644
--- a/sound/soc/codecs/es8328.c
+++ b/sound/soc/codecs/es8328.c
@@ -823,12 +823,14 @@ static struct snd_soc_codec_driver es8328_codec_driver = {
823 .set_bias_level = es8328_set_bias_level, 823 .set_bias_level = es8328_set_bias_level,
824 .suspend_bias_off = true, 824 .suspend_bias_off = true,
825 825
826 .controls = es8328_snd_controls, 826 .component_driver = {
827 .num_controls = ARRAY_SIZE(es8328_snd_controls), 827 .controls = es8328_snd_controls,
828 .dapm_widgets = es8328_dapm_widgets, 828 .num_controls = ARRAY_SIZE(es8328_snd_controls),
829 .num_dapm_widgets = ARRAY_SIZE(es8328_dapm_widgets), 829 .dapm_widgets = es8328_dapm_widgets,
830 .dapm_routes = es8328_dapm_routes, 830 .num_dapm_widgets = ARRAY_SIZE(es8328_dapm_widgets),
831 .num_dapm_routes = ARRAY_SIZE(es8328_dapm_routes), 831 .dapm_routes = es8328_dapm_routes,
832 .num_dapm_routes = ARRAY_SIZE(es8328_dapm_routes),
833 },
832}; 834};
833 835
834int es8328_probe(struct device *dev, struct regmap *regmap) 836int es8328_probe(struct device *dev, struct regmap *regmap)
diff --git a/sound/soc/codecs/gtm601.c b/sound/soc/codecs/gtm601.c
index 0b80052996d3..926b1a4e37d4 100644
--- a/sound/soc/codecs/gtm601.c
+++ b/sound/soc/codecs/gtm601.c
@@ -52,10 +52,12 @@ static struct snd_soc_dai_driver gtm601_dai = {
52}; 52};
53 53
54static const struct snd_soc_codec_driver soc_codec_dev_gtm601 = { 54static const struct snd_soc_codec_driver soc_codec_dev_gtm601 = {
55 .dapm_widgets = gtm601_dapm_widgets, 55 .component_driver = {
56 .num_dapm_widgets = ARRAY_SIZE(gtm601_dapm_widgets), 56 .dapm_widgets = gtm601_dapm_widgets,
57 .dapm_routes = gtm601_dapm_routes, 57 .num_dapm_widgets = ARRAY_SIZE(gtm601_dapm_widgets),
58 .num_dapm_routes = ARRAY_SIZE(gtm601_dapm_routes), 58 .dapm_routes = gtm601_dapm_routes,
59 .num_dapm_routes = ARRAY_SIZE(gtm601_dapm_routes),
60 },
59}; 61};
60 62
61static int gtm601_platform_probe(struct platform_device *pdev) 63static int gtm601_platform_probe(struct platform_device *pdev)
diff --git a/sound/soc/codecs/hdac_hdmi.c b/sound/soc/codecs/hdac_hdmi.c
index 4e181b270d95..c602c4960924 100644
--- a/sound/soc/codecs/hdac_hdmi.c
+++ b/sound/soc/codecs/hdac_hdmi.c
@@ -614,7 +614,7 @@ static int hdac_hdmi_pcm_open(struct snd_pcm_substream *substream,
614 (!pin->eld.eld_valid)) { 614 (!pin->eld.eld_valid)) {
615 615
616 dev_warn(&hdac->hdac.dev, 616 dev_warn(&hdac->hdac.dev,
617 "Failed: montior present? %d ELD valid?: %d for pin: %d\n", 617 "Failed: monitor present? %d ELD valid?: %d for pin: %d\n",
618 pin->eld.monitor_present, pin->eld.eld_valid, pin->nid); 618 pin->eld.monitor_present, pin->eld.eld_valid, pin->nid);
619 619
620 return 0; 620 return 0;
diff --git a/sound/soc/codecs/hdmi-codec.c b/sound/soc/codecs/hdmi-codec.c
index f27d115626db..b904492d7744 100644
--- a/sound/soc/codecs/hdmi-codec.c
+++ b/sound/soc/codecs/hdmi-codec.c
@@ -24,6 +24,15 @@
24 24
25#include <drm/drm_crtc.h> /* This is only to get MAX_ELD_BYTES */ 25#include <drm/drm_crtc.h> /* This is only to get MAX_ELD_BYTES */
26 26
27struct hdmi_device {
28 struct device *dev;
29 struct list_head list;
30 int cnt;
31};
32#define pos_to_hdmi_device(pos) container_of((pos), struct hdmi_device, list)
33LIST_HEAD(hdmi_device_list);
34
35#define DAI_NAME_SIZE 16
27struct hdmi_codec_priv { 36struct hdmi_codec_priv {
28 struct hdmi_codec_pdata hcd; 37 struct hdmi_codec_pdata hcd;
29 struct snd_soc_dai_driver *daidrv; 38 struct snd_soc_dai_driver *daidrv;
@@ -320,7 +329,6 @@ static const struct snd_soc_dai_ops hdmi_dai_ops = {
320 SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_S32_BE) 329 SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_S32_BE)
321 330
322static struct snd_soc_dai_driver hdmi_i2s_dai = { 331static struct snd_soc_dai_driver hdmi_i2s_dai = {
323 .name = "i2s-hifi",
324 .id = DAI_ID_I2S, 332 .id = DAI_ID_I2S,
325 .playback = { 333 .playback = {
326 .stream_name = "Playback", 334 .stream_name = "Playback",
@@ -334,7 +342,6 @@ static struct snd_soc_dai_driver hdmi_i2s_dai = {
334}; 342};
335 343
336static const struct snd_soc_dai_driver hdmi_spdif_dai = { 344static const struct snd_soc_dai_driver hdmi_spdif_dai = {
337 .name = "spdif-hifi",
338 .id = DAI_ID_SPDIF, 345 .id = DAI_ID_SPDIF,
339 .playback = { 346 .playback = {
340 .stream_name = "Playback", 347 .stream_name = "Playback",
@@ -346,13 +353,37 @@ static const struct snd_soc_dai_driver hdmi_spdif_dai = {
346 .ops = &hdmi_dai_ops, 353 .ops = &hdmi_dai_ops,
347}; 354};
348 355
356static char hdmi_dai_name[][DAI_NAME_SIZE] = {
357 "hdmi-hifi.0",
358 "hdmi-hifi.1",
359 "hdmi-hifi.2",
360 "hdmi-hifi.3",
361};
362
363static int hdmi_of_xlate_dai_name(struct snd_soc_component *component,
364 struct of_phandle_args *args,
365 const char **dai_name)
366{
367 int id = args->args[0];
368
369 if (id < ARRAY_SIZE(hdmi_dai_name)) {
370 *dai_name = hdmi_dai_name[id];
371 return 0;
372 }
373
374 return -EAGAIN;
375}
376
349static struct snd_soc_codec_driver hdmi_codec = { 377static struct snd_soc_codec_driver hdmi_codec = {
350 .controls = hdmi_controls, 378 .component_driver = {
351 .num_controls = ARRAY_SIZE(hdmi_controls), 379 .controls = hdmi_controls,
352 .dapm_widgets = hdmi_widgets, 380 .num_controls = ARRAY_SIZE(hdmi_controls),
353 .num_dapm_widgets = ARRAY_SIZE(hdmi_widgets), 381 .dapm_widgets = hdmi_widgets,
354 .dapm_routes = hdmi_routes, 382 .num_dapm_widgets = ARRAY_SIZE(hdmi_widgets),
355 .num_dapm_routes = ARRAY_SIZE(hdmi_routes), 383 .dapm_routes = hdmi_routes,
384 .num_dapm_routes = ARRAY_SIZE(hdmi_routes),
385 .of_xlate_dai_name = hdmi_of_xlate_dai_name,
386 },
356}; 387};
357 388
358static int hdmi_codec_probe(struct platform_device *pdev) 389static int hdmi_codec_probe(struct platform_device *pdev)
@@ -360,6 +391,8 @@ static int hdmi_codec_probe(struct platform_device *pdev)
360 struct hdmi_codec_pdata *hcd = pdev->dev.platform_data; 391 struct hdmi_codec_pdata *hcd = pdev->dev.platform_data;
361 struct device *dev = &pdev->dev; 392 struct device *dev = &pdev->dev;
362 struct hdmi_codec_priv *hcp; 393 struct hdmi_codec_priv *hcp;
394 struct hdmi_device *hd;
395 struct list_head *pos;
363 int dai_count, i = 0; 396 int dai_count, i = 0;
364 int ret; 397 int ret;
365 398
@@ -381,6 +414,31 @@ static int hdmi_codec_probe(struct platform_device *pdev)
381 if (!hcp) 414 if (!hcp)
382 return -ENOMEM; 415 return -ENOMEM;
383 416
417 hd = NULL;
418 list_for_each(pos, &hdmi_device_list) {
419 struct hdmi_device *tmp = pos_to_hdmi_device(pos);
420
421 if (tmp->dev == dev->parent) {
422 hd = tmp;
423 break;
424 }
425 }
426
427 if (!hd) {
428 hd = devm_kzalloc(dev, sizeof(*hd), GFP_KERNEL);
429 if (!hd)
430 return -ENOMEM;
431
432 hd->dev = dev->parent;
433
434 list_add_tail(&hd->list, &hdmi_device_list);
435 }
436
437 if (hd->cnt >= ARRAY_SIZE(hdmi_dai_name)) {
438 dev_err(dev, "too many hdmi codec are deteced\n");
439 return -EINVAL;
440 }
441
384 hcp->hcd = *hcd; 442 hcp->hcd = *hcd;
385 mutex_init(&hcp->current_stream_lock); 443 mutex_init(&hcp->current_stream_lock);
386 444
@@ -393,11 +451,14 @@ static int hdmi_codec_probe(struct platform_device *pdev)
393 hcp->daidrv[i] = hdmi_i2s_dai; 451 hcp->daidrv[i] = hdmi_i2s_dai;
394 hcp->daidrv[i].playback.channels_max = 452 hcp->daidrv[i].playback.channels_max =
395 hcd->max_i2s_channels; 453 hcd->max_i2s_channels;
454 hcp->daidrv[i].name = hdmi_dai_name[hd->cnt++];
396 i++; 455 i++;
397 } 456 }
398 457
399 if (hcd->spdif) 458 if (hcd->spdif) {
400 hcp->daidrv[i] = hdmi_spdif_dai; 459 hcp->daidrv[i] = hdmi_spdif_dai;
460 hcp->daidrv[i].name = hdmi_dai_name[hd->cnt++];
461 }
401 462
402 ret = snd_soc_register_codec(dev, &hdmi_codec, hcp->daidrv, 463 ret = snd_soc_register_codec(dev, &hdmi_codec, hcp->daidrv,
403 dai_count); 464 dai_count);
diff --git a/sound/soc/codecs/inno_rk3036.c b/sound/soc/codecs/inno_rk3036.c
index 9b6e8840a1b5..b918ba5c8ce5 100644
--- a/sound/soc/codecs/inno_rk3036.c
+++ b/sound/soc/codecs/inno_rk3036.c
@@ -380,12 +380,14 @@ static struct snd_soc_codec_driver rk3036_codec_driver = {
380 .probe = rk3036_codec_probe, 380 .probe = rk3036_codec_probe,
381 .remove = rk3036_codec_remove, 381 .remove = rk3036_codec_remove,
382 .set_bias_level = rk3036_codec_set_bias_level, 382 .set_bias_level = rk3036_codec_set_bias_level,
383 .controls = rk3036_codec_dapm_controls, 383 .component_driver = {
384 .num_controls = ARRAY_SIZE(rk3036_codec_dapm_controls), 384 .controls = rk3036_codec_dapm_controls,
385 .dapm_routes = rk3036_codec_dapm_routes, 385 .num_controls = ARRAY_SIZE(rk3036_codec_dapm_controls),
386 .num_dapm_routes = ARRAY_SIZE(rk3036_codec_dapm_routes), 386 .dapm_routes = rk3036_codec_dapm_routes,
387 .dapm_widgets = rk3036_codec_dapm_widgets, 387 .num_dapm_routes = ARRAY_SIZE(rk3036_codec_dapm_routes),
388 .num_dapm_widgets = ARRAY_SIZE(rk3036_codec_dapm_widgets), 388 .dapm_widgets = rk3036_codec_dapm_widgets,
389 .num_dapm_widgets = ARRAY_SIZE(rk3036_codec_dapm_widgets),
390 },
389}; 391};
390 392
391static const struct regmap_config rk3036_codec_regmap_config = { 393static const struct regmap_config rk3036_codec_regmap_config = {
diff --git a/sound/soc/codecs/isabelle.c b/sound/soc/codecs/isabelle.c
index be448373d39a..a4b0eded984a 100644
--- a/sound/soc/codecs/isabelle.c
+++ b/sound/soc/codecs/isabelle.c
@@ -1089,12 +1089,14 @@ static struct snd_soc_dai_driver isabelle_dai[] = {
1089 1089
1090static struct snd_soc_codec_driver soc_codec_dev_isabelle = { 1090static struct snd_soc_codec_driver soc_codec_dev_isabelle = {
1091 .set_bias_level = isabelle_set_bias_level, 1091 .set_bias_level = isabelle_set_bias_level,
1092 .controls = isabelle_snd_controls, 1092 .component_driver = {
1093 .num_controls = ARRAY_SIZE(isabelle_snd_controls), 1093 .controls = isabelle_snd_controls,
1094 .dapm_widgets = isabelle_dapm_widgets, 1094 .num_controls = ARRAY_SIZE(isabelle_snd_controls),
1095 .num_dapm_widgets = ARRAY_SIZE(isabelle_dapm_widgets), 1095 .dapm_widgets = isabelle_dapm_widgets,
1096 .dapm_routes = isabelle_intercon, 1096 .num_dapm_widgets = ARRAY_SIZE(isabelle_dapm_widgets),
1097 .num_dapm_routes = ARRAY_SIZE(isabelle_intercon), 1097 .dapm_routes = isabelle_intercon,
1098 .num_dapm_routes = ARRAY_SIZE(isabelle_intercon),
1099 },
1098 .idle_bias_off = true, 1100 .idle_bias_off = true,
1099}; 1101};
1100 1102
diff --git a/sound/soc/codecs/jz4740.c b/sound/soc/codecs/jz4740.c
index 1f5ab99956ed..0290fab383da 100644
--- a/sound/soc/codecs/jz4740.c
+++ b/sound/soc/codecs/jz4740.c
@@ -298,12 +298,14 @@ static struct snd_soc_codec_driver soc_codec_dev_jz4740_codec = {
298 .set_bias_level = jz4740_codec_set_bias_level, 298 .set_bias_level = jz4740_codec_set_bias_level,
299 .suspend_bias_off = true, 299 .suspend_bias_off = true,
300 300
301 .controls = jz4740_codec_controls, 301 .component_driver = {
302 .num_controls = ARRAY_SIZE(jz4740_codec_controls), 302 .controls = jz4740_codec_controls,
303 .dapm_widgets = jz4740_codec_dapm_widgets, 303 .num_controls = ARRAY_SIZE(jz4740_codec_controls),
304 .num_dapm_widgets = ARRAY_SIZE(jz4740_codec_dapm_widgets), 304 .dapm_widgets = jz4740_codec_dapm_widgets,
305 .dapm_routes = jz4740_codec_dapm_routes, 305 .num_dapm_widgets = ARRAY_SIZE(jz4740_codec_dapm_widgets),
306 .num_dapm_routes = ARRAY_SIZE(jz4740_codec_dapm_routes), 306 .dapm_routes = jz4740_codec_dapm_routes,
307 .num_dapm_routes = ARRAY_SIZE(jz4740_codec_dapm_routes),
308 },
307}; 309};
308 310
309static const struct regmap_config jz4740_codec_regmap_config = { 311static const struct regmap_config jz4740_codec_regmap_config = {
diff --git a/sound/soc/codecs/l3.c b/sound/soc/codecs/l3.c
index 5353af58862c..a10ea3c716c6 100644
--- a/sound/soc/codecs/l3.c
+++ b/sound/soc/codecs/l3.c
@@ -20,6 +20,8 @@
20#include <linux/module.h> 20#include <linux/module.h>
21#include <linux/kernel.h> 21#include <linux/kernel.h>
22#include <linux/delay.h> 22#include <linux/delay.h>
23#include <linux/device.h>
24#include <linux/gpio.h>
23 25
24#include <sound/l3.h> 26#include <sound/l3.h>
25 27
@@ -32,11 +34,11 @@ static void sendbyte(struct l3_pins *adap, unsigned int byte)
32 int i; 34 int i;
33 35
34 for (i = 0; i < 8; i++) { 36 for (i = 0; i < 8; i++) {
35 adap->setclk(0); 37 adap->setclk(adap, 0);
36 udelay(adap->data_hold); 38 udelay(adap->data_hold);
37 adap->setdat(byte & 1); 39 adap->setdat(adap, byte & 1);
38 udelay(adap->data_setup); 40 udelay(adap->data_setup);
39 adap->setclk(1); 41 adap->setclk(adap, 1);
40 udelay(adap->clock_high); 42 udelay(adap->clock_high);
41 byte >>= 1; 43 byte >>= 1;
42 } 44 }
@@ -55,10 +57,10 @@ static void sendbytes(struct l3_pins *adap, const u8 *buf,
55 for (i = 0; i < len; i++) { 57 for (i = 0; i < len; i++) {
56 if (i) { 58 if (i) {
57 udelay(adap->mode_hold); 59 udelay(adap->mode_hold);
58 adap->setmode(0); 60 adap->setmode(adap, 0);
59 udelay(adap->mode); 61 udelay(adap->mode);
60 } 62 }
61 adap->setmode(1); 63 adap->setmode(adap, 1);
62 udelay(adap->mode_setup); 64 udelay(adap->mode_setup);
63 sendbyte(adap, buf[i]); 65 sendbyte(adap, buf[i]);
64 } 66 }
@@ -66,26 +68,71 @@ static void sendbytes(struct l3_pins *adap, const u8 *buf,
66 68
67int l3_write(struct l3_pins *adap, u8 addr, u8 *data, int len) 69int l3_write(struct l3_pins *adap, u8 addr, u8 *data, int len)
68{ 70{
69 adap->setclk(1); 71 adap->setclk(adap, 1);
70 adap->setdat(1); 72 adap->setdat(adap, 1);
71 adap->setmode(1); 73 adap->setmode(adap, 1);
72 udelay(adap->mode); 74 udelay(adap->mode);
73 75
74 adap->setmode(0); 76 adap->setmode(adap, 0);
75 udelay(adap->mode_setup); 77 udelay(adap->mode_setup);
76 sendbyte(adap, addr); 78 sendbyte(adap, addr);
77 udelay(adap->mode_hold); 79 udelay(adap->mode_hold);
78 80
79 sendbytes(adap, data, len); 81 sendbytes(adap, data, len);
80 82
81 adap->setclk(1); 83 adap->setclk(adap, 1);
82 adap->setdat(1); 84 adap->setdat(adap, 1);
83 adap->setmode(0); 85 adap->setmode(adap, 0);
84 86
85 return len; 87 return len;
86} 88}
87EXPORT_SYMBOL_GPL(l3_write); 89EXPORT_SYMBOL_GPL(l3_write);
88 90
91
92static void l3_set_clk(struct l3_pins *adap, int val)
93{
94 gpio_set_value(adap->gpio_clk, val);
95}
96
97static void l3_set_data(struct l3_pins *adap, int val)
98{
99 gpio_set_value(adap->gpio_data, val);
100}
101
102static void l3_set_mode(struct l3_pins *adap, int val)
103{
104 gpio_set_value(adap->gpio_mode, val);
105}
106
107int l3_set_gpio_ops(struct device *dev, struct l3_pins *adap)
108{
109 int ret;
110
111 if (!adap->use_gpios)
112 return -EINVAL;
113
114 ret = devm_gpio_request_one(dev, adap->gpio_data,
115 GPIOF_OUT_INIT_LOW, "l3_data");
116 if (ret < 0)
117 return ret;
118 adap->setdat = l3_set_data;
119
120 ret = devm_gpio_request_one(dev, adap->gpio_clk,
121 GPIOF_OUT_INIT_LOW, "l3_clk");
122 if (ret < 0)
123 return ret;
124 adap->setclk = l3_set_clk;
125
126 ret = devm_gpio_request_one(dev, adap->gpio_mode,
127 GPIOF_OUT_INIT_LOW, "l3_mode");
128 if (ret < 0)
129 return ret;
130 adap->setmode = l3_set_mode;
131
132 return 0;
133}
134EXPORT_SYMBOL_GPL(l3_set_gpio_ops);
135
89MODULE_DESCRIPTION("L3 bit-banging driver"); 136MODULE_DESCRIPTION("L3 bit-banging driver");
90MODULE_AUTHOR("Christian Pellegrin <chripell@evolware.org>"); 137MODULE_AUTHOR("Christian Pellegrin <chripell@evolware.org>");
91MODULE_LICENSE("GPL"); 138MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/lm49453.c b/sound/soc/codecs/lm49453.c
index 9af5640e3446..8d413c2677cc 100644
--- a/sound/soc/codecs/lm49453.c
+++ b/sound/soc/codecs/lm49453.c
@@ -1391,12 +1391,14 @@ static struct snd_soc_dai_driver lm49453_dai[] = {
1391 1391
1392static struct snd_soc_codec_driver soc_codec_dev_lm49453 = { 1392static struct snd_soc_codec_driver soc_codec_dev_lm49453 = {
1393 .set_bias_level = lm49453_set_bias_level, 1393 .set_bias_level = lm49453_set_bias_level,
1394 .controls = lm49453_snd_controls, 1394 .component_driver = {
1395 .num_controls = ARRAY_SIZE(lm49453_snd_controls), 1395 .controls = lm49453_snd_controls,
1396 .dapm_widgets = lm49453_dapm_widgets, 1396 .num_controls = ARRAY_SIZE(lm49453_snd_controls),
1397 .num_dapm_widgets = ARRAY_SIZE(lm49453_dapm_widgets), 1397 .dapm_widgets = lm49453_dapm_widgets,
1398 .dapm_routes = lm49453_audio_map, 1398 .num_dapm_widgets = ARRAY_SIZE(lm49453_dapm_widgets),
1399 .num_dapm_routes = ARRAY_SIZE(lm49453_audio_map), 1399 .dapm_routes = lm49453_audio_map,
1400 .num_dapm_routes = ARRAY_SIZE(lm49453_audio_map),
1401 },
1400 .idle_bias_off = true, 1402 .idle_bias_off = true,
1401}; 1403};
1402 1404
diff --git a/sound/soc/codecs/max98088.c b/sound/soc/codecs/max98088.c
index fc22804cabc5..72f77455582e 100644
--- a/sound/soc/codecs/max98088.c
+++ b/sound/soc/codecs/max98088.c
@@ -1704,12 +1704,14 @@ static struct snd_soc_codec_driver soc_codec_dev_max98088 = {
1704 .set_bias_level = max98088_set_bias_level, 1704 .set_bias_level = max98088_set_bias_level,
1705 .suspend_bias_off = true, 1705 .suspend_bias_off = true,
1706 1706
1707 .controls = max98088_snd_controls, 1707 .component_driver = {
1708 .num_controls = ARRAY_SIZE(max98088_snd_controls), 1708 .controls = max98088_snd_controls,
1709 .dapm_widgets = max98088_dapm_widgets, 1709 .num_controls = ARRAY_SIZE(max98088_snd_controls),
1710 .num_dapm_widgets = ARRAY_SIZE(max98088_dapm_widgets), 1710 .dapm_widgets = max98088_dapm_widgets,
1711 .dapm_routes = max98088_audio_map, 1711 .num_dapm_widgets = ARRAY_SIZE(max98088_dapm_widgets),
1712 .num_dapm_routes = ARRAY_SIZE(max98088_audio_map), 1712 .dapm_routes = max98088_audio_map,
1713 .num_dapm_routes = ARRAY_SIZE(max98088_audio_map),
1714 },
1713}; 1715};
1714 1716
1715static int max98088_i2c_probe(struct i2c_client *i2c, 1717static int max98088_i2c_probe(struct i2c_client *i2c,
diff --git a/sound/soc/codecs/max98095.c b/sound/soc/codecs/max98095.c
index 3577003f39cf..6f8a757876ed 100644
--- a/sound/soc/codecs/max98095.c
+++ b/sound/soc/codecs/max98095.c
@@ -2108,12 +2108,14 @@ static struct snd_soc_codec_driver soc_codec_dev_max98095 = {
2108 .suspend = max98095_suspend, 2108 .suspend = max98095_suspend,
2109 .resume = max98095_resume, 2109 .resume = max98095_resume,
2110 .set_bias_level = max98095_set_bias_level, 2110 .set_bias_level = max98095_set_bias_level,
2111 .controls = max98095_snd_controls, 2111 .component_driver = {
2112 .num_controls = ARRAY_SIZE(max98095_snd_controls), 2112 .controls = max98095_snd_controls,
2113 .dapm_widgets = max98095_dapm_widgets, 2113 .num_controls = ARRAY_SIZE(max98095_snd_controls),
2114 .num_dapm_widgets = ARRAY_SIZE(max98095_dapm_widgets), 2114 .dapm_widgets = max98095_dapm_widgets,
2115 .dapm_routes = max98095_audio_map, 2115 .num_dapm_widgets = ARRAY_SIZE(max98095_dapm_widgets),
2116 .num_dapm_routes = ARRAY_SIZE(max98095_audio_map), 2116 .dapm_routes = max98095_audio_map,
2117 .num_dapm_routes = ARRAY_SIZE(max98095_audio_map),
2118 },
2117}; 2119};
2118 2120
2119static int max98095_i2c_probe(struct i2c_client *i2c, 2121static int max98095_i2c_probe(struct i2c_client *i2c,
diff --git a/sound/soc/codecs/max98357a.c b/sound/soc/codecs/max98357a.c
index 5b1dfb1518fb..6a6b68a4cb52 100644
--- a/sound/soc/codecs/max98357a.c
+++ b/sound/soc/codecs/max98357a.c
@@ -74,10 +74,12 @@ static int max98357a_codec_probe(struct snd_soc_codec *codec)
74 74
75static struct snd_soc_codec_driver max98357a_codec_driver = { 75static struct snd_soc_codec_driver max98357a_codec_driver = {
76 .probe = max98357a_codec_probe, 76 .probe = max98357a_codec_probe,
77 .dapm_widgets = max98357a_dapm_widgets, 77 .component_driver = {
78 .num_dapm_widgets = ARRAY_SIZE(max98357a_dapm_widgets), 78 .dapm_widgets = max98357a_dapm_widgets,
79 .dapm_routes = max98357a_dapm_routes, 79 .num_dapm_widgets = ARRAY_SIZE(max98357a_dapm_widgets),
80 .num_dapm_routes = ARRAY_SIZE(max98357a_dapm_routes), 80 .dapm_routes = max98357a_dapm_routes,
81 .num_dapm_routes = ARRAY_SIZE(max98357a_dapm_routes),
82 },
81}; 83};
82 84
83static const struct snd_soc_dai_ops max98357a_dai_ops = { 85static const struct snd_soc_dai_ops max98357a_dai_ops = {
diff --git a/sound/soc/codecs/max98371.c b/sound/soc/codecs/max98371.c
index 02352ed8961c..781be9ba8dba 100644
--- a/sound/soc/codecs/max98371.c
+++ b/sound/soc/codecs/max98371.c
@@ -426,7 +426,6 @@ MODULE_DEVICE_TABLE(of, max98371_of_match);
426static struct i2c_driver max98371_i2c_driver = { 426static struct i2c_driver max98371_i2c_driver = {
427 .driver = { 427 .driver = {
428 .name = "max98371", 428 .name = "max98371",
429 .owner = THIS_MODULE,
430 .pm = NULL, 429 .pm = NULL,
431 .of_match_table = of_match_ptr(max98371_of_match), 430 .of_match_table = of_match_ptr(max98371_of_match),
432 }, 431 },
diff --git a/sound/soc/codecs/max9850.c b/sound/soc/codecs/max9850.c
index c14a79d026a1..0610840733d1 100644
--- a/sound/soc/codecs/max9850.c
+++ b/sound/soc/codecs/max9850.c
@@ -306,12 +306,14 @@ static struct snd_soc_codec_driver soc_codec_dev_max9850 = {
306 .set_bias_level = max9850_set_bias_level, 306 .set_bias_level = max9850_set_bias_level,
307 .suspend_bias_off = true, 307 .suspend_bias_off = true,
308 308
309 .controls = max9850_controls, 309 .component_driver = {
310 .num_controls = ARRAY_SIZE(max9850_controls), 310 .controls = max9850_controls,
311 .dapm_widgets = max9850_dapm_widgets, 311 .num_controls = ARRAY_SIZE(max9850_controls),
312 .num_dapm_widgets = ARRAY_SIZE(max9850_dapm_widgets), 312 .dapm_widgets = max9850_dapm_widgets,
313 .dapm_routes = max9850_dapm_routes, 313 .num_dapm_widgets = ARRAY_SIZE(max9850_dapm_widgets),
314 .num_dapm_routes = ARRAY_SIZE(max9850_dapm_routes), 314 .dapm_routes = max9850_dapm_routes,
315 .num_dapm_routes = ARRAY_SIZE(max9850_dapm_routes),
316 },
315}; 317};
316 318
317static int max9850_i2c_probe(struct i2c_client *i2c, 319static int max9850_i2c_probe(struct i2c_client *i2c,
diff --git a/sound/soc/codecs/max9860.c b/sound/soc/codecs/max9860.c
index 68074c92a7c0..499bdbfd0a2d 100644
--- a/sound/soc/codecs/max9860.c
+++ b/sound/soc/codecs/max9860.c
@@ -538,12 +538,14 @@ static struct snd_soc_codec_driver max9860_codec_driver = {
538 .set_bias_level = max9860_set_bias_level, 538 .set_bias_level = max9860_set_bias_level,
539 .idle_bias_off = true, 539 .idle_bias_off = true,
540 540
541 .controls = max9860_controls, 541 .component_driver = {
542 .num_controls = ARRAY_SIZE(max9860_controls), 542 .controls = max9860_controls,
543 .dapm_widgets = max9860_dapm_widgets, 543 .num_controls = ARRAY_SIZE(max9860_controls),
544 .num_dapm_widgets = ARRAY_SIZE(max9860_dapm_widgets), 544 .dapm_widgets = max9860_dapm_widgets,
545 .dapm_routes = max9860_dapm_routes, 545 .num_dapm_widgets = ARRAY_SIZE(max9860_dapm_widgets),
546 .num_dapm_routes = ARRAY_SIZE(max9860_dapm_routes), 546 .dapm_routes = max9860_dapm_routes,
547 .num_dapm_routes = ARRAY_SIZE(max9860_dapm_routes),
548 },
547}; 549};
548 550
549#ifdef CONFIG_PM 551#ifdef CONFIG_PM
diff --git a/sound/soc/codecs/max9867.c b/sound/soc/codecs/max9867.c
index 2a22fddeb6af..42e2e407e287 100644
--- a/sound/soc/codecs/max9867.c
+++ b/sound/soc/codecs/max9867.c
@@ -38,11 +38,10 @@ static DECLARE_TLV_DB_SCALE(max9860_capture_tlv, -600, 200, 0);
38static DECLARE_TLV_DB_SCALE(max9860_mic_tlv, 2000, 100, 1); 38static DECLARE_TLV_DB_SCALE(max9860_mic_tlv, 2000, 100, 1);
39static DECLARE_TLV_DB_SCALE(max9860_adc_left_tlv, -1200, 100, 1); 39static DECLARE_TLV_DB_SCALE(max9860_adc_left_tlv, -1200, 100, 1);
40static DECLARE_TLV_DB_SCALE(max9860_adc_right_tlv, -1200, 100, 1); 40static DECLARE_TLV_DB_SCALE(max9860_adc_right_tlv, -1200, 100, 1);
41static const unsigned int max98088_micboost_tlv[] = { 41static const SNDRV_CTL_TLVD_DECLARE_DB_RANGE(max98088_micboost_tlv,
42 TLV_DB_RANGE_HEAD(2),
43 0, 1, TLV_DB_SCALE_ITEM(0, 2000, 0), 42 0, 1, TLV_DB_SCALE_ITEM(0, 2000, 0),
44 2, 2, TLV_DB_SCALE_ITEM(3000, 0, 0), 43 2, 2, TLV_DB_SCALE_ITEM(3000, 0, 0),
45}; 44);
46 45
47static const struct snd_kcontrol_new max9867_snd_controls[] = { 46static const struct snd_kcontrol_new max9867_snd_controls[] = {
48 SOC_DOUBLE_R("Master Playback Volume", MAX9867_LEFTVOL, 47 SOC_DOUBLE_R("Master Playback Volume", MAX9867_LEFTVOL,
@@ -417,12 +416,14 @@ static int max9867_probe(struct snd_soc_codec *codec)
417 416
418static struct snd_soc_codec_driver max9867_codec = { 417static struct snd_soc_codec_driver max9867_codec = {
419 .probe = max9867_probe, 418 .probe = max9867_probe,
420 .controls = max9867_snd_controls, 419 .component_driver = {
421 .num_controls = ARRAY_SIZE(max9867_snd_controls), 420 .controls = max9867_snd_controls,
422 .dapm_routes = max9867_audio_map, 421 .num_controls = ARRAY_SIZE(max9867_snd_controls),
423 .num_dapm_routes = ARRAY_SIZE(max9867_audio_map), 422 .dapm_routes = max9867_audio_map,
424 .dapm_widgets = max9867_dapm_widgets, 423 .num_dapm_routes = ARRAY_SIZE(max9867_audio_map),
425 .num_dapm_widgets = ARRAY_SIZE(max9867_dapm_widgets), 424 .dapm_widgets = max9867_dapm_widgets,
425 .num_dapm_widgets = ARRAY_SIZE(max9867_dapm_widgets),
426 },
426}; 427};
427 428
428static bool max9867_volatile_register(struct device *dev, unsigned int reg) 429static bool max9867_volatile_register(struct device *dev, unsigned int reg)
diff --git a/sound/soc/codecs/max98925.c b/sound/soc/codecs/max98925.c
index 5990de317999..327eaa25c9bd 100644
--- a/sound/soc/codecs/max98925.c
+++ b/sound/soc/codecs/max98925.c
@@ -540,12 +540,14 @@ static int max98925_probe(struct snd_soc_codec *codec)
540 540
541static const struct snd_soc_codec_driver soc_codec_dev_max98925 = { 541static const struct snd_soc_codec_driver soc_codec_dev_max98925 = {
542 .probe = max98925_probe, 542 .probe = max98925_probe,
543 .controls = max98925_snd_controls, 543 .component_driver = {
544 .num_controls = ARRAY_SIZE(max98925_snd_controls), 544 .controls = max98925_snd_controls,
545 .dapm_routes = max98925_audio_map, 545 .num_controls = ARRAY_SIZE(max98925_snd_controls),
546 .num_dapm_routes = ARRAY_SIZE(max98925_audio_map), 546 .dapm_routes = max98925_audio_map,
547 .dapm_widgets = max98925_dapm_widgets, 547 .num_dapm_routes = ARRAY_SIZE(max98925_audio_map),
548 .num_dapm_widgets = ARRAY_SIZE(max98925_dapm_widgets), 548 .dapm_widgets = max98925_dapm_widgets,
549 .num_dapm_widgets = ARRAY_SIZE(max98925_dapm_widgets),
550 },
549}; 551};
550 552
551static const struct regmap_config max98925_regmap = { 553static const struct regmap_config max98925_regmap = {
diff --git a/sound/soc/codecs/max98926.c b/sound/soc/codecs/max98926.c
index 8d14adae5cc5..1eff7e0b092e 100644
--- a/sound/soc/codecs/max98926.c
+++ b/sound/soc/codecs/max98926.c
@@ -347,7 +347,7 @@ static int max98926_dai_set_fmt(struct snd_soc_dai *codec_dai,
347 max98926_set_sense_data(max98926); 347 max98926_set_sense_data(max98926);
348 break; 348 break;
349 default: 349 default:
350 dev_err(codec->dev, "DAI clock mode unsupported"); 350 dev_err(codec->dev, "DAI clock mode unsupported\n");
351 return -EINVAL; 351 return -EINVAL;
352 } 352 }
353 353
@@ -364,7 +364,7 @@ static int max98926_dai_set_fmt(struct snd_soc_dai *codec_dai,
364 invert = MAX98926_DAI_BCI_MASK | MAX98926_DAI_WCI_MASK; 364 invert = MAX98926_DAI_BCI_MASK | MAX98926_DAI_WCI_MASK;
365 break; 365 break;
366 default: 366 default:
367 dev_err(codec->dev, "DAI invert mode unsupported"); 367 dev_err(codec->dev, "DAI invert mode unsupported\n");
368 return -EINVAL; 368 return -EINVAL;
369 } 369 }
370 370
@@ -408,7 +408,7 @@ static int max98926_dai_hw_params(struct snd_pcm_substream *substream,
408 max98926->ch_size = 32; 408 max98926->ch_size = 32;
409 break; 409 break;
410 default: 410 default:
411 dev_dbg(codec->dev, "format unsupported %d", 411 dev_dbg(codec->dev, "format unsupported %d\n",
412 params_format(params)); 412 params_format(params));
413 return -EINVAL; 413 return -EINVAL;
414 } 414 }
@@ -498,12 +498,14 @@ static int max98926_probe(struct snd_soc_codec *codec)
498 498
499static struct snd_soc_codec_driver soc_codec_dev_max98926 = { 499static struct snd_soc_codec_driver soc_codec_dev_max98926 = {
500 .probe = max98926_probe, 500 .probe = max98926_probe,
501 .controls = max98926_snd_controls, 501 .component_driver = {
502 .num_controls = ARRAY_SIZE(max98926_snd_controls), 502 .controls = max98926_snd_controls,
503 .dapm_routes = max98926_audio_map, 503 .num_controls = ARRAY_SIZE(max98926_snd_controls),
504 .num_dapm_routes = ARRAY_SIZE(max98926_audio_map), 504 .dapm_routes = max98926_audio_map,
505 .dapm_widgets = max98926_dapm_widgets, 505 .num_dapm_routes = ARRAY_SIZE(max98926_audio_map),
506 .num_dapm_widgets = ARRAY_SIZE(max98926_dapm_widgets), 506 .dapm_widgets = max98926_dapm_widgets,
507 .num_dapm_widgets = ARRAY_SIZE(max98926_dapm_widgets),
508 },
507}; 509};
508 510
509static const struct regmap_config max98926_regmap = { 511static const struct regmap_config max98926_regmap = {
diff --git a/sound/soc/codecs/mc13783.c b/sound/soc/codecs/mc13783.c
index 3e770cbe7f0f..90562703dcfd 100644
--- a/sound/soc/codecs/mc13783.c
+++ b/sound/soc/codecs/mc13783.c
@@ -737,12 +737,14 @@ static struct snd_soc_codec_driver soc_codec_dev_mc13783 = {
737 .probe = mc13783_probe, 737 .probe = mc13783_probe,
738 .remove = mc13783_remove, 738 .remove = mc13783_remove,
739 .get_regmap = mc13783_get_regmap, 739 .get_regmap = mc13783_get_regmap,
740 .controls = mc13783_control_list, 740 .component_driver = {
741 .num_controls = ARRAY_SIZE(mc13783_control_list), 741 .controls = mc13783_control_list,
742 .dapm_widgets = mc13783_dapm_widgets, 742 .num_controls = ARRAY_SIZE(mc13783_control_list),
743 .num_dapm_widgets = ARRAY_SIZE(mc13783_dapm_widgets), 743 .dapm_widgets = mc13783_dapm_widgets,
744 .dapm_routes = mc13783_routes, 744 .num_dapm_widgets = ARRAY_SIZE(mc13783_dapm_widgets),
745 .num_dapm_routes = ARRAY_SIZE(mc13783_routes), 745 .dapm_routes = mc13783_routes,
746 .num_dapm_routes = ARRAY_SIZE(mc13783_routes),
747 },
746}; 748};
747 749
748static int __init mc13783_codec_probe(struct platform_device *pdev) 750static int __init mc13783_codec_probe(struct platform_device *pdev)
diff --git a/sound/soc/codecs/ml26124.c b/sound/soc/codecs/ml26124.c
index f561c78b9e0e..69e5e18880c5 100644
--- a/sound/soc/codecs/ml26124.c
+++ b/sound/soc/codecs/ml26124.c
@@ -541,12 +541,14 @@ static struct snd_soc_codec_driver soc_codec_dev_ml26124 = {
541 .probe = ml26124_probe, 541 .probe = ml26124_probe,
542 .set_bias_level = ml26124_set_bias_level, 542 .set_bias_level = ml26124_set_bias_level,
543 .suspend_bias_off = true, 543 .suspend_bias_off = true,
544 .dapm_widgets = ml26124_dapm_widgets, 544 .component_driver = {
545 .num_dapm_widgets = ARRAY_SIZE(ml26124_dapm_widgets), 545 .controls = ml26124_snd_controls,
546 .dapm_routes = ml26124_intercon, 546 .num_controls = ARRAY_SIZE(ml26124_snd_controls),
547 .num_dapm_routes = ARRAY_SIZE(ml26124_intercon), 547 .dapm_widgets = ml26124_dapm_widgets,
548 .controls = ml26124_snd_controls, 548 .num_dapm_widgets = ARRAY_SIZE(ml26124_dapm_widgets),
549 .num_controls = ARRAY_SIZE(ml26124_snd_controls), 549 .dapm_routes = ml26124_intercon,
550 .num_dapm_routes = ARRAY_SIZE(ml26124_intercon),
551 },
550}; 552};
551 553
552static const struct regmap_config ml26124_i2c_regmap = { 554static const struct regmap_config ml26124_i2c_regmap = {
diff --git a/sound/soc/codecs/nau8810.c b/sound/soc/codecs/nau8810.c
new file mode 100644
index 000000000000..e45518629968
--- /dev/null
+++ b/sound/soc/codecs/nau8810.c
@@ -0,0 +1,884 @@
1/*
2 * nau8810.c -- NAU8810 ALSA Soc Audio driver
3 *
4 * Copyright 2016 Nuvoton Technology Corp.
5 *
6 * Author: David Lin <ctlin0@nuvoton.com>
7 *
8 * Based on WM8974.c
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation.
13 */
14
15#include <linux/module.h>
16#include <linux/moduleparam.h>
17#include <linux/kernel.h>
18#include <linux/init.h>
19#include <linux/delay.h>
20#include <linux/pm.h>
21#include <linux/i2c.h>
22#include <linux/regmap.h>
23#include <linux/slab.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/initval.h>
29#include <sound/tlv.h>
30
31#include "nau8810.h"
32
33#define NAU_PLL_FREQ_MAX 100000000
34#define NAU_PLL_FREQ_MIN 90000000
35#define NAU_PLL_REF_MAX 33000000
36#define NAU_PLL_REF_MIN 8000000
37#define NAU_PLL_OPTOP_MIN 6
38
39
40static const int nau8810_mclk_scaler[] = { 10, 15, 20, 30, 40, 60, 80, 120 };
41
42static const struct reg_default nau8810_reg_defaults[] = {
43 { NAU8810_REG_POWER1, 0x0000 },
44 { NAU8810_REG_POWER2, 0x0000 },
45 { NAU8810_REG_POWER3, 0x0000 },
46 { NAU8810_REG_IFACE, 0x0050 },
47 { NAU8810_REG_COMP, 0x0000 },
48 { NAU8810_REG_CLOCK, 0x0140 },
49 { NAU8810_REG_SMPLR, 0x0000 },
50 { NAU8810_REG_DAC, 0x0000 },
51 { NAU8810_REG_DACGAIN, 0x00FF },
52 { NAU8810_REG_ADC, 0x0100 },
53 { NAU8810_REG_ADCGAIN, 0x00FF },
54 { NAU8810_REG_EQ1, 0x012C },
55 { NAU8810_REG_EQ2, 0x002C },
56 { NAU8810_REG_EQ3, 0x002C },
57 { NAU8810_REG_EQ4, 0x002C },
58 { NAU8810_REG_EQ5, 0x002C },
59 { NAU8810_REG_DACLIM1, 0x0032 },
60 { NAU8810_REG_DACLIM2, 0x0000 },
61 { NAU8810_REG_NOTCH1, 0x0000 },
62 { NAU8810_REG_NOTCH2, 0x0000 },
63 { NAU8810_REG_NOTCH3, 0x0000 },
64 { NAU8810_REG_NOTCH4, 0x0000 },
65 { NAU8810_REG_ALC1, 0x0038 },
66 { NAU8810_REG_ALC2, 0x000B },
67 { NAU8810_REG_ALC3, 0x0032 },
68 { NAU8810_REG_NOISEGATE, 0x0000 },
69 { NAU8810_REG_PLLN, 0x0008 },
70 { NAU8810_REG_PLLK1, 0x000C },
71 { NAU8810_REG_PLLK2, 0x0093 },
72 { NAU8810_REG_PLLK3, 0x00E9 },
73 { NAU8810_REG_ATTEN, 0x0000 },
74 { NAU8810_REG_INPUT_SIGNAL, 0x0003 },
75 { NAU8810_REG_PGAGAIN, 0x0010 },
76 { NAU8810_REG_ADCBOOST, 0x0100 },
77 { NAU8810_REG_OUTPUT, 0x0002 },
78 { NAU8810_REG_SPKMIX, 0x0001 },
79 { NAU8810_REG_SPKGAIN, 0x0039 },
80 { NAU8810_REG_MONOMIX, 0x0001 },
81 { NAU8810_REG_POWER4, 0x0000 },
82 { NAU8810_REG_TSLOTCTL1, 0x0000 },
83 { NAU8810_REG_TSLOTCTL2, 0x0020 },
84 { NAU8810_REG_DEVICE_REVID, 0x0000 },
85 { NAU8810_REG_I2C_DEVICEID, 0x001A },
86 { NAU8810_REG_ADDITIONID, 0x00CA },
87 { NAU8810_REG_RESERVE, 0x0124 },
88 { NAU8810_REG_OUTCTL, 0x0001 },
89 { NAU8810_REG_ALC1ENHAN1, 0x0010 },
90 { NAU8810_REG_ALC1ENHAN2, 0x0000 },
91 { NAU8810_REG_MISCCTL, 0x0000 },
92 { NAU8810_REG_OUTTIEOFF, 0x0000 },
93 { NAU8810_REG_AGCP2POUT, 0x0000 },
94 { NAU8810_REG_AGCPOUT, 0x0000 },
95 { NAU8810_REG_AMTCTL, 0x0000 },
96 { NAU8810_REG_OUTTIEOFFMAN, 0x0000 },
97};
98
99static bool nau8810_readable_reg(struct device *dev, unsigned int reg)
100{
101 switch (reg) {
102 case NAU8810_REG_RESET ... NAU8810_REG_SMPLR:
103 case NAU8810_REG_DAC ... NAU8810_REG_DACGAIN:
104 case NAU8810_REG_ADC ... NAU8810_REG_ADCGAIN:
105 case NAU8810_REG_EQ1 ... NAU8810_REG_EQ5:
106 case NAU8810_REG_DACLIM1 ... NAU8810_REG_DACLIM2:
107 case NAU8810_REG_NOTCH1 ... NAU8810_REG_NOTCH4:
108 case NAU8810_REG_ALC1 ... NAU8810_REG_ATTEN:
109 case NAU8810_REG_INPUT_SIGNAL ... NAU8810_REG_PGAGAIN:
110 case NAU8810_REG_ADCBOOST:
111 case NAU8810_REG_OUTPUT ... NAU8810_REG_SPKMIX:
112 case NAU8810_REG_SPKGAIN:
113 case NAU8810_REG_MONOMIX:
114 case NAU8810_REG_POWER4 ... NAU8810_REG_TSLOTCTL2:
115 case NAU8810_REG_DEVICE_REVID ... NAU8810_REG_RESERVE:
116 case NAU8810_REG_OUTCTL ... NAU8810_REG_ALC1ENHAN2:
117 case NAU8810_REG_MISCCTL:
118 case NAU8810_REG_OUTTIEOFF ... NAU8810_REG_OUTTIEOFFMAN:
119 return true;
120 default:
121 return false;
122 }
123}
124
125static bool nau8810_writeable_reg(struct device *dev, unsigned int reg)
126{
127 switch (reg) {
128 case NAU8810_REG_RESET ... NAU8810_REG_SMPLR:
129 case NAU8810_REG_DAC ... NAU8810_REG_DACGAIN:
130 case NAU8810_REG_ADC ... NAU8810_REG_ADCGAIN:
131 case NAU8810_REG_EQ1 ... NAU8810_REG_EQ5:
132 case NAU8810_REG_DACLIM1 ... NAU8810_REG_DACLIM2:
133 case NAU8810_REG_NOTCH1 ... NAU8810_REG_NOTCH4:
134 case NAU8810_REG_ALC1 ... NAU8810_REG_ATTEN:
135 case NAU8810_REG_INPUT_SIGNAL ... NAU8810_REG_PGAGAIN:
136 case NAU8810_REG_ADCBOOST:
137 case NAU8810_REG_OUTPUT ... NAU8810_REG_SPKMIX:
138 case NAU8810_REG_SPKGAIN:
139 case NAU8810_REG_MONOMIX:
140 case NAU8810_REG_POWER4 ... NAU8810_REG_TSLOTCTL2:
141 case NAU8810_REG_OUTCTL ... NAU8810_REG_ALC1ENHAN2:
142 case NAU8810_REG_MISCCTL:
143 case NAU8810_REG_OUTTIEOFF ... NAU8810_REG_OUTTIEOFFMAN:
144 return true;
145 default:
146 return false;
147 }
148}
149
150static bool nau8810_volatile_reg(struct device *dev, unsigned int reg)
151{
152 switch (reg) {
153 case NAU8810_REG_RESET:
154 case NAU8810_REG_DEVICE_REVID ... NAU8810_REG_RESERVE:
155 return true;
156 default:
157 return false;
158 }
159}
160
161/* The EQ parameters get function is to get the 5 band equalizer control.
162 * The regmap raw read can't work here because regmap doesn't provide
163 * value format for value width of 9 bits. Therefore, the driver reads data
164 * from cache and makes value format according to the endianness of
165 * bytes type control element.
166 */
167static int nau8810_eq_get(struct snd_kcontrol *kcontrol,
168 struct snd_ctl_elem_value *ucontrol)
169{
170 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
171 struct nau8810 *nau8810 = snd_soc_codec_get_drvdata(codec);
172 struct soc_bytes_ext *params = (void *)kcontrol->private_value;
173 int i, reg, reg_val;
174 u16 *val;
175
176 val = (u16 *)ucontrol->value.bytes.data;
177 reg = NAU8810_REG_EQ1;
178 for (i = 0; i < params->max / sizeof(u16); i++) {
179 regmap_read(nau8810->regmap, reg + i, &reg_val);
180 /* conversion of 16-bit integers between native CPU format
181 * and big endian format
182 */
183 reg_val = cpu_to_be16(reg_val);
184 memcpy(val + i, &reg_val, sizeof(reg_val));
185 }
186
187 return 0;
188}
189
190/* The EQ parameters put function is to make configuration of 5 band equalizer
191 * control. These configuration includes central frequency, equalizer gain,
192 * cut-off frequency, bandwidth control, and equalizer path.
193 * The regmap raw write can't work here because regmap doesn't provide
194 * register and value format for register with address 7 bits and value 9 bits.
195 * Therefore, the driver makes value format according to the endianness of
196 * bytes type control element and writes data to codec.
197 */
198static int nau8810_eq_put(struct snd_kcontrol *kcontrol,
199 struct snd_ctl_elem_value *ucontrol)
200{
201 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
202 struct nau8810 *nau8810 = snd_soc_codec_get_drvdata(codec);
203 struct soc_bytes_ext *params = (void *)kcontrol->private_value;
204 void *data;
205 u16 *val, value;
206 int i, reg, ret;
207
208 data = kmemdup(ucontrol->value.bytes.data,
209 params->max, GFP_KERNEL | GFP_DMA);
210 if (!data)
211 return -ENOMEM;
212
213 val = (u16 *)data;
214 reg = NAU8810_REG_EQ1;
215 for (i = 0; i < params->max / sizeof(u16); i++) {
216 /* conversion of 16-bit integers between native CPU format
217 * and big endian format
218 */
219 value = be16_to_cpu(*(val + i));
220 ret = regmap_write(nau8810->regmap, reg + i, value);
221 if (ret) {
222 dev_err(codec->dev, "EQ configuration fail, register: %x ret: %d\n",
223 reg + i, ret);
224 kfree(data);
225 return ret;
226 }
227 }
228 kfree(data);
229
230 return 0;
231}
232
233static const char * const nau8810_companding[] = {
234 "Off", "NC", "u-law", "A-law" };
235
236static const struct soc_enum nau8810_companding_adc_enum =
237 SOC_ENUM_SINGLE(NAU8810_REG_COMP, NAU8810_ADCCM_SFT,
238 ARRAY_SIZE(nau8810_companding), nau8810_companding);
239
240static const struct soc_enum nau8810_companding_dac_enum =
241 SOC_ENUM_SINGLE(NAU8810_REG_COMP, NAU8810_DACCM_SFT,
242 ARRAY_SIZE(nau8810_companding), nau8810_companding);
243
244static const char * const nau8810_deemp[] = {
245 "None", "32kHz", "44.1kHz", "48kHz" };
246
247static const struct soc_enum nau8810_deemp_enum =
248 SOC_ENUM_SINGLE(NAU8810_REG_DAC, NAU8810_DEEMP_SFT,
249 ARRAY_SIZE(nau8810_deemp), nau8810_deemp);
250
251static const char * const nau8810_eqmode[] = {"Capture", "Playback" };
252
253static const struct soc_enum nau8810_eqmode_enum =
254 SOC_ENUM_SINGLE(NAU8810_REG_EQ1, NAU8810_EQM_SFT,
255 ARRAY_SIZE(nau8810_eqmode), nau8810_eqmode);
256
257static const char * const nau8810_alc[] = {"Normal", "Limiter" };
258
259static const struct soc_enum nau8810_alc_enum =
260 SOC_ENUM_SINGLE(NAU8810_REG_ALC3, NAU8810_ALCM_SFT,
261 ARRAY_SIZE(nau8810_alc), nau8810_alc);
262
263static const DECLARE_TLV_DB_SCALE(digital_tlv, -12750, 50, 1);
264static const DECLARE_TLV_DB_SCALE(eq_tlv, -1200, 100, 0);
265static const DECLARE_TLV_DB_SCALE(inpga_tlv, -1200, 75, 0);
266static const DECLARE_TLV_DB_SCALE(spk_tlv, -5700, 100, 0);
267
268static const struct snd_kcontrol_new nau8810_snd_controls[] = {
269 SOC_ENUM("ADC Companding", nau8810_companding_adc_enum),
270 SOC_ENUM("DAC Companding", nau8810_companding_dac_enum),
271 SOC_ENUM("DAC De-emphasis", nau8810_deemp_enum),
272
273 SOC_ENUM("EQ Function", nau8810_eqmode_enum),
274 SND_SOC_BYTES_EXT("EQ Parameters", 10,
275 nau8810_eq_get, nau8810_eq_put),
276
277 SOC_SINGLE("DAC Inversion Switch", NAU8810_REG_DAC,
278 NAU8810_DACPL_SFT, 1, 0),
279 SOC_SINGLE_TLV("Playback Volume", NAU8810_REG_DACGAIN,
280 NAU8810_DACGAIN_SFT, 0xff, 0, digital_tlv),
281
282 SOC_SINGLE("High Pass Filter Switch", NAU8810_REG_ADC,
283 NAU8810_HPFEN_SFT, 1, 0),
284 SOC_SINGLE("High Pass Cut Off", NAU8810_REG_ADC,
285 NAU8810_HPF_SFT, 0x7, 0),
286
287 SOC_SINGLE("ADC Inversion Switch", NAU8810_REG_ADC,
288 NAU8810_ADCPL_SFT, 1, 0),
289 SOC_SINGLE_TLV("Capture Volume", NAU8810_REG_ADCGAIN,
290 NAU8810_ADCGAIN_SFT, 0xff, 0, digital_tlv),
291
292 SOC_SINGLE_TLV("EQ1 Volume", NAU8810_REG_EQ1,
293 NAU8810_EQ1GC_SFT, 0x18, 1, eq_tlv),
294 SOC_SINGLE_TLV("EQ2 Volume", NAU8810_REG_EQ2,
295 NAU8810_EQ2GC_SFT, 0x18, 1, eq_tlv),
296 SOC_SINGLE_TLV("EQ3 Volume", NAU8810_REG_EQ3,
297 NAU8810_EQ3GC_SFT, 0x18, 1, eq_tlv),
298 SOC_SINGLE_TLV("EQ4 Volume", NAU8810_REG_EQ4,
299 NAU8810_EQ4GC_SFT, 0x18, 1, eq_tlv),
300 SOC_SINGLE_TLV("EQ5 Volume", NAU8810_REG_EQ5,
301 NAU8810_EQ5GC_SFT, 0x18, 1, eq_tlv),
302
303 SOC_SINGLE("DAC Limiter Switch", NAU8810_REG_DACLIM1,
304 NAU8810_DACLIMEN_SFT, 1, 0),
305 SOC_SINGLE("DAC Limiter Decay", NAU8810_REG_DACLIM1,
306 NAU8810_DACLIMDCY_SFT, 0xf, 0),
307 SOC_SINGLE("DAC Limiter Attack", NAU8810_REG_DACLIM1,
308 NAU8810_DACLIMATK_SFT, 0xf, 0),
309 SOC_SINGLE("DAC Limiter Threshold", NAU8810_REG_DACLIM2,
310 NAU8810_DACLIMTHL_SFT, 0x7, 0),
311 SOC_SINGLE("DAC Limiter Boost", NAU8810_REG_DACLIM2,
312 NAU8810_DACLIMBST_SFT, 0xf, 0),
313
314 SOC_ENUM("ALC Mode", nau8810_alc_enum),
315 SOC_SINGLE("ALC Enable Switch", NAU8810_REG_ALC1,
316 NAU8810_ALCEN_SFT, 1, 0),
317 SOC_SINGLE("ALC Max Volume", NAU8810_REG_ALC1,
318 NAU8810_ALCMXGAIN_SFT, 0x7, 0),
319 SOC_SINGLE("ALC Min Volume", NAU8810_REG_ALC1,
320 NAU8810_ALCMINGAIN_SFT, 0x7, 0),
321 SOC_SINGLE("ALC ZC Switch", NAU8810_REG_ALC2,
322 NAU8810_ALCZC_SFT, 1, 0),
323 SOC_SINGLE("ALC Hold", NAU8810_REG_ALC2,
324 NAU8810_ALCHT_SFT, 0xf, 0),
325 SOC_SINGLE("ALC Target", NAU8810_REG_ALC2,
326 NAU8810_ALCSL_SFT, 0xf, 0),
327 SOC_SINGLE("ALC Decay", NAU8810_REG_ALC3,
328 NAU8810_ALCDCY_SFT, 0xf, 0),
329 SOC_SINGLE("ALC Attack", NAU8810_REG_ALC3,
330 NAU8810_ALCATK_SFT, 0xf, 0),
331 SOC_SINGLE("ALC Noise Gate Switch", NAU8810_REG_NOISEGATE,
332 NAU8810_ALCNEN_SFT, 1, 0),
333 SOC_SINGLE("ALC Noise Gate Threshold", NAU8810_REG_NOISEGATE,
334 NAU8810_ALCNTH_SFT, 0x7, 0),
335
336 SOC_SINGLE("PGA ZC Switch", NAU8810_REG_PGAGAIN,
337 NAU8810_PGAZC_SFT, 1, 0),
338 SOC_SINGLE_TLV("PGA Volume", NAU8810_REG_PGAGAIN,
339 NAU8810_PGAGAIN_SFT, 0x3f, 0, inpga_tlv),
340
341 SOC_SINGLE("Speaker ZC Switch", NAU8810_REG_SPKGAIN,
342 NAU8810_SPKZC_SFT, 1, 0),
343 SOC_SINGLE("Speaker Mute Switch", NAU8810_REG_SPKGAIN,
344 NAU8810_SPKMT_SFT, 1, 0),
345 SOC_SINGLE_TLV("Speaker Volume", NAU8810_REG_SPKGAIN,
346 NAU8810_SPKGAIN_SFT, 0x3f, 0, spk_tlv),
347
348 SOC_SINGLE("Capture Boost(+20dB)", NAU8810_REG_ADCBOOST,
349 NAU8810_PGABST_SFT, 1, 0),
350 SOC_SINGLE("Mono Mute Switch", NAU8810_REG_MONOMIX,
351 NAU8810_MOUTMXMT_SFT, 1, 0),
352
353 SOC_SINGLE("DAC Oversampling Rate(128x) Switch", NAU8810_REG_DAC,
354 NAU8810_DACOS_SFT, 1, 0),
355 SOC_SINGLE("ADC Oversampling Rate(128x) Switch", NAU8810_REG_ADC,
356 NAU8810_ADCOS_SFT, 1, 0),
357};
358
359/* Speaker Output Mixer */
360static const struct snd_kcontrol_new nau8810_speaker_mixer_controls[] = {
361 SOC_DAPM_SINGLE("Line Bypass Switch", NAU8810_REG_SPKMIX,
362 NAU8810_BYPSPK_SFT, 1, 0),
363 SOC_DAPM_SINGLE("PCM Playback Switch", NAU8810_REG_SPKMIX,
364 NAU8810_DACSPK_SFT, 1, 0),
365};
366
367/* Mono Output Mixer */
368static const struct snd_kcontrol_new nau8810_mono_mixer_controls[] = {
369 SOC_DAPM_SINGLE("Line Bypass Switch", NAU8810_REG_MONOMIX,
370 NAU8810_BYPMOUT_SFT, 1, 0),
371 SOC_DAPM_SINGLE("PCM Playback Switch", NAU8810_REG_MONOMIX,
372 NAU8810_DACMOUT_SFT, 1, 0),
373};
374
375/* PGA Mute */
376static const struct snd_kcontrol_new nau8810_inpga_mute[] = {
377 SOC_DAPM_SINGLE("PGA Mute Switch", NAU8810_REG_PGAGAIN,
378 NAU8810_PGAMT_SFT, 1, 0),
379};
380
381/* Input PGA */
382static const struct snd_kcontrol_new nau8810_inpga[] = {
383 SOC_DAPM_SINGLE("MicN Switch", NAU8810_REG_INPUT_SIGNAL,
384 NAU8810_NMICPGA_SFT, 1, 0),
385 SOC_DAPM_SINGLE("MicP Switch", NAU8810_REG_INPUT_SIGNAL,
386 NAU8810_PMICPGA_SFT, 1, 0),
387};
388
389/* Mic Input boost vol */
390static const struct snd_kcontrol_new nau8810_mic_boost_controls =
391 SOC_DAPM_SINGLE("Mic Volume", NAU8810_REG_ADCBOOST,
392 NAU8810_PMICBSTGAIN_SFT, 0x7, 0);
393
394/* Loopback Switch */
395static const struct snd_kcontrol_new nau8810_loopback =
396 SOC_DAPM_SINGLE("Switch", NAU8810_REG_COMP,
397 NAU8810_ADDAP_SFT, 1, 0);
398
399static int check_mclk_select_pll(struct snd_soc_dapm_widget *source,
400 struct snd_soc_dapm_widget *sink)
401{
402 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(source->dapm);
403 struct nau8810 *nau8810 = snd_soc_codec_get_drvdata(codec);
404 unsigned int value;
405
406 regmap_read(nau8810->regmap, NAU8810_REG_CLOCK, &value);
407 return (value & NAU8810_CLKM_MASK);
408}
409
410static const struct snd_soc_dapm_widget nau8810_dapm_widgets[] = {
411 SND_SOC_DAPM_MIXER("Speaker Mixer", NAU8810_REG_POWER3,
412 NAU8810_SPKMX_EN_SFT, 0, &nau8810_speaker_mixer_controls[0],
413 ARRAY_SIZE(nau8810_speaker_mixer_controls)),
414 SND_SOC_DAPM_MIXER("Mono Mixer", NAU8810_REG_POWER3,
415 NAU8810_MOUTMX_EN_SFT, 0, &nau8810_mono_mixer_controls[0],
416 ARRAY_SIZE(nau8810_mono_mixer_controls)),
417 SND_SOC_DAPM_DAC("DAC", "HiFi Playback", NAU8810_REG_POWER3,
418 NAU8810_DAC_EN_SFT, 0),
419 SND_SOC_DAPM_ADC("ADC", "HiFi Capture", NAU8810_REG_POWER2,
420 NAU8810_ADC_EN_SFT, 0),
421 SND_SOC_DAPM_PGA("SpkN Out", NAU8810_REG_POWER3,
422 NAU8810_NSPK_EN_SFT, 0, NULL, 0),
423 SND_SOC_DAPM_PGA("SpkP Out", NAU8810_REG_POWER3,
424 NAU8810_PSPK_EN_SFT, 0, NULL, 0),
425 SND_SOC_DAPM_PGA("Mono Out", NAU8810_REG_POWER3,
426 NAU8810_MOUT_EN_SFT, 0, NULL, 0),
427
428 SND_SOC_DAPM_MIXER("Input PGA", NAU8810_REG_POWER2,
429 NAU8810_PGA_EN_SFT, 0, nau8810_inpga,
430 ARRAY_SIZE(nau8810_inpga)),
431 SND_SOC_DAPM_MIXER("Input Boost Stage", NAU8810_REG_POWER2,
432 NAU8810_BST_EN_SFT, 0, nau8810_inpga_mute,
433 ARRAY_SIZE(nau8810_inpga_mute)),
434
435 SND_SOC_DAPM_SUPPLY("Mic Bias", NAU8810_REG_POWER1,
436 NAU8810_MICBIAS_EN_SFT, 0, NULL, 0),
437 SND_SOC_DAPM_SUPPLY("PLL", NAU8810_REG_POWER1,
438 NAU8810_PLL_EN_SFT, 0, NULL, 0),
439
440 SND_SOC_DAPM_SWITCH("Digital Loopback", SND_SOC_NOPM, 0, 0,
441 &nau8810_loopback),
442
443 SND_SOC_DAPM_INPUT("MICN"),
444 SND_SOC_DAPM_INPUT("MICP"),
445 SND_SOC_DAPM_OUTPUT("MONOOUT"),
446 SND_SOC_DAPM_OUTPUT("SPKOUTP"),
447 SND_SOC_DAPM_OUTPUT("SPKOUTN"),
448};
449
450static const struct snd_soc_dapm_route nau8810_dapm_routes[] = {
451 {"DAC", NULL, "PLL", check_mclk_select_pll},
452
453 /* Mono output mixer */
454 {"Mono Mixer", "PCM Playback Switch", "DAC"},
455 {"Mono Mixer", "Line Bypass Switch", "Input Boost Stage"},
456
457 /* Speaker output mixer */
458 {"Speaker Mixer", "PCM Playback Switch", "DAC"},
459 {"Speaker Mixer", "Line Bypass Switch", "Input Boost Stage"},
460
461 /* Outputs */
462 {"Mono Out", NULL, "Mono Mixer"},
463 {"MONOOUT", NULL, "Mono Out"},
464 {"SpkN Out", NULL, "Speaker Mixer"},
465 {"SpkP Out", NULL, "Speaker Mixer"},
466 {"SPKOUTN", NULL, "SpkN Out"},
467 {"SPKOUTP", NULL, "SpkP Out"},
468
469 /* Input Boost Stage */
470 {"ADC", NULL, "Input Boost Stage"},
471 {"ADC", NULL, "PLL", check_mclk_select_pll},
472 {"Input Boost Stage", NULL, "Input PGA"},
473 {"Input Boost Stage", NULL, "MICP"},
474
475 /* Input PGA */
476 {"Input PGA", NULL, "Mic Bias"},
477 {"Input PGA", "MicN Switch", "MICN"},
478 {"Input PGA", "MicP Switch", "MICP"},
479
480 /* Digital Looptack */
481 {"Digital Loopback", "Switch", "ADC"},
482 {"DAC", NULL, "Digital Loopback"},
483};
484
485static int nau8810_set_sysclk(struct snd_soc_dai *dai,
486 int clk_id, unsigned int freq, int dir)
487{
488 struct snd_soc_codec *codec = dai->codec;
489 struct nau8810 *nau8810 = snd_soc_codec_get_drvdata(codec);
490
491 nau8810->clk_id = clk_id;
492 nau8810->sysclk = freq;
493 dev_dbg(nau8810->dev, "master sysclk %dHz, source %s\n",
494 freq, clk_id == NAU8810_SCLK_PLL ? "PLL" : "MCLK");
495
496 return 0;
497}
498
499static int nau88l0_calc_pll(unsigned int pll_in,
500 unsigned int fs, struct nau8810_pll *pll_param)
501{
502 u64 f2, f2_max, pll_ratio;
503 int i, scal_sel;
504
505 if (pll_in > NAU_PLL_REF_MAX || pll_in < NAU_PLL_REF_MIN)
506 return -EINVAL;
507
508 f2_max = 0;
509 scal_sel = ARRAY_SIZE(nau8810_mclk_scaler);
510 for (i = 0; i < ARRAY_SIZE(nau8810_mclk_scaler); i++) {
511 f2 = 256 * fs * 4 * nau8810_mclk_scaler[i] / 10;
512 if (f2 > NAU_PLL_FREQ_MIN && f2 < NAU_PLL_FREQ_MAX &&
513 f2_max < f2) {
514 f2_max = f2;
515 scal_sel = i;
516 }
517 }
518 if (ARRAY_SIZE(nau8810_mclk_scaler) == scal_sel)
519 return -EINVAL;
520 pll_param->mclk_scaler = scal_sel;
521 f2 = f2_max;
522
523 /* Calculate the PLL 4-bit integer input and the PLL 24-bit fractional
524 * input; round up the 24+4bit.
525 */
526 pll_ratio = div_u64(f2 << 28, pll_in);
527 pll_param->pre_factor = 0;
528 if (((pll_ratio >> 28) & 0xF) < NAU_PLL_OPTOP_MIN) {
529 pll_ratio <<= 1;
530 pll_param->pre_factor = 1;
531 }
532 pll_param->pll_int = (pll_ratio >> 28) & 0xF;
533 pll_param->pll_frac = ((pll_ratio & 0xFFFFFFF) >> 4);
534
535 return 0;
536}
537
538static int nau8810_set_pll(struct snd_soc_dai *codec_dai, int pll_id,
539 int source, unsigned int freq_in, unsigned int freq_out)
540{
541 struct snd_soc_codec *codec = codec_dai->codec;
542 struct nau8810 *nau8810 = snd_soc_codec_get_drvdata(codec);
543 struct regmap *map = nau8810->regmap;
544 struct nau8810_pll *pll_param = &nau8810->pll;
545 int ret, fs;
546
547 fs = freq_out / 256;
548 ret = nau88l0_calc_pll(freq_in, fs, pll_param);
549 if (ret < 0) {
550 dev_err(nau8810->dev, "Unsupported input clock %d\n", freq_in);
551 return ret;
552 }
553 dev_info(nau8810->dev, "pll_int=%x pll_frac=%x mclk_scaler=%x pre_factor=%x\n",
554 pll_param->pll_int, pll_param->pll_frac, pll_param->mclk_scaler,
555 pll_param->pre_factor);
556
557 regmap_update_bits(map, NAU8810_REG_PLLN,
558 NAU8810_PLLMCLK_DIV2 | NAU8810_PLLN_MASK,
559 (pll_param->pre_factor ? NAU8810_PLLMCLK_DIV2 : 0) |
560 pll_param->pll_int);
561 regmap_write(map, NAU8810_REG_PLLK1,
562 (pll_param->pll_frac >> NAU8810_PLLK1_SFT) &
563 NAU8810_PLLK1_MASK);
564 regmap_write(map, NAU8810_REG_PLLK2,
565 (pll_param->pll_frac >> NAU8810_PLLK2_SFT) &
566 NAU8810_PLLK2_MASK);
567 regmap_write(map, NAU8810_REG_PLLK3,
568 pll_param->pll_frac & NAU8810_PLLK3_MASK);
569 regmap_update_bits(map, NAU8810_REG_CLOCK, NAU8810_MCLKSEL_MASK,
570 pll_param->mclk_scaler << NAU8810_MCLKSEL_SFT);
571 regmap_update_bits(map, NAU8810_REG_CLOCK,
572 NAU8810_CLKM_MASK, NAU8810_CLKM_PLL);
573
574 return 0;
575}
576
577static int nau8810_set_dai_fmt(struct snd_soc_dai *codec_dai,
578 unsigned int fmt)
579{
580 struct snd_soc_codec *codec = codec_dai->codec;
581 struct nau8810 *nau8810 = snd_soc_codec_get_drvdata(codec);
582 u16 ctrl1_val = 0, ctrl2_val = 0;
583
584 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
585 case SND_SOC_DAIFMT_CBM_CFM:
586 ctrl2_val |= NAU8810_CLKIO_MASTER;
587 break;
588 case SND_SOC_DAIFMT_CBS_CFS:
589 break;
590 default:
591 return -EINVAL;
592 }
593
594 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
595 case SND_SOC_DAIFMT_I2S:
596 ctrl1_val |= NAU8810_AIFMT_I2S;
597 break;
598 case SND_SOC_DAIFMT_RIGHT_J:
599 break;
600 case SND_SOC_DAIFMT_LEFT_J:
601 ctrl1_val |= NAU8810_AIFMT_LEFT;
602 break;
603 case SND_SOC_DAIFMT_DSP_A:
604 ctrl1_val |= NAU8810_AIFMT_PCM_A;
605 break;
606 default:
607 return -EINVAL;
608 }
609
610 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
611 case SND_SOC_DAIFMT_NB_NF:
612 break;
613 case SND_SOC_DAIFMT_IB_IF:
614 ctrl1_val |= NAU8810_BCLKP_IB | NAU8810_FSP_IF;
615 break;
616 case SND_SOC_DAIFMT_IB_NF:
617 ctrl1_val |= NAU8810_BCLKP_IB;
618 break;
619 case SND_SOC_DAIFMT_NB_IF:
620 ctrl1_val |= NAU8810_FSP_IF;
621 break;
622 default:
623 return -EINVAL;
624 }
625
626 regmap_update_bits(nau8810->regmap, NAU8810_REG_IFACE,
627 NAU8810_AIFMT_MASK | NAU8810_FSP_IF |
628 NAU8810_BCLKP_IB, ctrl1_val);
629 regmap_update_bits(nau8810->regmap, NAU8810_REG_CLOCK,
630 NAU8810_CLKIO_MASK, ctrl2_val);
631
632 return 0;
633}
634
635static int nau8810_mclk_clkdiv(struct nau8810 *nau8810, int rate)
636{
637 int i, sclk, imclk = rate * 256, div = 0;
638
639 if (!nau8810->sysclk) {
640 dev_err(nau8810->dev, "Make mclk div configuration fail because of invalid system clock\n");
641 return -EINVAL;
642 }
643
644 /* Configure the master clock prescaler div to make system
645 * clock to approximate the internal master clock (IMCLK);
646 * and large or equal to IMCLK.
647 */
648 for (i = 1; i < ARRAY_SIZE(nau8810_mclk_scaler); i++) {
649 sclk = (nau8810->sysclk * 10) /
650 nau8810_mclk_scaler[i];
651 if (sclk < imclk)
652 break;
653 div = i;
654 }
655 dev_dbg(nau8810->dev,
656 "master clock prescaler %x for fs %d\n", div, rate);
657
658 /* master clock from MCLK and disable PLL */
659 regmap_update_bits(nau8810->regmap, NAU8810_REG_CLOCK,
660 NAU8810_MCLKSEL_MASK, (div << NAU8810_MCLKSEL_SFT));
661 regmap_update_bits(nau8810->regmap, NAU8810_REG_CLOCK,
662 NAU8810_CLKM_MASK, NAU8810_CLKM_MCLK);
663
664 return 0;
665}
666
667static int nau8810_pcm_hw_params(struct snd_pcm_substream *substream,
668 struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
669{
670 struct snd_soc_codec *codec = dai->codec;
671 struct nau8810 *nau8810 = snd_soc_codec_get_drvdata(codec);
672 int val_len = 0, val_rate = 0, ret = 0;
673
674 switch (params_width(params)) {
675 case 16:
676 break;
677 case 20:
678 val_len |= NAU8810_WLEN_20;
679 break;
680 case 24:
681 val_len |= NAU8810_WLEN_24;
682 break;
683 case 32:
684 val_len |= NAU8810_WLEN_32;
685 break;
686 }
687
688 switch (params_rate(params)) {
689 case 8000:
690 val_rate |= NAU8810_SMPLR_8K;
691 break;
692 case 11025:
693 val_rate |= NAU8810_SMPLR_12K;
694 break;
695 case 16000:
696 val_rate |= NAU8810_SMPLR_16K;
697 break;
698 case 22050:
699 val_rate |= NAU8810_SMPLR_24K;
700 break;
701 case 32000:
702 val_rate |= NAU8810_SMPLR_32K;
703 break;
704 case 44100:
705 case 48000:
706 break;
707 }
708
709 regmap_update_bits(nau8810->regmap, NAU8810_REG_IFACE,
710 NAU8810_WLEN_MASK, val_len);
711 regmap_update_bits(nau8810->regmap, NAU8810_REG_SMPLR,
712 NAU8810_SMPLR_MASK, val_rate);
713
714 /* If the master clock is from MCLK, provide the runtime FS for driver
715 * to get the master clock prescaler configuration.
716 */
717 if (nau8810->clk_id == NAU8810_SCLK_MCLK) {
718 ret = nau8810_mclk_clkdiv(nau8810, params_rate(params));
719 if (ret < 0)
720 dev_err(nau8810->dev, "MCLK div configuration fail\n");
721 }
722
723 return ret;
724}
725
726static int nau8810_set_bias_level(struct snd_soc_codec *codec,
727 enum snd_soc_bias_level level)
728{
729 struct nau8810 *nau8810 = snd_soc_codec_get_drvdata(codec);
730 struct regmap *map = nau8810->regmap;
731
732 switch (level) {
733 case SND_SOC_BIAS_ON:
734 case SND_SOC_BIAS_PREPARE:
735 regmap_update_bits(map, NAU8810_REG_POWER1,
736 NAU8810_REFIMP_MASK, NAU8810_REFIMP_80K);
737 break;
738
739 case SND_SOC_BIAS_STANDBY:
740 regmap_update_bits(map, NAU8810_REG_POWER1,
741 NAU8810_IOBUF_EN | NAU8810_ABIAS_EN,
742 NAU8810_IOBUF_EN | NAU8810_ABIAS_EN);
743
744 if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF) {
745 regcache_sync(map);
746 regmap_update_bits(map, NAU8810_REG_POWER1,
747 NAU8810_REFIMP_MASK, NAU8810_REFIMP_3K);
748 mdelay(100);
749 }
750 regmap_update_bits(map, NAU8810_REG_POWER1,
751 NAU8810_REFIMP_MASK, NAU8810_REFIMP_300K);
752 break;
753
754 case SND_SOC_BIAS_OFF:
755 regmap_write(map, NAU8810_REG_POWER1, 0);
756 regmap_write(map, NAU8810_REG_POWER2, 0);
757 regmap_write(map, NAU8810_REG_POWER3, 0);
758 break;
759 }
760
761 return 0;
762}
763
764
765#define NAU8810_RATES (SNDRV_PCM_RATE_8000_48000)
766
767#define NAU8810_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \
768 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
769
770static const struct snd_soc_dai_ops nau8810_ops = {
771 .hw_params = nau8810_pcm_hw_params,
772 .set_fmt = nau8810_set_dai_fmt,
773 .set_sysclk = nau8810_set_sysclk,
774 .set_pll = nau8810_set_pll,
775};
776
777static struct snd_soc_dai_driver nau8810_dai = {
778 .name = "nau8810-hifi",
779 .playback = {
780 .stream_name = "Playback",
781 .channels_min = 1,
782 .channels_max = 2, /* Only 1 channel of data */
783 .rates = NAU8810_RATES,
784 .formats = NAU8810_FORMATS,
785 },
786 .capture = {
787 .stream_name = "Capture",
788 .channels_min = 1,
789 .channels_max = 2, /* Only 1 channel of data */
790 .rates = NAU8810_RATES,
791 .formats = NAU8810_FORMATS,
792 },
793 .ops = &nau8810_ops,
794 .symmetric_rates = 1,
795};
796
797static const struct regmap_config nau8810_regmap_config = {
798 .reg_bits = 7,
799 .val_bits = 9,
800
801 .max_register = NAU8810_REG_MAX,
802 .readable_reg = nau8810_readable_reg,
803 .writeable_reg = nau8810_writeable_reg,
804 .volatile_reg = nau8810_volatile_reg,
805
806 .cache_type = REGCACHE_RBTREE,
807 .reg_defaults = nau8810_reg_defaults,
808 .num_reg_defaults = ARRAY_SIZE(nau8810_reg_defaults),
809};
810
811static struct snd_soc_codec_driver nau8810_codec_driver = {
812 .set_bias_level = nau8810_set_bias_level,
813 .suspend_bias_off = true,
814
815 .component_driver = {
816 .controls = nau8810_snd_controls,
817 .num_controls = ARRAY_SIZE(nau8810_snd_controls),
818 .dapm_widgets = nau8810_dapm_widgets,
819 .num_dapm_widgets = ARRAY_SIZE(nau8810_dapm_widgets),
820 .dapm_routes = nau8810_dapm_routes,
821 .num_dapm_routes = ARRAY_SIZE(nau8810_dapm_routes),
822 },
823};
824
825static int nau8810_i2c_probe(struct i2c_client *i2c,
826 const struct i2c_device_id *id)
827{
828 struct device *dev = &i2c->dev;
829 struct nau8810 *nau8810 = dev_get_platdata(dev);
830
831 if (!nau8810) {
832 nau8810 = devm_kzalloc(dev, sizeof(*nau8810), GFP_KERNEL);
833 if (!nau8810)
834 return -ENOMEM;
835 }
836 i2c_set_clientdata(i2c, nau8810);
837
838 nau8810->regmap = devm_regmap_init_i2c(i2c, &nau8810_regmap_config);
839 if (IS_ERR(nau8810->regmap))
840 return PTR_ERR(nau8810->regmap);
841 nau8810->dev = dev;
842
843 regmap_write(nau8810->regmap, NAU8810_REG_RESET, 0x00);
844
845 return snd_soc_register_codec(dev,
846 &nau8810_codec_driver, &nau8810_dai, 1);
847}
848
849static int nau8810_i2c_remove(struct i2c_client *client)
850{
851 snd_soc_unregister_codec(&client->dev);
852
853 return 0;
854}
855
856static const struct i2c_device_id nau8810_i2c_id[] = {
857 { "nau8810", 0 },
858 { }
859};
860MODULE_DEVICE_TABLE(i2c, nau8810_i2c_id);
861
862#ifdef CONFIG_OF
863static const struct of_device_id nau8810_of_match[] = {
864 { .compatible = "nuvoton,nau8810", },
865 { }
866};
867MODULE_DEVICE_TABLE(of, nau8810_of_match);
868#endif
869
870static struct i2c_driver nau8810_i2c_driver = {
871 .driver = {
872 .name = "nau8810",
873 .of_match_table = of_match_ptr(nau8810_of_match),
874 },
875 .probe = nau8810_i2c_probe,
876 .remove = nau8810_i2c_remove,
877 .id_table = nau8810_i2c_id,
878};
879
880module_i2c_driver(nau8810_i2c_driver);
881
882MODULE_DESCRIPTION("ASoC NAU8810 driver");
883MODULE_AUTHOR("David Lin <ctlin0@nuvoton.com>");
884MODULE_LICENSE("GPL v2");
diff --git a/sound/soc/codecs/nau8810.h b/sound/soc/codecs/nau8810.h
new file mode 100644
index 000000000000..df882658ca91
--- /dev/null
+++ b/sound/soc/codecs/nau8810.h
@@ -0,0 +1,281 @@
1/*
2 * NAU8810 ALSA SoC audio driver
3 *
4 * Copyright 2016 Nuvoton Technology Corp.
5 * Author: David Lin <ctlin0@nuvoton.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11
12#ifndef __NAU8810_H__
13#define __NAU8810_H__
14
15#define NAU8810_REG_RESET 0x00
16#define NAU8810_REG_POWER1 0x01
17#define NAU8810_REG_POWER2 0x02
18#define NAU8810_REG_POWER3 0x03
19#define NAU8810_REG_IFACE 0x04
20#define NAU8810_REG_COMP 0x05
21#define NAU8810_REG_CLOCK 0x06
22#define NAU8810_REG_SMPLR 0x07
23#define NAU8810_REG_DAC 0x0A
24#define NAU8810_REG_DACGAIN 0x0B
25#define NAU8810_REG_ADC 0x0E
26#define NAU8810_REG_ADCGAIN 0x0F
27#define NAU8810_REG_EQ1 0x12
28#define NAU8810_REG_EQ2 0x13
29#define NAU8810_REG_EQ3 0x14
30#define NAU8810_REG_EQ4 0x15
31#define NAU8810_REG_EQ5 0x16
32#define NAU8810_REG_DACLIM1 0x18
33#define NAU8810_REG_DACLIM2 0x19
34#define NAU8810_REG_NOTCH1 0x1B
35#define NAU8810_REG_NOTCH2 0x1C
36#define NAU8810_REG_NOTCH3 0x1D
37#define NAU8810_REG_NOTCH4 0x1E
38#define NAU8810_REG_ALC1 0x20
39#define NAU8810_REG_ALC2 0x21
40#define NAU8810_REG_ALC3 0x22
41#define NAU8810_REG_NOISEGATE 0x23
42#define NAU8810_REG_PLLN 0x24
43#define NAU8810_REG_PLLK1 0x25
44#define NAU8810_REG_PLLK2 0x26
45#define NAU8810_REG_PLLK3 0x27
46#define NAU8810_REG_ATTEN 0x28
47#define NAU8810_REG_INPUT_SIGNAL 0x2C
48#define NAU8810_REG_PGAGAIN 0x2D
49#define NAU8810_REG_ADCBOOST 0x2F
50#define NAU8810_REG_OUTPUT 0x31
51#define NAU8810_REG_SPKMIX 0x32
52#define NAU8810_REG_SPKGAIN 0x36
53#define NAU8810_REG_MONOMIX 0x38
54#define NAU8810_REG_POWER4 0x3A
55#define NAU8810_REG_TSLOTCTL1 0x3B
56#define NAU8810_REG_TSLOTCTL2 0x3C
57#define NAU8810_REG_DEVICE_REVID 0x3E
58#define NAU8810_REG_I2C_DEVICEID 0x3F
59#define NAU8810_REG_ADDITIONID 0x40
60#define NAU8810_REG_RESERVE 0x41
61#define NAU8810_REG_OUTCTL 0x45
62#define NAU8810_REG_ALC1ENHAN1 0x46
63#define NAU8810_REG_ALC1ENHAN2 0x47
64#define NAU8810_REG_MISCCTL 0x49
65#define NAU8810_REG_OUTTIEOFF 0x4B
66#define NAU8810_REG_AGCP2POUT 0x4C
67#define NAU8810_REG_AGCPOUT 0x4D
68#define NAU8810_REG_AMTCTL 0x4E
69#define NAU8810_REG_OUTTIEOFFMAN 0x4F
70#define NAU8810_REG_MAX NAU8810_REG_OUTTIEOFFMAN
71
72
73/* NAU8810_REG_POWER1 (0x1) */
74#define NAU8810_DCBUF_EN (0x1 << 8)
75#define NAU8810_PLL_EN_SFT 5
76#define NAU8810_MICBIAS_EN_SFT 4
77#define NAU8810_ABIAS_EN (0x1 << 3)
78#define NAU8810_IOBUF_EN (0x1 << 2)
79#define NAU8810_REFIMP_MASK 0x3
80#define NAU8810_REFIMP_DIS 0x0
81#define NAU8810_REFIMP_80K 0x1
82#define NAU8810_REFIMP_300K 0x2
83#define NAU8810_REFIMP_3K 0x3
84
85/* NAU8810_REG_POWER2 (0x2) */
86#define NAU8810_BST_EN_SFT 4
87#define NAU8810_PGA_EN_SFT 2
88#define NAU8810_ADC_EN_SFT 0
89
90/* NAU8810_REG_POWER3 (0x3) */
91#define NAU8810_DAC_EN_SFT 0
92#define NAU8810_SPKMX_EN_SFT 2
93#define NAU8810_MOUTMX_EN_SFT 3
94#define NAU8810_PSPK_EN_SFT 5
95#define NAU8810_NSPK_EN_SFT 6
96#define NAU8810_MOUT_EN_SFT 7
97
98/* NAU8810_REG_IFACE (0x4) */
99#define NAU8810_AIFMT_SFT 3
100#define NAU8810_AIFMT_MASK (0x3 << NAU8810_AIFMT_SFT)
101#define NAU8810_AIFMT_RIGHT (0x0 << NAU8810_AIFMT_SFT)
102#define NAU8810_AIFMT_LEFT (0x1 << NAU8810_AIFMT_SFT)
103#define NAU8810_AIFMT_I2S (0x2 << NAU8810_AIFMT_SFT)
104#define NAU8810_AIFMT_PCM_A (0x3 << NAU8810_AIFMT_SFT)
105#define NAU8810_WLEN_SFT 5
106#define NAU8810_WLEN_MASK (0x3 << NAU8810_WLEN_SFT)
107#define NAU8810_WLEN_16 (0x0 << NAU8810_WLEN_SFT)
108#define NAU8810_WLEN_20 (0x1 << NAU8810_WLEN_SFT)
109#define NAU8810_WLEN_24 (0x2 << NAU8810_WLEN_SFT)
110#define NAU8810_WLEN_32 (0x3 << NAU8810_WLEN_SFT)
111#define NAU8810_FSP_IF (0x1 << 7)
112#define NAU8810_BCLKP_IB (0x1 << 8)
113
114/* NAU8810_REG_COMP (0x5) */
115#define NAU8810_ADDAP_SFT 0
116#define NAU8810_ADCCM_SFT 1
117#define NAU8810_DACCM_SFT 3
118
119/* NAU8810_REG_CLOCK (0x6) */
120#define NAU8810_CLKIO_MASK 0x1
121#define NAU8810_CLKIO_SLAVE 0x0
122#define NAU8810_CLKIO_MASTER 0x1
123#define NAU8810_BCLKSEL_SFT 2
124#define NAU8810_BCLKSEL_MASK (0x7 << NAU8810_BCLKSEL_SFT)
125#define NAU8810_BCLKDIV_1 (0x0 << NAU8810_BCLKSEL_SFT)
126#define NAU8810_BCLKDIV_2 (0x1 << NAU8810_BCLKSEL_SFT)
127#define NAU8810_BCLKDIV_4 (0x2 << NAU8810_BCLKSEL_SFT)
128#define NAU8810_BCLKDIV_8 (0x3 << NAU8810_BCLKSEL_SFT)
129#define NAU8810_BCLKDIV_16 (0x4 << NAU8810_BCLKSEL_SFT)
130#define NAU8810_BCLKDIV_32 (0x5 << NAU8810_BCLKSEL_SFT)
131#define NAU8810_MCLKSEL_SFT 5
132#define NAU8810_MCLKSEL_MASK (0x7 << NAU8810_MCLKSEL_SFT)
133#define NAU8810_CLKM_SFT 8
134#define NAU8810_CLKM_MASK (0x1 << NAU8810_CLKM_SFT)
135#define NAU8810_CLKM_MCLK (0x0 << NAU8810_CLKM_SFT)
136#define NAU8810_CLKM_PLL (0x1 << NAU8810_CLKM_SFT)
137
138/* NAU8810_REG_SMPLR (0x7) */
139#define NAU8810_SMPLR_SFT 1
140#define NAU8810_SMPLR_MASK (0x7 << NAU8810_SMPLR_SFT)
141#define NAU8810_SMPLR_48K (0x0 << NAU8810_SMPLR_SFT)
142#define NAU8810_SMPLR_32K (0x1 << NAU8810_SMPLR_SFT)
143#define NAU8810_SMPLR_24K (0x2 << NAU8810_SMPLR_SFT)
144#define NAU8810_SMPLR_16K (0x3 << NAU8810_SMPLR_SFT)
145#define NAU8810_SMPLR_12K (0x4 << NAU8810_SMPLR_SFT)
146#define NAU8810_SMPLR_8K (0x5 << NAU8810_SMPLR_SFT)
147
148/* NAU8810_REG_DAC (0xA) */
149#define NAU8810_DACPL_SFT 0
150#define NAU8810_DACOS_SFT 3
151#define NAU8810_DEEMP_SFT 4
152
153/* NAU8810_REG_DACGAIN (0xB) */
154#define NAU8810_DACGAIN_SFT 0
155
156/* NAU8810_REG_ADC (0xE) */
157#define NAU8810_ADCPL_SFT 0
158#define NAU8810_ADCOS_SFT 3
159#define NAU8810_HPF_SFT 4
160#define NAU8810_HPFEN_SFT 8
161
162/* NAU8810_REG_ADCGAIN (0xF) */
163#define NAU8810_ADCGAIN_SFT 0
164
165/* NAU8810_REG_EQ1 (0x12) */
166#define NAU8810_EQ1GC_SFT 0
167#define NAU8810_EQ1CF_SFT 5
168#define NAU8810_EQM_SFT 8
169
170/* NAU8810_REG_EQ2 (0x13) */
171#define NAU8810_EQ2GC_SFT 0
172#define NAU8810_EQ2CF_SFT 5
173#define NAU8810_EQ2BW_SFT 8
174
175/* NAU8810_REG_EQ3 (0x14) */
176#define NAU8810_EQ3GC_SFT 0
177#define NAU8810_EQ3CF_SFT 5
178#define NAU8810_EQ3BW_SFT 8
179
180/* NAU8810_REG_EQ4 (0x15) */
181#define NAU8810_EQ4GC_SFT 0
182#define NAU8810_EQ4CF_SFT 5
183#define NAU8810_EQ4BW_SFT 8
184
185/* NAU8810_REG_EQ5 (0x16) */
186#define NAU8810_EQ5GC_SFT 0
187#define NAU8810_EQ5CF_SFT 5
188
189/* NAU8810_REG_DACLIM1 (0x18) */
190#define NAU8810_DACLIMATK_SFT 0
191#define NAU8810_DACLIMDCY_SFT 4
192#define NAU8810_DACLIMEN_SFT 8
193
194/* NAU8810_REG_DACLIM2 (0x19) */
195#define NAU8810_DACLIMBST_SFT 0
196#define NAU8810_DACLIMTHL_SFT 4
197
198/* NAU8810_REG_ALC1 (0x20) */
199#define NAU8810_ALCMINGAIN_SFT 0
200#define NAU8810_ALCMXGAIN_SFT 3
201#define NAU8810_ALCEN_SFT 8
202
203/* NAU8810_REG_ALC2 (0x21) */
204#define NAU8810_ALCSL_SFT 0
205#define NAU8810_ALCHT_SFT 4
206#define NAU8810_ALCZC_SFT 8
207
208/* NAU8810_REG_ALC3 (0x22) */
209#define NAU8810_ALCATK_SFT 0
210#define NAU8810_ALCDCY_SFT 4
211#define NAU8810_ALCM_SFT 8
212
213/* NAU8810_REG_NOISEGATE (0x23) */
214#define NAU8810_ALCNTH_SFT 0
215#define NAU8810_ALCNEN_SFT 3
216
217/* NAU8810_REG_PLLN (0x24) */
218#define NAU8810_PLLN_MASK 0xF
219#define NAU8810_PLLMCLK_DIV2 (0x1 << 4)
220
221/* NAU8810_REG_PLLK1 (0x25) */
222#define NAU8810_PLLK1_SFT 18
223#define NAU8810_PLLK1_MASK 0x3F
224
225/* NAU8810_REG_PLLK2 (0x26) */
226#define NAU8810_PLLK2_SFT 9
227#define NAU8810_PLLK2_MASK 0x1FF
228
229/* NAU8810_REG_PLLK3 (0x27) */
230#define NAU8810_PLLK3_MASK 0x1FF
231
232/* NAU8810_REG_INPUT_SIGNAL (0x2C) */
233#define NAU8810_PMICPGA_SFT 0
234#define NAU8810_NMICPGA_SFT 1
235
236/* NAU8810_REG_PGAGAIN (0x2D) */
237#define NAU8810_PGAGAIN_SFT 0
238#define NAU8810_PGAMT_SFT 6
239#define NAU8810_PGAZC_SFT 7
240
241/* NAU8810_REG_ADCBOOST (0x2F) */
242#define NAU8810_PMICBSTGAIN_SFT 4
243#define NAU8810_PGABST_SFT 8
244
245/* NAU8810_REG_SPKMIX (0x32) */
246#define NAU8810_DACSPK_SFT 0
247#define NAU8810_BYPSPK_SFT 1
248
249/* NAU8810_REG_SPKGAIN (0x36) */
250#define NAU8810_SPKGAIN_SFT 0
251#define NAU8810_SPKMT_SFT 6
252#define NAU8810_SPKZC_SFT 7
253
254/* NAU8810_REG_MONOMIX (0x38) */
255#define NAU8810_DACMOUT_SFT 0
256#define NAU8810_BYPMOUT_SFT 1
257#define NAU8810_MOUTMXMT_SFT 6
258
259
260/* System Clock Source */
261enum {
262 NAU8810_SCLK_MCLK,
263 NAU8810_SCLK_PLL,
264};
265
266struct nau8810_pll {
267 int pre_factor;
268 int mclk_scaler;
269 int pll_frac;
270 int pll_int;
271};
272
273struct nau8810 {
274 struct device *dev;
275 struct regmap *regmap;
276 struct nau8810_pll pll;
277 int sysclk;
278 int clk_id;
279};
280
281#endif
diff --git a/sound/soc/codecs/nau8825.c b/sound/soc/codecs/nau8825.c
index 2e59a85e360b..e643be91d762 100644
--- a/sound/soc/codecs/nau8825.c
+++ b/sound/soc/codecs/nau8825.c
@@ -1907,7 +1907,7 @@ static int nau8825_calc_fll_param(unsigned int fll_in, unsigned int fs,
1907 /* Calculate the FLL 10-bit integer input and the FLL 16-bit fractional 1907 /* Calculate the FLL 10-bit integer input and the FLL 16-bit fractional
1908 * input based on FDCO, FREF and FLL ratio. 1908 * input based on FDCO, FREF and FLL ratio.
1909 */ 1909 */
1910 fvco = div_u64(fvco << 16, fref * fll_param->ratio); 1910 fvco = div_u64(fvco_max << 16, fref * fll_param->ratio);
1911 fll_param->fll_int = (fvco >> 16) & 0x3FF; 1911 fll_param->fll_int = (fvco >> 16) & 0x3FF;
1912 fll_param->fll_frac = fvco & 0xFFFF; 1912 fll_param->fll_frac = fvco & 0xFFFF;
1913 return 0; 1913 return 0;
@@ -2256,12 +2256,14 @@ static struct snd_soc_codec_driver nau8825_codec_driver = {
2256 .suspend = nau8825_suspend, 2256 .suspend = nau8825_suspend,
2257 .resume = nau8825_resume, 2257 .resume = nau8825_resume,
2258 2258
2259 .controls = nau8825_controls, 2259 .component_driver = {
2260 .num_controls = ARRAY_SIZE(nau8825_controls), 2260 .controls = nau8825_controls,
2261 .dapm_widgets = nau8825_dapm_widgets, 2261 .num_controls = ARRAY_SIZE(nau8825_controls),
2262 .num_dapm_widgets = ARRAY_SIZE(nau8825_dapm_widgets), 2262 .dapm_widgets = nau8825_dapm_widgets,
2263 .dapm_routes = nau8825_dapm_routes, 2263 .num_dapm_widgets = ARRAY_SIZE(nau8825_dapm_widgets),
2264 .num_dapm_routes = ARRAY_SIZE(nau8825_dapm_routes), 2264 .dapm_routes = nau8825_dapm_routes,
2265 .num_dapm_routes = ARRAY_SIZE(nau8825_dapm_routes),
2266 },
2265}; 2267};
2266 2268
2267static void nau8825_reset_chip(struct regmap *regmap) 2269static void nau8825_reset_chip(struct regmap *regmap)
diff --git a/sound/soc/codecs/pcm1681.c b/sound/soc/codecs/pcm1681.c
index 33e1fc2d1598..0b14efab6280 100644
--- a/sound/soc/codecs/pcm1681.c
+++ b/sound/soc/codecs/pcm1681.c
@@ -289,12 +289,14 @@ static const struct regmap_config pcm1681_regmap = {
289}; 289};
290 290
291static struct snd_soc_codec_driver soc_codec_dev_pcm1681 = { 291static struct snd_soc_codec_driver soc_codec_dev_pcm1681 = {
292 .controls = pcm1681_controls, 292 .component_driver = {
293 .num_controls = ARRAY_SIZE(pcm1681_controls), 293 .controls = pcm1681_controls,
294 .dapm_widgets = pcm1681_dapm_widgets, 294 .num_controls = ARRAY_SIZE(pcm1681_controls),
295 .num_dapm_widgets = ARRAY_SIZE(pcm1681_dapm_widgets), 295 .dapm_widgets = pcm1681_dapm_widgets,
296 .dapm_routes = pcm1681_dapm_routes, 296 .num_dapm_widgets = ARRAY_SIZE(pcm1681_dapm_widgets),
297 .num_dapm_routes = ARRAY_SIZE(pcm1681_dapm_routes), 297 .dapm_routes = pcm1681_dapm_routes,
298 .num_dapm_routes = ARRAY_SIZE(pcm1681_dapm_routes),
299 },
298}; 300};
299 301
300static const struct i2c_device_id pcm1681_i2c_id[] = { 302static const struct i2c_device_id pcm1681_i2c_id[] = {
diff --git a/sound/soc/codecs/pcm179x.c b/sound/soc/codecs/pcm179x.c
index 88fbdd184aa0..b813a154ddd9 100644
--- a/sound/soc/codecs/pcm179x.c
+++ b/sound/soc/codecs/pcm179x.c
@@ -206,12 +206,14 @@ const struct regmap_config pcm179x_regmap_config = {
206EXPORT_SYMBOL_GPL(pcm179x_regmap_config); 206EXPORT_SYMBOL_GPL(pcm179x_regmap_config);
207 207
208static struct snd_soc_codec_driver soc_codec_dev_pcm179x = { 208static struct snd_soc_codec_driver soc_codec_dev_pcm179x = {
209 .controls = pcm179x_controls, 209 .component_driver = {
210 .num_controls = ARRAY_SIZE(pcm179x_controls), 210 .controls = pcm179x_controls,
211 .dapm_widgets = pcm179x_dapm_widgets, 211 .num_controls = ARRAY_SIZE(pcm179x_controls),
212 .num_dapm_widgets = ARRAY_SIZE(pcm179x_dapm_widgets), 212 .dapm_widgets = pcm179x_dapm_widgets,
213 .dapm_routes = pcm179x_dapm_routes, 213 .num_dapm_widgets = ARRAY_SIZE(pcm179x_dapm_widgets),
214 .num_dapm_routes = ARRAY_SIZE(pcm179x_dapm_routes), 214 .dapm_routes = pcm179x_dapm_routes,
215 .num_dapm_routes = ARRAY_SIZE(pcm179x_dapm_routes),
216 },
215}; 217};
216 218
217int pcm179x_common_init(struct device *dev, struct regmap *regmap) 219int pcm179x_common_init(struct device *dev, struct regmap *regmap)
diff --git a/sound/soc/codecs/pcm3008.c b/sound/soc/codecs/pcm3008.c
index 8fb445f33f6f..708af05486f6 100644
--- a/sound/soc/codecs/pcm3008.c
+++ b/sound/soc/codecs/pcm3008.c
@@ -99,10 +99,12 @@ static struct snd_soc_dai_driver pcm3008_dai = {
99}; 99};
100 100
101static struct snd_soc_codec_driver soc_codec_dev_pcm3008 = { 101static struct snd_soc_codec_driver soc_codec_dev_pcm3008 = {
102 .dapm_widgets = pcm3008_dapm_widgets, 102 .component_driver = {
103 .num_dapm_widgets = ARRAY_SIZE(pcm3008_dapm_widgets), 103 .dapm_widgets = pcm3008_dapm_widgets,
104 .dapm_routes = pcm3008_dapm_routes, 104 .num_dapm_widgets = ARRAY_SIZE(pcm3008_dapm_widgets),
105 .num_dapm_routes = ARRAY_SIZE(pcm3008_dapm_routes), 105 .dapm_routes = pcm3008_dapm_routes,
106 .num_dapm_routes = ARRAY_SIZE(pcm3008_dapm_routes),
107 },
106}; 108};
107 109
108static int pcm3008_codec_probe(struct platform_device *pdev) 110static int pcm3008_codec_probe(struct platform_device *pdev)
diff --git a/sound/soc/codecs/pcm3168a.c b/sound/soc/codecs/pcm3168a.c
index 992a77edcd5d..39bc02d5bc5d 100644
--- a/sound/soc/codecs/pcm3168a.c
+++ b/sound/soc/codecs/pcm3168a.c
@@ -599,12 +599,14 @@ EXPORT_SYMBOL_GPL(pcm3168a_regmap);
599 599
600static const struct snd_soc_codec_driver pcm3168a_driver = { 600static const struct snd_soc_codec_driver pcm3168a_driver = {
601 .idle_bias_off = true, 601 .idle_bias_off = true,
602 .controls = pcm3168a_snd_controls, 602 .component_driver = {
603 .num_controls = ARRAY_SIZE(pcm3168a_snd_controls), 603 .controls = pcm3168a_snd_controls,
604 .dapm_widgets = pcm3168a_dapm_widgets, 604 .num_controls = ARRAY_SIZE(pcm3168a_snd_controls),
605 .num_dapm_widgets = ARRAY_SIZE(pcm3168a_dapm_widgets), 605 .dapm_widgets = pcm3168a_dapm_widgets,
606 .dapm_routes = pcm3168a_dapm_routes, 606 .num_dapm_widgets = ARRAY_SIZE(pcm3168a_dapm_widgets),
607 .num_dapm_routes = ARRAY_SIZE(pcm3168a_dapm_routes) 607 .dapm_routes = pcm3168a_dapm_routes,
608 .num_dapm_routes = ARRAY_SIZE(pcm3168a_dapm_routes)
609 },
608}; 610};
609 611
610int pcm3168a_probe(struct device *dev, struct regmap *regmap) 612int pcm3168a_probe(struct device *dev, struct regmap *regmap)
diff --git a/sound/soc/codecs/pcm512x.c b/sound/soc/codecs/pcm512x.c
index 047c48953a20..72b19e62f626 100644
--- a/sound/soc/codecs/pcm512x.c
+++ b/sound/soc/codecs/pcm512x.c
@@ -1348,12 +1348,14 @@ static struct snd_soc_codec_driver pcm512x_codec_driver = {
1348 .set_bias_level = pcm512x_set_bias_level, 1348 .set_bias_level = pcm512x_set_bias_level,
1349 .idle_bias_off = true, 1349 .idle_bias_off = true,
1350 1350
1351 .controls = pcm512x_controls, 1351 .component_driver = {
1352 .num_controls = ARRAY_SIZE(pcm512x_controls), 1352 .controls = pcm512x_controls,
1353 .dapm_widgets = pcm512x_dapm_widgets, 1353 .num_controls = ARRAY_SIZE(pcm512x_controls),
1354 .num_dapm_widgets = ARRAY_SIZE(pcm512x_dapm_widgets), 1354 .dapm_widgets = pcm512x_dapm_widgets,
1355 .dapm_routes = pcm512x_dapm_routes, 1355 .num_dapm_widgets = ARRAY_SIZE(pcm512x_dapm_widgets),
1356 .num_dapm_routes = ARRAY_SIZE(pcm512x_dapm_routes), 1356 .dapm_routes = pcm512x_dapm_routes,
1357 .num_dapm_routes = ARRAY_SIZE(pcm512x_dapm_routes),
1358 },
1357}; 1359};
1358 1360
1359static const struct regmap_range_cfg pcm512x_range = { 1361static const struct regmap_range_cfg pcm512x_range = {
diff --git a/sound/soc/codecs/rt286.c b/sound/soc/codecs/rt286.c
index 74c0e4eb3788..9c365a7f758d 100644
--- a/sound/soc/codecs/rt286.c
+++ b/sound/soc/codecs/rt286.c
@@ -1053,12 +1053,14 @@ static struct snd_soc_codec_driver soc_codec_dev_rt286 = {
1053 .resume = rt286_resume, 1053 .resume = rt286_resume,
1054 .set_bias_level = rt286_set_bias_level, 1054 .set_bias_level = rt286_set_bias_level,
1055 .idle_bias_off = true, 1055 .idle_bias_off = true,
1056 .controls = rt286_snd_controls, 1056 .component_driver = {
1057 .num_controls = ARRAY_SIZE(rt286_snd_controls), 1057 .controls = rt286_snd_controls,
1058 .dapm_widgets = rt286_dapm_widgets, 1058 .num_controls = ARRAY_SIZE(rt286_snd_controls),
1059 .num_dapm_widgets = ARRAY_SIZE(rt286_dapm_widgets), 1059 .dapm_widgets = rt286_dapm_widgets,
1060 .dapm_routes = rt286_dapm_routes, 1060 .num_dapm_widgets = ARRAY_SIZE(rt286_dapm_widgets),
1061 .num_dapm_routes = ARRAY_SIZE(rt286_dapm_routes), 1061 .dapm_routes = rt286_dapm_routes,
1062 .num_dapm_routes = ARRAY_SIZE(rt286_dapm_routes),
1063 },
1062}; 1064};
1063 1065
1064static const struct regmap_config rt286_regmap = { 1066static const struct regmap_config rt286_regmap = {
diff --git a/sound/soc/codecs/rt298.c b/sound/soc/codecs/rt298.c
index f80cfe4d2ef2..55558643166f 100644
--- a/sound/soc/codecs/rt298.c
+++ b/sound/soc/codecs/rt298.c
@@ -1095,12 +1095,14 @@ static struct snd_soc_codec_driver soc_codec_dev_rt298 = {
1095 .resume = rt298_resume, 1095 .resume = rt298_resume,
1096 .set_bias_level = rt298_set_bias_level, 1096 .set_bias_level = rt298_set_bias_level,
1097 .idle_bias_off = true, 1097 .idle_bias_off = true,
1098 .controls = rt298_snd_controls, 1098 .component_driver = {
1099 .num_controls = ARRAY_SIZE(rt298_snd_controls), 1099 .controls = rt298_snd_controls,
1100 .dapm_widgets = rt298_dapm_widgets, 1100 .num_controls = ARRAY_SIZE(rt298_snd_controls),
1101 .num_dapm_widgets = ARRAY_SIZE(rt298_dapm_widgets), 1101 .dapm_widgets = rt298_dapm_widgets,
1102 .dapm_routes = rt298_dapm_routes, 1102 .num_dapm_widgets = ARRAY_SIZE(rt298_dapm_widgets),
1103 .num_dapm_routes = ARRAY_SIZE(rt298_dapm_routes), 1103 .dapm_routes = rt298_dapm_routes,
1104 .num_dapm_routes = ARRAY_SIZE(rt298_dapm_routes),
1105 },
1104}; 1106};
1105 1107
1106static const struct regmap_config rt298_regmap = { 1108static const struct regmap_config rt298_regmap = {
diff --git a/sound/soc/codecs/rt5514-spi.c b/sound/soc/codecs/rt5514-spi.c
index 77ff8ebe6dfb..09103aab0cb2 100644
--- a/sound/soc/codecs/rt5514-spi.c
+++ b/sound/soc/codecs/rt5514-spi.c
@@ -236,7 +236,7 @@ static snd_pcm_uframes_t rt5514_spi_pcm_pointer(
236 return bytes_to_frames(runtime, rt5514_dsp->dma_offset); 236 return bytes_to_frames(runtime, rt5514_dsp->dma_offset);
237} 237}
238 238
239static struct snd_pcm_ops rt5514_spi_pcm_ops = { 239static const struct snd_pcm_ops rt5514_spi_pcm_ops = {
240 .open = rt5514_spi_pcm_open, 240 .open = rt5514_spi_pcm_open,
241 .hw_params = rt5514_spi_hw_params, 241 .hw_params = rt5514_spi_hw_params,
242 .hw_free = rt5514_spi_hw_free, 242 .hw_free = rt5514_spi_hw_free,
diff --git a/sound/soc/codecs/rt5514.c b/sound/soc/codecs/rt5514.c
index 7162f05101d9..f24b7cfd3a89 100644
--- a/sound/soc/codecs/rt5514.c
+++ b/sound/soc/codecs/rt5514.c
@@ -278,7 +278,7 @@ static const DECLARE_TLV_DB_RANGE(bst_tlv,
278 8, 8, TLV_DB_SCALE_ITEM(1700, 0, 0) 278 8, 8, TLV_DB_SCALE_ITEM(1700, 0, 0)
279); 279);
280 280
281static const DECLARE_TLV_DB_SCALE(adc_vol_tlv, -17625, 375, 0); 281static const DECLARE_TLV_DB_SCALE(adc_vol_tlv, -1725, 75, 0);
282 282
283static int rt5514_dsp_voice_wake_up_get(struct snd_kcontrol *kcontrol, 283static int rt5514_dsp_voice_wake_up_get(struct snd_kcontrol *kcontrol,
284 struct snd_ctl_elem_value *ucontrol) 284 struct snd_ctl_elem_value *ucontrol)
@@ -352,10 +352,10 @@ static const struct snd_kcontrol_new rt5514_snd_controls[] = {
352 SOC_DOUBLE_TLV("MIC Boost Volume", RT5514_ANA_CTRL_MICBST, 352 SOC_DOUBLE_TLV("MIC Boost Volume", RT5514_ANA_CTRL_MICBST,
353 RT5514_SEL_BSTL_SFT, RT5514_SEL_BSTR_SFT, 8, 0, bst_tlv), 353 RT5514_SEL_BSTL_SFT, RT5514_SEL_BSTR_SFT, 8, 0, bst_tlv),
354 SOC_DOUBLE_R_TLV("ADC1 Capture Volume", RT5514_DOWNFILTER0_CTRL1, 354 SOC_DOUBLE_R_TLV("ADC1 Capture Volume", RT5514_DOWNFILTER0_CTRL1,
355 RT5514_DOWNFILTER0_CTRL2, RT5514_AD_GAIN_SFT, 127, 0, 355 RT5514_DOWNFILTER0_CTRL2, RT5514_AD_GAIN_SFT, 63, 0,
356 adc_vol_tlv), 356 adc_vol_tlv),
357 SOC_DOUBLE_R_TLV("ADC2 Capture Volume", RT5514_DOWNFILTER1_CTRL1, 357 SOC_DOUBLE_R_TLV("ADC2 Capture Volume", RT5514_DOWNFILTER1_CTRL1,
358 RT5514_DOWNFILTER1_CTRL2, RT5514_AD_GAIN_SFT, 127, 0, 358 RT5514_DOWNFILTER1_CTRL2, RT5514_AD_GAIN_SFT, 63, 0,
359 adc_vol_tlv), 359 adc_vol_tlv),
360 SOC_SINGLE_EXT("DSP Voice Wake Up", SND_SOC_NOPM, 0, 1, 0, 360 SOC_SINGLE_EXT("DSP Voice Wake Up", SND_SOC_NOPM, 0, 1, 0,
361 rt5514_dsp_voice_wake_up_get, rt5514_dsp_voice_wake_up_put), 361 rt5514_dsp_voice_wake_up_get, rt5514_dsp_voice_wake_up_put),
@@ -1023,12 +1023,14 @@ static struct snd_soc_codec_driver soc_codec_dev_rt5514 = {
1023 .probe = rt5514_probe, 1023 .probe = rt5514_probe,
1024 .idle_bias_off = true, 1024 .idle_bias_off = true,
1025 .set_bias_level = rt5514_set_bias_level, 1025 .set_bias_level = rt5514_set_bias_level,
1026 .controls = rt5514_snd_controls, 1026 .component_driver = {
1027 .num_controls = ARRAY_SIZE(rt5514_snd_controls), 1027 .controls = rt5514_snd_controls,
1028 .dapm_widgets = rt5514_dapm_widgets, 1028 .num_controls = ARRAY_SIZE(rt5514_snd_controls),
1029 .num_dapm_widgets = ARRAY_SIZE(rt5514_dapm_widgets), 1029 .dapm_widgets = rt5514_dapm_widgets,
1030 .dapm_routes = rt5514_dapm_routes, 1030 .num_dapm_widgets = ARRAY_SIZE(rt5514_dapm_widgets),
1031 .num_dapm_routes = ARRAY_SIZE(rt5514_dapm_routes), 1031 .dapm_routes = rt5514_dapm_routes,
1032 .num_dapm_routes = ARRAY_SIZE(rt5514_dapm_routes),
1033 },
1032}; 1034};
1033 1035
1034static const struct regmap_config rt5514_i2c_regmap = { 1036static const struct regmap_config rt5514_i2c_regmap = {
diff --git a/sound/soc/codecs/rt5514.h b/sound/soc/codecs/rt5514.h
index 68883c68e999..229de0e2c88c 100644
--- a/sound/soc/codecs/rt5514.h
+++ b/sound/soc/codecs/rt5514.h
@@ -196,8 +196,8 @@
196#define RT5514_AD_AD_MIX_BIT 10 196#define RT5514_AD_AD_MIX_BIT 10
197#define RT5514_AD_AD_MUTE (0x1 << 7) 197#define RT5514_AD_AD_MUTE (0x1 << 7)
198#define RT5514_AD_AD_MUTE_BIT 7 198#define RT5514_AD_AD_MUTE_BIT 7
199#define RT5514_AD_GAIN_MASK (0x7f << 0) 199#define RT5514_AD_GAIN_MASK (0x3f << 1)
200#define RT5514_AD_GAIN_SFT 0 200#define RT5514_AD_GAIN_SFT 1
201 201
202/* RT5514_ANA_CTRL_MICBST (0x2220) */ 202/* RT5514_ANA_CTRL_MICBST (0x2220) */
203#define RT5514_SEL_BSTL_MASK (0xf << 4) 203#define RT5514_SEL_BSTL_MASK (0xf << 4)
diff --git a/sound/soc/codecs/rt5616.c b/sound/soc/codecs/rt5616.c
index f527b5b2817b..d1f273b24991 100644
--- a/sound/soc/codecs/rt5616.c
+++ b/sound/soc/codecs/rt5616.c
@@ -294,8 +294,7 @@ static const DECLARE_TLV_DB_SCALE(adc_vol_tlv, -17625, 375, 0);
294static const DECLARE_TLV_DB_SCALE(adc_bst_tlv, 0, 1200, 0); 294static const DECLARE_TLV_DB_SCALE(adc_bst_tlv, 0, 1200, 0);
295 295
296/* {0, +20, +24, +30, +35, +40, +44, +50, +52} dB */ 296/* {0, +20, +24, +30, +35, +40, +44, +50, +52} dB */
297static unsigned int bst_tlv[] = { 297static const SNDRV_CTL_TLVD_DECLARE_DB_RANGE(bst_tlv,
298 TLV_DB_RANGE_HEAD(7),
299 0, 0, TLV_DB_SCALE_ITEM(0, 0, 0), 298 0, 0, TLV_DB_SCALE_ITEM(0, 0, 0),
300 1, 1, TLV_DB_SCALE_ITEM(2000, 0, 0), 299 1, 1, TLV_DB_SCALE_ITEM(2000, 0, 0),
301 2, 2, TLV_DB_SCALE_ITEM(2400, 0, 0), 300 2, 2, TLV_DB_SCALE_ITEM(2400, 0, 0),
@@ -303,7 +302,7 @@ static unsigned int bst_tlv[] = {
303 6, 6, TLV_DB_SCALE_ITEM(4400, 0, 0), 302 6, 6, TLV_DB_SCALE_ITEM(4400, 0, 0),
304 7, 7, TLV_DB_SCALE_ITEM(5000, 0, 0), 303 7, 7, TLV_DB_SCALE_ITEM(5000, 0, 0),
305 8, 8, TLV_DB_SCALE_ITEM(5200, 0, 0), 304 8, 8, TLV_DB_SCALE_ITEM(5200, 0, 0),
306}; 305);
307 306
308static const struct snd_kcontrol_new rt5616_snd_controls[] = { 307static const struct snd_kcontrol_new rt5616_snd_controls[] = {
309 /* Headphone Output Volume */ 308 /* Headphone Output Volume */
@@ -1267,14 +1266,14 @@ static int rt5616_resume(struct snd_soc_codec *codec)
1267#define RT5616_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \ 1266#define RT5616_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \
1268 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S8) 1267 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S8)
1269 1268
1270struct snd_soc_dai_ops rt5616_aif_dai_ops = { 1269static struct snd_soc_dai_ops rt5616_aif_dai_ops = {
1271 .hw_params = rt5616_hw_params, 1270 .hw_params = rt5616_hw_params,
1272 .set_fmt = rt5616_set_dai_fmt, 1271 .set_fmt = rt5616_set_dai_fmt,
1273 .set_sysclk = rt5616_set_dai_sysclk, 1272 .set_sysclk = rt5616_set_dai_sysclk,
1274 .set_pll = rt5616_set_dai_pll, 1273 .set_pll = rt5616_set_dai_pll,
1275}; 1274};
1276 1275
1277struct snd_soc_dai_driver rt5616_dai[] = { 1276static struct snd_soc_dai_driver rt5616_dai[] = {
1278 { 1277 {
1279 .name = "rt5616-aif1", 1278 .name = "rt5616-aif1",
1280 .id = RT5616_AIF1, 1279 .id = RT5616_AIF1,
@@ -1302,12 +1301,14 @@ static struct snd_soc_codec_driver soc_codec_dev_rt5616 = {
1302 .resume = rt5616_resume, 1301 .resume = rt5616_resume,
1303 .set_bias_level = rt5616_set_bias_level, 1302 .set_bias_level = rt5616_set_bias_level,
1304 .idle_bias_off = true, 1303 .idle_bias_off = true,
1305 .controls = rt5616_snd_controls, 1304 .component_driver = {
1306 .num_controls = ARRAY_SIZE(rt5616_snd_controls), 1305 .controls = rt5616_snd_controls,
1307 .dapm_widgets = rt5616_dapm_widgets, 1306 .num_controls = ARRAY_SIZE(rt5616_snd_controls),
1308 .num_dapm_widgets = ARRAY_SIZE(rt5616_dapm_widgets), 1307 .dapm_widgets = rt5616_dapm_widgets,
1309 .dapm_routes = rt5616_dapm_routes, 1308 .num_dapm_widgets = ARRAY_SIZE(rt5616_dapm_widgets),
1310 .num_dapm_routes = ARRAY_SIZE(rt5616_dapm_routes), 1309 .dapm_routes = rt5616_dapm_routes,
1310 .num_dapm_routes = ARRAY_SIZE(rt5616_dapm_routes),
1311 },
1311}; 1312};
1312 1313
1313static const struct regmap_config rt5616_regmap = { 1314static const struct regmap_config rt5616_regmap = {
diff --git a/sound/soc/codecs/rt5631.c b/sound/soc/codecs/rt5631.c
index 1be2bab7dee3..0e418089c053 100644
--- a/sound/soc/codecs/rt5631.c
+++ b/sound/soc/codecs/rt5631.c
@@ -1657,12 +1657,14 @@ static struct snd_soc_codec_driver soc_codec_dev_rt5631 = {
1657 .probe = rt5631_probe, 1657 .probe = rt5631_probe,
1658 .set_bias_level = rt5631_set_bias_level, 1658 .set_bias_level = rt5631_set_bias_level,
1659 .suspend_bias_off = true, 1659 .suspend_bias_off = true,
1660 .controls = rt5631_snd_controls, 1660 .component_driver = {
1661 .num_controls = ARRAY_SIZE(rt5631_snd_controls), 1661 .controls = rt5631_snd_controls,
1662 .dapm_widgets = rt5631_dapm_widgets, 1662 .num_controls = ARRAY_SIZE(rt5631_snd_controls),
1663 .num_dapm_widgets = ARRAY_SIZE(rt5631_dapm_widgets), 1663 .dapm_widgets = rt5631_dapm_widgets,
1664 .dapm_routes = rt5631_dapm_routes, 1664 .num_dapm_widgets = ARRAY_SIZE(rt5631_dapm_widgets),
1665 .num_dapm_routes = ARRAY_SIZE(rt5631_dapm_routes), 1665 .dapm_routes = rt5631_dapm_routes,
1666 .num_dapm_routes = ARRAY_SIZE(rt5631_dapm_routes),
1667 },
1666}; 1668};
1667 1669
1668static const struct i2c_device_id rt5631_i2c_id[] = { 1670static const struct i2c_device_id rt5631_i2c_id[] = {
diff --git a/sound/soc/codecs/rt5640.c b/sound/soc/codecs/rt5640.c
index 09e8988bbb2d..3cc1135fc2cd 100644
--- a/sound/soc/codecs/rt5640.c
+++ b/sound/soc/codecs/rt5640.c
@@ -1870,6 +1870,9 @@ static int rt5640_set_dai_sysclk(struct snd_soc_dai *dai,
1870 case RT5640_SCLK_S_PLL1: 1870 case RT5640_SCLK_S_PLL1:
1871 reg_val |= RT5640_SCLK_SRC_PLL1; 1871 reg_val |= RT5640_SCLK_SRC_PLL1;
1872 break; 1872 break;
1873 case RT5640_SCLK_S_RCCLK:
1874 reg_val |= RT5640_SCLK_SRC_RCCLK;
1875 break;
1873 default: 1876 default:
1874 dev_err(codec->dev, "Invalid clock id (%d)\n", clk_id); 1877 dev_err(codec->dev, "Invalid clock id (%d)\n", clk_id);
1875 return -EINVAL; 1878 return -EINVAL;
@@ -2261,12 +2264,14 @@ static struct snd_soc_codec_driver soc_codec_dev_rt5640 = {
2261 .resume = rt5640_resume, 2264 .resume = rt5640_resume,
2262 .set_bias_level = rt5640_set_bias_level, 2265 .set_bias_level = rt5640_set_bias_level,
2263 .idle_bias_off = true, 2266 .idle_bias_off = true,
2264 .controls = rt5640_snd_controls, 2267 .component_driver = {
2265 .num_controls = ARRAY_SIZE(rt5640_snd_controls), 2268 .controls = rt5640_snd_controls,
2266 .dapm_widgets = rt5640_dapm_widgets, 2269 .num_controls = ARRAY_SIZE(rt5640_snd_controls),
2267 .num_dapm_widgets = ARRAY_SIZE(rt5640_dapm_widgets), 2270 .dapm_widgets = rt5640_dapm_widgets,
2268 .dapm_routes = rt5640_dapm_routes, 2271 .num_dapm_widgets = ARRAY_SIZE(rt5640_dapm_widgets),
2269 .num_dapm_routes = ARRAY_SIZE(rt5640_dapm_routes), 2272 .dapm_routes = rt5640_dapm_routes,
2273 .num_dapm_routes = ARRAY_SIZE(rt5640_dapm_routes),
2274 },
2270}; 2275};
2271 2276
2272static const struct regmap_config rt5640_regmap = { 2277static const struct regmap_config rt5640_regmap = {
diff --git a/sound/soc/codecs/rt5640.h b/sound/soc/codecs/rt5640.h
index 58b664b06c16..90c88711c72a 100644
--- a/sound/soc/codecs/rt5640.h
+++ b/sound/soc/codecs/rt5640.h
@@ -984,6 +984,7 @@
984#define RT5640_SCLK_SRC_SFT 14 984#define RT5640_SCLK_SRC_SFT 14
985#define RT5640_SCLK_SRC_MCLK (0x0 << 14) 985#define RT5640_SCLK_SRC_MCLK (0x0 << 14)
986#define RT5640_SCLK_SRC_PLL1 (0x1 << 14) 986#define RT5640_SCLK_SRC_PLL1 (0x1 << 14)
987#define RT5640_SCLK_SRC_RCCLK (0x2 << 14)
987#define RT5640_PLL1_SRC_MASK (0x3 << 12) 988#define RT5640_PLL1_SRC_MASK (0x3 << 12)
988#define RT5640_PLL1_SRC_SFT 12 989#define RT5640_PLL1_SRC_SFT 12
989#define RT5640_PLL1_SRC_MCLK (0x0 << 12) 990#define RT5640_PLL1_SRC_MCLK (0x0 << 12)
diff --git a/sound/soc/codecs/rt5645.c b/sound/soc/codecs/rt5645.c
index 490bfe661346..10c2a564a715 100644
--- a/sound/soc/codecs/rt5645.c
+++ b/sound/soc/codecs/rt5645.c
@@ -3484,12 +3484,14 @@ static struct snd_soc_codec_driver soc_codec_dev_rt5645 = {
3484 .resume = rt5645_resume, 3484 .resume = rt5645_resume,
3485 .set_bias_level = rt5645_set_bias_level, 3485 .set_bias_level = rt5645_set_bias_level,
3486 .idle_bias_off = true, 3486 .idle_bias_off = true,
3487 .controls = rt5645_snd_controls, 3487 .component_driver = {
3488 .num_controls = ARRAY_SIZE(rt5645_snd_controls), 3488 .controls = rt5645_snd_controls,
3489 .dapm_widgets = rt5645_dapm_widgets, 3489 .num_controls = ARRAY_SIZE(rt5645_snd_controls),
3490 .num_dapm_widgets = ARRAY_SIZE(rt5645_dapm_widgets), 3490 .dapm_widgets = rt5645_dapm_widgets,
3491 .dapm_routes = rt5645_dapm_routes, 3491 .num_dapm_widgets = ARRAY_SIZE(rt5645_dapm_widgets),
3492 .num_dapm_routes = ARRAY_SIZE(rt5645_dapm_routes), 3492 .dapm_routes = rt5645_dapm_routes,
3493 .num_dapm_routes = ARRAY_SIZE(rt5645_dapm_routes),
3494 },
3493}; 3495};
3494 3496
3495static const struct regmap_config rt5645_regmap = { 3497static const struct regmap_config rt5645_regmap = {
diff --git a/sound/soc/codecs/rt5651.c b/sound/soc/codecs/rt5651.c
index 7a6197042423..f5d34153e21f 100644
--- a/sound/soc/codecs/rt5651.c
+++ b/sound/soc/codecs/rt5651.c
@@ -1712,12 +1712,14 @@ static struct snd_soc_codec_driver soc_codec_dev_rt5651 = {
1712 .resume = rt5651_resume, 1712 .resume = rt5651_resume,
1713 .set_bias_level = rt5651_set_bias_level, 1713 .set_bias_level = rt5651_set_bias_level,
1714 .idle_bias_off = true, 1714 .idle_bias_off = true,
1715 .controls = rt5651_snd_controls, 1715 .component_driver = {
1716 .num_controls = ARRAY_SIZE(rt5651_snd_controls), 1716 .controls = rt5651_snd_controls,
1717 .dapm_widgets = rt5651_dapm_widgets, 1717 .num_controls = ARRAY_SIZE(rt5651_snd_controls),
1718 .num_dapm_widgets = ARRAY_SIZE(rt5651_dapm_widgets), 1718 .dapm_widgets = rt5651_dapm_widgets,
1719 .dapm_routes = rt5651_dapm_routes, 1719 .num_dapm_widgets = ARRAY_SIZE(rt5651_dapm_widgets),
1720 .num_dapm_routes = ARRAY_SIZE(rt5651_dapm_routes), 1720 .dapm_routes = rt5651_dapm_routes,
1721 .num_dapm_routes = ARRAY_SIZE(rt5651_dapm_routes),
1722 },
1721}; 1723};
1722 1724
1723static const struct regmap_config rt5651_regmap = { 1725static const struct regmap_config rt5651_regmap = {
diff --git a/sound/soc/codecs/rt5659.c b/sound/soc/codecs/rt5659.c
index 1b30914c2d91..db54550aed60 100644
--- a/sound/soc/codecs/rt5659.c
+++ b/sound/soc/codecs/rt5659.c
@@ -9,6 +9,7 @@
9 * published by the Free Software Foundation. 9 * published by the Free Software Foundation.
10 */ 10 */
11 11
12#include <linux/clk.h>
12#include <linux/module.h> 13#include <linux/module.h>
13#include <linux/moduleparam.h> 14#include <linux/moduleparam.h>
14#include <linux/init.h> 15#include <linux/init.h>
@@ -3565,7 +3566,9 @@ static int rt5659_set_bclk_ratio(struct snd_soc_dai *dai, unsigned int ratio)
3565static int rt5659_set_bias_level(struct snd_soc_codec *codec, 3566static int rt5659_set_bias_level(struct snd_soc_codec *codec,
3566 enum snd_soc_bias_level level) 3567 enum snd_soc_bias_level level)
3567{ 3568{
3569 struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
3568 struct rt5659_priv *rt5659 = snd_soc_codec_get_drvdata(codec); 3570 struct rt5659_priv *rt5659 = snd_soc_codec_get_drvdata(codec);
3571 int ret;
3569 3572
3570 switch (level) { 3573 switch (level) {
3571 case SND_SOC_BIAS_PREPARE: 3574 case SND_SOC_BIAS_PREPARE:
@@ -3582,6 +3585,17 @@ static int rt5659_set_bias_level(struct snd_soc_codec *codec,
3582 RT5659_PWR_FV1 | RT5659_PWR_FV2); 3585 RT5659_PWR_FV1 | RT5659_PWR_FV2);
3583 break; 3586 break;
3584 3587
3588 case SND_SOC_BIAS_STANDBY:
3589 if (dapm->bias_level == SND_SOC_BIAS_OFF) {
3590 ret = clk_prepare_enable(rt5659->mclk);
3591 if (ret) {
3592 dev_err(codec->dev,
3593 "failed to enable MCLK: %d\n", ret);
3594 return ret;
3595 }
3596 }
3597 break;
3598
3585 case SND_SOC_BIAS_OFF: 3599 case SND_SOC_BIAS_OFF:
3586 regmap_update_bits(rt5659->regmap, RT5659_PWR_DIG_1, 3600 regmap_update_bits(rt5659->regmap, RT5659_PWR_DIG_1,
3587 RT5659_PWR_LDO, 0); 3601 RT5659_PWR_LDO, 0);
@@ -3591,6 +3605,7 @@ static int rt5659_set_bias_level(struct snd_soc_codec *codec,
3591 RT5659_PWR_MB | RT5659_PWR_VREF2); 3605 RT5659_PWR_MB | RT5659_PWR_VREF2);
3592 regmap_update_bits(rt5659->regmap, RT5659_DIG_MISC, 3606 regmap_update_bits(rt5659->regmap, RT5659_DIG_MISC,
3593 RT5659_DIG_GATE_CTRL, 0); 3607 RT5659_DIG_GATE_CTRL, 0);
3608 clk_disable_unprepare(rt5659->mclk);
3594 break; 3609 break;
3595 3610
3596 default: 3611 default:
@@ -3722,12 +3737,14 @@ static struct snd_soc_codec_driver soc_codec_dev_rt5659 = {
3722 .resume = rt5659_resume, 3737 .resume = rt5659_resume,
3723 .set_bias_level = rt5659_set_bias_level, 3738 .set_bias_level = rt5659_set_bias_level,
3724 .idle_bias_off = true, 3739 .idle_bias_off = true,
3725 .controls = rt5659_snd_controls, 3740 .component_driver = {
3726 .num_controls = ARRAY_SIZE(rt5659_snd_controls), 3741 .controls = rt5659_snd_controls,
3727 .dapm_widgets = rt5659_dapm_widgets, 3742 .num_controls = ARRAY_SIZE(rt5659_snd_controls),
3728 .num_dapm_widgets = ARRAY_SIZE(rt5659_dapm_widgets), 3743 .dapm_widgets = rt5659_dapm_widgets,
3729 .dapm_routes = rt5659_dapm_routes, 3744 .num_dapm_widgets = ARRAY_SIZE(rt5659_dapm_widgets),
3730 .num_dapm_routes = ARRAY_SIZE(rt5659_dapm_routes), 3745 .dapm_routes = rt5659_dapm_routes,
3746 .num_dapm_routes = ARRAY_SIZE(rt5659_dapm_routes),
3747 },
3731}; 3748};
3732 3749
3733 3750
@@ -4020,6 +4037,15 @@ static int rt5659_i2c_probe(struct i2c_client *i2c,
4020 4037
4021 regmap_write(rt5659->regmap, RT5659_RESET, 0); 4038 regmap_write(rt5659->regmap, RT5659_RESET, 0);
4022 4039
4040 /* Check if MCLK provided */
4041 rt5659->mclk = devm_clk_get(&i2c->dev, "mclk");
4042 if (IS_ERR(rt5659->mclk)) {
4043 if (PTR_ERR(rt5659->mclk) != -ENOENT)
4044 return PTR_ERR(rt5659->mclk);
4045 /* Otherwise mark the mclk pointer to NULL */
4046 rt5659->mclk = NULL;
4047 }
4048
4023 rt5659_calibrate(rt5659); 4049 rt5659_calibrate(rt5659);
4024 4050
4025 /* line in diff mode*/ 4051 /* line in diff mode*/
@@ -4163,6 +4189,9 @@ static int rt5659_i2c_probe(struct i2c_client *i2c,
4163 if (ret) 4189 if (ret)
4164 dev_err(&i2c->dev, "Failed to reguest IRQ: %d\n", ret); 4190 dev_err(&i2c->dev, "Failed to reguest IRQ: %d\n", ret);
4165 4191
4192 /* Enable IRQ output for GPIO1 pin any way */
4193 regmap_update_bits(rt5659->regmap, RT5659_GPIO_CTRL_1,
4194 RT5659_GP1_PIN_MASK, RT5659_GP1_PIN_IRQ);
4166 } 4195 }
4167 4196
4168 return snd_soc_register_codec(&i2c->dev, &soc_codec_dev_rt5659, 4197 return snd_soc_register_codec(&i2c->dev, &soc_codec_dev_rt5659,
diff --git a/sound/soc/codecs/rt5659.h b/sound/soc/codecs/rt5659.h
index d31c9e5bcec8..8f1aeef08489 100644
--- a/sound/soc/codecs/rt5659.h
+++ b/sound/soc/codecs/rt5659.h
@@ -180,9 +180,9 @@
180#define RT5659_IRQ_CTRL_1 0x00b6 180#define RT5659_IRQ_CTRL_1 0x00b6
181#define RT5659_IRQ_CTRL_2 0x00b7 181#define RT5659_IRQ_CTRL_2 0x00b7
182#define RT5659_IRQ_CTRL_3 0x00b8 182#define RT5659_IRQ_CTRL_3 0x00b8
183#define RT5659_IRQ_CTRL_4 0x00b9 183#define RT5659_IRQ_CTRL_4 0x00ba
184#define RT5659_IRQ_CTRL_5 0x00ba 184#define RT5659_IRQ_CTRL_5 0x00bb
185#define RT5659_IRQ_CTRL_6 0x00bb 185#define RT5659_IRQ_CTRL_6 0x00bc
186#define RT5659_INT_ST_1 0x00be 186#define RT5659_INT_ST_1 0x00be
187#define RT5659_INT_ST_2 0x00bf 187#define RT5659_INT_ST_2 0x00bf
188#define RT5659_GPIO_CTRL_1 0x00c0 188#define RT5659_GPIO_CTRL_1 0x00c0
@@ -1796,6 +1796,7 @@ struct rt5659_priv {
1796 struct gpio_desc *gpiod_reset; 1796 struct gpio_desc *gpiod_reset;
1797 struct snd_soc_jack *hs_jack; 1797 struct snd_soc_jack *hs_jack;
1798 struct delayed_work jack_detect_work; 1798 struct delayed_work jack_detect_work;
1799 struct clk *mclk;
1799 1800
1800 int sysclk; 1801 int sysclk;
1801 int sysclk_src; 1802 int sysclk_src;
diff --git a/sound/soc/codecs/rt5660.c b/sound/soc/codecs/rt5660.c
new file mode 100644
index 000000000000..9f0933ced804
--- /dev/null
+++ b/sound/soc/codecs/rt5660.c
@@ -0,0 +1,1353 @@
1/*
2 * rt5660.c -- RT5660 ALSA SoC audio codec driver
3 *
4 * Copyright 2016 Realtek Semiconductor Corp.
5 * Author: Oder Chiou <oder_chiou@realtek.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11
12#include <linux/module.h>
13#include <linux/moduleparam.h>
14#include <linux/init.h>
15#include <linux/delay.h>
16#include <linux/pm.h>
17#include <linux/gpio.h>
18#include <linux/i2c.h>
19#include <linux/regmap.h>
20#include <linux/of.h>
21#include <linux/of_gpio.h>
22#include <linux/platform_device.h>
23#include <linux/spi/spi.h>
24#include <linux/acpi.h>
25#include <sound/core.h>
26#include <sound/pcm.h>
27#include <sound/pcm_params.h>
28#include <sound/soc.h>
29#include <sound/soc-dapm.h>
30#include <sound/initval.h>
31#include <sound/tlv.h>
32
33#include "rl6231.h"
34#include "rt5660.h"
35
36#define RT5660_DEVICE_ID 0x6338
37
38#define RT5660_PR_RANGE_BASE (0xff + 1)
39#define RT5660_PR_SPACING 0x100
40
41#define RT5660_PR_BASE (RT5660_PR_RANGE_BASE + (0 * RT5660_PR_SPACING))
42
43static const struct regmap_range_cfg rt5660_ranges[] = {
44 { .name = "PR", .range_min = RT5660_PR_BASE,
45 .range_max = RT5660_PR_BASE + 0xf3,
46 .selector_reg = RT5660_PRIV_INDEX,
47 .selector_mask = 0xff,
48 .selector_shift = 0x0,
49 .window_start = RT5660_PRIV_DATA,
50 .window_len = 0x1, },
51};
52
53static const struct reg_sequence rt5660_patch[] = {
54 { RT5660_ALC_PGA_CTRL2, 0x44c3 },
55 { RT5660_PR_BASE + 0x3d, 0x2600 },
56};
57
58static const struct reg_default rt5660_reg[] = {
59 { 0x00, 0x0000 },
60 { 0x01, 0xc800 },
61 { 0x02, 0xc8c8 },
62 { 0x0d, 0x1010 },
63 { 0x0e, 0x1010 },
64 { 0x19, 0xafaf },
65 { 0x1c, 0x2f2f },
66 { 0x1e, 0x0000 },
67 { 0x27, 0x6060 },
68 { 0x29, 0x8080 },
69 { 0x2a, 0x4242 },
70 { 0x2f, 0x0000 },
71 { 0x3b, 0x0000 },
72 { 0x3c, 0x007f },
73 { 0x3d, 0x0000 },
74 { 0x3e, 0x007f },
75 { 0x45, 0xe000 },
76 { 0x46, 0x003e },
77 { 0x48, 0xf800 },
78 { 0x4a, 0x0004 },
79 { 0x4d, 0x0000 },
80 { 0x4e, 0x0000 },
81 { 0x4f, 0x01ff },
82 { 0x50, 0x0000 },
83 { 0x51, 0x0000 },
84 { 0x52, 0x01ff },
85 { 0x61, 0x0000 },
86 { 0x62, 0x0000 },
87 { 0x63, 0x00c0 },
88 { 0x64, 0x0000 },
89 { 0x65, 0x0000 },
90 { 0x66, 0x0000 },
91 { 0x70, 0x8000 },
92 { 0x73, 0x7000 },
93 { 0x74, 0x3c00 },
94 { 0x75, 0x2800 },
95 { 0x80, 0x0000 },
96 { 0x81, 0x0000 },
97 { 0x82, 0x0000 },
98 { 0x8c, 0x0228 },
99 { 0x8d, 0xa000 },
100 { 0x8e, 0x0000 },
101 { 0x92, 0x0000 },
102 { 0x93, 0x3000 },
103 { 0xa1, 0x0059 },
104 { 0xa2, 0x0001 },
105 { 0xa3, 0x5c80 },
106 { 0xa4, 0x0146 },
107 { 0xa5, 0x1f1f },
108 { 0xa6, 0x78c6 },
109 { 0xa7, 0xe5ec },
110 { 0xa8, 0xba61 },
111 { 0xa9, 0x3c78 },
112 { 0xaa, 0x8ae2 },
113 { 0xab, 0xe5ec },
114 { 0xac, 0xc600 },
115 { 0xad, 0xba61 },
116 { 0xae, 0x17ed },
117 { 0xb0, 0x2080 },
118 { 0xb1, 0x0000 },
119 { 0xb3, 0x001f },
120 { 0xb4, 0x020c },
121 { 0xb5, 0x1f00 },
122 { 0xb6, 0x0000 },
123 { 0xb7, 0x4000 },
124 { 0xbb, 0x0000 },
125 { 0xbd, 0x0000 },
126 { 0xbe, 0x0000 },
127 { 0xbf, 0x0100 },
128 { 0xc0, 0x0000 },
129 { 0xc2, 0x0000 },
130 { 0xd3, 0xa220 },
131 { 0xd9, 0x0809 },
132 { 0xda, 0x0000 },
133 { 0xe0, 0x8000 },
134 { 0xe1, 0x0200 },
135 { 0xe2, 0x8000 },
136 { 0xe3, 0x0200 },
137 { 0xe4, 0x0f20 },
138 { 0xe5, 0x001f },
139 { 0xe6, 0x020c },
140 { 0xe7, 0x1f00 },
141 { 0xe8, 0x0000 },
142 { 0xe9, 0x4000 },
143 { 0xea, 0x00a6 },
144 { 0xeb, 0x04c3 },
145 { 0xec, 0x27c8 },
146 { 0xed, 0x7418 },
147 { 0xee, 0xbf50 },
148 { 0xef, 0x0045 },
149 { 0xf0, 0x0007 },
150 { 0xfa, 0x0000 },
151 { 0xfd, 0x0000 },
152 { 0xfe, 0x10ec },
153 { 0xff, 0x6338 },
154};
155
156static bool rt5660_volatile_register(struct device *dev, unsigned int reg)
157{
158 int i;
159
160 for (i = 0; i < ARRAY_SIZE(rt5660_ranges); i++)
161 if ((reg >= rt5660_ranges[i].window_start &&
162 reg <= rt5660_ranges[i].window_start +
163 rt5660_ranges[i].window_len) ||
164 (reg >= rt5660_ranges[i].range_min &&
165 reg <= rt5660_ranges[i].range_max))
166 return true;
167
168 switch (reg) {
169 case RT5660_RESET:
170 case RT5660_PRIV_DATA:
171 case RT5660_EQ_CTRL1:
172 case RT5660_IRQ_CTRL2:
173 case RT5660_INT_IRQ_ST:
174 case RT5660_VENDOR_ID:
175 case RT5660_VENDOR_ID1:
176 case RT5660_VENDOR_ID2:
177 return true;
178 default:
179 return false;
180 }
181}
182
183static bool rt5660_readable_register(struct device *dev, unsigned int reg)
184{
185 int i;
186
187 for (i = 0; i < ARRAY_SIZE(rt5660_ranges); i++)
188 if ((reg >= rt5660_ranges[i].window_start &&
189 reg <= rt5660_ranges[i].window_start +
190 rt5660_ranges[i].window_len) ||
191 (reg >= rt5660_ranges[i].range_min &&
192 reg <= rt5660_ranges[i].range_max))
193 return true;
194
195 switch (reg) {
196 case RT5660_RESET:
197 case RT5660_SPK_VOL:
198 case RT5660_LOUT_VOL:
199 case RT5660_IN1_IN2:
200 case RT5660_IN3_IN4:
201 case RT5660_DAC1_DIG_VOL:
202 case RT5660_STO1_ADC_DIG_VOL:
203 case RT5660_ADC_BST_VOL1:
204 case RT5660_STO1_ADC_MIXER:
205 case RT5660_AD_DA_MIXER:
206 case RT5660_STO_DAC_MIXER:
207 case RT5660_DIG_INF1_DATA:
208 case RT5660_REC_L1_MIXER:
209 case RT5660_REC_L2_MIXER:
210 case RT5660_REC_R1_MIXER:
211 case RT5660_REC_R2_MIXER:
212 case RT5660_LOUT_MIXER:
213 case RT5660_SPK_MIXER:
214 case RT5660_SPO_MIXER:
215 case RT5660_SPO_CLSD_RATIO:
216 case RT5660_OUT_L_GAIN1:
217 case RT5660_OUT_L_GAIN2:
218 case RT5660_OUT_L1_MIXER:
219 case RT5660_OUT_R_GAIN1:
220 case RT5660_OUT_R_GAIN2:
221 case RT5660_OUT_R1_MIXER:
222 case RT5660_PWR_DIG1:
223 case RT5660_PWR_DIG2:
224 case RT5660_PWR_ANLG1:
225 case RT5660_PWR_ANLG2:
226 case RT5660_PWR_MIXER:
227 case RT5660_PWR_VOL:
228 case RT5660_PRIV_INDEX:
229 case RT5660_PRIV_DATA:
230 case RT5660_I2S1_SDP:
231 case RT5660_ADDA_CLK1:
232 case RT5660_ADDA_CLK2:
233 case RT5660_DMIC_CTRL1:
234 case RT5660_GLB_CLK:
235 case RT5660_PLL_CTRL1:
236 case RT5660_PLL_CTRL2:
237 case RT5660_CLSD_AMP_OC_CTRL:
238 case RT5660_CLSD_AMP_CTRL:
239 case RT5660_LOUT_AMP_CTRL:
240 case RT5660_SPK_AMP_SPKVDD:
241 case RT5660_MICBIAS:
242 case RT5660_CLSD_OUT_CTRL1:
243 case RT5660_CLSD_OUT_CTRL2:
244 case RT5660_DIPOLE_MIC_CTRL1:
245 case RT5660_DIPOLE_MIC_CTRL2:
246 case RT5660_DIPOLE_MIC_CTRL3:
247 case RT5660_DIPOLE_MIC_CTRL4:
248 case RT5660_DIPOLE_MIC_CTRL5:
249 case RT5660_DIPOLE_MIC_CTRL6:
250 case RT5660_DIPOLE_MIC_CTRL7:
251 case RT5660_DIPOLE_MIC_CTRL8:
252 case RT5660_DIPOLE_MIC_CTRL9:
253 case RT5660_DIPOLE_MIC_CTRL10:
254 case RT5660_DIPOLE_MIC_CTRL11:
255 case RT5660_DIPOLE_MIC_CTRL12:
256 case RT5660_EQ_CTRL1:
257 case RT5660_EQ_CTRL2:
258 case RT5660_DRC_AGC_CTRL1:
259 case RT5660_DRC_AGC_CTRL2:
260 case RT5660_DRC_AGC_CTRL3:
261 case RT5660_DRC_AGC_CTRL4:
262 case RT5660_DRC_AGC_CTRL5:
263 case RT5660_JD_CTRL:
264 case RT5660_IRQ_CTRL1:
265 case RT5660_IRQ_CTRL2:
266 case RT5660_INT_IRQ_ST:
267 case RT5660_GPIO_CTRL1:
268 case RT5660_GPIO_CTRL2:
269 case RT5660_WIND_FILTER_CTRL1:
270 case RT5660_SV_ZCD1:
271 case RT5660_SV_ZCD2:
272 case RT5660_DRC1_LM_CTRL1:
273 case RT5660_DRC1_LM_CTRL2:
274 case RT5660_DRC2_LM_CTRL1:
275 case RT5660_DRC2_LM_CTRL2:
276 case RT5660_MULTI_DRC_CTRL:
277 case RT5660_DRC2_CTRL1:
278 case RT5660_DRC2_CTRL2:
279 case RT5660_DRC2_CTRL3:
280 case RT5660_DRC2_CTRL4:
281 case RT5660_DRC2_CTRL5:
282 case RT5660_ALC_PGA_CTRL1:
283 case RT5660_ALC_PGA_CTRL2:
284 case RT5660_ALC_PGA_CTRL3:
285 case RT5660_ALC_PGA_CTRL4:
286 case RT5660_ALC_PGA_CTRL5:
287 case RT5660_ALC_PGA_CTRL6:
288 case RT5660_ALC_PGA_CTRL7:
289 case RT5660_GEN_CTRL1:
290 case RT5660_GEN_CTRL2:
291 case RT5660_GEN_CTRL3:
292 case RT5660_VENDOR_ID:
293 case RT5660_VENDOR_ID1:
294 case RT5660_VENDOR_ID2:
295 return true;
296 default:
297 return false;
298 }
299}
300
301static const DECLARE_TLV_DB_SCALE(rt5660_out_vol_tlv, -4650, 150, 0);
302static const DECLARE_TLV_DB_SCALE(rt5660_dac_vol_tlv, -6525, 75, 0);
303static const DECLARE_TLV_DB_SCALE(rt5660_adc_vol_tlv, -1725, 75, 0);
304static const DECLARE_TLV_DB_SCALE(rt5660_adc_bst_tlv, 0, 1200, 0);
305static const DECLARE_TLV_DB_SCALE(rt5660_bst_tlv, -1200, 75, 0);
306
307static const struct snd_kcontrol_new rt5660_snd_controls[] = {
308 /* Speaker Output Volume */
309 SOC_SINGLE("Speaker Playback Switch", RT5660_SPK_VOL, RT5660_L_MUTE_SFT,
310 1, 1),
311 SOC_SINGLE_TLV("Speaker Playback Volume", RT5660_SPK_VOL,
312 RT5660_L_VOL_SFT, 39, 1, rt5660_out_vol_tlv),
313
314 /* OUTPUT Control */
315 SOC_DOUBLE("OUT Playback Switch", RT5660_LOUT_VOL, RT5660_L_MUTE_SFT,
316 RT5660_R_MUTE_SFT, 1, 1),
317 SOC_DOUBLE_TLV("OUT Playback Volume", RT5660_LOUT_VOL, RT5660_L_VOL_SFT,
318 RT5660_R_VOL_SFT, 39, 1, rt5660_out_vol_tlv),
319
320 /* DAC Digital Volume */
321 SOC_DOUBLE_TLV("DAC1 Playback Volume", RT5660_DAC1_DIG_VOL,
322 RT5660_DAC_L1_VOL_SFT, RT5660_DAC_R1_VOL_SFT, 87, 0,
323 rt5660_dac_vol_tlv),
324
325 /* IN1/IN2/IN3 Control */
326 SOC_SINGLE_TLV("IN1 Boost Volume", RT5660_IN1_IN2, RT5660_BST_SFT1, 69,
327 0, rt5660_bst_tlv),
328 SOC_SINGLE_TLV("IN2 Boost Volume", RT5660_IN1_IN2, RT5660_BST_SFT2, 69,
329 0, rt5660_bst_tlv),
330 SOC_SINGLE_TLV("IN3 Boost Volume", RT5660_IN3_IN4, RT5660_BST_SFT3, 69,
331 0, rt5660_bst_tlv),
332
333 /* ADC Digital Volume Control */
334 SOC_DOUBLE("ADC Capture Switch", RT5660_STO1_ADC_DIG_VOL,
335 RT5660_L_MUTE_SFT, RT5660_R_MUTE_SFT, 1, 1),
336 SOC_DOUBLE_TLV("ADC Capture Volume", RT5660_STO1_ADC_DIG_VOL,
337 RT5660_ADC_L_VOL_SFT, RT5660_ADC_R_VOL_SFT, 63, 0,
338 rt5660_adc_vol_tlv),
339
340 /* ADC Boost Volume Control */
341 SOC_DOUBLE_TLV("STO1 ADC Boost Gain Volume", RT5660_ADC_BST_VOL1,
342 RT5660_STO1_ADC_L_BST_SFT, RT5660_STO1_ADC_R_BST_SFT, 3, 0,
343 rt5660_adc_bst_tlv),
344};
345
346/**
347 * rt5660_set_dmic_clk - Set parameter of dmic.
348 *
349 * @w: DAPM widget.
350 * @kcontrol: The kcontrol of this widget.
351 * @event: Event id.
352 *
353 */
354static int rt5660_set_dmic_clk(struct snd_soc_dapm_widget *w,
355 struct snd_kcontrol *kcontrol, int event)
356{
357 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
358 struct rt5660_priv *rt5660 = snd_soc_codec_get_drvdata(codec);
359 int idx, rate;
360
361 rate = rt5660->sysclk / rl6231_get_pre_div(rt5660->regmap,
362 RT5660_ADDA_CLK1, RT5660_I2S_PD1_SFT);
363 idx = rl6231_calc_dmic_clk(rate);
364 if (idx < 0)
365 dev_err(codec->dev, "Failed to set DMIC clock\n");
366 else
367 snd_soc_update_bits(codec, RT5660_DMIC_CTRL1,
368 RT5660_DMIC_CLK_MASK, idx << RT5660_DMIC_CLK_SFT);
369
370 return idx;
371}
372
373static int rt5660_is_sys_clk_from_pll(struct snd_soc_dapm_widget *source,
374 struct snd_soc_dapm_widget *sink)
375{
376 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(source->dapm);
377 unsigned int val;
378
379 val = snd_soc_read(codec, RT5660_GLB_CLK);
380 val &= RT5660_SCLK_SRC_MASK;
381 if (val == RT5660_SCLK_SRC_PLL1)
382 return 1;
383 else
384 return 0;
385}
386
387/* Digital Mixer */
388static const struct snd_kcontrol_new rt5660_sto1_adc_l_mix[] = {
389 SOC_DAPM_SINGLE("ADC1 Switch", RT5660_STO1_ADC_MIXER,
390 RT5660_M_ADC_L1_SFT, 1, 1),
391 SOC_DAPM_SINGLE("ADC2 Switch", RT5660_STO1_ADC_MIXER,
392 RT5660_M_ADC_L2_SFT, 1, 1),
393};
394
395static const struct snd_kcontrol_new rt5660_sto1_adc_r_mix[] = {
396 SOC_DAPM_SINGLE("ADC1 Switch", RT5660_STO1_ADC_MIXER,
397 RT5660_M_ADC_R1_SFT, 1, 1),
398 SOC_DAPM_SINGLE("ADC2 Switch", RT5660_STO1_ADC_MIXER,
399 RT5660_M_ADC_R2_SFT, 1, 1),
400};
401
402static const struct snd_kcontrol_new rt5660_dac_l_mix[] = {
403 SOC_DAPM_SINGLE("Stereo ADC Switch", RT5660_AD_DA_MIXER,
404 RT5660_M_ADCMIX_L_SFT, 1, 1),
405 SOC_DAPM_SINGLE("DAC1 Switch", RT5660_AD_DA_MIXER,
406 RT5660_M_DAC1_L_SFT, 1, 1),
407};
408
409static const struct snd_kcontrol_new rt5660_dac_r_mix[] = {
410 SOC_DAPM_SINGLE("Stereo ADC Switch", RT5660_AD_DA_MIXER,
411 RT5660_M_ADCMIX_R_SFT, 1, 1),
412 SOC_DAPM_SINGLE("DAC1 Switch", RT5660_AD_DA_MIXER,
413 RT5660_M_DAC1_R_SFT, 1, 1),
414};
415
416static const struct snd_kcontrol_new rt5660_sto_dac_l_mix[] = {
417 SOC_DAPM_SINGLE("DAC L1 Switch", RT5660_STO_DAC_MIXER,
418 RT5660_M_DAC_L1_SFT, 1, 1),
419 SOC_DAPM_SINGLE("DAC R1 Switch", RT5660_STO_DAC_MIXER,
420 RT5660_M_DAC_R1_STO_L_SFT, 1, 1),
421};
422
423static const struct snd_kcontrol_new rt5660_sto_dac_r_mix[] = {
424 SOC_DAPM_SINGLE("DAC R1 Switch", RT5660_STO_DAC_MIXER,
425 RT5660_M_DAC_R1_SFT, 1, 1),
426 SOC_DAPM_SINGLE("DAC L1 Switch", RT5660_STO_DAC_MIXER,
427 RT5660_M_DAC_L1_STO_R_SFT, 1, 1),
428};
429
430/* Analog Input Mixer */
431static const struct snd_kcontrol_new rt5660_rec_l_mix[] = {
432 SOC_DAPM_SINGLE("BST3 Switch", RT5660_REC_L2_MIXER,
433 RT5660_M_BST3_RM_L_SFT, 1, 1),
434 SOC_DAPM_SINGLE("BST2 Switch", RT5660_REC_L2_MIXER,
435 RT5660_M_BST2_RM_L_SFT, 1, 1),
436 SOC_DAPM_SINGLE("BST1 Switch", RT5660_REC_L2_MIXER,
437 RT5660_M_BST1_RM_L_SFT, 1, 1),
438 SOC_DAPM_SINGLE("OUT MIXL Switch", RT5660_REC_L2_MIXER,
439 RT5660_M_OM_L_RM_L_SFT, 1, 1),
440};
441
442static const struct snd_kcontrol_new rt5660_rec_r_mix[] = {
443 SOC_DAPM_SINGLE("BST3 Switch", RT5660_REC_R2_MIXER,
444 RT5660_M_BST3_RM_R_SFT, 1, 1),
445 SOC_DAPM_SINGLE("BST2 Switch", RT5660_REC_R2_MIXER,
446 RT5660_M_BST2_RM_R_SFT, 1, 1),
447 SOC_DAPM_SINGLE("BST1 Switch", RT5660_REC_R2_MIXER,
448 RT5660_M_BST1_RM_R_SFT, 1, 1),
449 SOC_DAPM_SINGLE("OUT MIXR Switch", RT5660_REC_R2_MIXER,
450 RT5660_M_OM_R_RM_R_SFT, 1, 1),
451};
452
453static const struct snd_kcontrol_new rt5660_spk_mix[] = {
454 SOC_DAPM_SINGLE("BST3 Switch", RT5660_SPK_MIXER,
455 RT5660_M_BST3_SM_SFT, 1, 1),
456 SOC_DAPM_SINGLE("BST1 Switch", RT5660_SPK_MIXER,
457 RT5660_M_BST1_SM_SFT, 1, 1),
458 SOC_DAPM_SINGLE("DACL Switch", RT5660_SPK_MIXER,
459 RT5660_M_DACL_SM_SFT, 1, 1),
460 SOC_DAPM_SINGLE("DACR Switch", RT5660_SPK_MIXER,
461 RT5660_M_DACR_SM_SFT, 1, 1),
462 SOC_DAPM_SINGLE("OUTMIXL Switch", RT5660_SPK_MIXER,
463 RT5660_M_OM_L_SM_SFT, 1, 1),
464};
465
466static const struct snd_kcontrol_new rt5660_out_l_mix[] = {
467 SOC_DAPM_SINGLE("BST3 Switch", RT5660_OUT_L1_MIXER,
468 RT5660_M_BST3_OM_L_SFT, 1, 1),
469 SOC_DAPM_SINGLE("BST2 Switch", RT5660_OUT_L1_MIXER,
470 RT5660_M_BST2_OM_L_SFT, 1, 1),
471 SOC_DAPM_SINGLE("BST1 Switch", RT5660_OUT_L1_MIXER,
472 RT5660_M_BST1_OM_L_SFT, 1, 1),
473 SOC_DAPM_SINGLE("RECMIXL Switch", RT5660_OUT_L1_MIXER,
474 RT5660_M_RM_L_OM_L_SFT, 1, 1),
475 SOC_DAPM_SINGLE("DACR Switch", RT5660_OUT_L1_MIXER,
476 RT5660_M_DAC_R_OM_L_SFT, 1, 1),
477 SOC_DAPM_SINGLE("DACL Switch", RT5660_OUT_L1_MIXER,
478 RT5660_M_DAC_L_OM_L_SFT, 1, 1),
479};
480
481static const struct snd_kcontrol_new rt5660_out_r_mix[] = {
482 SOC_DAPM_SINGLE("BST2 Switch", RT5660_OUT_R1_MIXER,
483 RT5660_M_BST2_OM_R_SFT, 1, 1),
484 SOC_DAPM_SINGLE("BST1 Switch", RT5660_OUT_R1_MIXER,
485 RT5660_M_BST1_OM_R_SFT, 1, 1),
486 SOC_DAPM_SINGLE("RECMIXR Switch", RT5660_OUT_R1_MIXER,
487 RT5660_M_RM_R_OM_R_SFT, 1, 1),
488 SOC_DAPM_SINGLE("DACR Switch", RT5660_OUT_R1_MIXER,
489 RT5660_M_DAC_R_OM_R_SFT, 1, 1),
490 SOC_DAPM_SINGLE("DACL Switch", RT5660_OUT_R1_MIXER,
491 RT5660_M_DAC_L_OM_R_SFT, 1, 1),
492};
493
494static const struct snd_kcontrol_new rt5660_spo_mix[] = {
495 SOC_DAPM_SINGLE("DACR Switch", RT5660_SPO_MIXER,
496 RT5660_M_DAC_R_SPM_SFT, 1, 1),
497 SOC_DAPM_SINGLE("DACL Switch", RT5660_SPO_MIXER,
498 RT5660_M_DAC_L_SPM_SFT, 1, 1),
499 SOC_DAPM_SINGLE("SPKVOL Switch", RT5660_SPO_MIXER,
500 RT5660_M_SV_SPM_SFT, 1, 1),
501 SOC_DAPM_SINGLE("BST1 Switch", RT5660_SPO_MIXER,
502 RT5660_M_BST1_SPM_SFT, 1, 1),
503};
504
505static const struct snd_kcontrol_new rt5660_lout_mix[] = {
506 SOC_DAPM_SINGLE("DAC Switch", RT5660_LOUT_MIXER,
507 RT5660_M_DAC1_LM_SFT, 1, 1),
508 SOC_DAPM_SINGLE("OUTMIX Switch", RT5660_LOUT_MIXER,
509 RT5660_M_LOVOL_LM_SFT, 1, 1),
510};
511
512static const struct snd_kcontrol_new spk_vol_control =
513 SOC_DAPM_SINGLE("Switch", RT5660_SPK_VOL,
514 RT5660_VOL_L_SFT, 1, 1);
515
516static const struct snd_kcontrol_new lout_l_vol_control =
517 SOC_DAPM_SINGLE("Switch", RT5660_LOUT_VOL,
518 RT5660_VOL_L_SFT, 1, 1);
519
520static const struct snd_kcontrol_new lout_r_vol_control =
521 SOC_DAPM_SINGLE("Switch", RT5660_LOUT_VOL,
522 RT5660_VOL_R_SFT, 1, 1);
523
524/* Interface data select */
525static const char * const rt5660_data_select[] = {
526 "L/R", "R/L", "L/L", "R/R"
527};
528
529static const SOC_ENUM_SINGLE_DECL(rt5660_if1_dac_enum,
530 RT5660_DIG_INF1_DATA, RT5660_IF1_DAC_IN_SFT, rt5660_data_select);
531
532static const SOC_ENUM_SINGLE_DECL(rt5660_if1_adc_enum,
533 RT5660_DIG_INF1_DATA, RT5660_IF1_ADC_IN_SFT, rt5660_data_select);
534
535static const struct snd_kcontrol_new rt5660_if1_dac_swap_mux =
536 SOC_DAPM_ENUM("IF1 DAC Swap Source", rt5660_if1_dac_enum);
537
538static const struct snd_kcontrol_new rt5660_if1_adc_swap_mux =
539 SOC_DAPM_ENUM("IF1 ADC Swap Source", rt5660_if1_adc_enum);
540
541static int rt5660_lout_event(struct snd_soc_dapm_widget *w,
542 struct snd_kcontrol *kcontrol, int event)
543{
544 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
545
546 switch (event) {
547 case SND_SOC_DAPM_POST_PMU:
548 snd_soc_update_bits(codec, RT5660_LOUT_AMP_CTRL,
549 RT5660_LOUT_CO_MASK | RT5660_LOUT_CB_MASK,
550 RT5660_LOUT_CO_EN | RT5660_LOUT_CB_PU);
551 break;
552
553 case SND_SOC_DAPM_PRE_PMD:
554 snd_soc_update_bits(codec, RT5660_LOUT_AMP_CTRL,
555 RT5660_LOUT_CO_MASK | RT5660_LOUT_CB_MASK,
556 RT5660_LOUT_CO_DIS | RT5660_LOUT_CB_PD);
557 break;
558
559 default:
560 return 0;
561 }
562
563 return 0;
564}
565
566static const struct snd_soc_dapm_widget rt5660_dapm_widgets[] = {
567 SND_SOC_DAPM_SUPPLY("LDO2", RT5660_PWR_ANLG1,
568 RT5660_PWR_LDO2_BIT, 0, NULL, 0),
569 SND_SOC_DAPM_SUPPLY("PLL1", RT5660_PWR_ANLG2,
570 RT5660_PWR_PLL_BIT, 0, NULL, 0),
571
572 /* MICBIAS */
573 SND_SOC_DAPM_SUPPLY("MICBIAS1", RT5660_PWR_ANLG2,
574 RT5660_PWR_MB1_BIT, 0, NULL, 0),
575 SND_SOC_DAPM_SUPPLY("MICBIAS2", RT5660_PWR_ANLG2,
576 RT5660_PWR_MB2_BIT, 0, NULL, 0),
577
578 /* Input Side */
579 /* Input Lines */
580 SND_SOC_DAPM_INPUT("DMIC L1"),
581 SND_SOC_DAPM_INPUT("DMIC R1"),
582
583 SND_SOC_DAPM_INPUT("IN1P"),
584 SND_SOC_DAPM_INPUT("IN1N"),
585 SND_SOC_DAPM_INPUT("IN2P"),
586 SND_SOC_DAPM_INPUT("IN3P"),
587 SND_SOC_DAPM_INPUT("IN3N"),
588
589 SND_SOC_DAPM_SUPPLY("DMIC CLK", SND_SOC_NOPM, 0, 0,
590 rt5660_set_dmic_clk, SND_SOC_DAPM_PRE_PMU),
591 SND_SOC_DAPM_SUPPLY("DMIC Power", RT5660_DMIC_CTRL1,
592 RT5660_DMIC_1_EN_SFT, 0, NULL, 0),
593
594 /* Boost */
595 SND_SOC_DAPM_PGA("BST1", RT5660_PWR_ANLG2, RT5660_PWR_BST1_BIT, 0,
596 NULL, 0),
597 SND_SOC_DAPM_PGA("BST2", RT5660_PWR_ANLG2, RT5660_PWR_BST2_BIT, 0,
598 NULL, 0),
599 SND_SOC_DAPM_PGA("BST3", RT5660_PWR_ANLG2, RT5660_PWR_BST3_BIT, 0,
600 NULL, 0),
601
602 /* REC Mixer */
603 SND_SOC_DAPM_MIXER("RECMIXL", RT5660_PWR_MIXER, RT5660_PWR_RM_L_BIT,
604 0, rt5660_rec_l_mix, ARRAY_SIZE(rt5660_rec_l_mix)),
605 SND_SOC_DAPM_MIXER("RECMIXR", RT5660_PWR_MIXER, RT5660_PWR_RM_R_BIT,
606 0, rt5660_rec_r_mix, ARRAY_SIZE(rt5660_rec_r_mix)),
607
608 /* ADCs */
609 SND_SOC_DAPM_ADC("ADC L", NULL, SND_SOC_NOPM, 0, 0),
610 SND_SOC_DAPM_ADC("ADC R", NULL, SND_SOC_NOPM, 0, 0),
611
612 SND_SOC_DAPM_SUPPLY("ADC L power", RT5660_PWR_DIG1,
613 RT5660_PWR_ADC_L_BIT, 0, NULL, 0),
614 SND_SOC_DAPM_SUPPLY("ADC R power", RT5660_PWR_DIG1,
615 RT5660_PWR_ADC_R_BIT, 0, NULL, 0),
616 SND_SOC_DAPM_SUPPLY("ADC clock", RT5660_PR_BASE + RT5660_CHOP_DAC_ADC,
617 12, 0, NULL, 0),
618
619 /* ADC Mixer */
620 SND_SOC_DAPM_SUPPLY("adc stereo1 filter", RT5660_PWR_DIG2,
621 RT5660_PWR_ADC_S1F_BIT, 0, NULL, 0),
622 SND_SOC_DAPM_MIXER("Sto1 ADC MIXL", SND_SOC_NOPM, 0, 0,
623 rt5660_sto1_adc_l_mix, ARRAY_SIZE(rt5660_sto1_adc_l_mix)),
624 SND_SOC_DAPM_MIXER("Sto1 ADC MIXR", SND_SOC_NOPM, 0, 0,
625 rt5660_sto1_adc_r_mix, ARRAY_SIZE(rt5660_sto1_adc_r_mix)),
626
627 /* ADC */
628 SND_SOC_DAPM_ADC("Stereo1 ADC MIXL", NULL, RT5660_STO1_ADC_DIG_VOL,
629 RT5660_L_MUTE_SFT, 1),
630 SND_SOC_DAPM_ADC("Stereo1 ADC MIXR", NULL, RT5660_STO1_ADC_DIG_VOL,
631 RT5660_R_MUTE_SFT, 1),
632
633 /* Digital Interface */
634 SND_SOC_DAPM_SUPPLY("I2S1", RT5660_PWR_DIG1, RT5660_PWR_I2S1_BIT, 0,
635 NULL, 0),
636 SND_SOC_DAPM_PGA("IF1 DAC", SND_SOC_NOPM, 0, 0, NULL, 0),
637 SND_SOC_DAPM_PGA("IF1 DAC L", SND_SOC_NOPM, 0, 0, NULL, 0),
638 SND_SOC_DAPM_PGA("IF1 DAC R", SND_SOC_NOPM, 0, 0, NULL, 0),
639 SND_SOC_DAPM_MUX("IF1 DAC Swap Mux", SND_SOC_NOPM, 0, 0,
640 &rt5660_if1_dac_swap_mux),
641 SND_SOC_DAPM_PGA("IF1 ADC", SND_SOC_NOPM, 0, 0, NULL, 0),
642 SND_SOC_DAPM_MUX("IF1 ADC Swap Mux", SND_SOC_NOPM, 0, 0,
643 &rt5660_if1_adc_swap_mux),
644
645 /* Audio Interface */
646 SND_SOC_DAPM_AIF_IN("AIF1RX", "AIF1 Playback", 0, SND_SOC_NOPM, 0, 0),
647 SND_SOC_DAPM_AIF_OUT("AIF1TX", "AIF1 Capture", 0, SND_SOC_NOPM, 0, 0),
648
649 /* Output Side */
650 /* DAC mixer before sound effect */
651 SND_SOC_DAPM_MIXER("DAC1 MIXL", SND_SOC_NOPM, 0, 0, rt5660_dac_l_mix,
652 ARRAY_SIZE(rt5660_dac_l_mix)),
653 SND_SOC_DAPM_MIXER("DAC1 MIXR", SND_SOC_NOPM, 0, 0, rt5660_dac_r_mix,
654 ARRAY_SIZE(rt5660_dac_r_mix)),
655
656 /* DAC Mixer */
657 SND_SOC_DAPM_SUPPLY("dac stereo1 filter", RT5660_PWR_DIG2,
658 RT5660_PWR_DAC_S1F_BIT, 0, NULL, 0),
659 SND_SOC_DAPM_MIXER("Stereo DAC MIXL", SND_SOC_NOPM, 0, 0,
660 rt5660_sto_dac_l_mix, ARRAY_SIZE(rt5660_sto_dac_l_mix)),
661 SND_SOC_DAPM_MIXER("Stereo DAC MIXR", SND_SOC_NOPM, 0, 0,
662 rt5660_sto_dac_r_mix, ARRAY_SIZE(rt5660_sto_dac_r_mix)),
663
664 /* DACs */
665 SND_SOC_DAPM_DAC("DAC L1", NULL, RT5660_PWR_DIG1,
666 RT5660_PWR_DAC_L1_BIT, 0),
667 SND_SOC_DAPM_DAC("DAC R1", NULL, RT5660_PWR_DIG1,
668 RT5660_PWR_DAC_R1_BIT, 0),
669
670 /* OUT Mixer */
671 SND_SOC_DAPM_MIXER("SPK MIX", RT5660_PWR_MIXER, RT5660_PWR_SM_BIT,
672 0, rt5660_spk_mix, ARRAY_SIZE(rt5660_spk_mix)),
673 SND_SOC_DAPM_MIXER("OUT MIXL", RT5660_PWR_MIXER, RT5660_PWR_OM_L_BIT,
674 0, rt5660_out_l_mix, ARRAY_SIZE(rt5660_out_l_mix)),
675 SND_SOC_DAPM_MIXER("OUT MIXR", RT5660_PWR_MIXER, RT5660_PWR_OM_R_BIT,
676 0, rt5660_out_r_mix, ARRAY_SIZE(rt5660_out_r_mix)),
677
678 /* Output Volume */
679 SND_SOC_DAPM_SWITCH("SPKVOL", RT5660_PWR_VOL,
680 RT5660_PWR_SV_BIT, 0, &spk_vol_control),
681 SND_SOC_DAPM_PGA("DAC 1", SND_SOC_NOPM,
682 0, 0, NULL, 0),
683 SND_SOC_DAPM_PGA("LOUTVOL", SND_SOC_NOPM,
684 0, 0, NULL, 0),
685 SND_SOC_DAPM_SWITCH("LOUTVOL L", SND_SOC_NOPM,
686 RT5660_PWR_LV_L_BIT, 0, &lout_l_vol_control),
687 SND_SOC_DAPM_SWITCH("LOUTVOL R", SND_SOC_NOPM,
688 RT5660_PWR_LV_R_BIT, 0, &lout_r_vol_control),
689
690 /* HPO/LOUT/Mono Mixer */
691 SND_SOC_DAPM_MIXER("SPO MIX", SND_SOC_NOPM, 0,
692 0, rt5660_spo_mix, ARRAY_SIZE(rt5660_spo_mix)),
693 SND_SOC_DAPM_MIXER("LOUT MIX", SND_SOC_NOPM, 0, 0,
694 rt5660_lout_mix, ARRAY_SIZE(rt5660_lout_mix)),
695 SND_SOC_DAPM_SUPPLY("VREF HP", RT5660_GEN_CTRL1,
696 RT5660_PWR_VREF_HP_SFT, 0, NULL, 0),
697 SND_SOC_DAPM_PGA_S("LOUT amp", 1, RT5660_PWR_ANLG1,
698 RT5660_PWR_HA_BIT, 0, rt5660_lout_event,
699 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
700 SND_SOC_DAPM_PGA_S("SPK amp", 1, RT5660_PWR_DIG1,
701 RT5660_PWR_CLS_D_BIT, 0, NULL, 0),
702
703 /* Output Lines */
704 SND_SOC_DAPM_OUTPUT("LOUTL"),
705 SND_SOC_DAPM_OUTPUT("LOUTR"),
706 SND_SOC_DAPM_OUTPUT("SPO"),
707};
708
709static const struct snd_soc_dapm_route rt5660_dapm_routes[] = {
710 { "MICBIAS1", NULL, "LDO2" },
711 { "MICBIAS2", NULL, "LDO2" },
712
713 { "BST1", NULL, "IN1P" },
714 { "BST1", NULL, "IN1N" },
715 { "BST2", NULL, "IN2P" },
716 { "BST3", NULL, "IN3P" },
717 { "BST3", NULL, "IN3N" },
718
719 { "RECMIXL", "BST3 Switch", "BST3" },
720 { "RECMIXL", "BST2 Switch", "BST2" },
721 { "RECMIXL", "BST1 Switch", "BST1" },
722 { "RECMIXL", "OUT MIXL Switch", "OUT MIXL" },
723
724 { "RECMIXR", "BST3 Switch", "BST3" },
725 { "RECMIXR", "BST2 Switch", "BST2" },
726 { "RECMIXR", "BST1 Switch", "BST1" },
727 { "RECMIXR", "OUT MIXR Switch", "OUT MIXR" },
728
729 { "ADC L", NULL, "RECMIXL" },
730 { "ADC L", NULL, "ADC L power" },
731 { "ADC L", NULL, "ADC clock" },
732 { "ADC R", NULL, "RECMIXR" },
733 { "ADC R", NULL, "ADC R power" },
734 { "ADC R", NULL, "ADC clock" },
735
736 {"DMIC L1", NULL, "DMIC CLK"},
737 {"DMIC L1", NULL, "DMIC Power"},
738 {"DMIC R1", NULL, "DMIC CLK"},
739 {"DMIC R1", NULL, "DMIC Power"},
740
741 { "Sto1 ADC MIXL", "ADC1 Switch", "ADC L" },
742 { "Sto1 ADC MIXL", "ADC2 Switch", "DMIC L1" },
743 { "Sto1 ADC MIXR", "ADC1 Switch", "ADC R" },
744 { "Sto1 ADC MIXR", "ADC2 Switch", "DMIC R1" },
745
746 { "Stereo1 ADC MIXL", NULL, "Sto1 ADC MIXL" },
747 { "Stereo1 ADC MIXL", NULL, "adc stereo1 filter" },
748 { "adc stereo1 filter", NULL, "PLL1", rt5660_is_sys_clk_from_pll },
749
750 { "Stereo1 ADC MIXR", NULL, "Sto1 ADC MIXR" },
751 { "Stereo1 ADC MIXR", NULL, "adc stereo1 filter" },
752 { "adc stereo1 filter", NULL, "PLL1", rt5660_is_sys_clk_from_pll },
753
754 { "IF1 ADC", NULL, "Stereo1 ADC MIXL" },
755 { "IF1 ADC", NULL, "Stereo1 ADC MIXR" },
756 { "IF1 ADC", NULL, "I2S1" },
757
758 { "IF1 ADC Swap Mux", "L/R", "IF1 ADC" },
759 { "IF1 ADC Swap Mux", "R/L", "IF1 ADC" },
760 { "IF1 ADC Swap Mux", "L/L", "IF1 ADC" },
761 { "IF1 ADC Swap Mux", "R/R", "IF1 ADC" },
762 { "AIF1TX", NULL, "IF1 ADC Swap Mux" },
763
764 { "IF1 DAC", NULL, "AIF1RX" },
765 { "IF1 DAC", NULL, "I2S1" },
766
767 { "IF1 DAC Swap Mux", "L/R", "IF1 DAC" },
768 { "IF1 DAC Swap Mux", "R/L", "IF1 DAC" },
769 { "IF1 DAC Swap Mux", "L/L", "IF1 DAC" },
770 { "IF1 DAC Swap Mux", "R/R", "IF1 DAC" },
771
772 { "IF1 DAC L", NULL, "IF1 DAC Swap Mux" },
773 { "IF1 DAC R", NULL, "IF1 DAC Swap Mux" },
774
775 { "DAC1 MIXL", "Stereo ADC Switch", "Stereo1 ADC MIXL" },
776 { "DAC1 MIXL", "DAC1 Switch", "IF1 DAC L" },
777 { "DAC1 MIXR", "Stereo ADC Switch", "Stereo1 ADC MIXR" },
778 { "DAC1 MIXR", "DAC1 Switch", "IF1 DAC R" },
779
780 { "Stereo DAC MIXL", "DAC L1 Switch", "DAC1 MIXL" },
781 { "Stereo DAC MIXL", "DAC R1 Switch", "DAC1 MIXR" },
782 { "Stereo DAC MIXL", NULL, "dac stereo1 filter" },
783 { "dac stereo1 filter", NULL, "PLL1", rt5660_is_sys_clk_from_pll },
784 { "Stereo DAC MIXR", "DAC R1 Switch", "DAC1 MIXR" },
785 { "Stereo DAC MIXR", "DAC L1 Switch", "DAC1 MIXL" },
786 { "Stereo DAC MIXR", NULL, "dac stereo1 filter" },
787 { "dac stereo1 filter", NULL, "PLL1", rt5660_is_sys_clk_from_pll },
788
789 { "DAC L1", NULL, "Stereo DAC MIXL" },
790 { "DAC R1", NULL, "Stereo DAC MIXR" },
791
792 { "SPK MIX", "BST3 Switch", "BST3" },
793 { "SPK MIX", "BST1 Switch", "BST1" },
794 { "SPK MIX", "DACL Switch", "DAC L1" },
795 { "SPK MIX", "DACR Switch", "DAC R1" },
796 { "SPK MIX", "OUTMIXL Switch", "OUT MIXL" },
797
798 { "OUT MIXL", "BST3 Switch", "BST3" },
799 { "OUT MIXL", "BST2 Switch", "BST2" },
800 { "OUT MIXL", "BST1 Switch", "BST1" },
801 { "OUT MIXL", "RECMIXL Switch", "RECMIXL" },
802 { "OUT MIXL", "DACR Switch", "DAC R1" },
803 { "OUT MIXL", "DACL Switch", "DAC L1" },
804
805 { "OUT MIXR", "BST2 Switch", "BST2" },
806 { "OUT MIXR", "BST1 Switch", "BST1" },
807 { "OUT MIXR", "RECMIXR Switch", "RECMIXR" },
808 { "OUT MIXR", "DACR Switch", "DAC R1" },
809 { "OUT MIXR", "DACL Switch", "DAC L1" },
810
811 { "SPO MIX", "DACR Switch", "DAC R1" },
812 { "SPO MIX", "DACL Switch", "DAC L1" },
813 { "SPO MIX", "SPKVOL Switch", "SPKVOL" },
814 { "SPO MIX", "BST1 Switch", "BST1" },
815
816 { "SPKVOL", "Switch", "SPK MIX" },
817 { "LOUTVOL L", "Switch", "OUT MIXL" },
818 { "LOUTVOL R", "Switch", "OUT MIXR" },
819
820 { "LOUTVOL", NULL, "LOUTVOL L" },
821 { "LOUTVOL", NULL, "LOUTVOL R" },
822
823 { "DAC 1", NULL, "DAC L1" },
824 { "DAC 1", NULL, "DAC R1" },
825
826 { "LOUT MIX", "DAC Switch", "DAC 1" },
827 { "LOUT MIX", "OUTMIX Switch", "LOUTVOL" },
828
829 { "LOUT amp", NULL, "LOUT MIX" },
830 { "LOUT amp", NULL, "VREF HP" },
831 { "LOUTL", NULL, "LOUT amp" },
832 { "LOUTR", NULL, "LOUT amp" },
833
834 { "SPK amp", NULL, "SPO MIX" },
835 { "SPO", NULL, "SPK amp" },
836};
837
838static int rt5660_hw_params(struct snd_pcm_substream *substream,
839 struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
840{
841 struct snd_soc_codec *codec = dai->codec;
842 struct rt5660_priv *rt5660 = snd_soc_codec_get_drvdata(codec);
843 unsigned int val_len = 0, val_clk, mask_clk;
844 int pre_div, bclk_ms, frame_size;
845
846 rt5660->lrck[dai->id] = params_rate(params);
847 pre_div = rl6231_get_clk_info(rt5660->sysclk, rt5660->lrck[dai->id]);
848 if (pre_div < 0) {
849 dev_err(codec->dev, "Unsupported clock setting %d for DAI %d\n",
850 rt5660->lrck[dai->id], dai->id);
851 return -EINVAL;
852 }
853
854 frame_size = snd_soc_params_to_frame_size(params);
855 if (frame_size < 0) {
856 dev_err(codec->dev, "Unsupported frame size: %d\n", frame_size);
857 return frame_size;
858 }
859
860 if (frame_size > 32)
861 bclk_ms = 1;
862 else
863 bclk_ms = 0;
864
865 rt5660->bclk[dai->id] = rt5660->lrck[dai->id] * (32 << bclk_ms);
866
867 dev_dbg(dai->dev, "bclk is %dHz and lrck is %dHz\n",
868 rt5660->bclk[dai->id], rt5660->lrck[dai->id]);
869 dev_dbg(dai->dev, "bclk_ms is %d and pre_div is %d for iis %d\n",
870 bclk_ms, pre_div, dai->id);
871
872 switch (params_width(params)) {
873 case 16:
874 break;
875 case 20:
876 val_len |= RT5660_I2S_DL_20;
877 break;
878 case 24:
879 val_len |= RT5660_I2S_DL_24;
880 break;
881 case 8:
882 val_len |= RT5660_I2S_DL_8;
883 break;
884 default:
885 return -EINVAL;
886 }
887
888 switch (dai->id) {
889 case RT5660_AIF1:
890 mask_clk = RT5660_I2S_BCLK_MS1_MASK | RT5660_I2S_PD1_MASK;
891 val_clk = bclk_ms << RT5660_I2S_BCLK_MS1_SFT |
892 pre_div << RT5660_I2S_PD1_SFT;
893 snd_soc_update_bits(codec, RT5660_I2S1_SDP, RT5660_I2S_DL_MASK,
894 val_len);
895 snd_soc_update_bits(codec, RT5660_ADDA_CLK1, mask_clk, val_clk);
896 break;
897
898 default:
899 dev_err(codec->dev, "Invalid dai->id: %d\n", dai->id);
900 return -EINVAL;
901 }
902
903 return 0;
904}
905
906static int rt5660_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
907{
908 struct snd_soc_codec *codec = dai->codec;
909 struct rt5660_priv *rt5660 = snd_soc_codec_get_drvdata(codec);
910 unsigned int reg_val = 0;
911
912 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
913 case SND_SOC_DAIFMT_CBM_CFM:
914 rt5660->master[dai->id] = 1;
915 break;
916
917 case SND_SOC_DAIFMT_CBS_CFS:
918 reg_val |= RT5660_I2S_MS_S;
919 rt5660->master[dai->id] = 0;
920 break;
921
922 default:
923 return -EINVAL;
924 }
925
926 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
927 case SND_SOC_DAIFMT_NB_NF:
928 break;
929
930 case SND_SOC_DAIFMT_IB_NF:
931 reg_val |= RT5660_I2S_BP_INV;
932 break;
933
934 default:
935 return -EINVAL;
936 }
937
938 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
939 case SND_SOC_DAIFMT_I2S:
940 break;
941
942 case SND_SOC_DAIFMT_LEFT_J:
943 reg_val |= RT5660_I2S_DF_LEFT;
944 break;
945
946 case SND_SOC_DAIFMT_DSP_A:
947 reg_val |= RT5660_I2S_DF_PCM_A;
948 break;
949
950 case SND_SOC_DAIFMT_DSP_B:
951 reg_val |= RT5660_I2S_DF_PCM_B;
952 break;
953
954 default:
955 return -EINVAL;
956 }
957
958 switch (dai->id) {
959 case RT5660_AIF1:
960 snd_soc_update_bits(codec, RT5660_I2S1_SDP,
961 RT5660_I2S_MS_MASK | RT5660_I2S_BP_MASK |
962 RT5660_I2S_DF_MASK, reg_val);
963 break;
964
965 default:
966 dev_err(codec->dev, "Invalid dai->id: %d\n", dai->id);
967 return -EINVAL;
968 }
969
970 return 0;
971}
972
973static int rt5660_set_dai_sysclk(struct snd_soc_dai *dai,
974 int clk_id, unsigned int freq, int dir)
975{
976 struct snd_soc_codec *codec = dai->codec;
977 struct rt5660_priv *rt5660 = snd_soc_codec_get_drvdata(codec);
978 unsigned int reg_val = 0;
979
980 if (freq == rt5660->sysclk && clk_id == rt5660->sysclk_src)
981 return 0;
982
983 switch (clk_id) {
984 case RT5660_SCLK_S_MCLK:
985 reg_val |= RT5660_SCLK_SRC_MCLK;
986 break;
987
988 case RT5660_SCLK_S_PLL1:
989 reg_val |= RT5660_SCLK_SRC_PLL1;
990 break;
991
992 case RT5660_SCLK_S_RCCLK:
993 reg_val |= RT5660_SCLK_SRC_RCCLK;
994 break;
995
996 default:
997 dev_err(codec->dev, "Invalid clock id (%d)\n", clk_id);
998 return -EINVAL;
999 }
1000
1001 snd_soc_update_bits(codec, RT5660_GLB_CLK, RT5660_SCLK_SRC_MASK,
1002 reg_val);
1003
1004 rt5660->sysclk = freq;
1005 rt5660->sysclk_src = clk_id;
1006
1007 dev_dbg(dai->dev, "Sysclk is %dHz and clock id is %d\n", freq, clk_id);
1008
1009 return 0;
1010}
1011
1012static int rt5660_set_dai_pll(struct snd_soc_dai *dai, int pll_id, int source,
1013 unsigned int freq_in, unsigned int freq_out)
1014{
1015 struct snd_soc_codec *codec = dai->codec;
1016 struct rt5660_priv *rt5660 = snd_soc_codec_get_drvdata(codec);
1017 struct rl6231_pll_code pll_code;
1018 int ret;
1019
1020 if (source == rt5660->pll_src && freq_in == rt5660->pll_in &&
1021 freq_out == rt5660->pll_out)
1022 return 0;
1023
1024 if (!freq_in || !freq_out) {
1025 dev_dbg(codec->dev, "PLL disabled\n");
1026
1027 rt5660->pll_in = 0;
1028 rt5660->pll_out = 0;
1029 snd_soc_update_bits(codec, RT5660_GLB_CLK,
1030 RT5660_SCLK_SRC_MASK, RT5660_SCLK_SRC_MCLK);
1031 return 0;
1032 }
1033
1034 switch (source) {
1035 case RT5660_PLL1_S_MCLK:
1036 snd_soc_update_bits(codec, RT5660_GLB_CLK,
1037 RT5660_PLL1_SRC_MASK, RT5660_PLL1_SRC_MCLK);
1038 break;
1039
1040 case RT5660_PLL1_S_BCLK:
1041 snd_soc_update_bits(codec, RT5660_GLB_CLK,
1042 RT5660_PLL1_SRC_MASK, RT5660_PLL1_SRC_BCLK1);
1043 break;
1044
1045 default:
1046 dev_err(codec->dev, "Unknown PLL source %d\n", source);
1047 return -EINVAL;
1048 }
1049
1050 ret = rl6231_pll_calc(freq_in, freq_out, &pll_code);
1051 if (ret < 0) {
1052 dev_err(codec->dev, "Unsupport input clock %d\n", freq_in);
1053 return ret;
1054 }
1055
1056 dev_dbg(codec->dev, "bypass=%d m=%d n=%d k=%d\n",
1057 pll_code.m_bp, (pll_code.m_bp ? 0 : pll_code.m_code),
1058 pll_code.n_code, pll_code.k_code);
1059
1060 snd_soc_write(codec, RT5660_PLL_CTRL1,
1061 pll_code.n_code << RT5660_PLL_N_SFT | pll_code.k_code);
1062 snd_soc_write(codec, RT5660_PLL_CTRL2,
1063 (pll_code.m_bp ? 0 : pll_code.m_code) << RT5660_PLL_M_SFT |
1064 pll_code.m_bp << RT5660_PLL_M_BP_SFT);
1065
1066 rt5660->pll_in = freq_in;
1067 rt5660->pll_out = freq_out;
1068 rt5660->pll_src = source;
1069
1070 return 0;
1071}
1072
1073static int rt5660_set_bias_level(struct snd_soc_codec *codec,
1074 enum snd_soc_bias_level level)
1075{
1076 struct rt5660_priv *rt5660 = snd_soc_codec_get_drvdata(codec);
1077 int ret;
1078
1079 switch (level) {
1080 case SND_SOC_BIAS_ON:
1081 break;
1082
1083 case SND_SOC_BIAS_PREPARE:
1084 snd_soc_update_bits(codec, RT5660_GEN_CTRL1,
1085 RT5660_DIG_GATE_CTRL, RT5660_DIG_GATE_CTRL);
1086
1087 if (IS_ERR(rt5660->mclk))
1088 break;
1089
1090 if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_ON) {
1091 clk_disable_unprepare(rt5660->mclk);
1092 } else {
1093 ret = clk_prepare_enable(rt5660->mclk);
1094 if (ret)
1095 return ret;
1096 }
1097 break;
1098
1099 case SND_SOC_BIAS_STANDBY:
1100 if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF) {
1101 snd_soc_update_bits(codec, RT5660_PWR_ANLG1,
1102 RT5660_PWR_VREF1 | RT5660_PWR_MB |
1103 RT5660_PWR_BG | RT5660_PWR_VREF2,
1104 RT5660_PWR_VREF1 | RT5660_PWR_MB |
1105 RT5660_PWR_BG | RT5660_PWR_VREF2);
1106 usleep_range(10000, 15000);
1107 snd_soc_update_bits(codec, RT5660_PWR_ANLG1,
1108 RT5660_PWR_FV1 | RT5660_PWR_FV2,
1109 RT5660_PWR_FV1 | RT5660_PWR_FV2);
1110 }
1111 break;
1112
1113 case SND_SOC_BIAS_OFF:
1114 snd_soc_update_bits(codec, RT5660_GEN_CTRL1,
1115 RT5660_DIG_GATE_CTRL, 0);
1116 break;
1117
1118 default:
1119 break;
1120 }
1121
1122 return 0;
1123}
1124
1125static int rt5660_probe(struct snd_soc_codec *codec)
1126{
1127 struct rt5660_priv *rt5660 = snd_soc_codec_get_drvdata(codec);
1128
1129 rt5660->codec = codec;
1130
1131 return 0;
1132}
1133
1134static int rt5660_remove(struct snd_soc_codec *codec)
1135{
1136 return snd_soc_write(codec, RT5660_RESET, 0);
1137}
1138
1139#ifdef CONFIG_PM
1140static int rt5660_suspend(struct snd_soc_codec *codec)
1141{
1142 struct rt5660_priv *rt5660 = snd_soc_codec_get_drvdata(codec);
1143
1144 regcache_cache_only(rt5660->regmap, true);
1145 regcache_mark_dirty(rt5660->regmap);
1146
1147 return 0;
1148}
1149
1150static int rt5660_resume(struct snd_soc_codec *codec)
1151{
1152 struct rt5660_priv *rt5660 = snd_soc_codec_get_drvdata(codec);
1153
1154 if (rt5660->pdata.poweroff_codec_in_suspend)
1155 usleep_range(350000, 400000);
1156
1157 regcache_cache_only(rt5660->regmap, false);
1158 regcache_sync(rt5660->regmap);
1159
1160 return 0;
1161}
1162#else
1163#define rt5660_suspend NULL
1164#define rt5660_resume NULL
1165#endif
1166
1167#define RT5660_STEREO_RATES SNDRV_PCM_RATE_8000_192000
1168#define RT5660_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \
1169 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S8)
1170
1171static const struct snd_soc_dai_ops rt5660_aif_dai_ops = {
1172 .hw_params = rt5660_hw_params,
1173 .set_fmt = rt5660_set_dai_fmt,
1174 .set_sysclk = rt5660_set_dai_sysclk,
1175 .set_pll = rt5660_set_dai_pll,
1176};
1177
1178static struct snd_soc_dai_driver rt5660_dai[] = {
1179 {
1180 .name = "rt5660-aif1",
1181 .id = RT5660_AIF1,
1182 .playback = {
1183 .stream_name = "AIF1 Playback",
1184 .channels_min = 1,
1185 .channels_max = 2,
1186 .rates = RT5660_STEREO_RATES,
1187 .formats = RT5660_FORMATS,
1188 },
1189 .capture = {
1190 .stream_name = "AIF1 Capture",
1191 .channels_min = 1,
1192 .channels_max = 2,
1193 .rates = RT5660_STEREO_RATES,
1194 .formats = RT5660_FORMATS,
1195 },
1196 .ops = &rt5660_aif_dai_ops,
1197 },
1198};
1199
1200static struct snd_soc_codec_driver soc_codec_dev_rt5660 = {
1201 .probe = rt5660_probe,
1202 .remove = rt5660_remove,
1203 .suspend = rt5660_suspend,
1204 .resume = rt5660_resume,
1205 .set_bias_level = rt5660_set_bias_level,
1206 .idle_bias_off = true,
1207 .component_driver = {
1208 .controls = rt5660_snd_controls,
1209 .num_controls = ARRAY_SIZE(rt5660_snd_controls),
1210 .dapm_widgets = rt5660_dapm_widgets,
1211 .num_dapm_widgets = ARRAY_SIZE(rt5660_dapm_widgets),
1212 .dapm_routes = rt5660_dapm_routes,
1213 .num_dapm_routes = ARRAY_SIZE(rt5660_dapm_routes),
1214 },
1215};
1216
1217static const struct regmap_config rt5660_regmap = {
1218 .reg_bits = 8,
1219 .val_bits = 16,
1220 .use_single_rw = true,
1221
1222 .max_register = RT5660_VENDOR_ID2 + 1 + (ARRAY_SIZE(rt5660_ranges) *
1223 RT5660_PR_SPACING),
1224 .volatile_reg = rt5660_volatile_register,
1225 .readable_reg = rt5660_readable_register,
1226
1227 .cache_type = REGCACHE_RBTREE,
1228 .reg_defaults = rt5660_reg,
1229 .num_reg_defaults = ARRAY_SIZE(rt5660_reg),
1230 .ranges = rt5660_ranges,
1231 .num_ranges = ARRAY_SIZE(rt5660_ranges),
1232};
1233
1234static const struct i2c_device_id rt5660_i2c_id[] = {
1235 { "rt5660", 0 },
1236 { }
1237};
1238MODULE_DEVICE_TABLE(i2c, rt5660_i2c_id);
1239
1240static const struct of_device_id rt5660_of_match[] = {
1241 { .compatible = "realtek,rt5660", },
1242 {},
1243};
1244MODULE_DEVICE_TABLE(of, rt5660_of_match);
1245
1246static const struct acpi_device_id rt5660_acpi_match[] = {
1247 { "10EC5660", 0 },
1248 { },
1249};
1250MODULE_DEVICE_TABLE(acpi, rt5660_acpi_match);
1251
1252static int rt5660_parse_dt(struct rt5660_priv *rt5660, struct device *dev)
1253{
1254 rt5660->pdata.in1_diff = device_property_read_bool(dev,
1255 "realtek,in1-differential");
1256 rt5660->pdata.in3_diff = device_property_read_bool(dev,
1257 "realtek,in3-differential");
1258 rt5660->pdata.poweroff_codec_in_suspend = device_property_read_bool(dev,
1259 "realtek,poweroff-in-suspend");
1260 device_property_read_u32(dev, "realtek,dmic1-data-pin",
1261 &rt5660->pdata.dmic1_data_pin);
1262
1263 return 0;
1264}
1265
1266static int rt5660_i2c_probe(struct i2c_client *i2c,
1267 const struct i2c_device_id *id)
1268{
1269 struct rt5660_platform_data *pdata = dev_get_platdata(&i2c->dev);
1270 struct rt5660_priv *rt5660;
1271 int ret;
1272 unsigned int val;
1273
1274 rt5660 = devm_kzalloc(&i2c->dev, sizeof(struct rt5660_priv),
1275 GFP_KERNEL);
1276
1277 if (rt5660 == NULL)
1278 return -ENOMEM;
1279
1280 /* Check if MCLK provided */
1281 rt5660->mclk = devm_clk_get(&i2c->dev, "mclk");
1282 if (PTR_ERR(rt5660->mclk) == -EPROBE_DEFER)
1283 return -EPROBE_DEFER;
1284
1285 i2c_set_clientdata(i2c, rt5660);
1286
1287 if (pdata)
1288 rt5660->pdata = *pdata;
1289 else if (i2c->dev.of_node)
1290 rt5660_parse_dt(rt5660, &i2c->dev);
1291
1292 rt5660->regmap = devm_regmap_init_i2c(i2c, &rt5660_regmap);
1293 if (IS_ERR(rt5660->regmap)) {
1294 ret = PTR_ERR(rt5660->regmap);
1295 dev_err(&i2c->dev, "Failed to allocate register map: %d\n",
1296 ret);
1297 return ret;
1298 }
1299
1300 regmap_read(rt5660->regmap, RT5660_VENDOR_ID2, &val);
1301 if (val != RT5660_DEVICE_ID) {
1302 dev_err(&i2c->dev,
1303 "Device with ID register %#x is not rt5660\n", val);
1304 return -ENODEV;
1305 }
1306
1307 regmap_write(rt5660->regmap, RT5660_RESET, 0);
1308
1309 ret = regmap_register_patch(rt5660->regmap, rt5660_patch,
1310 ARRAY_SIZE(rt5660_patch));
1311 if (ret != 0)
1312 dev_warn(&i2c->dev, "Failed to apply regmap patch: %d\n", ret);
1313
1314 if (rt5660->pdata.dmic1_data_pin) {
1315 regmap_update_bits(rt5660->regmap, RT5660_GPIO_CTRL1,
1316 RT5660_GP1_PIN_MASK, RT5660_GP1_PIN_DMIC1_SCL);
1317
1318 if (rt5660->pdata.dmic1_data_pin == RT5660_DMIC1_DATA_GPIO2)
1319 regmap_update_bits(rt5660->regmap, RT5660_DMIC_CTRL1,
1320 RT5660_SEL_DMIC_DATA_MASK,
1321 RT5660_SEL_DMIC_DATA_GPIO2);
1322 else if (rt5660->pdata.dmic1_data_pin == RT5660_DMIC1_DATA_IN1P)
1323 regmap_update_bits(rt5660->regmap, RT5660_DMIC_CTRL1,
1324 RT5660_SEL_DMIC_DATA_MASK,
1325 RT5660_SEL_DMIC_DATA_IN1P);
1326 }
1327
1328 return snd_soc_register_codec(&i2c->dev, &soc_codec_dev_rt5660,
1329 rt5660_dai, ARRAY_SIZE(rt5660_dai));
1330}
1331
1332static int rt5660_i2c_remove(struct i2c_client *i2c)
1333{
1334 snd_soc_unregister_codec(&i2c->dev);
1335
1336 return 0;
1337}
1338
1339static struct i2c_driver rt5660_i2c_driver = {
1340 .driver = {
1341 .name = "rt5660",
1342 .acpi_match_table = ACPI_PTR(rt5660_acpi_match),
1343 .of_match_table = of_match_ptr(rt5660_of_match),
1344 },
1345 .probe = rt5660_i2c_probe,
1346 .remove = rt5660_i2c_remove,
1347 .id_table = rt5660_i2c_id,
1348};
1349module_i2c_driver(rt5660_i2c_driver);
1350
1351MODULE_DESCRIPTION("ASoC RT5660 driver");
1352MODULE_AUTHOR("Oder Chiou <oder_chiou@realtek.com>");
1353MODULE_LICENSE("GPL v2");
diff --git a/sound/soc/codecs/rt5660.h b/sound/soc/codecs/rt5660.h
new file mode 100644
index 000000000000..6cdb9269ec9e
--- /dev/null
+++ b/sound/soc/codecs/rt5660.h
@@ -0,0 +1,847 @@
1/*
2 * rt5660.h -- RT5660 ALSA SoC audio driver
3 *
4 * Copyright 2016 Realtek Semiconductor Corp.
5 * Author: Oder Chiou <oder_chiou@realtek.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11
12#ifndef _RT5660_H
13#define _RT5660_H
14
15#include <linux/clk.h>
16#include <sound/rt5660.h>
17
18/* Info */
19#define RT5660_RESET 0x00
20#define RT5660_VENDOR_ID 0xfd
21#define RT5660_VENDOR_ID1 0xfe
22#define RT5660_VENDOR_ID2 0xff
23/* I/O - Output */
24#define RT5660_SPK_VOL 0x01
25#define RT5660_LOUT_VOL 0x02
26/* I/O - Input */
27#define RT5660_IN1_IN2 0x0d
28#define RT5660_IN3_IN4 0x0e
29/* I/O - ADC/DAC/DMIC */
30#define RT5660_DAC1_DIG_VOL 0x19
31#define RT5660_STO1_ADC_DIG_VOL 0x1c
32#define RT5660_ADC_BST_VOL1 0x1e
33/* Mixer - D-D */
34#define RT5660_STO1_ADC_MIXER 0x27
35#define RT5660_AD_DA_MIXER 0x29
36#define RT5660_STO_DAC_MIXER 0x2a
37#define RT5660_DIG_INF1_DATA 0x2f
38/* Mixer - ADC */
39#define RT5660_REC_L1_MIXER 0x3b
40#define RT5660_REC_L2_MIXER 0x3c
41#define RT5660_REC_R1_MIXER 0x3d
42#define RT5660_REC_R2_MIXER 0x3e
43/* Mixer - DAC */
44#define RT5660_LOUT_MIXER 0x45
45#define RT5660_SPK_MIXER 0x46
46#define RT5660_SPO_MIXER 0x48
47#define RT5660_SPO_CLSD_RATIO 0x4a
48#define RT5660_OUT_L_GAIN1 0x4d
49#define RT5660_OUT_L_GAIN2 0x4e
50#define RT5660_OUT_L1_MIXER 0x4f
51#define RT5660_OUT_R_GAIN1 0x50
52#define RT5660_OUT_R_GAIN2 0x51
53#define RT5660_OUT_R1_MIXER 0x52
54/* Power */
55#define RT5660_PWR_DIG1 0x61
56#define RT5660_PWR_DIG2 0x62
57#define RT5660_PWR_ANLG1 0x63
58#define RT5660_PWR_ANLG2 0x64
59#define RT5660_PWR_MIXER 0x65
60#define RT5660_PWR_VOL 0x66
61/* Private Register Control */
62#define RT5660_PRIV_INDEX 0x6a
63#define RT5660_PRIV_DATA 0x6c
64/* Format - ADC/DAC */
65#define RT5660_I2S1_SDP 0x70
66#define RT5660_ADDA_CLK1 0x73
67#define RT5660_ADDA_CLK2 0x74
68#define RT5660_DMIC_CTRL1 0x75
69/* Function - Analog */
70#define RT5660_GLB_CLK 0x80
71#define RT5660_PLL_CTRL1 0x81
72#define RT5660_PLL_CTRL2 0x82
73#define RT5660_CLSD_AMP_OC_CTRL 0x8c
74#define RT5660_CLSD_AMP_CTRL 0x8d
75#define RT5660_LOUT_AMP_CTRL 0x8e
76#define RT5660_SPK_AMP_SPKVDD 0x92
77#define RT5660_MICBIAS 0x93
78#define RT5660_CLSD_OUT_CTRL1 0xa1
79#define RT5660_CLSD_OUT_CTRL2 0xa2
80#define RT5660_DIPOLE_MIC_CTRL1 0xa3
81#define RT5660_DIPOLE_MIC_CTRL2 0xa4
82#define RT5660_DIPOLE_MIC_CTRL3 0xa5
83#define RT5660_DIPOLE_MIC_CTRL4 0xa6
84#define RT5660_DIPOLE_MIC_CTRL5 0xa7
85#define RT5660_DIPOLE_MIC_CTRL6 0xa8
86#define RT5660_DIPOLE_MIC_CTRL7 0xa9
87#define RT5660_DIPOLE_MIC_CTRL8 0xaa
88#define RT5660_DIPOLE_MIC_CTRL9 0xab
89#define RT5660_DIPOLE_MIC_CTRL10 0xac
90#define RT5660_DIPOLE_MIC_CTRL11 0xad
91#define RT5660_DIPOLE_MIC_CTRL12 0xae
92/* Function - Digital */
93#define RT5660_EQ_CTRL1 0xb0
94#define RT5660_EQ_CTRL2 0xb1
95#define RT5660_DRC_AGC_CTRL1 0xb3
96#define RT5660_DRC_AGC_CTRL2 0xb4
97#define RT5660_DRC_AGC_CTRL3 0xb5
98#define RT5660_DRC_AGC_CTRL4 0xb6
99#define RT5660_DRC_AGC_CTRL5 0xb7
100#define RT5660_JD_CTRL 0xbb
101#define RT5660_IRQ_CTRL1 0xbd
102#define RT5660_IRQ_CTRL2 0xbe
103#define RT5660_INT_IRQ_ST 0xbf
104#define RT5660_GPIO_CTRL1 0xc0
105#define RT5660_GPIO_CTRL2 0xc2
106#define RT5660_WIND_FILTER_CTRL1 0xd3
107#define RT5660_SV_ZCD1 0xd9
108#define RT5660_SV_ZCD2 0xda
109#define RT5660_DRC1_LM_CTRL1 0xe0
110#define RT5660_DRC1_LM_CTRL2 0xe1
111#define RT5660_DRC2_LM_CTRL1 0xe2
112#define RT5660_DRC2_LM_CTRL2 0xe3
113#define RT5660_MULTI_DRC_CTRL 0xe4
114#define RT5660_DRC2_CTRL1 0xe5
115#define RT5660_DRC2_CTRL2 0xe6
116#define RT5660_DRC2_CTRL3 0xe7
117#define RT5660_DRC2_CTRL4 0xe8
118#define RT5660_DRC2_CTRL5 0xe9
119#define RT5660_ALC_PGA_CTRL1 0xea
120#define RT5660_ALC_PGA_CTRL2 0xeb
121#define RT5660_ALC_PGA_CTRL3 0xec
122#define RT5660_ALC_PGA_CTRL4 0xed
123#define RT5660_ALC_PGA_CTRL5 0xee
124#define RT5660_ALC_PGA_CTRL6 0xef
125#define RT5660_ALC_PGA_CTRL7 0xf0
126
127/* General Control */
128#define RT5660_GEN_CTRL1 0xfa
129#define RT5660_GEN_CTRL2 0xfb
130#define RT5660_GEN_CTRL3 0xfc
131
132/* Index of Codec Private Register definition */
133#define RT5660_CHOP_DAC_ADC 0x3d
134
135/* Global Definition */
136#define RT5660_L_MUTE (0x1 << 15)
137#define RT5660_L_MUTE_SFT 15
138#define RT5660_VOL_L_MUTE (0x1 << 14)
139#define RT5660_VOL_L_SFT 14
140#define RT5660_R_MUTE (0x1 << 7)
141#define RT5660_R_MUTE_SFT 7
142#define RT5660_VOL_R_MUTE (0x1 << 6)
143#define RT5660_VOL_R_SFT 6
144#define RT5660_L_VOL_MASK (0x3f << 8)
145#define RT5660_L_VOL_SFT 8
146#define RT5660_R_VOL_MASK (0x3f)
147#define RT5660_R_VOL_SFT 0
148
149/* IN1 and IN2 Control (0x0d) */
150#define RT5660_IN_DF1 (0x1 << 15)
151#define RT5660_IN_SFT1 15
152#define RT5660_BST_MASK1 (0x7f << 8)
153#define RT5660_BST_SFT1 8
154#define RT5660_IN_DF2 (0x1 << 7)
155#define RT5660_IN_SFT2 7
156#define RT5660_BST_MASK2 (0x7f << 0)
157#define RT5660_BST_SFT2 0
158
159/* IN3 and IN4 Control (0x0e) */
160#define RT5660_IN_DF3 (0x1 << 15)
161#define RT5660_IN_SFT3 15
162#define RT5660_BST_MASK3 (0x7f << 8)
163#define RT5660_BST_SFT3 8
164#define RT5660_IN_DF4 (0x1 << 7)
165#define RT5660_IN_SFT4 7
166#define RT5660_BST_MASK4 (0x7f << 0)
167#define RT5660_BST_SFT4 0
168
169/* DAC1 Digital Volume (0x19) */
170#define RT5660_DAC_L1_VOL_MASK (0x7f << 9)
171#define RT5660_DAC_L1_VOL_SFT 9
172#define RT5660_DAC_R1_VOL_MASK (0x7f << 1)
173#define RT5660_DAC_R1_VOL_SFT 1
174
175/* ADC Digital Volume Control (0x1c) */
176#define RT5660_ADC_L_VOL_MASK (0x3f << 9)
177#define RT5660_ADC_L_VOL_SFT 9
178#define RT5660_ADC_R_VOL_MASK (0x3f << 1)
179#define RT5660_ADC_R_VOL_SFT 1
180
181/* ADC Boost Volume Control (0x1e) */
182#define RT5660_STO1_ADC_L_BST_MASK (0x3 << 14)
183#define RT5660_STO1_ADC_L_BST_SFT 14
184#define RT5660_STO1_ADC_R_BST_MASK (0x3 << 12)
185#define RT5660_STO1_ADC_R_BST_SFT 12
186
187/* Stereo ADC Mixer Control (0x27) */
188#define RT5660_M_ADC_L1 (0x1 << 14)
189#define RT5660_M_ADC_L1_SFT 14
190#define RT5660_M_ADC_L2 (0x1 << 13)
191#define RT5660_M_ADC_L2_SFT 13
192#define RT5660_M_ADC_R1 (0x1 << 6)
193#define RT5660_M_ADC_R1_SFT 6
194#define RT5660_M_ADC_R2 (0x1 << 5)
195#define RT5660_M_ADC_R2_SFT 5
196
197/* ADC Mixer to DAC Mixer Control (0x29) */
198#define RT5660_M_ADCMIX_L (0x1 << 15)
199#define RT5660_M_ADCMIX_L_SFT 15
200#define RT5660_M_DAC1_L (0x1 << 14)
201#define RT5660_M_DAC1_L_SFT 14
202#define RT5660_M_ADCMIX_R (0x1 << 7)
203#define RT5660_M_ADCMIX_R_SFT 7
204#define RT5660_M_DAC1_R (0x1 << 6)
205#define RT5660_M_DAC1_R_SFT 6
206
207/* Stereo DAC Mixer Control (0x2a) */
208#define RT5660_M_DAC_L1 (0x1 << 14)
209#define RT5660_M_DAC_L1_SFT 14
210#define RT5660_DAC_L1_STO_L_VOL_MASK (0x1 << 13)
211#define RT5660_DAC_L1_STO_L_VOL_SFT 13
212#define RT5660_M_DAC_R1_STO_L (0x1 << 9)
213#define RT5660_M_DAC_R1_STO_L_SFT 9
214#define RT5660_DAC_R1_STO_L_VOL_MASK (0x1 << 8)
215#define RT5660_DAC_R1_STO_L_VOL_SFT 8
216#define RT5660_M_DAC_R1 (0x1 << 6)
217#define RT5660_M_DAC_R1_SFT 6
218#define RT5660_DAC_R1_STO_R_VOL_MASK (0x1 << 5)
219#define RT5660_DAC_R1_STO_R_VOL_SFT 5
220#define RT5660_M_DAC_L1_STO_R (0x1 << 1)
221#define RT5660_M_DAC_L1_STO_R_SFT 1
222#define RT5660_DAC_L1_STO_R_VOL_MASK (0x1)
223#define RT5660_DAC_L1_STO_R_VOL_SFT 0
224
225/* Digital Interface Data Control (0x2f) */
226#define RT5660_IF1_DAC_IN_SEL (0x3 << 14)
227#define RT5660_IF1_DAC_IN_SFT 14
228#define RT5660_IF1_ADC_IN_SEL (0x3 << 12)
229#define RT5660_IF1_ADC_IN_SFT 12
230
231/* REC Left Mixer Control 1 (0x3b) */
232#define RT5660_G_BST3_RM_L_MASK (0x7 << 4)
233#define RT5660_G_BST3_RM_L_SFT 4
234#define RT5660_G_BST2_RM_L_MASK (0x7 << 1)
235#define RT5660_G_BST2_RM_L_SFT 1
236
237/* REC Left Mixer Control 2 (0x3c) */
238#define RT5660_G_BST1_RM_L_MASK (0x7 << 13)
239#define RT5660_G_BST1_RM_L_SFT 13
240#define RT5660_G_OM_L_RM_L_MASK (0x7 << 10)
241#define RT5660_G_OM_L_RM_L_SFT 10
242#define RT5660_M_BST3_RM_L (0x1 << 3)
243#define RT5660_M_BST3_RM_L_SFT 3
244#define RT5660_M_BST2_RM_L (0x1 << 2)
245#define RT5660_M_BST2_RM_L_SFT 2
246#define RT5660_M_BST1_RM_L (0x1 << 1)
247#define RT5660_M_BST1_RM_L_SFT 1
248#define RT5660_M_OM_L_RM_L (0x1)
249#define RT5660_M_OM_L_RM_L_SFT 0
250
251/* REC Right Mixer Control 1 (0x3d) */
252#define RT5660_G_BST3_RM_R_MASK (0x7 << 4)
253#define RT5660_G_BST3_RM_R_SFT 4
254#define RT5660_G_BST2_RM_R_MASK (0x7 << 1)
255#define RT5660_G_BST2_RM_R_SFT 1
256
257/* REC Right Mixer Control 2 (0x3e) */
258#define RT5660_G_BST1_RM_R_MASK (0x7 << 13)
259#define RT5660_G_BST1_RM_R_SFT 13
260#define RT5660_G_OM_R_RM_R_MASK (0x7 << 10)
261#define RT5660_G_OM_R_RM_R_SFT 10
262#define RT5660_M_BST3_RM_R (0x1 << 3)
263#define RT5660_M_BST3_RM_R_SFT 3
264#define RT5660_M_BST2_RM_R (0x1 << 2)
265#define RT5660_M_BST2_RM_R_SFT 2
266#define RT5660_M_BST1_RM_R (0x1 << 1)
267#define RT5660_M_BST1_RM_R_SFT 1
268#define RT5660_M_OM_R_RM_R (0x1)
269#define RT5660_M_OM_R_RM_R_SFT 0
270
271/* LOUTMIX Control (0x45) */
272#define RT5660_M_DAC1_LM (0x1 << 14)
273#define RT5660_M_DAC1_LM_SFT 14
274#define RT5660_M_LOVOL_M (0x1 << 13)
275#define RT5660_M_LOVOL_LM_SFT 13
276
277/* SPK Mixer Control (0x46) */
278#define RT5660_G_BST3_SM_MASK (0x3 << 14)
279#define RT5660_G_BST3_SM_SFT 14
280#define RT5660_G_BST1_SM_MASK (0x3 << 12)
281#define RT5660_G_BST1_SM_SFT 12
282#define RT5660_G_DACl_SM_MASK (0x3 << 10)
283#define RT5660_G_DACl_SM_SFT 10
284#define RT5660_G_DACR_SM_MASK (0x3 << 8)
285#define RT5660_G_DACR_SM_SFT 8
286#define RT5660_G_OM_L_SM_MASK (0x3 << 6)
287#define RT5660_G_OM_L_SM_SFT 6
288#define RT5660_M_DACR_SM (0x1 << 5)
289#define RT5660_M_DACR_SM_SFT 5
290#define RT5660_M_BST1_SM (0x1 << 4)
291#define RT5660_M_BST1_SM_SFT 4
292#define RT5660_M_BST3_SM (0x1 << 3)
293#define RT5660_M_BST3_SM_SFT 3
294#define RT5660_M_DACL_SM (0x1 << 2)
295#define RT5660_M_DACL_SM_SFT 2
296#define RT5660_M_OM_L_SM (0x1 << 1)
297#define RT5660_M_OM_L_SM_SFT 1
298
299/* SPOMIX Control (0x48) */
300#define RT5660_M_DAC_R_SPM (0x1 << 14)
301#define RT5660_M_DAC_R_SPM_SFT 14
302#define RT5660_M_DAC_L_SPM (0x1 << 13)
303#define RT5660_M_DAC_L_SPM_SFT 13
304#define RT5660_M_SV_SPM (0x1 << 12)
305#define RT5660_M_SV_SPM_SFT 12
306#define RT5660_M_BST1_SPM (0x1 << 11)
307#define RT5660_M_BST1_SPM_SFT 11
308
309/* Output Left Mixer Control 1 (0x4d) */
310#define RT5660_G_BST3_OM_L_MASK (0x7 << 13)
311#define RT5660_G_BST3_OM_L_SFT 13
312#define RT5660_G_BST2_OM_L_MASK (0x7 << 10)
313#define RT5660_G_BST2_OM_L_SFT 10
314#define RT5660_G_BST1_OM_L_MASK (0x7 << 7)
315#define RT5660_G_BST1_OM_L_SFT 7
316#define RT5660_G_RM_L_OM_L_MASK (0x7 << 1)
317#define RT5660_G_RM_L_OM_L_SFT 1
318
319/* Output Left Mixer Control 2 (0x4e) */
320#define RT5660_G_DAC_R1_OM_L_MASK (0x7 << 10)
321#define RT5660_G_DAC_R1_OM_L_SFT 10
322#define RT5660_G_DAC_L1_OM_L_MASK (0x7 << 7)
323#define RT5660_G_DAC_L1_OM_L_SFT 7
324
325/* Output Left Mixer Control 3 (0x4f) */
326#define RT5660_M_BST3_OM_L (0x1 << 5)
327#define RT5660_M_BST3_OM_L_SFT 5
328#define RT5660_M_BST2_OM_L (0x1 << 4)
329#define RT5660_M_BST2_OM_L_SFT 4
330#define RT5660_M_BST1_OM_L (0x1 << 3)
331#define RT5660_M_BST1_OM_L_SFT 3
332#define RT5660_M_RM_L_OM_L (0x1 << 2)
333#define RT5660_M_RM_L_OM_L_SFT 2
334#define RT5660_M_DAC_R_OM_L (0x1 << 1)
335#define RT5660_M_DAC_R_OM_L_SFT 1
336#define RT5660_M_DAC_L_OM_L (0x1)
337#define RT5660_M_DAC_L_OM_L_SFT 0
338
339/* Output Right Mixer Control 1 (0x50) */
340#define RT5660_G_BST2_OM_R_MASK (0x7 << 10)
341#define RT5660_G_BST2_OM_R_SFT 10
342#define RT5660_G_BST1_OM_R_MASK (0x7 << 7)
343#define RT5660_G_BST1_OM_R_SFT 7
344#define RT5660_G_RM_R_OM_R_MASK (0x7 << 1)
345#define RT5660_G_RM_R_OM_R_SFT 1
346
347/* Output Right Mixer Control 2 (0x51) */
348#define RT5660_G_DAC_L_OM_R_MASK (0x7 << 10)
349#define RT5660_G_DAC_L_OM_R_SFT 10
350#define RT5660_G_DAC_R_OM_R_MASK (0x7 << 7)
351#define RT5660_G_DAC_R_OM_R_SFT 7
352
353/* Output Right Mixer Control 3 (0x52) */
354#define RT5660_M_BST2_OM_R (0x1 << 4)
355#define RT5660_M_BST2_OM_R_SFT 4
356#define RT5660_M_BST1_OM_R (0x1 << 3)
357#define RT5660_M_BST1_OM_R_SFT 3
358#define RT5660_M_RM_R_OM_R (0x1 << 2)
359#define RT5660_M_RM_R_OM_R_SFT 2
360#define RT5660_M_DAC_L_OM_R (0x1 << 1)
361#define RT5660_M_DAC_L_OM_R_SFT 1
362#define RT5660_M_DAC_R_OM_R (0x1)
363#define RT5660_M_DAC_R_OM_R_SFT 0
364
365/* Power Management for Digital 1 (0x61) */
366#define RT5660_PWR_I2S1 (0x1 << 15)
367#define RT5660_PWR_I2S1_BIT 15
368#define RT5660_PWR_DAC_L1 (0x1 << 12)
369#define RT5660_PWR_DAC_L1_BIT 12
370#define RT5660_PWR_DAC_R1 (0x1 << 11)
371#define RT5660_PWR_DAC_R1_BIT 11
372#define RT5660_PWR_ADC_L (0x1 << 2)
373#define RT5660_PWR_ADC_L_BIT 2
374#define RT5660_PWR_ADC_R (0x1 << 1)
375#define RT5660_PWR_ADC_R_BIT 1
376#define RT5660_PWR_CLS_D (0x1)
377#define RT5660_PWR_CLS_D_BIT 0
378
379/* Power Management for Digital 2 (0x62) */
380#define RT5660_PWR_ADC_S1F (0x1 << 15)
381#define RT5660_PWR_ADC_S1F_BIT 15
382#define RT5660_PWR_DAC_S1F (0x1 << 11)
383#define RT5660_PWR_DAC_S1F_BIT 11
384
385/* Power Management for Analog 1 (0x63) */
386#define RT5660_PWR_VREF1 (0x1 << 15)
387#define RT5660_PWR_VREF1_BIT 15
388#define RT5660_PWR_FV1 (0x1 << 14)
389#define RT5660_PWR_FV1_BIT 14
390#define RT5660_PWR_MB (0x1 << 13)
391#define RT5660_PWR_MB_BIT 13
392#define RT5660_PWR_BG (0x1 << 11)
393#define RT5660_PWR_BG_BIT 11
394#define RT5660_PWR_HP_L (0x1 << 7)
395#define RT5660_PWR_HP_L_BIT 7
396#define RT5660_PWR_HP_R (0x1 << 6)
397#define RT5660_PWR_HP_R_BIT 6
398#define RT5660_PWR_HA (0x1 << 5)
399#define RT5660_PWR_HA_BIT 5
400#define RT5660_PWR_VREF2 (0x1 << 4)
401#define RT5660_PWR_VREF2_BIT 4
402#define RT5660_PWR_FV2 (0x1 << 3)
403#define RT5660_PWR_FV2_BIT 3
404#define RT5660_PWR_LDO2 (0x1 << 2)
405#define RT5660_PWR_LDO2_BIT 2
406
407/* Power Management for Analog 2 (0x64) */
408#define RT5660_PWR_BST1 (0x1 << 15)
409#define RT5660_PWR_BST1_BIT 15
410#define RT5660_PWR_BST2 (0x1 << 14)
411#define RT5660_PWR_BST2_BIT 14
412#define RT5660_PWR_BST3 (0x1 << 13)
413#define RT5660_PWR_BST3_BIT 13
414#define RT5660_PWR_MB1 (0x1 << 11)
415#define RT5660_PWR_MB1_BIT 11
416#define RT5660_PWR_MB2 (0x1 << 10)
417#define RT5660_PWR_MB2_BIT 10
418#define RT5660_PWR_PLL (0x1 << 9)
419#define RT5660_PWR_PLL_BIT 9
420
421/* Power Management for Mixer (0x65) */
422#define RT5660_PWR_OM_L (0x1 << 15)
423#define RT5660_PWR_OM_L_BIT 15
424#define RT5660_PWR_OM_R (0x1 << 14)
425#define RT5660_PWR_OM_R_BIT 14
426#define RT5660_PWR_SM (0x1 << 13)
427#define RT5660_PWR_SM_BIT 13
428#define RT5660_PWR_RM_L (0x1 << 11)
429#define RT5660_PWR_RM_L_BIT 11
430#define RT5660_PWR_RM_R (0x1 << 10)
431#define RT5660_PWR_RM_R_BIT 10
432
433/* Power Management for Volume (0x66) */
434#define RT5660_PWR_SV (0x1 << 15)
435#define RT5660_PWR_SV_BIT 15
436#define RT5660_PWR_LV_L (0x1 << 11)
437#define RT5660_PWR_LV_L_BIT 11
438#define RT5660_PWR_LV_R (0x1 << 10)
439#define RT5660_PWR_LV_R_BIT 10
440
441/* I2S1 Audio Serial Data Port Control (0x70) */
442#define RT5660_I2S_MS_MASK (0x1 << 15)
443#define RT5660_I2S_MS_SFT 15
444#define RT5660_I2S_MS_M (0x0 << 15)
445#define RT5660_I2S_MS_S (0x1 << 15)
446#define RT5660_I2S_O_CP_MASK (0x3 << 10)
447#define RT5660_I2S_O_CP_SFT 10
448#define RT5660_I2S_O_CP_OFF (0x0 << 10)
449#define RT5660_I2S_O_CP_U_LAW (0x1 << 10)
450#define RT5660_I2S_O_CP_A_LAW (0x2 << 10)
451#define RT5660_I2S_I_CP_MASK (0x3 << 8)
452#define RT5660_I2S_I_CP_SFT 8
453#define RT5660_I2S_I_CP_OFF (0x0 << 8)
454#define RT5660_I2S_I_CP_U_LAW (0x1 << 8)
455#define RT5660_I2S_I_CP_A_LAW (0x2 << 8)
456#define RT5660_I2S_BP_MASK (0x1 << 7)
457#define RT5660_I2S_BP_SFT 7
458#define RT5660_I2S_BP_NOR (0x0 << 7)
459#define RT5660_I2S_BP_INV (0x1 << 7)
460#define RT5660_I2S_DL_MASK (0x3 << 2)
461#define RT5660_I2S_DL_SFT 2
462#define RT5660_I2S_DL_16 (0x0 << 2)
463#define RT5660_I2S_DL_20 (0x1 << 2)
464#define RT5660_I2S_DL_24 (0x2 << 2)
465#define RT5660_I2S_DL_8 (0x3 << 2)
466#define RT5660_I2S_DF_MASK (0x3)
467#define RT5660_I2S_DF_SFT 0
468#define RT5660_I2S_DF_I2S (0x0)
469#define RT5660_I2S_DF_LEFT (0x1)
470#define RT5660_I2S_DF_PCM_A (0x2)
471#define RT5660_I2S_DF_PCM_B (0x3)
472
473/* ADC/DAC Clock Control 1 (0x73) */
474#define RT5660_I2S_BCLK_MS1_MASK (0x1 << 15)
475#define RT5660_I2S_BCLK_MS1_SFT 15
476#define RT5660_I2S_BCLK_MS1_32 (0x0 << 15)
477#define RT5660_I2S_BCLK_MS1_64 (0x1 << 15)
478#define RT5660_I2S_PD1_MASK (0x7 << 12)
479#define RT5660_I2S_PD1_SFT 12
480#define RT5660_I2S_PD1_1 (0x0 << 12)
481#define RT5660_I2S_PD1_2 (0x1 << 12)
482#define RT5660_I2S_PD1_3 (0x2 << 12)
483#define RT5660_I2S_PD1_4 (0x3 << 12)
484#define RT5660_I2S_PD1_6 (0x4 << 12)
485#define RT5660_I2S_PD1_8 (0x5 << 12)
486#define RT5660_I2S_PD1_12 (0x6 << 12)
487#define RT5660_I2S_PD1_16 (0x7 << 12)
488#define RT5660_DAC_OSR_MASK (0x3 << 2)
489#define RT5660_DAC_OSR_SFT 2
490#define RT5660_DAC_OSR_128 (0x0 << 2)
491#define RT5660_DAC_OSR_64 (0x1 << 2)
492#define RT5660_DAC_OSR_32 (0x2 << 2)
493#define RT5660_DAC_OSR_16 (0x3 << 2)
494#define RT5660_ADC_OSR_MASK (0x3)
495#define RT5660_ADC_OSR_SFT 0
496#define RT5660_ADC_OSR_128 (0x0)
497#define RT5660_ADC_OSR_64 (0x1)
498#define RT5660_ADC_OSR_32 (0x2)
499#define RT5660_ADC_OSR_16 (0x3)
500
501/* ADC/DAC Clock Control 2 (0x74) */
502#define RT5660_RESET_ADF (0x1 << 13)
503#define RT5660_RESET_ADF_SFT 13
504#define RT5660_RESET_DAF (0x1 << 12)
505#define RT5660_RESET_DAF_SFT 12
506#define RT5660_DAHPF_EN (0x1 << 11)
507#define RT5660_DAHPF_EN_SFT 11
508#define RT5660_ADHPF_EN (0x1 << 10)
509#define RT5660_ADHPF_EN_SFT 10
510
511/* Digital Microphone Control (0x75) */
512#define RT5660_DMIC_1_EN_MASK (0x1 << 15)
513#define RT5660_DMIC_1_EN_SFT 15
514#define RT5660_DMIC_1_DIS (0x0 << 15)
515#define RT5660_DMIC_1_EN (0x1 << 15)
516#define RT5660_DMIC_1L_LH_MASK (0x1 << 13)
517#define RT5660_DMIC_1L_LH_SFT 13
518#define RT5660_DMIC_1L_LH_RISING (0x0 << 13)
519#define RT5660_DMIC_1L_LH_FALLING (0x1 << 13)
520#define RT5660_DMIC_1R_LH_MASK (0x1 << 12)
521#define RT5660_DMIC_1R_LH_SFT 12
522#define RT5660_DMIC_1R_LH_RISING (0x0 << 12)
523#define RT5660_DMIC_1R_LH_FALLING (0x1 << 12)
524#define RT5660_SEL_DMIC_DATA_MASK (0x1 << 11)
525#define RT5660_SEL_DMIC_DATA_SFT 11
526#define RT5660_SEL_DMIC_DATA_GPIO2 (0x0 << 11)
527#define RT5660_SEL_DMIC_DATA_IN1P (0x1 << 11)
528#define RT5660_DMIC_CLK_MASK (0x7 << 5)
529#define RT5660_DMIC_CLK_SFT 5
530
531/* Global Clock Control (0x80) */
532#define RT5660_SCLK_SRC_MASK (0x3 << 14)
533#define RT5660_SCLK_SRC_SFT 14
534#define RT5660_SCLK_SRC_MCLK (0x0 << 14)
535#define RT5660_SCLK_SRC_PLL1 (0x1 << 14)
536#define RT5660_SCLK_SRC_RCCLK (0x2 << 14)
537#define RT5660_PLL1_SRC_MASK (0x3 << 12)
538#define RT5660_PLL1_SRC_SFT 12
539#define RT5660_PLL1_SRC_MCLK (0x0 << 12)
540#define RT5660_PLL1_SRC_BCLK1 (0x1 << 12)
541#define RT5660_PLL1_SRC_RCCLK (0x2 << 12)
542#define RT5660_PLL1_PD_MASK (0x1 << 3)
543#define RT5660_PLL1_PD_SFT 3
544#define RT5660_PLL1_PD_1 (0x0 << 3)
545#define RT5660_PLL1_PD_2 (0x1 << 3)
546
547#define RT5660_PLL_INP_MAX 40000000
548#define RT5660_PLL_INP_MIN 256000
549/* PLL M/N/K Code Control 1 (0x81) */
550#define RT5660_PLL_N_MAX 0x1ff
551#define RT5660_PLL_N_MASK (RT5660_PLL_N_MAX << 7)
552#define RT5660_PLL_N_SFT 7
553#define RT5660_PLL_K_MAX 0x1f
554#define RT5660_PLL_K_MASK (RT5660_PLL_K_MAX)
555#define RT5660_PLL_K_SFT 0
556
557/* PLL M/N/K Code Control 2 (0x82) */
558#define RT5660_PLL_M_MAX 0xf
559#define RT5660_PLL_M_MASK (RT5660_PLL_M_MAX << 12)
560#define RT5660_PLL_M_SFT 12
561#define RT5660_PLL_M_BP (0x1 << 11)
562#define RT5660_PLL_M_BP_SFT 11
563
564/* Class D Over Current Control (0x8c) */
565#define RT5660_CLSD_OC_MASK (0x1 << 9)
566#define RT5660_CLSD_OC_SFT 9
567#define RT5660_CLSD_OC_PU (0x0 << 9)
568#define RT5660_CLSD_OC_PD (0x1 << 9)
569#define RT5660_AUTO_PD_MASK (0x1 << 8)
570#define RT5660_AUTO_PD_SFT 8
571#define RT5660_AUTO_PD_DIS (0x0 << 8)
572#define RT5660_AUTO_PD_EN (0x1 << 8)
573#define RT5660_CLSD_OC_TH_MASK (0x3f)
574#define RT5660_CLSD_OC_TH_SFT 0
575
576/* Class D Output Control (0x8d) */
577#define RT5660_CLSD_RATIO_MASK (0xf << 12)
578#define RT5660_CLSD_RATIO_SFT 12
579
580/* Lout Amp Control 1 (0x8e) */
581#define RT5660_LOUT_CO_MASK (0x1 << 4)
582#define RT5660_LOUT_CO_SFT 4
583#define RT5660_LOUT_CO_DIS (0x0 << 4)
584#define RT5660_LOUT_CO_EN (0x1 << 4)
585#define RT5660_LOUT_CB_MASK (0x1)
586#define RT5660_LOUT_CB_SFT 0
587#define RT5660_LOUT_CB_PD (0x0)
588#define RT5660_LOUT_CB_PU (0x1)
589
590/* SPKVDD detection control (0x92) */
591#define RT5660_SPKVDD_DET_MASK (0x1 << 15)
592#define RT5660_SPKVDD_DET_SFT 15
593#define RT5660_SPKVDD_DET_DIS (0x0 << 15)
594#define RT5660_SPKVDD_DET_EN (0x1 << 15)
595#define RT5660_SPK_AG_MASK (0x1 << 14)
596#define RT5660_SPK_AG_SFT 14
597#define RT5660_SPK_AG_DIS (0x0 << 14)
598#define RT5660_SPK_AG_EN (0x1 << 14)
599
600/* Micbias Control (0x93) */
601#define RT5660_MIC1_BS_MASK (0x1 << 15)
602#define RT5660_MIC1_BS_SFT 15
603#define RT5660_MIC1_BS_9AV (0x0 << 15)
604#define RT5660_MIC1_BS_75AV (0x1 << 15)
605#define RT5660_MIC2_BS_MASK (0x1 << 14)
606#define RT5660_MIC2_BS_SFT 14
607#define RT5660_MIC2_BS_9AV (0x0 << 14)
608#define RT5660_MIC2_BS_75AV (0x1 << 14)
609#define RT5660_MIC1_OVCD_MASK (0x1 << 11)
610#define RT5660_MIC1_OVCD_SFT 11
611#define RT5660_MIC1_OVCD_DIS (0x0 << 11)
612#define RT5660_MIC1_OVCD_EN (0x1 << 11)
613#define RT5660_MIC1_OVTH_MASK (0x3 << 9)
614#define RT5660_MIC1_OVTH_SFT 9
615#define RT5660_MIC1_OVTH_600UA (0x0 << 9)
616#define RT5660_MIC1_OVTH_1500UA (0x1 << 9)
617#define RT5660_MIC1_OVTH_2000UA (0x2 << 9)
618#define RT5660_MIC2_OVCD_MASK (0x1 << 8)
619#define RT5660_MIC2_OVCD_SFT 8
620#define RT5660_MIC2_OVCD_DIS (0x0 << 8)
621#define RT5660_MIC2_OVCD_EN (0x1 << 8)
622#define RT5660_MIC2_OVTH_MASK (0x3 << 6)
623#define RT5660_MIC2_OVTH_SFT 6
624#define RT5660_MIC2_OVTH_600UA (0x0 << 6)
625#define RT5660_MIC2_OVTH_1500UA (0x1 << 6)
626#define RT5660_MIC2_OVTH_2000UA (0x2 << 6)
627#define RT5660_PWR_CLK25M_MASK (0x1 << 4)
628#define RT5660_PWR_CLK25M_SFT 4
629#define RT5660_PWR_CLK25M_PD (0x0 << 4)
630#define RT5660_PWR_CLK25M_PU (0x1 << 4)
631
632/* EQ Control 1 (0xb0) */
633#define RT5660_EQ_SRC_MASK (0x1 << 15)
634#define RT5660_EQ_SRC_SFT 15
635#define RT5660_EQ_SRC_DAC (0x0 << 15)
636#define RT5660_EQ_SRC_ADC (0x1 << 15)
637#define RT5660_EQ_UPD (0x1 << 14)
638#define RT5660_EQ_UPD_BIT 14
639
640/* Jack Detect Control (0xbb) */
641#define RT5660_JD_MASK (0x3 << 14)
642#define RT5660_JD_SFT 14
643#define RT5660_JD_DIS (0x0 << 14)
644#define RT5660_JD_GPIO1 (0x1 << 14)
645#define RT5660_JD_GPIO2 (0x2 << 14)
646#define RT5660_JD_LOUT_MASK (0x1 << 11)
647#define RT5660_JD_LOUT_SFT 11
648#define RT5660_JD_LOUT_DIS (0x0 << 11)
649#define RT5660_JD_LOUT_EN (0x1 << 11)
650#define RT5660_JD_LOUT_TRG_MASK (0x1 << 10)
651#define RT5660_JD_LOUT_TRG_SFT 10
652#define RT5660_JD_LOUT_TRG_LO (0x0 << 10)
653#define RT5660_JD_LOUT_TRG_HI (0x1 << 10)
654#define RT5660_JD_SPO_MASK (0x1 << 9)
655#define RT5660_JD_SPO_SFT 9
656#define RT5660_JD_SPO_DIS (0x0 << 9)
657#define RT5660_JD_SPO_EN (0x1 << 9)
658#define RT5660_JD_SPO_TRG_MASK (0x1 << 8)
659#define RT5660_JD_SPO_TRG_SFT 8
660#define RT5660_JD_SPO_TRG_LO (0x0 << 8)
661#define RT5660_JD_SPO_TRG_HI (0x1 << 8)
662
663/* IRQ Control 1 (0xbd) */
664#define RT5660_IRQ_JD_MASK (0x1 << 15)
665#define RT5660_IRQ_JD_SFT 15
666#define RT5660_IRQ_JD_BP (0x0 << 15)
667#define RT5660_IRQ_JD_NOR (0x1 << 15)
668#define RT5660_IRQ_OT_MASK (0x1 << 14)
669#define RT5660_IRQ_OT_SFT 14
670#define RT5660_IRQ_OT_BP (0x0 << 14)
671#define RT5660_IRQ_OT_NOR (0x1 << 14)
672#define RT5660_JD_STKY_MASK (0x1 << 13)
673#define RT5660_JD_STKY_SFT 13
674#define RT5660_JD_STKY_DIS (0x0 << 13)
675#define RT5660_JD_STKY_EN (0x1 << 13)
676#define RT5660_OT_STKY_MASK (0x1 << 12)
677#define RT5660_OT_STKY_SFT 12
678#define RT5660_OT_STKY_DIS (0x0 << 12)
679#define RT5660_OT_STKY_EN (0x1 << 12)
680#define RT5660_JD_P_MASK (0x1 << 11)
681#define RT5660_JD_P_SFT 11
682#define RT5660_JD_P_NOR (0x0 << 11)
683#define RT5660_JD_P_INV (0x1 << 11)
684#define RT5660_OT_P_MASK (0x1 << 10)
685#define RT5660_OT_P_SFT 10
686#define RT5660_OT_P_NOR (0x0 << 10)
687#define RT5660_OT_P_INV (0x1 << 10)
688
689/* IRQ Control 2 (0xbe) */
690#define RT5660_IRQ_MB1_OC_MASK (0x1 << 15)
691#define RT5660_IRQ_MB1_OC_SFT 15
692#define RT5660_IRQ_MB1_OC_BP (0x0 << 15)
693#define RT5660_IRQ_MB1_OC_NOR (0x1 << 15)
694#define RT5660_IRQ_MB2_OC_MASK (0x1 << 14)
695#define RT5660_IRQ_MB2_OC_SFT 14
696#define RT5660_IRQ_MB2_OC_BP (0x0 << 14)
697#define RT5660_IRQ_MB2_OC_NOR (0x1 << 14)
698#define RT5660_MB1_OC_STKY_MASK (0x1 << 11)
699#define RT5660_MB1_OC_STKY_SFT 11
700#define RT5660_MB1_OC_STKY_DIS (0x0 << 11)
701#define RT5660_MB1_OC_STKY_EN (0x1 << 11)
702#define RT5660_MB2_OC_STKY_MASK (0x1 << 10)
703#define RT5660_MB2_OC_STKY_SFT 10
704#define RT5660_MB2_OC_STKY_DIS (0x0 << 10)
705#define RT5660_MB2_OC_STKY_EN (0x1 << 10)
706#define RT5660_MB1_OC_P_MASK (0x1 << 7)
707#define RT5660_MB1_OC_P_SFT 7
708#define RT5660_MB1_OC_P_NOR (0x0 << 7)
709#define RT5660_MB1_OC_P_INV (0x1 << 7)
710#define RT5660_MB2_OC_P_MASK (0x1 << 6)
711#define RT5660_MB2_OC_P_SFT 6
712#define RT5660_MB2_OC_P_NOR (0x0 << 6)
713#define RT5660_MB2_OC_P_INV (0x1 << 6)
714#define RT5660_MB1_OC_CLR (0x1 << 3)
715#define RT5660_MB1_OC_CLR_SFT 3
716#define RT5660_MB2_OC_CLR (0x1 << 2)
717#define RT5660_MB2_OC_CLR_SFT 2
718
719/* GPIO Control 1 (0xc0) */
720#define RT5660_GP2_PIN_MASK (0x1 << 14)
721#define RT5660_GP2_PIN_SFT 14
722#define RT5660_GP2_PIN_GPIO2 (0x0 << 14)
723#define RT5660_GP2_PIN_DMIC1_SDA (0x1 << 14)
724#define RT5660_GP1_PIN_MASK (0x3 << 12)
725#define RT5660_GP1_PIN_SFT 12
726#define RT5660_GP1_PIN_GPIO1 (0x0 << 12)
727#define RT5660_GP1_PIN_DMIC1_SCL (0x1 << 12)
728#define RT5660_GP1_PIN_IRQ (0x2 << 12)
729#define RT5660_GPIO_M_MASK (0x1 << 9)
730#define RT5660_GPIO_M_SFT 9
731#define RT5660_GPIO_M_FLT (0x0 << 9)
732#define RT5660_GPIO_M_PH (0x1 << 9)
733
734/* GPIO Control 3 (0xc2) */
735#define RT5660_GP2_PF_MASK (0x1 << 5)
736#define RT5660_GP2_PF_SFT 5
737#define RT5660_GP2_PF_IN (0x0 << 5)
738#define RT5660_GP2_PF_OUT (0x1 << 5)
739#define RT5660_GP2_OUT_MASK (0x1 << 4)
740#define RT5660_GP2_OUT_SFT 4
741#define RT5660_GP2_OUT_LO (0x0 << 4)
742#define RT5660_GP2_OUT_HI (0x1 << 4)
743#define RT5660_GP2_P_MASK (0x1 << 3)
744#define RT5660_GP2_P_SFT 3
745#define RT5660_GP2_P_NOR (0x0 << 3)
746#define RT5660_GP2_P_INV (0x1 << 3)
747#define RT5660_GP1_PF_MASK (0x1 << 2)
748#define RT5660_GP1_PF_SFT 2
749#define RT5660_GP1_PF_IN (0x0 << 2)
750#define RT5660_GP1_PF_OUT (0x1 << 2)
751#define RT5660_GP1_OUT_MASK (0x1 << 1)
752#define RT5660_GP1_OUT_SFT 1
753#define RT5660_GP1_OUT_LO (0x0 << 1)
754#define RT5660_GP1_OUT_HI (0x1 << 1)
755#define RT5660_GP1_P_MASK (0x1)
756#define RT5660_GP1_P_SFT 0
757#define RT5660_GP1_P_NOR (0x0)
758#define RT5660_GP1_P_INV (0x1)
759
760/* Soft volume and zero cross control 1 (0xd9) */
761#define RT5660_SV_MASK (0x1 << 15)
762#define RT5660_SV_SFT 15
763#define RT5660_SV_DIS (0x0 << 15)
764#define RT5660_SV_EN (0x1 << 15)
765#define RT5660_SPO_SV_MASK (0x1 << 14)
766#define RT5660_SPO_SV_SFT 14
767#define RT5660_SPO_SV_DIS (0x0 << 14)
768#define RT5660_SPO_SV_EN (0x1 << 14)
769#define RT5660_OUT_SV_MASK (0x1 << 12)
770#define RT5660_OUT_SV_SFT 12
771#define RT5660_OUT_SV_DIS (0x0 << 12)
772#define RT5660_OUT_SV_EN (0x1 << 12)
773#define RT5660_ZCD_DIG_MASK (0x1 << 11)
774#define RT5660_ZCD_DIG_SFT 11
775#define RT5660_ZCD_DIG_DIS (0x0 << 11)
776#define RT5660_ZCD_DIG_EN (0x1 << 11)
777#define RT5660_ZCD_MASK (0x1 << 10)
778#define RT5660_ZCD_SFT 10
779#define RT5660_ZCD_PD (0x0 << 10)
780#define RT5660_ZCD_PU (0x1 << 10)
781#define RT5660_SV_DLY_MASK (0xf)
782#define RT5660_SV_DLY_SFT 0
783
784/* Soft volume and zero cross control 2 (0xda) */
785#define RT5660_ZCD_SPO_MASK (0x1 << 15)
786#define RT5660_ZCD_SPO_SFT 15
787#define RT5660_ZCD_SPO_DIS (0x0 << 15)
788#define RT5660_ZCD_SPO_EN (0x1 << 15)
789#define RT5660_ZCD_OMR_MASK (0x1 << 8)
790#define RT5660_ZCD_OMR_SFT 8
791#define RT5660_ZCD_OMR_DIS (0x0 << 8)
792#define RT5660_ZCD_OMR_EN (0x1 << 8)
793#define RT5660_ZCD_OML_MASK (0x1 << 7)
794#define RT5660_ZCD_OML_SFT 7
795#define RT5660_ZCD_OML_DIS (0x0 << 7)
796#define RT5660_ZCD_OML_EN (0x1 << 7)
797#define RT5660_ZCD_SPM_MASK (0x1 << 6)
798#define RT5660_ZCD_SPM_SFT 6
799#define RT5660_ZCD_SPM_DIS (0x0 << 6)
800#define RT5660_ZCD_SPM_EN (0x1 << 6)
801#define RT5660_ZCD_RMR_MASK (0x1 << 5)
802#define RT5660_ZCD_RMR_SFT 5
803#define RT5660_ZCD_RMR_DIS (0x0 << 5)
804#define RT5660_ZCD_RMR_EN (0x1 << 5)
805#define RT5660_ZCD_RML_MASK (0x1 << 4)
806#define RT5660_ZCD_RML_SFT 4
807#define RT5660_ZCD_RML_DIS (0x0 << 4)
808#define RT5660_ZCD_RML_EN (0x1 << 4)
809
810/* General Control 1 (0xfa) */
811#define RT5660_PWR_VREF_HP (0x1 << 11)
812#define RT5660_PWR_VREF_HP_SFT 11
813#define RT5660_DIG_GATE_CTRL (0x1)
814#define RT5660_DIG_GATE_CTRL_SFT 0
815
816/* System Clock Source */
817#define RT5660_SCLK_S_MCLK 0
818#define RT5660_SCLK_S_PLL1 1
819#define RT5660_SCLK_S_RCCLK 2
820
821/* PLL1 Source */
822#define RT5660_PLL1_S_MCLK 0
823#define RT5660_PLL1_S_BCLK 1
824
825enum {
826 RT5660_AIF1,
827 RT5660_AIFS,
828};
829
830struct rt5660_priv {
831 struct snd_soc_codec *codec;
832 struct rt5660_platform_data pdata;
833 struct regmap *regmap;
834 struct clk *mclk;
835
836 int sysclk;
837 int sysclk_src;
838 int lrck[RT5660_AIFS];
839 int bclk[RT5660_AIFS];
840 int master[RT5660_AIFS];
841
842 int pll_src;
843 int pll_in;
844 int pll_out;
845};
846
847#endif
diff --git a/sound/soc/codecs/rt5663.c b/sound/soc/codecs/rt5663.c
new file mode 100644
index 000000000000..01a18d88f1eb
--- /dev/null
+++ b/sound/soc/codecs/rt5663.c
@@ -0,0 +1,3218 @@
1/*
2 * rt5663.c -- RT5668/RT5663 ALSA SoC audio codec driver
3 *
4 * Copyright 2016 Realtek Semiconductor Corp.
5 * Author: Jack Yu <jack.yu@realtek.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11#include <linux/module.h>
12#include <linux/moduleparam.h>
13#include <linux/init.h>
14#include <linux/delay.h>
15#include <linux/pm.h>
16#include <linux/i2c.h>
17#include <linux/platform_device.h>
18#include <linux/spi/spi.h>
19#include <linux/acpi.h>
20#include <linux/workqueue.h>
21#include <sound/core.h>
22#include <sound/pcm.h>
23#include <sound/pcm_params.h>
24#include <sound/jack.h>
25#include <sound/soc.h>
26#include <sound/soc-dapm.h>
27#include <sound/initval.h>
28#include <sound/tlv.h>
29
30#include "rt5663.h"
31#include "rl6231.h"
32
33#define RT5668_DEVICE_ID 0x6451
34#define RT5663_DEVICE_ID 0x6406
35
36enum {
37 CODEC_TYPE_RT5668,
38 CODEC_TYPE_RT5663,
39};
40
41struct rt5663_priv {
42 struct snd_soc_codec *codec;
43 struct regmap *regmap;
44 struct delayed_work jack_detect_work;
45 struct snd_soc_jack *hs_jack;
46 struct timer_list btn_check_timer;
47
48 int codec_type;
49 int sysclk;
50 int sysclk_src;
51 int lrck;
52
53 int pll_src;
54 int pll_in;
55 int pll_out;
56
57 int jack_type;
58};
59
60static const struct reg_default rt5668_reg[] = {
61 { 0x0000, 0x0000 },
62 { 0x0001, 0xc8c8 },
63 { 0x0002, 0x8080 },
64 { 0x0003, 0x8000 },
65 { 0x0004, 0xc80a },
66 { 0x0005, 0x0000 },
67 { 0x0006, 0x0000 },
68 { 0x0007, 0x0000 },
69 { 0x000a, 0x0000 },
70 { 0x000b, 0x0000 },
71 { 0x000c, 0x0000 },
72 { 0x000d, 0x0000 },
73 { 0x000f, 0x0808 },
74 { 0x0010, 0x4000 },
75 { 0x0011, 0x0000 },
76 { 0x0012, 0x1404 },
77 { 0x0013, 0x1000 },
78 { 0x0014, 0xa00a },
79 { 0x0015, 0x0404 },
80 { 0x0016, 0x0404 },
81 { 0x0017, 0x0011 },
82 { 0x0018, 0xafaf },
83 { 0x0019, 0xafaf },
84 { 0x001a, 0xafaf },
85 { 0x001b, 0x0011 },
86 { 0x001c, 0x2f2f },
87 { 0x001d, 0x2f2f },
88 { 0x001e, 0x2f2f },
89 { 0x001f, 0x0000 },
90 { 0x0020, 0x0000 },
91 { 0x0021, 0x0000 },
92 { 0x0022, 0x5757 },
93 { 0x0023, 0x0039 },
94 { 0x0024, 0x000b },
95 { 0x0026, 0xc0c0 },
96 { 0x0027, 0xc0c0 },
97 { 0x0028, 0xc0c0 },
98 { 0x0029, 0x8080 },
99 { 0x002a, 0xaaaa },
100 { 0x002b, 0xaaaa },
101 { 0x002c, 0xaba8 },
102 { 0x002d, 0x0000 },
103 { 0x002e, 0x0000 },
104 { 0x002f, 0x0000 },
105 { 0x0030, 0x0000 },
106 { 0x0031, 0x5000 },
107 { 0x0032, 0x0000 },
108 { 0x0033, 0x0000 },
109 { 0x0034, 0x0000 },
110 { 0x0035, 0x0000 },
111 { 0x003a, 0x0000 },
112 { 0x003b, 0x0000 },
113 { 0x003c, 0x00ff },
114 { 0x003d, 0x0000 },
115 { 0x003e, 0x00ff },
116 { 0x003f, 0x0000 },
117 { 0x0040, 0x0000 },
118 { 0x0041, 0x00ff },
119 { 0x0042, 0x0000 },
120 { 0x0043, 0x00ff },
121 { 0x0044, 0x0c0c },
122 { 0x0049, 0xc00b },
123 { 0x004a, 0x0000 },
124 { 0x004b, 0x031f },
125 { 0x004d, 0x0000 },
126 { 0x004e, 0x001f },
127 { 0x004f, 0x0000 },
128 { 0x0050, 0x001f },
129 { 0x0052, 0xf000 },
130 { 0x0061, 0x0000 },
131 { 0x0062, 0x0000 },
132 { 0x0063, 0x003e },
133 { 0x0064, 0x0000 },
134 { 0x0065, 0x0000 },
135 { 0x0066, 0x003f },
136 { 0x0067, 0x0000 },
137 { 0x006b, 0x0000 },
138 { 0x006d, 0xff00 },
139 { 0x006e, 0x2808 },
140 { 0x006f, 0x000a },
141 { 0x0070, 0x8000 },
142 { 0x0071, 0x8000 },
143 { 0x0072, 0x8000 },
144 { 0x0073, 0x7000 },
145 { 0x0074, 0x7770 },
146 { 0x0075, 0x0002 },
147 { 0x0076, 0x0001 },
148 { 0x0078, 0x00f0 },
149 { 0x0079, 0x0000 },
150 { 0x007a, 0x0000 },
151 { 0x007b, 0x0000 },
152 { 0x007c, 0x0000 },
153 { 0x007d, 0x0123 },
154 { 0x007e, 0x4500 },
155 { 0x007f, 0x8003 },
156 { 0x0080, 0x0000 },
157 { 0x0081, 0x0000 },
158 { 0x0082, 0x0000 },
159 { 0x0083, 0x0000 },
160 { 0x0084, 0x0000 },
161 { 0x0085, 0x0000 },
162 { 0x0086, 0x0008 },
163 { 0x0087, 0x0000 },
164 { 0x0088, 0x0000 },
165 { 0x0089, 0x0000 },
166 { 0x008a, 0x0000 },
167 { 0x008b, 0x0000 },
168 { 0x008c, 0x0003 },
169 { 0x008e, 0x0060 },
170 { 0x008f, 0x1000 },
171 { 0x0091, 0x0c26 },
172 { 0x0092, 0x0073 },
173 { 0x0093, 0x0000 },
174 { 0x0094, 0x0080 },
175 { 0x0098, 0x0000 },
176 { 0x0099, 0x0000 },
177 { 0x009a, 0x0007 },
178 { 0x009f, 0x0000 },
179 { 0x00a0, 0x0000 },
180 { 0x00a1, 0x0002 },
181 { 0x00a2, 0x0001 },
182 { 0x00a3, 0x0002 },
183 { 0x00a4, 0x0001 },
184 { 0x00ae, 0x2040 },
185 { 0x00af, 0x0000 },
186 { 0x00b6, 0x0000 },
187 { 0x00b7, 0x0000 },
188 { 0x00b8, 0x0000 },
189 { 0x00b9, 0x0000 },
190 { 0x00ba, 0x0002 },
191 { 0x00bb, 0x0000 },
192 { 0x00be, 0x0000 },
193 { 0x00c0, 0x0000 },
194 { 0x00c1, 0x0aaa },
195 { 0x00c2, 0xaa80 },
196 { 0x00c3, 0x0003 },
197 { 0x00c4, 0x0000 },
198 { 0x00d0, 0x0000 },
199 { 0x00d1, 0x2244 },
200 { 0x00d2, 0x0000 },
201 { 0x00d3, 0x3300 },
202 { 0x00d4, 0x2200 },
203 { 0x00d9, 0x0809 },
204 { 0x00da, 0x0000 },
205 { 0x00db, 0x0008 },
206 { 0x00dc, 0x00c0 },
207 { 0x00dd, 0x6724 },
208 { 0x00de, 0x3131 },
209 { 0x00df, 0x0008 },
210 { 0x00e0, 0x4000 },
211 { 0x00e1, 0x3131 },
212 { 0x00e2, 0x600c },
213 { 0x00ea, 0xb320 },
214 { 0x00eb, 0x0000 },
215 { 0x00ec, 0xb300 },
216 { 0x00ed, 0x0000 },
217 { 0x00ee, 0xb320 },
218 { 0x00ef, 0x0000 },
219 { 0x00f0, 0x0201 },
220 { 0x00f1, 0x0ddd },
221 { 0x00f2, 0x0ddd },
222 { 0x00f6, 0x0000 },
223 { 0x00f7, 0x0000 },
224 { 0x00f8, 0x0000 },
225 { 0x00fa, 0x0000 },
226 { 0x00fb, 0x0000 },
227 { 0x00fc, 0x0000 },
228 { 0x00fd, 0x0000 },
229 { 0x00fe, 0x10ec },
230 { 0x00ff, 0x6451 },
231 { 0x0100, 0xaaaa },
232 { 0x0101, 0x000a },
233 { 0x010a, 0xaaaa },
234 { 0x010b, 0xa0a0 },
235 { 0x010c, 0xaeae },
236 { 0x010d, 0xaaaa },
237 { 0x010e, 0xaaaa },
238 { 0x010f, 0xaaaa },
239 { 0x0110, 0xe002 },
240 { 0x0111, 0xa602 },
241 { 0x0112, 0xaaaa },
242 { 0x0113, 0x2000 },
243 { 0x0117, 0x0f00 },
244 { 0x0125, 0x0420 },
245 { 0x0132, 0x0000 },
246 { 0x0133, 0x0000 },
247 { 0x0136, 0x5555 },
248 { 0x0137, 0x5540 },
249 { 0x0138, 0x3700 },
250 { 0x0139, 0x79a1 },
251 { 0x013a, 0x2020 },
252 { 0x013b, 0x2020 },
253 { 0x013c, 0x2005 },
254 { 0x013f, 0x0000 },
255 { 0x0145, 0x0002 },
256 { 0x0146, 0x0000 },
257 { 0x0147, 0x0000 },
258 { 0x0148, 0x0000 },
259 { 0x0160, 0x4ec0 },
260 { 0x0161, 0x0080 },
261 { 0x0162, 0x0200 },
262 { 0x0163, 0x0800 },
263 { 0x0164, 0x0000 },
264 { 0x0165, 0x0000 },
265 { 0x0166, 0x0000 },
266 { 0x0167, 0x000f },
267 { 0x0168, 0x000f },
268 { 0x0170, 0x4e80 },
269 { 0x0171, 0x0080 },
270 { 0x0172, 0x0200 },
271 { 0x0173, 0x0800 },
272 { 0x0174, 0x00ff },
273 { 0x0175, 0x0000 },
274 { 0x0190, 0x4131 },
275 { 0x0191, 0x4131 },
276 { 0x0192, 0x4131 },
277 { 0x0193, 0x4131 },
278 { 0x0194, 0x0000 },
279 { 0x0195, 0x0000 },
280 { 0x0196, 0x0000 },
281 { 0x0197, 0x0000 },
282 { 0x0198, 0x0000 },
283 { 0x0199, 0x0000 },
284 { 0x01a0, 0x1e64 },
285 { 0x01a1, 0x06a3 },
286 { 0x01a2, 0x0000 },
287 { 0x01a3, 0x0000 },
288 { 0x01a4, 0x0000 },
289 { 0x01a5, 0x0000 },
290 { 0x01a6, 0x0000 },
291 { 0x01a7, 0x0000 },
292 { 0x01a8, 0x0000 },
293 { 0x01a9, 0x0000 },
294 { 0x01aa, 0x0000 },
295 { 0x01ab, 0x0000 },
296 { 0x01b5, 0x0000 },
297 { 0x01b6, 0x01c3 },
298 { 0x01b7, 0x02a0 },
299 { 0x01b8, 0x03e9 },
300 { 0x01b9, 0x1389 },
301 { 0x01ba, 0xc351 },
302 { 0x01bb, 0x0009 },
303 { 0x01bc, 0x0018 },
304 { 0x01bd, 0x002a },
305 { 0x01be, 0x004c },
306 { 0x01bf, 0x0097 },
307 { 0x01c0, 0x433d },
308 { 0x01c1, 0x0000 },
309 { 0x01c2, 0x0000 },
310 { 0x01c3, 0x0000 },
311 { 0x01c4, 0x0000 },
312 { 0x01c5, 0x0000 },
313 { 0x01c6, 0x0000 },
314 { 0x01c7, 0x0000 },
315 { 0x01c8, 0x40af },
316 { 0x01c9, 0x0702 },
317 { 0x01ca, 0x0000 },
318 { 0x01cb, 0x0000 },
319 { 0x01cc, 0x5757 },
320 { 0x01cd, 0x5757 },
321 { 0x01ce, 0x5757 },
322 { 0x01cf, 0x5757 },
323 { 0x01d0, 0x5757 },
324 { 0x01d1, 0x5757 },
325 { 0x01d2, 0x5757 },
326 { 0x01d3, 0x5757 },
327 { 0x01d4, 0x5757 },
328 { 0x01d5, 0x5757 },
329 { 0x01d6, 0x003c },
330 { 0x01da, 0x0000 },
331 { 0x01db, 0x0000 },
332 { 0x01dc, 0x0000 },
333 { 0x01de, 0x7c00 },
334 { 0x01df, 0x0320 },
335 { 0x01e0, 0x06a1 },
336 { 0x01e1, 0x0000 },
337 { 0x01e2, 0x0000 },
338 { 0x01e3, 0x0000 },
339 { 0x01e4, 0x0000 },
340 { 0x01e5, 0x0000 },
341 { 0x01e6, 0x0001 },
342 { 0x01e7, 0x0000 },
343 { 0x01e8, 0x0000 },
344 { 0x01ea, 0x0000 },
345 { 0x01eb, 0x0000 },
346 { 0x01ec, 0x0000 },
347 { 0x01ed, 0x0000 },
348 { 0x01ee, 0x0000 },
349 { 0x01ef, 0x0000 },
350 { 0x01f0, 0x0000 },
351 { 0x01f1, 0x0000 },
352 { 0x01f2, 0x0000 },
353 { 0x01f3, 0x0000 },
354 { 0x01f4, 0x0000 },
355 { 0x0200, 0x0000 },
356 { 0x0201, 0x0000 },
357 { 0x0202, 0x0000 },
358 { 0x0203, 0x0000 },
359 { 0x0204, 0x0000 },
360 { 0x0205, 0x0000 },
361 { 0x0206, 0x0000 },
362 { 0x0207, 0x0000 },
363 { 0x0208, 0x0000 },
364 { 0x0210, 0x60b1 },
365 { 0x0211, 0xa000 },
366 { 0x0212, 0x024c },
367 { 0x0213, 0xf7ff },
368 { 0x0214, 0x024c },
369 { 0x0215, 0x0102 },
370 { 0x0216, 0x00a3 },
371 { 0x0217, 0x0048 },
372 { 0x0218, 0x92c0 },
373 { 0x0219, 0x0000 },
374 { 0x021a, 0x00c8 },
375 { 0x021b, 0x0020 },
376 { 0x02fa, 0x0000 },
377 { 0x02fb, 0x0000 },
378 { 0x02fc, 0x0000 },
379 { 0x02ff, 0x0110 },
380 { 0x0300, 0x001f },
381 { 0x0301, 0x032c },
382 { 0x0302, 0x5f21 },
383 { 0x0303, 0x4000 },
384 { 0x0304, 0x4000 },
385 { 0x0305, 0x06d5 },
386 { 0x0306, 0x8000 },
387 { 0x0307, 0x0700 },
388 { 0x0310, 0x4560 },
389 { 0x0311, 0xa4a8 },
390 { 0x0312, 0x7418 },
391 { 0x0313, 0x0000 },
392 { 0x0314, 0x0006 },
393 { 0x0315, 0xffff },
394 { 0x0316, 0xc400 },
395 { 0x0317, 0x0000 },
396 { 0x0330, 0x00a6 },
397 { 0x0331, 0x04c3 },
398 { 0x0332, 0x27c8 },
399 { 0x0333, 0xbf50 },
400 { 0x0334, 0x0045 },
401 { 0x0335, 0x0007 },
402 { 0x0336, 0x7418 },
403 { 0x0337, 0x0501 },
404 { 0x0338, 0x0000 },
405 { 0x0339, 0x0010 },
406 { 0x033a, 0x1010 },
407 { 0x03c0, 0x7e00 },
408 { 0x03c1, 0x8000 },
409 { 0x03c2, 0x8000 },
410 { 0x03c3, 0x8000 },
411 { 0x03c4, 0x8000 },
412 { 0x03c5, 0x8000 },
413 { 0x03c6, 0x8000 },
414 { 0x03c7, 0x8000 },
415 { 0x03c8, 0x8000 },
416 { 0x03c9, 0x8000 },
417 { 0x03ca, 0x8000 },
418 { 0x03cb, 0x8000 },
419 { 0x03cc, 0x8000 },
420 { 0x03d0, 0x0000 },
421 { 0x03d1, 0x0000 },
422 { 0x03d2, 0x0000 },
423 { 0x03d3, 0x0000 },
424 { 0x03d4, 0x2000 },
425 { 0x03d5, 0x2000 },
426 { 0x03d6, 0x0000 },
427 { 0x03d7, 0x0000 },
428 { 0x03d8, 0x2000 },
429 { 0x03d9, 0x2000 },
430 { 0x03da, 0x2000 },
431 { 0x03db, 0x2000 },
432 { 0x03dc, 0x0000 },
433 { 0x03dd, 0x0000 },
434 { 0x03de, 0x0000 },
435 { 0x03df, 0x2000 },
436 { 0x03e0, 0x0000 },
437 { 0x03e1, 0x0000 },
438 { 0x03e2, 0x0000 },
439 { 0x03e3, 0x0000 },
440 { 0x03e4, 0x0000 },
441 { 0x03e5, 0x0000 },
442 { 0x03e6, 0x0000 },
443 { 0x03e7, 0x0000 },
444 { 0x03e8, 0x0000 },
445 { 0x03e9, 0x0000 },
446 { 0x03ea, 0x0000 },
447 { 0x03eb, 0x0000 },
448 { 0x03ec, 0x0000 },
449 { 0x03ed, 0x0000 },
450 { 0x03ee, 0x0000 },
451 { 0x03ef, 0x0000 },
452 { 0x03f0, 0x0800 },
453 { 0x03f1, 0x0800 },
454 { 0x03f2, 0x0800 },
455 { 0x03f3, 0x0800 },
456 { 0x03fe, 0x0000 },
457 { 0x03ff, 0x0000 },
458 { 0x07f0, 0x0000 },
459 { 0x07fa, 0x0000 },
460};
461
462static const struct reg_default rt5663_reg[] = {
463 { 0x0000, 0x0000 },
464 { 0x0002, 0x0008 },
465 { 0x0005, 0x1000 },
466 { 0x0006, 0x1000 },
467 { 0x000a, 0x0000 },
468 { 0x0010, 0x000f },
469 { 0x0015, 0x42c1 },
470 { 0x0016, 0x0000 },
471 { 0x0018, 0x000b },
472 { 0x0019, 0xafaf },
473 { 0x001c, 0x2f2f },
474 { 0x001f, 0x0000 },
475 { 0x0022, 0x5757 },
476 { 0x0023, 0x0039 },
477 { 0x0026, 0xc0c0 },
478 { 0x0029, 0x8080 },
479 { 0x002a, 0xa0a0 },
480 { 0x002c, 0x000c },
481 { 0x002d, 0x0000 },
482 { 0x0040, 0x0808 },
483 { 0x0061, 0x0000 },
484 { 0x0062, 0x0000 },
485 { 0x0063, 0x003e },
486 { 0x0064, 0x0000 },
487 { 0x0065, 0x0000 },
488 { 0x0066, 0x0000 },
489 { 0x006b, 0x0000 },
490 { 0x006e, 0x0000 },
491 { 0x006f, 0x0000 },
492 { 0x0070, 0x8020 },
493 { 0x0073, 0x1000 },
494 { 0x0074, 0xe400 },
495 { 0x0075, 0x0002 },
496 { 0x0076, 0x0001 },
497 { 0x0077, 0x00f0 },
498 { 0x0078, 0x0000 },
499 { 0x0079, 0x0000 },
500 { 0x007a, 0x0123 },
501 { 0x007b, 0x8003 },
502 { 0x0080, 0x0000 },
503 { 0x0081, 0x0000 },
504 { 0x0082, 0x0000 },
505 { 0x0083, 0x0000 },
506 { 0x0084, 0x0000 },
507 { 0x0086, 0x0008 },
508 { 0x0087, 0x0000 },
509 { 0x008a, 0x0000 },
510 { 0x008b, 0x0000 },
511 { 0x008c, 0x0003 },
512 { 0x008e, 0x0004 },
513 { 0x008f, 0x1000 },
514 { 0x0090, 0x0646 },
515 { 0x0091, 0x0e3e },
516 { 0x0092, 0x1071 },
517 { 0x0093, 0x0000 },
518 { 0x0094, 0x0080 },
519 { 0x0097, 0x0000 },
520 { 0x0098, 0x0000 },
521 { 0x009a, 0x0000 },
522 { 0x009f, 0x0000 },
523 { 0x00ae, 0x2000 },
524 { 0x00af, 0x0000 },
525 { 0x00b6, 0x0000 },
526 { 0x00b7, 0x0000 },
527 { 0x00b8, 0x0000 },
528 { 0x00ba, 0x0000 },
529 { 0x00bb, 0x0000 },
530 { 0x00be, 0x0000 },
531 { 0x00bf, 0x0000 },
532 { 0x00c0, 0x0000 },
533 { 0x00c1, 0x0000 },
534 { 0x00c5, 0x0000 },
535 { 0x00cb, 0xa02f },
536 { 0x00cc, 0x0000 },
537 { 0x00cd, 0x0e02 },
538 { 0x00d9, 0x08f9 },
539 { 0x00db, 0x0008 },
540 { 0x00dc, 0x00c0 },
541 { 0x00dd, 0x6724 },
542 { 0x00de, 0x3131 },
543 { 0x00df, 0x0008 },
544 { 0x00e0, 0x4000 },
545 { 0x00e1, 0x3131 },
546 { 0x00e2, 0x0043 },
547 { 0x00e4, 0x400b },
548 { 0x00e5, 0x8031 },
549 { 0x00e6, 0x3080 },
550 { 0x00e7, 0x4100 },
551 { 0x00e8, 0x1400 },
552 { 0x00e9, 0xe00a },
553 { 0x00ea, 0x0404 },
554 { 0x00eb, 0x0404 },
555 { 0x00ec, 0xb320 },
556 { 0x00ed, 0x0000 },
557 { 0x00f4, 0x0000 },
558 { 0x00f6, 0x0000 },
559 { 0x00f8, 0x0000 },
560 { 0x00fa, 0x8000 },
561 { 0x00fd, 0x0001 },
562 { 0x00fe, 0x10ec },
563 { 0x00ff, 0x6406 },
564 { 0x0100, 0xa0a0 },
565 { 0x0108, 0x4444 },
566 { 0x0109, 0x4444 },
567 { 0x010a, 0xaaaa },
568 { 0x010b, 0x00a0 },
569 { 0x010c, 0x8aaa },
570 { 0x010d, 0xaaaa },
571 { 0x010e, 0x2aaa },
572 { 0x010f, 0x002a },
573 { 0x0110, 0xa0a4 },
574 { 0x0111, 0x4602 },
575 { 0x0112, 0x0101 },
576 { 0x0113, 0x2000 },
577 { 0x0114, 0x0000 },
578 { 0x0116, 0x0000 },
579 { 0x0117, 0x0f00 },
580 { 0x0118, 0x0006 },
581 { 0x0125, 0x2224 },
582 { 0x0126, 0x5550 },
583 { 0x0127, 0x0400 },
584 { 0x0128, 0x7711 },
585 { 0x0132, 0x0004 },
586 { 0x0137, 0x5441 },
587 { 0x0139, 0x79a1 },
588 { 0x013a, 0x30c0 },
589 { 0x013b, 0x2000 },
590 { 0x013c, 0x2005 },
591 { 0x013d, 0x30c0 },
592 { 0x013e, 0x0000 },
593 { 0x0140, 0x3700 },
594 { 0x0141, 0x1f00 },
595 { 0x0144, 0x0000 },
596 { 0x0145, 0x0002 },
597 { 0x0146, 0x0000 },
598 { 0x0160, 0x0e80 },
599 { 0x0161, 0x0020 },
600 { 0x0162, 0x0080 },
601 { 0x0163, 0x0800 },
602 { 0x0164, 0x0000 },
603 { 0x0165, 0x0000 },
604 { 0x0166, 0x0000 },
605 { 0x0167, 0x1417 },
606 { 0x0168, 0x0017 },
607 { 0x0169, 0x0017 },
608 { 0x0180, 0x2000 },
609 { 0x0181, 0x0000 },
610 { 0x0182, 0x0000 },
611 { 0x0183, 0x2000 },
612 { 0x0184, 0x0000 },
613 { 0x0185, 0x0000 },
614 { 0x01b0, 0x4b30 },
615 { 0x01b1, 0x0000 },
616 { 0x01b2, 0xd870 },
617 { 0x01b3, 0x0000 },
618 { 0x01b4, 0x0030 },
619 { 0x01b5, 0x5757 },
620 { 0x01b6, 0x5757 },
621 { 0x01b7, 0x5757 },
622 { 0x01b8, 0x5757 },
623 { 0x01c0, 0x433d },
624 { 0x01c1, 0x0540 },
625 { 0x01c2, 0x0000 },
626 { 0x01c3, 0x0000 },
627 { 0x01c4, 0x0000 },
628 { 0x01c5, 0x0009 },
629 { 0x01c6, 0x0018 },
630 { 0x01c7, 0x002a },
631 { 0x01c8, 0x004c },
632 { 0x01c9, 0x0097 },
633 { 0x01ca, 0x01c3 },
634 { 0x01cb, 0x03e9 },
635 { 0x01cc, 0x1389 },
636 { 0x01cd, 0xc351 },
637 { 0x01ce, 0x0000 },
638 { 0x01cf, 0x0000 },
639 { 0x01d0, 0x0000 },
640 { 0x01d1, 0x0000 },
641 { 0x01d2, 0x0000 },
642 { 0x01d3, 0x003c },
643 { 0x01d4, 0x5757 },
644 { 0x01d5, 0x5757 },
645 { 0x01d6, 0x5757 },
646 { 0x01d7, 0x5757 },
647 { 0x01d8, 0x5757 },
648 { 0x01d9, 0x5757 },
649 { 0x01da, 0x0000 },
650 { 0x01db, 0x0000 },
651 { 0x01dd, 0x0009 },
652 { 0x01de, 0x7f00 },
653 { 0x01df, 0x00c8 },
654 { 0x01e0, 0x0691 },
655 { 0x01e1, 0x0000 },
656 { 0x01e2, 0x0000 },
657 { 0x01e3, 0x0000 },
658 { 0x01e4, 0x0000 },
659 { 0x01e5, 0x0040 },
660 { 0x01e6, 0x0000 },
661 { 0x01e7, 0x0000 },
662 { 0x01e8, 0x0000 },
663 { 0x01ea, 0x0000 },
664 { 0x01eb, 0x0000 },
665 { 0x01ec, 0x0000 },
666 { 0x01ed, 0x0000 },
667 { 0x01ee, 0x0000 },
668 { 0x01ef, 0x0000 },
669 { 0x01f0, 0x0000 },
670 { 0x01f1, 0x0000 },
671 { 0x01f2, 0x0000 },
672 { 0x0200, 0x0000 },
673 { 0x0201, 0x2244 },
674 { 0x0202, 0xaaaa },
675 { 0x0250, 0x8010 },
676 { 0x0251, 0x0000 },
677 { 0x0252, 0x028a },
678 { 0x02fa, 0x0000 },
679 { 0x02fb, 0x0000 },
680 { 0x02fc, 0x0000 },
681 { 0x0300, 0x0000 },
682 { 0x03d0, 0x0000 },
683 { 0x03d1, 0x0000 },
684 { 0x03d2, 0x0000 },
685 { 0x03d3, 0x0000 },
686 { 0x03d4, 0x2000 },
687 { 0x03d5, 0x2000 },
688 { 0x03d6, 0x0000 },
689 { 0x03d7, 0x0000 },
690 { 0x03d8, 0x2000 },
691 { 0x03d9, 0x2000 },
692 { 0x03da, 0x2000 },
693 { 0x03db, 0x2000 },
694 { 0x03dc, 0x0000 },
695 { 0x03dd, 0x0000 },
696 { 0x03de, 0x0000 },
697 { 0x03df, 0x2000 },
698 { 0x03e0, 0x0000 },
699 { 0x03e1, 0x0000 },
700 { 0x03e2, 0x0000 },
701 { 0x03e3, 0x0000 },
702 { 0x03e4, 0x0000 },
703 { 0x03e5, 0x0000 },
704 { 0x03e6, 0x0000 },
705 { 0x03e7, 0x0000 },
706 { 0x03e8, 0x0000 },
707 { 0x03e9, 0x0000 },
708 { 0x03ea, 0x0000 },
709 { 0x03eb, 0x0000 },
710 { 0x03ec, 0x0000 },
711 { 0x03ed, 0x0000 },
712 { 0x03ee, 0x0000 },
713 { 0x03ef, 0x0000 },
714 { 0x03f0, 0x0800 },
715 { 0x03f1, 0x0800 },
716 { 0x03f2, 0x0800 },
717 { 0x03f3, 0x0800 },
718};
719
720static bool rt5663_volatile_register(struct device *dev, unsigned int reg)
721{
722 switch (reg) {
723 case RT5663_RESET:
724 case RT5663_SIL_DET_CTL:
725 case RT5663_HP_IMP_GAIN_2:
726 case RT5663_AD_DA_MIXER:
727 case RT5663_FRAC_DIV_2:
728 case RT5663_MICBIAS_1:
729 case RT5663_ASRC_11_2:
730 case RT5663_ADC_EQ_1:
731 case RT5663_INT_ST_1:
732 case RT5663_INT_ST_2:
733 case RT5663_GPIO_STA:
734 case RT5663_SIN_GEN_1:
735 case RT5663_IL_CMD_1:
736 case RT5663_IL_CMD_5:
737 case RT5663_IL_CMD_PWRSAV1:
738 case RT5663_EM_JACK_TYPE_1:
739 case RT5663_EM_JACK_TYPE_2:
740 case RT5663_EM_JACK_TYPE_3:
741 case RT5663_JD_CTRL2:
742 case RT5663_VENDOR_ID:
743 case RT5663_VENDOR_ID_1:
744 case RT5663_VENDOR_ID_2:
745 case RT5663_PLL_INT_REG:
746 case RT5663_SOFT_RAMP:
747 case RT5663_STO_DRE_1:
748 case RT5663_STO_DRE_5:
749 case RT5663_STO_DRE_6:
750 case RT5663_STO_DRE_7:
751 case RT5663_MIC_DECRO_1:
752 case RT5663_MIC_DECRO_4:
753 case RT5663_HP_IMP_SEN_1:
754 case RT5663_HP_IMP_SEN_3:
755 case RT5663_HP_IMP_SEN_4:
756 case RT5663_HP_IMP_SEN_5:
757 case RT5663_HP_CALIB_1_1:
758 case RT5663_HP_CALIB_9:
759 case RT5663_HP_CALIB_ST1:
760 case RT5663_HP_CALIB_ST2:
761 case RT5663_HP_CALIB_ST3:
762 case RT5663_HP_CALIB_ST4:
763 case RT5663_HP_CALIB_ST5:
764 case RT5663_HP_CALIB_ST6:
765 case RT5663_HP_CALIB_ST7:
766 case RT5663_HP_CALIB_ST8:
767 case RT5663_HP_CALIB_ST9:
768 case RT5663_ANA_JD:
769 return true;
770 default:
771 return false;
772 }
773}
774
775static bool rt5663_readable_register(struct device *dev, unsigned int reg)
776{
777 switch (reg) {
778 case RT5663_RESET:
779 case RT5663_HP_OUT_EN:
780 case RT5663_HP_LCH_DRE:
781 case RT5663_HP_RCH_DRE:
782 case RT5663_CALIB_BST:
783 case RT5663_RECMIX:
784 case RT5663_SIL_DET_CTL:
785 case RT5663_PWR_SAV_SILDET:
786 case RT5663_SIDETONE_CTL:
787 case RT5663_STO1_DAC_DIG_VOL:
788 case RT5663_STO1_ADC_DIG_VOL:
789 case RT5663_STO1_BOOST:
790 case RT5663_HP_IMP_GAIN_1:
791 case RT5663_HP_IMP_GAIN_2:
792 case RT5663_STO1_ADC_MIXER:
793 case RT5663_AD_DA_MIXER:
794 case RT5663_STO_DAC_MIXER:
795 case RT5663_DIG_SIDE_MIXER:
796 case RT5663_BYPASS_STO_DAC:
797 case RT5663_CALIB_REC_MIX:
798 case RT5663_PWR_DIG_1:
799 case RT5663_PWR_DIG_2:
800 case RT5663_PWR_ANLG_1:
801 case RT5663_PWR_ANLG_2:
802 case RT5663_PWR_ANLG_3:
803 case RT5663_PWR_MIXER:
804 case RT5663_SIG_CLK_DET:
805 case RT5663_PRE_DIV_GATING_1:
806 case RT5663_PRE_DIV_GATING_2:
807 case RT5663_I2S1_SDP:
808 case RT5663_ADDA_CLK_1:
809 case RT5663_ADDA_RST:
810 case RT5663_FRAC_DIV_1:
811 case RT5663_FRAC_DIV_2:
812 case RT5663_TDM_1:
813 case RT5663_TDM_2:
814 case RT5663_TDM_3:
815 case RT5663_TDM_4:
816 case RT5663_TDM_5:
817 case RT5663_GLB_CLK:
818 case RT5663_PLL_1:
819 case RT5663_PLL_2:
820 case RT5663_ASRC_1:
821 case RT5663_ASRC_2:
822 case RT5663_ASRC_4:
823 case RT5663_DUMMY_REG:
824 case RT5663_ASRC_8:
825 case RT5663_ASRC_9:
826 case RT5663_ASRC_11:
827 case RT5663_DEPOP_1:
828 case RT5663_DEPOP_2:
829 case RT5663_DEPOP_3:
830 case RT5663_HP_CHARGE_PUMP_1:
831 case RT5663_HP_CHARGE_PUMP_2:
832 case RT5663_MICBIAS_1:
833 case RT5663_RC_CLK:
834 case RT5663_ASRC_11_2:
835 case RT5663_DUMMY_REG_2:
836 case RT5663_REC_PATH_GAIN:
837 case RT5663_AUTO_1MRC_CLK:
838 case RT5663_ADC_EQ_1:
839 case RT5663_ADC_EQ_2:
840 case RT5663_IRQ_1:
841 case RT5663_IRQ_2:
842 case RT5663_IRQ_3:
843 case RT5663_IRQ_4:
844 case RT5663_IRQ_5:
845 case RT5663_INT_ST_1:
846 case RT5663_INT_ST_2:
847 case RT5663_GPIO_1:
848 case RT5663_GPIO_2:
849 case RT5663_GPIO_STA:
850 case RT5663_SIN_GEN_1:
851 case RT5663_SIN_GEN_2:
852 case RT5663_SIN_GEN_3:
853 case RT5663_SOF_VOL_ZC1:
854 case RT5663_IL_CMD_1:
855 case RT5663_IL_CMD_2:
856 case RT5663_IL_CMD_3:
857 case RT5663_IL_CMD_4:
858 case RT5663_IL_CMD_5:
859 case RT5663_IL_CMD_6:
860 case RT5663_IL_CMD_7:
861 case RT5663_IL_CMD_8:
862 case RT5663_IL_CMD_PWRSAV1:
863 case RT5663_IL_CMD_PWRSAV2:
864 case RT5663_EM_JACK_TYPE_1:
865 case RT5663_EM_JACK_TYPE_2:
866 case RT5663_EM_JACK_TYPE_3:
867 case RT5663_EM_JACK_TYPE_4:
868 case RT5663_EM_JACK_TYPE_5:
869 case RT5663_EM_JACK_TYPE_6:
870 case RT5663_STO1_HPF_ADJ1:
871 case RT5663_STO1_HPF_ADJ2:
872 case RT5663_FAST_OFF_MICBIAS:
873 case RT5663_JD_CTRL1:
874 case RT5663_JD_CTRL2:
875 case RT5663_DIG_MISC:
876 case RT5663_VENDOR_ID:
877 case RT5663_VENDOR_ID_1:
878 case RT5663_VENDOR_ID_2:
879 case RT5663_DIG_VOL_ZCD:
880 case RT5663_ANA_BIAS_CUR_1:
881 case RT5663_ANA_BIAS_CUR_2:
882 case RT5663_ANA_BIAS_CUR_3:
883 case RT5663_ANA_BIAS_CUR_4:
884 case RT5663_ANA_BIAS_CUR_5:
885 case RT5663_ANA_BIAS_CUR_6:
886 case RT5663_BIAS_CUR_5:
887 case RT5663_BIAS_CUR_6:
888 case RT5663_BIAS_CUR_7:
889 case RT5663_BIAS_CUR_8:
890 case RT5663_DACREF_LDO:
891 case RT5663_DUMMY_REG_3:
892 case RT5663_BIAS_CUR_9:
893 case RT5663_DUMMY_REG_4:
894 case RT5663_VREFADJ_OP:
895 case RT5663_VREF_RECMIX:
896 case RT5663_CHARGE_PUMP_1:
897 case RT5663_CHARGE_PUMP_1_2:
898 case RT5663_CHARGE_PUMP_1_3:
899 case RT5663_CHARGE_PUMP_2:
900 case RT5663_DIG_IN_PIN1:
901 case RT5663_PAD_DRV_CTL:
902 case RT5663_PLL_INT_REG:
903 case RT5663_CHOP_DAC_L:
904 case RT5663_CHOP_ADC:
905 case RT5663_CALIB_ADC:
906 case RT5663_CHOP_DAC_R:
907 case RT5663_DUMMY_CTL_DACLR:
908 case RT5663_DUMMY_REG_5:
909 case RT5663_SOFT_RAMP:
910 case RT5663_TEST_MODE_1:
911 case RT5663_TEST_MODE_2:
912 case RT5663_TEST_MODE_3:
913 case RT5663_STO_DRE_1:
914 case RT5663_STO_DRE_2:
915 case RT5663_STO_DRE_3:
916 case RT5663_STO_DRE_4:
917 case RT5663_STO_DRE_5:
918 case RT5663_STO_DRE_6:
919 case RT5663_STO_DRE_7:
920 case RT5663_STO_DRE_8:
921 case RT5663_STO_DRE_9:
922 case RT5663_STO_DRE_10:
923 case RT5663_MIC_DECRO_1:
924 case RT5663_MIC_DECRO_2:
925 case RT5663_MIC_DECRO_3:
926 case RT5663_MIC_DECRO_4:
927 case RT5663_MIC_DECRO_5:
928 case RT5663_MIC_DECRO_6:
929 case RT5663_HP_DECRO_1:
930 case RT5663_HP_DECRO_2:
931 case RT5663_HP_DECRO_3:
932 case RT5663_HP_DECRO_4:
933 case RT5663_HP_DECOUP:
934 case RT5663_HP_IMP_SEN_MAP8:
935 case RT5663_HP_IMP_SEN_MAP9:
936 case RT5663_HP_IMP_SEN_MAP10:
937 case RT5663_HP_IMP_SEN_MAP11:
938 case RT5663_HP_IMP_SEN_1:
939 case RT5663_HP_IMP_SEN_2:
940 case RT5663_HP_IMP_SEN_3:
941 case RT5663_HP_IMP_SEN_4:
942 case RT5663_HP_IMP_SEN_5:
943 case RT5663_HP_IMP_SEN_6:
944 case RT5663_HP_IMP_SEN_7:
945 case RT5663_HP_IMP_SEN_8:
946 case RT5663_HP_IMP_SEN_9:
947 case RT5663_HP_IMP_SEN_10:
948 case RT5663_HP_IMP_SEN_11:
949 case RT5663_HP_IMP_SEN_12:
950 case RT5663_HP_IMP_SEN_13:
951 case RT5663_HP_IMP_SEN_14:
952 case RT5663_HP_IMP_SEN_15:
953 case RT5663_HP_IMP_SEN_16:
954 case RT5663_HP_IMP_SEN_17:
955 case RT5663_HP_IMP_SEN_18:
956 case RT5663_HP_IMP_SEN_19:
957 case RT5663_HP_IMPSEN_DIG5:
958 case RT5663_HP_IMPSEN_MAP1:
959 case RT5663_HP_IMPSEN_MAP2:
960 case RT5663_HP_IMPSEN_MAP3:
961 case RT5663_HP_IMPSEN_MAP4:
962 case RT5663_HP_IMPSEN_MAP5:
963 case RT5663_HP_IMPSEN_MAP7:
964 case RT5663_HP_LOGIC_1:
965 case RT5663_HP_LOGIC_2:
966 case RT5663_HP_CALIB_1:
967 case RT5663_HP_CALIB_1_1:
968 case RT5663_HP_CALIB_2:
969 case RT5663_HP_CALIB_3:
970 case RT5663_HP_CALIB_4:
971 case RT5663_HP_CALIB_5:
972 case RT5663_HP_CALIB_5_1:
973 case RT5663_HP_CALIB_6:
974 case RT5663_HP_CALIB_7:
975 case RT5663_HP_CALIB_9:
976 case RT5663_HP_CALIB_10:
977 case RT5663_HP_CALIB_11:
978 case RT5663_HP_CALIB_ST1:
979 case RT5663_HP_CALIB_ST2:
980 case RT5663_HP_CALIB_ST3:
981 case RT5663_HP_CALIB_ST4:
982 case RT5663_HP_CALIB_ST5:
983 case RT5663_HP_CALIB_ST6:
984 case RT5663_HP_CALIB_ST7:
985 case RT5663_HP_CALIB_ST8:
986 case RT5663_HP_CALIB_ST9:
987 case RT5663_HP_AMP_DET:
988 case RT5663_DUMMY_REG_6:
989 case RT5663_HP_BIAS:
990 case RT5663_CBJ_1:
991 case RT5663_CBJ_2:
992 case RT5663_CBJ_3:
993 case RT5663_DUMMY_1:
994 case RT5663_DUMMY_2:
995 case RT5663_DUMMY_3:
996 case RT5663_ANA_JD:
997 case RT5663_ADC_LCH_LPF1_A1:
998 case RT5663_ADC_RCH_LPF1_A1:
999 case RT5663_ADC_LCH_LPF1_H0:
1000 case RT5663_ADC_RCH_LPF1_H0:
1001 case RT5663_ADC_LCH_BPF1_A1:
1002 case RT5663_ADC_RCH_BPF1_A1:
1003 case RT5663_ADC_LCH_BPF1_A2:
1004 case RT5663_ADC_RCH_BPF1_A2:
1005 case RT5663_ADC_LCH_BPF1_H0:
1006 case RT5663_ADC_RCH_BPF1_H0:
1007 case RT5663_ADC_LCH_BPF2_A1:
1008 case RT5663_ADC_RCH_BPF2_A1:
1009 case RT5663_ADC_LCH_BPF2_A2:
1010 case RT5663_ADC_RCH_BPF2_A2:
1011 case RT5663_ADC_LCH_BPF2_H0:
1012 case RT5663_ADC_RCH_BPF2_H0:
1013 case RT5663_ADC_LCH_BPF3_A1:
1014 case RT5663_ADC_RCH_BPF3_A1:
1015 case RT5663_ADC_LCH_BPF3_A2:
1016 case RT5663_ADC_RCH_BPF3_A2:
1017 case RT5663_ADC_LCH_BPF3_H0:
1018 case RT5663_ADC_RCH_BPF3_H0:
1019 case RT5663_ADC_LCH_BPF4_A1:
1020 case RT5663_ADC_RCH_BPF4_A1:
1021 case RT5663_ADC_LCH_BPF4_A2:
1022 case RT5663_ADC_RCH_BPF4_A2:
1023 case RT5663_ADC_LCH_BPF4_H0:
1024 case RT5663_ADC_RCH_BPF4_H0:
1025 case RT5663_ADC_LCH_HPF1_A1:
1026 case RT5663_ADC_RCH_HPF1_A1:
1027 case RT5663_ADC_LCH_HPF1_H0:
1028 case RT5663_ADC_RCH_HPF1_H0:
1029 case RT5663_ADC_EQ_PRE_VOL_L:
1030 case RT5663_ADC_EQ_PRE_VOL_R:
1031 case RT5663_ADC_EQ_POST_VOL_L:
1032 case RT5663_ADC_EQ_POST_VOL_R:
1033 return true;
1034 default:
1035 return false;
1036 }
1037}
1038
1039static bool rt5668_volatile_register(struct device *dev, unsigned int reg)
1040{
1041 switch (reg) {
1042 case RT5663_RESET:
1043 case RT5668_CBJ_TYPE_2:
1044 case RT5668_PDM_OUT_CTL:
1045 case RT5668_PDM_I2C_DATA_CTL1:
1046 case RT5668_PDM_I2C_DATA_CTL4:
1047 case RT5668_ALC_BK_GAIN:
1048 case RT5663_PLL_2:
1049 case RT5663_MICBIAS_1:
1050 case RT5663_ADC_EQ_1:
1051 case RT5663_INT_ST_1:
1052 case RT5668_GPIO_STA:
1053 case RT5663_IL_CMD_1:
1054 case RT5663_IL_CMD_5:
1055 case RT5668_A_JD_CTRL:
1056 case RT5663_JD_CTRL2:
1057 case RT5663_VENDOR_ID:
1058 case RT5663_VENDOR_ID_1:
1059 case RT5663_VENDOR_ID_2:
1060 case RT5663_STO_DRE_1:
1061 case RT5663_STO_DRE_5:
1062 case RT5663_STO_DRE_6:
1063 case RT5663_STO_DRE_7:
1064 case RT5668_MONO_DYNA_6:
1065 case RT5668_STO1_SIL_DET:
1066 case RT5668_MONOL_SIL_DET:
1067 case RT5668_MONOR_SIL_DET:
1068 case RT5668_STO2_DAC_SIL:
1069 case RT5668_MONO_AMP_CAL_ST1:
1070 case RT5668_MONO_AMP_CAL_ST2:
1071 case RT5668_MONO_AMP_CAL_ST3:
1072 case RT5668_MONO_AMP_CAL_ST4:
1073 case RT5663_HP_IMP_SEN_2:
1074 case RT5663_HP_IMP_SEN_3:
1075 case RT5663_HP_IMP_SEN_4:
1076 case RT5663_HP_IMP_SEN_10:
1077 case RT5663_HP_CALIB_1:
1078 case RT5663_HP_CALIB_10:
1079 case RT5663_HP_CALIB_ST1:
1080 case RT5663_HP_CALIB_ST4:
1081 case RT5663_HP_CALIB_ST5:
1082 case RT5663_HP_CALIB_ST6:
1083 case RT5663_HP_CALIB_ST7:
1084 case RT5663_HP_CALIB_ST8:
1085 case RT5663_HP_CALIB_ST9:
1086 case RT5668_HP_CALIB_ST10:
1087 case RT5668_HP_CALIB_ST11:
1088 return true;
1089 default:
1090 return false;
1091 }
1092}
1093
1094static bool rt5668_readable_register(struct device *dev, unsigned int reg)
1095{
1096 switch (reg) {
1097 case RT5668_LOUT_CTRL:
1098 case RT5668_HP_AMP_2:
1099 case RT5668_MONO_OUT:
1100 case RT5668_MONO_GAIN:
1101 case RT5668_AEC_BST:
1102 case RT5668_IN1_IN2:
1103 case RT5668_IN3_IN4:
1104 case RT5668_INL1_INR1:
1105 case RT5668_CBJ_TYPE_2:
1106 case RT5668_CBJ_TYPE_3:
1107 case RT5668_CBJ_TYPE_4:
1108 case RT5668_CBJ_TYPE_5:
1109 case RT5668_CBJ_TYPE_8:
1110 case RT5668_DAC3_DIG_VOL:
1111 case RT5668_DAC3_CTRL:
1112 case RT5668_MONO_ADC_DIG_VOL:
1113 case RT5668_STO2_ADC_DIG_VOL:
1114 case RT5668_MONO_ADC_BST_GAIN:
1115 case RT5668_STO2_ADC_BST_GAIN:
1116 case RT5668_SIDETONE_CTRL:
1117 case RT5668_MONO1_ADC_MIXER:
1118 case RT5668_STO2_ADC_MIXER:
1119 case RT5668_MONO_DAC_MIXER:
1120 case RT5668_DAC2_SRC_CTRL:
1121 case RT5668_IF_3_4_DATA_CTL:
1122 case RT5668_IF_5_DATA_CTL:
1123 case RT5668_PDM_OUT_CTL:
1124 case RT5668_PDM_I2C_DATA_CTL1:
1125 case RT5668_PDM_I2C_DATA_CTL2:
1126 case RT5668_PDM_I2C_DATA_CTL3:
1127 case RT5668_PDM_I2C_DATA_CTL4:
1128 case RT5668_RECMIX1_NEW:
1129 case RT5668_RECMIX1L_0:
1130 case RT5668_RECMIX1L:
1131 case RT5668_RECMIX1R_0:
1132 case RT5668_RECMIX1R:
1133 case RT5668_RECMIX2_NEW:
1134 case RT5668_RECMIX2_L_2:
1135 case RT5668_RECMIX2_R:
1136 case RT5668_RECMIX2_R_2:
1137 case RT5668_CALIB_REC_LR:
1138 case RT5668_ALC_BK_GAIN:
1139 case RT5668_MONOMIX_GAIN:
1140 case RT5668_MONOMIX_IN_GAIN:
1141 case RT5668_OUT_MIXL_GAIN:
1142 case RT5668_OUT_LMIX_IN_GAIN:
1143 case RT5668_OUT_RMIX_IN_GAIN:
1144 case RT5668_OUT_RMIX_IN_GAIN1:
1145 case RT5668_LOUT_MIXER_CTRL:
1146 case RT5668_PWR_VOL:
1147 case RT5668_ADCDAC_RST:
1148 case RT5668_I2S34_SDP:
1149 case RT5668_I2S5_SDP:
1150 case RT5668_TDM_5:
1151 case RT5668_TDM_6:
1152 case RT5668_TDM_7:
1153 case RT5668_TDM_8:
1154 case RT5668_ASRC_3:
1155 case RT5668_ASRC_6:
1156 case RT5668_ASRC_7:
1157 case RT5668_PLL_TRK_13:
1158 case RT5668_I2S_M_CLK_CTL:
1159 case RT5668_FDIV_I2S34_M_CLK:
1160 case RT5668_FDIV_I2S34_M_CLK2:
1161 case RT5668_FDIV_I2S5_M_CLK:
1162 case RT5668_FDIV_I2S5_M_CLK2:
1163 case RT5668_IRQ_4:
1164 case RT5668_GPIO_3:
1165 case RT5668_GPIO_4:
1166 case RT5668_GPIO_STA:
1167 case RT5668_HP_AMP_DET1:
1168 case RT5668_HP_AMP_DET2:
1169 case RT5668_HP_AMP_DET3:
1170 case RT5668_MID_BD_HP_AMP:
1171 case RT5668_LOW_BD_HP_AMP:
1172 case RT5668_SOF_VOL_ZC2:
1173 case RT5668_ADC_STO2_ADJ1:
1174 case RT5668_ADC_STO2_ADJ2:
1175 case RT5668_A_JD_CTRL:
1176 case RT5668_JD1_TRES_CTRL:
1177 case RT5668_JD2_TRES_CTRL:
1178 case RT5668_JD_CTRL2:
1179 case RT5668_DUM_REG_2:
1180 case RT5668_DUM_REG_3:
1181 case RT5663_VENDOR_ID:
1182 case RT5663_VENDOR_ID_1:
1183 case RT5663_VENDOR_ID_2:
1184 case RT5668_DACADC_DIG_VOL2:
1185 case RT5668_DIG_IN_PIN2:
1186 case RT5668_PAD_DRV_CTL1:
1187 case RT5668_SOF_RAM_DEPOP:
1188 case RT5668_VOL_TEST:
1189 case RT5668_TEST_MODE_3:
1190 case RT5668_TEST_MODE_4:
1191 case RT5663_STO_DRE_9:
1192 case RT5668_MONO_DYNA_1:
1193 case RT5668_MONO_DYNA_2:
1194 case RT5668_MONO_DYNA_3:
1195 case RT5668_MONO_DYNA_4:
1196 case RT5668_MONO_DYNA_5:
1197 case RT5668_MONO_DYNA_6:
1198 case RT5668_STO1_SIL_DET:
1199 case RT5668_MONOL_SIL_DET:
1200 case RT5668_MONOR_SIL_DET:
1201 case RT5668_STO2_DAC_SIL:
1202 case RT5668_PWR_SAV_CTL1:
1203 case RT5668_PWR_SAV_CTL2:
1204 case RT5668_PWR_SAV_CTL3:
1205 case RT5668_PWR_SAV_CTL4:
1206 case RT5668_PWR_SAV_CTL5:
1207 case RT5668_PWR_SAV_CTL6:
1208 case RT5668_MONO_AMP_CAL1:
1209 case RT5668_MONO_AMP_CAL2:
1210 case RT5668_MONO_AMP_CAL3:
1211 case RT5668_MONO_AMP_CAL4:
1212 case RT5668_MONO_AMP_CAL5:
1213 case RT5668_MONO_AMP_CAL6:
1214 case RT5668_MONO_AMP_CAL7:
1215 case RT5668_MONO_AMP_CAL_ST1:
1216 case RT5668_MONO_AMP_CAL_ST2:
1217 case RT5668_MONO_AMP_CAL_ST3:
1218 case RT5668_MONO_AMP_CAL_ST4:
1219 case RT5668_MONO_AMP_CAL_ST5:
1220 case RT5668_HP_IMP_SEN_13:
1221 case RT5668_HP_IMP_SEN_14:
1222 case RT5668_HP_IMP_SEN_6:
1223 case RT5668_HP_IMP_SEN_7:
1224 case RT5668_HP_IMP_SEN_8:
1225 case RT5668_HP_IMP_SEN_9:
1226 case RT5668_HP_IMP_SEN_10:
1227 case RT5668_HP_LOGIC_3:
1228 case RT5668_HP_CALIB_ST10:
1229 case RT5668_HP_CALIB_ST11:
1230 case RT5668_PRO_REG_TBL_4:
1231 case RT5668_PRO_REG_TBL_5:
1232 case RT5668_PRO_REG_TBL_6:
1233 case RT5668_PRO_REG_TBL_7:
1234 case RT5668_PRO_REG_TBL_8:
1235 case RT5668_PRO_REG_TBL_9:
1236 case RT5668_SAR_ADC_INL_1:
1237 case RT5668_SAR_ADC_INL_2:
1238 case RT5668_SAR_ADC_INL_3:
1239 case RT5668_SAR_ADC_INL_4:
1240 case RT5668_SAR_ADC_INL_5:
1241 case RT5668_SAR_ADC_INL_6:
1242 case RT5668_SAR_ADC_INL_7:
1243 case RT5668_SAR_ADC_INL_8:
1244 case RT5668_SAR_ADC_INL_9:
1245 case RT5668_SAR_ADC_INL_10:
1246 case RT5668_SAR_ADC_INL_11:
1247 case RT5668_SAR_ADC_INL_12:
1248 case RT5668_DRC_CTRL_1:
1249 case RT5668_DRC1_CTRL_2:
1250 case RT5668_DRC1_CTRL_3:
1251 case RT5668_DRC1_CTRL_4:
1252 case RT5668_DRC1_CTRL_5:
1253 case RT5668_DRC1_CTRL_6:
1254 case RT5668_DRC1_HD_CTRL_1:
1255 case RT5668_DRC1_HD_CTRL_2:
1256 case RT5668_DRC1_PRI_REG_1:
1257 case RT5668_DRC1_PRI_REG_2:
1258 case RT5668_DRC1_PRI_REG_3:
1259 case RT5668_DRC1_PRI_REG_4:
1260 case RT5668_DRC1_PRI_REG_5:
1261 case RT5668_DRC1_PRI_REG_6:
1262 case RT5668_DRC1_PRI_REG_7:
1263 case RT5668_DRC1_PRI_REG_8:
1264 case RT5668_ALC_PGA_CTL_1:
1265 case RT5668_ALC_PGA_CTL_2:
1266 case RT5668_ALC_PGA_CTL_3:
1267 case RT5668_ALC_PGA_CTL_4:
1268 case RT5668_ALC_PGA_CTL_5:
1269 case RT5668_ALC_PGA_CTL_6:
1270 case RT5668_ALC_PGA_CTL_7:
1271 case RT5668_ALC_PGA_CTL_8:
1272 case RT5668_ALC_PGA_REG_1:
1273 case RT5668_ALC_PGA_REG_2:
1274 case RT5668_ALC_PGA_REG_3:
1275 case RT5668_ADC_EQ_RECOV_1:
1276 case RT5668_ADC_EQ_RECOV_2:
1277 case RT5668_ADC_EQ_RECOV_3:
1278 case RT5668_ADC_EQ_RECOV_4:
1279 case RT5668_ADC_EQ_RECOV_5:
1280 case RT5668_ADC_EQ_RECOV_6:
1281 case RT5668_ADC_EQ_RECOV_7:
1282 case RT5668_ADC_EQ_RECOV_8:
1283 case RT5668_ADC_EQ_RECOV_9:
1284 case RT5668_ADC_EQ_RECOV_10:
1285 case RT5668_ADC_EQ_RECOV_11:
1286 case RT5668_ADC_EQ_RECOV_12:
1287 case RT5668_ADC_EQ_RECOV_13:
1288 case RT5668_VID_HIDDEN:
1289 case RT5668_VID_CUSTOMER:
1290 case RT5668_SCAN_MODE:
1291 case RT5668_I2C_BYPA:
1292 return true;
1293 case RT5663_TDM_1:
1294 case RT5663_DEPOP_3:
1295 case RT5663_ASRC_11_2:
1296 case RT5663_INT_ST_2:
1297 case RT5663_GPIO_STA:
1298 case RT5663_SIN_GEN_1:
1299 case RT5663_SIN_GEN_2:
1300 case RT5663_SIN_GEN_3:
1301 case RT5663_IL_CMD_PWRSAV1:
1302 case RT5663_IL_CMD_PWRSAV2:
1303 case RT5663_EM_JACK_TYPE_1:
1304 case RT5663_EM_JACK_TYPE_2:
1305 case RT5663_EM_JACK_TYPE_3:
1306 case RT5663_EM_JACK_TYPE_4:
1307 case RT5663_FAST_OFF_MICBIAS:
1308 case RT5663_ANA_BIAS_CUR_1:
1309 case RT5663_ANA_BIAS_CUR_2:
1310 case RT5663_BIAS_CUR_9:
1311 case RT5663_DUMMY_REG_4:
1312 case RT5663_VREF_RECMIX:
1313 case RT5663_CHARGE_PUMP_1_2:
1314 case RT5663_CHARGE_PUMP_1_3:
1315 case RT5663_CHARGE_PUMP_2:
1316 case RT5663_CHOP_DAC_R:
1317 case RT5663_DUMMY_CTL_DACLR:
1318 case RT5663_DUMMY_REG_5:
1319 case RT5663_SOFT_RAMP:
1320 case RT5663_TEST_MODE_1:
1321 case RT5663_STO_DRE_10:
1322 case RT5663_MIC_DECRO_1:
1323 case RT5663_MIC_DECRO_2:
1324 case RT5663_MIC_DECRO_3:
1325 case RT5663_MIC_DECRO_4:
1326 case RT5663_MIC_DECRO_5:
1327 case RT5663_MIC_DECRO_6:
1328 case RT5663_HP_DECRO_1:
1329 case RT5663_HP_DECRO_2:
1330 case RT5663_HP_DECRO_3:
1331 case RT5663_HP_DECRO_4:
1332 case RT5663_HP_DECOUP:
1333 case RT5663_HP_IMPSEN_MAP4:
1334 case RT5663_HP_IMPSEN_MAP5:
1335 case RT5663_HP_IMPSEN_MAP7:
1336 case RT5663_HP_CALIB_1:
1337 case RT5663_CBJ_1:
1338 case RT5663_CBJ_2:
1339 case RT5663_CBJ_3:
1340 return false;
1341 default:
1342 return rt5663_readable_register(dev, reg);
1343 }
1344}
1345
1346static const DECLARE_TLV_DB_SCALE(rt5663_hp_vol_tlv, -2400, 150, 0);
1347static const DECLARE_TLV_DB_SCALE(rt5668_hp_vol_tlv, -2250, 150, 0);
1348static const DECLARE_TLV_DB_SCALE(dac_vol_tlv, -6525, 75, 0);
1349static const DECLARE_TLV_DB_SCALE(adc_vol_tlv, -1725, 75, 0);
1350
1351/* {0, +20, +24, +30, +35, +40, +44, +50, +52} dB */
1352static const DECLARE_TLV_DB_RANGE(in_bst_tlv,
1353 0, 0, TLV_DB_SCALE_ITEM(0, 0, 0),
1354 1, 1, TLV_DB_SCALE_ITEM(2000, 0, 0),
1355 2, 2, TLV_DB_SCALE_ITEM(2400, 0, 0),
1356 3, 5, TLV_DB_SCALE_ITEM(3000, 500, 0),
1357 6, 6, TLV_DB_SCALE_ITEM(4400, 0, 0),
1358 7, 7, TLV_DB_SCALE_ITEM(5000, 0, 0),
1359 8, 8, TLV_DB_SCALE_ITEM(5200, 0, 0)
1360);
1361
1362/* Interface data select */
1363static const char * const rt5663_if1_adc_data_select[] = {
1364 "L/R", "R/L", "L/L", "R/R"
1365};
1366
1367static SOC_ENUM_SINGLE_DECL(rt5663_if1_adc_enum, RT5663_TDM_2,
1368 RT5663_DATA_SWAP_ADCDAT1_SHIFT, rt5663_if1_adc_data_select);
1369
1370static void rt5663_enable_push_button_irq(struct snd_soc_codec *codec,
1371 bool enable)
1372{
1373 struct rt5663_priv *rt5663 = snd_soc_codec_get_drvdata(codec);
1374
1375 if (enable) {
1376 snd_soc_update_bits(codec, RT5663_IL_CMD_6,
1377 RT5668_EN_4BTN_INL_MASK, RT5668_EN_4BTN_INL_EN);
1378 /* reset in-line command */
1379 snd_soc_update_bits(codec, RT5663_IL_CMD_6,
1380 RT5668_RESET_4BTN_INL_MASK,
1381 RT5668_RESET_4BTN_INL_RESET);
1382 snd_soc_update_bits(codec, RT5663_IL_CMD_6,
1383 RT5668_RESET_4BTN_INL_MASK,
1384 RT5668_RESET_4BTN_INL_NOR);
1385 switch (rt5663->codec_type) {
1386 case CODEC_TYPE_RT5668:
1387 snd_soc_update_bits(codec, RT5663_IRQ_3,
1388 RT5668_EN_IRQ_INLINE_MASK,
1389 RT5668_EN_IRQ_INLINE_NOR);
1390 break;
1391 case CODEC_TYPE_RT5663:
1392 snd_soc_update_bits(codec, RT5663_IRQ_2,
1393 RT5663_EN_IRQ_INLINE_MASK,
1394 RT5663_EN_IRQ_INLINE_NOR);
1395 break;
1396 default:
1397 dev_err(codec->dev, "Unknown CODEC_TYPE\n");
1398 }
1399 } else {
1400 switch (rt5663->codec_type) {
1401 case CODEC_TYPE_RT5668:
1402 snd_soc_update_bits(codec, RT5663_IRQ_3,
1403 RT5668_EN_IRQ_INLINE_MASK,
1404 RT5668_EN_IRQ_INLINE_BYP);
1405 break;
1406 case CODEC_TYPE_RT5663:
1407 snd_soc_update_bits(codec, RT5663_IRQ_2,
1408 RT5663_EN_IRQ_INLINE_MASK,
1409 RT5663_EN_IRQ_INLINE_BYP);
1410 break;
1411 default:
1412 dev_err(codec->dev, "Unknown CODEC_TYPE\n");
1413 }
1414 snd_soc_update_bits(codec, RT5663_IL_CMD_6,
1415 RT5668_EN_4BTN_INL_MASK, RT5668_EN_4BTN_INL_DIS);
1416 /* reset in-line command */
1417 snd_soc_update_bits(codec, RT5663_IL_CMD_6,
1418 RT5668_RESET_4BTN_INL_MASK,
1419 RT5668_RESET_4BTN_INL_RESET);
1420 snd_soc_update_bits(codec, RT5663_IL_CMD_6,
1421 RT5668_RESET_4BTN_INL_MASK,
1422 RT5668_RESET_4BTN_INL_NOR);
1423 }
1424}
1425
1426/**
1427 * rt5668_jack_detect - Detect headset.
1428 * @codec: SoC audio codec device.
1429 * @jack_insert: Jack insert or not.
1430 *
1431 * Detect whether is headset or not when jack inserted.
1432 *
1433 * Returns detect status.
1434 */
1435
1436static int rt5668_jack_detect(struct snd_soc_codec *codec, int jack_insert)
1437{
1438 struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
1439 struct rt5663_priv *rt5668 = snd_soc_codec_get_drvdata(codec);
1440 int val, i = 0, sleep_time[5] = {300, 150, 100, 50, 30};
1441
1442 dev_dbg(codec->dev, "%s jack_insert:%d\n", __func__, jack_insert);
1443 if (jack_insert) {
1444 snd_soc_write(codec, RT5668_CBJ_TYPE_2, 0x8040);
1445 snd_soc_write(codec, RT5668_CBJ_TYPE_3, 0x1484);
1446
1447 snd_soc_dapm_force_enable_pin(dapm, "MICBIAS1");
1448 snd_soc_dapm_force_enable_pin(dapm, "MICBIAS2");
1449 snd_soc_dapm_force_enable_pin(dapm, "Mic Det Power");
1450 snd_soc_dapm_force_enable_pin(dapm, "CBJ Power");
1451 snd_soc_dapm_sync(dapm);
1452 snd_soc_update_bits(codec, RT5663_RC_CLK,
1453 RT5668_DIG_1M_CLK_MASK, RT5668_DIG_1M_CLK_EN);
1454 snd_soc_update_bits(codec, RT5663_RECMIX, 0x8, 0x8);
1455
1456 while (i < 5) {
1457 msleep(sleep_time[i]);
1458 val = snd_soc_read(codec, RT5668_CBJ_TYPE_2) & 0x0003;
1459 if (val == 0x1 || val == 0x2 || val == 0x3)
1460 break;
1461 dev_dbg(codec->dev, "%s: MX-0011 val=%x sleep %d\n",
1462 __func__, val, sleep_time[i]);
1463 i++;
1464 }
1465 dev_dbg(codec->dev, "%s val = %d\n", __func__, val);
1466 switch (val) {
1467 case 1:
1468 case 2:
1469 rt5668->jack_type = SND_JACK_HEADSET;
1470 rt5663_enable_push_button_irq(codec, true);
1471 break;
1472 default:
1473 snd_soc_dapm_disable_pin(dapm, "MICBIAS1");
1474 snd_soc_dapm_disable_pin(dapm, "MICBIAS2");
1475 snd_soc_dapm_disable_pin(dapm, "Mic Det Power");
1476 snd_soc_dapm_disable_pin(dapm, "CBJ Power");
1477 snd_soc_dapm_sync(dapm);
1478 rt5668->jack_type = SND_JACK_HEADPHONE;
1479 break;
1480 }
1481 } else {
1482 snd_soc_update_bits(codec, RT5663_RECMIX, 0x8, 0x0);
1483
1484 if (rt5668->jack_type == SND_JACK_HEADSET) {
1485 rt5663_enable_push_button_irq(codec, false);
1486 snd_soc_dapm_disable_pin(dapm, "MICBIAS1");
1487 snd_soc_dapm_disable_pin(dapm, "MICBIAS2");
1488 snd_soc_dapm_disable_pin(dapm, "Mic Det Power");
1489 snd_soc_dapm_disable_pin(dapm, "CBJ Power");
1490 snd_soc_dapm_sync(dapm);
1491 }
1492 rt5668->jack_type = 0;
1493 }
1494
1495 dev_dbg(codec->dev, "jack_type = %d\n", rt5668->jack_type);
1496 return rt5668->jack_type;
1497}
1498
1499/**
1500 * rt5663_jack_detect - Detect headset.
1501 * @codec: SoC audio codec device.
1502 * @jack_insert: Jack insert or not.
1503 *
1504 * Detect whether is headset or not when jack inserted.
1505 *
1506 * Returns detect status.
1507 */
1508static int rt5663_jack_detect(struct snd_soc_codec *codec, int jack_insert)
1509{
1510 struct rt5663_priv *rt5663 = snd_soc_codec_get_drvdata(codec);
1511 int val, i = 0, sleep_time[5] = {300, 150, 100, 50, 30};
1512
1513 dev_dbg(codec->dev, "%s jack_insert:%d\n", __func__, jack_insert);
1514
1515 if (jack_insert) {
1516 snd_soc_update_bits(codec, RT5663_DIG_MISC,
1517 RT5668_DIG_GATE_CTRL_MASK, RT5668_DIG_GATE_CTRL_EN);
1518 snd_soc_update_bits(codec, RT5663_HP_CHARGE_PUMP_1,
1519 RT5663_SI_HP_MASK | RT5668_OSW_HP_L_MASK |
1520 RT5668_OSW_HP_R_MASK, RT5663_SI_HP_EN |
1521 RT5668_OSW_HP_L_DIS | RT5668_OSW_HP_R_DIS);
1522 snd_soc_update_bits(codec, RT5663_DUMMY_1,
1523 RT5663_EMB_CLK_MASK | RT5663_HPA_CPL_BIAS_MASK |
1524 RT5663_HPA_CPR_BIAS_MASK, RT5663_EMB_CLK_EN |
1525 RT5663_HPA_CPL_BIAS_1 | RT5663_HPA_CPR_BIAS_1);
1526 snd_soc_update_bits(codec, RT5663_CBJ_1,
1527 RT5663_INBUF_CBJ_BST1_MASK | RT5663_CBJ_SENSE_BST1_MASK,
1528 RT5663_INBUF_CBJ_BST1_ON | RT5663_CBJ_SENSE_BST1_L);
1529 snd_soc_update_bits(codec, RT5663_IL_CMD_2,
1530 RT5663_PWR_MIC_DET_MASK, RT5663_PWR_MIC_DET_ON);
1531 /* BST1 power on for JD */
1532 snd_soc_update_bits(codec, RT5663_PWR_ANLG_2,
1533 RT5668_PWR_BST1_MASK, RT5668_PWR_BST1_ON);
1534 snd_soc_update_bits(codec, RT5663_EM_JACK_TYPE_1,
1535 RT5663_CBJ_DET_MASK | RT5663_EXT_JD_MASK |
1536 RT5663_POL_EXT_JD_MASK, RT5663_CBJ_DET_EN |
1537 RT5663_EXT_JD_EN | RT5663_POL_EXT_JD_EN);
1538 snd_soc_update_bits(codec, RT5663_PWR_ANLG_1,
1539 RT5668_PWR_MB_MASK | RT5668_LDO1_DVO_MASK |
1540 RT5668_AMP_HP_MASK, RT5668_PWR_MB |
1541 RT5668_LDO1_DVO_0_9V | RT5668_AMP_HP_3X);
1542 snd_soc_update_bits(codec, RT5663_AUTO_1MRC_CLK,
1543 RT5668_IRQ_POW_SAV_MASK, RT5668_IRQ_POW_SAV_EN);
1544 snd_soc_update_bits(codec, RT5663_IRQ_1,
1545 RT5663_EN_IRQ_JD1_MASK, RT5663_EN_IRQ_JD1_EN);
1546 while (i < 5) {
1547 msleep(sleep_time[i]);
1548 val = snd_soc_read(codec, RT5663_EM_JACK_TYPE_2) &
1549 0x0003;
1550 i++;
1551 if (val == 0x1 || val == 0x2 || val == 0x3)
1552 break;
1553 dev_dbg(codec->dev, "%s: MX-00e7 val=%x sleep %d\n",
1554 __func__, val, sleep_time[i]);
1555 }
1556 dev_dbg(codec->dev, "%s val = %d\n", __func__, val);
1557 switch (val) {
1558 case 1:
1559 case 2:
1560 rt5663->jack_type = SND_JACK_HEADSET;
1561 rt5663_enable_push_button_irq(codec, true);
1562 break;
1563 default:
1564 rt5663->jack_type = SND_JACK_HEADPHONE;
1565 break;
1566 }
1567 } else {
1568 if (rt5663->jack_type == SND_JACK_HEADSET)
1569 rt5663_enable_push_button_irq(codec, false);
1570 rt5663->jack_type = 0;
1571 }
1572
1573 dev_dbg(codec->dev, "jack_type = %d\n", rt5663->jack_type);
1574 return rt5663->jack_type;
1575}
1576
1577static int rt5663_button_detect(struct snd_soc_codec *codec)
1578{
1579 int btn_type, val;
1580
1581 val = snd_soc_read(codec, RT5663_IL_CMD_5);
1582 dev_dbg(codec->dev, "%s: val=0x%x\n", __func__, val);
1583 btn_type = val & 0xfff0;
1584 snd_soc_write(codec, RT5663_IL_CMD_5, val);
1585
1586 return btn_type;
1587}
1588
1589static irqreturn_t rt5663_irq(int irq, void *data)
1590{
1591 struct rt5663_priv *rt5663 = data;
1592
1593 dev_dbg(rt5663->codec->dev, "%s IRQ queue work\n", __func__);
1594
1595 queue_delayed_work(system_wq, &rt5663->jack_detect_work,
1596 msecs_to_jiffies(250));
1597
1598 return IRQ_HANDLED;
1599}
1600
1601int rt5663_set_jack_detect(struct snd_soc_codec *codec,
1602 struct snd_soc_jack *hs_jack)
1603{
1604 struct rt5663_priv *rt5663 = snd_soc_codec_get_drvdata(codec);
1605
1606 rt5663->hs_jack = hs_jack;
1607
1608 rt5663_irq(0, rt5663);
1609
1610 return 0;
1611}
1612EXPORT_SYMBOL_GPL(rt5663_set_jack_detect);
1613
1614static bool rt5663_check_jd_status(struct snd_soc_codec *codec)
1615{
1616 struct rt5663_priv *rt5663 = snd_soc_codec_get_drvdata(codec);
1617 int val = snd_soc_read(codec, RT5663_INT_ST_1);
1618
1619 dev_dbg(codec->dev, "%s val=%x\n", __func__, val);
1620
1621 /* JD1 */
1622 switch (rt5663->codec_type) {
1623 case CODEC_TYPE_RT5668:
1624 return !(val & 0x2000);
1625 case CODEC_TYPE_RT5663:
1626 return !(val & 0x1000);
1627 default:
1628 dev_err(codec->dev, "Unknown CODEC_TYPE\n");
1629 }
1630
1631 return false;
1632}
1633
1634static void rt5663_jack_detect_work(struct work_struct *work)
1635{
1636 struct rt5663_priv *rt5663 =
1637 container_of(work, struct rt5663_priv, jack_detect_work.work);
1638 struct snd_soc_codec *codec = rt5663->codec;
1639 int btn_type, report = 0;
1640
1641 if (!codec)
1642 return;
1643
1644 if (rt5663_check_jd_status(codec)) {
1645 /* jack in */
1646 if (rt5663->jack_type == 0) {
1647 /* jack was out, report jack type */
1648 switch (rt5663->codec_type) {
1649 case CODEC_TYPE_RT5668:
1650 report = rt5668_jack_detect(rt5663->codec, 1);
1651 break;
1652 case CODEC_TYPE_RT5663:
1653 report = rt5663_jack_detect(rt5663->codec, 1);
1654 break;
1655 default:
1656 dev_err(codec->dev, "Unknown CODEC_TYPE\n");
1657 }
1658 } else {
1659 /* jack is already in, report button event */
1660 report = SND_JACK_HEADSET;
1661 btn_type = rt5663_button_detect(rt5663->codec);
1662 /**
1663 * rt5663 can report three kinds of button behavior,
1664 * one click, double click and hold. However,
1665 * currently we will report button pressed/released
1666 * event. So all the three button behaviors are
1667 * treated as button pressed.
1668 */
1669 switch (btn_type) {
1670 case 0x8000:
1671 case 0x4000:
1672 case 0x2000:
1673 report |= SND_JACK_BTN_0;
1674 break;
1675 case 0x1000:
1676 case 0x0800:
1677 case 0x0400:
1678 report |= SND_JACK_BTN_1;
1679 break;
1680 case 0x0200:
1681 case 0x0100:
1682 case 0x0080:
1683 report |= SND_JACK_BTN_2;
1684 break;
1685 case 0x0040:
1686 case 0x0020:
1687 case 0x0010:
1688 report |= SND_JACK_BTN_3;
1689 break;
1690 case 0x0000: /* unpressed */
1691 break;
1692 default:
1693 btn_type = 0;
1694 dev_err(rt5663->codec->dev,
1695 "Unexpected button code 0x%04x\n",
1696 btn_type);
1697 break;
1698 }
1699 /* button release or spurious interrput*/
1700 if (btn_type == 0)
1701 report = rt5663->jack_type;
1702 }
1703 } else {
1704 /* jack out */
1705 switch (rt5663->codec_type) {
1706 case CODEC_TYPE_RT5668:
1707 report = rt5668_jack_detect(rt5663->codec, 0);
1708 break;
1709 case CODEC_TYPE_RT5663:
1710 report = rt5663_jack_detect(rt5663->codec, 0);
1711 break;
1712 default:
1713 dev_err(codec->dev, "Unknown CODEC_TYPE\n");
1714 }
1715 }
1716 dev_dbg(codec->dev, "%s jack report: 0x%04x\n", __func__, report);
1717 snd_soc_jack_report(rt5663->hs_jack, report, SND_JACK_HEADSET |
1718 SND_JACK_BTN_0 | SND_JACK_BTN_1 |
1719 SND_JACK_BTN_2 | SND_JACK_BTN_3);
1720}
1721
1722static const struct snd_kcontrol_new rt5663_snd_controls[] = {
1723 /* DAC Digital Volume */
1724 SOC_DOUBLE_TLV("DAC Playback Volume", RT5663_STO1_DAC_DIG_VOL,
1725 RT5668_DAC_L1_VOL_SHIFT + 1, RT5668_DAC_R1_VOL_SHIFT + 1,
1726 87, 0, dac_vol_tlv),
1727 /* ADC Digital Volume Control */
1728 SOC_DOUBLE("ADC Capture Switch", RT5663_STO1_ADC_DIG_VOL,
1729 RT5668_ADC_L_MUTE_SHIFT, RT5668_ADC_R_MUTE_SHIFT, 1, 1),
1730 SOC_DOUBLE_TLV("ADC Capture Volume", RT5663_STO1_ADC_DIG_VOL,
1731 RT5668_ADC_L_VOL_SHIFT + 1, RT5668_ADC_R_VOL_SHIFT + 1,
1732 63, 0, adc_vol_tlv),
1733};
1734
1735static const struct snd_kcontrol_new rt5668_specific_controls[] = {
1736 /* Headphone Output Volume */
1737 SOC_DOUBLE_R_TLV("Headphone Playback Volume", RT5663_HP_LCH_DRE,
1738 RT5663_HP_RCH_DRE, RT5668_GAIN_HP_SHIFT, 15, 1,
1739 rt5668_hp_vol_tlv),
1740 /* Mic Boost Volume */
1741 SOC_SINGLE_TLV("IN1 Capture Volume", RT5668_AEC_BST,
1742 RT5668_GAIN_CBJ_SHIFT, 8, 0, in_bst_tlv),
1743};
1744
1745static const struct snd_kcontrol_new rt5663_specific_controls[] = {
1746 /* Headphone Output Volume */
1747 SOC_DOUBLE_R_TLV("Headphone Playback Volume", RT5663_STO_DRE_9,
1748 RT5663_STO_DRE_10, RT5663_DRE_GAIN_HP_SHIFT, 23, 1,
1749 rt5663_hp_vol_tlv),
1750 /* Mic Boost Volume*/
1751 SOC_SINGLE_TLV("IN1 Capture Volume", RT5663_CBJ_2,
1752 RT5663_GAIN_BST1_SHIFT, 8, 0, in_bst_tlv),
1753 /* Data Swap for Slot0/1 in ADCDAT1 */
1754 SOC_ENUM("IF1 ADC Data Swap", rt5663_if1_adc_enum),
1755};
1756
1757static int rt5663_is_sys_clk_from_pll(struct snd_soc_dapm_widget *w,
1758 struct snd_soc_dapm_widget *sink)
1759{
1760 unsigned int val;
1761 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
1762
1763 val = snd_soc_read(codec, RT5663_GLB_CLK);
1764 val &= RT5663_SCLK_SRC_MASK;
1765 if (val == RT5663_SCLK_SRC_PLL1)
1766 return 1;
1767 else
1768 return 0;
1769}
1770
1771static int rt5663_is_using_asrc(struct snd_soc_dapm_widget *w,
1772 struct snd_soc_dapm_widget *sink)
1773{
1774 unsigned int reg, shift, val;
1775 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
1776 struct rt5663_priv *rt5663 = snd_soc_codec_get_drvdata(codec);
1777
1778 if (rt5663->codec_type == CODEC_TYPE_RT5668) {
1779 switch (w->shift) {
1780 case RT5668_ADC_STO1_ASRC_SHIFT:
1781 reg = RT5668_ASRC_3;
1782 shift = RT5668_AD_STO1_TRACK_SHIFT;
1783 break;
1784 case RT5668_DAC_STO1_ASRC_SHIFT:
1785 reg = RT5663_ASRC_2;
1786 shift = RT5668_DA_STO1_TRACK_SHIFT;
1787 break;
1788 default:
1789 return 0;
1790 }
1791 } else {
1792 switch (w->shift) {
1793 case RT5663_ADC_STO1_ASRC_SHIFT:
1794 reg = RT5663_ASRC_2;
1795 shift = RT5663_AD_STO1_TRACK_SHIFT;
1796 break;
1797 case RT5663_DAC_STO1_ASRC_SHIFT:
1798 reg = RT5663_ASRC_2;
1799 shift = RT5663_DA_STO1_TRACK_SHIFT;
1800 break;
1801 default:
1802 return 0;
1803 }
1804 }
1805
1806 val = (snd_soc_read(codec, reg) >> shift) & 0x7;
1807
1808 if (val)
1809 return 1;
1810
1811 return 0;
1812}
1813
1814static int rt5663_i2s_use_asrc(struct snd_soc_dapm_widget *source,
1815 struct snd_soc_dapm_widget *sink)
1816{
1817 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(source->dapm);
1818 struct rt5663_priv *rt5663 = snd_soc_codec_get_drvdata(codec);
1819 int da_asrc_en, ad_asrc_en;
1820
1821 da_asrc_en = (snd_soc_read(codec, RT5663_ASRC_2) &
1822 RT5663_DA_STO1_TRACK_MASK) ? 1 : 0;
1823 switch (rt5663->codec_type) {
1824 case CODEC_TYPE_RT5668:
1825 ad_asrc_en = (snd_soc_read(codec, RT5668_ASRC_3) &
1826 RT5668_AD_STO1_TRACK_MASK) ? 1 : 0;
1827 break;
1828 case CODEC_TYPE_RT5663:
1829 ad_asrc_en = (snd_soc_read(codec, RT5663_ASRC_2) &
1830 RT5663_AD_STO1_TRACK_MASK) ? 1 : 0;
1831 break;
1832 default:
1833 dev_err(codec->dev, "Unknown CODEC_TYPE\n");
1834 return 1;
1835 }
1836
1837 if (da_asrc_en || ad_asrc_en)
1838 if (rt5663->sysclk > rt5663->lrck * 384)
1839 return 1;
1840
1841 dev_err(codec->dev, "sysclk < 384 x fs, disable i2s asrc\n");
1842
1843 return 0;
1844}
1845
1846/**
1847 * rt5663_sel_asrc_clk_src - select ASRC clock source for a set of filters
1848 * @codec: SoC audio codec device.
1849 * @filter_mask: mask of filters.
1850 * @clk_src: clock source
1851 *
1852 * The ASRC function is for asynchronous MCLK and LRCK. Also, since RT5668 can
1853 * only support standard 32fs or 64fs i2s format, ASRC should be enabled to
1854 * support special i2s clock format such as Intel's 100fs(100 * sampling rate).
1855 * ASRC function will track i2s clock and generate a corresponding system clock
1856 * for codec. This function provides an API to select the clock source for a
1857 * set of filters specified by the mask. And the codec driver will turn on ASRC
1858 * for these filters if ASRC is selected as their clock source.
1859 */
1860int rt5663_sel_asrc_clk_src(struct snd_soc_codec *codec,
1861 unsigned int filter_mask, unsigned int clk_src)
1862{
1863 struct rt5663_priv *rt5668 = snd_soc_codec_get_drvdata(codec);
1864 unsigned int asrc2_mask = 0;
1865 unsigned int asrc2_value = 0;
1866 unsigned int asrc3_mask = 0;
1867 unsigned int asrc3_value = 0;
1868
1869 switch (clk_src) {
1870 case RT5663_CLK_SEL_SYS:
1871 case RT5663_CLK_SEL_I2S1_ASRC:
1872 break;
1873
1874 default:
1875 return -EINVAL;
1876 }
1877
1878 if (filter_mask & RT5663_DA_STEREO_FILTER) {
1879 asrc2_mask |= RT5668_DA_STO1_TRACK_MASK;
1880 asrc2_value |= clk_src << RT5668_DA_STO1_TRACK_SHIFT;
1881 }
1882
1883 if (filter_mask & RT5663_AD_STEREO_FILTER) {
1884 switch (rt5668->codec_type) {
1885 case CODEC_TYPE_RT5668:
1886 asrc3_mask |= RT5668_AD_STO1_TRACK_MASK;
1887 asrc3_value |= clk_src << RT5668_AD_STO1_TRACK_SHIFT;
1888 break;
1889 case CODEC_TYPE_RT5663:
1890 asrc2_mask |= RT5663_AD_STO1_TRACK_MASK;
1891 asrc2_value |= clk_src << RT5663_AD_STO1_TRACK_SHIFT;
1892 break;
1893 default:
1894 dev_err(codec->dev, "Unknown CODEC_TYPE\n");
1895 }
1896 }
1897
1898 if (asrc2_mask)
1899 snd_soc_update_bits(codec, RT5663_ASRC_2, asrc2_mask,
1900 asrc2_value);
1901
1902 if (asrc3_mask)
1903 snd_soc_update_bits(codec, RT5668_ASRC_3, asrc3_mask,
1904 asrc3_value);
1905
1906 return 0;
1907}
1908EXPORT_SYMBOL_GPL(rt5663_sel_asrc_clk_src);
1909
1910/* Analog Mixer */
1911static const struct snd_kcontrol_new rt5668_recmix1l[] = {
1912 SOC_DAPM_SINGLE("BST2 Switch", RT5668_RECMIX1L,
1913 RT5668_RECMIX1L_BST2_SHIFT, 1, 1),
1914 SOC_DAPM_SINGLE("BST1 CBJ Switch", RT5668_RECMIX1L,
1915 RT5668_RECMIX1L_BST1_CBJ_SHIFT, 1, 1),
1916};
1917
1918static const struct snd_kcontrol_new rt5668_recmix1r[] = {
1919 SOC_DAPM_SINGLE("BST2 Switch", RT5668_RECMIX1R,
1920 RT5668_RECMIX1R_BST2_SHIFT, 1, 1),
1921};
1922
1923/* Digital Mixer */
1924static const struct snd_kcontrol_new rt5663_sto1_adc_l_mix[] = {
1925 SOC_DAPM_SINGLE("ADC1 Switch", RT5663_STO1_ADC_MIXER,
1926 RT5668_M_STO1_ADC_L1_SHIFT, 1, 1),
1927 SOC_DAPM_SINGLE("ADC2 Switch", RT5663_STO1_ADC_MIXER,
1928 RT5668_M_STO1_ADC_L2_SHIFT, 1, 1),
1929};
1930
1931static const struct snd_kcontrol_new rt5668_sto1_adc_r_mix[] = {
1932 SOC_DAPM_SINGLE("ADC1 Switch", RT5663_STO1_ADC_MIXER,
1933 RT5668_M_STO1_ADC_R1_SHIFT, 1, 1),
1934 SOC_DAPM_SINGLE("ADC2 Switch", RT5663_STO1_ADC_MIXER,
1935 RT5668_M_STO1_ADC_R2_SHIFT, 1, 1),
1936};
1937
1938static const struct snd_kcontrol_new rt5663_adda_l_mix[] = {
1939 SOC_DAPM_SINGLE("ADC L Switch", RT5663_AD_DA_MIXER,
1940 RT5668_M_ADCMIX_L_SHIFT, 1, 1),
1941 SOC_DAPM_SINGLE("DAC L Switch", RT5663_AD_DA_MIXER,
1942 RT5668_M_DAC1_L_SHIFT, 1, 1),
1943};
1944
1945static const struct snd_kcontrol_new rt5663_adda_r_mix[] = {
1946 SOC_DAPM_SINGLE("ADC R Switch", RT5663_AD_DA_MIXER,
1947 RT5668_M_ADCMIX_R_SHIFT, 1, 1),
1948 SOC_DAPM_SINGLE("DAC R Switch", RT5663_AD_DA_MIXER,
1949 RT5668_M_DAC1_R_SHIFT, 1, 1),
1950};
1951
1952static const struct snd_kcontrol_new rt5663_sto1_dac_l_mix[] = {
1953 SOC_DAPM_SINGLE("DAC L Switch", RT5663_STO_DAC_MIXER,
1954 RT5668_M_DAC_L1_STO_L_SHIFT, 1, 1),
1955 SOC_DAPM_SINGLE("DAC R Switch", RT5663_STO_DAC_MIXER,
1956 RT5668_M_DAC_R1_STO_L_SHIFT, 1, 1),
1957};
1958
1959static const struct snd_kcontrol_new rt5663_sto1_dac_r_mix[] = {
1960 SOC_DAPM_SINGLE("DAC L Switch", RT5663_STO_DAC_MIXER,
1961 RT5668_M_DAC_L1_STO_R_SHIFT, 1, 1),
1962 SOC_DAPM_SINGLE("DAC R Switch", RT5663_STO_DAC_MIXER,
1963 RT5668_M_DAC_R1_STO_R_SHIFT, 1, 1),
1964};
1965
1966/* Out Switch */
1967static const struct snd_kcontrol_new rt5668_hpo_switch =
1968 SOC_DAPM_SINGLE_AUTODISABLE("Switch", RT5668_HP_AMP_2,
1969 RT5668_EN_DAC_HPO_SHIFT, 1, 0);
1970
1971/* Stereo ADC source */
1972static const char * const rt5668_sto1_adc_src[] = {
1973 "ADC L", "ADC R"
1974};
1975
1976static SOC_ENUM_SINGLE_DECL(rt5668_sto1_adcl_enum, RT5663_STO1_ADC_MIXER,
1977 RT5668_STO1_ADC_L_SRC_SHIFT, rt5668_sto1_adc_src);
1978
1979static const struct snd_kcontrol_new rt5668_sto1_adcl_mux =
1980 SOC_DAPM_ENUM("STO1 ADC L Mux", rt5668_sto1_adcl_enum);
1981
1982static SOC_ENUM_SINGLE_DECL(rt5668_sto1_adcr_enum, RT5663_STO1_ADC_MIXER,
1983 RT5668_STO1_ADC_R_SRC_SHIFT, rt5668_sto1_adc_src);
1984
1985static const struct snd_kcontrol_new rt5668_sto1_adcr_mux =
1986 SOC_DAPM_ENUM("STO1 ADC R Mux", rt5668_sto1_adcr_enum);
1987
1988/* RT5663: Analog DACL1 input source */
1989static const char * const rt5663_alg_dacl_src[] = {
1990 "DAC L", "STO DAC MIXL"
1991};
1992
1993static SOC_ENUM_SINGLE_DECL(rt5663_alg_dacl_enum, RT5663_BYPASS_STO_DAC,
1994 RT5663_DACL1_SRC_SHIFT, rt5663_alg_dacl_src);
1995
1996static const struct snd_kcontrol_new rt5663_alg_dacl_mux =
1997 SOC_DAPM_ENUM("DAC L Mux", rt5663_alg_dacl_enum);
1998
1999/* RT5663: Analog DACR1 input source */
2000static const char * const rt5663_alg_dacr_src[] = {
2001 "DAC R", "STO DAC MIXR"
2002};
2003
2004static SOC_ENUM_SINGLE_DECL(rt5663_alg_dacr_enum, RT5663_BYPASS_STO_DAC,
2005 RT5663_DACR1_SRC_SHIFT, rt5663_alg_dacr_src);
2006
2007static const struct snd_kcontrol_new rt5663_alg_dacr_mux =
2008 SOC_DAPM_ENUM("DAC R Mux", rt5663_alg_dacr_enum);
2009
2010static int rt5663_hp_event(struct snd_soc_dapm_widget *w,
2011 struct snd_kcontrol *kcontrol, int event)
2012{
2013 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
2014 struct rt5663_priv *rt5663 = snd_soc_codec_get_drvdata(codec);
2015
2016 switch (event) {
2017 case SND_SOC_DAPM_POST_PMU:
2018 if (rt5663->codec_type == CODEC_TYPE_RT5668) {
2019 snd_soc_update_bits(codec, RT5663_HP_CHARGE_PUMP_1,
2020 RT5668_SEL_PM_HP_SHIFT, RT5668_SEL_PM_HP_HIGH);
2021 snd_soc_update_bits(codec, RT5663_HP_LOGIC_2,
2022 RT5668_HP_SIG_SRC1_MASK,
2023 RT5668_HP_SIG_SRC1_SILENCE);
2024 } else {
2025 snd_soc_write(codec, RT5663_DEPOP_2, 0x3003);
2026 snd_soc_update_bits(codec, RT5663_DEPOP_1, 0x000b,
2027 0x000b);
2028 snd_soc_update_bits(codec, RT5663_DEPOP_1, 0x0030,
2029 0x0030);
2030 snd_soc_update_bits(codec, RT5663_HP_CHARGE_PUMP_1,
2031 RT5668_OVCD_HP_MASK, RT5668_OVCD_HP_DIS);
2032 snd_soc_write(codec, RT5663_HP_CHARGE_PUMP_2, 0x1371);
2033 snd_soc_write(codec, RT5663_HP_BIAS, 0xabba);
2034 snd_soc_write(codec, RT5663_CHARGE_PUMP_1, 0x2224);
2035 snd_soc_write(codec, RT5663_ANA_BIAS_CUR_1, 0x7766);
2036 snd_soc_write(codec, RT5663_HP_BIAS, 0xafaa);
2037 snd_soc_write(codec, RT5663_CHARGE_PUMP_2, 0x7777);
2038 snd_soc_update_bits(codec, RT5663_DEPOP_1, 0x3000,
2039 0x3000);
2040 }
2041 break;
2042
2043 case SND_SOC_DAPM_PRE_PMD:
2044 if (rt5663->codec_type == CODEC_TYPE_RT5668) {
2045 snd_soc_update_bits(codec, RT5663_HP_LOGIC_2,
2046 RT5668_HP_SIG_SRC1_MASK,
2047 RT5668_HP_SIG_SRC1_REG);
2048 } else {
2049 snd_soc_update_bits(codec, RT5663_DEPOP_1, 0x3000, 0x0);
2050 snd_soc_update_bits(codec, RT5663_HP_CHARGE_PUMP_1,
2051 RT5668_OVCD_HP_MASK, RT5668_OVCD_HP_EN);
2052 snd_soc_update_bits(codec, RT5663_DEPOP_1, 0x0030, 0x0);
2053 snd_soc_update_bits(codec, RT5663_DEPOP_1, 0x000b,
2054 0x000b);
2055 }
2056 break;
2057
2058 default:
2059 return 0;
2060 }
2061
2062 return 0;
2063}
2064
2065static int rt5668_bst2_power(struct snd_soc_dapm_widget *w,
2066 struct snd_kcontrol *kcontrol, int event)
2067{
2068 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
2069
2070 switch (event) {
2071 case SND_SOC_DAPM_POST_PMU:
2072 snd_soc_update_bits(codec, RT5663_PWR_ANLG_2,
2073 RT5668_PWR_BST2_MASK | RT5668_PWR_BST2_OP_MASK,
2074 RT5668_PWR_BST2 | RT5668_PWR_BST2_OP);
2075 break;
2076
2077 case SND_SOC_DAPM_PRE_PMD:
2078 snd_soc_update_bits(codec, RT5663_PWR_ANLG_2,
2079 RT5668_PWR_BST2_MASK | RT5668_PWR_BST2_OP_MASK, 0);
2080 break;
2081
2082 default:
2083 return 0;
2084 }
2085
2086 return 0;
2087}
2088
2089static int rt5663_pre_div_power(struct snd_soc_dapm_widget *w,
2090 struct snd_kcontrol *kcontrol, int event)
2091{
2092 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
2093
2094 switch (event) {
2095 case SND_SOC_DAPM_POST_PMU:
2096 snd_soc_write(codec, RT5663_PRE_DIV_GATING_1, 0xff00);
2097 snd_soc_write(codec, RT5663_PRE_DIV_GATING_2, 0xfffc);
2098 break;
2099
2100 case SND_SOC_DAPM_PRE_PMD:
2101 snd_soc_write(codec, RT5663_PRE_DIV_GATING_1, 0x0000);
2102 snd_soc_write(codec, RT5663_PRE_DIV_GATING_2, 0x0000);
2103 break;
2104
2105 default:
2106 return 0;
2107 }
2108
2109 return 0;
2110}
2111
2112static const struct snd_soc_dapm_widget rt5663_dapm_widgets[] = {
2113 SND_SOC_DAPM_SUPPLY("PLL", RT5663_PWR_ANLG_3, RT5668_PWR_PLL_SHIFT, 0,
2114 NULL, 0),
2115
2116 /* micbias */
2117 SND_SOC_DAPM_MICBIAS("MICBIAS1", RT5663_PWR_ANLG_2,
2118 RT5668_PWR_MB1_SHIFT, 0),
2119 SND_SOC_DAPM_MICBIAS("MICBIAS2", RT5663_PWR_ANLG_2,
2120 RT5668_PWR_MB2_SHIFT, 0),
2121
2122 /* Input Lines */
2123 SND_SOC_DAPM_INPUT("IN1P"),
2124 SND_SOC_DAPM_INPUT("IN1N"),
2125
2126 /* REC Mixer Power */
2127 SND_SOC_DAPM_SUPPLY("RECMIX1L Power", RT5663_PWR_ANLG_2,
2128 RT5668_PWR_RECMIX1_SHIFT, 0, NULL, 0),
2129
2130 /* ADCs */
2131 SND_SOC_DAPM_ADC("ADC L", NULL, SND_SOC_NOPM, 0, 0),
2132 SND_SOC_DAPM_SUPPLY("ADC L Power", RT5663_PWR_DIG_1,
2133 RT5668_PWR_ADC_L1_SHIFT, 0, NULL, 0),
2134 SND_SOC_DAPM_SUPPLY("ADC Clock", RT5663_CHOP_ADC,
2135 RT5668_CKGEN_ADCC_SHIFT, 0, NULL, 0),
2136
2137 /* ADC Mixer */
2138 SND_SOC_DAPM_MIXER("STO1 ADC MIXL", SND_SOC_NOPM,
2139 0, 0, rt5663_sto1_adc_l_mix,
2140 ARRAY_SIZE(rt5663_sto1_adc_l_mix)),
2141
2142 /* ADC Filter Power */
2143 SND_SOC_DAPM_SUPPLY("STO1 ADC Filter", RT5663_PWR_DIG_2,
2144 RT5668_PWR_ADC_S1F_SHIFT, 0, NULL, 0),
2145
2146 /* Digital Interface */
2147 SND_SOC_DAPM_SUPPLY("I2S", RT5663_PWR_DIG_1, RT5668_PWR_I2S1_SHIFT, 0,
2148 NULL, 0),
2149 SND_SOC_DAPM_PGA("IF DAC", SND_SOC_NOPM, 0, 0, NULL, 0),
2150 SND_SOC_DAPM_PGA("IF1 DAC1 L", SND_SOC_NOPM, 0, 0, NULL, 0),
2151 SND_SOC_DAPM_PGA("IF1 DAC1 R", SND_SOC_NOPM, 0, 0, NULL, 0),
2152 SND_SOC_DAPM_PGA("IF1 ADC1", SND_SOC_NOPM, 0, 0, NULL, 0),
2153 SND_SOC_DAPM_PGA("IF ADC", SND_SOC_NOPM, 0, 0, NULL, 0),
2154
2155 /* Audio Interface */
2156 SND_SOC_DAPM_AIF_IN("AIFRX", "AIF Playback", 0, SND_SOC_NOPM, 0, 0),
2157 SND_SOC_DAPM_AIF_OUT("AIFTX", "AIF Capture", 0, SND_SOC_NOPM, 0, 0),
2158
2159 /* DAC mixer before sound effect */
2160 SND_SOC_DAPM_MIXER("ADDA MIXL", SND_SOC_NOPM, 0, 0, rt5663_adda_l_mix,
2161 ARRAY_SIZE(rt5663_adda_l_mix)),
2162 SND_SOC_DAPM_MIXER("ADDA MIXR", SND_SOC_NOPM, 0, 0, rt5663_adda_r_mix,
2163 ARRAY_SIZE(rt5663_adda_r_mix)),
2164 SND_SOC_DAPM_PGA("DAC L1", SND_SOC_NOPM, 0, 0, NULL, 0),
2165 SND_SOC_DAPM_PGA("DAC R1", SND_SOC_NOPM, 0, 0, NULL, 0),
2166
2167 /* DAC Mixer */
2168 SND_SOC_DAPM_SUPPLY("STO1 DAC Filter", RT5663_PWR_DIG_2,
2169 RT5668_PWR_DAC_S1F_SHIFT, 0, NULL, 0),
2170 SND_SOC_DAPM_MIXER("STO1 DAC MIXL", SND_SOC_NOPM, 0, 0,
2171 rt5663_sto1_dac_l_mix, ARRAY_SIZE(rt5663_sto1_dac_l_mix)),
2172 SND_SOC_DAPM_MIXER("STO1 DAC MIXR", SND_SOC_NOPM, 0, 0,
2173 rt5663_sto1_dac_r_mix, ARRAY_SIZE(rt5663_sto1_dac_r_mix)),
2174
2175 /* DACs */
2176 SND_SOC_DAPM_SUPPLY("STO1 DAC L Power", RT5663_PWR_DIG_1,
2177 RT5668_PWR_DAC_L1_SHIFT, 0, NULL, 0),
2178 SND_SOC_DAPM_SUPPLY("STO1 DAC R Power", RT5663_PWR_DIG_1,
2179 RT5668_PWR_DAC_R1_SHIFT, 0, NULL, 0),
2180 SND_SOC_DAPM_DAC("DAC L", NULL, SND_SOC_NOPM, 0, 0),
2181 SND_SOC_DAPM_DAC("DAC R", NULL, SND_SOC_NOPM, 0, 0),
2182
2183 /* Headphone*/
2184 SND_SOC_DAPM_PGA_S("HP Amp", 1, SND_SOC_NOPM, 0, 0, rt5663_hp_event,
2185 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
2186
2187 /* Output Lines */
2188 SND_SOC_DAPM_OUTPUT("HPOL"),
2189 SND_SOC_DAPM_OUTPUT("HPOR"),
2190};
2191
2192static const struct snd_soc_dapm_widget rt5668_specific_dapm_widgets[] = {
2193 SND_SOC_DAPM_SUPPLY("LDO2", RT5663_PWR_ANLG_3,
2194 RT5668_PWR_LDO2_SHIFT, 0, NULL, 0),
2195 SND_SOC_DAPM_SUPPLY("Mic Det Power", RT5668_PWR_VOL,
2196 RT5668_PWR_MIC_DET_SHIFT, 0, NULL, 0),
2197 SND_SOC_DAPM_SUPPLY("LDO DAC", RT5663_PWR_DIG_1,
2198 RT5668_PWR_LDO_DACREF_SHIFT, 0, NULL, 0),
2199
2200 /* ASRC */
2201 SND_SOC_DAPM_SUPPLY("I2S ASRC", RT5663_ASRC_1,
2202 RT5668_I2S1_ASRC_SHIFT, 0, NULL, 0),
2203 SND_SOC_DAPM_SUPPLY("DAC ASRC", RT5663_ASRC_1,
2204 RT5668_DAC_STO1_ASRC_SHIFT, 0, NULL, 0),
2205 SND_SOC_DAPM_SUPPLY("ADC ASRC", RT5663_ASRC_1,
2206 RT5668_ADC_STO1_ASRC_SHIFT, 0, NULL, 0),
2207
2208 /* Input Lines */
2209 SND_SOC_DAPM_INPUT("IN2P"),
2210 SND_SOC_DAPM_INPUT("IN2N"),
2211
2212 /* Boost */
2213 SND_SOC_DAPM_PGA("BST1 CBJ", SND_SOC_NOPM, 0, 0, NULL, 0),
2214 SND_SOC_DAPM_SUPPLY("CBJ Power", RT5663_PWR_ANLG_3,
2215 RT5668_PWR_CBJ_SHIFT, 0, NULL, 0),
2216 SND_SOC_DAPM_PGA("BST2", SND_SOC_NOPM, 0, 0, NULL, 0),
2217 SND_SOC_DAPM_SUPPLY("BST2 Power", SND_SOC_NOPM, 0, 0,
2218 rt5668_bst2_power, SND_SOC_DAPM_PRE_PMD |
2219 SND_SOC_DAPM_POST_PMU),
2220
2221 /* REC Mixer */
2222 SND_SOC_DAPM_MIXER("RECMIX1L", SND_SOC_NOPM, 0, 0, rt5668_recmix1l,
2223 ARRAY_SIZE(rt5668_recmix1l)),
2224 SND_SOC_DAPM_MIXER("RECMIX1R", SND_SOC_NOPM, 0, 0, rt5668_recmix1r,
2225 ARRAY_SIZE(rt5668_recmix1r)),
2226 SND_SOC_DAPM_SUPPLY("RECMIX1R Power", RT5663_PWR_ANLG_2,
2227 RT5668_PWR_RECMIX2_SHIFT, 0, NULL, 0),
2228
2229 /* ADC */
2230 SND_SOC_DAPM_ADC("ADC R", NULL, SND_SOC_NOPM, 0, 0),
2231 SND_SOC_DAPM_SUPPLY("ADC R Power", RT5663_PWR_DIG_1,
2232 RT5668_PWR_ADC_R1_SHIFT, 0, NULL, 0),
2233
2234 /* ADC Mux */
2235 SND_SOC_DAPM_PGA("STO1 ADC L1", RT5663_STO1_ADC_MIXER,
2236 RT5668_STO1_ADC_L1_SRC_SHIFT, 0, NULL, 0),
2237 SND_SOC_DAPM_PGA("STO1 ADC R1", RT5663_STO1_ADC_MIXER,
2238 RT5668_STO1_ADC_R1_SRC_SHIFT, 0, NULL, 0),
2239 SND_SOC_DAPM_PGA("STO1 ADC L2", RT5663_STO1_ADC_MIXER,
2240 RT5668_STO1_ADC_L2_SRC_SHIFT, 1, NULL, 0),
2241 SND_SOC_DAPM_PGA("STO1 ADC R2", RT5663_STO1_ADC_MIXER,
2242 RT5668_STO1_ADC_R2_SRC_SHIFT, 1, NULL, 0),
2243
2244 SND_SOC_DAPM_MUX("STO1 ADC L Mux", SND_SOC_NOPM, 0, 0,
2245 &rt5668_sto1_adcl_mux),
2246 SND_SOC_DAPM_MUX("STO1 ADC R Mux", SND_SOC_NOPM, 0, 0,
2247 &rt5668_sto1_adcr_mux),
2248
2249 /* ADC Mix */
2250 SND_SOC_DAPM_MIXER("STO1 ADC MIXR", SND_SOC_NOPM, 0, 0,
2251 rt5668_sto1_adc_r_mix, ARRAY_SIZE(rt5668_sto1_adc_r_mix)),
2252
2253 /* Analog DAC Clock */
2254 SND_SOC_DAPM_SUPPLY("DAC Clock", RT5663_CHOP_DAC_L,
2255 RT5668_CKGEN_DAC1_SHIFT, 0, NULL, 0),
2256
2257 /* Headphone out */
2258 SND_SOC_DAPM_SWITCH("HPO Playback", SND_SOC_NOPM, 0, 0,
2259 &rt5668_hpo_switch),
2260};
2261
2262static const struct snd_soc_dapm_widget rt5663_specific_dapm_widgets[] = {
2263 /* System Clock Pre Divider Gating */
2264 SND_SOC_DAPM_SUPPLY("Pre Div Power", SND_SOC_NOPM, 0, 0,
2265 rt5663_pre_div_power, SND_SOC_DAPM_POST_PMU |
2266 SND_SOC_DAPM_PRE_PMD),
2267
2268 /* LDO */
2269 SND_SOC_DAPM_SUPPLY("LDO ADC", RT5663_PWR_DIG_1,
2270 RT5668_PWR_LDO_DACREF_SHIFT, 0, NULL, 0),
2271
2272 /* ASRC */
2273 SND_SOC_DAPM_SUPPLY("I2S ASRC", RT5663_ASRC_1,
2274 RT5663_I2S1_ASRC_SHIFT, 0, NULL, 0),
2275 SND_SOC_DAPM_SUPPLY("DAC ASRC", RT5663_ASRC_1,
2276 RT5663_DAC_STO1_ASRC_SHIFT, 0, NULL, 0),
2277 SND_SOC_DAPM_SUPPLY("ADC ASRC", RT5663_ASRC_1,
2278 RT5663_ADC_STO1_ASRC_SHIFT, 0, NULL, 0),
2279
2280 /* Boost */
2281 SND_SOC_DAPM_PGA("BST1", SND_SOC_NOPM, 0, 0, NULL, 0),
2282
2283 /* STO ADC */
2284 SND_SOC_DAPM_PGA("STO1 ADC L1", SND_SOC_NOPM, 0, 0, NULL, 0),
2285 SND_SOC_DAPM_PGA("STO1 ADC L2", SND_SOC_NOPM, 0, 0, NULL, 0),
2286
2287 /* Analog DAC source */
2288 SND_SOC_DAPM_MUX("DAC L Mux", SND_SOC_NOPM, 0, 0, &rt5663_alg_dacl_mux),
2289 SND_SOC_DAPM_MUX("DAC R Mux", SND_SOC_NOPM, 0, 0, &rt5663_alg_dacr_mux),
2290};
2291
2292static const struct snd_soc_dapm_route rt5663_dapm_routes[] = {
2293 /* PLL */
2294 { "I2S", NULL, "PLL", rt5663_is_sys_clk_from_pll },
2295
2296 /* ASRC */
2297 { "STO1 ADC Filter", NULL, "ADC ASRC", rt5663_is_using_asrc },
2298 { "STO1 DAC Filter", NULL, "DAC ASRC", rt5663_is_using_asrc },
2299 { "I2S", NULL, "I2S ASRC", rt5663_i2s_use_asrc },
2300
2301 { "ADC L", NULL, "ADC L Power" },
2302 { "ADC L", NULL, "ADC Clock" },
2303
2304 { "STO1 ADC L2", NULL, "STO1 DAC MIXL" },
2305
2306 { "STO1 ADC MIXL", "ADC1 Switch", "STO1 ADC L1" },
2307 { "STO1 ADC MIXL", "ADC2 Switch", "STO1 ADC L2" },
2308 { "STO1 ADC MIXL", NULL, "STO1 ADC Filter" },
2309
2310 { "IF1 ADC1", NULL, "STO1 ADC MIXL" },
2311 { "IF ADC", NULL, "IF1 ADC1" },
2312 { "AIFTX", NULL, "IF ADC" },
2313 { "AIFTX", NULL, "I2S" },
2314
2315 { "AIFRX", NULL, "I2S" },
2316 { "IF DAC", NULL, "AIFRX" },
2317 { "IF1 DAC1 L", NULL, "IF DAC" },
2318 { "IF1 DAC1 R", NULL, "IF DAC" },
2319
2320 { "ADDA MIXL", "ADC L Switch", "STO1 ADC MIXL" },
2321 { "ADDA MIXL", "DAC L Switch", "IF1 DAC1 L" },
2322 { "ADDA MIXL", NULL, "STO1 DAC Filter" },
2323 { "ADDA MIXL", NULL, "STO1 DAC L Power" },
2324 { "ADDA MIXR", "DAC R Switch", "IF1 DAC1 R" },
2325 { "ADDA MIXR", NULL, "STO1 DAC Filter" },
2326 { "ADDA MIXR", NULL, "STO1 DAC R Power" },
2327
2328 { "DAC L1", NULL, "ADDA MIXL" },
2329 { "DAC R1", NULL, "ADDA MIXR" },
2330
2331 { "STO1 DAC MIXL", "DAC L Switch", "DAC L1" },
2332 { "STO1 DAC MIXL", "DAC R Switch", "DAC R1" },
2333 { "STO1 DAC MIXL", NULL, "STO1 DAC L Power" },
2334 { "STO1 DAC MIXL", NULL, "STO1 DAC Filter" },
2335 { "STO1 DAC MIXR", "DAC R Switch", "DAC R1" },
2336 { "STO1 DAC MIXR", "DAC L Switch", "DAC L1" },
2337 { "STO1 DAC MIXR", NULL, "STO1 DAC R Power" },
2338 { "STO1 DAC MIXR", NULL, "STO1 DAC Filter" },
2339
2340 { "HP Amp", NULL, "DAC L" },
2341 { "HP Amp", NULL, "DAC R" },
2342};
2343
2344static const struct snd_soc_dapm_route rt5668_specific_dapm_routes[] = {
2345 { "MICBIAS1", NULL, "LDO2" },
2346 { "MICBIAS2", NULL, "LDO2" },
2347
2348 { "BST1 CBJ", NULL, "IN1P" },
2349 { "BST1 CBJ", NULL, "IN1N" },
2350 { "BST1 CBJ", NULL, "CBJ Power" },
2351
2352 { "BST2", NULL, "IN2P" },
2353 { "BST2", NULL, "IN2N" },
2354 { "BST2", NULL, "BST2 Power" },
2355
2356 { "RECMIX1L", "BST2 Switch", "BST2" },
2357 { "RECMIX1L", "BST1 CBJ Switch", "BST1 CBJ" },
2358 { "RECMIX1L", NULL, "RECMIX1L Power" },
2359 { "RECMIX1R", "BST2 Switch", "BST2" },
2360 { "RECMIX1R", NULL, "RECMIX1R Power" },
2361
2362 { "ADC L", NULL, "RECMIX1L" },
2363 { "ADC R", NULL, "RECMIX1R" },
2364 { "ADC R", NULL, "ADC R Power" },
2365 { "ADC R", NULL, "ADC Clock" },
2366
2367 { "STO1 ADC L Mux", "ADC L", "ADC L" },
2368 { "STO1 ADC L Mux", "ADC R", "ADC R" },
2369 { "STO1 ADC L1", NULL, "STO1 ADC L Mux" },
2370
2371 { "STO1 ADC R Mux", "ADC L", "ADC L" },
2372 { "STO1 ADC R Mux", "ADC R", "ADC R" },
2373 { "STO1 ADC R1", NULL, "STO1 ADC R Mux" },
2374 { "STO1 ADC R2", NULL, "STO1 DAC MIXR" },
2375
2376 { "STO1 ADC MIXR", "ADC1 Switch", "STO1 ADC R1" },
2377 { "STO1 ADC MIXR", "ADC2 Switch", "STO1 ADC R2" },
2378 { "STO1 ADC MIXR", NULL, "STO1 ADC Filter" },
2379
2380 { "IF1 ADC1", NULL, "STO1 ADC MIXR" },
2381
2382 { "ADDA MIXR", "ADC R Switch", "STO1 ADC MIXR" },
2383
2384 { "DAC L", NULL, "STO1 DAC MIXL" },
2385 { "DAC L", NULL, "LDO DAC" },
2386 { "DAC L", NULL, "DAC Clock" },
2387 { "DAC R", NULL, "STO1 DAC MIXR" },
2388 { "DAC R", NULL, "LDO DAC" },
2389 { "DAC R", NULL, "DAC Clock" },
2390
2391 { "HPO Playback", "Switch", "HP Amp" },
2392 { "HPOL", NULL, "HPO Playback" },
2393 { "HPOR", NULL, "HPO Playback" },
2394};
2395
2396static const struct snd_soc_dapm_route rt5663_specific_dapm_routes[] = {
2397 { "I2S", NULL, "Pre Div Power" },
2398
2399 { "BST1", NULL, "IN1P" },
2400 { "BST1", NULL, "IN1N" },
2401 { "BST1", NULL, "RECMIX1L Power" },
2402
2403 { "ADC L", NULL, "BST1" },
2404
2405 { "STO1 ADC L1", NULL, "ADC L" },
2406
2407 { "DAC L Mux", "DAC L", "DAC L1" },
2408 { "DAC L Mux", "STO DAC MIXL", "STO1 DAC MIXL" },
2409 { "DAC R Mux", "DAC R", "DAC R1"},
2410 { "DAC R Mux", "STO DAC MIXR", "STO1 DAC MIXR" },
2411
2412 { "DAC L", NULL, "DAC L Mux" },
2413 { "DAC R", NULL, "DAC R Mux" },
2414
2415 { "HPOL", NULL, "HP Amp" },
2416 { "HPOR", NULL, "HP Amp" },
2417};
2418
2419static int rt5663_hw_params(struct snd_pcm_substream *substream,
2420 struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
2421{
2422 struct snd_soc_codec *codec = dai->codec;
2423 struct rt5663_priv *rt5663 = snd_soc_codec_get_drvdata(codec);
2424 unsigned int val_len = 0;
2425 int pre_div;
2426
2427 rt5663->lrck = params_rate(params);
2428
2429 dev_dbg(dai->dev, "bclk is %dHz and sysclk is %dHz\n",
2430 rt5663->lrck, rt5663->sysclk);
2431
2432 pre_div = rl6231_get_clk_info(rt5663->sysclk, rt5663->lrck);
2433 if (pre_div < 0) {
2434 dev_err(codec->dev, "Unsupported clock setting %d for DAI %d\n",
2435 rt5663->lrck, dai->id);
2436 return -EINVAL;
2437 }
2438
2439 dev_dbg(dai->dev, "pre_div is %d for iis %d\n", pre_div, dai->id);
2440
2441 switch (params_width(params)) {
2442 case 8:
2443 val_len = RT5668_I2S_DL_8;
2444 break;
2445 case 16:
2446 val_len = RT5668_I2S_DL_16;
2447 break;
2448 case 20:
2449 val_len = RT5668_I2S_DL_20;
2450 break;
2451 case 24:
2452 val_len = RT5668_I2S_DL_24;
2453 break;
2454 default:
2455 return -EINVAL;
2456 }
2457
2458 snd_soc_update_bits(codec, RT5663_I2S1_SDP,
2459 RT5668_I2S_DL_MASK, val_len);
2460
2461 snd_soc_update_bits(codec, RT5663_ADDA_CLK_1,
2462 RT5668_I2S_PD1_MASK, pre_div << RT5668_I2S_PD1_SHIFT);
2463
2464 return 0;
2465}
2466
2467static int rt5663_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
2468{
2469 struct snd_soc_codec *codec = dai->codec;
2470 unsigned int reg_val = 0;
2471
2472 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
2473 case SND_SOC_DAIFMT_CBM_CFM:
2474 break;
2475 case SND_SOC_DAIFMT_CBS_CFS:
2476 reg_val |= RT5668_I2S_MS_S;
2477 break;
2478 default:
2479 return -EINVAL;
2480 }
2481
2482 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
2483 case SND_SOC_DAIFMT_NB_NF:
2484 break;
2485 case SND_SOC_DAIFMT_IB_NF:
2486 reg_val |= RT5668_I2S_BP_INV;
2487 break;
2488 default:
2489 return -EINVAL;
2490 }
2491
2492 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
2493 case SND_SOC_DAIFMT_I2S:
2494 break;
2495 case SND_SOC_DAIFMT_LEFT_J:
2496 reg_val |= RT5668_I2S_DF_LEFT;
2497 break;
2498 case SND_SOC_DAIFMT_DSP_A:
2499 reg_val |= RT5668_I2S_DF_PCM_A;
2500 break;
2501 case SND_SOC_DAIFMT_DSP_B:
2502 reg_val |= RT5668_I2S_DF_PCM_B;
2503 break;
2504 default:
2505 return -EINVAL;
2506 }
2507
2508 snd_soc_update_bits(codec, RT5663_I2S1_SDP, RT5668_I2S_MS_MASK |
2509 RT5668_I2S_BP_MASK | RT5668_I2S_DF_MASK, reg_val);
2510
2511 return 0;
2512}
2513
2514static int rt5663_set_dai_sysclk(struct snd_soc_dai *dai, int clk_id,
2515 unsigned int freq, int dir)
2516{
2517 struct snd_soc_codec *codec = dai->codec;
2518 struct rt5663_priv *rt5663 = snd_soc_codec_get_drvdata(codec);
2519 unsigned int reg_val = 0;
2520
2521 if (freq == rt5663->sysclk && clk_id == rt5663->sysclk_src)
2522 return 0;
2523
2524 switch (clk_id) {
2525 case RT5663_SCLK_S_MCLK:
2526 reg_val |= RT5663_SCLK_SRC_MCLK;
2527 break;
2528 case RT5663_SCLK_S_PLL1:
2529 reg_val |= RT5663_SCLK_SRC_PLL1;
2530 break;
2531 case RT5663_SCLK_S_RCCLK:
2532 reg_val |= RT5663_SCLK_SRC_RCCLK;
2533 break;
2534 default:
2535 dev_err(codec->dev, "Invalid clock id (%d)\n", clk_id);
2536 return -EINVAL;
2537 }
2538 snd_soc_update_bits(codec, RT5663_GLB_CLK, RT5668_SCLK_SRC_MASK,
2539 reg_val);
2540 rt5663->sysclk = freq;
2541 rt5663->sysclk_src = clk_id;
2542
2543 dev_dbg(codec->dev, "Sysclk is %dHz and clock id is %d\n",
2544 freq, clk_id);
2545
2546 return 0;
2547}
2548
2549static int rt5663_set_dai_pll(struct snd_soc_dai *dai, int pll_id, int source,
2550 unsigned int freq_in, unsigned int freq_out)
2551{
2552 struct snd_soc_codec *codec = dai->codec;
2553 struct rt5663_priv *rt5663 = snd_soc_codec_get_drvdata(codec);
2554 struct rl6231_pll_code pll_code;
2555 int ret;
2556 int mask, shift, val;
2557
2558 if (source == rt5663->pll_src && freq_in == rt5663->pll_in &&
2559 freq_out == rt5663->pll_out)
2560 return 0;
2561
2562 if (!freq_in || !freq_out) {
2563 dev_dbg(codec->dev, "PLL disabled\n");
2564
2565 rt5663->pll_in = 0;
2566 rt5663->pll_out = 0;
2567 snd_soc_update_bits(codec, RT5663_GLB_CLK,
2568 RT5663_SCLK_SRC_MASK, RT5663_SCLK_SRC_MCLK);
2569 return 0;
2570 }
2571
2572 switch (rt5663->codec_type) {
2573 case CODEC_TYPE_RT5668:
2574 mask = RT5668_PLL1_SRC_MASK;
2575 shift = RT5668_PLL1_SRC_SHIFT;
2576 break;
2577 case CODEC_TYPE_RT5663:
2578 mask = RT5663_PLL1_SRC_MASK;
2579 shift = RT5663_PLL1_SRC_SHIFT;
2580 break;
2581 default:
2582 dev_err(codec->dev, "Unknown CODEC_TYPE\n");
2583 return -EINVAL;
2584 }
2585
2586 switch (source) {
2587 case RT5663_PLL1_S_MCLK:
2588 val = 0x0;
2589 break;
2590 case RT5663_PLL1_S_BCLK1:
2591 val = 0x1;
2592 break;
2593 default:
2594 dev_err(codec->dev, "Unknown PLL source %d\n", source);
2595 return -EINVAL;
2596 }
2597 snd_soc_update_bits(codec, RT5663_GLB_CLK, mask, (val << shift));
2598
2599 ret = rl6231_pll_calc(freq_in, freq_out, &pll_code);
2600 if (ret < 0) {
2601 dev_err(codec->dev, "Unsupport input clock %d\n", freq_in);
2602 return ret;
2603 }
2604
2605 dev_dbg(codec->dev, "bypass=%d m=%d n=%d k=%d\n", pll_code.m_bp,
2606 (pll_code.m_bp ? 0 : pll_code.m_code), pll_code.n_code,
2607 pll_code.k_code);
2608
2609 snd_soc_write(codec, RT5663_PLL_1,
2610 pll_code.n_code << RT5668_PLL_N_SHIFT | pll_code.k_code);
2611 snd_soc_write(codec, RT5663_PLL_2,
2612 (pll_code.m_bp ? 0 : pll_code.m_code) << RT5668_PLL_M_SHIFT |
2613 pll_code.m_bp << RT5668_PLL_M_BP_SHIFT);
2614
2615 rt5663->pll_in = freq_in;
2616 rt5663->pll_out = freq_out;
2617 rt5663->pll_src = source;
2618
2619 return 0;
2620}
2621
2622static int rt5663_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
2623 unsigned int rx_mask, int slots, int slot_width)
2624{
2625 struct snd_soc_codec *codec = dai->codec;
2626 struct rt5663_priv *rt5663 = snd_soc_codec_get_drvdata(codec);
2627 unsigned int val = 0, reg;
2628
2629 if (rx_mask || tx_mask)
2630 val |= RT5668_TDM_MODE_TDM;
2631
2632 switch (slots) {
2633 case 4:
2634 val |= RT5668_TDM_IN_CH_4;
2635 val |= RT5668_TDM_OUT_CH_4;
2636 break;
2637 case 6:
2638 val |= RT5668_TDM_IN_CH_6;
2639 val |= RT5668_TDM_OUT_CH_6;
2640 break;
2641 case 8:
2642 val |= RT5668_TDM_IN_CH_8;
2643 val |= RT5668_TDM_OUT_CH_8;
2644 break;
2645 case 2:
2646 break;
2647 default:
2648 return -EINVAL;
2649 }
2650
2651 switch (slot_width) {
2652 case 20:
2653 val |= RT5668_TDM_IN_LEN_20;
2654 val |= RT5668_TDM_OUT_LEN_20;
2655 break;
2656 case 24:
2657 val |= RT5668_TDM_IN_LEN_24;
2658 val |= RT5668_TDM_OUT_LEN_24;
2659 break;
2660 case 32:
2661 val |= RT5668_TDM_IN_LEN_32;
2662 val |= RT5668_TDM_OUT_LEN_32;
2663 break;
2664 case 16:
2665 break;
2666 default:
2667 return -EINVAL;
2668 }
2669
2670 switch (rt5663->codec_type) {
2671 case CODEC_TYPE_RT5668:
2672 reg = RT5663_TDM_2;
2673 break;
2674 case CODEC_TYPE_RT5663:
2675 reg = RT5663_TDM_1;
2676 break;
2677 default:
2678 dev_err(codec->dev, "Unknown CODEC_TYPE\n");
2679 return -EINVAL;
2680 }
2681
2682 snd_soc_update_bits(codec, reg, RT5668_TDM_MODE_MASK |
2683 RT5668_TDM_IN_CH_MASK | RT5668_TDM_OUT_CH_MASK |
2684 RT5668_TDM_IN_LEN_MASK | RT5668_TDM_OUT_LEN_MASK, val);
2685
2686 return 0;
2687}
2688
2689static int rt5663_set_bclk_ratio(struct snd_soc_dai *dai, unsigned int ratio)
2690{
2691 struct snd_soc_codec *codec = dai->codec;
2692 struct rt5663_priv *rt5663 = snd_soc_codec_get_drvdata(codec);
2693 unsigned int reg;
2694
2695 dev_dbg(codec->dev, "%s ratio = %d\n", __func__, ratio);
2696
2697 if (rt5663->codec_type == CODEC_TYPE_RT5668)
2698 reg = RT5668_TDM_8;
2699 else
2700 reg = RT5663_TDM_5;
2701
2702 switch (ratio) {
2703 case 32:
2704 snd_soc_update_bits(codec, reg,
2705 RT5663_TDM_LENGTN_MASK,
2706 RT5663_TDM_LENGTN_16);
2707 break;
2708 case 40:
2709 snd_soc_update_bits(codec, reg,
2710 RT5663_TDM_LENGTN_MASK,
2711 RT5663_TDM_LENGTN_20);
2712 break;
2713 case 48:
2714 snd_soc_update_bits(codec, reg,
2715 RT5663_TDM_LENGTN_MASK,
2716 RT5663_TDM_LENGTN_24);
2717 break;
2718 case 64:
2719 snd_soc_update_bits(codec, reg,
2720 RT5663_TDM_LENGTN_MASK,
2721 RT5663_TDM_LENGTN_32);
2722 break;
2723 default:
2724 dev_err(codec->dev, "Invalid ratio!\n");
2725 return -EINVAL;
2726 }
2727
2728 return 0;
2729}
2730
2731static int rt5663_set_bias_level(struct snd_soc_codec *codec,
2732 enum snd_soc_bias_level level)
2733{
2734 struct rt5663_priv *rt5663 = snd_soc_codec_get_drvdata(codec);
2735
2736 switch (level) {
2737 case SND_SOC_BIAS_ON:
2738 snd_soc_update_bits(codec, RT5663_PWR_ANLG_1,
2739 RT5668_PWR_FV1_MASK | RT5668_PWR_FV2_MASK,
2740 RT5668_PWR_FV1 | RT5668_PWR_FV2);
2741 break;
2742
2743 case SND_SOC_BIAS_PREPARE:
2744 if (rt5663->codec_type == CODEC_TYPE_RT5668) {
2745 snd_soc_update_bits(codec, RT5663_DIG_MISC,
2746 RT5668_DIG_GATE_CTRL_MASK,
2747 RT5668_DIG_GATE_CTRL_EN);
2748 snd_soc_update_bits(codec, RT5663_SIG_CLK_DET,
2749 RT5668_EN_ANA_CLK_DET_MASK |
2750 RT5668_PWR_CLK_DET_MASK,
2751 RT5668_EN_ANA_CLK_DET_AUTO |
2752 RT5668_PWR_CLK_DET_EN);
2753 }
2754 break;
2755
2756 case SND_SOC_BIAS_STANDBY:
2757 if (rt5663->codec_type == CODEC_TYPE_RT5668)
2758 snd_soc_update_bits(codec, RT5663_DIG_MISC,
2759 RT5668_DIG_GATE_CTRL_MASK,
2760 RT5668_DIG_GATE_CTRL_DIS);
2761 snd_soc_update_bits(codec, RT5663_PWR_ANLG_1,
2762 RT5668_PWR_VREF1_MASK | RT5668_PWR_VREF2_MASK |
2763 RT5668_PWR_FV1_MASK | RT5668_PWR_FV2_MASK |
2764 RT5668_PWR_MB_MASK, RT5668_PWR_VREF1 |
2765 RT5668_PWR_VREF2 | RT5668_PWR_MB);
2766 usleep_range(10000, 10005);
2767 if (rt5663->codec_type == CODEC_TYPE_RT5668) {
2768 snd_soc_update_bits(codec, RT5663_SIG_CLK_DET,
2769 RT5668_EN_ANA_CLK_DET_MASK |
2770 RT5668_PWR_CLK_DET_MASK,
2771 RT5668_EN_ANA_CLK_DET_DIS |
2772 RT5668_PWR_CLK_DET_DIS);
2773 }
2774 break;
2775
2776 case SND_SOC_BIAS_OFF:
2777 snd_soc_update_bits(codec, RT5663_PWR_ANLG_1,
2778 RT5668_PWR_VREF1_MASK | RT5668_PWR_VREF2_MASK |
2779 RT5668_PWR_FV1 | RT5668_PWR_FV2, 0x0);
2780 break;
2781
2782 default:
2783 break;
2784 }
2785
2786 return 0;
2787}
2788
2789static int rt5663_probe(struct snd_soc_codec *codec)
2790{
2791 struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
2792 struct rt5663_priv *rt5663 = snd_soc_codec_get_drvdata(codec);
2793
2794 rt5663->codec = codec;
2795
2796 switch (rt5663->codec_type) {
2797 case CODEC_TYPE_RT5668:
2798 snd_soc_dapm_new_controls(dapm,
2799 rt5668_specific_dapm_widgets,
2800 ARRAY_SIZE(rt5668_specific_dapm_widgets));
2801 snd_soc_dapm_add_routes(dapm,
2802 rt5668_specific_dapm_routes,
2803 ARRAY_SIZE(rt5668_specific_dapm_routes));
2804 snd_soc_add_codec_controls(codec, rt5668_specific_controls,
2805 ARRAY_SIZE(rt5668_specific_controls));
2806 break;
2807 case CODEC_TYPE_RT5663:
2808 snd_soc_dapm_new_controls(dapm,
2809 rt5663_specific_dapm_widgets,
2810 ARRAY_SIZE(rt5663_specific_dapm_widgets));
2811 snd_soc_dapm_add_routes(dapm,
2812 rt5663_specific_dapm_routes,
2813 ARRAY_SIZE(rt5663_specific_dapm_routes));
2814 snd_soc_add_codec_controls(codec, rt5663_specific_controls,
2815 ARRAY_SIZE(rt5663_specific_controls));
2816 break;
2817 }
2818
2819 return 0;
2820}
2821
2822static int rt5663_remove(struct snd_soc_codec *codec)
2823{
2824 struct rt5663_priv *rt5663 = snd_soc_codec_get_drvdata(codec);
2825
2826 regmap_write(rt5663->regmap, RT5663_RESET, 0);
2827
2828 return 0;
2829}
2830
2831#ifdef CONFIG_PM
2832static int rt5663_suspend(struct snd_soc_codec *codec)
2833{
2834 struct rt5663_priv *rt5663 = snd_soc_codec_get_drvdata(codec);
2835
2836 regcache_cache_only(rt5663->regmap, true);
2837 regcache_mark_dirty(rt5663->regmap);
2838
2839 return 0;
2840}
2841
2842static int rt5663_resume(struct snd_soc_codec *codec)
2843{
2844 struct rt5663_priv *rt5663 = snd_soc_codec_get_drvdata(codec);
2845
2846 regcache_cache_only(rt5663->regmap, false);
2847 regcache_sync(rt5663->regmap);
2848
2849 return 0;
2850}
2851#else
2852#define rt5663_suspend NULL
2853#define rt5663_resume NULL
2854#endif
2855
2856#define RT5663_STEREO_RATES SNDRV_PCM_RATE_8000_192000
2857#define RT5663_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \
2858 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S8)
2859
2860static struct snd_soc_dai_ops rt5663_aif_dai_ops = {
2861 .hw_params = rt5663_hw_params,
2862 .set_fmt = rt5663_set_dai_fmt,
2863 .set_sysclk = rt5663_set_dai_sysclk,
2864 .set_pll = rt5663_set_dai_pll,
2865 .set_tdm_slot = rt5663_set_tdm_slot,
2866 .set_bclk_ratio = rt5663_set_bclk_ratio,
2867};
2868
2869static struct snd_soc_dai_driver rt5663_dai[] = {
2870 {
2871 .name = "rt5663-aif",
2872 .id = RT5663_AIF,
2873 .playback = {
2874 .stream_name = "AIF Playback",
2875 .channels_min = 1,
2876 .channels_max = 2,
2877 .rates = RT5663_STEREO_RATES,
2878 .formats = RT5663_FORMATS,
2879 },
2880 .capture = {
2881 .stream_name = "AIF Capture",
2882 .channels_min = 1,
2883 .channels_max = 2,
2884 .rates = RT5663_STEREO_RATES,
2885 .formats = RT5663_FORMATS,
2886 },
2887 .ops = &rt5663_aif_dai_ops,
2888 },
2889};
2890
2891static struct snd_soc_codec_driver soc_codec_dev_rt5663 = {
2892 .probe = rt5663_probe,
2893 .remove = rt5663_remove,
2894 .suspend = rt5663_suspend,
2895 .resume = rt5663_resume,
2896 .set_bias_level = rt5663_set_bias_level,
2897 .idle_bias_off = true,
2898 .component_driver = {
2899 .controls = rt5663_snd_controls,
2900 .num_controls = ARRAY_SIZE(rt5663_snd_controls),
2901 .dapm_widgets = rt5663_dapm_widgets,
2902 .num_dapm_widgets = ARRAY_SIZE(rt5663_dapm_widgets),
2903 .dapm_routes = rt5663_dapm_routes,
2904 .num_dapm_routes = ARRAY_SIZE(rt5663_dapm_routes),
2905 }
2906};
2907
2908static const struct regmap_config rt5668_regmap = {
2909 .reg_bits = 16,
2910 .val_bits = 16,
2911 .use_single_rw = true,
2912 .max_register = 0x07fa,
2913 .volatile_reg = rt5668_volatile_register,
2914 .readable_reg = rt5668_readable_register,
2915 .cache_type = REGCACHE_RBTREE,
2916 .reg_defaults = rt5668_reg,
2917 .num_reg_defaults = ARRAY_SIZE(rt5668_reg),
2918};
2919
2920static const struct regmap_config rt5663_regmap = {
2921 .reg_bits = 16,
2922 .val_bits = 16,
2923 .use_single_rw = true,
2924 .max_register = 0x03f3,
2925 .volatile_reg = rt5663_volatile_register,
2926 .readable_reg = rt5663_readable_register,
2927 .cache_type = REGCACHE_RBTREE,
2928 .reg_defaults = rt5663_reg,
2929 .num_reg_defaults = ARRAY_SIZE(rt5663_reg),
2930};
2931
2932static const struct regmap_config temp_regmap = {
2933 .name = "nocache",
2934 .reg_bits = 16,
2935 .val_bits = 16,
2936 .use_single_rw = true,
2937 .max_register = 0x03f3,
2938 .cache_type = REGCACHE_NONE,
2939};
2940
2941static const struct i2c_device_id rt5663_i2c_id[] = {
2942 { "rt5668", 0 },
2943 { "rt5663", 0 },
2944 {}
2945};
2946MODULE_DEVICE_TABLE(i2c, rt5663_i2c_id);
2947
2948#if defined(CONFIG_OF)
2949static const struct of_device_id rt5663_of_match[] = {
2950 { .compatible = "realtek,rt5668", },
2951 { .compatible = "realtek,rt5663", },
2952 {},
2953};
2954MODULE_DEVICE_TABLE(of, rt5663_of_match);
2955#endif
2956
2957#ifdef CONFIG_ACPI
2958static struct acpi_device_id rt5663_acpi_match[] = {
2959 { "10EC5668", 0},
2960 { "10EC5663", 0},
2961 {},
2962};
2963MODULE_DEVICE_TABLE(acpi, rt5663_acpi_match);
2964#endif
2965
2966static void rt5668_calibrate(struct rt5663_priv *rt5668)
2967{
2968 regmap_write(rt5668->regmap, RT5663_BIAS_CUR_8, 0xa402);
2969 regmap_write(rt5668->regmap, RT5663_PWR_DIG_1, 0x0100);
2970 regmap_write(rt5668->regmap, RT5663_RECMIX, 0x4040);
2971 regmap_write(rt5668->regmap, RT5663_DIG_MISC, 0x0001);
2972 regmap_write(rt5668->regmap, RT5663_RC_CLK, 0x0380);
2973 regmap_write(rt5668->regmap, RT5663_GLB_CLK, 0x8000);
2974 regmap_write(rt5668->regmap, RT5663_ADDA_CLK_1, 0x1000);
2975 regmap_write(rt5668->regmap, RT5663_CHOP_DAC_L, 0x3030);
2976 regmap_write(rt5668->regmap, RT5663_CALIB_ADC, 0x3c05);
2977 regmap_write(rt5668->regmap, RT5663_PWR_ANLG_1, 0xa23e);
2978 msleep(40);
2979 regmap_write(rt5668->regmap, RT5663_PWR_ANLG_1, 0xf23e);
2980 regmap_write(rt5668->regmap, RT5663_HP_CALIB_2, 0x0321);
2981 regmap_write(rt5668->regmap, RT5663_HP_CALIB_1, 0xfc00);
2982 msleep(500);
2983}
2984
2985static void rt5663_calibrate(struct rt5663_priv *rt5668)
2986{
2987 int value, count;
2988
2989 regmap_write(rt5668->regmap, RT5663_RC_CLK, 0x0280);
2990 regmap_write(rt5668->regmap, RT5663_GLB_CLK, 0x8000);
2991 regmap_write(rt5668->regmap, RT5663_DIG_MISC, 0x8001);
2992 regmap_write(rt5668->regmap, RT5663_VREF_RECMIX, 0x0032);
2993 regmap_write(rt5668->regmap, RT5663_PWR_ANLG_1, 0xa2be);
2994 msleep(20);
2995 regmap_write(rt5668->regmap, RT5663_PWR_ANLG_1, 0xf2be);
2996 regmap_write(rt5668->regmap, RT5663_PWR_DIG_2, 0x8400);
2997 regmap_write(rt5668->regmap, RT5663_CHOP_ADC, 0x3000);
2998 regmap_write(rt5668->regmap, RT5663_DEPOP_1, 0x003b);
2999 regmap_write(rt5668->regmap, RT5663_PWR_DIG_1, 0x8df8);
3000 regmap_write(rt5668->regmap, RT5663_PWR_ANLG_2, 0x0003);
3001 regmap_write(rt5668->regmap, RT5663_PWR_ANLG_3, 0x018c);
3002 regmap_write(rt5668->regmap, RT5663_ADDA_CLK_1, 0x1111);
3003 regmap_write(rt5668->regmap, RT5663_PRE_DIV_GATING_1, 0xffff);
3004 regmap_write(rt5668->regmap, RT5663_PRE_DIV_GATING_2, 0xffff);
3005 regmap_write(rt5668->regmap, RT5663_DEPOP_2, 0x3003);
3006 regmap_write(rt5668->regmap, RT5663_DEPOP_1, 0x003b);
3007 regmap_write(rt5668->regmap, RT5663_HP_CHARGE_PUMP_1, 0x1e32);
3008 regmap_write(rt5668->regmap, RT5663_HP_CHARGE_PUMP_2, 0x1371);
3009 regmap_write(rt5668->regmap, RT5663_DACREF_LDO, 0x3b0b);
3010 regmap_write(rt5668->regmap, RT5663_STO_DAC_MIXER, 0x2080);
3011 regmap_write(rt5668->regmap, RT5663_BYPASS_STO_DAC, 0x000c);
3012 regmap_write(rt5668->regmap, RT5663_HP_BIAS, 0xabba);
3013 regmap_write(rt5668->regmap, RT5663_CHARGE_PUMP_1, 0x2224);
3014 regmap_write(rt5668->regmap, RT5663_HP_OUT_EN, 0x8088);
3015 regmap_write(rt5668->regmap, RT5663_STO_DRE_9, 0x0017);
3016 regmap_write(rt5668->regmap, RT5663_STO_DRE_10, 0x0017);
3017 regmap_write(rt5668->regmap, RT5663_STO1_ADC_MIXER, 0x4040);
3018 regmap_write(rt5668->regmap, RT5663_RECMIX, 0x0005);
3019 regmap_write(rt5668->regmap, RT5663_ADDA_RST, 0xc000);
3020 regmap_write(rt5668->regmap, RT5663_STO1_HPF_ADJ1, 0x3320);
3021 regmap_write(rt5668->regmap, RT5663_HP_CALIB_2, 0x00c9);
3022 regmap_write(rt5668->regmap, RT5663_DUMMY_1, 0x004c);
3023 regmap_write(rt5668->regmap, RT5663_ANA_BIAS_CUR_1, 0x7766);
3024 regmap_write(rt5668->regmap, RT5663_BIAS_CUR_8, 0x4702);
3025 msleep(200);
3026 regmap_write(rt5668->regmap, RT5663_HP_CALIB_1, 0x0069);
3027 regmap_write(rt5668->regmap, RT5663_HP_CALIB_3, 0x06c2);
3028 regmap_write(rt5668->regmap, RT5663_HP_CALIB_1_1, 0x7b00);
3029 regmap_write(rt5668->regmap, RT5663_HP_CALIB_1_1, 0xfb00);
3030 count = 0;
3031 while (true) {
3032 regmap_read(rt5668->regmap, RT5663_HP_CALIB_1_1, &value);
3033 if (value & 0x8000)
3034 usleep_range(10000, 10005);
3035 else
3036 break;
3037
3038 if (count > 200)
3039 return;
3040 count++;
3041 }
3042}
3043
3044static int rt5663_i2c_probe(struct i2c_client *i2c,
3045 const struct i2c_device_id *id)
3046{
3047 struct rt5663_priv *rt5663;
3048 int ret;
3049 unsigned int val;
3050 struct regmap *regmap;
3051
3052 rt5663 = devm_kzalloc(&i2c->dev, sizeof(struct rt5663_priv),
3053 GFP_KERNEL);
3054
3055 if (rt5663 == NULL)
3056 return -ENOMEM;
3057
3058 i2c_set_clientdata(i2c, rt5663);
3059
3060 regmap = devm_regmap_init_i2c(i2c, &temp_regmap);
3061 if (IS_ERR(regmap)) {
3062 ret = PTR_ERR(regmap);
3063 dev_err(&i2c->dev, "Failed to allocate temp register map: %d\n",
3064 ret);
3065 return ret;
3066 }
3067 regmap_read(regmap, RT5663_VENDOR_ID_2, &val);
3068 switch (val) {
3069 case RT5668_DEVICE_ID:
3070 rt5663->regmap = devm_regmap_init_i2c(i2c, &rt5668_regmap);
3071 rt5663->codec_type = CODEC_TYPE_RT5668;
3072 break;
3073 case RT5663_DEVICE_ID:
3074 rt5663->regmap = devm_regmap_init_i2c(i2c, &rt5663_regmap);
3075 rt5663->codec_type = CODEC_TYPE_RT5663;
3076 break;
3077 default:
3078 dev_err(&i2c->dev,
3079 "Device with ID register %#x is not rt5663 or rt5668\n",
3080 val);
3081 return -ENODEV;
3082 }
3083
3084 if (IS_ERR(rt5663->regmap)) {
3085 ret = PTR_ERR(rt5663->regmap);
3086 dev_err(&i2c->dev, "Failed to allocate register map: %d\n",
3087 ret);
3088 return ret;
3089 }
3090
3091 /* reset and calibrate */
3092 regmap_write(rt5663->regmap, RT5663_RESET, 0);
3093 regcache_cache_bypass(rt5663->regmap, true);
3094 switch (rt5663->codec_type) {
3095 case CODEC_TYPE_RT5668:
3096 rt5668_calibrate(rt5663);
3097 break;
3098 case CODEC_TYPE_RT5663:
3099 rt5663_calibrate(rt5663);
3100 break;
3101 default:
3102 dev_err(&i2c->dev, "%s:Unknown codec type\n", __func__);
3103 }
3104 regcache_cache_bypass(rt5663->regmap, false);
3105 regmap_write(rt5663->regmap, RT5663_RESET, 0);
3106 dev_dbg(&i2c->dev, "calibrate done\n");
3107
3108 /* GPIO1 as IRQ */
3109 regmap_update_bits(rt5663->regmap, RT5663_GPIO_1, RT5668_GP1_PIN_MASK,
3110 RT5668_GP1_PIN_IRQ);
3111 /* 4btn inline command debounce */
3112 regmap_update_bits(rt5663->regmap, RT5663_IL_CMD_5,
3113 RT5668_4BTN_CLK_DEB_MASK, RT5668_4BTN_CLK_DEB_65MS);
3114
3115 switch (rt5663->codec_type) {
3116 case CODEC_TYPE_RT5668:
3117 regmap_write(rt5663->regmap, RT5663_BIAS_CUR_8, 0xa402);
3118 /* JD1 */
3119 regmap_update_bits(rt5663->regmap, RT5663_AUTO_1MRC_CLK,
3120 RT5668_IRQ_POW_SAV_MASK | RT5668_IRQ_POW_SAV_JD1_MASK,
3121 RT5668_IRQ_POW_SAV_EN | RT5668_IRQ_POW_SAV_JD1_EN);
3122 regmap_update_bits(rt5663->regmap, RT5663_PWR_ANLG_2,
3123 RT5668_PWR_JD1_MASK, RT5668_PWR_JD1);
3124 regmap_update_bits(rt5663->regmap, RT5663_IRQ_1,
3125 RT5668_EN_CB_JD_MASK, RT5668_EN_CB_JD_EN);
3126
3127 regmap_update_bits(rt5663->regmap, RT5663_HP_LOGIC_2,
3128 RT5668_HP_SIG_SRC1_MASK, RT5668_HP_SIG_SRC1_REG);
3129 regmap_update_bits(rt5663->regmap, RT5663_RECMIX,
3130 RT5668_VREF_BIAS_MASK | RT5668_CBJ_DET_MASK |
3131 RT5668_DET_TYPE_MASK, RT5668_VREF_BIAS_REG |
3132 RT5668_CBJ_DET_EN | RT5668_DET_TYPE_QFN);
3133 /* Set GPIO4 and GPIO8 as input for combo jack */
3134 regmap_update_bits(rt5663->regmap, RT5663_GPIO_2,
3135 RT5668_GP4_PIN_CONF_MASK, RT5668_GP4_PIN_CONF_INPUT);
3136 regmap_update_bits(rt5663->regmap, RT5668_GPIO_3,
3137 RT5668_GP8_PIN_CONF_MASK, RT5668_GP8_PIN_CONF_INPUT);
3138 regmap_update_bits(rt5663->regmap, RT5663_PWR_ANLG_1,
3139 RT5668_LDO1_DVO_MASK | RT5668_AMP_HP_MASK,
3140 RT5668_LDO1_DVO_0_9V | RT5668_AMP_HP_3X);
3141 break;
3142 case CODEC_TYPE_RT5663:
3143 regmap_write(rt5663->regmap, RT5663_VREF_RECMIX, 0x0032);
3144 regmap_write(rt5663->regmap, RT5663_PWR_ANLG_1, 0xa2be);
3145 msleep(20);
3146 regmap_write(rt5663->regmap, RT5663_PWR_ANLG_1, 0xf2be);
3147 regmap_update_bits(rt5663->regmap, RT5663_GPIO_2,
3148 RT5663_GP1_PIN_CONF_MASK, RT5663_GP1_PIN_CONF_OUTPUT);
3149 /* DACREF LDO control */
3150 regmap_update_bits(rt5663->regmap, RT5663_DACREF_LDO, 0x3e0e,
3151 0x3a0a);
3152 regmap_update_bits(rt5663->regmap, RT5663_RECMIX,
3153 RT5663_RECMIX1_BST1_MASK, RT5663_RECMIX1_BST1_ON);
3154 regmap_update_bits(rt5663->regmap, RT5663_TDM_2,
3155 RT5663_DATA_SWAP_ADCDAT1_MASK,
3156 RT5663_DATA_SWAP_ADCDAT1_LL);
3157 break;
3158 default:
3159 dev_err(&i2c->dev, "%s:Unknown codec type\n", __func__);
3160 }
3161
3162 INIT_DELAYED_WORK(&rt5663->jack_detect_work, rt5663_jack_detect_work);
3163
3164 if (i2c->irq) {
3165 ret = request_irq(i2c->irq, rt5663_irq,
3166 IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING
3167 | IRQF_ONESHOT, "rt5663", rt5663);
3168 if (ret)
3169 dev_err(&i2c->dev, "%s Failed to reguest IRQ: %d\n",
3170 __func__, ret);
3171 }
3172
3173 ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_rt5663,
3174 rt5663_dai, ARRAY_SIZE(rt5663_dai));
3175
3176 if (ret) {
3177 if (i2c->irq)
3178 free_irq(i2c->irq, rt5663);
3179 }
3180
3181 return ret;
3182}
3183
3184static int rt5663_i2c_remove(struct i2c_client *i2c)
3185{
3186 struct rt5663_priv *rt5663 = i2c_get_clientdata(i2c);
3187
3188 if (i2c->irq)
3189 free_irq(i2c->irq, rt5663);
3190
3191 snd_soc_unregister_codec(&i2c->dev);
3192
3193 return 0;
3194}
3195
3196static void rt5663_i2c_shutdown(struct i2c_client *client)
3197{
3198 struct rt5663_priv *rt5663 = i2c_get_clientdata(client);
3199
3200 regmap_write(rt5663->regmap, RT5663_RESET, 0);
3201}
3202
3203static struct i2c_driver rt5663_i2c_driver = {
3204 .driver = {
3205 .name = "rt5663",
3206 .acpi_match_table = ACPI_PTR(rt5663_acpi_match),
3207 .of_match_table = of_match_ptr(rt5663_of_match),
3208 },
3209 .probe = rt5663_i2c_probe,
3210 .remove = rt5663_i2c_remove,
3211 .shutdown = rt5663_i2c_shutdown,
3212 .id_table = rt5663_i2c_id,
3213};
3214module_i2c_driver(rt5663_i2c_driver);
3215
3216MODULE_DESCRIPTION("ASoC RT5663 driver");
3217MODULE_AUTHOR("Jack Yu <jack.yu@realtek.com>");
3218MODULE_LICENSE("GPL v2");
diff --git a/sound/soc/codecs/rt5663.h b/sound/soc/codecs/rt5663.h
new file mode 100644
index 000000000000..2cc8f28080f6
--- /dev/null
+++ b/sound/soc/codecs/rt5663.h
@@ -0,0 +1,1121 @@
1/*
2 * rt5663.h -- RT5663 ALSA SoC audio driver
3 *
4 * Copyright 2016 Realtek Microelectronics
5 * Author: Jack Yu <jack.yu@realtek.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11
12#ifndef __RT5663_H__
13#define __RT5663_H__
14
15/* Info */
16#define RT5663_RESET 0x0000
17#define RT5663_VENDOR_ID 0x00fd
18#define RT5663_VENDOR_ID_1 0x00fe
19#define RT5663_VENDOR_ID_2 0x00ff
20
21#define RT5668_LOUT_CTRL 0x0001
22#define RT5668_HP_AMP_2 0x0003
23#define RT5668_MONO_OUT 0x0004
24#define RT5668_MONO_GAIN 0x0007
25
26#define RT5668_AEC_BST 0x000b
27#define RT5668_IN1_IN2 0x000c
28#define RT5668_IN3_IN4 0x000d
29#define RT5668_INL1_INR1 0x000f
30#define RT5668_CBJ_TYPE_2 0x0011
31#define RT5668_CBJ_TYPE_3 0x0012
32#define RT5668_CBJ_TYPE_4 0x0013
33#define RT5668_CBJ_TYPE_5 0x0014
34#define RT5668_CBJ_TYPE_8 0x0017
35
36/* I/O - ADC/DAC/DMIC */
37#define RT5668_DAC3_DIG_VOL 0x001a
38#define RT5668_DAC3_CTRL 0x001b
39#define RT5668_MONO_ADC_DIG_VOL 0x001d
40#define RT5668_STO2_ADC_DIG_VOL 0x001e
41#define RT5668_MONO_ADC_BST_GAIN 0x0020
42#define RT5668_STO2_ADC_BST_GAIN 0x0021
43#define RT5668_SIDETONE_CTRL 0x0024
44/* Mixer - D-D */
45#define RT5668_MONO1_ADC_MIXER 0x0027
46#define RT5668_STO2_ADC_MIXER 0x0028
47#define RT5668_MONO_DAC_MIXER 0x002b
48#define RT5668_DAC2_SRC_CTRL 0x002e
49#define RT5668_IF_3_4_DATA_CTL 0x002f
50#define RT5668_IF_5_DATA_CTL 0x0030
51#define RT5668_PDM_OUT_CTL 0x0031
52#define RT5668_PDM_I2C_DATA_CTL1 0x0032
53#define RT5668_PDM_I2C_DATA_CTL2 0x0033
54#define RT5668_PDM_I2C_DATA_CTL3 0x0034
55#define RT5668_PDM_I2C_DATA_CTL4 0x0035
56
57/*Mixer - Analog*/
58#define RT5668_RECMIX1_NEW 0x003a
59#define RT5668_RECMIX1L_0 0x003b
60#define RT5668_RECMIX1L 0x003c
61#define RT5668_RECMIX1R_0 0x003d
62#define RT5668_RECMIX1R 0x003e
63#define RT5668_RECMIX2_NEW 0x003f
64#define RT5668_RECMIX2_L_2 0x0041
65#define RT5668_RECMIX2_R 0x0042
66#define RT5668_RECMIX2_R_2 0x0043
67#define RT5668_CALIB_REC_LR 0x0044
68#define RT5668_ALC_BK_GAIN 0x0049
69#define RT5668_MONOMIX_GAIN 0x004a
70#define RT5668_MONOMIX_IN_GAIN 0x004b
71#define RT5668_OUT_MIXL_GAIN 0x004d
72#define RT5668_OUT_LMIX_IN_GAIN 0x004e
73#define RT5668_OUT_RMIX_IN_GAIN 0x004f
74#define RT5668_OUT_RMIX_IN_GAIN1 0x0050
75#define RT5668_LOUT_MIXER_CTRL 0x0052
76/* Power */
77#define RT5668_PWR_VOL 0x0067
78
79#define RT5668_ADCDAC_RST 0x006d
80/* Format - ADC/DAC */
81#define RT5668_I2S34_SDP 0x0071
82#define RT5668_I2S5_SDP 0x0072
83/* Format - TDM Control */
84#define RT5668_TDM_5 0x007c
85#define RT5668_TDM_6 0x007d
86#define RT5668_TDM_7 0x007e
87#define RT5668_TDM_8 0x007f
88
89/* Function - Analog */
90#define RT5668_ASRC_3 0x0085
91#define RT5668_ASRC_6 0x0088
92#define RT5668_ASRC_7 0x0089
93#define RT5668_PLL_TRK_13 0x0099
94#define RT5668_I2S_M_CLK_CTL 0x00a0
95#define RT5668_FDIV_I2S34_M_CLK 0x00a1
96#define RT5668_FDIV_I2S34_M_CLK2 0x00a2
97#define RT5668_FDIV_I2S5_M_CLK 0x00a3
98#define RT5668_FDIV_I2S5_M_CLK2 0x00a4
99
100/* Function - Digital */
101#define RT5668_IRQ_4 0x00b9
102#define RT5668_GPIO_3 0x00c2
103#define RT5668_GPIO_4 0x00c3
104#define RT5668_GPIO_STA 0x00c4
105#define RT5668_HP_AMP_DET1 0x00d0
106#define RT5668_HP_AMP_DET2 0x00d1
107#define RT5668_HP_AMP_DET3 0x00d2
108#define RT5668_MID_BD_HP_AMP 0x00d3
109#define RT5668_LOW_BD_HP_AMP 0x00d4
110#define RT5668_SOF_VOL_ZC2 0x00da
111#define RT5668_ADC_STO2_ADJ1 0x00ee
112#define RT5668_ADC_STO2_ADJ2 0x00ef
113/* General Control */
114#define RT5668_A_JD_CTRL 0x00f0
115#define RT5668_JD1_TRES_CTRL 0x00f1
116#define RT5668_JD2_TRES_CTRL 0x00f2
117#define RT5668_JD_CTRL2 0x00f7
118#define RT5668_DUM_REG_2 0x00fb
119#define RT5668_DUM_REG_3 0x00fc
120
121
122#define RT5668_DACADC_DIG_VOL2 0x0101
123#define RT5668_DIG_IN_PIN2 0x0133
124#define RT5668_PAD_DRV_CTL1 0x0136
125#define RT5668_SOF_RAM_DEPOP 0x0138
126#define RT5668_VOL_TEST 0x013f
127#define RT5668_TEST_MODE_3 0x0147
128#define RT5668_TEST_MODE_4 0x0148
129#define RT5668_MONO_DYNA_1 0x0170
130#define RT5668_MONO_DYNA_2 0x0171
131#define RT5668_MONO_DYNA_3 0x0172
132#define RT5668_MONO_DYNA_4 0x0173
133#define RT5668_MONO_DYNA_5 0x0174
134#define RT5668_MONO_DYNA_6 0x0175
135#define RT5668_STO1_SIL_DET 0x0190
136#define RT5668_MONOL_SIL_DET 0x0191
137#define RT5668_MONOR_SIL_DET 0x0192
138#define RT5668_STO2_DAC_SIL 0x0193
139#define RT5668_PWR_SAV_CTL1 0x0194
140#define RT5668_PWR_SAV_CTL2 0x0195
141#define RT5668_PWR_SAV_CTL3 0x0196
142#define RT5668_PWR_SAV_CTL4 0x0197
143#define RT5668_PWR_SAV_CTL5 0x0198
144#define RT5668_PWR_SAV_CTL6 0x0199
145#define RT5668_MONO_AMP_CAL1 0x01a0
146#define RT5668_MONO_AMP_CAL2 0x01a1
147#define RT5668_MONO_AMP_CAL3 0x01a2
148#define RT5668_MONO_AMP_CAL4 0x01a3
149#define RT5668_MONO_AMP_CAL5 0x01a4
150#define RT5668_MONO_AMP_CAL6 0x01a5
151#define RT5668_MONO_AMP_CAL7 0x01a6
152#define RT5668_MONO_AMP_CAL_ST1 0x01a7
153#define RT5668_MONO_AMP_CAL_ST2 0x01a8
154#define RT5668_MONO_AMP_CAL_ST3 0x01a9
155#define RT5668_MONO_AMP_CAL_ST4 0x01aa
156#define RT5668_MONO_AMP_CAL_ST5 0x01ab
157#define RT5668_HP_IMP_SEN_13 0x01b9
158#define RT5668_HP_IMP_SEN_14 0x01ba
159#define RT5668_HP_IMP_SEN_6 0x01bb
160#define RT5668_HP_IMP_SEN_7 0x01bc
161#define RT5668_HP_IMP_SEN_8 0x01bd
162#define RT5668_HP_IMP_SEN_9 0x01be
163#define RT5668_HP_IMP_SEN_10 0x01bf
164#define RT5668_HP_LOGIC_3 0x01dc
165#define RT5668_HP_CALIB_ST10 0x01f3
166#define RT5668_HP_CALIB_ST11 0x01f4
167#define RT5668_PRO_REG_TBL_4 0x0203
168#define RT5668_PRO_REG_TBL_5 0x0204
169#define RT5668_PRO_REG_TBL_6 0x0205
170#define RT5668_PRO_REG_TBL_7 0x0206
171#define RT5668_PRO_REG_TBL_8 0x0207
172#define RT5668_PRO_REG_TBL_9 0x0208
173#define RT5668_SAR_ADC_INL_1 0x0210
174#define RT5668_SAR_ADC_INL_2 0x0211
175#define RT5668_SAR_ADC_INL_3 0x0212
176#define RT5668_SAR_ADC_INL_4 0x0213
177#define RT5668_SAR_ADC_INL_5 0x0214
178#define RT5668_SAR_ADC_INL_6 0x0215
179#define RT5668_SAR_ADC_INL_7 0x0216
180#define RT5668_SAR_ADC_INL_8 0x0217
181#define RT5668_SAR_ADC_INL_9 0x0218
182#define RT5668_SAR_ADC_INL_10 0x0219
183#define RT5668_SAR_ADC_INL_11 0x021a
184#define RT5668_SAR_ADC_INL_12 0x021b
185#define RT5668_DRC_CTRL_1 0x02ff
186#define RT5668_DRC1_CTRL_2 0x0301
187#define RT5668_DRC1_CTRL_3 0x0302
188#define RT5668_DRC1_CTRL_4 0x0303
189#define RT5668_DRC1_CTRL_5 0x0304
190#define RT5668_DRC1_CTRL_6 0x0305
191#define RT5668_DRC1_HD_CTRL_1 0x0306
192#define RT5668_DRC1_HD_CTRL_2 0x0307
193#define RT5668_DRC1_PRI_REG_1 0x0310
194#define RT5668_DRC1_PRI_REG_2 0x0311
195#define RT5668_DRC1_PRI_REG_3 0x0312
196#define RT5668_DRC1_PRI_REG_4 0x0313
197#define RT5668_DRC1_PRI_REG_5 0x0314
198#define RT5668_DRC1_PRI_REG_6 0x0315
199#define RT5668_DRC1_PRI_REG_7 0x0316
200#define RT5668_DRC1_PRI_REG_8 0x0317
201#define RT5668_ALC_PGA_CTL_1 0x0330
202#define RT5668_ALC_PGA_CTL_2 0x0331
203#define RT5668_ALC_PGA_CTL_3 0x0332
204#define RT5668_ALC_PGA_CTL_4 0x0333
205#define RT5668_ALC_PGA_CTL_5 0x0334
206#define RT5668_ALC_PGA_CTL_6 0x0335
207#define RT5668_ALC_PGA_CTL_7 0x0336
208#define RT5668_ALC_PGA_CTL_8 0x0337
209#define RT5668_ALC_PGA_REG_1 0x0338
210#define RT5668_ALC_PGA_REG_2 0x0339
211#define RT5668_ALC_PGA_REG_3 0x033a
212#define RT5668_ADC_EQ_RECOV_1 0x03c0
213#define RT5668_ADC_EQ_RECOV_2 0x03c1
214#define RT5668_ADC_EQ_RECOV_3 0x03c2
215#define RT5668_ADC_EQ_RECOV_4 0x03c3
216#define RT5668_ADC_EQ_RECOV_5 0x03c4
217#define RT5668_ADC_EQ_RECOV_6 0x03c5
218#define RT5668_ADC_EQ_RECOV_7 0x03c6
219#define RT5668_ADC_EQ_RECOV_8 0x03c7
220#define RT5668_ADC_EQ_RECOV_9 0x03c8
221#define RT5668_ADC_EQ_RECOV_10 0x03c9
222#define RT5668_ADC_EQ_RECOV_11 0x03ca
223#define RT5668_ADC_EQ_RECOV_12 0x03cb
224#define RT5668_ADC_EQ_RECOV_13 0x03cc
225#define RT5668_VID_HIDDEN 0x03fe
226#define RT5668_VID_CUSTOMER 0x03ff
227#define RT5668_SCAN_MODE 0x07f0
228#define RT5668_I2C_BYPA 0x07fa
229
230/* Headphone Amp Control 2 (0x0003) */
231#define RT5668_EN_DAC_HPO_MASK (0x1 << 14)
232#define RT5668_EN_DAC_HPO_SHIFT 14
233#define RT5668_EN_DAC_HPO_DIS (0x0 << 14)
234#define RT5668_EN_DAC_HPO_EN (0x1 << 14)
235
236/*Headphone Amp L/R Analog Gain and Digital NG2 Gain Control (0x0005 0x0006)*/
237#define RT5668_GAIN_HP (0x1f << 8)
238#define RT5668_GAIN_HP_SHIFT 8
239
240/* AEC BST Control (0x000b) */
241#define RT5668_GAIN_CBJ_MASK (0xf << 8)
242#define RT5668_GAIN_CBJ_SHIFT 8
243
244/* IN1 Control / MIC GND REF (0x000c) */
245#define RT5668_IN1_DF_MASK (0x1 << 15)
246#define RT5668_IN1_DF_SHIFT 15
247
248/* Combo Jack and Type Detection Control 1 (0x0010) */
249#define RT5668_CBJ_DET_MASK (0x1 << 15)
250#define RT5668_CBJ_DET_SHIFT 15
251#define RT5668_CBJ_DET_DIS (0x0 << 15)
252#define RT5668_CBJ_DET_EN (0x1 << 15)
253#define RT5668_DET_TYPE_MASK (0x1 << 12)
254#define RT5668_DET_TYPE_SHIFT 12
255#define RT5668_DET_TYPE_WLCSP (0x0 << 12)
256#define RT5668_DET_TYPE_QFN (0x1 << 12)
257#define RT5668_VREF_BIAS_MASK (0x1 << 6)
258#define RT5668_VREF_BIAS_SHIFT 6
259#define RT5668_VREF_BIAS_FSM (0x0 << 6)
260#define RT5668_VREF_BIAS_REG (0x1 << 6)
261
262/* REC Left Mixer Control 2 (0x003c) */
263#define RT5668_RECMIX1L_BST1_CBJ (0x1 << 7)
264#define RT5668_RECMIX1L_BST1_CBJ_SHIFT 7
265#define RT5668_RECMIX1L_BST2 (0x1 << 4)
266#define RT5668_RECMIX1L_BST2_SHIFT 4
267
268/* REC Right Mixer Control 2 (0x003e) */
269#define RT5668_RECMIX1R_BST2 (0x1 << 4)
270#define RT5668_RECMIX1R_BST2_SHIFT 4
271
272/* DAC1 Digital Volume (0x0019) */
273#define RT5668_DAC_L1_VOL_MASK (0xff << 8)
274#define RT5668_DAC_L1_VOL_SHIFT 8
275#define RT5668_DAC_R1_VOL_MASK (0xff)
276#define RT5668_DAC_R1_VOL_SHIFT 0
277
278/* ADC Digital Volume Control (0x001c) */
279#define RT5668_ADC_L_MUTE_MASK (0x1 << 15)
280#define RT5668_ADC_L_MUTE_SHIFT 15
281#define RT5668_ADC_L_VOL_MASK (0x7f << 8)
282#define RT5668_ADC_L_VOL_SHIFT 8
283#define RT5668_ADC_R_MUTE_MASK (0x1 << 7)
284#define RT5668_ADC_R_MUTE_SHIFT 7
285#define RT5668_ADC_R_VOL_MASK (0x7f)
286#define RT5668_ADC_R_VOL_SHIFT 0
287
288/* Stereo ADC Mixer Control (0x0026) */
289#define RT5668_M_STO1_ADC_L1 (0x1 << 15)
290#define RT5668_M_STO1_ADC_L1_SHIFT 15
291#define RT5668_M_STO1_ADC_L2 (0x1 << 14)
292#define RT5668_M_STO1_ADC_L2_SHIFT 14
293#define RT5668_STO1_ADC_L1_SRC (0x1 << 13)
294#define RT5668_STO1_ADC_L1_SRC_SHIFT 13
295#define RT5668_STO1_ADC_L2_SRC (0x1 << 12)
296#define RT5668_STO1_ADC_L2_SRC_SHIFT 12
297#define RT5668_STO1_ADC_L_SRC (0x3 << 10)
298#define RT5668_STO1_ADC_L_SRC_SHIFT 10
299#define RT5668_M_STO1_ADC_R1 (0x1 << 7)
300#define RT5668_M_STO1_ADC_R1_SHIFT 7
301#define RT5668_M_STO1_ADC_R2 (0x1 << 6)
302#define RT5668_M_STO1_ADC_R2_SHIFT 6
303#define RT5668_STO1_ADC_R1_SRC (0x1 << 5)
304#define RT5668_STO1_ADC_R1_SRC_SHIFT 5
305#define RT5668_STO1_ADC_R2_SRC (0x1 << 4)
306#define RT5668_STO1_ADC_R2_SRC_SHIFT 4
307#define RT5668_STO1_ADC_R_SRC (0x3 << 2)
308#define RT5668_STO1_ADC_R_SRC_SHIFT 2
309
310/* ADC Mixer to DAC Mixer Control (0x0029) */
311#define RT5668_M_ADCMIX_L (0x1 << 15)
312#define RT5668_M_ADCMIX_L_SHIFT 15
313#define RT5668_M_DAC1_L (0x1 << 14)
314#define RT5668_M_DAC1_L_SHIFT 14
315#define RT5668_M_ADCMIX_R (0x1 << 7)
316#define RT5668_M_ADCMIX_R_SHIFT 7
317#define RT5668_M_DAC1_R (0x1 << 6)
318#define RT5668_M_DAC1_R_SHIFT 6
319
320/* Stereo DAC Mixer Control (0x002a) */
321#define RT5668_M_DAC_L1_STO_L (0x1 << 15)
322#define RT5668_M_DAC_L1_STO_L_SHIFT 15
323#define RT5668_M_DAC_R1_STO_L (0x1 << 13)
324#define RT5668_M_DAC_R1_STO_L_SHIFT 13
325#define RT5668_M_DAC_L1_STO_R (0x1 << 7)
326#define RT5668_M_DAC_L1_STO_R_SHIFT 7
327#define RT5668_M_DAC_R1_STO_R (0x1 << 5)
328#define RT5668_M_DAC_R1_STO_R_SHIFT 5
329
330/* Power Management for Digital 1 (0x0061) */
331#define RT5668_PWR_I2S1 (0x1 << 15)
332#define RT5668_PWR_I2S1_SHIFT 15
333#define RT5668_PWR_DAC_L1 (0x1 << 11)
334#define RT5668_PWR_DAC_L1_SHIFT 11
335#define RT5668_PWR_DAC_R1 (0x1 << 10)
336#define RT5668_PWR_DAC_R1_SHIFT 10
337#define RT5668_PWR_LDO_DACREF_MASK (0x1 << 8)
338#define RT5668_PWR_LDO_DACREF_SHIFT 8
339#define RT5668_PWR_LDO_DACREF_ON (0x1 << 8)
340#define RT5668_PWR_LDO_DACREF_DOWN (0x0 << 8)
341#define RT5668_PWR_LDO_SHIFT 8
342#define RT5668_PWR_ADC_L1 (0x1 << 4)
343#define RT5668_PWR_ADC_L1_SHIFT 4
344#define RT5668_PWR_ADC_R1 (0x1 << 3)
345#define RT5668_PWR_ADC_R1_SHIFT 3
346
347/* Power Management for Digital 2 (0x0062) */
348#define RT5668_PWR_ADC_S1F (0x1 << 15)
349#define RT5668_PWR_ADC_S1F_SHIFT 15
350#define RT5668_PWR_DAC_S1F (0x1 << 10)
351#define RT5668_PWR_DAC_S1F_SHIFT 10
352
353/* Power Management for Analog 1 (0x0063) */
354#define RT5668_PWR_VREF1 (0x1 << 15)
355#define RT5668_PWR_VREF1_MASK (0x1 << 15)
356#define RT5668_PWR_VREF1_SHIFT 15
357#define RT5668_PWR_FV1 (0x1 << 14)
358#define RT5668_PWR_FV1_MASK (0x1 << 14)
359#define RT5668_PWR_FV1_SHIFT 14
360#define RT5668_PWR_VREF2 (0x1 << 13)
361#define RT5668_PWR_VREF2_MASK (0x1 << 13)
362#define RT5668_PWR_VREF2_SHIFT 13
363#define RT5668_PWR_FV2 (0x1 << 12)
364#define RT5668_PWR_FV2_MASK (0x1 << 12)
365#define RT5668_PWR_FV2_SHIFT 12
366#define RT5668_PWR_MB (0x1 << 9)
367#define RT5668_PWR_MB_MASK (0x1 << 9)
368#define RT5668_PWR_MB_SHIFT 9
369#define RT5668_AMP_HP_MASK (0x3 << 2)
370#define RT5668_AMP_HP_SHIFT 2
371#define RT5668_AMP_HP_1X (0x0 << 2)
372#define RT5668_AMP_HP_3X (0x1 << 2)
373#define RT5668_AMP_HP_5X (0x3 << 2)
374#define RT5668_LDO1_DVO_MASK (0x3)
375#define RT5668_LDO1_DVO_SHIFT 0
376#define RT5668_LDO1_DVO_0_9V (0x0)
377#define RT5668_LDO1_DVO_1_0V (0x1)
378#define RT5668_LDO1_DVO_1_2V (0x2)
379#define RT5668_LDO1_DVO_1_4V (0x3)
380
381/* Power Management for Analog 2 (0x0064) */
382#define RT5668_PWR_BST1 (0x1 << 15)
383#define RT5668_PWR_BST1_MASK (0x1 << 15)
384#define RT5668_PWR_BST1_SHIFT 15
385#define RT5668_PWR_BST1_OFF (0x0 << 15)
386#define RT5668_PWR_BST1_ON (0x1 << 15)
387#define RT5668_PWR_BST2 (0x1 << 14)
388#define RT5668_PWR_BST2_MASK (0x1 << 14)
389#define RT5668_PWR_BST2_SHIFT 14
390#define RT5668_PWR_MB1 (0x1 << 11)
391#define RT5668_PWR_MB1_SHIFT 11
392#define RT5668_PWR_MB2 (0x1 << 10)
393#define RT5668_PWR_MB2_SHIFT 10
394#define RT5668_PWR_BST2_OP (0x1 << 6)
395#define RT5668_PWR_BST2_OP_MASK (0x1 << 6)
396#define RT5668_PWR_BST2_OP_SHIFT 6
397#define RT5668_PWR_JD1 (0x1 << 3)
398#define RT5668_PWR_JD1_MASK (0x1 << 3)
399#define RT5668_PWR_JD1_SHIFT 3
400#define RT5668_PWR_JD2 (0x1 << 2)
401#define RT5668_PWR_JD2_MASK (0x1 << 2)
402#define RT5668_PWR_JD2_SHIFT 2
403#define RT5668_PWR_RECMIX1 (0x1 << 1)
404#define RT5668_PWR_RECMIX1_SHIFT 1
405#define RT5668_PWR_RECMIX2 (0x1)
406#define RT5668_PWR_RECMIX2_SHIFT 0
407
408/* Power Management for Analog 3 (0x0065) */
409#define RT5668_PWR_CBJ_MASK (0x1 << 9)
410#define RT5668_PWR_CBJ_SHIFT 9
411#define RT5668_PWR_CBJ_OFF (0x0 << 9)
412#define RT5668_PWR_CBJ_ON (0x1 << 9)
413#define RT5668_PWR_PLL (0x1 << 6)
414#define RT5668_PWR_PLL_SHIFT 6
415#define RT5668_PWR_LDO2 (0x1 << 2)
416#define RT5668_PWR_LDO2_SHIFT 2
417
418/* Power Management for Volume (0x0067) */
419#define RT5668_PWR_MIC_DET (0x1 << 5)
420#define RT5668_PWR_MIC_DET_SHIFT 5
421
422/* MCLK and System Clock Detection Control (0x006b) */
423#define RT5668_EN_ANA_CLK_DET_MASK (0x1 << 15)
424#define RT5668_EN_ANA_CLK_DET_SHIFT 15
425#define RT5668_EN_ANA_CLK_DET_DIS (0x0 << 15)
426#define RT5668_EN_ANA_CLK_DET_AUTO (0x1 << 15)
427#define RT5668_PWR_CLK_DET_MASK (0x1)
428#define RT5668_PWR_CLK_DET_SHIFT 0
429#define RT5668_PWR_CLK_DET_DIS (0x0)
430#define RT5668_PWR_CLK_DET_EN (0x1)
431
432/* I2S1 Audio Serial Data Port Control (0x0070) */
433#define RT5668_I2S_MS_MASK (0x1 << 15)
434#define RT5668_I2S_MS_SHIFT 15
435#define RT5668_I2S_MS_M (0x0 << 15)
436#define RT5668_I2S_MS_S (0x1 << 15)
437#define RT5668_I2S_BP_MASK (0x1 << 8)
438#define RT5668_I2S_BP_SHIFT 8
439#define RT5668_I2S_BP_NOR (0x0 << 8)
440#define RT5668_I2S_BP_INV (0x1 << 8)
441#define RT5668_I2S_DL_MASK (0x3 << 4)
442#define RT5668_I2S_DL_SHIFT 4
443#define RT5668_I2S_DL_16 (0x0 << 4)
444#define RT5668_I2S_DL_20 (0x1 << 4)
445#define RT5668_I2S_DL_24 (0x2 << 4)
446#define RT5668_I2S_DL_8 (0x3 << 4)
447#define RT5668_I2S_DF_MASK (0x7)
448#define RT5668_I2S_DF_SHIFT 0
449#define RT5668_I2S_DF_I2S (0x0)
450#define RT5668_I2S_DF_LEFT (0x1)
451#define RT5668_I2S_DF_PCM_A (0x2)
452#define RT5668_I2S_DF_PCM_B (0x3)
453#define RT5668_I2S_DF_PCM_A_N (0x6)
454#define RT5668_I2S_DF_PCM_B_N (0x7)
455
456/* ADC/DAC Clock Control 1 (0x0073) */
457#define RT5668_I2S_PD1_MASK (0x7 << 12)
458#define RT5668_I2S_PD1_SHIFT 12
459#define RT5668_M_I2S_DIV_MASK (0x7 << 8)
460#define RT5668_M_I2S_DIV_SHIFT 8
461#define RT5668_CLK_SRC_MASK (0x3 << 4)
462#define RT5668_CLK_SRC_MCLK (0x0 << 4)
463#define RT5668_CLK_SRC_PLL_OUT (0x1 << 4)
464#define RT5668_CLK_SRC_DIV (0x2 << 4)
465#define RT5668_CLK_SRC_RC (0x3 << 4)
466#define RT5668_DAC_OSR_MASK (0x3 << 2)
467#define RT5668_DAC_OSR_SHIFT 2
468#define RT5668_DAC_OSR_128 (0x0 << 2)
469#define RT5668_DAC_OSR_64 (0x1 << 2)
470#define RT5668_DAC_OSR_32 (0x2 << 2)
471#define RT5668_ADC_OSR_MASK (0x3)
472#define RT5668_ADC_OSR_SHIFT 0
473#define RT5668_ADC_OSR_128 (0x0)
474#define RT5668_ADC_OSR_64 (0x1)
475#define RT5668_ADC_OSR_32 (0x2)
476
477/* TDM1 control 1 (0x0078) */
478#define RT5668_TDM_MODE_MASK (0x1 << 15)
479#define RT5668_TDM_MODE_SHIFT 15
480#define RT5668_TDM_MODE_I2S (0x0 << 15)
481#define RT5668_TDM_MODE_TDM (0x1 << 15)
482#define RT5668_TDM_IN_CH_MASK (0x3 << 10)
483#define RT5668_TDM_IN_CH_SHIFT 10
484#define RT5668_TDM_IN_CH_2 (0x0 << 10)
485#define RT5668_TDM_IN_CH_4 (0x1 << 10)
486#define RT5668_TDM_IN_CH_6 (0x2 << 10)
487#define RT5668_TDM_IN_CH_8 (0x3 << 10)
488#define RT5668_TDM_OUT_CH_MASK (0x3 << 8)
489#define RT5668_TDM_OUT_CH_SHIFT 8
490#define RT5668_TDM_OUT_CH_2 (0x0 << 8)
491#define RT5668_TDM_OUT_CH_4 (0x1 << 8)
492#define RT5668_TDM_OUT_CH_6 (0x2 << 8)
493#define RT5668_TDM_OUT_CH_8 (0x3 << 8)
494#define RT5668_TDM_IN_LEN_MASK (0x3 << 6)
495#define RT5668_TDM_IN_LEN_SHIFT 6
496#define RT5668_TDM_IN_LEN_16 (0x0 << 6)
497#define RT5668_TDM_IN_LEN_20 (0x1 << 6)
498#define RT5668_TDM_IN_LEN_24 (0x2 << 6)
499#define RT5668_TDM_IN_LEN_32 (0x3 << 6)
500#define RT5668_TDM_OUT_LEN_MASK (0x3 << 4)
501#define RT5668_TDM_OUT_LEN_SHIFT 4
502#define RT5668_TDM_OUT_LEN_16 (0x0 << 4)
503#define RT5668_TDM_OUT_LEN_20 (0x1 << 4)
504#define RT5668_TDM_OUT_LEN_24 (0x2 << 4)
505#define RT5668_TDM_OUT_LEN_32 (0x3 << 4)
506
507/* Global Clock Control (0x0080) */
508#define RT5668_SCLK_SRC_MASK (0x3 << 14)
509#define RT5668_SCLK_SRC_SHIFT 14
510#define RT5668_SCLK_SRC_MCLK (0x0 << 14)
511#define RT5668_SCLK_SRC_PLL1 (0x1 << 14)
512#define RT5668_SCLK_SRC_RCCLK (0x2 << 14)
513#define RT5668_PLL1_SRC_MASK (0x7 << 8)
514#define RT5668_PLL1_SRC_SHIFT 8
515#define RT5668_PLL1_SRC_MCLK (0x0 << 8)
516#define RT5668_PLL1_SRC_BCLK1 (0x1 << 8)
517#define RT5668_PLL1_PD_MASK (0x1 << 4)
518#define RT5668_PLL1_PD_SHIFT 4
519
520#define RT5668_PLL_INP_MAX 40000000
521#define RT5668_PLL_INP_MIN 256000
522/* PLL M/N/K Code Control 1 (0x0081) */
523#define RT5668_PLL_N_MAX 0x001ff
524#define RT5668_PLL_N_MASK (RT5668_PLL_N_MAX << 7)
525#define RT5668_PLL_N_SHIFT 7
526#define RT5668_PLL_K_MAX 0x001f
527#define RT5668_PLL_K_MASK (RT5668_PLL_K_MAX)
528#define RT5668_PLL_K_SHIFT 0
529
530/* PLL M/N/K Code Control 2 (0x0082) */
531#define RT5668_PLL_M_MAX 0x00f
532#define RT5668_PLL_M_MASK (RT5668_PLL_M_MAX << 12)
533#define RT5668_PLL_M_SHIFT 12
534#define RT5668_PLL_M_BP (0x1 << 11)
535#define RT5668_PLL_M_BP_SHIFT 11
536
537/* PLL tracking mode 1 (0x0083) */
538#define RT5668_I2S1_ASRC_MASK (0x1 << 13)
539#define RT5668_I2S1_ASRC_SHIFT 13
540#define RT5668_DAC_STO1_ASRC_MASK (0x1 << 12)
541#define RT5668_DAC_STO1_ASRC_SHIFT 12
542#define RT5668_ADC_STO1_ASRC_MASK (0x1 << 4)
543#define RT5668_ADC_STO1_ASRC_SHIFT 4
544
545/* PLL tracking mode 2 (0x0084)*/
546#define RT5668_DA_STO1_TRACK_MASK (0x7 << 12)
547#define RT5668_DA_STO1_TRACK_SHIFT 12
548#define RT5668_DA_STO1_TRACK_SYSCLK (0x0 << 12)
549#define RT5668_DA_STO1_TRACK_I2S1 (0x1 << 12)
550
551/* PLL tracking mode 3 (0x0085)*/
552#define RT5668_AD_STO1_TRACK_MASK (0x7 << 12)
553#define RT5668_AD_STO1_TRACK_SHIFT 12
554#define RT5668_AD_STO1_TRACK_SYSCLK (0x0 << 12)
555#define RT5668_AD_STO1_TRACK_I2S1 (0x1 << 12)
556
557/* HPOUT Charge pump control 1 (0x0091) */
558#define RT5668_OSW_HP_L_MASK (0x1 << 11)
559#define RT5668_OSW_HP_L_SHIFT 11
560#define RT5668_OSW_HP_L_EN (0x1 << 11)
561#define RT5668_OSW_HP_L_DIS (0x0 << 11)
562#define RT5668_OSW_HP_R_MASK (0x1 << 10)
563#define RT5668_OSW_HP_R_SHIFT 10
564#define RT5668_OSW_HP_R_EN (0x1 << 10)
565#define RT5668_OSW_HP_R_DIS (0x0 << 10)
566#define RT5668_SEL_PM_HP_MASK (0x3 << 8)
567#define RT5668_SEL_PM_HP_SHIFT 8
568#define RT5668_SEL_PM_HP_0_6 (0x0 << 8)
569#define RT5668_SEL_PM_HP_0_9 (0x1 << 8)
570#define RT5668_SEL_PM_HP_1_8 (0x2 << 8)
571#define RT5668_SEL_PM_HP_HIGH (0x3 << 8)
572#define RT5668_OVCD_HP_MASK (0x1 << 2)
573#define RT5668_OVCD_HP_SHIFT 2
574#define RT5668_OVCD_HP_EN (0x1 << 2)
575#define RT5668_OVCD_HP_DIS (0x0 << 2)
576
577/* RC Clock Control (0x0094) */
578#define RT5668_DIG_25M_CLK_MASK (0x1 << 9)
579#define RT5668_DIG_25M_CLK_SHIFT 9
580#define RT5668_DIG_25M_CLK_DIS (0x0 << 9)
581#define RT5668_DIG_25M_CLK_EN (0x1 << 9)
582#define RT5668_DIG_1M_CLK_MASK (0x1 << 8)
583#define RT5668_DIG_1M_CLK_SHIFT 8
584#define RT5668_DIG_1M_CLK_DIS (0x0 << 8)
585#define RT5668_DIG_1M_CLK_EN (0x1 << 8)
586
587/* Auto Turn On 1M RC CLK (0x009f) */
588#define RT5668_IRQ_POW_SAV_MASK (0x1 << 15)
589#define RT5668_IRQ_POW_SAV_SHIFT 15
590#define RT5668_IRQ_POW_SAV_DIS (0x0 << 15)
591#define RT5668_IRQ_POW_SAV_EN (0x1 << 15)
592#define RT5668_IRQ_POW_SAV_JD1_MASK (0x1 << 14)
593#define RT5668_IRQ_POW_SAV_JD1_SHIFT 14
594#define RT5668_IRQ_POW_SAV_JD1_DIS (0x0 << 14)
595#define RT5668_IRQ_POW_SAV_JD1_EN (0x1 << 14)
596
597/* IRQ Control 1 (0x00b6) */
598#define RT5668_EN_CB_JD_MASK (0x1 << 3)
599#define RT5668_EN_CB_JD_SHIFT 3
600#define RT5668_EN_CB_JD_EN (0x1 << 3)
601#define RT5668_EN_CB_JD_DIS (0x0 << 3)
602
603/* IRQ Control 3 (0x00b8) */
604#define RT5668_EN_IRQ_INLINE_MASK (0x1 << 6)
605#define RT5668_EN_IRQ_INLINE_SHIFT 6
606#define RT5668_EN_IRQ_INLINE_BYP (0x0 << 6)
607#define RT5668_EN_IRQ_INLINE_NOR (0x1 << 6)
608
609/* GPIO Control 1 (0x00c0) */
610#define RT5668_GP1_PIN_MASK (0x1 << 15)
611#define RT5668_GP1_PIN_SHIFT 15
612#define RT5668_GP1_PIN_GPIO1 (0x0 << 15)
613#define RT5668_GP1_PIN_IRQ (0x1 << 15)
614
615/* GPIO Control 2 (0x00c1) */
616#define RT5668_GP4_PIN_CONF_MASK (0x1 << 5)
617#define RT5668_GP4_PIN_CONF_SHIFT 5
618#define RT5668_GP4_PIN_CONF_INPUT (0x0 << 5)
619#define RT5668_GP4_PIN_CONF_OUTPUT (0x1 << 5)
620
621/* GPIO Control 2 (0x00c2) */
622#define RT5668_GP8_PIN_CONF_MASK (0x1 << 13)
623#define RT5668_GP8_PIN_CONF_SHIFT 13
624#define RT5668_GP8_PIN_CONF_INPUT (0x0 << 13)
625#define RT5668_GP8_PIN_CONF_OUTPUT (0x1 << 13)
626
627/* 4 Buttons Inline Command Function 1 (0x00df) */
628#define RT5668_4BTN_CLK_DEB_MASK (0x3 << 2)
629#define RT5668_4BTN_CLK_DEB_SHIFT 2
630#define RT5668_4BTN_CLK_DEB_8MS (0x0 << 2)
631#define RT5668_4BTN_CLK_DEB_16MS (0x1 << 2)
632#define RT5668_4BTN_CLK_DEB_32MS (0x2 << 2)
633#define RT5668_4BTN_CLK_DEB_65MS (0x3 << 2)
634
635/* Inline Command Function 6 (0x00e0) */
636#define RT5668_EN_4BTN_INL_MASK (0x1 << 15)
637#define RT5668_EN_4BTN_INL_SHIFT 15
638#define RT5668_EN_4BTN_INL_DIS (0x0 << 15)
639#define RT5668_EN_4BTN_INL_EN (0x1 << 15)
640#define RT5668_RESET_4BTN_INL_MASK (0x1 << 14)
641#define RT5668_RESET_4BTN_INL_SHIFT 14
642#define RT5668_RESET_4BTN_INL_RESET (0x0 << 14)
643#define RT5668_RESET_4BTN_INL_NOR (0x1 << 14)
644
645/* Digital Misc Control (0x00fa) */
646#define RT5668_DIG_GATE_CTRL_MASK 0x1
647#define RT5668_DIG_GATE_CTRL_SHIFT (0)
648#define RT5668_DIG_GATE_CTRL_DIS 0x0
649#define RT5668_DIG_GATE_CTRL_EN 0x1
650
651/* Chopper and Clock control for DAC L (0x013a)*/
652#define RT5668_CKXEN_DAC1_MASK (0x1 << 13)
653#define RT5668_CKXEN_DAC1_SHIFT 13
654#define RT5668_CKGEN_DAC1_MASK (0x1 << 12)
655#define RT5668_CKGEN_DAC1_SHIFT 12
656
657/* Chopper and Clock control for ADC (0x013b)*/
658#define RT5668_CKXEN_ADCC_MASK (0x1 << 13)
659#define RT5668_CKXEN_ADCC_SHIFT 13
660#define RT5668_CKGEN_ADCC_MASK (0x1 << 12)
661#define RT5668_CKGEN_ADCC_SHIFT 12
662
663/* HP Behavior Logic Control 2 (0x01db) */
664#define RT5668_HP_SIG_SRC1_MASK (0x3)
665#define RT5668_HP_SIG_SRC1_SHIFT 0
666#define RT5668_HP_SIG_SRC1_HP_DC (0x0)
667#define RT5668_HP_SIG_SRC1_HP_CALIB (0x1)
668#define RT5668_HP_SIG_SRC1_REG (0x2)
669#define RT5668_HP_SIG_SRC1_SILENCE (0x3)
670
671/* RT5663 specific register */
672#define RT5663_HP_OUT_EN 0x0002
673#define RT5663_HP_LCH_DRE 0x0005
674#define RT5663_HP_RCH_DRE 0x0006
675#define RT5663_CALIB_BST 0x000a
676#define RT5663_RECMIX 0x0010
677#define RT5663_SIL_DET_CTL 0x0015
678#define RT5663_PWR_SAV_SILDET 0x0016
679#define RT5663_SIDETONE_CTL 0x0018
680#define RT5663_STO1_DAC_DIG_VOL 0x0019
681#define RT5663_STO1_ADC_DIG_VOL 0x001c
682#define RT5663_STO1_BOOST 0x001f
683#define RT5663_HP_IMP_GAIN_1 0x0022
684#define RT5663_HP_IMP_GAIN_2 0x0023
685#define RT5663_STO1_ADC_MIXER 0x0026
686#define RT5663_AD_DA_MIXER 0x0029
687#define RT5663_STO_DAC_MIXER 0x002a
688#define RT5663_DIG_SIDE_MIXER 0x002c
689#define RT5663_BYPASS_STO_DAC 0x002d
690#define RT5663_CALIB_REC_MIX 0x0040
691#define RT5663_PWR_DIG_1 0x0061
692#define RT5663_PWR_DIG_2 0x0062
693#define RT5663_PWR_ANLG_1 0x0063
694#define RT5663_PWR_ANLG_2 0x0064
695#define RT5663_PWR_ANLG_3 0x0065
696#define RT5663_PWR_MIXER 0x0066
697#define RT5663_SIG_CLK_DET 0x006b
698#define RT5663_PRE_DIV_GATING_1 0x006e
699#define RT5663_PRE_DIV_GATING_2 0x006f
700#define RT5663_I2S1_SDP 0x0070
701#define RT5663_ADDA_CLK_1 0x0073
702#define RT5663_ADDA_RST 0x0074
703#define RT5663_FRAC_DIV_1 0x0075
704#define RT5663_FRAC_DIV_2 0x0076
705#define RT5663_TDM_1 0x0077
706#define RT5663_TDM_2 0x0078
707#define RT5663_TDM_3 0x0079
708#define RT5663_TDM_4 0x007a
709#define RT5663_TDM_5 0x007b
710#define RT5663_GLB_CLK 0x0080
711#define RT5663_PLL_1 0x0081
712#define RT5663_PLL_2 0x0082
713#define RT5663_ASRC_1 0x0083
714#define RT5663_ASRC_2 0x0084
715#define RT5663_ASRC_4 0x0086
716#define RT5663_DUMMY_REG 0x0087
717#define RT5663_ASRC_8 0x008a
718#define RT5663_ASRC_9 0x008b
719#define RT5663_ASRC_11 0x008c
720#define RT5663_DEPOP_1 0x008e
721#define RT5663_DEPOP_2 0x008f
722#define RT5663_DEPOP_3 0x0090
723#define RT5663_HP_CHARGE_PUMP_1 0x0091
724#define RT5663_HP_CHARGE_PUMP_2 0x0092
725#define RT5663_MICBIAS_1 0x0093
726#define RT5663_RC_CLK 0x0094
727#define RT5663_ASRC_11_2 0x0097
728#define RT5663_DUMMY_REG_2 0x0098
729#define RT5663_REC_PATH_GAIN 0x009a
730#define RT5663_AUTO_1MRC_CLK 0x009f
731#define RT5663_ADC_EQ_1 0x00ae
732#define RT5663_ADC_EQ_2 0x00af
733#define RT5663_IRQ_1 0x00b6
734#define RT5663_IRQ_2 0x00b7
735#define RT5663_IRQ_3 0x00b8
736#define RT5663_IRQ_4 0x00ba
737#define RT5663_IRQ_5 0x00bb
738#define RT5663_INT_ST_1 0x00be
739#define RT5663_INT_ST_2 0x00bf
740#define RT5663_GPIO_1 0x00c0
741#define RT5663_GPIO_2 0x00c1
742#define RT5663_GPIO_STA 0x00c5
743#define RT5663_SIN_GEN_1 0x00cb
744#define RT5663_SIN_GEN_2 0x00cc
745#define RT5663_SIN_GEN_3 0x00cd
746#define RT5663_SOF_VOL_ZC1 0x00d9
747#define RT5663_IL_CMD_1 0x00db
748#define RT5663_IL_CMD_2 0x00dc
749#define RT5663_IL_CMD_3 0x00dd
750#define RT5663_IL_CMD_4 0x00de
751#define RT5663_IL_CMD_5 0x00df
752#define RT5663_IL_CMD_6 0x00e0
753#define RT5663_IL_CMD_7 0x00e1
754#define RT5663_IL_CMD_8 0x00e2
755#define RT5663_IL_CMD_PWRSAV1 0x00e4
756#define RT5663_IL_CMD_PWRSAV2 0x00e5
757#define RT5663_EM_JACK_TYPE_1 0x00e6
758#define RT5663_EM_JACK_TYPE_2 0x00e7
759#define RT5663_EM_JACK_TYPE_3 0x00e8
760#define RT5663_EM_JACK_TYPE_4 0x00e9
761#define RT5663_EM_JACK_TYPE_5 0x00ea
762#define RT5663_EM_JACK_TYPE_6 0x00eb
763#define RT5663_STO1_HPF_ADJ1 0x00ec
764#define RT5663_STO1_HPF_ADJ2 0x00ed
765#define RT5663_FAST_OFF_MICBIAS 0x00f4
766#define RT5663_JD_CTRL1 0x00f6
767#define RT5663_JD_CTRL2 0x00f8
768#define RT5663_DIG_MISC 0x00fa
769#define RT5663_DIG_VOL_ZCD 0x0100
770#define RT5663_ANA_BIAS_CUR_1 0x0108
771#define RT5663_ANA_BIAS_CUR_2 0x0109
772#define RT5663_ANA_BIAS_CUR_3 0x010a
773#define RT5663_ANA_BIAS_CUR_4 0x010b
774#define RT5663_ANA_BIAS_CUR_5 0x010c
775#define RT5663_ANA_BIAS_CUR_6 0x010d
776#define RT5663_BIAS_CUR_5 0x010e
777#define RT5663_BIAS_CUR_6 0x010f
778#define RT5663_BIAS_CUR_7 0x0110
779#define RT5663_BIAS_CUR_8 0x0111
780#define RT5663_DACREF_LDO 0x0112
781#define RT5663_DUMMY_REG_3 0x0113
782#define RT5663_BIAS_CUR_9 0x0114
783#define RT5663_DUMMY_REG_4 0x0116
784#define RT5663_VREFADJ_OP 0x0117
785#define RT5663_VREF_RECMIX 0x0118
786#define RT5663_CHARGE_PUMP_1 0x0125
787#define RT5663_CHARGE_PUMP_1_2 0x0126
788#define RT5663_CHARGE_PUMP_1_3 0x0127
789#define RT5663_CHARGE_PUMP_2 0x0128
790#define RT5663_DIG_IN_PIN1 0x0132
791#define RT5663_PAD_DRV_CTL 0x0137
792#define RT5663_PLL_INT_REG 0x0139
793#define RT5663_CHOP_DAC_L 0x013a
794#define RT5663_CHOP_ADC 0x013b
795#define RT5663_CALIB_ADC 0x013c
796#define RT5663_CHOP_DAC_R 0x013d
797#define RT5663_DUMMY_CTL_DACLR 0x013e
798#define RT5663_DUMMY_REG_5 0x0140
799#define RT5663_SOFT_RAMP 0x0141
800#define RT5663_TEST_MODE_1 0x0144
801#define RT5663_TEST_MODE_2 0x0145
802#define RT5663_TEST_MODE_3 0x0146
803#define RT5663_STO_DRE_1 0x0160
804#define RT5663_STO_DRE_2 0x0161
805#define RT5663_STO_DRE_3 0x0162
806#define RT5663_STO_DRE_4 0x0163
807#define RT5663_STO_DRE_5 0x0164
808#define RT5663_STO_DRE_6 0x0165
809#define RT5663_STO_DRE_7 0x0166
810#define RT5663_STO_DRE_8 0x0167
811#define RT5663_STO_DRE_9 0x0168
812#define RT5663_STO_DRE_10 0x0169
813#define RT5663_MIC_DECRO_1 0x0180
814#define RT5663_MIC_DECRO_2 0x0181
815#define RT5663_MIC_DECRO_3 0x0182
816#define RT5663_MIC_DECRO_4 0x0183
817#define RT5663_MIC_DECRO_5 0x0184
818#define RT5663_MIC_DECRO_6 0x0185
819#define RT5663_HP_DECRO_1 0x01b0
820#define RT5663_HP_DECRO_2 0x01b1
821#define RT5663_HP_DECRO_3 0x01b2
822#define RT5663_HP_DECRO_4 0x01b3
823#define RT5663_HP_DECOUP 0x01b4
824#define RT5663_HP_IMP_SEN_MAP8 0x01b5
825#define RT5663_HP_IMP_SEN_MAP9 0x01b6
826#define RT5663_HP_IMP_SEN_MAP10 0x01b7
827#define RT5663_HP_IMP_SEN_MAP11 0x01b8
828#define RT5663_HP_IMP_SEN_1 0x01c0
829#define RT5663_HP_IMP_SEN_2 0x01c1
830#define RT5663_HP_IMP_SEN_3 0x01c2
831#define RT5663_HP_IMP_SEN_4 0x01c3
832#define RT5663_HP_IMP_SEN_5 0x01c4
833#define RT5663_HP_IMP_SEN_6 0x01c5
834#define RT5663_HP_IMP_SEN_7 0x01c6
835#define RT5663_HP_IMP_SEN_8 0x01c7
836#define RT5663_HP_IMP_SEN_9 0x01c8
837#define RT5663_HP_IMP_SEN_10 0x01c9
838#define RT5663_HP_IMP_SEN_11 0x01ca
839#define RT5663_HP_IMP_SEN_12 0x01cb
840#define RT5663_HP_IMP_SEN_13 0x01cc
841#define RT5663_HP_IMP_SEN_14 0x01cd
842#define RT5663_HP_IMP_SEN_15 0x01ce
843#define RT5663_HP_IMP_SEN_16 0x01cf
844#define RT5663_HP_IMP_SEN_17 0x01d0
845#define RT5663_HP_IMP_SEN_18 0x01d1
846#define RT5663_HP_IMP_SEN_19 0x01d2
847#define RT5663_HP_IMPSEN_DIG5 0x01d3
848#define RT5663_HP_IMPSEN_MAP1 0x01d4
849#define RT5663_HP_IMPSEN_MAP2 0x01d5
850#define RT5663_HP_IMPSEN_MAP3 0x01d6
851#define RT5663_HP_IMPSEN_MAP4 0x01d7
852#define RT5663_HP_IMPSEN_MAP5 0x01d8
853#define RT5663_HP_IMPSEN_MAP7 0x01d9
854#define RT5663_HP_LOGIC_1 0x01da
855#define RT5663_HP_LOGIC_2 0x01db
856#define RT5663_HP_CALIB_1 0x01dd
857#define RT5663_HP_CALIB_1_1 0x01de
858#define RT5663_HP_CALIB_2 0x01df
859#define RT5663_HP_CALIB_3 0x01e0
860#define RT5663_HP_CALIB_4 0x01e1
861#define RT5663_HP_CALIB_5 0x01e2
862#define RT5663_HP_CALIB_5_1 0x01e3
863#define RT5663_HP_CALIB_6 0x01e4
864#define RT5663_HP_CALIB_7 0x01e5
865#define RT5663_HP_CALIB_9 0x01e6
866#define RT5663_HP_CALIB_10 0x01e7
867#define RT5663_HP_CALIB_11 0x01e8
868#define RT5663_HP_CALIB_ST1 0x01ea
869#define RT5663_HP_CALIB_ST2 0x01eb
870#define RT5663_HP_CALIB_ST3 0x01ec
871#define RT5663_HP_CALIB_ST4 0x01ed
872#define RT5663_HP_CALIB_ST5 0x01ee
873#define RT5663_HP_CALIB_ST6 0x01ef
874#define RT5663_HP_CALIB_ST7 0x01f0
875#define RT5663_HP_CALIB_ST8 0x01f1
876#define RT5663_HP_CALIB_ST9 0x01f2
877#define RT5663_HP_AMP_DET 0x0200
878#define RT5663_DUMMY_REG_6 0x0201
879#define RT5663_HP_BIAS 0x0202
880#define RT5663_CBJ_1 0x0250
881#define RT5663_CBJ_2 0x0251
882#define RT5663_CBJ_3 0x0252
883#define RT5663_DUMMY_1 0x02fa
884#define RT5663_DUMMY_2 0x02fb
885#define RT5663_DUMMY_3 0x02fc
886#define RT5663_ANA_JD 0x0300
887#define RT5663_ADC_LCH_LPF1_A1 0x03d0
888#define RT5663_ADC_RCH_LPF1_A1 0x03d1
889#define RT5663_ADC_LCH_LPF1_H0 0x03d2
890#define RT5663_ADC_RCH_LPF1_H0 0x03d3
891#define RT5663_ADC_LCH_BPF1_A1 0x03d4
892#define RT5663_ADC_RCH_BPF1_A1 0x03d5
893#define RT5663_ADC_LCH_BPF1_A2 0x03d6
894#define RT5663_ADC_RCH_BPF1_A2 0x03d7
895#define RT5663_ADC_LCH_BPF1_H0 0x03d8
896#define RT5663_ADC_RCH_BPF1_H0 0x03d9
897#define RT5663_ADC_LCH_BPF2_A1 0x03da
898#define RT5663_ADC_RCH_BPF2_A1 0x03db
899#define RT5663_ADC_LCH_BPF2_A2 0x03dc
900#define RT5663_ADC_RCH_BPF2_A2 0x03dd
901#define RT5663_ADC_LCH_BPF2_H0 0x03de
902#define RT5663_ADC_RCH_BPF2_H0 0x03df
903#define RT5663_ADC_LCH_BPF3_A1 0x03e0
904#define RT5663_ADC_RCH_BPF3_A1 0x03e1
905#define RT5663_ADC_LCH_BPF3_A2 0x03e2
906#define RT5663_ADC_RCH_BPF3_A2 0x03e3
907#define RT5663_ADC_LCH_BPF3_H0 0x03e4
908#define RT5663_ADC_RCH_BPF3_H0 0x03e5
909#define RT5663_ADC_LCH_BPF4_A1 0x03e6
910#define RT5663_ADC_RCH_BPF4_A1 0x03e7
911#define RT5663_ADC_LCH_BPF4_A2 0x03e8
912#define RT5663_ADC_RCH_BPF4_A2 0x03e9
913#define RT5663_ADC_LCH_BPF4_H0 0x03ea
914#define RT5663_ADC_RCH_BPF4_H0 0x03eb
915#define RT5663_ADC_LCH_HPF1_A1 0x03ec
916#define RT5663_ADC_RCH_HPF1_A1 0x03ed
917#define RT5663_ADC_LCH_HPF1_H0 0x03ee
918#define RT5663_ADC_RCH_HPF1_H0 0x03ef
919#define RT5663_ADC_EQ_PRE_VOL_L 0x03f0
920#define RT5663_ADC_EQ_PRE_VOL_R 0x03f1
921#define RT5663_ADC_EQ_POST_VOL_L 0x03f2
922#define RT5663_ADC_EQ_POST_VOL_R 0x03f3
923
924/* RT5663: RECMIX Control (0x0010) */
925#define RT5663_RECMIX1_BST1_MASK (0x1)
926#define RT5663_RECMIX1_BST1_SHIFT 0
927#define RT5663_RECMIX1_BST1_ON (0x0)
928#define RT5663_RECMIX1_BST1_OFF (0x1)
929
930/* RT5663: Bypass Stereo1 DAC Mixer Control (0x002d) */
931#define RT5663_DACL1_SRC_MASK (0x1 << 3)
932#define RT5663_DACL1_SRC_SHIFT 3
933#define RT5663_DACR1_SRC_MASK (0x1 << 2)
934#define RT5663_DACR1_SRC_SHIFT 2
935
936/* RT5663: TDM control 2 (0x0078) */
937#define RT5663_DATA_SWAP_ADCDAT1_MASK (0x3 << 14)
938#define RT5663_DATA_SWAP_ADCDAT1_SHIFT 14
939#define RT5663_DATA_SWAP_ADCDAT1_LR (0x0 << 14)
940#define RT5663_DATA_SWAP_ADCDAT1_RL (0x1 << 14)
941#define RT5663_DATA_SWAP_ADCDAT1_LL (0x2 << 14)
942#define RT5663_DATA_SWAP_ADCDAT1_RR (0x3 << 14)
943
944/* RT5663: TDM control 5 (0x007b) */
945#define RT5663_TDM_LENGTN_MASK (0x3)
946#define RT5663_TDM_LENGTN_SHIFT 0
947#define RT5663_TDM_LENGTN_16 (0x0)
948#define RT5663_TDM_LENGTN_20 (0x1)
949#define RT5663_TDM_LENGTN_24 (0x2)
950#define RT5663_TDM_LENGTN_32 (0x3)
951
952/* RT5663: Global Clock Control (0x0080) */
953#define RT5663_SCLK_SRC_MASK (0x3 << 14)
954#define RT5663_SCLK_SRC_SHIFT 14
955#define RT5663_SCLK_SRC_MCLK (0x0 << 14)
956#define RT5663_SCLK_SRC_PLL1 (0x1 << 14)
957#define RT5663_SCLK_SRC_RCCLK (0x2 << 14)
958#define RT5663_PLL1_SRC_MASK (0x7 << 11)
959#define RT5663_PLL1_SRC_SHIFT 11
960#define RT5663_PLL1_SRC_MCLK (0x0 << 11)
961#define RT5663_PLL1_SRC_BCLK1 (0x1 << 11)
962
963/* PLL tracking mode 1 (0x0083) */
964#define RT5663_I2S1_ASRC_MASK (0x1 << 11)
965#define RT5663_I2S1_ASRC_SHIFT 11
966#define RT5663_DAC_STO1_ASRC_MASK (0x1 << 10)
967#define RT5663_DAC_STO1_ASRC_SHIFT 10
968#define RT5663_ADC_STO1_ASRC_MASK (0x1 << 3)
969#define RT5663_ADC_STO1_ASRC_SHIFT 3
970
971/* PLL tracking mode 2 (0x0084)*/
972#define RT5663_DA_STO1_TRACK_MASK (0x7 << 12)
973#define RT5663_DA_STO1_TRACK_SHIFT 12
974#define RT5663_DA_STO1_TRACK_SYSCLK (0x0 << 12)
975#define RT5663_DA_STO1_TRACK_I2S1 (0x1 << 12)
976#define RT5663_AD_STO1_TRACK_MASK (0x7)
977#define RT5663_AD_STO1_TRACK_SHIFT 0
978#define RT5663_AD_STO1_TRACK_SYSCLK (0x0)
979#define RT5663_AD_STO1_TRACK_I2S1 (0x1)
980
981/* RT5663: HPOUT Charge pump control 1 (0x0091) */
982#define RT5663_SI_HP_MASK (0x1 << 12)
983#define RT5663_SI_HP_SHIFT 12
984#define RT5663_SI_HP_EN (0x1 << 12)
985#define RT5663_SI_HP_DIS (0x0 << 12)
986
987/* RT5663: GPIO Control 2 (0x00b6) */
988#define RT5663_GP1_PIN_CONF_MASK (0x1 << 2)
989#define RT5663_GP1_PIN_CONF_SHIFT 2
990#define RT5663_GP1_PIN_CONF_OUTPUT (0x1 << 2)
991#define RT5663_GP1_PIN_CONF_INPUT (0x0 << 2)
992
993/* RT5663: GPIO Control 2 (0x00b7) */
994#define RT5663_EN_IRQ_INLINE_MASK (0x1 << 3)
995#define RT5663_EN_IRQ_INLINE_SHIFT 3
996#define RT5663_EN_IRQ_INLINE_NOR (0x1 << 3)
997#define RT5663_EN_IRQ_INLINE_BYP (0x0 << 3)
998
999/* RT5663: IRQ Control 1 (0x00c1) */
1000#define RT5663_EN_IRQ_JD1_MASK (0x1 << 6)
1001#define RT5663_EN_IRQ_JD1_SHIFT 6
1002#define RT5663_EN_IRQ_JD1_EN (0x1 << 6)
1003#define RT5663_EN_IRQ_JD1_DIS (0x0 << 6)
1004
1005/* RT5663: Inline Command Function 2 (0x00dc) */
1006#define RT5663_PWR_MIC_DET_MASK (0x1)
1007#define RT5663_PWR_MIC_DET_SHIFT 0
1008#define RT5663_PWR_MIC_DET_ON (0x1)
1009#define RT5663_PWR_MIC_DET_OFF (0x0)
1010
1011/* RT5663: Embeeded Jack and Type Detection Control 1 (0x00e6)*/
1012#define RT5663_CBJ_DET_MASK (0x1 << 15)
1013#define RT5663_CBJ_DET_SHIFT 15
1014#define RT5663_CBJ_DET_DIS (0x0 << 15)
1015#define RT5663_CBJ_DET_EN (0x1 << 15)
1016#define RT5663_EXT_JD_MASK (0x1 << 11)
1017#define RT5663_EXT_JD_SHIFT 11
1018#define RT5663_EXT_JD_EN (0x1 << 11)
1019#define RT5663_EXT_JD_DIS (0x0 << 11)
1020#define RT5663_POL_EXT_JD_MASK (0x1 << 10)
1021#define RT5663_POL_EXT_JD_SHIFT 10
1022#define RT5663_POL_EXT_JD_EN (0x1 << 10)
1023#define RT5663_POL_EXT_JD_DIS (0x0 << 10)
1024
1025/* RT5663: DACREF LDO Control (0x0112)*/
1026#define RT5663_PWR_LDO_DACREFL_MASK (0x1 << 9)
1027#define RT5663_PWR_LDO_DACREFL_SHIFT 9
1028#define RT5663_PWR_LDO_DACREFR_MASK (0x1 << 1)
1029#define RT5663_PWR_LDO_DACREFR_SHIFT 1
1030
1031/* RT5663: Stereo Dynamic Range Enhancement Control 9 (0x0168, 0x0169)*/
1032#define RT5663_DRE_GAIN_HP_MASK (0x1f)
1033#define RT5663_DRE_GAIN_HP_SHIFT 0
1034
1035/* RT5663: Combo Jack Control (0x0250) */
1036#define RT5663_INBUF_CBJ_BST1_MASK (0x1 << 11)
1037#define RT5663_INBUF_CBJ_BST1_SHIFT 11
1038#define RT5663_INBUF_CBJ_BST1_ON (0x1 << 11)
1039#define RT5663_INBUF_CBJ_BST1_OFF (0x0 << 11)
1040#define RT5663_CBJ_SENSE_BST1_MASK (0x1 << 10)
1041#define RT5663_CBJ_SENSE_BST1_SHIFT 10
1042#define RT5663_CBJ_SENSE_BST1_L (0x1 << 10)
1043#define RT5663_CBJ_SENSE_BST1_R (0x0 << 10)
1044
1045/* RT5663: Combo Jack Control (0x0251) */
1046#define RT5663_GAIN_BST1_MASK (0xf)
1047#define RT5663_GAIN_BST1_SHIFT 0
1048
1049/* RT5663: Dummy register 1 (0x02fa) */
1050#define RT5663_EMB_CLK_MASK (0x1 << 9)
1051#define RT5663_EMB_CLK_SHIFT 9
1052#define RT5663_EMB_CLK_EN (0x1 << 9)
1053#define RT5663_EMB_CLK_DIS (0x0 << 9)
1054#define RT5663_HPA_CPL_BIAS_MASK (0x7 << 6)
1055#define RT5663_HPA_CPL_BIAS_SHIFT 6
1056#define RT5663_HPA_CPL_BIAS_0_5 (0x0 << 6)
1057#define RT5663_HPA_CPL_BIAS_1 (0x1 << 6)
1058#define RT5663_HPA_CPL_BIAS_2 (0x2 << 6)
1059#define RT5663_HPA_CPL_BIAS_3 (0x3 << 6)
1060#define RT5663_HPA_CPL_BIAS_4_1 (0x4 << 6)
1061#define RT5663_HPA_CPL_BIAS_4_2 (0x5 << 6)
1062#define RT5663_HPA_CPL_BIAS_6 (0x6 << 6)
1063#define RT5663_HPA_CPL_BIAS_8 (0x7 << 6)
1064#define RT5663_HPA_CPR_BIAS_MASK (0x7 << 3)
1065#define RT5663_HPA_CPR_BIAS_SHIFT 3
1066#define RT5663_HPA_CPR_BIAS_0_5 (0x0 << 3)
1067#define RT5663_HPA_CPR_BIAS_1 (0x1 << 3)
1068#define RT5663_HPA_CPR_BIAS_2 (0x2 << 3)
1069#define RT5663_HPA_CPR_BIAS_3 (0x3 << 3)
1070#define RT5663_HPA_CPR_BIAS_4_1 (0x4 << 3)
1071#define RT5663_HPA_CPR_BIAS_4_2 (0x5 << 3)
1072#define RT5663_HPA_CPR_BIAS_6 (0x6 << 3)
1073#define RT5663_HPA_CPR_BIAS_8 (0x7 << 3)
1074#define RT5663_DUMMY_BIAS_MASK (0x7)
1075#define RT5663_DUMMY_BIAS_SHIFT 0
1076#define RT5663_DUMMY_BIAS_0_5 (0x0)
1077#define RT5663_DUMMY_BIAS_1 (0x1)
1078#define RT5663_DUMMY_BIAS_2 (0x2)
1079#define RT5663_DUMMY_BIAS_3 (0x3)
1080#define RT5663_DUMMY_BIAS_4_1 (0x4)
1081#define RT5663_DUMMY_BIAS_4_2 (0x5)
1082#define RT5663_DUMMY_BIAS_6 (0x6)
1083#define RT5663_DUMMY_BIAS_8 (0x7)
1084
1085
1086/* System Clock Source */
1087enum {
1088 RT5663_SCLK_S_MCLK,
1089 RT5663_SCLK_S_PLL1,
1090 RT5663_SCLK_S_RCCLK,
1091};
1092
1093/* PLL1 Source */
1094enum {
1095 RT5663_PLL1_S_MCLK,
1096 RT5663_PLL1_S_BCLK1,
1097};
1098
1099enum {
1100 RT5663_AIF,
1101 RT5663_AIFS,
1102};
1103
1104/* asrc clock source */
1105enum {
1106 RT5663_CLK_SEL_SYS = 0x0,
1107 RT5663_CLK_SEL_I2S1_ASRC = 0x1,
1108};
1109
1110/* filter mask */
1111enum {
1112 RT5663_DA_STEREO_FILTER = 0x1,
1113 RT5663_AD_STEREO_FILTER = 0x2,
1114};
1115
1116int rt5663_set_jack_detect(struct snd_soc_codec *codec,
1117 struct snd_soc_jack *hs_jack);
1118int rt5663_sel_asrc_clk_src(struct snd_soc_codec *codec,
1119 unsigned int filter_mask, unsigned int clk_src);
1120
1121#endif /* __RT5663_H__ */
diff --git a/sound/soc/codecs/rt5670.c b/sound/soc/codecs/rt5670.c
index 8ef467f64f03..49caf1393aeb 100644
--- a/sound/soc/codecs/rt5670.c
+++ b/sound/soc/codecs/rt5670.c
@@ -2777,12 +2777,14 @@ static struct snd_soc_codec_driver soc_codec_dev_rt5670 = {
2777 .resume = rt5670_resume, 2777 .resume = rt5670_resume,
2778 .set_bias_level = rt5670_set_bias_level, 2778 .set_bias_level = rt5670_set_bias_level,
2779 .idle_bias_off = true, 2779 .idle_bias_off = true,
2780 .controls = rt5670_snd_controls, 2780 .component_driver = {
2781 .num_controls = ARRAY_SIZE(rt5670_snd_controls), 2781 .controls = rt5670_snd_controls,
2782 .dapm_widgets = rt5670_dapm_widgets, 2782 .num_controls = ARRAY_SIZE(rt5670_snd_controls),
2783 .num_dapm_widgets = ARRAY_SIZE(rt5670_dapm_widgets), 2783 .dapm_widgets = rt5670_dapm_widgets,
2784 .dapm_routes = rt5670_dapm_routes, 2784 .num_dapm_widgets = ARRAY_SIZE(rt5670_dapm_widgets),
2785 .num_dapm_routes = ARRAY_SIZE(rt5670_dapm_routes), 2785 .dapm_routes = rt5670_dapm_routes,
2786 .num_dapm_routes = ARRAY_SIZE(rt5670_dapm_routes),
2787 },
2786}; 2788};
2787 2789
2788static const struct regmap_config rt5670_regmap = { 2790static const struct regmap_config rt5670_regmap = {
diff --git a/sound/soc/codecs/rt5677.c b/sound/soc/codecs/rt5677.c
index da9483c1c6fb..abc802a5a479 100644
--- a/sound/soc/codecs/rt5677.c
+++ b/sound/soc/codecs/rt5677.c
@@ -9,6 +9,7 @@
9 * published by the Free Software Foundation. 9 * published by the Free Software Foundation.
10 */ 10 */
11 11
12#include <linux/acpi.h>
12#include <linux/fs.h> 13#include <linux/fs.h>
13#include <linux/module.h> 14#include <linux/module.h>
14#include <linux/moduleparam.h> 15#include <linux/moduleparam.h>
@@ -40,6 +41,15 @@
40 41
41#define RT5677_PR_BASE (RT5677_PR_RANGE_BASE + (0 * RT5677_PR_SPACING)) 42#define RT5677_PR_BASE (RT5677_PR_RANGE_BASE + (0 * RT5677_PR_SPACING))
42 43
44/* GPIO indexes defined by ACPI */
45enum {
46 RT5677_GPIO_PLUG_DET = 0,
47 RT5677_GPIO_MIC_PRESENT_L = 1,
48 RT5677_GPIO_HOTWORD_DET_L = 2,
49 RT5677_GPIO_DSP_INT = 3,
50 RT5677_GPIO_HP_AMP_SHDN_L = 4,
51};
52
43static const struct regmap_range_cfg rt5677_ranges[] = { 53static const struct regmap_range_cfg rt5677_ranges[] = {
44 { 54 {
45 .name = "PR", 55 .name = "PR",
@@ -4657,7 +4667,7 @@ static int rt5677_to_irq(struct gpio_chip *chip, unsigned offset)
4657 return regmap_irq_get_virq(data, irq); 4667 return regmap_irq_get_virq(data, irq);
4658} 4668}
4659 4669
4660static struct gpio_chip rt5677_template_chip = { 4670static const struct gpio_chip rt5677_template_chip = {
4661 .label = "rt5677", 4671 .label = "rt5677",
4662 .owner = THIS_MODULE, 4672 .owner = THIS_MODULE,
4663 .direction_output = rt5677_gpio_direction_out, 4673 .direction_output = rt5677_gpio_direction_out,
@@ -4974,12 +4984,14 @@ static struct snd_soc_codec_driver soc_codec_dev_rt5677 = {
4974 .resume = rt5677_resume, 4984 .resume = rt5677_resume,
4975 .set_bias_level = rt5677_set_bias_level, 4985 .set_bias_level = rt5677_set_bias_level,
4976 .idle_bias_off = true, 4986 .idle_bias_off = true,
4977 .controls = rt5677_snd_controls, 4987 .component_driver = {
4978 .num_controls = ARRAY_SIZE(rt5677_snd_controls), 4988 .controls = rt5677_snd_controls,
4979 .dapm_widgets = rt5677_dapm_widgets, 4989 .num_controls = ARRAY_SIZE(rt5677_snd_controls),
4980 .num_dapm_widgets = ARRAY_SIZE(rt5677_dapm_widgets), 4990 .dapm_widgets = rt5677_dapm_widgets,
4981 .dapm_routes = rt5677_dapm_routes, 4991 .num_dapm_widgets = ARRAY_SIZE(rt5677_dapm_widgets),
4982 .num_dapm_routes = ARRAY_SIZE(rt5677_dapm_routes), 4992 .dapm_routes = rt5677_dapm_routes,
4993 .num_dapm_routes = ARRAY_SIZE(rt5677_dapm_routes),
4994 },
4983}; 4995};
4984 4996
4985static const struct regmap_config rt5677_regmap_physical = { 4997static const struct regmap_config rt5677_regmap_physical = {
@@ -5018,10 +5030,47 @@ static const struct regmap_config rt5677_regmap = {
5018static const struct i2c_device_id rt5677_i2c_id[] = { 5030static const struct i2c_device_id rt5677_i2c_id[] = {
5019 { "rt5677", RT5677 }, 5031 { "rt5677", RT5677 },
5020 { "rt5676", RT5676 }, 5032 { "rt5676", RT5676 },
5033 { "RT5677CE:00", RT5677 },
5021 { } 5034 { }
5022}; 5035};
5023MODULE_DEVICE_TABLE(i2c, rt5677_i2c_id); 5036MODULE_DEVICE_TABLE(i2c, rt5677_i2c_id);
5024 5037
5038static const struct acpi_gpio_params plug_det_gpio = { RT5677_GPIO_PLUG_DET, 0, false };
5039static const struct acpi_gpio_params mic_present_gpio = { RT5677_GPIO_MIC_PRESENT_L, 0, false };
5040static const struct acpi_gpio_params headphone_enable_gpio = { RT5677_GPIO_HP_AMP_SHDN_L, 0, false };
5041
5042static const struct acpi_gpio_mapping bdw_rt5677_gpios[] = {
5043 { "plug-det-gpios", &plug_det_gpio, 1 },
5044 { "mic-present-gpios", &mic_present_gpio, 1 },
5045 { "headphone-enable-gpios", &headphone_enable_gpio, 1 },
5046 { NULL },
5047};
5048
5049static void rt5677_read_acpi_properties(struct rt5677_priv *rt5677,
5050 struct device *dev)
5051{
5052 int ret;
5053 u32 val;
5054
5055 ret = acpi_dev_add_driver_gpios(ACPI_COMPANION(dev),
5056 bdw_rt5677_gpios);
5057 if (ret)
5058 dev_warn(dev, "Failed to add driver gpios\n");
5059
5060 if (!device_property_read_u32(dev, "DCLK", &val))
5061 rt5677->pdata.dmic2_clk_pin = val;
5062
5063 rt5677->pdata.in1_diff = device_property_read_bool(dev, "IN1");
5064 rt5677->pdata.in2_diff = device_property_read_bool(dev, "IN2");
5065 rt5677->pdata.lout1_diff = device_property_read_bool(dev, "OUT1");
5066 rt5677->pdata.lout2_diff = device_property_read_bool(dev, "OUT2");
5067 rt5677->pdata.lout3_diff = device_property_read_bool(dev, "OUT3");
5068
5069 device_property_read_u32(dev, "JD1", &rt5677->pdata.jd1_gpio);
5070 device_property_read_u32(dev, "JD2", &rt5677->pdata.jd2_gpio);
5071 device_property_read_u32(dev, "JD3", &rt5677->pdata.jd3_gpio);
5072}
5073
5025static void rt5677_read_device_properties(struct rt5677_priv *rt5677, 5074static void rt5677_read_device_properties(struct rt5677_priv *rt5677,
5026 struct device *dev) 5075 struct device *dev)
5027{ 5076{
@@ -5127,8 +5176,12 @@ static int rt5677_i2c_probe(struct i2c_client *i2c,
5127 5176
5128 if (pdata) 5177 if (pdata)
5129 rt5677->pdata = *pdata; 5178 rt5677->pdata = *pdata;
5130 else 5179 else if (i2c->dev.of_node)
5131 rt5677_read_device_properties(rt5677, &i2c->dev); 5180 rt5677_read_device_properties(rt5677, &i2c->dev);
5181 else if (ACPI_HANDLE(&i2c->dev))
5182 rt5677_read_acpi_properties(rt5677, &i2c->dev);
5183 else
5184 return -EINVAL;
5132 5185
5133 /* pow-ldo2 and reset are optional. The codec pins may be statically 5186 /* pow-ldo2 and reset are optional. The codec pins may be statically
5134 * connected on the board without gpios. If the gpio device property 5187 * connected on the board without gpios. If the gpio device property
diff --git a/sound/soc/codecs/sgtl5000.c b/sound/soc/codecs/sgtl5000.c
index 527b759c1562..1589325855bc 100644
--- a/sound/soc/codecs/sgtl5000.c
+++ b/sound/soc/codecs/sgtl5000.c
@@ -411,6 +411,8 @@ static const struct snd_kcontrol_new sgtl5000_snd_controls[] = {
411 0, 8, 411 0, 8,
412 0x7f, 1, 412 0x7f, 1,
413 headphone_volume), 413 headphone_volume),
414 SOC_SINGLE("Headphone Playback Switch", SGTL5000_CHIP_ANA_CTRL,
415 4, 1, 1),
414 SOC_SINGLE("Headphone Playback ZC Switch", SGTL5000_CHIP_ANA_CTRL, 416 SOC_SINGLE("Headphone Playback ZC Switch", SGTL5000_CHIP_ANA_CTRL,
415 5, 1, 0), 417 5, 1, 0),
416 418
@@ -423,6 +425,7 @@ static const struct snd_kcontrol_new sgtl5000_snd_controls[] = {
423 SGTL5000_LINE_OUT_VOL_RIGHT_SHIFT, 425 SGTL5000_LINE_OUT_VOL_RIGHT_SHIFT,
424 0x1f, 1, 426 0x1f, 1,
425 lineout_volume), 427 lineout_volume),
428 SOC_SINGLE("Lineout Playback Switch", SGTL5000_CHIP_ANA_CTRL, 8, 1, 1),
426}; 429};
427 430
428/* mute the codec used by alsa core */ 431/* mute the codec used by alsa core */
@@ -1151,12 +1154,14 @@ static struct snd_soc_codec_driver sgtl5000_driver = {
1151 .remove = sgtl5000_remove, 1154 .remove = sgtl5000_remove,
1152 .set_bias_level = sgtl5000_set_bias_level, 1155 .set_bias_level = sgtl5000_set_bias_level,
1153 .suspend_bias_off = true, 1156 .suspend_bias_off = true,
1154 .controls = sgtl5000_snd_controls, 1157 .component_driver = {
1155 .num_controls = ARRAY_SIZE(sgtl5000_snd_controls), 1158 .controls = sgtl5000_snd_controls,
1156 .dapm_widgets = sgtl5000_dapm_widgets, 1159 .num_controls = ARRAY_SIZE(sgtl5000_snd_controls),
1157 .num_dapm_widgets = ARRAY_SIZE(sgtl5000_dapm_widgets), 1160 .dapm_widgets = sgtl5000_dapm_widgets,
1158 .dapm_routes = sgtl5000_dapm_routes, 1161 .num_dapm_widgets = ARRAY_SIZE(sgtl5000_dapm_widgets),
1159 .num_dapm_routes = ARRAY_SIZE(sgtl5000_dapm_routes), 1162 .dapm_routes = sgtl5000_dapm_routes,
1163 .num_dapm_routes = ARRAY_SIZE(sgtl5000_dapm_routes),
1164 },
1160}; 1165};
1161 1166
1162static const struct regmap_config sgtl5000_regmap = { 1167static const struct regmap_config sgtl5000_regmap = {
diff --git a/sound/soc/codecs/si476x.c b/sound/soc/codecs/si476x.c
index a8402d0af0ea..5344f4aa8fde 100644
--- a/sound/soc/codecs/si476x.c
+++ b/sound/soc/codecs/si476x.c
@@ -238,10 +238,12 @@ static struct regmap *si476x_get_regmap(struct device *dev)
238 238
239static struct snd_soc_codec_driver soc_codec_dev_si476x = { 239static struct snd_soc_codec_driver soc_codec_dev_si476x = {
240 .get_regmap = si476x_get_regmap, 240 .get_regmap = si476x_get_regmap,
241 .dapm_widgets = si476x_dapm_widgets, 241 .component_driver = {
242 .num_dapm_widgets = ARRAY_SIZE(si476x_dapm_widgets), 242 .dapm_widgets = si476x_dapm_widgets,
243 .dapm_routes = si476x_dapm_routes, 243 .num_dapm_widgets = ARRAY_SIZE(si476x_dapm_widgets),
244 .num_dapm_routes = ARRAY_SIZE(si476x_dapm_routes), 244 .dapm_routes = si476x_dapm_routes,
245 .num_dapm_routes = ARRAY_SIZE(si476x_dapm_routes),
246 },
245}; 247};
246 248
247static int si476x_platform_probe(struct platform_device *pdev) 249static int si476x_platform_probe(struct platform_device *pdev)
diff --git a/sound/soc/codecs/sn95031.c b/sound/soc/codecs/sn95031.c
index 3a7de0159f24..eae54c37cff9 100644
--- a/sound/soc/codecs/sn95031.c
+++ b/sound/soc/codecs/sn95031.c
@@ -888,12 +888,14 @@ static struct snd_soc_codec_driver sn95031_codec = {
888 .set_bias_level = sn95031_set_vaud_bias, 888 .set_bias_level = sn95031_set_vaud_bias,
889 .idle_bias_off = true, 889 .idle_bias_off = true,
890 890
891 .controls = sn95031_snd_controls, 891 .component_driver = {
892 .num_controls = ARRAY_SIZE(sn95031_snd_controls), 892 .controls = sn95031_snd_controls,
893 .dapm_widgets = sn95031_dapm_widgets, 893 .num_controls = ARRAY_SIZE(sn95031_snd_controls),
894 .num_dapm_widgets = ARRAY_SIZE(sn95031_dapm_widgets), 894 .dapm_widgets = sn95031_dapm_widgets,
895 .dapm_routes = sn95031_audio_map, 895 .num_dapm_widgets = ARRAY_SIZE(sn95031_dapm_widgets),
896 .num_dapm_routes = ARRAY_SIZE(sn95031_audio_map), 896 .dapm_routes = sn95031_audio_map,
897 .num_dapm_routes = ARRAY_SIZE(sn95031_audio_map),
898 },
897}; 899};
898 900
899static int sn95031_device_probe(struct platform_device *pdev) 901static int sn95031_device_probe(struct platform_device *pdev)
diff --git a/sound/soc/codecs/spdif_receiver.c b/sound/soc/codecs/spdif_receiver.c
index 3ec41ccbf4e2..234f87b54838 100644
--- a/sound/soc/codecs/spdif_receiver.c
+++ b/sound/soc/codecs/spdif_receiver.c
@@ -38,10 +38,12 @@ static const struct snd_soc_dapm_route dir_routes[] = {
38 SNDRV_PCM_FMTBIT_IEC958_SUBFRAME_LE) 38 SNDRV_PCM_FMTBIT_IEC958_SUBFRAME_LE)
39 39
40static struct snd_soc_codec_driver soc_codec_spdif_dir = { 40static struct snd_soc_codec_driver soc_codec_spdif_dir = {
41 .dapm_widgets = dir_widgets, 41 .component_driver = {
42 .num_dapm_widgets = ARRAY_SIZE(dir_widgets), 42 .dapm_widgets = dir_widgets,
43 .dapm_routes = dir_routes, 43 .num_dapm_widgets = ARRAY_SIZE(dir_widgets),
44 .num_dapm_routes = ARRAY_SIZE(dir_routes), 44 .dapm_routes = dir_routes,
45 .num_dapm_routes = ARRAY_SIZE(dir_routes),
46 },
45}; 47};
46 48
47static struct snd_soc_dai_driver dir_stub_dai = { 49static struct snd_soc_dai_driver dir_stub_dai = {
diff --git a/sound/soc/codecs/spdif_transmitter.c b/sound/soc/codecs/spdif_transmitter.c
index ef634a9ad673..ee367536a498 100644
--- a/sound/soc/codecs/spdif_transmitter.c
+++ b/sound/soc/codecs/spdif_transmitter.c
@@ -38,10 +38,12 @@ static const struct snd_soc_dapm_route dit_routes[] = {
38}; 38};
39 39
40static struct snd_soc_codec_driver soc_codec_spdif_dit = { 40static struct snd_soc_codec_driver soc_codec_spdif_dit = {
41 .dapm_widgets = dit_widgets, 41 .component_driver = {
42 .num_dapm_widgets = ARRAY_SIZE(dit_widgets), 42 .dapm_widgets = dit_widgets,
43 .dapm_routes = dit_routes, 43 .num_dapm_widgets = ARRAY_SIZE(dit_widgets),
44 .num_dapm_routes = ARRAY_SIZE(dit_routes), 44 .dapm_routes = dit_routes,
45 .num_dapm_routes = ARRAY_SIZE(dit_routes),
46 },
45}; 47};
46 48
47static struct snd_soc_dai_driver dit_stub_dai = { 49static struct snd_soc_dai_driver dit_stub_dai = {
diff --git a/sound/soc/codecs/ssm2518.c b/sound/soc/codecs/ssm2518.c
index e2e0bfa7ec20..38a85f3adc80 100644
--- a/sound/soc/codecs/ssm2518.c
+++ b/sound/soc/codecs/ssm2518.c
@@ -715,12 +715,14 @@ static struct snd_soc_codec_driver ssm2518_codec_driver = {
715 .set_sysclk = ssm2518_set_sysclk, 715 .set_sysclk = ssm2518_set_sysclk,
716 .idle_bias_off = true, 716 .idle_bias_off = true,
717 717
718 .controls = ssm2518_snd_controls, 718 .component_driver = {
719 .num_controls = ARRAY_SIZE(ssm2518_snd_controls), 719 .controls = ssm2518_snd_controls,
720 .dapm_widgets = ssm2518_dapm_widgets, 720 .num_controls = ARRAY_SIZE(ssm2518_snd_controls),
721 .num_dapm_widgets = ARRAY_SIZE(ssm2518_dapm_widgets), 721 .dapm_widgets = ssm2518_dapm_widgets,
722 .dapm_routes = ssm2518_routes, 722 .num_dapm_widgets = ARRAY_SIZE(ssm2518_dapm_widgets),
723 .num_dapm_routes = ARRAY_SIZE(ssm2518_routes), 723 .dapm_routes = ssm2518_routes,
724 .num_dapm_routes = ARRAY_SIZE(ssm2518_routes),
725 },
724}; 726};
725 727
726static const struct regmap_config ssm2518_regmap_config = { 728static const struct regmap_config ssm2518_regmap_config = {
diff --git a/sound/soc/codecs/ssm2602.c b/sound/soc/codecs/ssm2602.c
index 4452fea0b118..993bde29ca1b 100644
--- a/sound/soc/codecs/ssm2602.c
+++ b/sound/soc/codecs/ssm2602.c
@@ -597,12 +597,14 @@ static struct snd_soc_codec_driver soc_codec_dev_ssm2602 = {
597 .set_bias_level = ssm2602_set_bias_level, 597 .set_bias_level = ssm2602_set_bias_level,
598 .suspend_bias_off = true, 598 .suspend_bias_off = true,
599 599
600 .controls = ssm260x_snd_controls, 600 .component_driver = {
601 .num_controls = ARRAY_SIZE(ssm260x_snd_controls), 601 .controls = ssm260x_snd_controls,
602 .dapm_widgets = ssm260x_dapm_widgets, 602 .num_controls = ARRAY_SIZE(ssm260x_snd_controls),
603 .num_dapm_widgets = ARRAY_SIZE(ssm260x_dapm_widgets), 603 .dapm_widgets = ssm260x_dapm_widgets,
604 .dapm_routes = ssm260x_routes, 604 .num_dapm_widgets = ARRAY_SIZE(ssm260x_dapm_widgets),
605 .num_dapm_routes = ARRAY_SIZE(ssm260x_routes), 605 .dapm_routes = ssm260x_routes,
606 .num_dapm_routes = ARRAY_SIZE(ssm260x_routes),
607 },
606}; 608};
607 609
608static bool ssm2602_register_volatile(struct device *dev, unsigned int reg) 610static bool ssm2602_register_volatile(struct device *dev, unsigned int reg)
diff --git a/sound/soc/codecs/ssm4567.c b/sound/soc/codecs/ssm4567.c
index 080c78e88e10..2bb5a11c9ba1 100644
--- a/sound/soc/codecs/ssm4567.c
+++ b/sound/soc/codecs/ssm4567.c
@@ -421,12 +421,14 @@ static struct snd_soc_codec_driver ssm4567_codec_driver = {
421 .set_bias_level = ssm4567_set_bias_level, 421 .set_bias_level = ssm4567_set_bias_level,
422 .idle_bias_off = true, 422 .idle_bias_off = true,
423 423
424 .controls = ssm4567_snd_controls, 424 .component_driver = {
425 .num_controls = ARRAY_SIZE(ssm4567_snd_controls), 425 .controls = ssm4567_snd_controls,
426 .dapm_widgets = ssm4567_dapm_widgets, 426 .num_controls = ARRAY_SIZE(ssm4567_snd_controls),
427 .num_dapm_widgets = ARRAY_SIZE(ssm4567_dapm_widgets), 427 .dapm_widgets = ssm4567_dapm_widgets,
428 .dapm_routes = ssm4567_routes, 428 .num_dapm_widgets = ARRAY_SIZE(ssm4567_dapm_widgets),
429 .num_dapm_routes = ARRAY_SIZE(ssm4567_routes), 429 .dapm_routes = ssm4567_routes,
430 .num_dapm_routes = ARRAY_SIZE(ssm4567_routes),
431 },
430}; 432};
431 433
432static const struct regmap_config ssm4567_regmap_config = { 434static const struct regmap_config ssm4567_regmap_config = {
diff --git a/sound/soc/codecs/sta32x.c b/sound/soc/codecs/sta32x.c
index a9844b2ac829..0790ae8530d9 100644
--- a/sound/soc/codecs/sta32x.c
+++ b/sound/soc/codecs/sta32x.c
@@ -991,12 +991,14 @@ static const struct snd_soc_codec_driver sta32x_codec = {
991 .remove = sta32x_remove, 991 .remove = sta32x_remove,
992 .set_bias_level = sta32x_set_bias_level, 992 .set_bias_level = sta32x_set_bias_level,
993 .suspend_bias_off = true, 993 .suspend_bias_off = true,
994 .controls = sta32x_snd_controls, 994 .component_driver = {
995 .num_controls = ARRAY_SIZE(sta32x_snd_controls), 995 .controls = sta32x_snd_controls,
996 .dapm_widgets = sta32x_dapm_widgets, 996 .num_controls = ARRAY_SIZE(sta32x_snd_controls),
997 .num_dapm_widgets = ARRAY_SIZE(sta32x_dapm_widgets), 997 .dapm_widgets = sta32x_dapm_widgets,
998 .dapm_routes = sta32x_dapm_routes, 998 .num_dapm_widgets = ARRAY_SIZE(sta32x_dapm_widgets),
999 .num_dapm_routes = ARRAY_SIZE(sta32x_dapm_routes), 999 .dapm_routes = sta32x_dapm_routes,
1000 .num_dapm_routes = ARRAY_SIZE(sta32x_dapm_routes),
1001 },
1000}; 1002};
1001 1003
1002static const struct regmap_config sta32x_regmap = { 1004static const struct regmap_config sta32x_regmap = {
diff --git a/sound/soc/codecs/sta350.c b/sound/soc/codecs/sta350.c
index 33a4612f0a07..9644c20f44e3 100644
--- a/sound/soc/codecs/sta350.c
+++ b/sound/soc/codecs/sta350.c
@@ -1057,12 +1057,14 @@ static const struct snd_soc_codec_driver sta350_codec = {
1057 .remove = sta350_remove, 1057 .remove = sta350_remove,
1058 .set_bias_level = sta350_set_bias_level, 1058 .set_bias_level = sta350_set_bias_level,
1059 .suspend_bias_off = true, 1059 .suspend_bias_off = true,
1060 .controls = sta350_snd_controls, 1060 .component_driver = {
1061 .num_controls = ARRAY_SIZE(sta350_snd_controls), 1061 .controls = sta350_snd_controls,
1062 .dapm_widgets = sta350_dapm_widgets, 1062 .num_controls = ARRAY_SIZE(sta350_snd_controls),
1063 .num_dapm_widgets = ARRAY_SIZE(sta350_dapm_widgets), 1063 .dapm_widgets = sta350_dapm_widgets,
1064 .dapm_routes = sta350_dapm_routes, 1064 .num_dapm_widgets = ARRAY_SIZE(sta350_dapm_widgets),
1065 .num_dapm_routes = ARRAY_SIZE(sta350_dapm_routes), 1065 .dapm_routes = sta350_dapm_routes,
1066 .num_dapm_routes = ARRAY_SIZE(sta350_dapm_routes),
1067 },
1066}; 1068};
1067 1069
1068static const struct regmap_config sta350_regmap = { 1070static const struct regmap_config sta350_regmap = {
diff --git a/sound/soc/codecs/sta529.c b/sound/soc/codecs/sta529.c
index 2cdaca943a8c..d4b384e4b266 100644
--- a/sound/soc/codecs/sta529.c
+++ b/sound/soc/codecs/sta529.c
@@ -317,8 +317,10 @@ static const struct snd_soc_codec_driver sta529_codec_driver = {
317 .set_bias_level = sta529_set_bias_level, 317 .set_bias_level = sta529_set_bias_level,
318 .suspend_bias_off = true, 318 .suspend_bias_off = true,
319 319
320 .controls = sta529_snd_controls, 320 .component_driver = {
321 .num_controls = ARRAY_SIZE(sta529_snd_controls), 321 .controls = sta529_snd_controls,
322 .num_controls = ARRAY_SIZE(sta529_snd_controls),
323 },
322}; 324};
323 325
324static const struct regmap_config sta529_regmap = { 326static const struct regmap_config sta529_regmap = {
diff --git a/sound/soc/codecs/stac9766.c b/sound/soc/codecs/stac9766.c
index 0945c51df003..27f30d352867 100644
--- a/sound/soc/codecs/stac9766.c
+++ b/sound/soc/codecs/stac9766.c
@@ -85,10 +85,10 @@ static SOC_ENUM_SINGLE_DECL(stac9766_boost2_enum,
85static SOC_ENUM_SINGLE_DECL(stac9766_stereo_mic_enum, 85static SOC_ENUM_SINGLE_DECL(stac9766_stereo_mic_enum,
86 AC97_STAC_STEREO_MIC, 2, stac9766_stereo_mic); 86 AC97_STAC_STEREO_MIC, 2, stac9766_stereo_mic);
87 87
88static const DECLARE_TLV_DB_LINEAR(master_tlv, -4600, 0); 88static const SNDRV_CTL_TLVD_DECLARE_DB_SCALE(master_tlv, -4650, 150, 0);
89static const DECLARE_TLV_DB_LINEAR(record_tlv, 0, 2250); 89static const SNDRV_CTL_TLVD_DECLARE_DB_SCALE(record_tlv, 0, 150, 0);
90static const DECLARE_TLV_DB_LINEAR(beep_tlv, -4500, 0); 90static const SNDRV_CTL_TLVD_DECLARE_DB_SCALE(beep_tlv, -4500, 300, 0);
91static const DECLARE_TLV_DB_LINEAR(mix_tlv, -3450, 1200); 91static const SNDRV_CTL_TLVD_DECLARE_DB_SCALE(mix_tlv, -3450, 150, 0);
92 92
93static const struct snd_kcontrol_new stac9766_snd_ac97_controls[] = { 93static const struct snd_kcontrol_new stac9766_snd_ac97_controls[] = {
94 SOC_DOUBLE_TLV("Speaker Volume", AC97_MASTER, 8, 0, 31, 1, master_tlv), 94 SOC_DOUBLE_TLV("Speaker Volume", AC97_MASTER, 8, 0, 31, 1, master_tlv),
@@ -320,8 +320,10 @@ static int stac9766_codec_remove(struct snd_soc_codec *codec)
320} 320}
321 321
322static struct snd_soc_codec_driver soc_codec_dev_stac9766 = { 322static struct snd_soc_codec_driver soc_codec_dev_stac9766 = {
323 .controls = stac9766_snd_ac97_controls, 323 .component_driver = {
324 .num_controls = ARRAY_SIZE(stac9766_snd_ac97_controls), 324 .controls = stac9766_snd_ac97_controls,
325 .num_controls = ARRAY_SIZE(stac9766_snd_ac97_controls),
326 },
325 .write = stac9766_ac97_write, 327 .write = stac9766_ac97_write,
326 .read = stac9766_ac97_read, 328 .read = stac9766_ac97_read,
327 .set_bias_level = stac9766_set_bias_level, 329 .set_bias_level = stac9766_set_bias_level,
diff --git a/sound/soc/codecs/sti-sas.c b/sound/soc/codecs/sti-sas.c
index 160d61a66204..7b31ee9b82bc 100644
--- a/sound/soc/codecs/sti-sas.c
+++ b/sound/soc/codecs/sti-sas.c
@@ -591,11 +591,11 @@ static int sti_sas_driver_probe(struct platform_device *pdev)
591 sti_sas_dai[STI_SAS_DAI_ANALOG_OUT].ops = drvdata->dev_data->dac_ops; 591 sti_sas_dai[STI_SAS_DAI_ANALOG_OUT].ops = drvdata->dev_data->dac_ops;
592 592
593 /* Set dapms*/ 593 /* Set dapms*/
594 sti_sas_driver.dapm_widgets = drvdata->dev_data->dapm_widgets; 594 sti_sas_driver.component_driver.dapm_widgets = drvdata->dev_data->dapm_widgets;
595 sti_sas_driver.num_dapm_widgets = drvdata->dev_data->num_dapm_widgets; 595 sti_sas_driver.component_driver.num_dapm_widgets = drvdata->dev_data->num_dapm_widgets;
596 596
597 sti_sas_driver.dapm_routes = drvdata->dev_data->dapm_routes; 597 sti_sas_driver.component_driver.dapm_routes = drvdata->dev_data->dapm_routes;
598 sti_sas_driver.num_dapm_routes = drvdata->dev_data->num_dapm_routes; 598 sti_sas_driver.component_driver.num_dapm_routes = drvdata->dev_data->num_dapm_routes;
599 599
600 /* Store context */ 600 /* Store context */
601 dev_set_drvdata(&pdev->dev, drvdata); 601 dev_set_drvdata(&pdev->dev, drvdata);
diff --git a/sound/soc/codecs/tas2552.c b/sound/soc/codecs/tas2552.c
index cc1d3981fa4b..baf455e8c2f7 100644
--- a/sound/soc/codecs/tas2552.c
+++ b/sound/soc/codecs/tas2552.c
@@ -667,12 +667,14 @@ static struct snd_soc_codec_driver soc_codec_dev_tas2552 = {
667 .resume = tas2552_resume, 667 .resume = tas2552_resume,
668 .ignore_pmdown_time = true, 668 .ignore_pmdown_time = true,
669 669
670 .controls = tas2552_snd_controls, 670 .component_driver = {
671 .num_controls = ARRAY_SIZE(tas2552_snd_controls), 671 .controls = tas2552_snd_controls,
672 .dapm_widgets = tas2552_dapm_widgets, 672 .num_controls = ARRAY_SIZE(tas2552_snd_controls),
673 .num_dapm_widgets = ARRAY_SIZE(tas2552_dapm_widgets), 673 .dapm_widgets = tas2552_dapm_widgets,
674 .dapm_routes = tas2552_audio_map, 674 .num_dapm_widgets = ARRAY_SIZE(tas2552_dapm_widgets),
675 .num_dapm_routes = ARRAY_SIZE(tas2552_audio_map), 675 .dapm_routes = tas2552_audio_map,
676 .num_dapm_routes = ARRAY_SIZE(tas2552_audio_map),
677 },
676}; 678};
677 679
678static const struct regmap_config tas2552_regmap_config = { 680static const struct regmap_config tas2552_regmap_config = {
diff --git a/sound/soc/codecs/tas5086.c b/sound/soc/codecs/tas5086.c
index d49d25d51957..b7de857abb16 100644
--- a/sound/soc/codecs/tas5086.c
+++ b/sound/soc/codecs/tas5086.c
@@ -387,7 +387,7 @@ static int tas5086_hw_params(struct snd_pcm_substream *substream,
387 val = index_in_array(tas5086_ratios, ARRAY_SIZE(tas5086_ratios), 387 val = index_in_array(tas5086_ratios, ARRAY_SIZE(tas5086_ratios),
388 priv->mclk / priv->rate); 388 priv->mclk / priv->rate);
389 if (val < 0) { 389 if (val < 0) {
390 dev_err(codec->dev, "Inavlid MCLK / Fs ratio\n"); 390 dev_err(codec->dev, "Invalid MCLK / Fs ratio\n");
391 return -EINVAL; 391 return -EINVAL;
392 } 392 }
393 393
@@ -890,12 +890,14 @@ static struct snd_soc_codec_driver soc_codec_dev_tas5086 = {
890 .remove = tas5086_remove, 890 .remove = tas5086_remove,
891 .suspend = tas5086_soc_suspend, 891 .suspend = tas5086_soc_suspend,
892 .resume = tas5086_soc_resume, 892 .resume = tas5086_soc_resume,
893 .controls = tas5086_controls, 893 .component_driver = {
894 .num_controls = ARRAY_SIZE(tas5086_controls), 894 .controls = tas5086_controls,
895 .dapm_widgets = tas5086_dapm_widgets, 895 .num_controls = ARRAY_SIZE(tas5086_controls),
896 .num_dapm_widgets = ARRAY_SIZE(tas5086_dapm_widgets), 896 .dapm_widgets = tas5086_dapm_widgets,
897 .dapm_routes = tas5086_dapm_routes, 897 .num_dapm_widgets = ARRAY_SIZE(tas5086_dapm_widgets),
898 .num_dapm_routes = ARRAY_SIZE(tas5086_dapm_routes), 898 .dapm_routes = tas5086_dapm_routes,
899 .num_dapm_routes = ARRAY_SIZE(tas5086_dapm_routes),
900 },
899}; 901};
900 902
901static const struct i2c_device_id tas5086_i2c_id[] = { 903static const struct i2c_device_id tas5086_i2c_id[] = {
diff --git a/sound/soc/codecs/tas571x.c b/sound/soc/codecs/tas571x.c
index d8baca3f8413..df5e5cb33baa 100644
--- a/sound/soc/codecs/tas571x.c
+++ b/sound/soc/codecs/tas571x.c
@@ -658,10 +658,12 @@ static const struct snd_soc_codec_driver tas571x_codec = {
658 .set_bias_level = tas571x_set_bias_level, 658 .set_bias_level = tas571x_set_bias_level,
659 .idle_bias_off = true, 659 .idle_bias_off = true,
660 660
661 .dapm_widgets = tas571x_dapm_widgets, 661 .component_driver = {
662 .num_dapm_widgets = ARRAY_SIZE(tas571x_dapm_widgets), 662 .dapm_widgets = tas571x_dapm_widgets,
663 .dapm_routes = tas571x_dapm_routes, 663 .num_dapm_widgets = ARRAY_SIZE(tas571x_dapm_widgets),
664 .num_dapm_routes = ARRAY_SIZE(tas571x_dapm_routes), 664 .dapm_routes = tas571x_dapm_routes,
665 .num_dapm_routes = ARRAY_SIZE(tas571x_dapm_routes),
666 },
665}; 667};
666 668
667static struct snd_soc_dai_driver tas571x_dai = { 669static struct snd_soc_dai_driver tas571x_dai = {
@@ -754,8 +756,8 @@ static int tas571x_i2c_probe(struct i2c_client *client,
754 756
755 757
756 memcpy(&priv->codec_driver, &tas571x_codec, sizeof(priv->codec_driver)); 758 memcpy(&priv->codec_driver, &tas571x_codec, sizeof(priv->codec_driver));
757 priv->codec_driver.controls = priv->chip->controls; 759 priv->codec_driver.component_driver.controls = priv->chip->controls;
758 priv->codec_driver.num_controls = priv->chip->num_controls; 760 priv->codec_driver.component_driver.num_controls = priv->chip->num_controls;
759 761
760 if (priv->chip->vol_reg_size == 2) { 762 if (priv->chip->vol_reg_size == 2) {
761 /* 763 /*
diff --git a/sound/soc/codecs/tas5720.c b/sound/soc/codecs/tas5720.c
index f54fb46b77c2..c65b917598d2 100644
--- a/sound/soc/codecs/tas5720.c
+++ b/sound/soc/codecs/tas5720.c
@@ -489,12 +489,14 @@ static struct snd_soc_codec_driver soc_codec_dev_tas5720 = {
489 .suspend = tas5720_suspend, 489 .suspend = tas5720_suspend,
490 .resume = tas5720_resume, 490 .resume = tas5720_resume,
491 491
492 .controls = tas5720_snd_controls, 492 .component_driver = {
493 .num_controls = ARRAY_SIZE(tas5720_snd_controls), 493 .controls = tas5720_snd_controls,
494 .dapm_widgets = tas5720_dapm_widgets, 494 .num_controls = ARRAY_SIZE(tas5720_snd_controls),
495 .num_dapm_widgets = ARRAY_SIZE(tas5720_dapm_widgets), 495 .dapm_widgets = tas5720_dapm_widgets,
496 .dapm_routes = tas5720_audio_map, 496 .num_dapm_widgets = ARRAY_SIZE(tas5720_dapm_widgets),
497 .num_dapm_routes = ARRAY_SIZE(tas5720_audio_map), 497 .dapm_routes = tas5720_audio_map,
498 .num_dapm_routes = ARRAY_SIZE(tas5720_audio_map),
499 },
498}; 500};
499 501
500/* PCM rates supported by the TAS5720 driver */ 502/* PCM rates supported by the TAS5720 driver */
diff --git a/sound/soc/codecs/tfa9879.c b/sound/soc/codecs/tfa9879.c
index cb5310d89c0f..95e0a7abeb7a 100644
--- a/sound/soc/codecs/tfa9879.c
+++ b/sound/soc/codecs/tfa9879.c
@@ -231,13 +231,14 @@ static const struct snd_soc_dapm_route tfa9879_dapm_routes[] = {
231}; 231};
232 232
233static const struct snd_soc_codec_driver tfa9879_codec = { 233static const struct snd_soc_codec_driver tfa9879_codec = {
234 .controls = tfa9879_controls, 234 .component_driver = {
235 .num_controls = ARRAY_SIZE(tfa9879_controls), 235 .controls = tfa9879_controls,
236 236 .num_controls = ARRAY_SIZE(tfa9879_controls),
237 .dapm_widgets = tfa9879_dapm_widgets, 237 .dapm_widgets = tfa9879_dapm_widgets,
238 .num_dapm_widgets = ARRAY_SIZE(tfa9879_dapm_widgets), 238 .num_dapm_widgets = ARRAY_SIZE(tfa9879_dapm_widgets),
239 .dapm_routes = tfa9879_dapm_routes, 239 .dapm_routes = tfa9879_dapm_routes,
240 .num_dapm_routes = ARRAY_SIZE(tfa9879_dapm_routes), 240 .num_dapm_routes = ARRAY_SIZE(tfa9879_dapm_routes),
241 },
241}; 242};
242 243
243static const struct regmap_config tfa9879_regmap = { 244static const struct regmap_config tfa9879_regmap = {
diff --git a/sound/soc/codecs/tlv320aic23.c b/sound/soc/codecs/tlv320aic23.c
index cd8c02b6e4de..410cae0f2060 100644
--- a/sound/soc/codecs/tlv320aic23.c
+++ b/sound/soc/codecs/tlv320aic23.c
@@ -583,12 +583,14 @@ static struct snd_soc_codec_driver soc_codec_dev_tlv320aic23 = {
583 .set_bias_level = tlv320aic23_set_bias_level, 583 .set_bias_level = tlv320aic23_set_bias_level,
584 .suspend_bias_off = true, 584 .suspend_bias_off = true,
585 585
586 .controls = tlv320aic23_snd_controls, 586 .component_driver = {
587 .num_controls = ARRAY_SIZE(tlv320aic23_snd_controls), 587 .controls = tlv320aic23_snd_controls,
588 .dapm_widgets = tlv320aic23_dapm_widgets, 588 .num_controls = ARRAY_SIZE(tlv320aic23_snd_controls),
589 .num_dapm_widgets = ARRAY_SIZE(tlv320aic23_dapm_widgets), 589 .dapm_widgets = tlv320aic23_dapm_widgets,
590 .dapm_routes = tlv320aic23_intercon, 590 .num_dapm_widgets = ARRAY_SIZE(tlv320aic23_dapm_widgets),
591 .num_dapm_routes = ARRAY_SIZE(tlv320aic23_intercon), 591 .dapm_routes = tlv320aic23_intercon,
592 .num_dapm_routes = ARRAY_SIZE(tlv320aic23_intercon),
593 },
592}; 594};
593 595
594int tlv320aic23_probe(struct device *dev, struct regmap *regmap) 596int tlv320aic23_probe(struct device *dev, struct regmap *regmap)
diff --git a/sound/soc/codecs/tlv320aic26.c b/sound/soc/codecs/tlv320aic26.c
index 2c904d7150ad..14aa96d41719 100644
--- a/sound/soc/codecs/tlv320aic26.c
+++ b/sound/soc/codecs/tlv320aic26.c
@@ -321,12 +321,14 @@ static int aic26_probe(struct snd_soc_codec *codec)
321 321
322static struct snd_soc_codec_driver aic26_soc_codec_dev = { 322static struct snd_soc_codec_driver aic26_soc_codec_dev = {
323 .probe = aic26_probe, 323 .probe = aic26_probe,
324 .controls = aic26_snd_controls, 324 .component_driver = {
325 .num_controls = ARRAY_SIZE(aic26_snd_controls), 325 .controls = aic26_snd_controls,
326 .dapm_widgets = tlv320aic26_dapm_widgets, 326 .num_controls = ARRAY_SIZE(aic26_snd_controls),
327 .num_dapm_widgets = ARRAY_SIZE(tlv320aic26_dapm_widgets), 327 .dapm_widgets = tlv320aic26_dapm_widgets,
328 .dapm_routes = tlv320aic26_dapm_routes, 328 .num_dapm_widgets = ARRAY_SIZE(tlv320aic26_dapm_widgets),
329 .num_dapm_routes = ARRAY_SIZE(tlv320aic26_dapm_routes), 329 .dapm_routes = tlv320aic26_dapm_routes,
330 .num_dapm_routes = ARRAY_SIZE(tlv320aic26_dapm_routes),
331 },
330}; 332};
331 333
332static const struct regmap_config aic26_regmap = { 334static const struct regmap_config aic26_regmap = {
diff --git a/sound/soc/codecs/tlv320aic31xx.c b/sound/soc/codecs/tlv320aic31xx.c
index 3c5e1df01c19..be1a64bfd320 100644
--- a/sound/soc/codecs/tlv320aic31xx.c
+++ b/sound/soc/codecs/tlv320aic31xx.c
@@ -273,10 +273,20 @@ static const DECLARE_TLV_DB_SCALE(sp_vol_tlv, -6350, 50, 0);
273/* 273/*
274 * controls to be exported to the user space 274 * controls to be exported to the user space
275 */ 275 */
276static const struct snd_kcontrol_new aic31xx_snd_controls[] = { 276static const struct snd_kcontrol_new common31xx_snd_controls[] = {
277 SOC_DOUBLE_R_S_TLV("DAC Playback Volume", AIC31XX_LDACVOL, 277 SOC_DOUBLE_R_S_TLV("DAC Playback Volume", AIC31XX_LDACVOL,
278 AIC31XX_RDACVOL, 0, -127, 48, 7, 0, dac_vol_tlv), 278 AIC31XX_RDACVOL, 0, -127, 48, 7, 0, dac_vol_tlv),
279 279
280 SOC_DOUBLE_R("HP Driver Playback Switch", AIC31XX_HPLGAIN,
281 AIC31XX_HPRGAIN, 2, 1, 0),
282 SOC_DOUBLE_R_TLV("HP Driver Playback Volume", AIC31XX_HPLGAIN,
283 AIC31XX_HPRGAIN, 3, 0x09, 0, hp_drv_tlv),
284
285 SOC_DOUBLE_R_TLV("HP Analog Playback Volume", AIC31XX_LANALOGHPL,
286 AIC31XX_RANALOGHPR, 0, 0x7F, 1, hp_vol_tlv),
287};
288
289static const struct snd_kcontrol_new aic31xx_snd_controls[] = {
280 SOC_SINGLE_TLV("ADC Fine Capture Volume", AIC31XX_ADCFGA, 4, 4, 1, 290 SOC_SINGLE_TLV("ADC Fine Capture Volume", AIC31XX_ADCFGA, 4, 4, 1,
281 adc_fgain_tlv), 291 adc_fgain_tlv),
282 292
@@ -286,14 +296,6 @@ static const struct snd_kcontrol_new aic31xx_snd_controls[] = {
286 296
287 SOC_SINGLE_TLV("Mic PGA Capture Volume", AIC31XX_MICPGA, 0, 297 SOC_SINGLE_TLV("Mic PGA Capture Volume", AIC31XX_MICPGA, 0,
288 119, 0, mic_pga_tlv), 298 119, 0, mic_pga_tlv),
289
290 SOC_DOUBLE_R("HP Driver Playback Switch", AIC31XX_HPLGAIN,
291 AIC31XX_HPRGAIN, 2, 1, 0),
292 SOC_DOUBLE_R_TLV("HP Driver Playback Volume", AIC31XX_HPLGAIN,
293 AIC31XX_HPRGAIN, 3, 0x09, 0, hp_drv_tlv),
294
295 SOC_DOUBLE_R_TLV("HP Analog Playback Volume", AIC31XX_LANALOGHPL,
296 AIC31XX_RANALOGHPR, 0, 0x7F, 1, hp_vol_tlv),
297}; 299};
298 300
299static const struct snd_kcontrol_new aic311x_snd_controls[] = { 301static const struct snd_kcontrol_new aic311x_snd_controls[] = {
@@ -397,17 +399,28 @@ static int aic31xx_dapm_power_event(struct snd_soc_dapm_widget *w,
397 return 0; 399 return 0;
398} 400}
399 401
400static const struct snd_kcontrol_new left_output_switches[] = { 402static const struct snd_kcontrol_new aic31xx_left_output_switches[] = {
401 SOC_DAPM_SINGLE("From Left DAC", AIC31XX_DACMIXERROUTE, 6, 1, 0), 403 SOC_DAPM_SINGLE("From Left DAC", AIC31XX_DACMIXERROUTE, 6, 1, 0),
402 SOC_DAPM_SINGLE("From MIC1LP", AIC31XX_DACMIXERROUTE, 5, 1, 0), 404 SOC_DAPM_SINGLE("From MIC1LP", AIC31XX_DACMIXERROUTE, 5, 1, 0),
403 SOC_DAPM_SINGLE("From MIC1RP", AIC31XX_DACMIXERROUTE, 4, 1, 0), 405 SOC_DAPM_SINGLE("From MIC1RP", AIC31XX_DACMIXERROUTE, 4, 1, 0),
404}; 406};
405 407
406static const struct snd_kcontrol_new right_output_switches[] = { 408static const struct snd_kcontrol_new aic31xx_right_output_switches[] = {
407 SOC_DAPM_SINGLE("From Right DAC", AIC31XX_DACMIXERROUTE, 2, 1, 0), 409 SOC_DAPM_SINGLE("From Right DAC", AIC31XX_DACMIXERROUTE, 2, 1, 0),
408 SOC_DAPM_SINGLE("From MIC1RP", AIC31XX_DACMIXERROUTE, 1, 1, 0), 410 SOC_DAPM_SINGLE("From MIC1RP", AIC31XX_DACMIXERROUTE, 1, 1, 0),
409}; 411};
410 412
413static const struct snd_kcontrol_new dac31xx_left_output_switches[] = {
414 SOC_DAPM_SINGLE("From Left DAC", AIC31XX_DACMIXERROUTE, 6, 1, 0),
415 SOC_DAPM_SINGLE("From AIN1", AIC31XX_DACMIXERROUTE, 5, 1, 0),
416 SOC_DAPM_SINGLE("From AIN2", AIC31XX_DACMIXERROUTE, 4, 1, 0),
417};
418
419static const struct snd_kcontrol_new dac31xx_right_output_switches[] = {
420 SOC_DAPM_SINGLE("From Right DAC", AIC31XX_DACMIXERROUTE, 2, 1, 0),
421 SOC_DAPM_SINGLE("From AIN2", AIC31XX_DACMIXERROUTE, 1, 1, 0),
422};
423
411static const struct snd_kcontrol_new p_term_mic1lp = 424static const struct snd_kcontrol_new p_term_mic1lp =
412 SOC_DAPM_ENUM("MIC1LP P-Terminal", mic1lp_p_enum); 425 SOC_DAPM_ENUM("MIC1LP P-Terminal", mic1lp_p_enum);
413 426
@@ -457,7 +470,7 @@ static int mic_bias_event(struct snd_soc_dapm_widget *w,
457 return 0; 470 return 0;
458} 471}
459 472
460static const struct snd_soc_dapm_widget aic31xx_dapm_widgets[] = { 473static const struct snd_soc_dapm_widget common31xx_dapm_widgets[] = {
461 SND_SOC_DAPM_AIF_IN("DAC IN", "DAC Playback", 0, SND_SOC_NOPM, 0, 0), 474 SND_SOC_DAPM_AIF_IN("DAC IN", "DAC Playback", 0, SND_SOC_NOPM, 0, 0),
462 475
463 SND_SOC_DAPM_MUX("DAC Left Input", 476 SND_SOC_DAPM_MUX("DAC Left Input",
@@ -473,14 +486,7 @@ static const struct snd_soc_dapm_widget aic31xx_dapm_widgets[] = {
473 AIC31XX_DACSETUP, 6, 0, aic31xx_dapm_power_event, 486 AIC31XX_DACSETUP, 6, 0, aic31xx_dapm_power_event,
474 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), 487 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
475 488
476 /* Output Mixers */ 489 /* HP */
477 SND_SOC_DAPM_MIXER("Output Left", SND_SOC_NOPM, 0, 0,
478 left_output_switches,
479 ARRAY_SIZE(left_output_switches)),
480 SND_SOC_DAPM_MIXER("Output Right", SND_SOC_NOPM, 0, 0,
481 right_output_switches,
482 ARRAY_SIZE(right_output_switches)),
483
484 SND_SOC_DAPM_SWITCH("HP Left", SND_SOC_NOPM, 0, 0, 490 SND_SOC_DAPM_SWITCH("HP Left", SND_SOC_NOPM, 0, 0,
485 &aic31xx_dapm_hpl_switch), 491 &aic31xx_dapm_hpl_switch),
486 SND_SOC_DAPM_SWITCH("HP Right", SND_SOC_NOPM, 0, 0, 492 SND_SOC_DAPM_SWITCH("HP Right", SND_SOC_NOPM, 0, 0,
@@ -494,10 +500,34 @@ static const struct snd_soc_dapm_widget aic31xx_dapm_widgets[] = {
494 NULL, 0, aic31xx_dapm_power_event, 500 NULL, 0, aic31xx_dapm_power_event,
495 SND_SOC_DAPM_POST_PMD | SND_SOC_DAPM_POST_PMU), 501 SND_SOC_DAPM_POST_PMD | SND_SOC_DAPM_POST_PMU),
496 502
497 /* ADC */ 503 /* Mic Bias */
498 SND_SOC_DAPM_ADC_E("ADC", "Capture", AIC31XX_ADCSETUP, 7, 0, 504 SND_SOC_DAPM_SUPPLY("MICBIAS", SND_SOC_NOPM, 0, 0, mic_bias_event,
499 aic31xx_dapm_power_event, SND_SOC_DAPM_POST_PMU | 505 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
500 SND_SOC_DAPM_POST_PMD), 506
507 /* Outputs */
508 SND_SOC_DAPM_OUTPUT("HPL"),
509 SND_SOC_DAPM_OUTPUT("HPR"),
510};
511
512static const struct snd_soc_dapm_widget dac31xx_dapm_widgets[] = {
513 /* Inputs */
514 SND_SOC_DAPM_INPUT("AIN1"),
515 SND_SOC_DAPM_INPUT("AIN2"),
516
517 /* Output Mixers */
518 SND_SOC_DAPM_MIXER("Output Left", SND_SOC_NOPM, 0, 0,
519 dac31xx_left_output_switches,
520 ARRAY_SIZE(dac31xx_left_output_switches)),
521 SND_SOC_DAPM_MIXER("Output Right", SND_SOC_NOPM, 0, 0,
522 dac31xx_right_output_switches,
523 ARRAY_SIZE(dac31xx_right_output_switches)),
524};
525
526static const struct snd_soc_dapm_widget aic31xx_dapm_widgets[] = {
527 /* Inputs */
528 SND_SOC_DAPM_INPUT("MIC1LP"),
529 SND_SOC_DAPM_INPUT("MIC1RP"),
530 SND_SOC_DAPM_INPUT("MIC1LM"),
501 531
502 /* Input Selection to MIC_PGA */ 532 /* Input Selection to MIC_PGA */
503 SND_SOC_DAPM_MUX("MIC1LP P-Terminal", SND_SOC_NOPM, 0, 0, 533 SND_SOC_DAPM_MUX("MIC1LP P-Terminal", SND_SOC_NOPM, 0, 0,
@@ -507,24 +537,25 @@ static const struct snd_soc_dapm_widget aic31xx_dapm_widgets[] = {
507 SND_SOC_DAPM_MUX("MIC1LM P-Terminal", SND_SOC_NOPM, 0, 0, 537 SND_SOC_DAPM_MUX("MIC1LM P-Terminal", SND_SOC_NOPM, 0, 0,
508 &p_term_mic1lm), 538 &p_term_mic1lm),
509 539
540 /* ADC */
541 SND_SOC_DAPM_ADC_E("ADC", "Capture", AIC31XX_ADCSETUP, 7, 0,
542 aic31xx_dapm_power_event, SND_SOC_DAPM_POST_PMU |
543 SND_SOC_DAPM_POST_PMD),
544
510 SND_SOC_DAPM_MUX("MIC1LM M-Terminal", SND_SOC_NOPM, 0, 0, 545 SND_SOC_DAPM_MUX("MIC1LM M-Terminal", SND_SOC_NOPM, 0, 0,
511 &m_term_mic1lm), 546 &m_term_mic1lm),
547
512 /* Enabling & Disabling MIC Gain Ctl */ 548 /* Enabling & Disabling MIC Gain Ctl */
513 SND_SOC_DAPM_PGA("MIC_GAIN_CTL", AIC31XX_MICPGA, 549 SND_SOC_DAPM_PGA("MIC_GAIN_CTL", AIC31XX_MICPGA,
514 7, 1, NULL, 0), 550 7, 1, NULL, 0),
515 551
516 /* Mic Bias */ 552 /* Output Mixers */
517 SND_SOC_DAPM_SUPPLY("MICBIAS", SND_SOC_NOPM, 0, 0, mic_bias_event, 553 SND_SOC_DAPM_MIXER("Output Left", SND_SOC_NOPM, 0, 0,
518 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), 554 aic31xx_left_output_switches,
519 555 ARRAY_SIZE(aic31xx_left_output_switches)),
520 /* Outputs */ 556 SND_SOC_DAPM_MIXER("Output Right", SND_SOC_NOPM, 0, 0,
521 SND_SOC_DAPM_OUTPUT("HPL"), 557 aic31xx_right_output_switches,
522 SND_SOC_DAPM_OUTPUT("HPR"), 558 ARRAY_SIZE(aic31xx_right_output_switches)),
523
524 /* Inputs */
525 SND_SOC_DAPM_INPUT("MIC1LP"),
526 SND_SOC_DAPM_INPUT("MIC1RP"),
527 SND_SOC_DAPM_INPUT("MIC1LM"),
528}; 559};
529 560
530static const struct snd_soc_dapm_widget aic311x_dapm_widgets[] = { 561static const struct snd_soc_dapm_widget aic311x_dapm_widgets[] = {
@@ -554,7 +585,7 @@ static const struct snd_soc_dapm_widget aic310x_dapm_widgets[] = {
554}; 585};
555 586
556static const struct snd_soc_dapm_route 587static const struct snd_soc_dapm_route
557aic31xx_audio_map[] = { 588common31xx_audio_map[] = {
558 /* DAC Input Routing */ 589 /* DAC Input Routing */
559 {"DAC Left Input", "Left Data", "DAC IN"}, 590 {"DAC Left Input", "Left Data", "DAC IN"},
560 {"DAC Left Input", "Right Data", "DAC IN"}, 591 {"DAC Left Input", "Right Data", "DAC IN"},
@@ -565,6 +596,31 @@ aic31xx_audio_map[] = {
565 {"DAC Left", NULL, "DAC Left Input"}, 596 {"DAC Left", NULL, "DAC Left Input"},
566 {"DAC Right", NULL, "DAC Right Input"}, 597 {"DAC Right", NULL, "DAC Right Input"},
567 598
599 /* HPL path */
600 {"HP Left", "Switch", "Output Left"},
601 {"HPL Driver", NULL, "HP Left"},
602 {"HPL", NULL, "HPL Driver"},
603
604 /* HPR path */
605 {"HP Right", "Switch", "Output Right"},
606 {"HPR Driver", NULL, "HP Right"},
607 {"HPR", NULL, "HPR Driver"},
608};
609
610static const struct snd_soc_dapm_route
611dac31xx_audio_map[] = {
612 /* Left Output */
613 {"Output Left", "From Left DAC", "DAC Left"},
614 {"Output Left", "From AIN1", "AIN1"},
615 {"Output Left", "From AIN2", "AIN2"},
616
617 /* Right Output */
618 {"Output Right", "From Right DAC", "DAC Right"},
619 {"Output Right", "From AIN2", "AIN2"},
620};
621
622static const struct snd_soc_dapm_route
623aic31xx_audio_map[] = {
568 /* Mic input */ 624 /* Mic input */
569 {"MIC1LP P-Terminal", "FFR 10 Ohm", "MIC1LP"}, 625 {"MIC1LP P-Terminal", "FFR 10 Ohm", "MIC1LP"},
570 {"MIC1LP P-Terminal", "FFR 20 Ohm", "MIC1LP"}, 626 {"MIC1LP P-Terminal", "FFR 20 Ohm", "MIC1LP"},
@@ -595,16 +651,6 @@ aic31xx_audio_map[] = {
595 /* Right Output */ 651 /* Right Output */
596 {"Output Right", "From Right DAC", "DAC Right"}, 652 {"Output Right", "From Right DAC", "DAC Right"},
597 {"Output Right", "From MIC1RP", "MIC1RP"}, 653 {"Output Right", "From MIC1RP", "MIC1RP"},
598
599 /* HPL path */
600 {"HP Left", "Switch", "Output Left"},
601 {"HPL Driver", NULL, "HP Left"},
602 {"HPL", NULL, "HPL Driver"},
603
604 /* HPR path */
605 {"HP Right", "Switch", "Output Right"},
606 {"HPR Driver", NULL, "HP Right"},
607 {"HPR", NULL, "HPR Driver"},
608}; 654};
609 655
610static const struct snd_soc_dapm_route 656static const struct snd_soc_dapm_route
@@ -633,6 +679,13 @@ static int aic31xx_add_controls(struct snd_soc_codec *codec)
633 int ret = 0; 679 int ret = 0;
634 struct aic31xx_priv *aic31xx = snd_soc_codec_get_drvdata(codec); 680 struct aic31xx_priv *aic31xx = snd_soc_codec_get_drvdata(codec);
635 681
682 if (!(aic31xx->pdata.codec_type & DAC31XX_BIT))
683 ret = snd_soc_add_codec_controls(
684 codec, aic31xx_snd_controls,
685 ARRAY_SIZE(aic31xx_snd_controls));
686 if (ret)
687 return ret;
688
636 if (aic31xx->pdata.codec_type & AIC31XX_STEREO_CLASS_D_BIT) 689 if (aic31xx->pdata.codec_type & AIC31XX_STEREO_CLASS_D_BIT)
637 ret = snd_soc_add_codec_controls( 690 ret = snd_soc_add_codec_controls(
638 codec, aic311x_snd_controls, 691 codec, aic311x_snd_controls,
@@ -651,6 +704,30 @@ static int aic31xx_add_widgets(struct snd_soc_codec *codec)
651 struct aic31xx_priv *aic31xx = snd_soc_codec_get_drvdata(codec); 704 struct aic31xx_priv *aic31xx = snd_soc_codec_get_drvdata(codec);
652 int ret = 0; 705 int ret = 0;
653 706
707 if (aic31xx->pdata.codec_type & DAC31XX_BIT) {
708 ret = snd_soc_dapm_new_controls(
709 dapm, dac31xx_dapm_widgets,
710 ARRAY_SIZE(dac31xx_dapm_widgets));
711 if (ret)
712 return ret;
713
714 ret = snd_soc_dapm_add_routes(dapm, dac31xx_audio_map,
715 ARRAY_SIZE(dac31xx_audio_map));
716 if (ret)
717 return ret;
718 } else {
719 ret = snd_soc_dapm_new_controls(
720 dapm, aic31xx_dapm_widgets,
721 ARRAY_SIZE(aic31xx_dapm_widgets));
722 if (ret)
723 return ret;
724
725 ret = snd_soc_dapm_add_routes(dapm, aic31xx_audio_map,
726 ARRAY_SIZE(aic31xx_audio_map));
727 if (ret)
728 return ret;
729 }
730
654 if (aic31xx->pdata.codec_type & AIC31XX_STEREO_CLASS_D_BIT) { 731 if (aic31xx->pdata.codec_type & AIC31XX_STEREO_CLASS_D_BIT) {
655 ret = snd_soc_dapm_new_controls( 732 ret = snd_soc_dapm_new_controls(
656 dapm, aic311x_dapm_widgets, 733 dapm, aic311x_dapm_widgets,
@@ -1114,12 +1191,14 @@ static struct snd_soc_codec_driver soc_codec_driver_aic31xx = {
1114 .set_bias_level = aic31xx_set_bias_level, 1191 .set_bias_level = aic31xx_set_bias_level,
1115 .suspend_bias_off = true, 1192 .suspend_bias_off = true,
1116 1193
1117 .controls = aic31xx_snd_controls, 1194 .component_driver = {
1118 .num_controls = ARRAY_SIZE(aic31xx_snd_controls), 1195 .controls = common31xx_snd_controls,
1119 .dapm_widgets = aic31xx_dapm_widgets, 1196 .num_controls = ARRAY_SIZE(common31xx_snd_controls),
1120 .num_dapm_widgets = ARRAY_SIZE(aic31xx_dapm_widgets), 1197 .dapm_widgets = common31xx_dapm_widgets,
1121 .dapm_routes = aic31xx_audio_map, 1198 .num_dapm_widgets = ARRAY_SIZE(common31xx_dapm_widgets),
1122 .num_dapm_routes = ARRAY_SIZE(aic31xx_audio_map), 1199 .dapm_routes = common31xx_audio_map,
1200 .num_dapm_routes = ARRAY_SIZE(common31xx_audio_map),
1201 },
1123}; 1202};
1124 1203
1125static const struct snd_soc_dai_ops aic31xx_dai_ops = { 1204static const struct snd_soc_dai_ops aic31xx_dai_ops = {
@@ -1129,19 +1208,34 @@ static const struct snd_soc_dai_ops aic31xx_dai_ops = {
1129 .digital_mute = aic31xx_dac_mute, 1208 .digital_mute = aic31xx_dac_mute,
1130}; 1209};
1131 1210
1211static struct snd_soc_dai_driver dac31xx_dai_driver[] = {
1212 {
1213 .name = "tlv32dac31xx-hifi",
1214 .playback = {
1215 .stream_name = "Playback",
1216 .channels_min = 2,
1217 .channels_max = 2,
1218 .rates = AIC31XX_RATES,
1219 .formats = AIC31XX_FORMATS,
1220 },
1221 .ops = &aic31xx_dai_ops,
1222 .symmetric_rates = 1,
1223 }
1224};
1225
1132static struct snd_soc_dai_driver aic31xx_dai_driver[] = { 1226static struct snd_soc_dai_driver aic31xx_dai_driver[] = {
1133 { 1227 {
1134 .name = "tlv320aic31xx-hifi", 1228 .name = "tlv320aic31xx-hifi",
1135 .playback = { 1229 .playback = {
1136 .stream_name = "Playback", 1230 .stream_name = "Playback",
1137 .channels_min = 1, 1231 .channels_min = 2,
1138 .channels_max = 2, 1232 .channels_max = 2,
1139 .rates = AIC31XX_RATES, 1233 .rates = AIC31XX_RATES,
1140 .formats = AIC31XX_FORMATS, 1234 .formats = AIC31XX_FORMATS,
1141 }, 1235 },
1142 .capture = { 1236 .capture = {
1143 .stream_name = "Capture", 1237 .stream_name = "Capture",
1144 .channels_min = 1, 1238 .channels_min = 2,
1145 .channels_max = 2, 1239 .channels_max = 2,
1146 .rates = AIC31XX_RATES, 1240 .rates = AIC31XX_RATES,
1147 .formats = AIC31XX_FORMATS, 1241 .formats = AIC31XX_FORMATS,
@@ -1259,9 +1353,16 @@ static int aic31xx_i2c_probe(struct i2c_client *i2c,
1259 if (ret) 1353 if (ret)
1260 return ret; 1354 return ret;
1261 1355
1262 return snd_soc_register_codec(&i2c->dev, &soc_codec_driver_aic31xx, 1356 if (aic31xx->pdata.codec_type & DAC31XX_BIT)
1263 aic31xx_dai_driver, 1357 return snd_soc_register_codec(&i2c->dev,
1264 ARRAY_SIZE(aic31xx_dai_driver)); 1358 &soc_codec_driver_aic31xx,
1359 dac31xx_dai_driver,
1360 ARRAY_SIZE(dac31xx_dai_driver));
1361 else
1362 return snd_soc_register_codec(&i2c->dev,
1363 &soc_codec_driver_aic31xx,
1364 aic31xx_dai_driver,
1365 ARRAY_SIZE(aic31xx_dai_driver));
1265} 1366}
1266 1367
1267static int aic31xx_i2c_remove(struct i2c_client *i2c) 1368static int aic31xx_i2c_remove(struct i2c_client *i2c)
@@ -1277,6 +1378,7 @@ static const struct i2c_device_id aic31xx_i2c_id[] = {
1277 { "tlv320aic3110", AIC3110 }, 1378 { "tlv320aic3110", AIC3110 },
1278 { "tlv320aic3120", AIC3120 }, 1379 { "tlv320aic3120", AIC3120 },
1279 { "tlv320aic3111", AIC3111 }, 1380 { "tlv320aic3111", AIC3111 },
1381 { "tlv320dac3100", DAC3100 },
1280 { } 1382 { }
1281}; 1383};
1282MODULE_DEVICE_TABLE(i2c, aic31xx_i2c_id); 1384MODULE_DEVICE_TABLE(i2c, aic31xx_i2c_id);
diff --git a/sound/soc/codecs/tlv320aic31xx.h b/sound/soc/codecs/tlv320aic31xx.h
index ac9b146526eb..5acd5b69fb83 100644
--- a/sound/soc/codecs/tlv320aic31xx.h
+++ b/sound/soc/codecs/tlv320aic31xx.h
@@ -24,12 +24,14 @@
24 24
25#define AIC31XX_STEREO_CLASS_D_BIT 0x1 25#define AIC31XX_STEREO_CLASS_D_BIT 0x1
26#define AIC31XX_MINIDSP_BIT 0x2 26#define AIC31XX_MINIDSP_BIT 0x2
27#define DAC31XX_BIT 0x4
27 28
28enum aic31xx_type { 29enum aic31xx_type {
29 AIC3100 = 0, 30 AIC3100 = 0,
30 AIC3110 = AIC31XX_STEREO_CLASS_D_BIT, 31 AIC3110 = AIC31XX_STEREO_CLASS_D_BIT,
31 AIC3120 = AIC31XX_MINIDSP_BIT, 32 AIC3120 = AIC31XX_MINIDSP_BIT,
32 AIC3111 = (AIC31XX_STEREO_CLASS_D_BIT | AIC31XX_MINIDSP_BIT), 33 AIC3111 = (AIC31XX_STEREO_CLASS_D_BIT | AIC31XX_MINIDSP_BIT),
34 DAC3100 = DAC31XX_BIT,
33}; 35};
34 36
35struct aic31xx_pdata { 37struct aic31xx_pdata {
diff --git a/sound/soc/codecs/tlv320aic32x4.c b/sound/soc/codecs/tlv320aic32x4.c
index 85d4978d0384..28fdfc5ec544 100644
--- a/sound/soc/codecs/tlv320aic32x4.c
+++ b/sound/soc/codecs/tlv320aic32x4.c
@@ -797,12 +797,14 @@ static struct snd_soc_codec_driver soc_codec_dev_aic32x4 = {
797 .set_bias_level = aic32x4_set_bias_level, 797 .set_bias_level = aic32x4_set_bias_level,
798 .suspend_bias_off = true, 798 .suspend_bias_off = true,
799 799
800 .controls = aic32x4_snd_controls, 800 .component_driver = {
801 .num_controls = ARRAY_SIZE(aic32x4_snd_controls), 801 .controls = aic32x4_snd_controls,
802 .dapm_widgets = aic32x4_dapm_widgets, 802 .num_controls = ARRAY_SIZE(aic32x4_snd_controls),
803 .num_dapm_widgets = ARRAY_SIZE(aic32x4_dapm_widgets), 803 .dapm_widgets = aic32x4_dapm_widgets,
804 .dapm_routes = aic32x4_dapm_routes, 804 .num_dapm_widgets = ARRAY_SIZE(aic32x4_dapm_widgets),
805 .num_dapm_routes = ARRAY_SIZE(aic32x4_dapm_routes), 805 .dapm_routes = aic32x4_dapm_routes,
806 .num_dapm_routes = ARRAY_SIZE(aic32x4_dapm_routes),
807 },
806}; 808};
807 809
808static int aic32x4_parse_dt(struct aic32x4_priv *aic32x4, 810static int aic32x4_parse_dt(struct aic32x4_priv *aic32x4,
diff --git a/sound/soc/codecs/tlv320aic3x.c b/sound/soc/codecs/tlv320aic3x.c
index a564759845f9..5a8d96ec058c 100644
--- a/sound/soc/codecs/tlv320aic3x.c
+++ b/sound/soc/codecs/tlv320aic3x.c
@@ -1670,12 +1670,14 @@ static struct snd_soc_codec_driver soc_codec_dev_aic3x = {
1670 .idle_bias_off = true, 1670 .idle_bias_off = true,
1671 .probe = aic3x_probe, 1671 .probe = aic3x_probe,
1672 .remove = aic3x_remove, 1672 .remove = aic3x_remove,
1673 .controls = aic3x_snd_controls, 1673 .component_driver = {
1674 .num_controls = ARRAY_SIZE(aic3x_snd_controls), 1674 .controls = aic3x_snd_controls,
1675 .dapm_widgets = aic3x_dapm_widgets, 1675 .num_controls = ARRAY_SIZE(aic3x_snd_controls),
1676 .num_dapm_widgets = ARRAY_SIZE(aic3x_dapm_widgets), 1676 .dapm_widgets = aic3x_dapm_widgets,
1677 .dapm_routes = intercon, 1677 .num_dapm_widgets = ARRAY_SIZE(aic3x_dapm_widgets),
1678 .num_dapm_routes = ARRAY_SIZE(intercon), 1678 .dapm_routes = intercon,
1679 .num_dapm_routes = ARRAY_SIZE(intercon),
1680 },
1679}; 1681};
1680 1682
1681/* 1683/*
diff --git a/sound/soc/codecs/tlv320dac33.c b/sound/soc/codecs/tlv320dac33.c
index f7a6ce7e5fb1..7bcf01efdf9a 100644
--- a/sound/soc/codecs/tlv320dac33.c
+++ b/sound/soc/codecs/tlv320dac33.c
@@ -90,7 +90,6 @@ static const char *dac33_supply_names[DAC33_NUM_SUPPLIES] = {
90 90
91struct tlv320dac33_priv { 91struct tlv320dac33_priv {
92 struct mutex mutex; 92 struct mutex mutex;
93 struct workqueue_struct *dac33_wq;
94 struct work_struct work; 93 struct work_struct work;
95 struct snd_soc_codec *codec; 94 struct snd_soc_codec *codec;
96 struct regulator_bulk_data supplies[DAC33_NUM_SUPPLIES]; 95 struct regulator_bulk_data supplies[DAC33_NUM_SUPPLIES];
@@ -771,7 +770,7 @@ static irqreturn_t dac33_interrupt_handler(int irq, void *dev)
771 770
772 /* Do not schedule the workqueue in Mode7 */ 771 /* Do not schedule the workqueue in Mode7 */
773 if (dac33->fifo_mode != DAC33_FIFO_MODE7) 772 if (dac33->fifo_mode != DAC33_FIFO_MODE7)
774 queue_work(dac33->dac33_wq, &dac33->work); 773 schedule_work(&dac33->work);
775 774
776 return IRQ_HANDLED; 775 return IRQ_HANDLED;
777} 776}
@@ -1127,7 +1126,7 @@ static int dac33_pcm_trigger(struct snd_pcm_substream *substream, int cmd,
1127 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: 1126 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
1128 if (dac33->fifo_mode) { 1127 if (dac33->fifo_mode) {
1129 dac33->state = DAC33_PREFILL; 1128 dac33->state = DAC33_PREFILL;
1130 queue_work(dac33->dac33_wq, &dac33->work); 1129 schedule_work(&dac33->work);
1131 } 1130 }
1132 break; 1131 break;
1133 case SNDRV_PCM_TRIGGER_STOP: 1132 case SNDRV_PCM_TRIGGER_STOP:
@@ -1135,7 +1134,7 @@ static int dac33_pcm_trigger(struct snd_pcm_substream *substream, int cmd,
1135 case SNDRV_PCM_TRIGGER_PAUSE_PUSH: 1134 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
1136 if (dac33->fifo_mode) { 1135 if (dac33->fifo_mode) {
1137 dac33->state = DAC33_FLUSH; 1136 dac33->state = DAC33_FLUSH;
1138 queue_work(dac33->dac33_wq, &dac33->work); 1137 schedule_work(&dac33->work);
1139 } 1138 }
1140 break; 1139 break;
1141 default: 1140 default:
@@ -1410,14 +1409,6 @@ static int dac33_soc_probe(struct snd_soc_codec *codec)
1410 dac33->irq = -1; 1409 dac33->irq = -1;
1411 } 1410 }
1412 if (dac33->irq != -1) { 1411 if (dac33->irq != -1) {
1413 /* Setup work queue */
1414 dac33->dac33_wq =
1415 create_singlethread_workqueue("tlv320dac33");
1416 if (dac33->dac33_wq == NULL) {
1417 free_irq(dac33->irq, codec);
1418 return -ENOMEM;
1419 }
1420
1421 INIT_WORK(&dac33->work, dac33_work); 1412 INIT_WORK(&dac33->work, dac33_work);
1422 } 1413 }
1423 } 1414 }
@@ -1437,7 +1428,7 @@ static int dac33_soc_remove(struct snd_soc_codec *codec)
1437 1428
1438 if (dac33->irq >= 0) { 1429 if (dac33->irq >= 0) {
1439 free_irq(dac33->irq, dac33->codec); 1430 free_irq(dac33->irq, dac33->codec);
1440 destroy_workqueue(dac33->dac33_wq); 1431 flush_work(&dac33->work);
1441 } 1432 }
1442 return 0; 1433 return 0;
1443} 1434}
@@ -1453,12 +1444,14 @@ static struct snd_soc_codec_driver soc_codec_dev_tlv320dac33 = {
1453 .probe = dac33_soc_probe, 1444 .probe = dac33_soc_probe,
1454 .remove = dac33_soc_remove, 1445 .remove = dac33_soc_remove,
1455 1446
1456 .controls = dac33_snd_controls, 1447 .component_driver = {
1457 .num_controls = ARRAY_SIZE(dac33_snd_controls), 1448 .controls = dac33_snd_controls,
1458 .dapm_widgets = dac33_dapm_widgets, 1449 .num_controls = ARRAY_SIZE(dac33_snd_controls),
1459 .num_dapm_widgets = ARRAY_SIZE(dac33_dapm_widgets), 1450 .dapm_widgets = dac33_dapm_widgets,
1460 .dapm_routes = audio_map, 1451 .num_dapm_widgets = ARRAY_SIZE(dac33_dapm_widgets),
1461 .num_dapm_routes = ARRAY_SIZE(audio_map), 1452 .dapm_routes = audio_map,
1453 .num_dapm_routes = ARRAY_SIZE(audio_map),
1454 },
1462}; 1455};
1463 1456
1464#define DAC33_RATES (SNDRV_PCM_RATE_44100 | \ 1457#define DAC33_RATES (SNDRV_PCM_RATE_44100 | \
diff --git a/sound/soc/codecs/tpa6130a2.c b/sound/soc/codecs/tpa6130a2.c
index f1ea052a822e..2e014c80d113 100644
--- a/sound/soc/codecs/tpa6130a2.c
+++ b/sound/soc/codecs/tpa6130a2.c
@@ -52,7 +52,7 @@ struct tpa6130a2_data {
52 52
53static int tpa6130a2_power(struct tpa6130a2_data *data, bool enable) 53static int tpa6130a2_power(struct tpa6130a2_data *data, bool enable)
54{ 54{
55 int ret; 55 int ret = 0, ret2;
56 56
57 if (enable) { 57 if (enable) {
58 ret = regulator_enable(data->supply); 58 ret = regulator_enable(data->supply);
@@ -64,7 +64,30 @@ static int tpa6130a2_power(struct tpa6130a2_data *data, bool enable)
64 /* Power on */ 64 /* Power on */
65 if (data->power_gpio >= 0) 65 if (data->power_gpio >= 0)
66 gpio_set_value(data->power_gpio, 1); 66 gpio_set_value(data->power_gpio, 1);
67
68 /* Sync registers */
69 regcache_cache_only(data->regmap, false);
70 ret = regcache_sync(data->regmap);
71 if (ret != 0) {
72 dev_err(data->dev,
73 "Failed to sync registers: %d\n", ret);
74 regcache_cache_only(data->regmap, true);
75 if (data->power_gpio >= 0)
76 gpio_set_value(data->power_gpio, 0);
77 ret2 = regulator_disable(data->supply);
78 if (ret2 != 0)
79 dev_err(data->dev,
80 "Failed to disable supply: %d\n", ret2);
81 return ret;
82 }
67 } else { 83 } else {
84 /* Powered off device does not retain registers. While device
85 * is off, any register updates (i.e. volume changes) should
86 * happen in cache only.
87 */
88 regcache_mark_dirty(data->regmap);
89 regcache_cache_only(data->regmap, true);
90
68 /* Power off */ 91 /* Power off */
69 if (data->power_gpio >= 0) 92 if (data->power_gpio >= 0)
70 gpio_set_value(data->power_gpio, 0); 93 gpio_set_value(data->power_gpio, 0);
@@ -75,9 +98,6 @@ static int tpa6130a2_power(struct tpa6130a2_data *data, bool enable)
75 "Failed to disable supply: %d\n", ret); 98 "Failed to disable supply: %d\n", ret);
76 return ret; 99 return ret;
77 } 100 }
78
79 /* device regs does not match the cache state anymore */
80 regcache_mark_dirty(data->regmap);
81 } 101 }
82 102
83 return ret; 103 return ret;
@@ -88,25 +108,14 @@ static int tpa6130a2_power_event(struct snd_soc_dapm_widget *w,
88{ 108{
89 struct snd_soc_component *c = snd_soc_dapm_to_component(w->dapm); 109 struct snd_soc_component *c = snd_soc_dapm_to_component(w->dapm);
90 struct tpa6130a2_data *data = snd_soc_component_get_drvdata(c); 110 struct tpa6130a2_data *data = snd_soc_component_get_drvdata(c);
91 int ret;
92 111
93 /* before widget power up */
94 if (SND_SOC_DAPM_EVENT_ON(event)) { 112 if (SND_SOC_DAPM_EVENT_ON(event)) {
95 /* Turn on the chip */ 113 /* Before widget power up: turn chip on, sync registers */
96 tpa6130a2_power(data, true); 114 return tpa6130a2_power(data, true);
97 /* Sync the registers */
98 ret = regcache_sync(data->regmap);
99 if (ret < 0) {
100 dev_err(c->dev, "Failed to initialize chip\n");
101 tpa6130a2_power(data, false);
102 return ret;
103 }
104 /* after widget power down */
105 } else { 115 } else {
106 tpa6130a2_power(data, false); 116 /* After widget power down: turn chip off */
117 return tpa6130a2_power(data, false);
107 } 118 }
108
109 return 0;
110} 119}
111 120
112/* 121/*
@@ -190,7 +199,7 @@ static const struct snd_soc_dapm_route tpa6130a2_dapm_routes[] = {
190 { "Right PGA", NULL, "Power" }, 199 { "Right PGA", NULL, "Power" },
191}; 200};
192 201
193struct snd_soc_component_driver tpa6130a2_component_driver = { 202static const struct snd_soc_component_driver tpa6130a2_component_driver = {
194 .name = "tpa6130a2", 203 .name = "tpa6130a2",
195 .probe = tpa6130a2_component_probe, 204 .probe = tpa6130a2_component_probe,
196 .dapm_widgets = tpa6130a2_dapm_widgets, 205 .dapm_widgets = tpa6130a2_dapm_widgets,
diff --git a/sound/soc/codecs/twl4030.c b/sound/soc/codecs/twl4030.c
index a5a4e9f75c57..a2104d68169d 100644
--- a/sound/soc/codecs/twl4030.c
+++ b/sound/soc/codecs/twl4030.c
@@ -2199,12 +2199,14 @@ static struct snd_soc_codec_driver soc_codec_dev_twl4030 = {
2199 .set_bias_level = twl4030_set_bias_level, 2199 .set_bias_level = twl4030_set_bias_level,
2200 .idle_bias_off = true, 2200 .idle_bias_off = true,
2201 2201
2202 .controls = twl4030_snd_controls, 2202 .component_driver = {
2203 .num_controls = ARRAY_SIZE(twl4030_snd_controls), 2203 .controls = twl4030_snd_controls,
2204 .dapm_widgets = twl4030_dapm_widgets, 2204 .num_controls = ARRAY_SIZE(twl4030_snd_controls),
2205 .num_dapm_widgets = ARRAY_SIZE(twl4030_dapm_widgets), 2205 .dapm_widgets = twl4030_dapm_widgets,
2206 .dapm_routes = intercon, 2206 .num_dapm_widgets = ARRAY_SIZE(twl4030_dapm_widgets),
2207 .num_dapm_routes = ARRAY_SIZE(intercon), 2207 .dapm_routes = intercon,
2208 .num_dapm_routes = ARRAY_SIZE(intercon),
2209 },
2208}; 2210};
2209 2211
2210static int twl4030_codec_probe(struct platform_device *pdev) 2212static int twl4030_codec_probe(struct platform_device *pdev)
diff --git a/sound/soc/codecs/twl6040.c b/sound/soc/codecs/twl6040.c
index 1f7081043566..748036e851ea 100644
--- a/sound/soc/codecs/twl6040.c
+++ b/sound/soc/codecs/twl6040.c
@@ -1156,12 +1156,14 @@ static struct snd_soc_codec_driver soc_codec_dev_twl6040 = {
1156 .suspend_bias_off = true, 1156 .suspend_bias_off = true,
1157 .ignore_pmdown_time = true, 1157 .ignore_pmdown_time = true,
1158 1158
1159 .controls = twl6040_snd_controls, 1159 .component_driver = {
1160 .num_controls = ARRAY_SIZE(twl6040_snd_controls), 1160 .controls = twl6040_snd_controls,
1161 .dapm_widgets = twl6040_dapm_widgets, 1161 .num_controls = ARRAY_SIZE(twl6040_snd_controls),
1162 .num_dapm_widgets = ARRAY_SIZE(twl6040_dapm_widgets), 1162 .dapm_widgets = twl6040_dapm_widgets,
1163 .dapm_routes = intercon, 1163 .num_dapm_widgets = ARRAY_SIZE(twl6040_dapm_widgets),
1164 .num_dapm_routes = ARRAY_SIZE(intercon), 1164 .dapm_routes = intercon,
1165 .num_dapm_routes = ARRAY_SIZE(intercon),
1166 },
1165}; 1167};
1166 1168
1167static int twl6040_codec_probe(struct platform_device *pdev) 1169static int twl6040_codec_probe(struct platform_device *pdev)
diff --git a/sound/soc/codecs/uda134x.c b/sound/soc/codecs/uda134x.c
index e4c694c758b8..5fdee874406d 100644
--- a/sound/soc/codecs/uda134x.c
+++ b/sound/soc/codecs/uda134x.c
@@ -523,10 +523,12 @@ static struct snd_soc_codec_driver soc_codec_dev_uda134x = {
523 .set_bias_level = uda134x_set_bias_level, 523 .set_bias_level = uda134x_set_bias_level,
524 .suspend_bias_off = true, 524 .suspend_bias_off = true,
525 525
526 .dapm_widgets = uda134x_dapm_widgets, 526 .component_driver = {
527 .num_dapm_widgets = ARRAY_SIZE(uda134x_dapm_widgets), 527 .dapm_widgets = uda134x_dapm_widgets,
528 .dapm_routes = uda134x_dapm_routes, 528 .num_dapm_widgets = ARRAY_SIZE(uda134x_dapm_widgets),
529 .num_dapm_routes = ARRAY_SIZE(uda134x_dapm_routes), 529 .dapm_routes = uda134x_dapm_routes,
530 .num_dapm_routes = ARRAY_SIZE(uda134x_dapm_routes),
531 },
530}; 532};
531 533
532static const struct regmap_config uda134x_regmap_config = { 534static const struct regmap_config uda134x_regmap_config = {
@@ -544,6 +546,7 @@ static int uda134x_codec_probe(struct platform_device *pdev)
544{ 546{
545 struct uda134x_platform_data *pd = pdev->dev.platform_data; 547 struct uda134x_platform_data *pd = pdev->dev.platform_data;
546 struct uda134x_priv *uda134x; 548 struct uda134x_priv *uda134x;
549 int ret;
547 550
548 if (!pd) { 551 if (!pd) {
549 dev_err(&pdev->dev, "Missing L3 bitbang function\n"); 552 dev_err(&pdev->dev, "Missing L3 bitbang function\n");
@@ -557,6 +560,12 @@ static int uda134x_codec_probe(struct platform_device *pdev)
557 uda134x->pd = pd; 560 uda134x->pd = pd;
558 platform_set_drvdata(pdev, uda134x); 561 platform_set_drvdata(pdev, uda134x);
559 562
563 if (pd->l3.use_gpios) {
564 ret = l3_set_gpio_ops(&pdev->dev, &uda134x->pd->l3);
565 if (ret < 0)
566 return ret;
567 }
568
560 uda134x->regmap = devm_regmap_init(&pdev->dev, NULL, pd, 569 uda134x->regmap = devm_regmap_init(&pdev->dev, NULL, pd,
561 &uda134x_regmap_config); 570 &uda134x_regmap_config);
562 if (IS_ERR(uda134x->regmap)) 571 if (IS_ERR(uda134x->regmap))
diff --git a/sound/soc/codecs/uda1380.c b/sound/soc/codecs/uda1380.c
index 35f0469ebb16..533e3bb444e4 100644
--- a/sound/soc/codecs/uda1380.c
+++ b/sound/soc/codecs/uda1380.c
@@ -765,12 +765,14 @@ static struct snd_soc_codec_driver soc_codec_dev_uda1380 = {
765 .reg_cache_default = uda1380_reg, 765 .reg_cache_default = uda1380_reg,
766 .reg_cache_step = 1, 766 .reg_cache_step = 1,
767 767
768 .controls = uda1380_snd_controls, 768 .component_driver = {
769 .num_controls = ARRAY_SIZE(uda1380_snd_controls), 769 .controls = uda1380_snd_controls,
770 .dapm_widgets = uda1380_dapm_widgets, 770 .num_controls = ARRAY_SIZE(uda1380_snd_controls),
771 .num_dapm_widgets = ARRAY_SIZE(uda1380_dapm_widgets), 771 .dapm_widgets = uda1380_dapm_widgets,
772 .dapm_routes = uda1380_dapm_routes, 772 .num_dapm_widgets = ARRAY_SIZE(uda1380_dapm_widgets),
773 .num_dapm_routes = ARRAY_SIZE(uda1380_dapm_routes), 773 .dapm_routes = uda1380_dapm_routes,
774 .num_dapm_routes = ARRAY_SIZE(uda1380_dapm_routes),
775 },
774}; 776};
775 777
776#if IS_ENABLED(CONFIG_I2C) 778#if IS_ENABLED(CONFIG_I2C)
diff --git a/sound/soc/codecs/wl1273.c b/sound/soc/codecs/wl1273.c
index 1b79778098d2..fcffb6e707d9 100644
--- a/sound/soc/codecs/wl1273.c
+++ b/sound/soc/codecs/wl1273.c
@@ -484,12 +484,14 @@ static struct snd_soc_codec_driver soc_codec_dev_wl1273 = {
484 .probe = wl1273_probe, 484 .probe = wl1273_probe,
485 .remove = wl1273_remove, 485 .remove = wl1273_remove,
486 486
487 .controls = wl1273_controls, 487 .component_driver = {
488 .num_controls = ARRAY_SIZE(wl1273_controls), 488 .controls = wl1273_controls,
489 .dapm_widgets = wl1273_dapm_widgets, 489 .num_controls = ARRAY_SIZE(wl1273_controls),
490 .num_dapm_widgets = ARRAY_SIZE(wl1273_dapm_widgets), 490 .dapm_widgets = wl1273_dapm_widgets,
491 .dapm_routes = wl1273_dapm_routes, 491 .num_dapm_widgets = ARRAY_SIZE(wl1273_dapm_widgets),
492 .num_dapm_routes = ARRAY_SIZE(wl1273_dapm_routes), 492 .dapm_routes = wl1273_dapm_routes,
493 .num_dapm_routes = ARRAY_SIZE(wl1273_dapm_routes),
494 },
493}; 495};
494 496
495static int wl1273_platform_probe(struct platform_device *pdev) 497static int wl1273_platform_probe(struct platform_device *pdev)
diff --git a/sound/soc/codecs/wm0010.c b/sound/soc/codecs/wm0010.c
index e3c34bdc2772..0eb5dcf4c29d 100644
--- a/sound/soc/codecs/wm0010.c
+++ b/sound/soc/codecs/wm0010.c
@@ -789,16 +789,18 @@ static int wm0010_set_sysclk(struct snd_soc_codec *codec, int source,
789 789
790static int wm0010_probe(struct snd_soc_codec *codec); 790static int wm0010_probe(struct snd_soc_codec *codec);
791 791
792static struct snd_soc_codec_driver soc_codec_dev_wm0010 = { 792static const struct snd_soc_codec_driver soc_codec_dev_wm0010 = {
793 .probe = wm0010_probe, 793 .probe = wm0010_probe,
794 .set_bias_level = wm0010_set_bias_level, 794 .set_bias_level = wm0010_set_bias_level,
795 .set_sysclk = wm0010_set_sysclk, 795 .set_sysclk = wm0010_set_sysclk,
796 .idle_bias_off = true, 796 .idle_bias_off = true,
797 797
798 .dapm_widgets = wm0010_dapm_widgets, 798 .component_driver = {
799 .num_dapm_widgets = ARRAY_SIZE(wm0010_dapm_widgets), 799 .dapm_widgets = wm0010_dapm_widgets,
800 .dapm_routes = wm0010_dapm_routes, 800 .num_dapm_widgets = ARRAY_SIZE(wm0010_dapm_widgets),
801 .num_dapm_routes = ARRAY_SIZE(wm0010_dapm_routes), 801 .dapm_routes = wm0010_dapm_routes,
802 .num_dapm_routes = ARRAY_SIZE(wm0010_dapm_routes),
803 },
802}; 804};
803 805
804#define WM0010_RATES (SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000) 806#define WM0010_RATES (SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000)
diff --git a/sound/soc/codecs/wm1250-ev1.c b/sound/soc/codecs/wm1250-ev1.c
index ec45c5b220b1..cf5f0580df6a 100644
--- a/sound/soc/codecs/wm1250-ev1.c
+++ b/sound/soc/codecs/wm1250-ev1.c
@@ -141,12 +141,13 @@ static struct snd_soc_dai_driver wm1250_ev1_dai = {
141 .ops = &wm1250_ev1_ops, 141 .ops = &wm1250_ev1_ops,
142}; 142};
143 143
144static struct snd_soc_codec_driver soc_codec_dev_wm1250_ev1 = { 144static const struct snd_soc_codec_driver soc_codec_dev_wm1250_ev1 = {
145 .dapm_widgets = wm1250_ev1_dapm_widgets, 145 .component_driver = {
146 .num_dapm_widgets = ARRAY_SIZE(wm1250_ev1_dapm_widgets), 146 .dapm_widgets = wm1250_ev1_dapm_widgets,
147 .dapm_routes = wm1250_ev1_dapm_routes, 147 .num_dapm_widgets = ARRAY_SIZE(wm1250_ev1_dapm_widgets),
148 .num_dapm_routes = ARRAY_SIZE(wm1250_ev1_dapm_routes), 148 .dapm_routes = wm1250_ev1_dapm_routes,
149 149 .num_dapm_routes = ARRAY_SIZE(wm1250_ev1_dapm_routes),
150 },
150 .set_bias_level = wm1250_ev1_set_bias_level, 151 .set_bias_level = wm1250_ev1_set_bias_level,
151 .idle_bias_off = true, 152 .idle_bias_off = true,
152}; 153};
diff --git a/sound/soc/codecs/wm2000.c b/sound/soc/codecs/wm2000.c
index f2664396be6f..23cde3a0dc11 100644
--- a/sound/soc/codecs/wm2000.c
+++ b/sound/soc/codecs/wm2000.c
@@ -799,18 +799,20 @@ static int wm2000_remove(struct snd_soc_codec *codec)
799 return wm2000_anc_transition(wm2000, ANC_OFF); 799 return wm2000_anc_transition(wm2000, ANC_OFF);
800} 800}
801 801
802static struct snd_soc_codec_driver soc_codec_dev_wm2000 = { 802static const struct snd_soc_codec_driver soc_codec_dev_wm2000 = {
803 .probe = wm2000_probe, 803 .probe = wm2000_probe,
804 .remove = wm2000_remove, 804 .remove = wm2000_remove,
805 .suspend = wm2000_suspend, 805 .suspend = wm2000_suspend,
806 .resume = wm2000_resume, 806 .resume = wm2000_resume,
807 807
808 .dapm_widgets = wm2000_dapm_widgets, 808 .component_driver = {
809 .num_dapm_widgets = ARRAY_SIZE(wm2000_dapm_widgets), 809 .controls = wm2000_controls,
810 .dapm_routes = wm2000_audio_map, 810 .num_controls = ARRAY_SIZE(wm2000_controls),
811 .num_dapm_routes = ARRAY_SIZE(wm2000_audio_map), 811 .dapm_widgets = wm2000_dapm_widgets,
812 .controls = wm2000_controls, 812 .num_dapm_widgets = ARRAY_SIZE(wm2000_dapm_widgets),
813 .num_controls = ARRAY_SIZE(wm2000_controls), 813 .dapm_routes = wm2000_audio_map,
814 .num_dapm_routes = ARRAY_SIZE(wm2000_audio_map),
815 },
814}; 816};
815 817
816static int wm2000_i2c_probe(struct i2c_client *i2c, 818static int wm2000_i2c_probe(struct i2c_client *i2c,
diff --git a/sound/soc/codecs/wm2200.c b/sound/soc/codecs/wm2200.c
index fd1439ecb50a..606bf88abfc4 100644
--- a/sound/soc/codecs/wm2200.c
+++ b/sound/soc/codecs/wm2200.c
@@ -2103,7 +2103,7 @@ static struct snd_soc_dai_driver wm2200_dai = {
2103 .ops = &wm2200_dai_ops, 2103 .ops = &wm2200_dai_ops,
2104}; 2104};
2105 2105
2106static struct snd_soc_codec_driver soc_codec_wm2200 = { 2106static const struct snd_soc_codec_driver soc_codec_wm2200 = {
2107 .probe = wm2200_probe, 2107 .probe = wm2200_probe,
2108 2108
2109 .idle_bias_off = true, 2109 .idle_bias_off = true,
@@ -2111,12 +2111,14 @@ static struct snd_soc_codec_driver soc_codec_wm2200 = {
2111 .set_sysclk = wm2200_set_sysclk, 2111 .set_sysclk = wm2200_set_sysclk,
2112 .set_pll = wm2200_set_fll, 2112 .set_pll = wm2200_set_fll,
2113 2113
2114 .controls = wm2200_snd_controls, 2114 .component_driver = {
2115 .num_controls = ARRAY_SIZE(wm2200_snd_controls), 2115 .controls = wm2200_snd_controls,
2116 .dapm_widgets = wm2200_dapm_widgets, 2116 .num_controls = ARRAY_SIZE(wm2200_snd_controls),
2117 .num_dapm_widgets = ARRAY_SIZE(wm2200_dapm_widgets), 2117 .dapm_widgets = wm2200_dapm_widgets,
2118 .dapm_routes = wm2200_dapm_routes, 2118 .num_dapm_widgets = ARRAY_SIZE(wm2200_dapm_widgets),
2119 .num_dapm_routes = ARRAY_SIZE(wm2200_dapm_routes), 2119 .dapm_routes = wm2200_dapm_routes,
2120 .num_dapm_routes = ARRAY_SIZE(wm2200_dapm_routes),
2121 },
2120}; 2122};
2121 2123
2122static irqreturn_t wm2200_irq(int irq, void *data) 2124static irqreturn_t wm2200_irq(int irq, void *data)
diff --git a/sound/soc/codecs/wm5100.c b/sound/soc/codecs/wm5100.c
index 512a9d25fe6f..560575000cc5 100644
--- a/sound/soc/codecs/wm5100.c
+++ b/sound/soc/codecs/wm5100.c
@@ -2285,7 +2285,7 @@ static int wm5100_gpio_direction_in(struct gpio_chip *chip, unsigned offset)
2285 (1 << WM5100_GP1_DIR_SHIFT)); 2285 (1 << WM5100_GP1_DIR_SHIFT));
2286} 2286}
2287 2287
2288static struct gpio_chip wm5100_template_chip = { 2288static const struct gpio_chip wm5100_template_chip = {
2289 .label = "wm5100", 2289 .label = "wm5100",
2290 .owner = THIS_MODULE, 2290 .owner = THIS_MODULE,
2291 .direction_output = wm5100_gpio_direction_out, 2291 .direction_output = wm5100_gpio_direction_out,
@@ -2381,7 +2381,7 @@ static int wm5100_remove(struct snd_soc_codec *codec)
2381 return 0; 2381 return 0;
2382} 2382}
2383 2383
2384static struct snd_soc_codec_driver soc_codec_dev_wm5100 = { 2384static const struct snd_soc_codec_driver soc_codec_dev_wm5100 = {
2385 .probe = wm5100_probe, 2385 .probe = wm5100_probe,
2386 .remove = wm5100_remove, 2386 .remove = wm5100_remove,
2387 2387
@@ -2390,12 +2390,14 @@ static struct snd_soc_codec_driver soc_codec_dev_wm5100 = {
2390 .idle_bias_off = 1, 2390 .idle_bias_off = 1,
2391 2391
2392 .seq_notifier = wm5100_seq_notifier, 2392 .seq_notifier = wm5100_seq_notifier,
2393 .controls = wm5100_snd_controls, 2393 .component_driver = {
2394 .num_controls = ARRAY_SIZE(wm5100_snd_controls), 2394 .controls = wm5100_snd_controls,
2395 .dapm_widgets = wm5100_dapm_widgets, 2395 .num_controls = ARRAY_SIZE(wm5100_snd_controls),
2396 .num_dapm_widgets = ARRAY_SIZE(wm5100_dapm_widgets), 2396 .dapm_widgets = wm5100_dapm_widgets,
2397 .dapm_routes = wm5100_dapm_routes, 2397 .num_dapm_widgets = ARRAY_SIZE(wm5100_dapm_widgets),
2398 .num_dapm_routes = ARRAY_SIZE(wm5100_dapm_routes), 2398 .dapm_routes = wm5100_dapm_routes,
2399 .num_dapm_routes = ARRAY_SIZE(wm5100_dapm_routes),
2400 },
2399}; 2401};
2400 2402
2401static const struct regmap_config wm5100_regmap = { 2403static const struct regmap_config wm5100_regmap = {
diff --git a/sound/soc/codecs/wm5102.c b/sound/soc/codecs/wm5102.c
index 846deed6af41..93876c6d48ee 100644
--- a/sound/soc/codecs/wm5102.c
+++ b/sound/soc/codecs/wm5102.c
@@ -1521,6 +1521,16 @@ static const struct snd_soc_dapm_route wm5102_dapm_routes[] = {
1521 { "IN3L", NULL, "SYSCLK" }, 1521 { "IN3L", NULL, "SYSCLK" },
1522 { "IN3R", NULL, "SYSCLK" }, 1522 { "IN3R", NULL, "SYSCLK" },
1523 1523
1524 { "ASRC1L", NULL, "SYSCLK" },
1525 { "ASRC1R", NULL, "SYSCLK" },
1526 { "ASRC2L", NULL, "SYSCLK" },
1527 { "ASRC2R", NULL, "SYSCLK" },
1528
1529 { "ASRC1L", NULL, "ASYNCCLK" },
1530 { "ASRC1R", NULL, "ASYNCCLK" },
1531 { "ASRC2L", NULL, "ASYNCCLK" },
1532 { "ASRC2R", NULL, "ASYNCCLK" },
1533
1524 { "MICBIAS1", NULL, "MICVDD" }, 1534 { "MICBIAS1", NULL, "MICVDD" },
1525 { "MICBIAS2", NULL, "MICVDD" }, 1535 { "MICBIAS2", NULL, "MICVDD" },
1526 { "MICBIAS3", NULL, "MICVDD" }, 1536 { "MICBIAS3", NULL, "MICVDD" },
@@ -1600,7 +1610,6 @@ static const struct snd_soc_dapm_route wm5102_dapm_routes[] = {
1600 { "Slim3 Capture", NULL, "SYSCLK" }, 1610 { "Slim3 Capture", NULL, "SYSCLK" },
1601 1611
1602 { "Audio Trace DSP", NULL, "DSP1" }, 1612 { "Audio Trace DSP", NULL, "DSP1" },
1603 { "Audio Trace DSP", NULL, "SYSCLK" },
1604 1613
1605 { "IN1L PGA", NULL, "IN1L" }, 1614 { "IN1L PGA", NULL, "IN1L" },
1606 { "IN1R PGA", NULL, "IN1R" }, 1615 { "IN1R PGA", NULL, "IN1R" },
@@ -1990,7 +1999,7 @@ static struct regmap *wm5102_get_regmap(struct device *dev)
1990 return priv->core.arizona->regmap; 1999 return priv->core.arizona->regmap;
1991} 2000}
1992 2001
1993static struct snd_soc_codec_driver soc_codec_dev_wm5102 = { 2002static const struct snd_soc_codec_driver soc_codec_dev_wm5102 = {
1994 .probe = wm5102_codec_probe, 2003 .probe = wm5102_codec_probe,
1995 .remove = wm5102_codec_remove, 2004 .remove = wm5102_codec_remove,
1996 .get_regmap = wm5102_get_regmap, 2005 .get_regmap = wm5102_get_regmap,
@@ -2000,12 +2009,14 @@ static struct snd_soc_codec_driver soc_codec_dev_wm5102 = {
2000 .set_sysclk = arizona_set_sysclk, 2009 .set_sysclk = arizona_set_sysclk,
2001 .set_pll = wm5102_set_fll, 2010 .set_pll = wm5102_set_fll,
2002 2011
2003 .controls = wm5102_snd_controls, 2012 .component_driver = {
2004 .num_controls = ARRAY_SIZE(wm5102_snd_controls), 2013 .controls = wm5102_snd_controls,
2005 .dapm_widgets = wm5102_dapm_widgets, 2014 .num_controls = ARRAY_SIZE(wm5102_snd_controls),
2006 .num_dapm_widgets = ARRAY_SIZE(wm5102_dapm_widgets), 2015 .dapm_widgets = wm5102_dapm_widgets,
2007 .dapm_routes = wm5102_dapm_routes, 2016 .num_dapm_widgets = ARRAY_SIZE(wm5102_dapm_widgets),
2008 .num_dapm_routes = ARRAY_SIZE(wm5102_dapm_routes), 2017 .dapm_routes = wm5102_dapm_routes,
2018 .num_dapm_routes = ARRAY_SIZE(wm5102_dapm_routes),
2019 },
2009}; 2020};
2010 2021
2011static struct snd_compr_ops wm5102_compr_ops = { 2022static struct snd_compr_ops wm5102_compr_ops = {
diff --git a/sound/soc/codecs/wm5110.c b/sound/soc/codecs/wm5110.c
index 156547026a40..06bae3b23fce 100644
--- a/sound/soc/codecs/wm5110.c
+++ b/sound/soc/codecs/wm5110.c
@@ -1745,6 +1745,16 @@ static const struct snd_soc_dapm_route wm5110_dapm_routes[] = {
1745 { "IN4L", NULL, "SYSCLK" }, 1745 { "IN4L", NULL, "SYSCLK" },
1746 { "IN4R", NULL, "SYSCLK" }, 1746 { "IN4R", NULL, "SYSCLK" },
1747 1747
1748 { "ASRC1L", NULL, "SYSCLK" },
1749 { "ASRC1R", NULL, "SYSCLK" },
1750 { "ASRC2L", NULL, "SYSCLK" },
1751 { "ASRC2R", NULL, "SYSCLK" },
1752
1753 { "ASRC1L", NULL, "ASYNCCLK" },
1754 { "ASRC1R", NULL, "ASYNCCLK" },
1755 { "ASRC2L", NULL, "ASYNCCLK" },
1756 { "ASRC2R", NULL, "ASYNCCLK" },
1757
1748 { "MICBIAS1", NULL, "MICVDD" }, 1758 { "MICBIAS1", NULL, "MICVDD" },
1749 { "MICBIAS2", NULL, "MICVDD" }, 1759 { "MICBIAS2", NULL, "MICVDD" },
1750 { "MICBIAS3", NULL, "MICVDD" }, 1760 { "MICBIAS3", NULL, "MICVDD" },
@@ -1832,10 +1842,8 @@ static const struct snd_soc_dapm_route wm5110_dapm_routes[] = {
1832 { "Slim3 Capture", NULL, "SYSCLK" }, 1842 { "Slim3 Capture", NULL, "SYSCLK" },
1833 1843
1834 { "Voice Control DSP", NULL, "DSP3" }, 1844 { "Voice Control DSP", NULL, "DSP3" },
1835 { "Voice Control DSP", NULL, "SYSCLK" },
1836 1845
1837 { "Audio Trace DSP", NULL, "DSP1" }, 1846 { "Audio Trace DSP", NULL, "DSP1" },
1838 { "Audio Trace DSP", NULL, "SYSCLK" },
1839 1847
1840 { "IN1L PGA", NULL, "IN1L" }, 1848 { "IN1L PGA", NULL, "IN1L" },
1841 { "IN1R PGA", NULL, "IN1R" }, 1849 { "IN1R PGA", NULL, "IN1R" },
@@ -2347,7 +2355,7 @@ static struct regmap *wm5110_get_regmap(struct device *dev)
2347 return priv->core.arizona->regmap; 2355 return priv->core.arizona->regmap;
2348} 2356}
2349 2357
2350static struct snd_soc_codec_driver soc_codec_dev_wm5110 = { 2358static const struct snd_soc_codec_driver soc_codec_dev_wm5110 = {
2351 .probe = wm5110_codec_probe, 2359 .probe = wm5110_codec_probe,
2352 .remove = wm5110_codec_remove, 2360 .remove = wm5110_codec_remove,
2353 .get_regmap = wm5110_get_regmap, 2361 .get_regmap = wm5110_get_regmap,
@@ -2357,12 +2365,14 @@ static struct snd_soc_codec_driver soc_codec_dev_wm5110 = {
2357 .set_sysclk = arizona_set_sysclk, 2365 .set_sysclk = arizona_set_sysclk,
2358 .set_pll = wm5110_set_fll, 2366 .set_pll = wm5110_set_fll,
2359 2367
2360 .controls = wm5110_snd_controls, 2368 .component_driver = {
2361 .num_controls = ARRAY_SIZE(wm5110_snd_controls), 2369 .controls = wm5110_snd_controls,
2362 .dapm_widgets = wm5110_dapm_widgets, 2370 .num_controls = ARRAY_SIZE(wm5110_snd_controls),
2363 .num_dapm_widgets = ARRAY_SIZE(wm5110_dapm_widgets), 2371 .dapm_widgets = wm5110_dapm_widgets,
2364 .dapm_routes = wm5110_dapm_routes, 2372 .num_dapm_widgets = ARRAY_SIZE(wm5110_dapm_widgets),
2365 .num_dapm_routes = ARRAY_SIZE(wm5110_dapm_routes), 2373 .dapm_routes = wm5110_dapm_routes,
2374 .num_dapm_routes = ARRAY_SIZE(wm5110_dapm_routes),
2375 },
2366}; 2376};
2367 2377
2368static struct snd_compr_ops wm5110_compr_ops = { 2378static struct snd_compr_ops wm5110_compr_ops = {
diff --git a/sound/soc/codecs/wm8350.c b/sound/soc/codecs/wm8350.c
index ffbf3df8ae97..2efc5b41ad0f 100644
--- a/sound/soc/codecs/wm8350.c
+++ b/sound/soc/codecs/wm8350.c
@@ -1587,19 +1587,21 @@ static struct regmap *wm8350_get_regmap(struct device *dev)
1587 return wm8350->regmap; 1587 return wm8350->regmap;
1588} 1588}
1589 1589
1590static struct snd_soc_codec_driver soc_codec_dev_wm8350 = { 1590static const struct snd_soc_codec_driver soc_codec_dev_wm8350 = {
1591 .probe = wm8350_codec_probe, 1591 .probe = wm8350_codec_probe,
1592 .remove = wm8350_codec_remove, 1592 .remove = wm8350_codec_remove,
1593 .get_regmap = wm8350_get_regmap, 1593 .get_regmap = wm8350_get_regmap,
1594 .set_bias_level = wm8350_set_bias_level, 1594 .set_bias_level = wm8350_set_bias_level,
1595 .suspend_bias_off = true, 1595 .suspend_bias_off = true,
1596 1596
1597 .controls = wm8350_snd_controls, 1597 .component_driver = {
1598 .num_controls = ARRAY_SIZE(wm8350_snd_controls), 1598 .controls = wm8350_snd_controls,
1599 .dapm_widgets = wm8350_dapm_widgets, 1599 .num_controls = ARRAY_SIZE(wm8350_snd_controls),
1600 .num_dapm_widgets = ARRAY_SIZE(wm8350_dapm_widgets), 1600 .dapm_widgets = wm8350_dapm_widgets,
1601 .dapm_routes = wm8350_dapm_routes, 1601 .num_dapm_widgets = ARRAY_SIZE(wm8350_dapm_widgets),
1602 .num_dapm_routes = ARRAY_SIZE(wm8350_dapm_routes), 1602 .dapm_routes = wm8350_dapm_routes,
1603 .num_dapm_routes = ARRAY_SIZE(wm8350_dapm_routes),
1604 },
1603}; 1605};
1604 1606
1605static int wm8350_probe(struct platform_device *pdev) 1607static int wm8350_probe(struct platform_device *pdev)
diff --git a/sound/soc/codecs/wm8400.c b/sound/soc/codecs/wm8400.c
index b1d346aa4696..6c59fb933bd6 100644
--- a/sound/soc/codecs/wm8400.c
+++ b/sound/soc/codecs/wm8400.c
@@ -1332,19 +1332,21 @@ static struct regmap *wm8400_get_regmap(struct device *dev)
1332 return wm8400->regmap; 1332 return wm8400->regmap;
1333} 1333}
1334 1334
1335static struct snd_soc_codec_driver soc_codec_dev_wm8400 = { 1335static const struct snd_soc_codec_driver soc_codec_dev_wm8400 = {
1336 .probe = wm8400_codec_probe, 1336 .probe = wm8400_codec_probe,
1337 .remove = wm8400_codec_remove, 1337 .remove = wm8400_codec_remove,
1338 .get_regmap = wm8400_get_regmap, 1338 .get_regmap = wm8400_get_regmap,
1339 .set_bias_level = wm8400_set_bias_level, 1339 .set_bias_level = wm8400_set_bias_level,
1340 .suspend_bias_off = true, 1340 .suspend_bias_off = true,
1341 1341
1342 .controls = wm8400_snd_controls, 1342 .component_driver = {
1343 .num_controls = ARRAY_SIZE(wm8400_snd_controls), 1343 .controls = wm8400_snd_controls,
1344 .dapm_widgets = wm8400_dapm_widgets, 1344 .num_controls = ARRAY_SIZE(wm8400_snd_controls),
1345 .num_dapm_widgets = ARRAY_SIZE(wm8400_dapm_widgets), 1345 .dapm_widgets = wm8400_dapm_widgets,
1346 .dapm_routes = wm8400_dapm_routes, 1346 .num_dapm_widgets = ARRAY_SIZE(wm8400_dapm_widgets),
1347 .num_dapm_routes = ARRAY_SIZE(wm8400_dapm_routes), 1347 .dapm_routes = wm8400_dapm_routes,
1348 .num_dapm_routes = ARRAY_SIZE(wm8400_dapm_routes),
1349 },
1348}; 1350};
1349 1351
1350static int wm8400_probe(struct platform_device *pdev) 1352static int wm8400_probe(struct platform_device *pdev)
diff --git a/sound/soc/codecs/wm8510.c b/sound/soc/codecs/wm8510.c
index 99e40e629cca..119ceac684ae 100644
--- a/sound/soc/codecs/wm8510.c
+++ b/sound/soc/codecs/wm8510.c
@@ -581,17 +581,19 @@ static int wm8510_probe(struct snd_soc_codec *codec)
581 return 0; 581 return 0;
582} 582}
583 583
584static struct snd_soc_codec_driver soc_codec_dev_wm8510 = { 584static const struct snd_soc_codec_driver soc_codec_dev_wm8510 = {
585 .probe = wm8510_probe, 585 .probe = wm8510_probe,
586 .set_bias_level = wm8510_set_bias_level, 586 .set_bias_level = wm8510_set_bias_level,
587 .suspend_bias_off = true, 587 .suspend_bias_off = true,
588 588
589 .controls = wm8510_snd_controls, 589 .component_driver = {
590 .num_controls = ARRAY_SIZE(wm8510_snd_controls), 590 .controls = wm8510_snd_controls,
591 .dapm_widgets = wm8510_dapm_widgets, 591 .num_controls = ARRAY_SIZE(wm8510_snd_controls),
592 .num_dapm_widgets = ARRAY_SIZE(wm8510_dapm_widgets), 592 .dapm_widgets = wm8510_dapm_widgets,
593 .dapm_routes = wm8510_dapm_routes, 593 .num_dapm_widgets = ARRAY_SIZE(wm8510_dapm_widgets),
594 .num_dapm_routes = ARRAY_SIZE(wm8510_dapm_routes), 594 .dapm_routes = wm8510_dapm_routes,
595 .num_dapm_routes = ARRAY_SIZE(wm8510_dapm_routes),
596 },
595}; 597};
596 598
597static const struct of_device_id wm8510_of_match[] = { 599static const struct of_device_id wm8510_of_match[] = {
diff --git a/sound/soc/codecs/wm8523.c b/sound/soc/codecs/wm8523.c
index aa287a3965e7..deb2e075428e 100644
--- a/sound/soc/codecs/wm8523.c
+++ b/sound/soc/codecs/wm8523.c
@@ -413,17 +413,19 @@ static int wm8523_probe(struct snd_soc_codec *codec)
413 return 0; 413 return 0;
414} 414}
415 415
416static struct snd_soc_codec_driver soc_codec_dev_wm8523 = { 416static const struct snd_soc_codec_driver soc_codec_dev_wm8523 = {
417 .probe = wm8523_probe, 417 .probe = wm8523_probe,
418 .set_bias_level = wm8523_set_bias_level, 418 .set_bias_level = wm8523_set_bias_level,
419 .suspend_bias_off = true, 419 .suspend_bias_off = true,
420 420
421 .controls = wm8523_controls, 421 .component_driver = {
422 .num_controls = ARRAY_SIZE(wm8523_controls), 422 .controls = wm8523_controls,
423 .dapm_widgets = wm8523_dapm_widgets, 423 .num_controls = ARRAY_SIZE(wm8523_controls),
424 .num_dapm_widgets = ARRAY_SIZE(wm8523_dapm_widgets), 424 .dapm_widgets = wm8523_dapm_widgets,
425 .dapm_routes = wm8523_dapm_routes, 425 .num_dapm_widgets = ARRAY_SIZE(wm8523_dapm_widgets),
426 .num_dapm_routes = ARRAY_SIZE(wm8523_dapm_routes), 426 .dapm_routes = wm8523_dapm_routes,
427 .num_dapm_routes = ARRAY_SIZE(wm8523_dapm_routes),
428 },
427}; 429};
428 430
429static const struct of_device_id wm8523_of_match[] = { 431static const struct of_device_id wm8523_of_match[] = {
diff --git a/sound/soc/codecs/wm8580.c b/sound/soc/codecs/wm8580.c
index 66602bf02f6e..faa7287a5253 100644
--- a/sound/soc/codecs/wm8580.c
+++ b/sound/soc/codecs/wm8580.c
@@ -899,17 +899,19 @@ static int wm8580_remove(struct snd_soc_codec *codec)
899 return 0; 899 return 0;
900} 900}
901 901
902static struct snd_soc_codec_driver soc_codec_dev_wm8580 = { 902static const struct snd_soc_codec_driver soc_codec_dev_wm8580 = {
903 .probe = wm8580_probe, 903 .probe = wm8580_probe,
904 .remove = wm8580_remove, 904 .remove = wm8580_remove,
905 .set_bias_level = wm8580_set_bias_level, 905 .set_bias_level = wm8580_set_bias_level,
906 906
907 .controls = wm8580_snd_controls, 907 .component_driver = {
908 .num_controls = ARRAY_SIZE(wm8580_snd_controls), 908 .controls = wm8580_snd_controls,
909 .dapm_widgets = wm8580_dapm_widgets, 909 .num_controls = ARRAY_SIZE(wm8580_snd_controls),
910 .num_dapm_widgets = ARRAY_SIZE(wm8580_dapm_widgets), 910 .dapm_widgets = wm8580_dapm_widgets,
911 .dapm_routes = wm8580_dapm_routes, 911 .num_dapm_widgets = ARRAY_SIZE(wm8580_dapm_widgets),
912 .num_dapm_routes = ARRAY_SIZE(wm8580_dapm_routes), 912 .dapm_routes = wm8580_dapm_routes,
913 .num_dapm_routes = ARRAY_SIZE(wm8580_dapm_routes),
914 },
913}; 915};
914 916
915static const struct of_device_id wm8580_of_match[] = { 917static const struct of_device_id wm8580_of_match[] = {
diff --git a/sound/soc/codecs/wm8711.c b/sound/soc/codecs/wm8711.c
index c759ec068e97..2b376c9c99af 100644
--- a/sound/soc/codecs/wm8711.c
+++ b/sound/soc/codecs/wm8711.c
@@ -367,17 +367,19 @@ static int wm8711_probe(struct snd_soc_codec *codec)
367 367
368} 368}
369 369
370static struct snd_soc_codec_driver soc_codec_dev_wm8711 = { 370static const struct snd_soc_codec_driver soc_codec_dev_wm8711 = {
371 .probe = wm8711_probe, 371 .probe = wm8711_probe,
372 .set_bias_level = wm8711_set_bias_level, 372 .set_bias_level = wm8711_set_bias_level,
373 .suspend_bias_off = true, 373 .suspend_bias_off = true,
374 374
375 .controls = wm8711_snd_controls, 375 .component_driver = {
376 .num_controls = ARRAY_SIZE(wm8711_snd_controls), 376 .controls = wm8711_snd_controls,
377 .dapm_widgets = wm8711_dapm_widgets, 377 .num_controls = ARRAY_SIZE(wm8711_snd_controls),
378 .num_dapm_widgets = ARRAY_SIZE(wm8711_dapm_widgets), 378 .dapm_widgets = wm8711_dapm_widgets,
379 .dapm_routes = wm8711_intercon, 379 .num_dapm_widgets = ARRAY_SIZE(wm8711_dapm_widgets),
380 .num_dapm_routes = ARRAY_SIZE(wm8711_intercon), 380 .dapm_routes = wm8711_intercon,
381 .num_dapm_routes = ARRAY_SIZE(wm8711_intercon),
382 },
381}; 383};
382 384
383static const struct of_device_id wm8711_of_match[] = { 385static const struct of_device_id wm8711_of_match[] = {
diff --git a/sound/soc/codecs/wm8727.c b/sound/soc/codecs/wm8727.c
index bb25a75f92a2..7fde077a014b 100644
--- a/sound/soc/codecs/wm8727.c
+++ b/sound/soc/codecs/wm8727.c
@@ -53,11 +53,13 @@ static struct snd_soc_dai_driver wm8727_dai = {
53 }, 53 },
54}; 54};
55 55
56static struct snd_soc_codec_driver soc_codec_dev_wm8727 = { 56static const struct snd_soc_codec_driver soc_codec_dev_wm8727 = {
57 .dapm_widgets = wm8727_dapm_widgets, 57 .component_driver = {
58 .num_dapm_widgets = ARRAY_SIZE(wm8727_dapm_widgets), 58 .dapm_widgets = wm8727_dapm_widgets,
59 .dapm_routes = wm8727_dapm_routes, 59 .num_dapm_widgets = ARRAY_SIZE(wm8727_dapm_widgets),
60 .num_dapm_routes = ARRAY_SIZE(wm8727_dapm_routes), 60 .dapm_routes = wm8727_dapm_routes,
61 .num_dapm_routes = ARRAY_SIZE(wm8727_dapm_routes),
62 },
61}; 63};
62 64
63static int wm8727_probe(struct platform_device *pdev) 65static int wm8727_probe(struct platform_device *pdev)
diff --git a/sound/soc/codecs/wm8728.c b/sound/soc/codecs/wm8728.c
index 1564e6926527..797cc6e7c70f 100644
--- a/sound/soc/codecs/wm8728.c
+++ b/sound/soc/codecs/wm8728.c
@@ -211,16 +211,18 @@ static struct snd_soc_dai_driver wm8728_dai = {
211 .ops = &wm8728_dai_ops, 211 .ops = &wm8728_dai_ops,
212}; 212};
213 213
214static struct snd_soc_codec_driver soc_codec_dev_wm8728 = { 214static const struct snd_soc_codec_driver soc_codec_dev_wm8728 = {
215 .set_bias_level = wm8728_set_bias_level, 215 .set_bias_level = wm8728_set_bias_level,
216 .suspend_bias_off = true, 216 .suspend_bias_off = true,
217 217
218 .controls = wm8728_snd_controls, 218 .component_driver = {
219 .num_controls = ARRAY_SIZE(wm8728_snd_controls), 219 .controls = wm8728_snd_controls,
220 .dapm_widgets = wm8728_dapm_widgets, 220 .num_controls = ARRAY_SIZE(wm8728_snd_controls),
221 .num_dapm_widgets = ARRAY_SIZE(wm8728_dapm_widgets), 221 .dapm_widgets = wm8728_dapm_widgets,
222 .dapm_routes = wm8728_intercon, 222 .num_dapm_widgets = ARRAY_SIZE(wm8728_dapm_widgets),
223 .num_dapm_routes = ARRAY_SIZE(wm8728_intercon), 223 .dapm_routes = wm8728_intercon,
224 .num_dapm_routes = ARRAY_SIZE(wm8728_intercon),
225 },
224}; 226};
225 227
226static const struct of_device_id wm8728_of_match[] = { 228static const struct of_device_id wm8728_of_match[] = {
diff --git a/sound/soc/codecs/wm8731.c b/sound/soc/codecs/wm8731.c
index d18261a44256..4f9a1eb28120 100644
--- a/sound/soc/codecs/wm8731.c
+++ b/sound/soc/codecs/wm8731.c
@@ -628,16 +628,18 @@ err_regulator_enable:
628 return ret; 628 return ret;
629} 629}
630 630
631static struct snd_soc_codec_driver soc_codec_dev_wm8731 = { 631static const struct snd_soc_codec_driver soc_codec_dev_wm8731 = {
632 .set_bias_level = wm8731_set_bias_level, 632 .set_bias_level = wm8731_set_bias_level,
633 .suspend_bias_off = true, 633 .suspend_bias_off = true,
634 634
635 .dapm_widgets = wm8731_dapm_widgets, 635 .component_driver = {
636 .num_dapm_widgets = ARRAY_SIZE(wm8731_dapm_widgets), 636 .controls = wm8731_snd_controls,
637 .dapm_routes = wm8731_intercon, 637 .num_controls = ARRAY_SIZE(wm8731_snd_controls),
638 .num_dapm_routes = ARRAY_SIZE(wm8731_intercon), 638 .dapm_widgets = wm8731_dapm_widgets,
639 .controls = wm8731_snd_controls, 639 .num_dapm_widgets = ARRAY_SIZE(wm8731_dapm_widgets),
640 .num_controls = ARRAY_SIZE(wm8731_snd_controls), 640 .dapm_routes = wm8731_intercon,
641 .num_dapm_routes = ARRAY_SIZE(wm8731_intercon),
642 },
641}; 643};
642 644
643static const struct of_device_id wm8731_of_match[] = { 645static const struct of_device_id wm8731_of_match[] = {
diff --git a/sound/soc/codecs/wm8737.c b/sound/soc/codecs/wm8737.c
index e7807601e675..f0cb1c4afe3c 100644
--- a/sound/soc/codecs/wm8737.c
+++ b/sound/soc/codecs/wm8737.c
@@ -573,17 +573,19 @@ err_get:
573 return ret; 573 return ret;
574} 574}
575 575
576static struct snd_soc_codec_driver soc_codec_dev_wm8737 = { 576static const struct snd_soc_codec_driver soc_codec_dev_wm8737 = {
577 .probe = wm8737_probe, 577 .probe = wm8737_probe,
578 .set_bias_level = wm8737_set_bias_level, 578 .set_bias_level = wm8737_set_bias_level,
579 .suspend_bias_off = true, 579 .suspend_bias_off = true,
580 580
581 .controls = wm8737_snd_controls, 581 .component_driver = {
582 .num_controls = ARRAY_SIZE(wm8737_snd_controls), 582 .controls = wm8737_snd_controls,
583 .dapm_widgets = wm8737_dapm_widgets, 583 .num_controls = ARRAY_SIZE(wm8737_snd_controls),
584 .num_dapm_widgets = ARRAY_SIZE(wm8737_dapm_widgets), 584 .dapm_widgets = wm8737_dapm_widgets,
585 .dapm_routes = intercon, 585 .num_dapm_widgets = ARRAY_SIZE(wm8737_dapm_widgets),
586 .num_dapm_routes = ARRAY_SIZE(intercon), 586 .dapm_routes = intercon,
587 .num_dapm_routes = ARRAY_SIZE(intercon),
588 },
587}; 589};
588 590
589static const struct of_device_id wm8737_of_match[] = { 591static const struct of_device_id wm8737_of_match[] = {
diff --git a/sound/soc/codecs/wm8741.c b/sound/soc/codecs/wm8741.c
index 36ef91fe0511..565d477cd790 100644
--- a/sound/soc/codecs/wm8741.c
+++ b/sound/soc/codecs/wm8741.c
@@ -497,15 +497,17 @@ static int wm8741_remove(struct snd_soc_codec *codec)
497 return 0; 497 return 0;
498} 498}
499 499
500static struct snd_soc_codec_driver soc_codec_dev_wm8741 = { 500static const struct snd_soc_codec_driver soc_codec_dev_wm8741 = {
501 .probe = wm8741_probe, 501 .probe = wm8741_probe,
502 .remove = wm8741_remove, 502 .remove = wm8741_remove,
503 .resume = wm8741_resume, 503 .resume = wm8741_resume,
504 504
505 .dapm_widgets = wm8741_dapm_widgets, 505 .component_driver = {
506 .num_dapm_widgets = ARRAY_SIZE(wm8741_dapm_widgets), 506 .dapm_widgets = wm8741_dapm_widgets,
507 .dapm_routes = wm8741_dapm_routes, 507 .num_dapm_widgets = ARRAY_SIZE(wm8741_dapm_widgets),
508 .num_dapm_routes = ARRAY_SIZE(wm8741_dapm_routes), 508 .dapm_routes = wm8741_dapm_routes,
509 .num_dapm_routes = ARRAY_SIZE(wm8741_dapm_routes),
510 },
509}; 511};
510 512
511static const struct of_device_id wm8741_of_match[] = { 513static const struct of_device_id wm8741_of_match[] = {
diff --git a/sound/soc/codecs/wm8750.c b/sound/soc/codecs/wm8750.c
index bd9dcd2161bc..0da2bbaf06d1 100644
--- a/sound/soc/codecs/wm8750.c
+++ b/sound/soc/codecs/wm8750.c
@@ -708,17 +708,19 @@ static int wm8750_probe(struct snd_soc_codec *codec)
708 return ret; 708 return ret;
709} 709}
710 710
711static struct snd_soc_codec_driver soc_codec_dev_wm8750 = { 711static const struct snd_soc_codec_driver soc_codec_dev_wm8750 = {
712 .probe = wm8750_probe, 712 .probe = wm8750_probe,
713 .set_bias_level = wm8750_set_bias_level, 713 .set_bias_level = wm8750_set_bias_level,
714 .suspend_bias_off = true, 714 .suspend_bias_off = true,
715 715
716 .controls = wm8750_snd_controls, 716 .component_driver = {
717 .num_controls = ARRAY_SIZE(wm8750_snd_controls), 717 .controls = wm8750_snd_controls,
718 .dapm_widgets = wm8750_dapm_widgets, 718 .num_controls = ARRAY_SIZE(wm8750_snd_controls),
719 .num_dapm_widgets = ARRAY_SIZE(wm8750_dapm_widgets), 719 .dapm_widgets = wm8750_dapm_widgets,
720 .dapm_routes = wm8750_dapm_routes, 720 .num_dapm_widgets = ARRAY_SIZE(wm8750_dapm_widgets),
721 .num_dapm_routes = ARRAY_SIZE(wm8750_dapm_routes), 721 .dapm_routes = wm8750_dapm_routes,
722 .num_dapm_routes = ARRAY_SIZE(wm8750_dapm_routes),
723 },
722}; 724};
723 725
724static const struct of_device_id wm8750_of_match[] = { 726static const struct of_device_id wm8750_of_match[] = {
diff --git a/sound/soc/codecs/wm8753.c b/sound/soc/codecs/wm8753.c
index cdcc91282e8a..9bdf5447f6f6 100644
--- a/sound/soc/codecs/wm8753.c
+++ b/sound/soc/codecs/wm8753.c
@@ -1478,18 +1478,20 @@ static int wm8753_probe(struct snd_soc_codec *codec)
1478 return 0; 1478 return 0;
1479} 1479}
1480 1480
1481static struct snd_soc_codec_driver soc_codec_dev_wm8753 = { 1481static const struct snd_soc_codec_driver soc_codec_dev_wm8753 = {
1482 .probe = wm8753_probe, 1482 .probe = wm8753_probe,
1483 .resume = wm8753_resume, 1483 .resume = wm8753_resume,
1484 .set_bias_level = wm8753_set_bias_level, 1484 .set_bias_level = wm8753_set_bias_level,
1485 .suspend_bias_off = true, 1485 .suspend_bias_off = true,
1486 1486
1487 .controls = wm8753_snd_controls, 1487 .component_driver = {
1488 .num_controls = ARRAY_SIZE(wm8753_snd_controls), 1488 .controls = wm8753_snd_controls,
1489 .dapm_widgets = wm8753_dapm_widgets, 1489 .num_controls = ARRAY_SIZE(wm8753_snd_controls),
1490 .num_dapm_widgets = ARRAY_SIZE(wm8753_dapm_widgets), 1490 .dapm_widgets = wm8753_dapm_widgets,
1491 .dapm_routes = wm8753_dapm_routes, 1491 .num_dapm_widgets = ARRAY_SIZE(wm8753_dapm_widgets),
1492 .num_dapm_routes = ARRAY_SIZE(wm8753_dapm_routes), 1492 .dapm_routes = wm8753_dapm_routes,
1493 .num_dapm_routes = ARRAY_SIZE(wm8753_dapm_routes),
1494 },
1493}; 1495};
1494 1496
1495static const struct of_device_id wm8753_of_match[] = { 1497static const struct of_device_id wm8753_of_match[] = {
diff --git a/sound/soc/codecs/wm8770.c b/sound/soc/codecs/wm8770.c
index df6178464b00..d6edcbbdec12 100644
--- a/sound/soc/codecs/wm8770.c
+++ b/sound/soc/codecs/wm8770.c
@@ -608,17 +608,19 @@ err_reg_enable:
608 return ret; 608 return ret;
609} 609}
610 610
611static struct snd_soc_codec_driver soc_codec_dev_wm8770 = { 611static const struct snd_soc_codec_driver soc_codec_dev_wm8770 = {
612 .probe = wm8770_probe, 612 .probe = wm8770_probe,
613 .set_bias_level = wm8770_set_bias_level, 613 .set_bias_level = wm8770_set_bias_level,
614 .idle_bias_off = true, 614 .idle_bias_off = true,
615 615
616 .controls = wm8770_snd_controls, 616 .component_driver = {
617 .num_controls = ARRAY_SIZE(wm8770_snd_controls), 617 .controls = wm8770_snd_controls,
618 .dapm_widgets = wm8770_dapm_widgets, 618 .num_controls = ARRAY_SIZE(wm8770_snd_controls),
619 .num_dapm_widgets = ARRAY_SIZE(wm8770_dapm_widgets), 619 .dapm_widgets = wm8770_dapm_widgets,
620 .dapm_routes = wm8770_intercon, 620 .num_dapm_widgets = ARRAY_SIZE(wm8770_dapm_widgets),
621 .num_dapm_routes = ARRAY_SIZE(wm8770_intercon), 621 .dapm_routes = wm8770_intercon,
622 .num_dapm_routes = ARRAY_SIZE(wm8770_intercon),
623 },
622}; 624};
623 625
624static const struct of_device_id wm8770_of_match[] = { 626static const struct of_device_id wm8770_of_match[] = {
diff --git a/sound/soc/codecs/wm8776.c b/sound/soc/codecs/wm8776.c
index 5af44f9a8cf2..ae30480b3976 100644
--- a/sound/soc/codecs/wm8776.c
+++ b/sound/soc/codecs/wm8776.c
@@ -425,17 +425,19 @@ static int wm8776_probe(struct snd_soc_codec *codec)
425 return ret; 425 return ret;
426} 426}
427 427
428static struct snd_soc_codec_driver soc_codec_dev_wm8776 = { 428static const struct snd_soc_codec_driver soc_codec_dev_wm8776 = {
429 .probe = wm8776_probe, 429 .probe = wm8776_probe,
430 .set_bias_level = wm8776_set_bias_level, 430 .set_bias_level = wm8776_set_bias_level,
431 .suspend_bias_off = true, 431 .suspend_bias_off = true,
432 432
433 .controls = wm8776_snd_controls, 433 .component_driver = {
434 .num_controls = ARRAY_SIZE(wm8776_snd_controls), 434 .controls = wm8776_snd_controls,
435 .dapm_widgets = wm8776_dapm_widgets, 435 .num_controls = ARRAY_SIZE(wm8776_snd_controls),
436 .num_dapm_widgets = ARRAY_SIZE(wm8776_dapm_widgets), 436 .dapm_widgets = wm8776_dapm_widgets,
437 .dapm_routes = routes, 437 .num_dapm_widgets = ARRAY_SIZE(wm8776_dapm_widgets),
438 .num_dapm_routes = ARRAY_SIZE(routes), 438 .dapm_routes = routes,
439 .num_dapm_routes = ARRAY_SIZE(routes),
440 },
439}; 441};
440 442
441static const struct of_device_id wm8776_of_match[] = { 443static const struct of_device_id wm8776_of_match[] = {
diff --git a/sound/soc/codecs/wm8782.c b/sound/soc/codecs/wm8782.c
index fb55fd845d27..bcda21018505 100644
--- a/sound/soc/codecs/wm8782.c
+++ b/sound/soc/codecs/wm8782.c
@@ -50,11 +50,13 @@ static struct snd_soc_dai_driver wm8782_dai = {
50 }, 50 },
51}; 51};
52 52
53static struct snd_soc_codec_driver soc_codec_dev_wm8782 = { 53static const struct snd_soc_codec_driver soc_codec_dev_wm8782 = {
54 .dapm_widgets = wm8782_dapm_widgets, 54 .component_driver = {
55 .num_dapm_widgets = ARRAY_SIZE(wm8782_dapm_widgets), 55 .dapm_widgets = wm8782_dapm_widgets,
56 .dapm_routes = wm8782_dapm_routes, 56 .num_dapm_widgets = ARRAY_SIZE(wm8782_dapm_widgets),
57 .num_dapm_routes = ARRAY_SIZE(wm8782_dapm_routes), 57 .dapm_routes = wm8782_dapm_routes,
58 .num_dapm_routes = ARRAY_SIZE(wm8782_dapm_routes),
59 },
58}; 60};
59 61
60static int wm8782_probe(struct platform_device *pdev) 62static int wm8782_probe(struct platform_device *pdev)
diff --git a/sound/soc/codecs/wm8804.c b/sound/soc/codecs/wm8804.c
index 8d914702cae4..af95d648265b 100644
--- a/sound/soc/codecs/wm8804.c
+++ b/sound/soc/codecs/wm8804.c
@@ -545,10 +545,12 @@ static struct snd_soc_dai_driver wm8804_dai = {
545static const struct snd_soc_codec_driver soc_codec_dev_wm8804 = { 545static const struct snd_soc_codec_driver soc_codec_dev_wm8804 = {
546 .idle_bias_off = true, 546 .idle_bias_off = true,
547 547
548 .dapm_widgets = wm8804_dapm_widgets, 548 .component_driver = {
549 .num_dapm_widgets = ARRAY_SIZE(wm8804_dapm_widgets), 549 .dapm_widgets = wm8804_dapm_widgets,
550 .dapm_routes = wm8804_dapm_routes, 550 .num_dapm_widgets = ARRAY_SIZE(wm8804_dapm_widgets),
551 .num_dapm_routes = ARRAY_SIZE(wm8804_dapm_routes), 551 .dapm_routes = wm8804_dapm_routes,
552 .num_dapm_routes = ARRAY_SIZE(wm8804_dapm_routes),
553 },
552}; 554};
553 555
554const struct regmap_config wm8804_regmap_config = { 556const struct regmap_config wm8804_regmap_config = {
diff --git a/sound/soc/codecs/wm8900.c b/sound/soc/codecs/wm8900.c
index 5d8dca88d612..c77b49a29311 100644
--- a/sound/soc/codecs/wm8900.c
+++ b/sound/soc/codecs/wm8900.c
@@ -1208,18 +1208,20 @@ static int wm8900_probe(struct snd_soc_codec *codec)
1208 return 0; 1208 return 0;
1209} 1209}
1210 1210
1211static struct snd_soc_codec_driver soc_codec_dev_wm8900 = { 1211static const struct snd_soc_codec_driver soc_codec_dev_wm8900 = {
1212 .probe = wm8900_probe, 1212 .probe = wm8900_probe,
1213 .suspend = wm8900_suspend, 1213 .suspend = wm8900_suspend,
1214 .resume = wm8900_resume, 1214 .resume = wm8900_resume,
1215 .set_bias_level = wm8900_set_bias_level, 1215 .set_bias_level = wm8900_set_bias_level,
1216 1216
1217 .controls = wm8900_snd_controls, 1217 .component_driver = {
1218 .num_controls = ARRAY_SIZE(wm8900_snd_controls), 1218 .controls = wm8900_snd_controls,
1219 .dapm_widgets = wm8900_dapm_widgets, 1219 .num_controls = ARRAY_SIZE(wm8900_snd_controls),
1220 .num_dapm_widgets = ARRAY_SIZE(wm8900_dapm_widgets), 1220 .dapm_widgets = wm8900_dapm_widgets,
1221 .dapm_routes = wm8900_dapm_routes, 1221 .num_dapm_widgets = ARRAY_SIZE(wm8900_dapm_widgets),
1222 .num_dapm_routes = ARRAY_SIZE(wm8900_dapm_routes), 1222 .dapm_routes = wm8900_dapm_routes,
1223 .num_dapm_routes = ARRAY_SIZE(wm8900_dapm_routes),
1224 },
1223}; 1225};
1224 1226
1225static const struct regmap_config wm8900_regmap = { 1227static const struct regmap_config wm8900_regmap = {
diff --git a/sound/soc/codecs/wm8903.c b/sound/soc/codecs/wm8903.c
index a26ca490cf31..6e887c2c42b1 100644
--- a/sound/soc/codecs/wm8903.c
+++ b/sound/soc/codecs/wm8903.c
@@ -1830,7 +1830,7 @@ static void wm8903_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
1830 !!value << WM8903_GP1_LVL_SHIFT); 1830 !!value << WM8903_GP1_LVL_SHIFT);
1831} 1831}
1832 1832
1833static struct gpio_chip wm8903_template_chip = { 1833static const struct gpio_chip wm8903_template_chip = {
1834 .label = "wm8903", 1834 .label = "wm8903",
1835 .owner = THIS_MODULE, 1835 .owner = THIS_MODULE,
1836 .request = wm8903_gpio_request, 1836 .request = wm8903_gpio_request,
@@ -1874,18 +1874,20 @@ static void wm8903_free_gpio(struct wm8903_priv *wm8903)
1874} 1874}
1875#endif 1875#endif
1876 1876
1877static struct snd_soc_codec_driver soc_codec_dev_wm8903 = { 1877static const struct snd_soc_codec_driver soc_codec_dev_wm8903 = {
1878 .resume = wm8903_resume, 1878 .resume = wm8903_resume,
1879 .set_bias_level = wm8903_set_bias_level, 1879 .set_bias_level = wm8903_set_bias_level,
1880 .seq_notifier = wm8903_seq_notifier, 1880 .seq_notifier = wm8903_seq_notifier,
1881 .suspend_bias_off = true, 1881 .suspend_bias_off = true,
1882 1882
1883 .controls = wm8903_snd_controls, 1883 .component_driver = {
1884 .num_controls = ARRAY_SIZE(wm8903_snd_controls), 1884 .controls = wm8903_snd_controls,
1885 .dapm_widgets = wm8903_dapm_widgets, 1885 .num_controls = ARRAY_SIZE(wm8903_snd_controls),
1886 .num_dapm_widgets = ARRAY_SIZE(wm8903_dapm_widgets), 1886 .dapm_widgets = wm8903_dapm_widgets,
1887 .dapm_routes = wm8903_intercon, 1887 .num_dapm_widgets = ARRAY_SIZE(wm8903_dapm_widgets),
1888 .num_dapm_routes = ARRAY_SIZE(wm8903_intercon), 1888 .dapm_routes = wm8903_intercon,
1889 .num_dapm_routes = ARRAY_SIZE(wm8903_intercon),
1890 },
1889}; 1891};
1890 1892
1891static const struct regmap_config wm8903_regmap = { 1893static const struct regmap_config wm8903_regmap = {
diff --git a/sound/soc/codecs/wm8904.c b/sound/soc/codecs/wm8904.c
index edd7a7709194..4fd350e8420d 100644
--- a/sound/soc/codecs/wm8904.c
+++ b/sound/soc/codecs/wm8904.c
@@ -2086,7 +2086,7 @@ static int wm8904_remove(struct snd_soc_codec *codec)
2086 return 0; 2086 return 0;
2087} 2087}
2088 2088
2089static struct snd_soc_codec_driver soc_codec_dev_wm8904 = { 2089static const struct snd_soc_codec_driver soc_codec_dev_wm8904 = {
2090 .probe = wm8904_probe, 2090 .probe = wm8904_probe,
2091 .remove = wm8904_remove, 2091 .remove = wm8904_remove,
2092 .set_bias_level = wm8904_set_bias_level, 2092 .set_bias_level = wm8904_set_bias_level,
diff --git a/sound/soc/codecs/wm8940.c b/sound/soc/codecs/wm8940.c
index 1c600819f768..b5935625feeb 100644
--- a/sound/soc/codecs/wm8940.c
+++ b/sound/soc/codecs/wm8940.c
@@ -723,17 +723,19 @@ static int wm8940_probe(struct snd_soc_codec *codec)
723 return ret; 723 return ret;
724} 724}
725 725
726static struct snd_soc_codec_driver soc_codec_dev_wm8940 = { 726static const struct snd_soc_codec_driver soc_codec_dev_wm8940 = {
727 .probe = wm8940_probe, 727 .probe = wm8940_probe,
728 .set_bias_level = wm8940_set_bias_level, 728 .set_bias_level = wm8940_set_bias_level,
729 .suspend_bias_off = true, 729 .suspend_bias_off = true,
730 730
731 .controls = wm8940_snd_controls, 731 .component_driver = {
732 .num_controls = ARRAY_SIZE(wm8940_snd_controls), 732 .controls = wm8940_snd_controls,
733 .dapm_widgets = wm8940_dapm_widgets, 733 .num_controls = ARRAY_SIZE(wm8940_snd_controls),
734 .num_dapm_widgets = ARRAY_SIZE(wm8940_dapm_widgets), 734 .dapm_widgets = wm8940_dapm_widgets,
735 .dapm_routes = wm8940_dapm_routes, 735 .num_dapm_widgets = ARRAY_SIZE(wm8940_dapm_widgets),
736 .num_dapm_routes = ARRAY_SIZE(wm8940_dapm_routes), 736 .dapm_routes = wm8940_dapm_routes,
737 .num_dapm_routes = ARRAY_SIZE(wm8940_dapm_routes),
738 },
737}; 739};
738 740
739static const struct regmap_config wm8940_regmap = { 741static const struct regmap_config wm8940_regmap = {
diff --git a/sound/soc/codecs/wm8955.c b/sound/soc/codecs/wm8955.c
index 9db00d53abe7..1edc7b1df31d 100644
--- a/sound/soc/codecs/wm8955.c
+++ b/sound/soc/codecs/wm8955.c
@@ -940,17 +940,19 @@ err_enable:
940 return ret; 940 return ret;
941} 941}
942 942
943static struct snd_soc_codec_driver soc_codec_dev_wm8955 = { 943static const struct snd_soc_codec_driver soc_codec_dev_wm8955 = {
944 .probe = wm8955_probe, 944 .probe = wm8955_probe,
945 .set_bias_level = wm8955_set_bias_level, 945 .set_bias_level = wm8955_set_bias_level,
946 .suspend_bias_off = true, 946 .suspend_bias_off = true,
947 947
948 .controls = wm8955_snd_controls, 948 .component_driver = {
949 .num_controls = ARRAY_SIZE(wm8955_snd_controls), 949 .controls = wm8955_snd_controls,
950 .dapm_widgets = wm8955_dapm_widgets, 950 .num_controls = ARRAY_SIZE(wm8955_snd_controls),
951 .num_dapm_widgets = ARRAY_SIZE(wm8955_dapm_widgets), 951 .dapm_widgets = wm8955_dapm_widgets,
952 .dapm_routes = wm8955_dapm_routes, 952 .num_dapm_widgets = ARRAY_SIZE(wm8955_dapm_widgets),
953 .num_dapm_routes = ARRAY_SIZE(wm8955_dapm_routes), 953 .dapm_routes = wm8955_dapm_routes,
954 .num_dapm_routes = ARRAY_SIZE(wm8955_dapm_routes),
955 },
954}; 956};
955 957
956static const struct regmap_config wm8955_regmap = { 958static const struct regmap_config wm8955_regmap = {
diff --git a/sound/soc/codecs/wm8960.c b/sound/soc/codecs/wm8960.c
index d7f444f87460..3bf081a7e450 100644
--- a/sound/soc/codecs/wm8960.c
+++ b/sound/soc/codecs/wm8960.c
@@ -226,11 +226,10 @@ static const DECLARE_TLV_DB_SCALE(dac_tlv, -12750, 50, 1);
226static const DECLARE_TLV_DB_SCALE(bypass_tlv, -2100, 300, 0); 226static const DECLARE_TLV_DB_SCALE(bypass_tlv, -2100, 300, 0);
227static const DECLARE_TLV_DB_SCALE(out_tlv, -12100, 100, 1); 227static const DECLARE_TLV_DB_SCALE(out_tlv, -12100, 100, 1);
228static const DECLARE_TLV_DB_SCALE(lineinboost_tlv, -1500, 300, 1); 228static const DECLARE_TLV_DB_SCALE(lineinboost_tlv, -1500, 300, 1);
229static const unsigned int micboost_tlv[] = { 229static const SNDRV_CTL_TLVD_DECLARE_DB_RANGE(micboost_tlv,
230 TLV_DB_RANGE_HEAD(2),
231 0, 1, TLV_DB_SCALE_ITEM(0, 1300, 0), 230 0, 1, TLV_DB_SCALE_ITEM(0, 1300, 0),
232 2, 3, TLV_DB_SCALE_ITEM(2000, 900, 0), 231 2, 3, TLV_DB_SCALE_ITEM(2000, 900, 0),
233}; 232);
234 233
235static const struct snd_kcontrol_new wm8960_snd_controls[] = { 234static const struct snd_kcontrol_new wm8960_snd_controls[] = {
236SOC_DOUBLE_R_TLV("Capture Volume", WM8960_LINVOL, WM8960_RINVOL, 235SOC_DOUBLE_R_TLV("Capture Volume", WM8960_LINVOL, WM8960_RINVOL,
@@ -1264,7 +1263,7 @@ static int wm8960_probe(struct snd_soc_codec *codec)
1264 return 0; 1263 return 0;
1265} 1264}
1266 1265
1267static struct snd_soc_codec_driver soc_codec_dev_wm8960 = { 1266static const struct snd_soc_codec_driver soc_codec_dev_wm8960 = {
1268 .probe = wm8960_probe, 1267 .probe = wm8960_probe,
1269 .set_bias_level = wm8960_set_bias_level, 1268 .set_bias_level = wm8960_set_bias_level,
1270 .suspend_bias_off = true, 1269 .suspend_bias_off = true,
diff --git a/sound/soc/codecs/wm8961.c b/sound/soc/codecs/wm8961.c
index e30446a04740..e23ceac76015 100644
--- a/sound/soc/codecs/wm8961.c
+++ b/sound/soc/codecs/wm8961.c
@@ -882,18 +882,20 @@ static int wm8961_resume(struct snd_soc_codec *codec)
882#define wm8961_resume NULL 882#define wm8961_resume NULL
883#endif 883#endif
884 884
885static struct snd_soc_codec_driver soc_codec_dev_wm8961 = { 885static const struct snd_soc_codec_driver soc_codec_dev_wm8961 = {
886 .probe = wm8961_probe, 886 .probe = wm8961_probe,
887 .resume = wm8961_resume, 887 .resume = wm8961_resume,
888 .set_bias_level = wm8961_set_bias_level, 888 .set_bias_level = wm8961_set_bias_level,
889 .suspend_bias_off = true, 889 .suspend_bias_off = true,
890 890
891 .controls = wm8961_snd_controls, 891 .component_driver = {
892 .num_controls = ARRAY_SIZE(wm8961_snd_controls), 892 .controls = wm8961_snd_controls,
893 .dapm_widgets = wm8961_dapm_widgets, 893 .num_controls = ARRAY_SIZE(wm8961_snd_controls),
894 .num_dapm_widgets = ARRAY_SIZE(wm8961_dapm_widgets), 894 .dapm_widgets = wm8961_dapm_widgets,
895 .dapm_routes = audio_paths, 895 .num_dapm_widgets = ARRAY_SIZE(wm8961_dapm_widgets),
896 .num_dapm_routes = ARRAY_SIZE(audio_paths), 896 .dapm_routes = audio_paths,
897 .num_dapm_routes = ARRAY_SIZE(audio_paths),
898 },
897}; 899};
898 900
899static const struct regmap_config wm8961_regmap = { 901static const struct regmap_config wm8961_regmap = {
diff --git a/sound/soc/codecs/wm8962.c b/sound/soc/codecs/wm8962.c
index f3109da24769..fd2731d171dd 100644
--- a/sound/soc/codecs/wm8962.c
+++ b/sound/soc/codecs/wm8962.c
@@ -3357,7 +3357,7 @@ static int wm8962_gpio_direction_out(struct gpio_chip *chip,
3357 return 0; 3357 return 0;
3358} 3358}
3359 3359
3360static struct gpio_chip wm8962_template_chip = { 3360static const struct gpio_chip wm8962_template_chip = {
3361 .label = "wm8962", 3361 .label = "wm8962",
3362 .owner = THIS_MODULE, 3362 .owner = THIS_MODULE,
3363 .request = wm8962_gpio_request, 3363 .request = wm8962_gpio_request,
@@ -3479,7 +3479,7 @@ static int wm8962_remove(struct snd_soc_codec *codec)
3479 return 0; 3479 return 0;
3480} 3480}
3481 3481
3482static struct snd_soc_codec_driver soc_codec_dev_wm8962 = { 3482static const struct snd_soc_codec_driver soc_codec_dev_wm8962 = {
3483 .probe = wm8962_probe, 3483 .probe = wm8962_probe,
3484 .remove = wm8962_remove, 3484 .remove = wm8962_remove,
3485 .set_bias_level = wm8962_set_bias_level, 3485 .set_bias_level = wm8962_set_bias_level,
@@ -3713,7 +3713,7 @@ static int wm8962_i2c_probe(struct i2c_client *i2c,
3713 ARRAY_SIZE(wm8962_dc_measure)); 3713 ARRAY_SIZE(wm8962_dc_measure));
3714 if (ret != 0) 3714 if (ret != 0)
3715 dev_err(&i2c->dev, 3715 dev_err(&i2c->dev,
3716 "Failed to configure for DC mesurement: %d\n", 3716 "Failed to configure for DC measurement: %d\n",
3717 ret); 3717 ret);
3718 } 3718 }
3719 3719
diff --git a/sound/soc/codecs/wm8971.c b/sound/soc/codecs/wm8971.c
index 2cdde32c43c6..887d31cf3945 100644
--- a/sound/soc/codecs/wm8971.c
+++ b/sound/soc/codecs/wm8971.c
@@ -649,17 +649,19 @@ static int wm8971_probe(struct snd_soc_codec *codec)
649 return 0; 649 return 0;
650} 650}
651 651
652static struct snd_soc_codec_driver soc_codec_dev_wm8971 = { 652static const struct snd_soc_codec_driver soc_codec_dev_wm8971 = {
653 .probe = wm8971_probe, 653 .probe = wm8971_probe,
654 .set_bias_level = wm8971_set_bias_level, 654 .set_bias_level = wm8971_set_bias_level,
655 .suspend_bias_off = true, 655 .suspend_bias_off = true,
656 656
657 .controls = wm8971_snd_controls, 657 .component_driver = {
658 .num_controls = ARRAY_SIZE(wm8971_snd_controls), 658 .controls = wm8971_snd_controls,
659 .dapm_widgets = wm8971_dapm_widgets, 659 .num_controls = ARRAY_SIZE(wm8971_snd_controls),
660 .num_dapm_widgets = ARRAY_SIZE(wm8971_dapm_widgets), 660 .dapm_widgets = wm8971_dapm_widgets,
661 .dapm_routes = wm8971_dapm_routes, 661 .num_dapm_widgets = ARRAY_SIZE(wm8971_dapm_widgets),
662 .num_dapm_routes = ARRAY_SIZE(wm8971_dapm_routes), 662 .dapm_routes = wm8971_dapm_routes,
663 .num_dapm_routes = ARRAY_SIZE(wm8971_dapm_routes),
664 },
663}; 665};
664 666
665static const struct regmap_config wm8971_regmap = { 667static const struct regmap_config wm8971_regmap = {
diff --git a/sound/soc/codecs/wm8974.c b/sound/soc/codecs/wm8974.c
index dc8c3b1ebb6f..d414ddd6e197 100644
--- a/sound/soc/codecs/wm8974.c
+++ b/sound/soc/codecs/wm8974.c
@@ -676,17 +676,19 @@ static int wm8974_probe(struct snd_soc_codec *codec)
676 return 0; 676 return 0;
677} 677}
678 678
679static struct snd_soc_codec_driver soc_codec_dev_wm8974 = { 679static const struct snd_soc_codec_driver soc_codec_dev_wm8974 = {
680 .probe = wm8974_probe, 680 .probe = wm8974_probe,
681 .set_bias_level = wm8974_set_bias_level, 681 .set_bias_level = wm8974_set_bias_level,
682 .suspend_bias_off = true, 682 .suspend_bias_off = true,
683 683
684 .controls = wm8974_snd_controls, 684 .component_driver = {
685 .num_controls = ARRAY_SIZE(wm8974_snd_controls), 685 .controls = wm8974_snd_controls,
686 .dapm_widgets = wm8974_dapm_widgets, 686 .num_controls = ARRAY_SIZE(wm8974_snd_controls),
687 .num_dapm_widgets = ARRAY_SIZE(wm8974_dapm_widgets), 687 .dapm_widgets = wm8974_dapm_widgets,
688 .dapm_routes = wm8974_dapm_routes, 688 .num_dapm_widgets = ARRAY_SIZE(wm8974_dapm_widgets),
689 .num_dapm_routes = ARRAY_SIZE(wm8974_dapm_routes), 689 .dapm_routes = wm8974_dapm_routes,
690 .num_dapm_routes = ARRAY_SIZE(wm8974_dapm_routes),
691 },
690}; 692};
691 693
692static int wm8974_i2c_probe(struct i2c_client *i2c, 694static int wm8974_i2c_probe(struct i2c_client *i2c,
diff --git a/sound/soc/codecs/wm8978.c b/sound/soc/codecs/wm8978.c
index d36d6001fbb7..90b2d418ef60 100644
--- a/sound/soc/codecs/wm8978.c
+++ b/sound/soc/codecs/wm8978.c
@@ -993,18 +993,20 @@ static int wm8978_probe(struct snd_soc_codec *codec)
993 return 0; 993 return 0;
994} 994}
995 995
996static struct snd_soc_codec_driver soc_codec_dev_wm8978 = { 996static const struct snd_soc_codec_driver soc_codec_dev_wm8978 = {
997 .probe = wm8978_probe, 997 .probe = wm8978_probe,
998 .suspend = wm8978_suspend, 998 .suspend = wm8978_suspend,
999 .resume = wm8978_resume, 999 .resume = wm8978_resume,
1000 .set_bias_level = wm8978_set_bias_level, 1000 .set_bias_level = wm8978_set_bias_level,
1001 1001
1002 .controls = wm8978_snd_controls, 1002 .component_driver = {
1003 .num_controls = ARRAY_SIZE(wm8978_snd_controls), 1003 .controls = wm8978_snd_controls,
1004 .dapm_widgets = wm8978_dapm_widgets, 1004 .num_controls = ARRAY_SIZE(wm8978_snd_controls),
1005 .num_dapm_widgets = ARRAY_SIZE(wm8978_dapm_widgets), 1005 .dapm_widgets = wm8978_dapm_widgets,
1006 .dapm_routes = wm8978_dapm_routes, 1006 .num_dapm_widgets = ARRAY_SIZE(wm8978_dapm_widgets),
1007 .num_dapm_routes = ARRAY_SIZE(wm8978_dapm_routes), 1007 .dapm_routes = wm8978_dapm_routes,
1008 .num_dapm_routes = ARRAY_SIZE(wm8978_dapm_routes),
1009 },
1008}; 1010};
1009 1011
1010static const struct regmap_config wm8978_regmap_config = { 1012static const struct regmap_config wm8978_regmap_config = {
diff --git a/sound/soc/codecs/wm8983.c b/sound/soc/codecs/wm8983.c
index 0c002a5712cb..bfdbe72ee687 100644
--- a/sound/soc/codecs/wm8983.c
+++ b/sound/soc/codecs/wm8983.c
@@ -976,16 +976,18 @@ static struct snd_soc_dai_driver wm8983_dai = {
976 .symmetric_rates = 1 976 .symmetric_rates = 1
977}; 977};
978 978
979static struct snd_soc_codec_driver soc_codec_dev_wm8983 = { 979static const struct snd_soc_codec_driver soc_codec_dev_wm8983 = {
980 .probe = wm8983_probe, 980 .probe = wm8983_probe,
981 .set_bias_level = wm8983_set_bias_level, 981 .set_bias_level = wm8983_set_bias_level,
982 .suspend_bias_off = true, 982 .suspend_bias_off = true,
983 .controls = wm8983_snd_controls, 983 .component_driver = {
984 .num_controls = ARRAY_SIZE(wm8983_snd_controls), 984 .controls = wm8983_snd_controls,
985 .dapm_widgets = wm8983_dapm_widgets, 985 .num_controls = ARRAY_SIZE(wm8983_snd_controls),
986 .num_dapm_widgets = ARRAY_SIZE(wm8983_dapm_widgets), 986 .dapm_widgets = wm8983_dapm_widgets,
987 .dapm_routes = wm8983_audio_map, 987 .num_dapm_widgets = ARRAY_SIZE(wm8983_dapm_widgets),
988 .num_dapm_routes = ARRAY_SIZE(wm8983_audio_map), 988 .dapm_routes = wm8983_audio_map,
989 .num_dapm_routes = ARRAY_SIZE(wm8983_audio_map),
990 },
989}; 991};
990 992
991static const struct regmap_config wm8983_regmap = { 993static const struct regmap_config wm8983_regmap = {
diff --git a/sound/soc/codecs/wm8985.c b/sound/soc/codecs/wm8985.c
index 7347abff4b2c..05344f974ff3 100644
--- a/sound/soc/codecs/wm8985.c
+++ b/sound/soc/codecs/wm8985.c
@@ -1105,17 +1105,19 @@ static struct snd_soc_dai_driver wm8985_dai = {
1105 .symmetric_rates = 1 1105 .symmetric_rates = 1
1106}; 1106};
1107 1107
1108static struct snd_soc_codec_driver soc_codec_dev_wm8985 = { 1108static const struct snd_soc_codec_driver soc_codec_dev_wm8985 = {
1109 .probe = wm8985_probe, 1109 .probe = wm8985_probe,
1110 .set_bias_level = wm8985_set_bias_level, 1110 .set_bias_level = wm8985_set_bias_level,
1111 .suspend_bias_off = true, 1111 .suspend_bias_off = true,
1112 1112
1113 .controls = wm8985_common_snd_controls, 1113 .component_driver = {
1114 .num_controls = ARRAY_SIZE(wm8985_common_snd_controls), 1114 .controls = wm8985_common_snd_controls,
1115 .dapm_widgets = wm8985_common_dapm_widgets, 1115 .num_controls = ARRAY_SIZE(wm8985_common_snd_controls),
1116 .num_dapm_widgets = ARRAY_SIZE(wm8985_common_dapm_widgets), 1116 .dapm_widgets = wm8985_common_dapm_widgets,
1117 .dapm_routes = wm8985_common_dapm_routes, 1117 .num_dapm_widgets = ARRAY_SIZE(wm8985_common_dapm_widgets),
1118 .num_dapm_routes = ARRAY_SIZE(wm8985_common_dapm_routes), 1118 .dapm_routes = wm8985_common_dapm_routes,
1119 .num_dapm_routes = ARRAY_SIZE(wm8985_common_dapm_routes),
1120 },
1119}; 1121};
1120 1122
1121static const struct regmap_config wm8985_regmap = { 1123static const struct regmap_config wm8985_regmap = {
diff --git a/sound/soc/codecs/wm8988.c b/sound/soc/codecs/wm8988.c
index 895721a256f0..b0d0219532f2 100644
--- a/sound/soc/codecs/wm8988.c
+++ b/sound/soc/codecs/wm8988.c
@@ -817,12 +817,14 @@ static const struct snd_soc_codec_driver soc_codec_dev_wm8988 = {
817 .set_bias_level = wm8988_set_bias_level, 817 .set_bias_level = wm8988_set_bias_level,
818 .suspend_bias_off = true, 818 .suspend_bias_off = true,
819 819
820 .controls = wm8988_snd_controls, 820 .component_driver = {
821 .num_controls = ARRAY_SIZE(wm8988_snd_controls), 821 .controls = wm8988_snd_controls,
822 .dapm_widgets = wm8988_dapm_widgets, 822 .num_controls = ARRAY_SIZE(wm8988_snd_controls),
823 .num_dapm_widgets = ARRAY_SIZE(wm8988_dapm_widgets), 823 .dapm_widgets = wm8988_dapm_widgets,
824 .dapm_routes = wm8988_dapm_routes, 824 .num_dapm_widgets = ARRAY_SIZE(wm8988_dapm_widgets),
825 .num_dapm_routes = ARRAY_SIZE(wm8988_dapm_routes), 825 .dapm_routes = wm8988_dapm_routes,
826 .num_dapm_routes = ARRAY_SIZE(wm8988_dapm_routes),
827 },
826}; 828};
827 829
828static const struct regmap_config wm8988_regmap = { 830static const struct regmap_config wm8988_regmap = {
diff --git a/sound/soc/codecs/wm8990.c b/sound/soc/codecs/wm8990.c
index 23ecd30d8bca..a8945001e696 100644
--- a/sound/soc/codecs/wm8990.c
+++ b/sound/soc/codecs/wm8990.c
@@ -1294,17 +1294,19 @@ static int wm8990_probe(struct snd_soc_codec *codec)
1294 return 0; 1294 return 0;
1295} 1295}
1296 1296
1297static struct snd_soc_codec_driver soc_codec_dev_wm8990 = { 1297static const struct snd_soc_codec_driver soc_codec_dev_wm8990 = {
1298 .probe = wm8990_probe, 1298 .probe = wm8990_probe,
1299 .set_bias_level = wm8990_set_bias_level, 1299 .set_bias_level = wm8990_set_bias_level,
1300 .suspend_bias_off = true, 1300 .suspend_bias_off = true,
1301 1301
1302 .controls = wm8990_snd_controls, 1302 .component_driver = {
1303 .num_controls = ARRAY_SIZE(wm8990_snd_controls), 1303 .controls = wm8990_snd_controls,
1304 .dapm_widgets = wm8990_dapm_widgets, 1304 .num_controls = ARRAY_SIZE(wm8990_snd_controls),
1305 .num_dapm_widgets = ARRAY_SIZE(wm8990_dapm_widgets), 1305 .dapm_widgets = wm8990_dapm_widgets,
1306 .dapm_routes = wm8990_dapm_routes, 1306 .num_dapm_widgets = ARRAY_SIZE(wm8990_dapm_widgets),
1307 .num_dapm_routes = ARRAY_SIZE(wm8990_dapm_routes), 1307 .dapm_routes = wm8990_dapm_routes,
1308 .num_dapm_routes = ARRAY_SIZE(wm8990_dapm_routes),
1309 },
1308}; 1310};
1309 1311
1310static const struct regmap_config wm8990_regmap = { 1312static const struct regmap_config wm8990_regmap = {
diff --git a/sound/soc/codecs/wm8991.c b/sound/soc/codecs/wm8991.c
index c9ee0ac6a654..802c0694e5c3 100644
--- a/sound/soc/codecs/wm8991.c
+++ b/sound/soc/codecs/wm8991.c
@@ -111,14 +111,24 @@ static bool wm8991_volatile(struct device *dev, unsigned int reg)
111 } 111 }
112} 112}
113 113
114static const DECLARE_TLV_DB_LINEAR(rec_mix_tlv, -1500, 600); 114static const SNDRV_CTL_TLVD_DECLARE_DB_SCALE(in_pga_tlv, -1650, 150, 0);
115static const DECLARE_TLV_DB_LINEAR(in_pga_tlv, -1650, 3000); 115static const SNDRV_CTL_TLVD_DECLARE_DB_SCALE(out_mix_tlv, -2100, 300, 0);
116static const DECLARE_TLV_DB_LINEAR(out_mix_tlv, 0, -2100); 116static const SNDRV_CTL_TLVD_DECLARE_DB_RANGE(out_pga_tlv,
117static const DECLARE_TLV_DB_LINEAR(out_pga_tlv, -7300, 600); 117 0x00, 0x2f, SNDRV_CTL_TLVD_DB_SCALE_ITEM(SNDRV_CTL_TLVD_DB_GAIN_MUTE, 0, 1),
118static const DECLARE_TLV_DB_LINEAR(out_omix_tlv, -600, 0); 118 0x30, 0x7f, SNDRV_CTL_TLVD_DB_SCALE_ITEM(-7300, 100, 0),
119static const DECLARE_TLV_DB_LINEAR(out_dac_tlv, -7163, 0); 119);
120static const DECLARE_TLV_DB_LINEAR(in_adc_tlv, -7163, 1763); 120static const SNDRV_CTL_TLVD_DECLARE_DB_RANGE(out_dac_tlv,
121static const DECLARE_TLV_DB_LINEAR(out_sidetone_tlv, -3600, 0); 121 0x00, 0xbf, SNDRV_CTL_TLVD_DB_SCALE_ITEM(-71625, 375, 1),
122 0xc0, 0xff, SNDRV_CTL_TLVD_DB_SCALE_ITEM(0, 0, 0),
123);
124static const SNDRV_CTL_TLVD_DECLARE_DB_RANGE(in_adc_tlv,
125 0x00, 0xef, SNDRV_CTL_TLVD_DB_SCALE_ITEM(-71625, 375, 1),
126 0xf0, 0xff, SNDRV_CTL_TLVD_DB_SCALE_ITEM(17625, 0, 0),
127);
128static const SNDRV_CTL_TLVD_DECLARE_DB_RANGE(out_sidetone_tlv,
129 0x00, 0x0c, SNDRV_CTL_TLVD_DB_SCALE_ITEM(-3600, 300, 0),
130 0x0d, 0x0f, SNDRV_CTL_TLVD_DB_SCALE_ITEM(0, 0, 0),
131);
122 132
123static int wm899x_outpga_put_volsw_vu(struct snd_kcontrol *kcontrol, 133static int wm899x_outpga_put_volsw_vu(struct snd_kcontrol *kcontrol,
124 struct snd_ctl_elem_value *ucontrol) 134 struct snd_ctl_elem_value *ucontrol)
@@ -398,7 +408,7 @@ static int outmixer_event(struct snd_soc_dapm_widget *w,
398} 408}
399 409
400/* INMIX dB values */ 410/* INMIX dB values */
401static const DECLARE_TLV_DB_LINEAR(in_mix_tlv, -1200, 600); 411static const SNDRV_CTL_TLVD_DECLARE_DB_SCALE(in_mix_tlv, -1200, 300, 1);
402 412
403/* Left In PGA Connections */ 413/* Left In PGA Connections */
404static const struct snd_kcontrol_new wm8991_dapm_lin12_pga_controls[] = { 414static const struct snd_kcontrol_new wm8991_dapm_lin12_pga_controls[] = {
@@ -1232,16 +1242,18 @@ static struct snd_soc_dai_driver wm8991_dai = {
1232 .ops = &wm8991_ops 1242 .ops = &wm8991_ops
1233}; 1243};
1234 1244
1235static struct snd_soc_codec_driver soc_codec_dev_wm8991 = { 1245static const struct snd_soc_codec_driver soc_codec_dev_wm8991 = {
1236 .set_bias_level = wm8991_set_bias_level, 1246 .set_bias_level = wm8991_set_bias_level,
1237 .suspend_bias_off = true, 1247 .suspend_bias_off = true,
1238 1248
1239 .controls = wm8991_snd_controls, 1249 .component_driver = {
1240 .num_controls = ARRAY_SIZE(wm8991_snd_controls), 1250 .controls = wm8991_snd_controls,
1241 .dapm_widgets = wm8991_dapm_widgets, 1251 .num_controls = ARRAY_SIZE(wm8991_snd_controls),
1242 .num_dapm_widgets = ARRAY_SIZE(wm8991_dapm_widgets), 1252 .dapm_widgets = wm8991_dapm_widgets,
1243 .dapm_routes = wm8991_dapm_routes, 1253 .num_dapm_widgets = ARRAY_SIZE(wm8991_dapm_widgets),
1244 .num_dapm_routes = ARRAY_SIZE(wm8991_dapm_routes), 1254 .dapm_routes = wm8991_dapm_routes,
1255 .num_dapm_routes = ARRAY_SIZE(wm8991_dapm_routes),
1256 },
1245}; 1257};
1246 1258
1247static const struct regmap_config wm8991_regmap = { 1259static const struct regmap_config wm8991_regmap = {
diff --git a/sound/soc/codecs/wm8993.c b/sound/soc/codecs/wm8993.c
index 8668c4c391b0..195f7bf6eb22 100644
--- a/sound/soc/codecs/wm8993.c
+++ b/sound/soc/codecs/wm8993.c
@@ -1613,7 +1613,7 @@ static const struct regmap_config wm8993_regmap = {
1613 .num_reg_defaults = ARRAY_SIZE(wm8993_reg_defaults), 1613 .num_reg_defaults = ARRAY_SIZE(wm8993_reg_defaults),
1614}; 1614};
1615 1615
1616static struct snd_soc_codec_driver soc_codec_dev_wm8993 = { 1616static const struct snd_soc_codec_driver soc_codec_dev_wm8993 = {
1617 .probe = wm8993_probe, 1617 .probe = wm8993_probe,
1618 .suspend = wm8993_suspend, 1618 .suspend = wm8993_suspend,
1619 .resume = wm8993_resume, 1619 .resume = wm8993_resume,
diff --git a/sound/soc/codecs/wm8994.c b/sound/soc/codecs/wm8994.c
index a18aecb49935..3896523b71e9 100644
--- a/sound/soc/codecs/wm8994.c
+++ b/sound/soc/codecs/wm8994.c
@@ -4439,7 +4439,7 @@ static struct regmap *wm8994_get_regmap(struct device *dev)
4439 return control->regmap; 4439 return control->regmap;
4440} 4440}
4441 4441
4442static struct snd_soc_codec_driver soc_codec_dev_wm8994 = { 4442static const struct snd_soc_codec_driver soc_codec_dev_wm8994 = {
4443 .probe = wm8994_codec_probe, 4443 .probe = wm8994_codec_probe,
4444 .remove = wm8994_codec_remove, 4444 .remove = wm8994_codec_remove,
4445 .suspend = wm8994_codec_suspend, 4445 .suspend = wm8994_codec_suspend,
diff --git a/sound/soc/codecs/wm8995.c b/sound/soc/codecs/wm8995.c
index 24500bafb0a8..19b08a5cae62 100644
--- a/sound/soc/codecs/wm8995.c
+++ b/sound/soc/codecs/wm8995.c
@@ -2192,12 +2192,14 @@ static const struct snd_soc_codec_driver soc_codec_dev_wm8995 = {
2192 .set_bias_level = wm8995_set_bias_level, 2192 .set_bias_level = wm8995_set_bias_level,
2193 .idle_bias_off = true, 2193 .idle_bias_off = true,
2194 2194
2195 .controls = wm8995_snd_controls, 2195 .component_driver = {
2196 .num_controls = ARRAY_SIZE(wm8995_snd_controls), 2196 .controls = wm8995_snd_controls,
2197 .dapm_widgets = wm8995_dapm_widgets, 2197 .num_controls = ARRAY_SIZE(wm8995_snd_controls),
2198 .num_dapm_widgets = ARRAY_SIZE(wm8995_dapm_widgets), 2198 .dapm_widgets = wm8995_dapm_widgets,
2199 .dapm_routes = wm8995_intercon, 2199 .num_dapm_widgets = ARRAY_SIZE(wm8995_dapm_widgets),
2200 .num_dapm_routes = ARRAY_SIZE(wm8995_intercon), 2200 .dapm_routes = wm8995_intercon,
2201 .num_dapm_routes = ARRAY_SIZE(wm8995_intercon),
2202 },
2201}; 2203};
2202 2204
2203static const struct regmap_config wm8995_regmap = { 2205static const struct regmap_config wm8995_regmap = {
diff --git a/sound/soc/codecs/wm8996.c b/sound/soc/codecs/wm8996.c
index a73044251218..8affa4969120 100644
--- a/sound/soc/codecs/wm8996.c
+++ b/sound/soc/codecs/wm8996.c
@@ -2184,7 +2184,7 @@ static int wm8996_gpio_direction_in(struct gpio_chip *chip, unsigned offset)
2184 (1 << WM8996_GP1_DIR_SHIFT)); 2184 (1 << WM8996_GP1_DIR_SHIFT));
2185} 2185}
2186 2186
2187static struct gpio_chip wm8996_template_chip = { 2187static const struct gpio_chip wm8996_template_chip = {
2188 .label = "wm8996", 2188 .label = "wm8996",
2189 .owner = THIS_MODULE, 2189 .owner = THIS_MODULE,
2190 .direction_output = wm8996_gpio_direction_out, 2190 .direction_output = wm8996_gpio_direction_out,
@@ -2684,18 +2684,20 @@ static int wm8996_remove(struct snd_soc_codec *codec)
2684 return 0; 2684 return 0;
2685} 2685}
2686 2686
2687static struct snd_soc_codec_driver soc_codec_dev_wm8996 = { 2687static const struct snd_soc_codec_driver soc_codec_dev_wm8996 = {
2688 .probe = wm8996_probe, 2688 .probe = wm8996_probe,
2689 .remove = wm8996_remove, 2689 .remove = wm8996_remove,
2690 .set_bias_level = wm8996_set_bias_level, 2690 .set_bias_level = wm8996_set_bias_level,
2691 .idle_bias_off = true, 2691 .idle_bias_off = true,
2692 .seq_notifier = wm8996_seq_notifier, 2692 .seq_notifier = wm8996_seq_notifier,
2693 .controls = wm8996_snd_controls, 2693 .component_driver = {
2694 .num_controls = ARRAY_SIZE(wm8996_snd_controls), 2694 .controls = wm8996_snd_controls,
2695 .dapm_widgets = wm8996_dapm_widgets, 2695 .num_controls = ARRAY_SIZE(wm8996_snd_controls),
2696 .num_dapm_widgets = ARRAY_SIZE(wm8996_dapm_widgets), 2696 .dapm_widgets = wm8996_dapm_widgets,
2697 .dapm_routes = wm8996_dapm_routes, 2697 .num_dapm_widgets = ARRAY_SIZE(wm8996_dapm_widgets),
2698 .num_dapm_routes = ARRAY_SIZE(wm8996_dapm_routes), 2698 .dapm_routes = wm8996_dapm_routes,
2699 .num_dapm_routes = ARRAY_SIZE(wm8996_dapm_routes),
2700 },
2699 .set_pll = wm8996_set_fll, 2701 .set_pll = wm8996_set_fll,
2700}; 2702};
2701 2703
diff --git a/sound/soc/codecs/wm8997.c b/sound/soc/codecs/wm8997.c
index 6b0785b5a5c5..2f2821b3382f 100644
--- a/sound/soc/codecs/wm8997.c
+++ b/sound/soc/codecs/wm8997.c
@@ -1095,7 +1095,7 @@ static struct regmap *wm8997_get_regmap(struct device *dev)
1095 return priv->core.arizona->regmap; 1095 return priv->core.arizona->regmap;
1096} 1096}
1097 1097
1098static struct snd_soc_codec_driver soc_codec_dev_wm8997 = { 1098static const struct snd_soc_codec_driver soc_codec_dev_wm8997 = {
1099 .probe = wm8997_codec_probe, 1099 .probe = wm8997_codec_probe,
1100 .remove = wm8997_codec_remove, 1100 .remove = wm8997_codec_remove,
1101 .get_regmap = wm8997_get_regmap, 1101 .get_regmap = wm8997_get_regmap,
@@ -1105,12 +1105,14 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8997 = {
1105 .set_sysclk = arizona_set_sysclk, 1105 .set_sysclk = arizona_set_sysclk,
1106 .set_pll = wm8997_set_fll, 1106 .set_pll = wm8997_set_fll,
1107 1107
1108 .controls = wm8997_snd_controls, 1108 .component_driver = {
1109 .num_controls = ARRAY_SIZE(wm8997_snd_controls), 1109 .controls = wm8997_snd_controls,
1110 .dapm_widgets = wm8997_dapm_widgets, 1110 .num_controls = ARRAY_SIZE(wm8997_snd_controls),
1111 .num_dapm_widgets = ARRAY_SIZE(wm8997_dapm_widgets), 1111 .dapm_widgets = wm8997_dapm_widgets,
1112 .dapm_routes = wm8997_dapm_routes, 1112 .num_dapm_widgets = ARRAY_SIZE(wm8997_dapm_widgets),
1113 .num_dapm_routes = ARRAY_SIZE(wm8997_dapm_routes), 1113 .dapm_routes = wm8997_dapm_routes,
1114 .num_dapm_routes = ARRAY_SIZE(wm8997_dapm_routes),
1115 },
1114}; 1116};
1115 1117
1116static int wm8997_probe(struct platform_device *pdev) 1118static int wm8997_probe(struct platform_device *pdev)
diff --git a/sound/soc/codecs/wm8998.c b/sound/soc/codecs/wm8998.c
index 3a5c896a2d13..bcc2e1060a6c 100644
--- a/sound/soc/codecs/wm8998.c
+++ b/sound/soc/codecs/wm8998.c
@@ -966,6 +966,16 @@ static const struct snd_soc_dapm_route wm8998_dapm_routes[] = {
966 { "IN2A", NULL, "SYSCLK" }, 966 { "IN2A", NULL, "SYSCLK" },
967 { "IN2B", NULL, "SYSCLK" }, 967 { "IN2B", NULL, "SYSCLK" },
968 968
969 { "ASRC1L", NULL, "SYSCLK" },
970 { "ASRC1R", NULL, "SYSCLK" },
971 { "ASRC2L", NULL, "SYSCLK" },
972 { "ASRC2R", NULL, "SYSCLK" },
973
974 { "ASRC1L", NULL, "ASYNCCLK" },
975 { "ASRC1R", NULL, "ASYNCCLK" },
976 { "ASRC2L", NULL, "ASYNCCLK" },
977 { "ASRC2R", NULL, "ASYNCCLK" },
978
969 { "SPD1", NULL, "SYSCLK" }, 979 { "SPD1", NULL, "SYSCLK" },
970 { "SPD1", NULL, "SPD1TX1" }, 980 { "SPD1", NULL, "SPD1TX1" },
971 { "SPD1", NULL, "SPD1TX2" }, 981 { "SPD1", NULL, "SPD1TX2" },
@@ -1351,7 +1361,7 @@ static struct regmap *wm8998_get_regmap(struct device *dev)
1351 return priv->core.arizona->regmap; 1361 return priv->core.arizona->regmap;
1352} 1362}
1353 1363
1354static struct snd_soc_codec_driver soc_codec_dev_wm8998 = { 1364static const struct snd_soc_codec_driver soc_codec_dev_wm8998 = {
1355 .probe = wm8998_codec_probe, 1365 .probe = wm8998_codec_probe,
1356 .remove = wm8998_codec_remove, 1366 .remove = wm8998_codec_remove,
1357 .get_regmap = wm8998_get_regmap, 1367 .get_regmap = wm8998_get_regmap,
@@ -1361,12 +1371,14 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8998 = {
1361 .set_sysclk = arizona_set_sysclk, 1371 .set_sysclk = arizona_set_sysclk,
1362 .set_pll = wm8998_set_fll, 1372 .set_pll = wm8998_set_fll,
1363 1373
1364 .controls = wm8998_snd_controls, 1374 .component_driver = {
1365 .num_controls = ARRAY_SIZE(wm8998_snd_controls), 1375 .controls = wm8998_snd_controls,
1366 .dapm_widgets = wm8998_dapm_widgets, 1376 .num_controls = ARRAY_SIZE(wm8998_snd_controls),
1367 .num_dapm_widgets = ARRAY_SIZE(wm8998_dapm_widgets), 1377 .dapm_widgets = wm8998_dapm_widgets,
1368 .dapm_routes = wm8998_dapm_routes, 1378 .num_dapm_widgets = ARRAY_SIZE(wm8998_dapm_widgets),
1369 .num_dapm_routes = ARRAY_SIZE(wm8998_dapm_routes), 1379 .dapm_routes = wm8998_dapm_routes,
1380 .num_dapm_routes = ARRAY_SIZE(wm8998_dapm_routes),
1381 },
1370}; 1382};
1371 1383
1372static int wm8998_probe(struct platform_device *pdev) 1384static int wm8998_probe(struct platform_device *pdev)
diff --git a/sound/soc/codecs/wm9081.c b/sound/soc/codecs/wm9081.c
index 363b3b667616..856867ec2813 100644
--- a/sound/soc/codecs/wm9081.c
+++ b/sound/soc/codecs/wm9081.c
@@ -1274,7 +1274,7 @@ static int wm9081_probe(struct snd_soc_codec *codec)
1274 return 0; 1274 return 0;
1275} 1275}
1276 1276
1277static struct snd_soc_codec_driver soc_codec_dev_wm9081 = { 1277static const struct snd_soc_codec_driver soc_codec_dev_wm9081 = {
1278 .probe = wm9081_probe, 1278 .probe = wm9081_probe,
1279 1279
1280 .set_sysclk = wm9081_set_sysclk, 1280 .set_sysclk = wm9081_set_sysclk,
@@ -1282,12 +1282,14 @@ static struct snd_soc_codec_driver soc_codec_dev_wm9081 = {
1282 1282
1283 .idle_bias_off = true, 1283 .idle_bias_off = true,
1284 1284
1285 .controls = wm9081_snd_controls, 1285 .component_driver = {
1286 .num_controls = ARRAY_SIZE(wm9081_snd_controls), 1286 .controls = wm9081_snd_controls,
1287 .dapm_widgets = wm9081_dapm_widgets, 1287 .num_controls = ARRAY_SIZE(wm9081_snd_controls),
1288 .num_dapm_widgets = ARRAY_SIZE(wm9081_dapm_widgets), 1288 .dapm_widgets = wm9081_dapm_widgets,
1289 .dapm_routes = wm9081_audio_paths, 1289 .num_dapm_widgets = ARRAY_SIZE(wm9081_dapm_widgets),
1290 .num_dapm_routes = ARRAY_SIZE(wm9081_audio_paths), 1290 .dapm_routes = wm9081_audio_paths,
1291 .num_dapm_routes = ARRAY_SIZE(wm9081_audio_paths),
1292 },
1291}; 1293};
1292 1294
1293static const struct regmap_config wm9081_regmap = { 1295static const struct regmap_config wm9081_regmap = {
diff --git a/sound/soc/codecs/wm9090.c b/sound/soc/codecs/wm9090.c
index 5d737290f547..5a131385cb2f 100644
--- a/sound/soc/codecs/wm9090.c
+++ b/sound/soc/codecs/wm9090.c
@@ -550,7 +550,7 @@ static int wm9090_probe(struct snd_soc_codec *codec)
550 return 0; 550 return 0;
551} 551}
552 552
553static struct snd_soc_codec_driver soc_codec_dev_wm9090 = { 553static const struct snd_soc_codec_driver soc_codec_dev_wm9090 = {
554 .probe = wm9090_probe, 554 .probe = wm9090_probe,
555 .set_bias_level = wm9090_set_bias_level, 555 .set_bias_level = wm9090_set_bias_level,
556 .suspend_bias_off = true, 556 .suspend_bias_off = true,
diff --git a/sound/soc/codecs/wm9705.c b/sound/soc/codecs/wm9705.c
index 744842c76a60..dcdd055db57b 100644
--- a/sound/soc/codecs/wm9705.c
+++ b/sound/soc/codecs/wm9705.c
@@ -352,7 +352,7 @@ static int wm9705_soc_remove(struct snd_soc_codec *codec)
352 return 0; 352 return 0;
353} 353}
354 354
355static struct snd_soc_codec_driver soc_codec_dev_wm9705 = { 355static const struct snd_soc_codec_driver soc_codec_dev_wm9705 = {
356 .probe = wm9705_soc_probe, 356 .probe = wm9705_soc_probe,
357 .remove = wm9705_soc_remove, 357 .remove = wm9705_soc_remove,
358 .suspend = wm9705_soc_suspend, 358 .suspend = wm9705_soc_suspend,
@@ -364,12 +364,14 @@ static struct snd_soc_codec_driver soc_codec_dev_wm9705 = {
364 .reg_cache_step = 2, 364 .reg_cache_step = 2,
365 .reg_cache_default = wm9705_reg, 365 .reg_cache_default = wm9705_reg,
366 366
367 .controls = wm9705_snd_ac97_controls, 367 .component_driver = {
368 .num_controls = ARRAY_SIZE(wm9705_snd_ac97_controls), 368 .controls = wm9705_snd_ac97_controls,
369 .dapm_widgets = wm9705_dapm_widgets, 369 .num_controls = ARRAY_SIZE(wm9705_snd_ac97_controls),
370 .num_dapm_widgets = ARRAY_SIZE(wm9705_dapm_widgets), 370 .dapm_widgets = wm9705_dapm_widgets,
371 .dapm_routes = wm9705_audio_map, 371 .num_dapm_widgets = ARRAY_SIZE(wm9705_dapm_widgets),
372 .num_dapm_routes = ARRAY_SIZE(wm9705_audio_map), 372 .dapm_routes = wm9705_audio_map,
373 .num_dapm_routes = ARRAY_SIZE(wm9705_audio_map),
374 },
373}; 375};
374 376
375static int wm9705_probe(struct platform_device *pdev) 377static int wm9705_probe(struct platform_device *pdev)
diff --git a/sound/soc/codecs/wm9712.c b/sound/soc/codecs/wm9712.c
index 488a92224249..557709eac698 100644
--- a/sound/soc/codecs/wm9712.c
+++ b/sound/soc/codecs/wm9712.c
@@ -669,7 +669,7 @@ static int wm9712_soc_remove(struct snd_soc_codec *codec)
669 return 0; 669 return 0;
670} 670}
671 671
672static struct snd_soc_codec_driver soc_codec_dev_wm9712 = { 672static const struct snd_soc_codec_driver soc_codec_dev_wm9712 = {
673 .probe = wm9712_soc_probe, 673 .probe = wm9712_soc_probe,
674 .remove = wm9712_soc_remove, 674 .remove = wm9712_soc_remove,
675 .resume = wm9712_soc_resume, 675 .resume = wm9712_soc_resume,
@@ -682,12 +682,14 @@ static struct snd_soc_codec_driver soc_codec_dev_wm9712 = {
682 .reg_cache_step = 2, 682 .reg_cache_step = 2,
683 .reg_cache_default = wm9712_reg, 683 .reg_cache_default = wm9712_reg,
684 684
685 .controls = wm9712_snd_ac97_controls, 685 .component_driver = {
686 .num_controls = ARRAY_SIZE(wm9712_snd_ac97_controls), 686 .controls = wm9712_snd_ac97_controls,
687 .dapm_widgets = wm9712_dapm_widgets, 687 .num_controls = ARRAY_SIZE(wm9712_snd_ac97_controls),
688 .num_dapm_widgets = ARRAY_SIZE(wm9712_dapm_widgets), 688 .dapm_widgets = wm9712_dapm_widgets,
689 .dapm_routes = wm9712_audio_map, 689 .num_dapm_widgets = ARRAY_SIZE(wm9712_dapm_widgets),
690 .num_dapm_routes = ARRAY_SIZE(wm9712_audio_map), 690 .dapm_routes = wm9712_audio_map,
691 .num_dapm_routes = ARRAY_SIZE(wm9712_audio_map),
692 },
691}; 693};
692 694
693static int wm9712_probe(struct platform_device *pdev) 695static int wm9712_probe(struct platform_device *pdev)
diff --git a/sound/soc/codecs/wm9713.c b/sound/soc/codecs/wm9713.c
index 9849643ef809..e4301ddb1b84 100644
--- a/sound/soc/codecs/wm9713.c
+++ b/sound/soc/codecs/wm9713.c
@@ -1235,19 +1235,21 @@ static int wm9713_soc_remove(struct snd_soc_codec *codec)
1235 return 0; 1235 return 0;
1236} 1236}
1237 1237
1238static struct snd_soc_codec_driver soc_codec_dev_wm9713 = { 1238static const struct snd_soc_codec_driver soc_codec_dev_wm9713 = {
1239 .probe = wm9713_soc_probe, 1239 .probe = wm9713_soc_probe,
1240 .remove = wm9713_soc_remove, 1240 .remove = wm9713_soc_remove,
1241 .suspend = wm9713_soc_suspend, 1241 .suspend = wm9713_soc_suspend,
1242 .resume = wm9713_soc_resume, 1242 .resume = wm9713_soc_resume,
1243 .set_bias_level = wm9713_set_bias_level, 1243 .set_bias_level = wm9713_set_bias_level,
1244 1244
1245 .controls = wm9713_snd_ac97_controls, 1245 .component_driver = {
1246 .num_controls = ARRAY_SIZE(wm9713_snd_ac97_controls), 1246 .controls = wm9713_snd_ac97_controls,
1247 .dapm_widgets = wm9713_dapm_widgets, 1247 .num_controls = ARRAY_SIZE(wm9713_snd_ac97_controls),
1248 .num_dapm_widgets = ARRAY_SIZE(wm9713_dapm_widgets), 1248 .dapm_widgets = wm9713_dapm_widgets,
1249 .dapm_routes = wm9713_audio_map, 1249 .num_dapm_widgets = ARRAY_SIZE(wm9713_dapm_widgets),
1250 .num_dapm_routes = ARRAY_SIZE(wm9713_audio_map), 1250 .dapm_routes = wm9713_audio_map,
1251 .num_dapm_routes = ARRAY_SIZE(wm9713_audio_map),
1252 },
1251}; 1253};
1252 1254
1253static int wm9713_probe(struct platform_device *pdev) 1255static int wm9713_probe(struct platform_device *pdev)
diff --git a/sound/soc/codecs/wm_adsp.c b/sound/soc/codecs/wm_adsp.c
index 21fbe7d07063..b943dde8dbe5 100644
--- a/sound/soc/codecs/wm_adsp.c
+++ b/sound/soc/codecs/wm_adsp.c
@@ -480,7 +480,7 @@ static ssize_t wm_adsp_debugfs_wmfw_read(struct file *file,
480 480
481 mutex_lock(&dsp->pwr_lock); 481 mutex_lock(&dsp->pwr_lock);
482 482
483 if (!dsp->wmfw_file_name || !dsp->running) 483 if (!dsp->wmfw_file_name || !dsp->booted)
484 ret = 0; 484 ret = 0;
485 else 485 else
486 ret = simple_read_from_buffer(user_buf, count, ppos, 486 ret = simple_read_from_buffer(user_buf, count, ppos,
@@ -500,7 +500,7 @@ static ssize_t wm_adsp_debugfs_bin_read(struct file *file,
500 500
501 mutex_lock(&dsp->pwr_lock); 501 mutex_lock(&dsp->pwr_lock);
502 502
503 if (!dsp->bin_file_name || !dsp->running) 503 if (!dsp->bin_file_name || !dsp->booted)
504 ret = 0; 504 ret = 0;
505 else 505 else
506 ret = simple_read_from_buffer(user_buf, count, ppos, 506 ret = simple_read_from_buffer(user_buf, count, ppos,
@@ -554,6 +554,9 @@ static void wm_adsp2_init_debugfs(struct wm_adsp *dsp,
554 if (!root) 554 if (!root)
555 goto err; 555 goto err;
556 556
557 if (!debugfs_create_bool("booted", S_IRUGO, root, &dsp->booted))
558 goto err;
559
557 if (!debugfs_create_bool("running", S_IRUGO, root, &dsp->running)) 560 if (!debugfs_create_bool("running", S_IRUGO, root, &dsp->running))
558 goto err; 561 goto err;
559 562
@@ -637,7 +640,7 @@ static int wm_adsp_fw_put(struct snd_kcontrol *kcontrol,
637 640
638 mutex_lock(&dsp[e->shift_l].pwr_lock); 641 mutex_lock(&dsp[e->shift_l].pwr_lock);
639 642
640 if (dsp[e->shift_l].running || dsp[e->shift_l].compr) 643 if (dsp[e->shift_l].booted || dsp[e->shift_l].compr)
641 ret = -EBUSY; 644 ret = -EBUSY;
642 else 645 else
643 dsp[e->shift_l].fw = ucontrol->value.enumerated.item[0]; 646 dsp[e->shift_l].fw = ucontrol->value.enumerated.item[0];
@@ -789,7 +792,7 @@ static int wm_coeff_put(struct snd_kcontrol *kctl,
789 memcpy(ctl->cache, p, ctl->len); 792 memcpy(ctl->cache, p, ctl->len);
790 793
791 ctl->set = 1; 794 ctl->set = 1;
792 if (ctl->enabled) 795 if (ctl->enabled && ctl->dsp->running)
793 ret = wm_coeff_write_control(ctl, p, ctl->len); 796 ret = wm_coeff_write_control(ctl, p, ctl->len);
794 797
795 mutex_unlock(&ctl->dsp->pwr_lock); 798 mutex_unlock(&ctl->dsp->pwr_lock);
@@ -811,7 +814,7 @@ static int wm_coeff_tlv_put(struct snd_kcontrol *kctl,
811 ret = -EFAULT; 814 ret = -EFAULT;
812 } else { 815 } else {
813 ctl->set = 1; 816 ctl->set = 1;
814 if (ctl->enabled) 817 if (ctl->enabled && ctl->dsp->running)
815 ret = wm_coeff_write_control(ctl, ctl->cache, size); 818 ret = wm_coeff_write_control(ctl, ctl->cache, size);
816 } 819 }
817 820
@@ -871,12 +874,12 @@ static int wm_coeff_get(struct snd_kcontrol *kctl,
871 mutex_lock(&ctl->dsp->pwr_lock); 874 mutex_lock(&ctl->dsp->pwr_lock);
872 875
873 if (ctl->flags & WMFW_CTL_FLAG_VOLATILE) { 876 if (ctl->flags & WMFW_CTL_FLAG_VOLATILE) {
874 if (ctl->enabled) 877 if (ctl->enabled && ctl->dsp->running)
875 ret = wm_coeff_read_control(ctl, p, ctl->len); 878 ret = wm_coeff_read_control(ctl, p, ctl->len);
876 else 879 else
877 ret = -EPERM; 880 ret = -EPERM;
878 } else { 881 } else {
879 if (!ctl->flags && ctl->enabled) 882 if (!ctl->flags && ctl->enabled && ctl->dsp->running)
880 ret = wm_coeff_read_control(ctl, ctl->cache, ctl->len); 883 ret = wm_coeff_read_control(ctl, ctl->cache, ctl->len);
881 884
882 memcpy(p, ctl->cache, ctl->len); 885 memcpy(p, ctl->cache, ctl->len);
@@ -898,12 +901,12 @@ static int wm_coeff_tlv_get(struct snd_kcontrol *kctl,
898 mutex_lock(&ctl->dsp->pwr_lock); 901 mutex_lock(&ctl->dsp->pwr_lock);
899 902
900 if (ctl->flags & WMFW_CTL_FLAG_VOLATILE) { 903 if (ctl->flags & WMFW_CTL_FLAG_VOLATILE) {
901 if (ctl->enabled) 904 if (ctl->enabled && ctl->dsp->running)
902 ret = wm_coeff_read_control(ctl, ctl->cache, size); 905 ret = wm_coeff_read_control(ctl, ctl->cache, size);
903 else 906 else
904 ret = -EPERM; 907 ret = -EPERM;
905 } else { 908 } else {
906 if (!ctl->flags && ctl->enabled) 909 if (!ctl->flags && ctl->enabled && ctl->dsp->running)
907 ret = wm_coeff_read_control(ctl, ctl->cache, size); 910 ret = wm_coeff_read_control(ctl, ctl->cache, size);
908 } 911 }
909 912
@@ -2166,13 +2169,20 @@ int wm_adsp1_event(struct snd_soc_dapm_widget *w,
2166 if (ret != 0) 2169 if (ret != 0)
2167 goto err_ena; 2170 goto err_ena;
2168 2171
2172 dsp->booted = true;
2173
2169 /* Start the core running */ 2174 /* Start the core running */
2170 regmap_update_bits(dsp->regmap, dsp->base + ADSP1_CONTROL_30, 2175 regmap_update_bits(dsp->regmap, dsp->base + ADSP1_CONTROL_30,
2171 ADSP1_CORE_ENA | ADSP1_START, 2176 ADSP1_CORE_ENA | ADSP1_START,
2172 ADSP1_CORE_ENA | ADSP1_START); 2177 ADSP1_CORE_ENA | ADSP1_START);
2178
2179 dsp->running = true;
2173 break; 2180 break;
2174 2181
2175 case SND_SOC_DAPM_PRE_PMD: 2182 case SND_SOC_DAPM_PRE_PMD:
2183 dsp->running = false;
2184 dsp->booted = false;
2185
2176 /* Halt the core */ 2186 /* Halt the core */
2177 regmap_update_bits(dsp->regmap, dsp->base + ADSP1_CONTROL_30, 2187 regmap_update_bits(dsp->regmap, dsp->base + ADSP1_CONTROL_30,
2178 ADSP1_CORE_ENA | ADSP1_START, 0); 2188 ADSP1_CORE_ENA | ADSP1_START, 0);
@@ -2227,7 +2237,7 @@ static int wm_adsp2_ena(struct wm_adsp *dsp)
2227 if (val & ADSP2_RAM_RDY) 2237 if (val & ADSP2_RAM_RDY)
2228 break; 2238 break;
2229 2239
2230 msleep(1); 2240 usleep_range(250, 500);
2231 } 2241 }
2232 2242
2233 if (!(val & ADSP2_RAM_RDY)) { 2243 if (!(val & ADSP2_RAM_RDY)) {
@@ -2249,6 +2259,11 @@ static void wm_adsp2_boot_work(struct work_struct *work)
2249 2259
2250 mutex_lock(&dsp->pwr_lock); 2260 mutex_lock(&dsp->pwr_lock);
2251 2261
2262 ret = regmap_update_bits(dsp->regmap, dsp->base + ADSP2_CONTROL,
2263 ADSP2_MEM_ENA, ADSP2_MEM_ENA);
2264 if (ret != 0)
2265 goto err_mutex;
2266
2252 ret = wm_adsp2_ena(dsp); 2267 ret = wm_adsp2_ena(dsp);
2253 if (ret != 0) 2268 if (ret != 0)
2254 goto err_mutex; 2269 goto err_mutex;
@@ -2270,13 +2285,14 @@ static void wm_adsp2_boot_work(struct work_struct *work)
2270 if (ret != 0) 2285 if (ret != 0)
2271 goto err_ena; 2286 goto err_ena;
2272 2287
2273 /* Sync set controls */ 2288 dsp->booted = true;
2274 ret = wm_coeff_sync_controls(dsp); 2289
2290 /* Turn DSP back off until we are ready to run */
2291 ret = regmap_update_bits(dsp->regmap, dsp->base + ADSP2_CONTROL,
2292 ADSP2_SYS_ENA, 0);
2275 if (ret != 0) 2293 if (ret != 0)
2276 goto err_ena; 2294 goto err_ena;
2277 2295
2278 dsp->running = true;
2279
2280 mutex_unlock(&dsp->pwr_lock); 2296 mutex_unlock(&dsp->pwr_lock);
2281 2297
2282 return; 2298 return;
@@ -2307,6 +2323,7 @@ int wm_adsp2_early_event(struct snd_soc_dapm_widget *w,
2307 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); 2323 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
2308 struct wm_adsp *dsps = snd_soc_codec_get_drvdata(codec); 2324 struct wm_adsp *dsps = snd_soc_codec_get_drvdata(codec);
2309 struct wm_adsp *dsp = &dsps[w->shift]; 2325 struct wm_adsp *dsp = &dsps[w->shift];
2326 struct wm_coeff_ctl *ctl;
2310 2327
2311 dsp->card = codec->component.card; 2328 dsp->card = codec->component.card;
2312 2329
@@ -2315,6 +2332,24 @@ int wm_adsp2_early_event(struct snd_soc_dapm_widget *w,
2315 wm_adsp2_set_dspclk(dsp, freq); 2332 wm_adsp2_set_dspclk(dsp, freq);
2316 queue_work(system_unbound_wq, &dsp->boot_work); 2333 queue_work(system_unbound_wq, &dsp->boot_work);
2317 break; 2334 break;
2335 case SND_SOC_DAPM_PRE_PMD:
2336 wm_adsp_debugfs_clear(dsp);
2337
2338 dsp->fw_id = 0;
2339 dsp->fw_id_version = 0;
2340
2341 dsp->booted = false;
2342
2343 regmap_update_bits(dsp->regmap, dsp->base + ADSP2_CONTROL,
2344 ADSP2_MEM_ENA, 0);
2345
2346 list_for_each_entry(ctl, &dsp->ctl_list, list)
2347 ctl->enabled = 0;
2348
2349 wm_adsp_free_alg_regions(dsp);
2350
2351 adsp_dbg(dsp, "Shutdown complete\n");
2352 break;
2318 default: 2353 default:
2319 break; 2354 break;
2320 } 2355 }
@@ -2329,16 +2364,24 @@ int wm_adsp2_event(struct snd_soc_dapm_widget *w,
2329 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); 2364 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
2330 struct wm_adsp *dsps = snd_soc_codec_get_drvdata(codec); 2365 struct wm_adsp *dsps = snd_soc_codec_get_drvdata(codec);
2331 struct wm_adsp *dsp = &dsps[w->shift]; 2366 struct wm_adsp *dsp = &dsps[w->shift];
2332 struct wm_coeff_ctl *ctl;
2333 int ret; 2367 int ret;
2334 2368
2335 switch (event) { 2369 switch (event) {
2336 case SND_SOC_DAPM_POST_PMU: 2370 case SND_SOC_DAPM_POST_PMU:
2337 flush_work(&dsp->boot_work); 2371 flush_work(&dsp->boot_work);
2338 2372
2339 if (!dsp->running) 2373 if (!dsp->booted)
2340 return -EIO; 2374 return -EIO;
2341 2375
2376 ret = wm_adsp2_ena(dsp);
2377 if (ret != 0)
2378 goto err;
2379
2380 /* Sync set controls */
2381 ret = wm_coeff_sync_controls(dsp);
2382 if (ret != 0)
2383 goto err;
2384
2342 ret = regmap_update_bits(dsp->regmap, 2385 ret = regmap_update_bits(dsp->regmap,
2343 dsp->base + ADSP2_CONTROL, 2386 dsp->base + ADSP2_CONTROL,
2344 ADSP2_CORE_ENA | ADSP2_START, 2387 ADSP2_CORE_ENA | ADSP2_START,
@@ -2346,6 +2389,8 @@ int wm_adsp2_event(struct snd_soc_dapm_widget *w,
2346 if (ret != 0) 2389 if (ret != 0)
2347 goto err; 2390 goto err;
2348 2391
2392 dsp->running = true;
2393
2349 mutex_lock(&dsp->pwr_lock); 2394 mutex_lock(&dsp->pwr_lock);
2350 2395
2351 if (wm_adsp_fw[dsp->fw].num_caps != 0) 2396 if (wm_adsp_fw[dsp->fw].num_caps != 0)
@@ -2361,10 +2406,6 @@ int wm_adsp2_event(struct snd_soc_dapm_widget *w,
2361 2406
2362 mutex_lock(&dsp->pwr_lock); 2407 mutex_lock(&dsp->pwr_lock);
2363 2408
2364 wm_adsp_debugfs_clear(dsp);
2365
2366 dsp->fw_id = 0;
2367 dsp->fw_id_version = 0;
2368 dsp->running = false; 2409 dsp->running = false;
2369 2410
2370 regmap_update_bits(dsp->regmap, dsp->base + ADSP2_CONTROL, 2411 regmap_update_bits(dsp->regmap, dsp->base + ADSP2_CONTROL,
@@ -2378,17 +2419,12 @@ int wm_adsp2_event(struct snd_soc_dapm_widget *w,
2378 regmap_update_bits(dsp->regmap, dsp->base + ADSP2_CONTROL, 2419 regmap_update_bits(dsp->regmap, dsp->base + ADSP2_CONTROL,
2379 ADSP2_SYS_ENA, 0); 2420 ADSP2_SYS_ENA, 0);
2380 2421
2381 list_for_each_entry(ctl, &dsp->ctl_list, list)
2382 ctl->enabled = 0;
2383
2384 wm_adsp_free_alg_regions(dsp);
2385
2386 if (wm_adsp_fw[dsp->fw].num_caps != 0) 2422 if (wm_adsp_fw[dsp->fw].num_caps != 0)
2387 wm_adsp_buffer_free(dsp); 2423 wm_adsp_buffer_free(dsp);
2388 2424
2389 mutex_unlock(&dsp->pwr_lock); 2425 mutex_unlock(&dsp->pwr_lock);
2390 2426
2391 adsp_dbg(dsp, "Shutdown complete\n"); 2427 adsp_dbg(dsp, "Execution stopped\n");
2392 break; 2428 break;
2393 2429
2394 default: 2430 default:
diff --git a/sound/soc/codecs/wm_adsp.h b/sound/soc/codecs/wm_adsp.h
index be3b5bcb7f17..362dd7ce60d8 100644
--- a/sound/soc/codecs/wm_adsp.h
+++ b/sound/soc/codecs/wm_adsp.h
@@ -61,6 +61,8 @@ struct wm_adsp {
61 61
62 int fw; 62 int fw;
63 int fw_ver; 63 int fw_ver;
64
65 bool booted;
64 bool running; 66 bool running;
65 67
66 struct list_head ctl_list; 68 struct list_head ctl_list;
@@ -85,9 +87,10 @@ struct wm_adsp {
85 wm_adsp1_event, SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD) 87 wm_adsp1_event, SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD)
86 88
87#define WM_ADSP2(wname, num, event_fn) \ 89#define WM_ADSP2(wname, num, event_fn) \
88{ .id = snd_soc_dapm_dai_link, .name = wname " Preloader", \ 90{ .id = snd_soc_dapm_supply, .name = wname " Preloader", \
89 .reg = SND_SOC_NOPM, .shift = num, .event = event_fn, \ 91 .reg = SND_SOC_NOPM, .shift = num, .event = event_fn, \
90 .event_flags = SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD }, \ 92 .event_flags = SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD, \
93 .subseq = 100, /* Ensure we run after SYSCLK supply widget */ }, \
91{ .id = snd_soc_dapm_out_drv, .name = wname, \ 94{ .id = snd_soc_dapm_out_drv, .name = wname, \
92 .reg = SND_SOC_NOPM, .shift = num, .event = wm_adsp2_event, \ 95 .reg = SND_SOC_NOPM, .shift = num, .event = wm_adsp2_event, \
93 .event_flags = SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD } 96 .event_flags = SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD }
diff --git a/sound/soc/davinci/davinci-mcasp.c b/sound/soc/davinci/davinci-mcasp.c
index 05c2d33aa74d..3c5a9804d3f5 100644
--- a/sound/soc/davinci/davinci-mcasp.c
+++ b/sound/soc/davinci/davinci-mcasp.c
@@ -1218,7 +1218,7 @@ static int davinci_mcasp_hw_rule_format(struct snd_pcm_hw_params *params,
1218 1218
1219 snd_mask_none(&nfmt); 1219 snd_mask_none(&nfmt);
1220 1220
1221 for (i = 0; i < SNDRV_PCM_FORMAT_LAST; i++) { 1221 for (i = 0; i <= SNDRV_PCM_FORMAT_LAST; i++) {
1222 if (snd_mask_test(fmt, i)) { 1222 if (snd_mask_test(fmt, i)) {
1223 uint sbits = snd_pcm_format_width(i); 1223 uint sbits = snd_pcm_format_width(i);
1224 int ppm; 1224 int ppm;
diff --git a/sound/soc/dwc/designware_i2s.c b/sound/soc/dwc/designware_i2s.c
index dc97f4349e66..2998954a1c74 100644
--- a/sound/soc/dwc/designware_i2s.c
+++ b/sound/soc/dwc/designware_i2s.c
@@ -577,7 +577,6 @@ static int dw_configure_dai_by_dt(struct dw_i2s_dev *dev,
577 dev->capability |= DWC_I2S_PLAY; 577 dev->capability |= DWC_I2S_PLAY;
578 dev->play_dma_data.dt.addr = res->start + I2S_TXDMA; 578 dev->play_dma_data.dt.addr = res->start + I2S_TXDMA;
579 dev->play_dma_data.dt.addr_width = bus_widths[idx]; 579 dev->play_dma_data.dt.addr_width = bus_widths[idx];
580 dev->play_dma_data.dt.chan_name = "TX";
581 dev->play_dma_data.dt.fifo_size = fifo_depth * 580 dev->play_dma_data.dt.fifo_size = fifo_depth *
582 (fifo_width[idx2]) >> 8; 581 (fifo_width[idx2]) >> 8;
583 dev->play_dma_data.dt.maxburst = 16; 582 dev->play_dma_data.dt.maxburst = 16;
@@ -588,7 +587,6 @@ static int dw_configure_dai_by_dt(struct dw_i2s_dev *dev,
588 dev->capability |= DWC_I2S_RECORD; 587 dev->capability |= DWC_I2S_RECORD;
589 dev->capture_dma_data.dt.addr = res->start + I2S_RXDMA; 588 dev->capture_dma_data.dt.addr = res->start + I2S_RXDMA;
590 dev->capture_dma_data.dt.addr_width = bus_widths[idx]; 589 dev->capture_dma_data.dt.addr_width = bus_widths[idx];
591 dev->capture_dma_data.dt.chan_name = "RX";
592 dev->capture_dma_data.dt.fifo_size = fifo_depth * 590 dev->capture_dma_data.dt.fifo_size = fifo_depth *
593 (fifo_width[idx2] >> 8); 591 (fifo_width[idx2] >> 8);
594 dev->capture_dma_data.dt.maxburst = 16; 592 dev->capture_dma_data.dt.maxburst = 16;
diff --git a/sound/soc/fsl/fsl_asrc.c b/sound/soc/fsl/fsl_asrc.c
index c1a0e01cb8e7..1d82f68305c3 100644
--- a/sound/soc/fsl/fsl_asrc.c
+++ b/sound/soc/fsl/fsl_asrc.c
@@ -726,7 +726,7 @@ static const struct regmap_config fsl_asrc_regmap_config = {
726 .readable_reg = fsl_asrc_readable_reg, 726 .readable_reg = fsl_asrc_readable_reg,
727 .volatile_reg = fsl_asrc_volatile_reg, 727 .volatile_reg = fsl_asrc_volatile_reg,
728 .writeable_reg = fsl_asrc_writeable_reg, 728 .writeable_reg = fsl_asrc_writeable_reg,
729 .cache_type = REGCACHE_RBTREE, 729 .cache_type = REGCACHE_FLAT,
730}; 730};
731 731
732/** 732/**
@@ -879,7 +879,7 @@ static int fsl_asrc_probe(struct platform_device *pdev)
879 } 879 }
880 } 880 }
881 881
882 if (of_device_is_compatible(pdev->dev.of_node, "fsl,imx35-asrc")) { 882 if (of_device_is_compatible(np, "fsl,imx35-asrc")) {
883 asrc_priv->channel_bits = 3; 883 asrc_priv->channel_bits = 3;
884 clk_map[IN] = input_clk_map_imx35; 884 clk_map[IN] = input_clk_map_imx35;
885 clk_map[OUT] = output_clk_map_imx35; 885 clk_map[OUT] = output_clk_map_imx35;
@@ -892,7 +892,7 @@ static int fsl_asrc_probe(struct platform_device *pdev)
892 ret = fsl_asrc_init(asrc_priv); 892 ret = fsl_asrc_init(asrc_priv);
893 if (ret) { 893 if (ret) {
894 dev_err(&pdev->dev, "failed to init asrc %d\n", ret); 894 dev_err(&pdev->dev, "failed to init asrc %d\n", ret);
895 return -EINVAL; 895 return ret;
896 } 896 }
897 897
898 asrc_priv->channel_avail = 10; 898 asrc_priv->channel_avail = 10;
@@ -901,14 +901,14 @@ static int fsl_asrc_probe(struct platform_device *pdev)
901 &asrc_priv->asrc_rate); 901 &asrc_priv->asrc_rate);
902 if (ret) { 902 if (ret) {
903 dev_err(&pdev->dev, "failed to get output rate\n"); 903 dev_err(&pdev->dev, "failed to get output rate\n");
904 return -EINVAL; 904 return ret;
905 } 905 }
906 906
907 ret = of_property_read_u32(np, "fsl,asrc-width", 907 ret = of_property_read_u32(np, "fsl,asrc-width",
908 &asrc_priv->asrc_width); 908 &asrc_priv->asrc_width);
909 if (ret) { 909 if (ret) {
910 dev_err(&pdev->dev, "failed to get output width\n"); 910 dev_err(&pdev->dev, "failed to get output width\n");
911 return -EINVAL; 911 return ret;
912 } 912 }
913 913
914 if (asrc_priv->asrc_width != 16 && asrc_priv->asrc_width != 24) { 914 if (asrc_priv->asrc_width != 16 && asrc_priv->asrc_width != 24) {
@@ -933,8 +933,6 @@ static int fsl_asrc_probe(struct platform_device *pdev)
933 return ret; 933 return ret;
934 } 934 }
935 935
936 dev_info(&pdev->dev, "driver registered\n");
937
938 return 0; 936 return 0;
939} 937}
940 938
diff --git a/sound/soc/fsl/fsl_asrc_dma.c b/sound/soc/fsl/fsl_asrc_dma.c
index ffc000bc1f15..dc30d780f874 100644
--- a/sound/soc/fsl/fsl_asrc_dma.c
+++ b/sound/soc/fsl/fsl_asrc_dma.c
@@ -322,7 +322,7 @@ static snd_pcm_uframes_t fsl_asrc_dma_pcm_pointer(struct snd_pcm_substream *subs
322 return bytes_to_frames(substream->runtime, pair->pos); 322 return bytes_to_frames(substream->runtime, pair->pos);
323} 323}
324 324
325static struct snd_pcm_ops fsl_asrc_dma_pcm_ops = { 325static const struct snd_pcm_ops fsl_asrc_dma_pcm_ops = {
326 .ioctl = snd_pcm_lib_ioctl, 326 .ioctl = snd_pcm_lib_ioctl,
327 .hw_params = fsl_asrc_dma_hw_params, 327 .hw_params = fsl_asrc_dma_hw_params,
328 .hw_free = fsl_asrc_dma_hw_free, 328 .hw_free = fsl_asrc_dma_hw_free,
diff --git a/sound/soc/fsl/fsl_esai.c b/sound/soc/fsl/fsl_esai.c
index 26a90e12ede4..38bfd46f4ad8 100644
--- a/sound/soc/fsl/fsl_esai.c
+++ b/sound/soc/fsl/fsl_esai.c
@@ -77,19 +77,19 @@ static irqreturn_t esai_isr(int irq, void *devid)
77 regmap_read(esai_priv->regmap, REG_ESAI_ESR, &esr); 77 regmap_read(esai_priv->regmap, REG_ESAI_ESR, &esr);
78 78
79 if (esr & ESAI_ESR_TINIT_MASK) 79 if (esr & ESAI_ESR_TINIT_MASK)
80 dev_dbg(&pdev->dev, "isr: Transmition Initialized\n"); 80 dev_dbg(&pdev->dev, "isr: Transmission Initialized\n");
81 81
82 if (esr & ESAI_ESR_RFF_MASK) 82 if (esr & ESAI_ESR_RFF_MASK)
83 dev_warn(&pdev->dev, "isr: Receiving overrun\n"); 83 dev_warn(&pdev->dev, "isr: Receiving overrun\n");
84 84
85 if (esr & ESAI_ESR_TFE_MASK) 85 if (esr & ESAI_ESR_TFE_MASK)
86 dev_warn(&pdev->dev, "isr: Transmition underrun\n"); 86 dev_warn(&pdev->dev, "isr: Transmission underrun\n");
87 87
88 if (esr & ESAI_ESR_TLS_MASK) 88 if (esr & ESAI_ESR_TLS_MASK)
89 dev_dbg(&pdev->dev, "isr: Just transmitted the last slot\n"); 89 dev_dbg(&pdev->dev, "isr: Just transmitted the last slot\n");
90 90
91 if (esr & ESAI_ESR_TDE_MASK) 91 if (esr & ESAI_ESR_TDE_MASK)
92 dev_dbg(&pdev->dev, "isr: Transmition data exception\n"); 92 dev_dbg(&pdev->dev, "isr: Transmission data exception\n");
93 93
94 if (esr & ESAI_ESR_TED_MASK) 94 if (esr & ESAI_ESR_TED_MASK)
95 dev_dbg(&pdev->dev, "isr: Transmitting even slots\n"); 95 dev_dbg(&pdev->dev, "isr: Transmitting even slots\n");
@@ -781,7 +781,7 @@ static const struct regmap_config fsl_esai_regmap_config = {
781 .readable_reg = fsl_esai_readable_reg, 781 .readable_reg = fsl_esai_readable_reg,
782 .volatile_reg = fsl_esai_volatile_reg, 782 .volatile_reg = fsl_esai_volatile_reg,
783 .writeable_reg = fsl_esai_writeable_reg, 783 .writeable_reg = fsl_esai_writeable_reg,
784 .cache_type = REGCACHE_RBTREE, 784 .cache_type = REGCACHE_FLAT,
785}; 785};
786 786
787static int fsl_esai_probe(struct platform_device *pdev) 787static int fsl_esai_probe(struct platform_device *pdev)
diff --git a/sound/soc/fsl/fsl_sai.c b/sound/soc/fsl/fsl_sai.c
index 2147994ab46f..9fadf7e31c5f 100644
--- a/sound/soc/fsl/fsl_sai.c
+++ b/sound/soc/fsl/fsl_sai.c
@@ -801,8 +801,8 @@ static int fsl_sai_probe(struct platform_device *pdev)
801 801
802 sai->pdev = pdev; 802 sai->pdev = pdev;
803 803
804 if (of_device_is_compatible(pdev->dev.of_node, "fsl,imx6sx-sai") || 804 if (of_device_is_compatible(np, "fsl,imx6sx-sai") ||
805 of_device_is_compatible(pdev->dev.of_node, "fsl,imx6ul-sai")) 805 of_device_is_compatible(np, "fsl,imx6ul-sai"))
806 sai->sai_on_imx = true; 806 sai->sai_on_imx = true;
807 807
808 sai->is_lsb_first = of_property_read_bool(np, "lsb-first"); 808 sai->is_lsb_first = of_property_read_bool(np, "lsb-first");
@@ -883,7 +883,7 @@ static int fsl_sai_probe(struct platform_device *pdev)
883 } 883 }
884 884
885 if (of_find_property(np, "fsl,sai-mclk-direction-output", NULL) && 885 if (of_find_property(np, "fsl,sai-mclk-direction-output", NULL) &&
886 of_device_is_compatible(pdev->dev.of_node, "fsl,imx6ul-sai")) { 886 of_device_is_compatible(np, "fsl,imx6ul-sai")) {
887 gpr = syscon_regmap_lookup_by_compatible("fsl,imx6ul-iomuxc-gpr"); 887 gpr = syscon_regmap_lookup_by_compatible("fsl,imx6ul-iomuxc-gpr");
888 if (IS_ERR(gpr)) { 888 if (IS_ERR(gpr)) {
889 dev_err(&pdev->dev, "cannot find iomuxc registers\n"); 889 dev_err(&pdev->dev, "cannot find iomuxc registers\n");
diff --git a/sound/soc/fsl/fsl_spdif.c b/sound/soc/fsl/fsl_spdif.c
index beec7934a265..1ff467c9598a 100644
--- a/sound/soc/fsl/fsl_spdif.c
+++ b/sound/soc/fsl/fsl_spdif.c
@@ -1103,7 +1103,7 @@ static const struct regmap_config fsl_spdif_regmap_config = {
1103 .readable_reg = fsl_spdif_readable_reg, 1103 .readable_reg = fsl_spdif_readable_reg,
1104 .volatile_reg = fsl_spdif_volatile_reg, 1104 .volatile_reg = fsl_spdif_volatile_reg,
1105 .writeable_reg = fsl_spdif_writeable_reg, 1105 .writeable_reg = fsl_spdif_writeable_reg,
1106 .cache_type = REGCACHE_RBTREE, 1106 .cache_type = REGCACHE_FLAT,
1107}; 1107};
1108 1108
1109static u32 fsl_spdif_txclk_caldiv(struct fsl_spdif_priv *spdif_priv, 1109static u32 fsl_spdif_txclk_caldiv(struct fsl_spdif_priv *spdif_priv,
diff --git a/sound/soc/fsl/fsl_ssi.c b/sound/soc/fsl/fsl_ssi.c
index bedec4a32581..50349437d961 100644
--- a/sound/soc/fsl/fsl_ssi.c
+++ b/sound/soc/fsl/fsl_ssi.c
@@ -182,7 +182,7 @@ static const struct regmap_config fsl_ssi_regconfig = {
182 .volatile_reg = fsl_ssi_volatile_reg, 182 .volatile_reg = fsl_ssi_volatile_reg,
183 .precious_reg = fsl_ssi_precious_reg, 183 .precious_reg = fsl_ssi_precious_reg,
184 .writeable_reg = fsl_ssi_writeable_reg, 184 .writeable_reg = fsl_ssi_writeable_reg,
185 .cache_type = REGCACHE_RBTREE, 185 .cache_type = REGCACHE_FLAT,
186}; 186};
187 187
188struct fsl_ssi_soc_data { 188struct fsl_ssi_soc_data {
diff --git a/sound/soc/generic/Kconfig b/sound/soc/generic/Kconfig
index c01c5dd68601..d023959b8cd6 100644
--- a/sound/soc/generic/Kconfig
+++ b/sound/soc/generic/Kconfig
@@ -6,3 +6,11 @@ config SND_SIMPLE_CARD
6 select SND_SIMPLE_CARD_UTILS 6 select SND_SIMPLE_CARD_UTILS
7 help 7 help
8 This option enables generic simple sound card support 8 This option enables generic simple sound card support
9
10config SND_SIMPLE_SCU_CARD
11 tristate "ASoC Simple SCU sound card support"
12 depends on OF
13 select SND_SIMPLE_CARD_UTILS
14 help
15 This option enables generic simple SCU sound card support.
16 It supports DPCM of multi CPU single Codec system.
diff --git a/sound/soc/generic/Makefile b/sound/soc/generic/Makefile
index 2d53c8d70705..ee750f3023ba 100644
--- a/sound/soc/generic/Makefile
+++ b/sound/soc/generic/Makefile
@@ -1,5 +1,7 @@
1snd-soc-simple-card-utils-objs := simple-card-utils.o 1snd-soc-simple-card-utils-objs := simple-card-utils.o
2snd-soc-simple-card-objs := simple-card.o 2snd-soc-simple-card-objs := simple-card.o
3snd-soc-simple-scu-card-objs := simple-scu-card.o
3 4
4obj-$(CONFIG_SND_SIMPLE_CARD_UTILS) += snd-soc-simple-card-utils.o 5obj-$(CONFIG_SND_SIMPLE_CARD_UTILS) += snd-soc-simple-card-utils.o
5obj-$(CONFIG_SND_SIMPLE_CARD) += snd-soc-simple-card.o 6obj-$(CONFIG_SND_SIMPLE_CARD) += snd-soc-simple-card.o
7obj-$(CONFIG_SND_SIMPLE_SCU_CARD) += snd-soc-simple-scu-card.o
diff --git a/sound/soc/generic/simple-card-utils.c b/sound/soc/generic/simple-card-utils.c
index 9599de69a880..1cb39309f5d5 100644
--- a/sound/soc/generic/simple-card-utils.c
+++ b/sound/soc/generic/simple-card-utils.c
@@ -7,6 +7,7 @@
7 * it under the terms of the GNU General Public License version 2 as 7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation. 8 * published by the Free Software Foundation.
9 */ 9 */
10#include <linux/clk.h>
10#include <linux/module.h> 11#include <linux/module.h>
11#include <linux/of.h> 12#include <linux/of.h>
12#include <sound/simple_card_utils.h> 13#include <sound/simple_card_utils.h>
@@ -97,6 +98,146 @@ int asoc_simple_card_parse_card_name(struct snd_soc_card *card,
97} 98}
98EXPORT_SYMBOL_GPL(asoc_simple_card_parse_card_name); 99EXPORT_SYMBOL_GPL(asoc_simple_card_parse_card_name);
99 100
101int asoc_simple_card_parse_clk(struct device_node *node,
102 struct device_node *dai_of_node,
103 struct asoc_simple_dai *simple_dai)
104{
105 struct clk *clk;
106 u32 val;
107
108 /*
109 * Parse dai->sysclk come from "clocks = <&xxx>"
110 * (if system has common clock)
111 * or "system-clock-frequency = <xxx>"
112 * or device's module clock.
113 */
114 clk = of_clk_get(node, 0);
115 if (!IS_ERR(clk)) {
116 simple_dai->sysclk = clk_get_rate(clk);
117 simple_dai->clk = clk;
118 } else if (!of_property_read_u32(node, "system-clock-frequency", &val)) {
119 simple_dai->sysclk = val;
120 } else {
121 clk = of_clk_get(dai_of_node, 0);
122 if (!IS_ERR(clk))
123 simple_dai->sysclk = clk_get_rate(clk);
124 }
125
126 return 0;
127}
128EXPORT_SYMBOL_GPL(asoc_simple_card_parse_clk);
129
130int asoc_simple_card_parse_dai(struct device_node *node,
131 struct device_node **dai_of_node,
132 const char **dai_name,
133 const char *list_name,
134 const char *cells_name,
135 int *is_single_link)
136{
137 struct of_phandle_args args;
138 int ret;
139
140 if (!node)
141 return 0;
142
143 /*
144 * Get node via "sound-dai = <&phandle port>"
145 * it will be used as xxx_of_node on soc_bind_dai_link()
146 */
147 ret = of_parse_phandle_with_args(node, list_name, cells_name, 0, &args);
148 if (ret)
149 return ret;
150
151 /* Get dai->name */
152 if (dai_name) {
153 ret = snd_soc_of_get_dai_name(node, dai_name);
154 if (ret < 0)
155 return ret;
156 }
157
158 *dai_of_node = args.np;
159
160 if (is_single_link)
161 *is_single_link = !args.args_count;
162
163 return 0;
164}
165EXPORT_SYMBOL_GPL(asoc_simple_card_parse_dai);
166
167int asoc_simple_card_init_dai(struct snd_soc_dai *dai,
168 struct asoc_simple_dai *simple_dai)
169{
170 int ret;
171
172 if (simple_dai->sysclk) {
173 ret = snd_soc_dai_set_sysclk(dai, 0, simple_dai->sysclk, 0);
174 if (ret && ret != -ENOTSUPP) {
175 dev_err(dai->dev, "simple-card: set_sysclk error\n");
176 return ret;
177 }
178 }
179
180 if (simple_dai->slots) {
181 ret = snd_soc_dai_set_tdm_slot(dai,
182 simple_dai->tx_slot_mask,
183 simple_dai->rx_slot_mask,
184 simple_dai->slots,
185 simple_dai->slot_width);
186 if (ret && ret != -ENOTSUPP) {
187 dev_err(dai->dev, "simple-card: set_tdm_slot error\n");
188 return ret;
189 }
190 }
191
192 return 0;
193}
194EXPORT_SYMBOL_GPL(asoc_simple_card_init_dai);
195
196int asoc_simple_card_canonicalize_dailink(struct snd_soc_dai_link *dai_link)
197{
198 if (!dai_link->cpu_dai_name || !dai_link->codec_dai_name)
199 return -EINVAL;
200
201 /* Assumes platform == cpu */
202 if (!dai_link->platform_of_node)
203 dai_link->platform_of_node = dai_link->cpu_of_node;
204
205 return 0;
206}
207EXPORT_SYMBOL_GPL(asoc_simple_card_canonicalize_dailink);
208
209void asoc_simple_card_canonicalize_cpu(struct snd_soc_dai_link *dai_link,
210 int is_single_links)
211{
212 /*
213 * In soc_bind_dai_link() will check cpu name after
214 * of_node matching if dai_link has cpu_dai_name.
215 * but, it will never match if name was created by
216 * fmt_single_name() remove cpu_dai_name if cpu_args
217 * was 0. See:
218 * fmt_single_name()
219 * fmt_multiple_name()
220 */
221 if (is_single_links)
222 dai_link->cpu_dai_name = NULL;
223}
224EXPORT_SYMBOL_GPL(asoc_simple_card_canonicalize_cpu);
225
226int asoc_simple_card_clean_reference(struct snd_soc_card *card)
227{
228 struct snd_soc_dai_link *dai_link;
229 int num_links;
230
231 for (num_links = 0, dai_link = card->dai_link;
232 num_links < card->num_links;
233 num_links++, dai_link++) {
234 of_node_put(dai_link->cpu_of_node);
235 of_node_put(dai_link->codec_of_node);
236 }
237 return 0;
238}
239EXPORT_SYMBOL_GPL(asoc_simple_card_clean_reference);
240
100/* Module information */ 241/* Module information */
101MODULE_AUTHOR("Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>"); 242MODULE_AUTHOR("Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>");
102MODULE_DESCRIPTION("ALSA SoC Simple Card Utils"); 243MODULE_DESCRIPTION("ALSA SoC Simple Card Utils");
diff --git a/sound/soc/generic/simple-card.c b/sound/soc/generic/simple-card.c
index 43295f024982..f608f8d23f3d 100644
--- a/sound/soc/generic/simple-card.c
+++ b/sound/soc/generic/simple-card.c
@@ -37,13 +37,15 @@ struct simple_card_data {
37 unsigned int mclk_fs; 37 unsigned int mclk_fs;
38 struct asoc_simple_jack hp_jack; 38 struct asoc_simple_jack hp_jack;
39 struct asoc_simple_jack mic_jack; 39 struct asoc_simple_jack mic_jack;
40 struct snd_soc_dai_link dai_link[]; /* dynamically allocated */ 40 struct snd_soc_dai_link *dai_link;
41}; 41};
42 42
43#define simple_priv_to_dev(priv) ((priv)->snd_card.dev) 43#define simple_priv_to_dev(priv) ((priv)->snd_card.dev)
44#define simple_priv_to_link(priv, i) ((priv)->snd_card.dai_link + i) 44#define simple_priv_to_link(priv, i) ((priv)->snd_card.dai_link + (i))
45#define simple_priv_to_props(priv, i) ((priv)->dai_props + i) 45#define simple_priv_to_props(priv, i) ((priv)->dai_props + (i))
46 46
47#define DAI "sound-dai"
48#define CELL "#sound-dai-cells"
47#define PREFIX "simple-audio-card," 49#define PREFIX "simple-audio-card,"
48 50
49#define asoc_simple_card_init_hp(card, sjack, prefix)\ 51#define asoc_simple_card_init_hp(card, sjack, prefix)\
@@ -112,13 +114,13 @@ static int asoc_simple_card_startup(struct snd_pcm_substream *substream)
112 struct snd_soc_pcm_runtime *rtd = substream->private_data; 114 struct snd_soc_pcm_runtime *rtd = substream->private_data;
113 struct simple_card_data *priv = snd_soc_card_get_drvdata(rtd->card); 115 struct simple_card_data *priv = snd_soc_card_get_drvdata(rtd->card);
114 struct simple_dai_props *dai_props = 116 struct simple_dai_props *dai_props =
115 &priv->dai_props[rtd->num]; 117 simple_priv_to_props(priv, rtd->num);
116 int ret; 118 int ret;
117 119
118 ret = clk_prepare_enable(dai_props->cpu_dai.clk); 120 ret = clk_prepare_enable(dai_props->cpu_dai.clk);
119 if (ret) 121 if (ret)
120 return ret; 122 return ret;
121 123
122 ret = clk_prepare_enable(dai_props->codec_dai.clk); 124 ret = clk_prepare_enable(dai_props->codec_dai.clk);
123 if (ret) 125 if (ret)
124 clk_disable_unprepare(dai_props->cpu_dai.clk); 126 clk_disable_unprepare(dai_props->cpu_dai.clk);
@@ -131,7 +133,7 @@ static void asoc_simple_card_shutdown(struct snd_pcm_substream *substream)
131 struct snd_soc_pcm_runtime *rtd = substream->private_data; 133 struct snd_soc_pcm_runtime *rtd = substream->private_data;
132 struct simple_card_data *priv = snd_soc_card_get_drvdata(rtd->card); 134 struct simple_card_data *priv = snd_soc_card_get_drvdata(rtd->card);
133 struct simple_dai_props *dai_props = 135 struct simple_dai_props *dai_props =
134 &priv->dai_props[rtd->num]; 136 simple_priv_to_props(priv, rtd->num);
135 137
136 clk_disable_unprepare(dai_props->cpu_dai.clk); 138 clk_disable_unprepare(dai_props->cpu_dai.clk);
137 139
@@ -145,7 +147,8 @@ static int asoc_simple_card_hw_params(struct snd_pcm_substream *substream,
145 struct snd_soc_dai *codec_dai = rtd->codec_dai; 147 struct snd_soc_dai *codec_dai = rtd->codec_dai;
146 struct snd_soc_dai *cpu_dai = rtd->cpu_dai; 148 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
147 struct simple_card_data *priv = snd_soc_card_get_drvdata(rtd->card); 149 struct simple_card_data *priv = snd_soc_card_get_drvdata(rtd->card);
148 struct simple_dai_props *dai_props = &priv->dai_props[rtd->num]; 150 struct simple_dai_props *dai_props =
151 simple_priv_to_props(priv, rtd->num);
149 unsigned int mclk, mclk_fs = 0; 152 unsigned int mclk, mclk_fs = 0;
150 int ret = 0; 153 int ret = 0;
151 154
@@ -177,51 +180,20 @@ static struct snd_soc_ops asoc_simple_card_ops = {
177 .hw_params = asoc_simple_card_hw_params, 180 .hw_params = asoc_simple_card_hw_params,
178}; 181};
179 182
180static int __asoc_simple_card_dai_init(struct snd_soc_dai *dai,
181 struct asoc_simple_dai *set)
182{
183 int ret;
184
185 if (set->sysclk) {
186 ret = snd_soc_dai_set_sysclk(dai, 0, set->sysclk, 0);
187 if (ret && ret != -ENOTSUPP) {
188 dev_err(dai->dev, "simple-card: set_sysclk error\n");
189 goto err;
190 }
191 }
192
193 if (set->slots) {
194 ret = snd_soc_dai_set_tdm_slot(dai,
195 set->tx_slot_mask,
196 set->rx_slot_mask,
197 set->slots,
198 set->slot_width);
199 if (ret && ret != -ENOTSUPP) {
200 dev_err(dai->dev, "simple-card: set_tdm_slot error\n");
201 goto err;
202 }
203 }
204
205 ret = 0;
206
207err:
208 return ret;
209}
210
211static int asoc_simple_card_dai_init(struct snd_soc_pcm_runtime *rtd) 183static int asoc_simple_card_dai_init(struct snd_soc_pcm_runtime *rtd)
212{ 184{
213 struct simple_card_data *priv = snd_soc_card_get_drvdata(rtd->card); 185 struct simple_card_data *priv = snd_soc_card_get_drvdata(rtd->card);
214 struct snd_soc_dai *codec = rtd->codec_dai; 186 struct snd_soc_dai *codec = rtd->codec_dai;
215 struct snd_soc_dai *cpu = rtd->cpu_dai; 187 struct snd_soc_dai *cpu = rtd->cpu_dai;
216 struct simple_dai_props *dai_props; 188 struct simple_dai_props *dai_props =
189 simple_priv_to_props(priv, rtd->num);
217 int ret; 190 int ret;
218 191
219 dai_props = &priv->dai_props[rtd->num]; 192 ret = asoc_simple_card_init_dai(codec, &dai_props->codec_dai);
220 ret = __asoc_simple_card_dai_init(codec, &dai_props->codec_dai);
221 if (ret < 0) 193 if (ret < 0)
222 return ret; 194 return ret;
223 195
224 ret = __asoc_simple_card_dai_init(cpu, &dai_props->cpu_dai); 196 ret = asoc_simple_card_init_dai(cpu, &dai_props->cpu_dai);
225 if (ret < 0) 197 if (ret < 0)
226 return ret; 198 return ret;
227 199
@@ -236,78 +208,6 @@ static int asoc_simple_card_dai_init(struct snd_soc_pcm_runtime *rtd)
236 return 0; 208 return 0;
237} 209}
238 210
239static int
240asoc_simple_card_sub_parse_of(struct device_node *np,
241 struct asoc_simple_dai *dai,
242 struct device_node **p_node,
243 const char **name,
244 int *args_count)
245{
246 struct of_phandle_args args;
247 struct clk *clk;
248 u32 val;
249 int ret;
250
251 if (!np)
252 return 0;
253
254 /*
255 * Get node via "sound-dai = <&phandle port>"
256 * it will be used as xxx_of_node on soc_bind_dai_link()
257 */
258 ret = of_parse_phandle_with_args(np, "sound-dai",
259 "#sound-dai-cells", 0, &args);
260 if (ret)
261 return ret;
262
263 *p_node = args.np;
264
265 if (args_count)
266 *args_count = args.args_count;
267
268 /* Get dai->name */
269 if (name) {
270 ret = snd_soc_of_get_dai_name(np, name);
271 if (ret < 0)
272 return ret;
273 }
274
275 if (!dai)
276 return 0;
277
278 /* Parse TDM slot */
279 ret = snd_soc_of_parse_tdm_slot(np, &dai->tx_slot_mask,
280 &dai->rx_slot_mask,
281 &dai->slots, &dai->slot_width);
282 if (ret)
283 return ret;
284
285 /*
286 * Parse dai->sysclk come from "clocks = <&xxx>"
287 * (if system has common clock)
288 * or "system-clock-frequency = <xxx>"
289 * or device's module clock.
290 */
291 if (of_property_read_bool(np, "clocks")) {
292 clk = of_clk_get(np, 0);
293 if (IS_ERR(clk)) {
294 ret = PTR_ERR(clk);
295 return ret;
296 }
297
298 dai->sysclk = clk_get_rate(clk);
299 dai->clk = clk;
300 } else if (!of_property_read_u32(np, "system-clock-frequency", &val)) {
301 dai->sysclk = val;
302 } else {
303 clk = of_clk_get(args.np, 0);
304 if (!IS_ERR(clk))
305 dai->sysclk = clk_get_rate(clk);
306 }
307
308 return 0;
309}
310
311static int asoc_simple_card_dai_link_of(struct device_node *node, 211static int asoc_simple_card_dai_link_of(struct device_node *node,
312 struct simple_card_data *priv, 212 struct simple_card_data *priv,
313 int idx, 213 int idx,
@@ -316,13 +216,14 @@ static int asoc_simple_card_dai_link_of(struct device_node *node,
316 struct device *dev = simple_priv_to_dev(priv); 216 struct device *dev = simple_priv_to_dev(priv);
317 struct snd_soc_dai_link *dai_link = simple_priv_to_link(priv, idx); 217 struct snd_soc_dai_link *dai_link = simple_priv_to_link(priv, idx);
318 struct simple_dai_props *dai_props = simple_priv_to_props(priv, idx); 218 struct simple_dai_props *dai_props = simple_priv_to_props(priv, idx);
219 struct asoc_simple_dai *cpu_dai = &dai_props->cpu_dai;
220 struct asoc_simple_dai *codec_dai = &dai_props->codec_dai;
319 struct device_node *cpu = NULL; 221 struct device_node *cpu = NULL;
320 struct device_node *plat = NULL; 222 struct device_node *plat = NULL;
321 struct device_node *codec = NULL; 223 struct device_node *codec = NULL;
322 char prop[128]; 224 char prop[128];
323 char *prefix = ""; 225 char *prefix = "";
324 int ret, cpu_args; 226 int ret, single_cpu;
325 u32 val;
326 227
327 /* For single DAI link & old style of DT node */ 228 /* For single DAI link & old style of DT node */
328 if (is_top_level_node) 229 if (is_top_level_node)
@@ -348,36 +249,46 @@ static int asoc_simple_card_dai_link_of(struct device_node *node,
348 if (ret < 0) 249 if (ret < 0)
349 goto dai_link_of_err; 250 goto dai_link_of_err;
350 251
351 if (!of_property_read_u32(node, "mclk-fs", &val)) 252 of_property_read_u32(node, "mclk-fs", &dai_props->mclk_fs);
352 dai_props->mclk_fs = val;
353 253
354 ret = asoc_simple_card_sub_parse_of(cpu, &dai_props->cpu_dai, 254 ret = asoc_simple_card_parse_cpu(cpu, dai_link,
355 &dai_link->cpu_of_node, 255 DAI, CELL, &single_cpu);
356 &dai_link->cpu_dai_name,
357 &cpu_args);
358 if (ret < 0) 256 if (ret < 0)
359 goto dai_link_of_err; 257 goto dai_link_of_err;
360 258
361 ret = asoc_simple_card_sub_parse_of(codec, &dai_props->codec_dai, 259 ret = asoc_simple_card_parse_codec(codec, dai_link, DAI, CELL);
362 &dai_link->codec_of_node,
363 &dai_link->codec_dai_name, NULL);
364 if (ret < 0) 260 if (ret < 0)
365 goto dai_link_of_err; 261 goto dai_link_of_err;
366 262
367 ret = asoc_simple_card_sub_parse_of(plat, NULL, 263 ret = asoc_simple_card_parse_platform(plat, dai_link, DAI, CELL);
368 &dai_link->platform_of_node,
369 NULL, NULL);
370 if (ret < 0) 264 if (ret < 0)
371 goto dai_link_of_err; 265 goto dai_link_of_err;
372 266
373 if (!dai_link->cpu_dai_name || !dai_link->codec_dai_name) { 267 ret = snd_soc_of_parse_tdm_slot(cpu, &cpu_dai->tx_slot_mask,
374 ret = -EINVAL; 268 &cpu_dai->rx_slot_mask,
269 &cpu_dai->slots,
270 &cpu_dai->slot_width);
271 if (ret < 0)
272 goto dai_link_of_err;
273
274 ret = snd_soc_of_parse_tdm_slot(codec, &codec_dai->tx_slot_mask,
275 &codec_dai->rx_slot_mask,
276 &codec_dai->slots,
277 &codec_dai->slot_width);
278 if (ret < 0)
279 goto dai_link_of_err;
280
281 ret = asoc_simple_card_parse_clk_cpu(cpu, dai_link, cpu_dai);
282 if (ret < 0)
375 goto dai_link_of_err; 283 goto dai_link_of_err;
376 }
377 284
378 /* Assumes platform == cpu */ 285 ret = asoc_simple_card_parse_clk_codec(codec, dai_link, codec_dai);
379 if (!dai_link->platform_of_node) 286 if (ret < 0)
380 dai_link->platform_of_node = dai_link->cpu_of_node; 287 goto dai_link_of_err;
288
289 ret = asoc_simple_card_canonicalize_dailink(dai_link);
290 if (ret < 0)
291 goto dai_link_of_err;
381 292
382 ret = asoc_simple_card_set_dailink_name(dev, dai_link, 293 ret = asoc_simple_card_set_dailink_name(dev, dai_link,
383 "%s-%s", 294 "%s-%s",
@@ -398,17 +309,7 @@ static int asoc_simple_card_dai_link_of(struct device_node *node,
398 dai_link->codec_dai_name, 309 dai_link->codec_dai_name,
399 dai_props->codec_dai.sysclk); 310 dai_props->codec_dai.sysclk);
400 311
401 /* 312 asoc_simple_card_canonicalize_cpu(dai_link, single_cpu);
402 * In soc_bind_dai_link() will check cpu name after
403 * of_node matching if dai_link has cpu_dai_name.
404 * but, it will never match if name was created by
405 * fmt_single_name() remove cpu_dai_name if cpu_args
406 * was 0. See:
407 * fmt_single_name()
408 * fmt_multiple_name()
409 */
410 if (!cpu_args)
411 dai_link->cpu_dai_name = NULL;
412 313
413dai_link_of_err: 314dai_link_of_err:
414 of_node_put(cpu); 315 of_node_put(cpu);
@@ -417,22 +318,54 @@ dai_link_of_err:
417 return ret; 318 return ret;
418} 319}
419 320
321static int asoc_simple_card_parse_aux_devs(struct device_node *node,
322 struct simple_card_data *priv)
323{
324 struct device *dev = simple_priv_to_dev(priv);
325 struct device_node *aux_node;
326 int i, n, len;
327
328 if (!of_find_property(node, PREFIX "aux-devs", &len))
329 return 0; /* Ok to have no aux-devs */
330
331 n = len / sizeof(__be32);
332 if (n <= 0)
333 return -EINVAL;
334
335 priv->snd_card.aux_dev = devm_kzalloc(dev,
336 n * sizeof(*priv->snd_card.aux_dev), GFP_KERNEL);
337 if (!priv->snd_card.aux_dev)
338 return -ENOMEM;
339
340 for (i = 0; i < n; i++) {
341 aux_node = of_parse_phandle(node, PREFIX "aux-devs", i);
342 if (!aux_node)
343 return -EINVAL;
344 priv->snd_card.aux_dev[i].codec_of_node = aux_node;
345 }
346
347 priv->snd_card.num_aux_devs = n;
348 return 0;
349}
350
420static int asoc_simple_card_parse_of(struct device_node *node, 351static int asoc_simple_card_parse_of(struct device_node *node,
421 struct simple_card_data *priv) 352 struct simple_card_data *priv)
422{ 353{
423 struct device *dev = simple_priv_to_dev(priv); 354 struct device *dev = simple_priv_to_dev(priv);
424 u32 val; 355 struct device_node *dai_link;
425 int ret; 356 int ret;
426 357
427 if (!node) 358 if (!node)
428 return -EINVAL; 359 return -EINVAL;
429 360
361 dai_link = of_get_child_by_name(node, PREFIX "dai-link");
362
430 /* The off-codec widgets */ 363 /* The off-codec widgets */
431 if (of_property_read_bool(node, PREFIX "widgets")) { 364 if (of_property_read_bool(node, PREFIX "widgets")) {
432 ret = snd_soc_of_parse_audio_simple_widgets(&priv->snd_card, 365 ret = snd_soc_of_parse_audio_simple_widgets(&priv->snd_card,
433 PREFIX "widgets"); 366 PREFIX "widgets");
434 if (ret) 367 if (ret)
435 return ret; 368 goto card_parse_end;
436 } 369 }
437 370
438 /* DAPM routes */ 371 /* DAPM routes */
@@ -440,16 +373,14 @@ static int asoc_simple_card_parse_of(struct device_node *node,
440 ret = snd_soc_of_parse_audio_routing(&priv->snd_card, 373 ret = snd_soc_of_parse_audio_routing(&priv->snd_card,
441 PREFIX "routing"); 374 PREFIX "routing");
442 if (ret) 375 if (ret)
443 return ret; 376 goto card_parse_end;
444 } 377 }
445 378
446 /* Factor to mclk, used in hw_params() */ 379 /* Factor to mclk, used in hw_params() */
447 ret = of_property_read_u32(node, PREFIX "mclk-fs", &val); 380 of_property_read_u32(node, PREFIX "mclk-fs", &priv->mclk_fs);
448 if (ret == 0)
449 priv->mclk_fs = val;
450 381
451 /* Single/Muti DAI link(s) & New style of DT node */ 382 /* Single/Muti DAI link(s) & New style of DT node */
452 if (of_get_child_by_name(node, PREFIX "dai-link")) { 383 if (dai_link) {
453 struct device_node *np = NULL; 384 struct device_node *np = NULL;
454 int i = 0; 385 int i = 0;
455 386
@@ -459,7 +390,7 @@ static int asoc_simple_card_parse_of(struct device_node *node,
459 i, false); 390 i, false);
460 if (ret < 0) { 391 if (ret < 0) {
461 of_node_put(np); 392 of_node_put(np);
462 return ret; 393 goto card_parse_end;
463 } 394 }
464 i++; 395 i++;
465 } 396 }
@@ -467,66 +398,55 @@ static int asoc_simple_card_parse_of(struct device_node *node,
467 /* For single DAI link & old style of DT node */ 398 /* For single DAI link & old style of DT node */
468 ret = asoc_simple_card_dai_link_of(node, priv, 0, true); 399 ret = asoc_simple_card_dai_link_of(node, priv, 0, true);
469 if (ret < 0) 400 if (ret < 0)
470 return ret; 401 goto card_parse_end;
471 } 402 }
472 403
473 ret = asoc_simple_card_parse_card_name(&priv->snd_card, PREFIX); 404 ret = asoc_simple_card_parse_card_name(&priv->snd_card, PREFIX);
474 if (ret) 405 if (ret < 0)
475 return ret; 406 goto card_parse_end;
476 407
477 return 0; 408 ret = asoc_simple_card_parse_aux_devs(node, priv);
478}
479 409
480/* Decrease the reference count of the device nodes */ 410card_parse_end:
481static int asoc_simple_card_unref(struct snd_soc_card *card) 411 of_node_put(dai_link);
482{
483 struct snd_soc_dai_link *dai_link;
484 int num_links;
485 412
486 for (num_links = 0, dai_link = card->dai_link; 413 return ret;
487 num_links < card->num_links;
488 num_links++, dai_link++) {
489 of_node_put(dai_link->cpu_of_node);
490 of_node_put(dai_link->codec_of_node);
491 }
492 return 0;
493} 414}
494 415
495static int asoc_simple_card_probe(struct platform_device *pdev) 416static int asoc_simple_card_probe(struct platform_device *pdev)
496{ 417{
497 struct simple_card_data *priv; 418 struct simple_card_data *priv;
498 struct snd_soc_dai_link *dai_link; 419 struct snd_soc_dai_link *dai_link;
420 struct simple_dai_props *dai_props;
499 struct device_node *np = pdev->dev.of_node; 421 struct device_node *np = pdev->dev.of_node;
500 struct device *dev = &pdev->dev; 422 struct device *dev = &pdev->dev;
501 int num_links, ret; 423 int num, ret;
502 424
503 /* Get the number of DAI links */ 425 /* Get the number of DAI links */
504 if (np && of_get_child_by_name(np, PREFIX "dai-link")) 426 if (np && of_get_child_by_name(np, PREFIX "dai-link"))
505 num_links = of_get_child_count(np); 427 num = of_get_child_count(np);
506 else 428 else
507 num_links = 1; 429 num = 1;
508 430
509 /* Allocate the private data and the DAI link array */ 431 /* Allocate the private data and the DAI link array */
510 priv = devm_kzalloc(dev, 432 priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
511 sizeof(*priv) + sizeof(*dai_link) * num_links,
512 GFP_KERNEL);
513 if (!priv) 433 if (!priv)
514 return -ENOMEM; 434 return -ENOMEM;
515 435
516 /* Init snd_soc_card */ 436 dai_props = devm_kzalloc(dev, sizeof(*dai_props) * num, GFP_KERNEL);
517 priv->snd_card.owner = THIS_MODULE; 437 dai_link = devm_kzalloc(dev, sizeof(*dai_link) * num, GFP_KERNEL);
518 priv->snd_card.dev = dev; 438 if (!dai_props || !dai_link)
519 dai_link = priv->dai_link;
520 priv->snd_card.dai_link = dai_link;
521 priv->snd_card.num_links = num_links;
522
523 /* Get room for the other properties */
524 priv->dai_props = devm_kzalloc(dev,
525 sizeof(*priv->dai_props) * num_links,
526 GFP_KERNEL);
527 if (!priv->dai_props)
528 return -ENOMEM; 439 return -ENOMEM;
529 440
441 priv->dai_props = dai_props;
442 priv->dai_link = dai_link;
443
444 /* Init snd_soc_card */
445 priv->snd_card.owner = THIS_MODULE;
446 priv->snd_card.dev = dev;
447 priv->snd_card.dai_link = priv->dai_link;
448 priv->snd_card.num_links = num;
449
530 if (np && of_device_is_available(np)) { 450 if (np && of_device_is_available(np)) {
531 451
532 ret = asoc_simple_card_parse_of(np, priv); 452 ret = asoc_simple_card_parse_of(np, priv);
@@ -567,7 +487,6 @@ static int asoc_simple_card_probe(struct platform_device *pdev)
567 sizeof(priv->dai_props->cpu_dai)); 487 sizeof(priv->dai_props->cpu_dai));
568 memcpy(&priv->dai_props->codec_dai, &cinfo->codec_dai, 488 memcpy(&priv->dai_props->codec_dai, &cinfo->codec_dai,
569 sizeof(priv->dai_props->codec_dai)); 489 sizeof(priv->dai_props->codec_dai));
570
571 } 490 }
572 491
573 snd_soc_card_set_drvdata(&priv->snd_card, priv); 492 snd_soc_card_set_drvdata(&priv->snd_card, priv);
@@ -575,9 +494,9 @@ static int asoc_simple_card_probe(struct platform_device *pdev)
575 ret = devm_snd_soc_register_card(&pdev->dev, &priv->snd_card); 494 ret = devm_snd_soc_register_card(&pdev->dev, &priv->snd_card);
576 if (ret >= 0) 495 if (ret >= 0)
577 return ret; 496 return ret;
578
579err: 497err:
580 asoc_simple_card_unref(&priv->snd_card); 498 asoc_simple_card_clean_reference(&priv->snd_card);
499
581 return ret; 500 return ret;
582} 501}
583 502
@@ -589,7 +508,7 @@ static int asoc_simple_card_remove(struct platform_device *pdev)
589 asoc_simple_card_remove_jack(&priv->hp_jack); 508 asoc_simple_card_remove_jack(&priv->hp_jack);
590 asoc_simple_card_remove_jack(&priv->mic_jack); 509 asoc_simple_card_remove_jack(&priv->mic_jack);
591 510
592 return asoc_simple_card_unref(card); 511 return asoc_simple_card_clean_reference(card);
593} 512}
594 513
595static const struct of_device_id asoc_simple_of_match[] = { 514static const struct of_device_id asoc_simple_of_match[] = {
@@ -611,6 +530,6 @@ static struct platform_driver asoc_simple_card = {
611module_platform_driver(asoc_simple_card); 530module_platform_driver(asoc_simple_card);
612 531
613MODULE_ALIAS("platform:asoc-simple-card"); 532MODULE_ALIAS("platform:asoc-simple-card");
614MODULE_LICENSE("GPL"); 533MODULE_LICENSE("GPL v2");
615MODULE_DESCRIPTION("ASoC Simple Sound Card"); 534MODULE_DESCRIPTION("ASoC Simple Sound Card");
616MODULE_AUTHOR("Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>"); 535MODULE_AUTHOR("Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>");
diff --git a/sound/soc/generic/simple-scu-card.c b/sound/soc/generic/simple-scu-card.c
new file mode 100644
index 000000000000..b9973a56bcb0
--- /dev/null
+++ b/sound/soc/generic/simple-scu-card.c
@@ -0,0 +1,345 @@
1/*
2 * ASoC simple SCU sound card support
3 *
4 * Copyright (C) 2015 Renesas Solutions Corp.
5 * Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
6 *
7 * based on ${LINUX}/sound/soc/generic/simple-card.c
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 version 2 as
11 * published by the Free Software Foundation.
12 */
13#include <linux/clk.h>
14#include <linux/device.h>
15#include <linux/module.h>
16#include <linux/of.h>
17#include <linux/of_device.h>
18#include <linux/platform_device.h>
19#include <linux/string.h>
20#include <sound/jack.h>
21#include <sound/soc.h>
22#include <sound/soc-dai.h>
23#include <sound/simple_card_utils.h>
24
25struct asoc_simple_card_priv {
26 struct snd_soc_card snd_card;
27 struct snd_soc_codec_conf codec_conf;
28 struct asoc_simple_dai *dai_props;
29 struct snd_soc_dai_link *dai_link;
30 u32 convert_rate;
31 u32 convert_channels;
32};
33
34#define simple_priv_to_dev(priv) ((priv)->snd_card.dev)
35#define simple_priv_to_link(priv, i) ((priv)->snd_card.dai_link + (i))
36#define simple_priv_to_props(priv, i) ((priv)->dai_props + (i))
37
38#define DAI "sound-dai"
39#define CELL "#sound-dai-cells"
40#define PREFIX "simple-audio-card,"
41
42static int asoc_simple_card_startup(struct snd_pcm_substream *substream)
43{
44 struct snd_soc_pcm_runtime *rtd = substream->private_data;
45 struct asoc_simple_card_priv *priv = snd_soc_card_get_drvdata(rtd->card);
46 struct asoc_simple_dai *dai_props =
47 simple_priv_to_props(priv, rtd->num);
48
49 return clk_prepare_enable(dai_props->clk);
50}
51
52static void asoc_simple_card_shutdown(struct snd_pcm_substream *substream)
53{
54 struct snd_soc_pcm_runtime *rtd = substream->private_data;
55 struct asoc_simple_card_priv *priv = snd_soc_card_get_drvdata(rtd->card);
56 struct asoc_simple_dai *dai_props =
57 simple_priv_to_props(priv, rtd->num);
58
59 clk_disable_unprepare(dai_props->clk);
60}
61
62static struct snd_soc_ops asoc_simple_card_ops = {
63 .startup = asoc_simple_card_startup,
64 .shutdown = asoc_simple_card_shutdown,
65};
66
67static int asoc_simple_card_dai_init(struct snd_soc_pcm_runtime *rtd)
68{
69 struct asoc_simple_card_priv *priv = snd_soc_card_get_drvdata(rtd->card);
70 struct snd_soc_dai *dai;
71 struct snd_soc_dai_link *dai_link;
72 struct asoc_simple_dai *dai_props;
73 int num = rtd->num;
74
75 dai_link = simple_priv_to_link(priv, num);
76 dai_props = simple_priv_to_props(priv, num);
77 dai = dai_link->dynamic ?
78 rtd->cpu_dai :
79 rtd->codec_dai;
80
81 return asoc_simple_card_init_dai(dai, dai_props);
82}
83
84static int asoc_simple_card_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
85 struct snd_pcm_hw_params *params)
86{
87 struct asoc_simple_card_priv *priv = snd_soc_card_get_drvdata(rtd->card);
88 struct snd_interval *rate = hw_param_interval(params,
89 SNDRV_PCM_HW_PARAM_RATE);
90 struct snd_interval *channels = hw_param_interval(params,
91 SNDRV_PCM_HW_PARAM_CHANNELS);
92
93 if (priv->convert_rate)
94 rate->min =
95 rate->max = priv->convert_rate;
96
97 if (priv->convert_channels)
98 channels->min =
99 channels->max = priv->convert_channels;
100
101 return 0;
102}
103
104static int asoc_simple_card_parse_links(struct device_node *np,
105 struct asoc_simple_card_priv *priv,
106 unsigned int daifmt,
107 int idx, bool is_fe)
108{
109 struct device *dev = simple_priv_to_dev(priv);
110 struct snd_soc_dai_link *dai_link = simple_priv_to_link(priv, idx);
111 struct asoc_simple_dai *dai_props = simple_priv_to_props(priv, idx);
112 int ret;
113
114 if (is_fe) {
115 int is_single_links = 0;
116
117 /* BE is dummy */
118 dai_link->codec_of_node = NULL;
119 dai_link->codec_dai_name = "snd-soc-dummy-dai";
120 dai_link->codec_name = "snd-soc-dummy";
121
122 /* FE settings */
123 dai_link->dynamic = 1;
124 dai_link->dpcm_merged_format = 1;
125
126 ret = asoc_simple_card_parse_cpu(np, dai_link, DAI, CELL,
127 &is_single_links);
128 if (ret)
129 return ret;
130
131 ret = asoc_simple_card_parse_clk_cpu(np, dai_link, dai_props);
132 if (ret < 0)
133 return ret;
134
135 ret = asoc_simple_card_set_dailink_name(dev, dai_link,
136 "fe.%s",
137 dai_link->cpu_dai_name);
138 if (ret < 0)
139 return ret;
140
141 asoc_simple_card_canonicalize_cpu(dai_link, is_single_links);
142 } else {
143 /* FE is dummy */
144 dai_link->cpu_of_node = NULL;
145 dai_link->cpu_dai_name = "snd-soc-dummy-dai";
146 dai_link->cpu_name = "snd-soc-dummy";
147
148 /* BE settings */
149 dai_link->no_pcm = 1;
150 dai_link->be_hw_params_fixup = asoc_simple_card_be_hw_params_fixup;
151
152 ret = asoc_simple_card_parse_codec(np, dai_link, DAI, CELL);
153 if (ret < 0)
154 return ret;
155
156 ret = asoc_simple_card_parse_clk_codec(np, dai_link, dai_props);
157 if (ret < 0)
158 return ret;
159
160 ret = asoc_simple_card_set_dailink_name(dev, dai_link,
161 "be.%s",
162 dai_link->codec_dai_name);
163 if (ret < 0)
164 return ret;
165
166 snd_soc_of_parse_audio_prefix(&priv->snd_card,
167 &priv->codec_conf,
168 dai_link->codec_of_node,
169 PREFIX "prefix");
170 }
171
172 ret = snd_soc_of_parse_tdm_slot(np,
173 &dai_props->tx_slot_mask,
174 &dai_props->rx_slot_mask,
175 &dai_props->slots,
176 &dai_props->slot_width);
177 if (ret)
178 return ret;
179
180 ret = asoc_simple_card_canonicalize_dailink(dai_link);
181 if (ret < 0)
182 return ret;
183
184 dai_link->dai_fmt = daifmt;
185 dai_link->dpcm_playback = 1;
186 dai_link->dpcm_capture = 1;
187 dai_link->ops = &asoc_simple_card_ops;
188 dai_link->init = asoc_simple_card_dai_init;
189
190 dev_dbg(dev, "\t%s / %04x / %d\n",
191 dai_link->name,
192 dai_link->dai_fmt,
193 dai_props->sysclk);
194
195 return 0;
196}
197
198static int asoc_simple_card_dai_link_of(struct device_node *node,
199 struct asoc_simple_card_priv *priv)
200{
201 struct device *dev = simple_priv_to_dev(priv);
202 struct device_node *np;
203 unsigned int daifmt = 0;
204 int ret, i;
205 bool is_fe;
206
207 /* find 1st codec */
208 np = of_get_child_by_name(node, PREFIX "codec");
209 if (!np)
210 return -ENODEV;
211
212 ret = asoc_simple_card_parse_daifmt(dev, node, np,
213 PREFIX, &daifmt);
214 if (ret < 0)
215 return ret;
216
217 i = 0;
218 for_each_child_of_node(node, np) {
219 is_fe = false;
220 if (strcmp(np->name, PREFIX "cpu") == 0)
221 is_fe = true;
222
223 ret = asoc_simple_card_parse_links(np, priv, daifmt, i, is_fe);
224 if (ret < 0)
225 return ret;
226 i++;
227 }
228
229 return 0;
230}
231
232static int asoc_simple_card_parse_of(struct device_node *node,
233 struct asoc_simple_card_priv *priv,
234 struct device *dev)
235{
236 struct asoc_simple_dai *props;
237 struct snd_soc_dai_link *links;
238 int ret;
239 int num;
240
241 if (!node)
242 return -EINVAL;
243
244 num = of_get_child_count(node);
245 props = devm_kzalloc(dev, sizeof(*props) * num, GFP_KERNEL);
246 links = devm_kzalloc(dev, sizeof(*links) * num, GFP_KERNEL);
247 if (!props || !links)
248 return -ENOMEM;
249
250 priv->dai_props = props;
251 priv->dai_link = links;
252
253 /* Init snd_soc_card */
254 priv->snd_card.owner = THIS_MODULE;
255 priv->snd_card.dev = dev;
256 priv->snd_card.dai_link = priv->dai_link;
257 priv->snd_card.num_links = num;
258 priv->snd_card.codec_conf = &priv->codec_conf;
259 priv->snd_card.num_configs = 1;
260
261 ret = snd_soc_of_parse_audio_routing(&priv->snd_card, PREFIX "routing");
262 if (ret < 0)
263 return ret;
264
265 /* sampling rate convert */
266 of_property_read_u32(node, PREFIX "convert-rate", &priv->convert_rate);
267
268 /* channels transfer */
269 of_property_read_u32(node, PREFIX "convert-channels", &priv->convert_channels);
270
271 ret = asoc_simple_card_dai_link_of(node, priv);
272 if (ret < 0)
273 return ret;
274
275 ret = asoc_simple_card_parse_card_name(&priv->snd_card, PREFIX);
276 if (ret < 0)
277 return ret;
278
279 dev_dbg(dev, "New card: %s\n",
280 priv->snd_card.name ? priv->snd_card.name : "");
281 dev_dbg(dev, "convert_rate %d\n", priv->convert_rate);
282 dev_dbg(dev, "convert_channels %d\n", priv->convert_channels);
283
284 return 0;
285}
286
287static int asoc_simple_card_probe(struct platform_device *pdev)
288{
289 struct asoc_simple_card_priv *priv;
290 struct device_node *np = pdev->dev.of_node;
291 struct device *dev = &pdev->dev;
292 int ret;
293
294 /* Allocate the private data */
295 priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
296 if (!priv)
297 return -ENOMEM;
298
299 ret = asoc_simple_card_parse_of(np, priv, dev);
300 if (ret < 0) {
301 if (ret != -EPROBE_DEFER)
302 dev_err(dev, "parse error %d\n", ret);
303 goto err;
304 }
305
306 snd_soc_card_set_drvdata(&priv->snd_card, priv);
307
308 ret = devm_snd_soc_register_card(&pdev->dev, &priv->snd_card);
309 if (ret >= 0)
310 return ret;
311err:
312 asoc_simple_card_clean_reference(&priv->snd_card);
313
314 return ret;
315}
316
317static int asoc_simple_card_remove(struct platform_device *pdev)
318{
319 struct snd_soc_card *card = platform_get_drvdata(pdev);
320
321 return asoc_simple_card_clean_reference(card);
322}
323
324static const struct of_device_id asoc_simple_of_match[] = {
325 { .compatible = "renesas,rsrc-card", },
326 { .compatible = "simple-scu-audio-card", },
327 {},
328};
329MODULE_DEVICE_TABLE(of, asoc_simple_of_match);
330
331static struct platform_driver asoc_simple_card = {
332 .driver = {
333 .name = "simple-scu-audio-card",
334 .of_match_table = asoc_simple_of_match,
335 },
336 .probe = asoc_simple_card_probe,
337 .remove = asoc_simple_card_remove,
338};
339
340module_platform_driver(asoc_simple_card);
341
342MODULE_ALIAS("platform:asoc-simple-scu-card");
343MODULE_LICENSE("GPL v2");
344MODULE_DESCRIPTION("ASoC Simple SCU Sound Card");
345MODULE_AUTHOR("Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>");
diff --git a/sound/soc/img/pistachio-internal-dac.c b/sound/soc/img/pistachio-internal-dac.c
index 162a0fd68c7b..53e11c6d4e22 100644
--- a/sound/soc/img/pistachio-internal-dac.c
+++ b/sound/soc/img/pistachio-internal-dac.c
@@ -134,12 +134,14 @@ static int pistachio_internal_dac_codec_probe(struct snd_soc_codec *codec)
134static const struct snd_soc_codec_driver pistachio_internal_dac_driver = { 134static const struct snd_soc_codec_driver pistachio_internal_dac_driver = {
135 .probe = pistachio_internal_dac_codec_probe, 135 .probe = pistachio_internal_dac_codec_probe,
136 .idle_bias_off = true, 136 .idle_bias_off = true,
137 .controls = pistachio_internal_dac_snd_controls, 137 .component_driver = {
138 .num_controls = ARRAY_SIZE(pistachio_internal_dac_snd_controls), 138 .controls = pistachio_internal_dac_snd_controls,
139 .dapm_widgets = pistachio_internal_dac_widgets, 139 .num_controls = ARRAY_SIZE(pistachio_internal_dac_snd_controls),
140 .num_dapm_widgets = ARRAY_SIZE(pistachio_internal_dac_widgets), 140 .dapm_widgets = pistachio_internal_dac_widgets,
141 .dapm_routes = pistachio_internal_dac_routes, 141 .num_dapm_widgets = ARRAY_SIZE(pistachio_internal_dac_widgets),
142 .num_dapm_routes = ARRAY_SIZE(pistachio_internal_dac_routes), 142 .dapm_routes = pistachio_internal_dac_routes,
143 .num_dapm_routes = ARRAY_SIZE(pistachio_internal_dac_routes),
144 },
143}; 145};
144 146
145static int pistachio_internal_dac_probe(struct platform_device *pdev) 147static int pistachio_internal_dac_probe(struct platform_device *pdev)
diff --git a/sound/soc/intel/Kconfig b/sound/soc/intel/Kconfig
index a20c3dfbcb5d..26eb5a0a5575 100644
--- a/sound/soc/intel/Kconfig
+++ b/sound/soc/intel/Kconfig
@@ -25,6 +25,7 @@ config SND_SST_IPC_ACPI
25 tristate 25 tristate
26 select SND_SST_IPC 26 select SND_SST_IPC
27 select SND_SOC_INTEL_SST 27 select SND_SOC_INTEL_SST
28 select IOSF_MBI
28 29
29config SND_SOC_INTEL_SST 30config SND_SOC_INTEL_SST
30 tristate 31 tristate
@@ -120,6 +121,17 @@ config SND_SOC_INTEL_BYT_MAX98090_MACH
120 This adds audio driver for Intel Baytrail platform based boards 121 This adds audio driver for Intel Baytrail platform based boards
121 with the MAX98090 audio codec. 122 with the MAX98090 audio codec.
122 123
124config SND_SOC_INTEL_BDW_RT5677_MACH
125 tristate "ASoC Audio driver for Intel Broadwell with RT5677 codec"
126 depends on X86_INTEL_LPSS && GPIOLIB && I2C && DW_DMAC
127 depends on DW_DMAC_CORE=y
128 select SND_SOC_INTEL_SST
129 select SND_SOC_INTEL_HASWELL
130 select SND_SOC_RT5677
131 help
132 This adds support for Intel Broadwell platform based boards with
133 the RT5677 audio codec.
134
123config SND_SOC_INTEL_BROADWELL_MACH 135config SND_SOC_INTEL_BROADWELL_MACH
124 tristate "ASoC Audio DSP support for Intel Broadwell Wildcatpoint" 136 tristate "ASoC Audio DSP support for Intel Broadwell Wildcatpoint"
125 depends on X86_INTEL_LPSS && I2C && DW_DMAC && \ 137 depends on X86_INTEL_LPSS && I2C && DW_DMAC && \
diff --git a/sound/soc/intel/atom/sst-atom-controls.c b/sound/soc/intel/atom/sst-atom-controls.c
index 98720a93de8a..0838478c4c3f 100644
--- a/sound/soc/intel/atom/sst-atom-controls.c
+++ b/sound/soc/intel/atom/sst-atom-controls.c
@@ -1,4 +1,4 @@
1/* 1 /*
2 * sst-atom-controls.c - Intel MID Platform driver DPCM ALSA controls for Mrfld 2 * sst-atom-controls.c - Intel MID Platform driver DPCM ALSA controls for Mrfld
3 * 3 *
4 * Copyright (C) 2013-14 Intel Corp 4 * Copyright (C) 2013-14 Intel Corp
@@ -534,6 +534,7 @@ static const DECLARE_TLV_DB_SCALE(sst_gain_tlv_common, SST_GAIN_MIN_VALUE * 10,
534 534
535/* Look up table to convert MIXER SW bit regs to SWM inputs */ 535/* Look up table to convert MIXER SW bit regs to SWM inputs */
536static const uint swm_mixer_input_ids[SST_SWM_INPUT_COUNT] = { 536static const uint swm_mixer_input_ids[SST_SWM_INPUT_COUNT] = {
537 [SST_IP_MODEM] = SST_SWM_IN_MODEM,
537 [SST_IP_CODEC0] = SST_SWM_IN_CODEC0, 538 [SST_IP_CODEC0] = SST_SWM_IN_CODEC0,
538 [SST_IP_CODEC1] = SST_SWM_IN_CODEC1, 539 [SST_IP_CODEC1] = SST_SWM_IN_CODEC1,
539 [SST_IP_LOOP0] = SST_SWM_IN_SPROT_LOOP, 540 [SST_IP_LOOP0] = SST_SWM_IN_SPROT_LOOP,
@@ -674,6 +675,7 @@ static int sst_swm_mixer_event(struct snd_soc_dapm_widget *w,
674/* SBA mixers - 16 inputs */ 675/* SBA mixers - 16 inputs */
675#define SST_SBA_DECLARE_MIX_CONTROLS(kctl_name) \ 676#define SST_SBA_DECLARE_MIX_CONTROLS(kctl_name) \
676 static const struct snd_kcontrol_new kctl_name[] = { \ 677 static const struct snd_kcontrol_new kctl_name[] = { \
678 SOC_DAPM_SINGLE("modem_in Switch", SND_SOC_NOPM, SST_IP_MODEM, 1, 0), \
677 SOC_DAPM_SINGLE("codec_in0 Switch", SND_SOC_NOPM, SST_IP_CODEC0, 1, 0), \ 679 SOC_DAPM_SINGLE("codec_in0 Switch", SND_SOC_NOPM, SST_IP_CODEC0, 1, 0), \
678 SOC_DAPM_SINGLE("codec_in1 Switch", SND_SOC_NOPM, SST_IP_CODEC1, 1, 0), \ 680 SOC_DAPM_SINGLE("codec_in1 Switch", SND_SOC_NOPM, SST_IP_CODEC1, 1, 0), \
679 SOC_DAPM_SINGLE("sprot_loop_in Switch", SND_SOC_NOPM, SST_IP_LOOP0, 1, 0), \ 681 SOC_DAPM_SINGLE("sprot_loop_in Switch", SND_SOC_NOPM, SST_IP_LOOP0, 1, 0), \
@@ -684,6 +686,7 @@ static int sst_swm_mixer_event(struct snd_soc_dapm_widget *w,
684 } 686 }
685 687
686#define SST_SBA_MIXER_GRAPH_MAP(mix_name) \ 688#define SST_SBA_MIXER_GRAPH_MAP(mix_name) \
689 { mix_name, "modem_in Switch", "modem_in" }, \
687 { mix_name, "codec_in0 Switch", "codec_in0" }, \ 690 { mix_name, "codec_in0 Switch", "codec_in0" }, \
688 { mix_name, "codec_in1 Switch", "codec_in1" }, \ 691 { mix_name, "codec_in1 Switch", "codec_in1" }, \
689 { mix_name, "sprot_loop_in Switch", "sprot_loop_in" }, \ 692 { mix_name, "sprot_loop_in Switch", "sprot_loop_in" }, \
@@ -713,6 +716,7 @@ SST_SBA_DECLARE_MIX_CONTROLS(sst_mix_media_l2_controls);
713SST_SBA_DECLARE_MIX_CONTROLS(sst_mix_voip_controls); 716SST_SBA_DECLARE_MIX_CONTROLS(sst_mix_voip_controls);
714SST_SBA_DECLARE_MIX_CONTROLS(sst_mix_codec0_controls); 717SST_SBA_DECLARE_MIX_CONTROLS(sst_mix_codec0_controls);
715SST_SBA_DECLARE_MIX_CONTROLS(sst_mix_codec1_controls); 718SST_SBA_DECLARE_MIX_CONTROLS(sst_mix_codec1_controls);
719SST_SBA_DECLARE_MIX_CONTROLS(sst_mix_modem_controls);
716 720
717/* 721/*
718 * sst_handle_vb_timer - Start/Stop the DSP scheduler 722 * sst_handle_vb_timer - Start/Stop the DSP scheduler
@@ -931,17 +935,26 @@ void sst_fill_ssp_defaults(struct snd_soc_dai *dai)
931int send_ssp_cmd(struct snd_soc_dai *dai, const char *id, bool enable) 935int send_ssp_cmd(struct snd_soc_dai *dai, const char *id, bool enable)
932{ 936{
933 struct sst_data *drv = snd_soc_dai_get_drvdata(dai); 937 struct sst_data *drv = snd_soc_dai_get_drvdata(dai);
934 const struct sst_ssp_config *config; 938 int ssp_id;
935 939
936 dev_info(dai->dev, "Enter: enable=%d port_name=%s\n", enable, id); 940 dev_info(dai->dev, "Enter: enable=%d port_name=%s\n", enable, id);
937 941
942 if (strcmp(id, "ssp0-port") == 0)
943 ssp_id = SSP_MODEM;
944 else if (strcmp(id, "ssp2-port") == 0)
945 ssp_id = SSP_CODEC;
946 else {
947 dev_dbg(dai->dev, "port %s is not supported\n", id);
948 return -1;
949 }
950
938 SST_FILL_DEFAULT_DESTINATION(drv->ssp_cmd.header.dst); 951 SST_FILL_DEFAULT_DESTINATION(drv->ssp_cmd.header.dst);
939 drv->ssp_cmd.header.command_id = SBA_HW_SET_SSP; 952 drv->ssp_cmd.header.command_id = SBA_HW_SET_SSP;
940 drv->ssp_cmd.header.length = sizeof(struct sst_cmd_sba_hw_set_ssp) 953 drv->ssp_cmd.header.length = sizeof(struct sst_cmd_sba_hw_set_ssp)
941 - sizeof(struct sst_dsp_header); 954 - sizeof(struct sst_dsp_header);
942 955
943 config = &sst_ssp_configs; 956 drv->ssp_cmd.selection = ssp_id;
944 dev_dbg(dai->dev, "ssp_id: %u\n", config->ssp_id); 957 dev_dbg(dai->dev, "ssp_id: %u\n", ssp_id);
945 958
946 if (enable) 959 if (enable)
947 drv->ssp_cmd.switch_state = SST_SWITCH_ON; 960 drv->ssp_cmd.switch_state = SST_SWITCH_ON;
@@ -1047,8 +1060,10 @@ static int sst_set_media_loop(struct snd_soc_dapm_widget *w,
1047} 1060}
1048 1061
1049static const struct snd_soc_dapm_widget sst_dapm_widgets[] = { 1062static const struct snd_soc_dapm_widget sst_dapm_widgets[] = {
1063 SST_AIF_IN("modem_in", sst_set_be_modules),
1050 SST_AIF_IN("codec_in0", sst_set_be_modules), 1064 SST_AIF_IN("codec_in0", sst_set_be_modules),
1051 SST_AIF_IN("codec_in1", sst_set_be_modules), 1065 SST_AIF_IN("codec_in1", sst_set_be_modules),
1066 SST_AIF_OUT("modem_out", sst_set_be_modules),
1052 SST_AIF_OUT("codec_out0", sst_set_be_modules), 1067 SST_AIF_OUT("codec_out0", sst_set_be_modules),
1053 SST_AIF_OUT("codec_out1", sst_set_be_modules), 1068 SST_AIF_OUT("codec_out1", sst_set_be_modules),
1054 1069
@@ -1103,6 +1118,9 @@ static const struct snd_soc_dapm_widget sst_dapm_widgets[] = {
1103 sst_mix_codec0_controls, sst_swm_mixer_event), 1118 sst_mix_codec0_controls, sst_swm_mixer_event),
1104 SST_SWM_MIXER("codec_out1 mix 0", SND_SOC_NOPM, SST_TASK_SBA, SST_SWM_OUT_CODEC1, 1119 SST_SWM_MIXER("codec_out1 mix 0", SND_SOC_NOPM, SST_TASK_SBA, SST_SWM_OUT_CODEC1,
1105 sst_mix_codec1_controls, sst_swm_mixer_event), 1120 sst_mix_codec1_controls, sst_swm_mixer_event),
1121 SST_SWM_MIXER("modem_out mix 0", SND_SOC_NOPM, SST_TASK_SBA, SST_SWM_OUT_MODEM,
1122 sst_mix_modem_controls, sst_swm_mixer_event),
1123
1106}; 1124};
1107 1125
1108static const struct snd_soc_dapm_route intercon[] = { 1126static const struct snd_soc_dapm_route intercon[] = {
@@ -1148,6 +1166,9 @@ static const struct snd_soc_dapm_route intercon[] = {
1148 SST_SBA_MIXER_GRAPH_MAP("codec_out0 mix 0"), 1166 SST_SBA_MIXER_GRAPH_MAP("codec_out0 mix 0"),
1149 {"codec_out1", NULL, "codec_out1 mix 0"}, 1167 {"codec_out1", NULL, "codec_out1 mix 0"},
1150 SST_SBA_MIXER_GRAPH_MAP("codec_out1 mix 0"), 1168 SST_SBA_MIXER_GRAPH_MAP("codec_out1 mix 0"),
1169 {"modem_out", NULL, "modem_out mix 0"},
1170 SST_SBA_MIXER_GRAPH_MAP("modem_out mix 0"),
1171
1151 1172
1152}; 1173};
1153static const char * const slot_names[] = { 1174static const char * const slot_names[] = {
@@ -1217,6 +1238,9 @@ static const struct snd_kcontrol_new sst_gain_controls[] = {
1217 SST_GAIN("media_loop2_out", SST_PATH_INDEX_MEDIA_LOOP2_OUT, SST_TASK_SBA, 0, &sst_gains[13]), 1238 SST_GAIN("media_loop2_out", SST_PATH_INDEX_MEDIA_LOOP2_OUT, SST_TASK_SBA, 0, &sst_gains[13]),
1218 SST_GAIN("sprot_loop_out", SST_PATH_INDEX_SPROT_LOOP_OUT, SST_TASK_SBA, 0, &sst_gains[14]), 1239 SST_GAIN("sprot_loop_out", SST_PATH_INDEX_SPROT_LOOP_OUT, SST_TASK_SBA, 0, &sst_gains[14]),
1219 SST_VOLUME("media0_in", SST_PATH_INDEX_MEDIA0_IN, SST_TASK_MMX, 0, &sst_gains[15]), 1240 SST_VOLUME("media0_in", SST_PATH_INDEX_MEDIA0_IN, SST_TASK_MMX, 0, &sst_gains[15]),
1241 SST_GAIN("modem_in", SST_PATH_INDEX_MODEM_IN, SST_TASK_SBA, 0, &sst_gains[16]),
1242 SST_GAIN("modem_out", SST_PATH_INDEX_MODEM_OUT, SST_TASK_SBA, 0, &sst_gains[17]),
1243
1220}; 1244};
1221 1245
1222#define SST_GAIN_NUM_CONTROLS 3 1246#define SST_GAIN_NUM_CONTROLS 3
diff --git a/sound/soc/intel/atom/sst-atom-controls.h b/sound/soc/intel/atom/sst-atom-controls.h
index e0113112f668..351d81469685 100644
--- a/sound/soc/intel/atom/sst-atom-controls.h
+++ b/sound/soc/intel/atom/sst-atom-controls.h
@@ -35,6 +35,8 @@ enum {
35/* define a bit for each mixer input */ 35/* define a bit for each mixer input */
36#define SST_MIX_IP(x) (x) 36#define SST_MIX_IP(x) (x)
37 37
38#define SST_IP_MODEM SST_MIX_IP(0)
39#define SST_IP_BT SST_MIX_IP(1)
38#define SST_IP_CODEC0 SST_MIX_IP(2) 40#define SST_IP_CODEC0 SST_MIX_IP(2)
39#define SST_IP_CODEC1 SST_MIX_IP(3) 41#define SST_IP_CODEC1 SST_MIX_IP(3)
40#define SST_IP_LOOP0 SST_MIX_IP(4) 42#define SST_IP_LOOP0 SST_MIX_IP(4)
@@ -63,6 +65,7 @@ enum {
63 * Audio DSP Path Ids. Specified by the audio DSP FW 65 * Audio DSP Path Ids. Specified by the audio DSP FW
64 */ 66 */
65enum sst_path_index { 67enum sst_path_index {
68 SST_PATH_INDEX_MODEM_OUT = (0x00 << SST_PATH_ID_SHIFT),
66 SST_PATH_INDEX_CODEC_OUT0 = (0x02 << SST_PATH_ID_SHIFT), 69 SST_PATH_INDEX_CODEC_OUT0 = (0x02 << SST_PATH_ID_SHIFT),
67 SST_PATH_INDEX_CODEC_OUT1 = (0x03 << SST_PATH_ID_SHIFT), 70 SST_PATH_INDEX_CODEC_OUT1 = (0x03 << SST_PATH_ID_SHIFT),
68 71
@@ -80,6 +83,7 @@ enum sst_path_index {
80 83
81 84
82 /* Start of input paths */ 85 /* Start of input paths */
86 SST_PATH_INDEX_MODEM_IN = (0x80 << SST_PATH_ID_SHIFT),
83 SST_PATH_INDEX_CODEC_IN0 = (0x82 << SST_PATH_ID_SHIFT), 87 SST_PATH_INDEX_CODEC_IN0 = (0x82 << SST_PATH_ID_SHIFT),
84 SST_PATH_INDEX_CODEC_IN1 = (0x83 << SST_PATH_ID_SHIFT), 88 SST_PATH_INDEX_CODEC_IN1 = (0x83 << SST_PATH_ID_SHIFT),
85 89
@@ -105,6 +109,7 @@ enum sst_path_index {
105 * path IDs 109 * path IDs
106 */ 110 */
107enum sst_swm_inputs { 111enum sst_swm_inputs {
112 SST_SWM_IN_MODEM = (SST_PATH_INDEX_MODEM_IN | SST_DEFAULT_CELL_NBR),
108 SST_SWM_IN_CODEC0 = (SST_PATH_INDEX_CODEC_IN0 | SST_DEFAULT_CELL_NBR), 113 SST_SWM_IN_CODEC0 = (SST_PATH_INDEX_CODEC_IN0 | SST_DEFAULT_CELL_NBR),
109 SST_SWM_IN_CODEC1 = (SST_PATH_INDEX_CODEC_IN1 | SST_DEFAULT_CELL_NBR), 114 SST_SWM_IN_CODEC1 = (SST_PATH_INDEX_CODEC_IN1 | SST_DEFAULT_CELL_NBR),
110 SST_SWM_IN_SPROT_LOOP = (SST_PATH_INDEX_SPROT_LOOP_IN | SST_DEFAULT_CELL_NBR), 115 SST_SWM_IN_SPROT_LOOP = (SST_PATH_INDEX_SPROT_LOOP_IN | SST_DEFAULT_CELL_NBR),
@@ -124,6 +129,7 @@ enum sst_swm_inputs {
124 * path IDs 129 * path IDs
125 */ 130 */
126enum sst_swm_outputs { 131enum sst_swm_outputs {
132 SST_SWM_OUT_MODEM = (SST_PATH_INDEX_MODEM_OUT | SST_DEFAULT_CELL_NBR),
127 SST_SWM_OUT_CODEC0 = (SST_PATH_INDEX_CODEC_OUT0 | SST_DEFAULT_CELL_NBR), 133 SST_SWM_OUT_CODEC0 = (SST_PATH_INDEX_CODEC_OUT0 | SST_DEFAULT_CELL_NBR),
128 SST_SWM_OUT_CODEC1 = (SST_PATH_INDEX_CODEC_OUT1 | SST_DEFAULT_CELL_NBR), 134 SST_SWM_OUT_CODEC1 = (SST_PATH_INDEX_CODEC_OUT1 | SST_DEFAULT_CELL_NBR),
129 SST_SWM_OUT_SPROT_LOOP = (SST_PATH_INDEX_SPROT_LOOP_OUT | SST_DEFAULT_CELL_NBR), 135 SST_SWM_OUT_SPROT_LOOP = (SST_PATH_INDEX_SPROT_LOOP_OUT | SST_DEFAULT_CELL_NBR),
diff --git a/sound/soc/intel/atom/sst-mfld-platform-pcm.c b/sound/soc/intel/atom/sst-mfld-platform-pcm.c
index 52ed434cbca6..25c6d87c818e 100644
--- a/sound/soc/intel/atom/sst-mfld-platform-pcm.c
+++ b/sound/soc/intel/atom/sst-mfld-platform-pcm.c
@@ -670,7 +670,7 @@ static snd_pcm_uframes_t sst_platform_pcm_pointer
670 return str_info->buffer_ptr; 670 return str_info->buffer_ptr;
671} 671}
672 672
673static struct snd_pcm_ops sst_platform_ops = { 673static const struct snd_pcm_ops sst_platform_ops = {
674 .open = sst_platform_open, 674 .open = sst_platform_open,
675 .ioctl = snd_pcm_lib_ioctl, 675 .ioctl = snd_pcm_lib_ioctl,
676 .trigger = sst_platform_pcm_trigger, 676 .trigger = sst_platform_pcm_trigger,
diff --git a/sound/soc/intel/atom/sst/sst.c b/sound/soc/intel/atom/sst/sst.c
index a4b458e77089..9b6e27385dc9 100644
--- a/sound/soc/intel/atom/sst/sst.c
+++ b/sound/soc/intel/atom/sst/sst.c
@@ -190,7 +190,8 @@ int sst_driver_ops(struct intel_sst_drv *sst)
190 190
191 default: 191 default:
192 dev_err(sst->dev, 192 dev_err(sst->dev,
193 "SST Driver capablities missing for dev_id: %x", sst->dev_id); 193 "SST Driver capabilities missing for dev_id: %x",
194 sst->dev_id);
194 return -EINVAL; 195 return -EINVAL;
195 }; 196 };
196} 197}
@@ -441,7 +442,7 @@ static int intel_sst_suspend(struct device *dev)
441 struct stream_info *stream = &ctx->streams[i]; 442 struct stream_info *stream = &ctx->streams[i];
442 443
443 if (stream->status == STREAM_RUNNING) { 444 if (stream->status == STREAM_RUNNING) {
444 dev_err(dev, "stream %d is running, cant susupend, abort\n", i); 445 dev_err(dev, "stream %d is running, can't suspend, abort\n", i);
445 return -EBUSY; 446 return -EBUSY;
446 } 447 }
447 } 448 }
diff --git a/sound/soc/intel/atom/sst/sst_acpi.c b/sound/soc/intel/atom/sst/sst_acpi.c
index 4d3184971227..ba5c0d71720a 100644
--- a/sound/soc/intel/atom/sst/sst_acpi.c
+++ b/sound/soc/intel/atom/sst/sst_acpi.c
@@ -39,6 +39,8 @@
39#include <acpi/platform/aclinux.h> 39#include <acpi/platform/aclinux.h>
40#include <acpi/actypes.h> 40#include <acpi/actypes.h>
41#include <acpi/acpi_bus.h> 41#include <acpi/acpi_bus.h>
42#include <asm/cpu_device_id.h>
43#include <asm/iosf_mbi.h>
42#include "../sst-mfld-platform.h" 44#include "../sst-mfld-platform.h"
43#include "../../common/sst-dsp.h" 45#include "../../common/sst-dsp.h"
44#include "../../common/sst-acpi.h" 46#include "../../common/sst-acpi.h"
@@ -113,6 +115,28 @@ static const struct sst_res_info byt_rvp_res_info = {
113 .acpi_ipc_irq_index = 5, 115 .acpi_ipc_irq_index = 5,
114}; 116};
115 117
118/* BYTCR has different BIOS from BYT */
119static const struct sst_res_info bytcr_res_info = {
120 .shim_offset = 0x140000,
121 .shim_size = 0x000100,
122 .shim_phy_addr = SST_BYT_SHIM_PHY_ADDR,
123 .ssp0_offset = 0xa0000,
124 .ssp0_size = 0x1000,
125 .dma0_offset = 0x98000,
126 .dma0_size = 0x4000,
127 .dma1_offset = 0x9c000,
128 .dma1_size = 0x4000,
129 .iram_offset = 0x0c0000,
130 .iram_size = 0x14000,
131 .dram_offset = 0x100000,
132 .dram_size = 0x28000,
133 .mbox_offset = 0x144000,
134 .mbox_size = 0x1000,
135 .acpi_lpe_res_index = 0,
136 .acpi_ddr_index = 2,
137 .acpi_ipc_irq_index = 0
138};
139
116static struct sst_platform_info byt_rvp_platform_data = { 140static struct sst_platform_info byt_rvp_platform_data = {
117 .probe_data = &byt_fwparse_info, 141 .probe_data = &byt_fwparse_info,
118 .ipc_info = &byt_ipc_info, 142 .ipc_info = &byt_ipc_info,
@@ -142,7 +166,7 @@ static int sst_platform_get_resources(struct intel_sst_drv *ctx)
142 rsrc = platform_get_resource(pdev, IORESOURCE_MEM, 166 rsrc = platform_get_resource(pdev, IORESOURCE_MEM,
143 ctx->pdata->res_info->acpi_lpe_res_index); 167 ctx->pdata->res_info->acpi_lpe_res_index);
144 if (!rsrc) { 168 if (!rsrc) {
145 dev_err(ctx->dev, "Invalid SHIM base from IFWI"); 169 dev_err(ctx->dev, "Invalid SHIM base from IFWI\n");
146 return -EIO; 170 return -EIO;
147 } 171 }
148 dev_info(ctx->dev, "LPE base: %#x size:%#x", (unsigned int) rsrc->start, 172 dev_info(ctx->dev, "LPE base: %#x size:%#x", (unsigned int) rsrc->start,
@@ -154,7 +178,7 @@ static int sst_platform_get_resources(struct intel_sst_drv *ctx)
154 ctx->iram = devm_ioremap_nocache(ctx->dev, ctx->iram_base, 178 ctx->iram = devm_ioremap_nocache(ctx->dev, ctx->iram_base,
155 ctx->pdata->res_info->iram_size); 179 ctx->pdata->res_info->iram_size);
156 if (!ctx->iram) { 180 if (!ctx->iram) {
157 dev_err(ctx->dev, "unable to map IRAM"); 181 dev_err(ctx->dev, "unable to map IRAM\n");
158 return -EIO; 182 return -EIO;
159 } 183 }
160 184
@@ -164,7 +188,7 @@ static int sst_platform_get_resources(struct intel_sst_drv *ctx)
164 ctx->dram = devm_ioremap_nocache(ctx->dev, ctx->dram_base, 188 ctx->dram = devm_ioremap_nocache(ctx->dev, ctx->dram_base,
165 ctx->pdata->res_info->dram_size); 189 ctx->pdata->res_info->dram_size);
166 if (!ctx->dram) { 190 if (!ctx->dram) {
167 dev_err(ctx->dev, "unable to map DRAM"); 191 dev_err(ctx->dev, "unable to map DRAM\n");
168 return -EIO; 192 return -EIO;
169 } 193 }
170 194
@@ -173,7 +197,7 @@ static int sst_platform_get_resources(struct intel_sst_drv *ctx)
173 ctx->shim = devm_ioremap_nocache(ctx->dev, ctx->shim_phy_add, 197 ctx->shim = devm_ioremap_nocache(ctx->dev, ctx->shim_phy_add,
174 ctx->pdata->res_info->shim_size); 198 ctx->pdata->res_info->shim_size);
175 if (!ctx->shim) { 199 if (!ctx->shim) {
176 dev_err(ctx->dev, "unable to map SHIM"); 200 dev_err(ctx->dev, "unable to map SHIM\n");
177 return -EIO; 201 return -EIO;
178 } 202 }
179 203
@@ -186,7 +210,7 @@ static int sst_platform_get_resources(struct intel_sst_drv *ctx)
186 ctx->mailbox = devm_ioremap_nocache(ctx->dev, ctx->mailbox_add, 210 ctx->mailbox = devm_ioremap_nocache(ctx->dev, ctx->mailbox_add,
187 ctx->pdata->res_info->mbox_size); 211 ctx->pdata->res_info->mbox_size);
188 if (!ctx->mailbox) { 212 if (!ctx->mailbox) {
189 dev_err(ctx->dev, "unable to map mailbox"); 213 dev_err(ctx->dev, "unable to map mailbox\n");
190 return -EIO; 214 return -EIO;
191 } 215 }
192 216
@@ -196,7 +220,7 @@ static int sst_platform_get_resources(struct intel_sst_drv *ctx)
196 rsrc = platform_get_resource(pdev, IORESOURCE_MEM, 220 rsrc = platform_get_resource(pdev, IORESOURCE_MEM,
197 ctx->pdata->res_info->acpi_ddr_index); 221 ctx->pdata->res_info->acpi_ddr_index);
198 if (!rsrc) { 222 if (!rsrc) {
199 dev_err(ctx->dev, "Invalid DDR base from IFWI"); 223 dev_err(ctx->dev, "Invalid DDR base from IFWI\n");
200 return -EIO; 224 return -EIO;
201 } 225 }
202 ctx->ddr_base = rsrc->start; 226 ctx->ddr_base = rsrc->start;
@@ -205,7 +229,7 @@ static int sst_platform_get_resources(struct intel_sst_drv *ctx)
205 ctx->ddr = devm_ioremap_nocache(ctx->dev, ctx->ddr_base, 229 ctx->ddr = devm_ioremap_nocache(ctx->dev, ctx->ddr_base,
206 resource_size(rsrc)); 230 resource_size(rsrc));
207 if (!ctx->ddr) { 231 if (!ctx->ddr) {
208 dev_err(ctx->dev, "unable to map DDR"); 232 dev_err(ctx->dev, "unable to map DDR\n");
209 return -EIO; 233 return -EIO;
210 } 234 }
211 235
@@ -215,6 +239,46 @@ static int sst_platform_get_resources(struct intel_sst_drv *ctx)
215 return 0; 239 return 0;
216} 240}
217 241
242
243static int is_byt_cr(struct device *dev, bool *bytcr)
244{
245 int status = 0;
246
247 if (IS_ENABLED(CONFIG_IOSF_MBI)) {
248 static const struct x86_cpu_id cpu_ids[] = {
249 { X86_VENDOR_INTEL, 6, 55 }, /* Valleyview, Bay Trail */
250 {}
251 };
252 u32 bios_status;
253
254 if (!x86_match_cpu(cpu_ids) || !iosf_mbi_available()) {
255 /* bail silently */
256 return status;
257 }
258
259 status = iosf_mbi_read(BT_MBI_UNIT_PMC, /* 0x04 PUNIT */
260 MBI_REG_READ, /* 0x10 */
261 0x006, /* BIOS_CONFIG */
262 &bios_status);
263
264 if (status) {
265 dev_err(dev, "could not read PUNIT BIOS_CONFIG\n");
266 } else {
267 /* bits 26:27 mirror PMIC options */
268 bios_status = (bios_status >> 26) & 3;
269
270 if ((bios_status == 1) || (bios_status == 3))
271 *bytcr = true;
272 else
273 dev_info(dev, "BYT-CR not detected\n");
274 }
275 } else {
276 dev_info(dev, "IOSF_MBI not enabled, no BYT-CR detection\n");
277 }
278 return status;
279}
280
281
218static int sst_acpi_probe(struct platform_device *pdev) 282static int sst_acpi_probe(struct platform_device *pdev)
219{ 283{
220 struct device *dev = &pdev->dev; 284 struct device *dev = &pdev->dev;
@@ -226,11 +290,12 @@ static int sst_acpi_probe(struct platform_device *pdev)
226 struct platform_device *plat_dev; 290 struct platform_device *plat_dev;
227 struct sst_platform_info *pdata; 291 struct sst_platform_info *pdata;
228 unsigned int dev_id; 292 unsigned int dev_id;
293 bool bytcr = false;
229 294
230 id = acpi_match_device(dev->driver->acpi_match_table, dev); 295 id = acpi_match_device(dev->driver->acpi_match_table, dev);
231 if (!id) 296 if (!id)
232 return -ENODEV; 297 return -ENODEV;
233 dev_dbg(dev, "for %s", id->id); 298 dev_dbg(dev, "for %s\n", id->id);
234 299
235 mach = (struct sst_acpi_mach *)id->driver_data; 300 mach = (struct sst_acpi_mach *)id->driver_data;
236 mach = sst_acpi_find_machine(mach); 301 mach = sst_acpi_find_machine(mach);
@@ -251,6 +316,18 @@ static int sst_acpi_probe(struct platform_device *pdev)
251 316
252 dev_dbg(dev, "ACPI device id: %x\n", dev_id); 317 dev_dbg(dev, "ACPI device id: %x\n", dev_id);
253 318
319 ret = sst_alloc_drv_context(&ctx, dev, dev_id);
320 if (ret < 0)
321 return ret;
322
323 ret = is_byt_cr(dev, &bytcr);
324 if (!((ret < 0) || (bytcr == false))) {
325 dev_info(dev, "Detected Baytrail-CR platform\n");
326
327 /* override resource info */
328 byt_rvp_platform_data.res_info = &bytcr_res_info;
329 }
330
254 plat_dev = platform_device_register_data(dev, pdata->platform, -1, 331 plat_dev = platform_device_register_data(dev, pdata->platform, -1,
255 NULL, 0); 332 NULL, 0);
256 if (IS_ERR(plat_dev)) { 333 if (IS_ERR(plat_dev)) {
@@ -271,10 +348,6 @@ static int sst_acpi_probe(struct platform_device *pdev)
271 return PTR_ERR(mdev); 348 return PTR_ERR(mdev);
272 } 349 }
273 350
274 ret = sst_alloc_drv_context(&ctx, dev, dev_id);
275 if (ret < 0)
276 return ret;
277
278 /* Fill sst platform data */ 351 /* Fill sst platform data */
279 ctx->pdata = pdata; 352 ctx->pdata = pdata;
280 strcpy(ctx->firmware_name, mach->fw_filename); 353 strcpy(ctx->firmware_name, mach->fw_filename);
diff --git a/sound/soc/intel/atom/sst/sst_ipc.c b/sound/soc/intel/atom/sst/sst_ipc.c
index 8afa6fe7b0b0..bfc889950bb2 100644
--- a/sound/soc/intel/atom/sst/sst_ipc.c
+++ b/sound/soc/intel/atom/sst/sst_ipc.c
@@ -267,6 +267,9 @@ static void process_fw_async_msg(struct intel_sst_drv *sst_drv_ctx,
267 "Period elapsed rcvd for pipe id 0x%x\n", 267 "Period elapsed rcvd for pipe id 0x%x\n",
268 pipe_id); 268 pipe_id);
269 stream = &sst_drv_ctx->streams[str_id]; 269 stream = &sst_drv_ctx->streams[str_id];
270 /* If stream is dropped, skip processing this message*/
271 if (stream->status == STREAM_INIT)
272 break;
270 if (stream->period_elapsed) 273 if (stream->period_elapsed)
271 stream->period_elapsed(stream->pcm_substream); 274 stream->period_elapsed(stream->pcm_substream);
272 if (stream->compr_cb) 275 if (stream->compr_cb)
diff --git a/sound/soc/intel/atom/sst/sst_pvt.c b/sound/soc/intel/atom/sst/sst_pvt.c
index adb32fefd693..b1e6b8f34a6a 100644
--- a/sound/soc/intel/atom/sst/sst_pvt.c
+++ b/sound/soc/intel/atom/sst/sst_pvt.c
@@ -279,17 +279,15 @@ int sst_prepare_and_post_msg(struct intel_sst_drv *sst,
279 279
280 if (response) { 280 if (response) {
281 ret = sst_wait_timeout(sst, block); 281 ret = sst_wait_timeout(sst, block);
282 if (ret < 0) { 282 if (ret < 0)
283 goto out; 283 goto out;
284 } else if(block->data) { 284
285 if (!data) 285 if (data && block->data) {
286 goto out; 286 *data = kmemdup(block->data, block->size, GFP_KERNEL);
287 *data = kzalloc(block->size, GFP_KERNEL); 287 if (!*data) {
288 if (!(*data)) {
289 ret = -ENOMEM; 288 ret = -ENOMEM;
290 goto out; 289 goto out;
291 } else 290 }
292 memcpy(data, (void *) block->data, block->size);
293 } 291 }
294 } 292 }
295out: 293out:
diff --git a/sound/soc/intel/baytrail/sst-baytrail-ipc.c b/sound/soc/intel/baytrail/sst-baytrail-ipc.c
index 5bbaa667bec1..c8455b47388b 100644
--- a/sound/soc/intel/baytrail/sst-baytrail-ipc.c
+++ b/sound/soc/intel/baytrail/sst-baytrail-ipc.c
@@ -184,15 +184,9 @@ struct sst_byt {
184 184
185static inline u64 sst_byt_header(int msg_id, int data, bool large, int str_id) 185static inline u64 sst_byt_header(int msg_id, int data, bool large, int str_id)
186{ 186{
187 u64 header; 187 return IPC_HEADER_MSG_ID(msg_id) | IPC_HEADER_STR_ID(str_id) |
188 188 IPC_HEADER_LARGE(large) | IPC_HEADER_DATA(data) |
189 header = IPC_HEADER_MSG_ID(msg_id) | 189 SST_BYT_IPCX_BUSY;
190 IPC_HEADER_STR_ID(str_id) |
191 IPC_HEADER_LARGE(large) |
192 IPC_HEADER_DATA(data) |
193 SST_BYT_IPCX_BUSY;
194
195 return header;
196} 190}
197 191
198static inline u16 sst_byt_header_msg_id(u64 header) 192static inline u16 sst_byt_header_msg_id(u64 header)
diff --git a/sound/soc/intel/boards/Makefile b/sound/soc/intel/boards/Makefile
index dac03a06bfd8..5639f10774e6 100644
--- a/sound/soc/intel/boards/Makefile
+++ b/sound/soc/intel/boards/Makefile
@@ -1,6 +1,7 @@
1snd-soc-sst-haswell-objs := haswell.o 1snd-soc-sst-haswell-objs := haswell.o
2snd-soc-sst-byt-rt5640-mach-objs := byt-rt5640.o 2snd-soc-sst-byt-rt5640-mach-objs := byt-rt5640.o
3snd-soc-sst-byt-max98090-mach-objs := byt-max98090.o 3snd-soc-sst-byt-max98090-mach-objs := byt-max98090.o
4snd-soc-sst-bdw-rt5677-mach-objs := bdw-rt5677.o
4snd-soc-sst-broadwell-objs := broadwell.o 5snd-soc-sst-broadwell-objs := broadwell.o
5snd-soc-sst-bxt-da7219_max98357a-objs := bxt_da7219_max98357a.o 6snd-soc-sst-bxt-da7219_max98357a-objs := bxt_da7219_max98357a.o
6snd-soc-sst-bxt-rt298-objs := bxt_rt298.o 7snd-soc-sst-bxt-rt298-objs := bxt_rt298.o
@@ -19,6 +20,7 @@ obj-$(CONFIG_SND_SOC_INTEL_BYT_MAX98090_MACH) += snd-soc-sst-byt-max98090-mach.o
19obj-$(CONFIG_SND_SOC_INTEL_BXT_DA7219_MAX98357A_MACH) += snd-soc-sst-bxt-da7219_max98357a.o 20obj-$(CONFIG_SND_SOC_INTEL_BXT_DA7219_MAX98357A_MACH) += snd-soc-sst-bxt-da7219_max98357a.o
20obj-$(CONFIG_SND_SOC_INTEL_BXT_RT298_MACH) += snd-soc-sst-bxt-rt298.o 21obj-$(CONFIG_SND_SOC_INTEL_BXT_RT298_MACH) += snd-soc-sst-bxt-rt298.o
21obj-$(CONFIG_SND_SOC_INTEL_BROADWELL_MACH) += snd-soc-sst-broadwell.o 22obj-$(CONFIG_SND_SOC_INTEL_BROADWELL_MACH) += snd-soc-sst-broadwell.o
23obj-$(CONFIG_SND_SOC_INTEL_BDW_RT5677_MACH) += snd-soc-sst-bdw-rt5677-mach.o
22obj-$(CONFIG_SND_SOC_INTEL_BYTCR_RT5640_MACH) += snd-soc-sst-bytcr-rt5640.o 24obj-$(CONFIG_SND_SOC_INTEL_BYTCR_RT5640_MACH) += snd-soc-sst-bytcr-rt5640.o
23obj-$(CONFIG_SND_SOC_INTEL_BYTCR_RT5651_MACH) += snd-soc-sst-bytcr-rt5651.o 25obj-$(CONFIG_SND_SOC_INTEL_BYTCR_RT5651_MACH) += snd-soc-sst-bytcr-rt5651.o
24obj-$(CONFIG_SND_SOC_INTEL_CHT_BSW_RT5672_MACH) += snd-soc-sst-cht-bsw-rt5672.o 26obj-$(CONFIG_SND_SOC_INTEL_CHT_BSW_RT5672_MACH) += snd-soc-sst-cht-bsw-rt5672.o
diff --git a/sound/soc/intel/boards/bdw-rt5677.c b/sound/soc/intel/boards/bdw-rt5677.c
new file mode 100644
index 000000000000..547e6705bf6d
--- /dev/null
+++ b/sound/soc/intel/boards/bdw-rt5677.c
@@ -0,0 +1,347 @@
1/*
2 * ASoC machine driver for Intel Broadwell platforms with RT5677 codec
3 *
4 * Copyright (c) 2014, The Chromium OS Authors. All rights reserved.
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms and conditions of the GNU General Public License,
8 * version 2, as published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
13 * more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19#include <linux/module.h>
20#include <linux/platform_device.h>
21#include <linux/gpio/consumer.h>
22#include <linux/delay.h>
23#include <sound/core.h>
24#include <sound/pcm.h>
25#include <sound/soc.h>
26#include <sound/pcm_params.h>
27#include <sound/jack.h>
28
29#include "../common/sst-dsp.h"
30#include "../haswell/sst-haswell-ipc.h"
31
32#include "../../codecs/rt5677.h"
33
34struct bdw_rt5677_priv {
35 struct gpio_desc *gpio_hp_en;
36 struct snd_soc_codec *codec;
37};
38
39static int bdw_rt5677_event_hp(struct snd_soc_dapm_widget *w,
40 struct snd_kcontrol *k, int event)
41{
42 struct snd_soc_dapm_context *dapm = w->dapm;
43 struct snd_soc_card *card = dapm->card;
44 struct bdw_rt5677_priv *bdw_rt5677 = snd_soc_card_get_drvdata(card);
45
46 if (SND_SOC_DAPM_EVENT_ON(event))
47 msleep(70);
48
49 gpiod_set_value_cansleep(bdw_rt5677->gpio_hp_en,
50 SND_SOC_DAPM_EVENT_ON(event));
51
52 return 0;
53}
54
55static const struct snd_soc_dapm_widget bdw_rt5677_widgets[] = {
56 SND_SOC_DAPM_HP("Headphone", bdw_rt5677_event_hp),
57 SND_SOC_DAPM_SPK("Speaker", NULL),
58 SND_SOC_DAPM_MIC("Headset Mic", NULL),
59 SND_SOC_DAPM_MIC("Local DMICs", NULL),
60 SND_SOC_DAPM_MIC("Remote DMICs", NULL),
61};
62
63static const struct snd_soc_dapm_route bdw_rt5677_map[] = {
64 /* Speakers */
65 {"Speaker", NULL, "PDM1L"},
66 {"Speaker", NULL, "PDM1R"},
67
68 /* Headset jack connectors */
69 {"Headphone", NULL, "LOUT1"},
70 {"Headphone", NULL, "LOUT2"},
71 {"IN1P", NULL, "Headset Mic"},
72 {"IN1N", NULL, "Headset Mic"},
73
74 /* Digital MICs
75 * Local DMICs: the two DMICs on the mainboard
76 * Remote DMICs: the two DMICs on the camera module
77 */
78 {"DMIC L1", NULL, "Remote DMICs"},
79 {"DMIC R1", NULL, "Remote DMICs"},
80 {"DMIC L2", NULL, "Local DMICs"},
81 {"DMIC R2", NULL, "Local DMICs"},
82
83 /* CODEC BE connections */
84 {"SSP0 CODEC IN", NULL, "AIF1 Capture"},
85 {"AIF1 Playback", NULL, "SSP0 CODEC OUT"},
86};
87
88static const struct snd_kcontrol_new bdw_rt5677_controls[] = {
89 SOC_DAPM_PIN_SWITCH("Speaker"),
90 SOC_DAPM_PIN_SWITCH("Headphone"),
91 SOC_DAPM_PIN_SWITCH("Headset Mic"),
92 SOC_DAPM_PIN_SWITCH("Local DMICs"),
93 SOC_DAPM_PIN_SWITCH("Remote DMICs"),
94};
95
96
97static struct snd_soc_jack headphone_jack;
98static struct snd_soc_jack mic_jack;
99
100static struct snd_soc_jack_pin headphone_jack_pin = {
101 .pin = "Headphone",
102 .mask = SND_JACK_HEADPHONE,
103};
104
105static struct snd_soc_jack_pin mic_jack_pin = {
106 .pin = "Headset Mic",
107 .mask = SND_JACK_MICROPHONE,
108};
109
110static struct snd_soc_jack_gpio headphone_jack_gpio = {
111 .name = "plug-det",
112 .report = SND_JACK_HEADPHONE,
113 .debounce_time = 200,
114};
115
116static struct snd_soc_jack_gpio mic_jack_gpio = {
117 .name = "mic-present",
118 .report = SND_JACK_MICROPHONE,
119 .debounce_time = 200,
120 .invert = 1,
121};
122
123static int broadwell_ssp0_fixup(struct snd_soc_pcm_runtime *rtd,
124 struct snd_pcm_hw_params *params)
125{
126 struct snd_interval *rate = hw_param_interval(params,
127 SNDRV_PCM_HW_PARAM_RATE);
128 struct snd_interval *channels = hw_param_interval(params,
129 SNDRV_PCM_HW_PARAM_CHANNELS);
130
131 /* The ADSP will covert the FE rate to 48k, stereo */
132 rate->min = rate->max = 48000;
133 channels->min = channels->max = 2;
134
135 /* set SSP0 to 16 bit */
136 snd_mask_set(&params->masks[SNDRV_PCM_HW_PARAM_FORMAT -
137 SNDRV_PCM_HW_PARAM_FIRST_MASK],
138 SNDRV_PCM_FORMAT_S16_LE);
139 return 0;
140}
141
142static int bdw_rt5677_hw_params(struct snd_pcm_substream *substream,
143 struct snd_pcm_hw_params *params)
144{
145 struct snd_soc_pcm_runtime *rtd = substream->private_data;
146 struct snd_soc_dai *codec_dai = rtd->codec_dai;
147 int ret;
148
149 ret = snd_soc_dai_set_sysclk(codec_dai, RT5677_SCLK_S_MCLK, 24576000,
150 SND_SOC_CLOCK_IN);
151 if (ret < 0) {
152 dev_err(rtd->dev, "can't set codec sysclk configuration\n");
153 return ret;
154 }
155
156 return ret;
157}
158
159static struct snd_soc_ops bdw_rt5677_ops = {
160 .hw_params = bdw_rt5677_hw_params,
161};
162
163static int bdw_rt5677_rtd_init(struct snd_soc_pcm_runtime *rtd)
164{
165 struct sst_pdata *pdata = dev_get_platdata(rtd->platform->dev);
166 struct sst_hsw *broadwell = pdata->dsp;
167 int ret;
168
169 /* Set ADSP SSP port settings */
170 ret = sst_hsw_device_set_config(broadwell, SST_HSW_DEVICE_SSP_0,
171 SST_HSW_DEVICE_MCLK_FREQ_24_MHZ,
172 SST_HSW_DEVICE_CLOCK_MASTER, 9);
173 if (ret < 0) {
174 dev_err(rtd->dev, "error: failed to set device config\n");
175 return ret;
176 }
177
178 return 0;
179}
180
181static int bdw_rt5677_init(struct snd_soc_pcm_runtime *rtd)
182{
183 struct bdw_rt5677_priv *bdw_rt5677 =
184 snd_soc_card_get_drvdata(rtd->card);
185 struct snd_soc_codec *codec = rtd->codec;
186 struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
187
188 /* Enable codec ASRC function for Stereo DAC/Stereo1 ADC/DMIC/I2S1.
189 * The ASRC clock source is clk_i2s1_asrc.
190 */
191 rt5677_sel_asrc_clk_src(codec, RT5677_DA_STEREO_FILTER |
192 RT5677_AD_STEREO1_FILTER | RT5677_I2S1_SOURCE,
193 RT5677_CLK_SEL_I2S1_ASRC);
194
195 /* Request rt5677 GPIO for headphone amp control */
196 bdw_rt5677->gpio_hp_en = devm_gpiod_get_index(codec->dev,
197 "headphone-enable", 0, 0);
198 if (IS_ERR(bdw_rt5677->gpio_hp_en)) {
199 dev_err(codec->dev, "Can't find HP_AMP_SHDN_L gpio\n");
200 return PTR_ERR(bdw_rt5677->gpio_hp_en);
201 }
202 gpiod_direction_output(bdw_rt5677->gpio_hp_en, 0);
203
204 /* Create and initialize headphone jack */
205 if (!snd_soc_card_jack_new(rtd->card, "Headphone Jack",
206 SND_JACK_HEADPHONE, &headphone_jack,
207 &headphone_jack_pin, 1)) {
208 headphone_jack_gpio.gpiod_dev = codec->dev;
209 if (snd_soc_jack_add_gpios(&headphone_jack, 1,
210 &headphone_jack_gpio))
211 dev_err(codec->dev, "Can't add headphone jack gpio\n");
212 } else {
213 dev_err(codec->dev, "Can't create headphone jack\n");
214 }
215
216 /* Create and initialize mic jack */
217 if (!snd_soc_card_jack_new(rtd->card, "Mic Jack",
218 SND_JACK_MICROPHONE, &mic_jack,
219 &mic_jack_pin, 1)) {
220 mic_jack_gpio.gpiod_dev = codec->dev;
221 if (snd_soc_jack_add_gpios(&mic_jack, 1, &mic_jack_gpio))
222 dev_err(codec->dev, "Can't add mic jack gpio\n");
223 } else {
224 dev_err(codec->dev, "Can't create mic jack\n");
225 }
226 bdw_rt5677->codec = codec;
227
228 snd_soc_dapm_force_enable_pin(dapm, "MICBIAS1");
229 return 0;
230}
231
232/* broadwell digital audio interface glue - connects codec <--> CPU */
233static struct snd_soc_dai_link bdw_rt5677_dais[] = {
234 /* Front End DAI links */
235 {
236 .name = "System PCM",
237 .stream_name = "System Playback/Capture",
238 .cpu_dai_name = "System Pin",
239 .platform_name = "haswell-pcm-audio",
240 .dynamic = 1,
241 .codec_name = "snd-soc-dummy",
242 .codec_dai_name = "snd-soc-dummy-dai",
243 .init = bdw_rt5677_rtd_init,
244 .trigger = {
245 SND_SOC_DPCM_TRIGGER_POST,
246 SND_SOC_DPCM_TRIGGER_POST
247 },
248 .dpcm_capture = 1,
249 .dpcm_playback = 1,
250 },
251
252 /* Back End DAI links */
253 {
254 /* SSP0 - Codec */
255 .name = "Codec",
256 .id = 0,
257 .cpu_dai_name = "snd-soc-dummy-dai",
258 .platform_name = "snd-soc-dummy",
259 .no_pcm = 1,
260 .codec_name = "i2c-RT5677CE:00",
261 .codec_dai_name = "rt5677-aif1",
262 .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
263 SND_SOC_DAIFMT_CBS_CFS,
264 .ignore_suspend = 1,
265 .ignore_pmdown_time = 1,
266 .be_hw_params_fixup = broadwell_ssp0_fixup,
267 .ops = &bdw_rt5677_ops,
268 .dpcm_playback = 1,
269 .dpcm_capture = 1,
270 .init = bdw_rt5677_init,
271 },
272};
273
274static int bdw_rt5677_suspend_pre(struct snd_soc_card *card)
275{
276 struct bdw_rt5677_priv *bdw_rt5677 = snd_soc_card_get_drvdata(card);
277 struct snd_soc_dapm_context *dapm;
278
279 if (bdw_rt5677->codec) {
280 dapm = snd_soc_codec_get_dapm(bdw_rt5677->codec);
281 snd_soc_dapm_disable_pin(dapm, "MICBIAS1");
282 }
283 return 0;
284}
285
286static int bdw_rt5677_resume_post(struct snd_soc_card *card)
287{
288 struct bdw_rt5677_priv *bdw_rt5677 = snd_soc_card_get_drvdata(card);
289 struct snd_soc_dapm_context *dapm;
290
291 if (bdw_rt5677->codec) {
292 dapm = snd_soc_codec_get_dapm(bdw_rt5677->codec);
293 snd_soc_dapm_force_enable_pin(dapm, "MICBIAS1");
294 }
295 return 0;
296}
297
298/* ASoC machine driver for Broadwell DSP + RT5677 */
299static struct snd_soc_card bdw_rt5677_card = {
300 .name = "bdw-rt5677",
301 .owner = THIS_MODULE,
302 .dai_link = bdw_rt5677_dais,
303 .num_links = ARRAY_SIZE(bdw_rt5677_dais),
304 .dapm_widgets = bdw_rt5677_widgets,
305 .num_dapm_widgets = ARRAY_SIZE(bdw_rt5677_widgets),
306 .dapm_routes = bdw_rt5677_map,
307 .num_dapm_routes = ARRAY_SIZE(bdw_rt5677_map),
308 .controls = bdw_rt5677_controls,
309 .num_controls = ARRAY_SIZE(bdw_rt5677_controls),
310 .fully_routed = true,
311 .suspend_pre = bdw_rt5677_suspend_pre,
312 .resume_post = bdw_rt5677_resume_post,
313};
314
315static int bdw_rt5677_probe(struct platform_device *pdev)
316{
317 struct bdw_rt5677_priv *bdw_rt5677;
318
319 bdw_rt5677_card.dev = &pdev->dev;
320
321 /* Allocate driver private struct */
322 bdw_rt5677 = devm_kzalloc(&pdev->dev, sizeof(struct bdw_rt5677_priv),
323 GFP_KERNEL);
324 if (!bdw_rt5677) {
325 dev_err(&pdev->dev, "Can't allocate bdw_rt5677\n");
326 return -ENOMEM;
327 }
328
329 snd_soc_card_set_drvdata(&bdw_rt5677_card, bdw_rt5677);
330
331 return devm_snd_soc_register_card(&pdev->dev, &bdw_rt5677_card);
332}
333
334static struct platform_driver bdw_rt5677_audio = {
335 .probe = bdw_rt5677_probe,
336 .driver = {
337 .name = "bdw-rt5677",
338 },
339};
340
341module_platform_driver(bdw_rt5677_audio)
342
343/* Module information */
344MODULE_AUTHOR("Ben Zhang");
345MODULE_DESCRIPTION("Intel Broadwell RT5677 machine driver");
346MODULE_LICENSE("GPL v2");
347MODULE_ALIAS("platform:bdw-rt5677");
diff --git a/sound/soc/intel/boards/bxt_da7219_max98357a.c b/sound/soc/intel/boards/bxt_da7219_max98357a.c
index 3774b117d365..6532b8f0ab2f 100644
--- a/sound/soc/intel/boards/bxt_da7219_max98357a.c
+++ b/sound/soc/intel/boards/bxt_da7219_max98357a.c
@@ -37,6 +37,7 @@ enum {
37 BXT_DPCM_AUDIO_PB = 0, 37 BXT_DPCM_AUDIO_PB = 0,
38 BXT_DPCM_AUDIO_CP, 38 BXT_DPCM_AUDIO_CP,
39 BXT_DPCM_AUDIO_REF_CP, 39 BXT_DPCM_AUDIO_REF_CP,
40 BXT_DPCM_AUDIO_DMIC_CP,
40 BXT_DPCM_AUDIO_HDMI1_PB, 41 BXT_DPCM_AUDIO_HDMI1_PB,
41 BXT_DPCM_AUDIO_HDMI2_PB, 42 BXT_DPCM_AUDIO_HDMI2_PB,
42 BXT_DPCM_AUDIO_HDMI3_PB, 43 BXT_DPCM_AUDIO_HDMI3_PB,
@@ -252,10 +253,56 @@ static struct snd_soc_ops broxton_da7219_ops = {
252 .hw_free = broxton_da7219_hw_free, 253 .hw_free = broxton_da7219_hw_free,
253}; 254};
254 255
256static int broxton_dmic_fixup(struct snd_soc_pcm_runtime *rtd,
257 struct snd_pcm_hw_params *params)
258{
259 struct snd_interval *channels = hw_param_interval(params,
260 SNDRV_PCM_HW_PARAM_CHANNELS);
261 channels->min = channels->max = DUAL_CHANNEL;
262
263 return 0;
264}
265
266static int broxton_dmic_startup(struct snd_pcm_substream *substream)
267{
268 struct snd_pcm_runtime *runtime = substream->runtime;
269
270 runtime->hw.channels_max = DUAL_CHANNEL;
271 snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
272 &constraints_channels);
273
274 return snd_pcm_hw_constraint_list(substream->runtime, 0,
275 SNDRV_PCM_HW_PARAM_RATE, &constraints_rates);
276}
277
278static const struct snd_soc_ops broxton_dmic_ops = {
279 .startup = broxton_dmic_startup,
280};
281
282static const unsigned int rates_16000[] = {
283 16000,
284};
285
286static const struct snd_pcm_hw_constraint_list constraints_16000 = {
287 .count = ARRAY_SIZE(rates_16000),
288 .list = rates_16000,
289};
290
291static int broxton_refcap_startup(struct snd_pcm_substream *substream)
292{
293 return snd_pcm_hw_constraint_list(substream->runtime, 0,
294 SNDRV_PCM_HW_PARAM_RATE,
295 &constraints_16000);
296};
297
298static struct snd_soc_ops broxton_refcap_ops = {
299 .startup = broxton_refcap_startup,
300};
301
255/* broxton digital audio interface glue - connects codec <--> CPU */ 302/* broxton digital audio interface glue - connects codec <--> CPU */
256static struct snd_soc_dai_link broxton_dais[] = { 303static struct snd_soc_dai_link broxton_dais[] = {
257 /* Front End DAI links */ 304 /* Front End DAI links */
258 [BXT_DPCM_AUDIO_PB] 305 [BXT_DPCM_AUDIO_PB] =
259 { 306 {
260 .name = "Bxt Audio Port", 307 .name = "Bxt Audio Port",
261 .stream_name = "Audio", 308 .stream_name = "Audio",
@@ -271,7 +318,7 @@ static struct snd_soc_dai_link broxton_dais[] = {
271 .dpcm_playback = 1, 318 .dpcm_playback = 1,
272 .ops = &broxton_da7219_fe_ops, 319 .ops = &broxton_da7219_fe_ops,
273 }, 320 },
274 [BXT_DPCM_AUDIO_CP] 321 [BXT_DPCM_AUDIO_CP] =
275 { 322 {
276 .name = "Bxt Audio Capture Port", 323 .name = "Bxt Audio Capture Port",
277 .stream_name = "Audio Record", 324 .stream_name = "Audio Record",
@@ -286,7 +333,7 @@ static struct snd_soc_dai_link broxton_dais[] = {
286 .dpcm_capture = 1, 333 .dpcm_capture = 1,
287 .ops = &broxton_da7219_fe_ops, 334 .ops = &broxton_da7219_fe_ops,
288 }, 335 },
289 [BXT_DPCM_AUDIO_REF_CP] 336 [BXT_DPCM_AUDIO_REF_CP] =
290 { 337 {
291 .name = "Bxt Audio Reference cap", 338 .name = "Bxt Audio Reference cap",
292 .stream_name = "Refcap", 339 .stream_name = "Refcap",
@@ -299,8 +346,23 @@ static struct snd_soc_dai_link broxton_dais[] = {
299 .ignore_suspend = 1, 346 .ignore_suspend = 1,
300 .nonatomic = 1, 347 .nonatomic = 1,
301 .dynamic = 1, 348 .dynamic = 1,
349 .ops = &broxton_refcap_ops,
350 },
351 [BXT_DPCM_AUDIO_DMIC_CP]
352 {
353 .name = "Bxt Audio DMIC cap",
354 .stream_name = "dmiccap",
355 .cpu_dai_name = "DMIC Pin",
356 .codec_name = "snd-soc-dummy",
357 .codec_dai_name = "snd-soc-dummy-dai",
358 .platform_name = "0000:00:0e.0",
359 .init = NULL,
360 .dpcm_capture = 1,
361 .nonatomic = 1,
362 .dynamic = 1,
363 .ops = &broxton_dmic_ops,
302 }, 364 },
303 [BXT_DPCM_AUDIO_HDMI1_PB] 365 [BXT_DPCM_AUDIO_HDMI1_PB] =
304 { 366 {
305 .name = "Bxt HDMI Port1", 367 .name = "Bxt HDMI Port1",
306 .stream_name = "Hdmi1", 368 .stream_name = "Hdmi1",
@@ -313,7 +375,7 @@ static struct snd_soc_dai_link broxton_dais[] = {
313 .nonatomic = 1, 375 .nonatomic = 1,
314 .dynamic = 1, 376 .dynamic = 1,
315 }, 377 },
316 [BXT_DPCM_AUDIO_HDMI2_PB] 378 [BXT_DPCM_AUDIO_HDMI2_PB] =
317 { 379 {
318 .name = "Bxt HDMI Port2", 380 .name = "Bxt HDMI Port2",
319 .stream_name = "Hdmi2", 381 .stream_name = "Hdmi2",
@@ -326,7 +388,7 @@ static struct snd_soc_dai_link broxton_dais[] = {
326 .nonatomic = 1, 388 .nonatomic = 1,
327 .dynamic = 1, 389 .dynamic = 1,
328 }, 390 },
329 [BXT_DPCM_AUDIO_HDMI3_PB] 391 [BXT_DPCM_AUDIO_HDMI3_PB] =
330 { 392 {
331 .name = "Bxt HDMI Port3", 393 .name = "Bxt HDMI Port3",
332 .stream_name = "Hdmi3", 394 .stream_name = "Hdmi3",
@@ -382,6 +444,7 @@ static struct snd_soc_dai_link broxton_dais[] = {
382 .codec_dai_name = "dmic-hifi", 444 .codec_dai_name = "dmic-hifi",
383 .platform_name = "0000:00:0e.0", 445 .platform_name = "0000:00:0e.0",
384 .ignore_suspend = 1, 446 .ignore_suspend = 1,
447 .be_hw_params_fixup = broxton_dmic_fixup,
385 .dpcm_capture = 1, 448 .dpcm_capture = 1,
386 .no_pcm = 1, 449 .no_pcm = 1,
387 }, 450 },
diff --git a/sound/soc/intel/boards/bxt_rt298.c b/sound/soc/intel/boards/bxt_rt298.c
index 253d7bfbf511..d610bdca1608 100644
--- a/sound/soc/intel/boards/bxt_rt298.c
+++ b/sound/soc/intel/boards/bxt_rt298.c
@@ -271,7 +271,7 @@ static const struct snd_soc_ops broxton_rt286_fe_ops = {
271/* broxton digital audio interface glue - connects codec <--> CPU */ 271/* broxton digital audio interface glue - connects codec <--> CPU */
272static struct snd_soc_dai_link broxton_rt298_dais[] = { 272static struct snd_soc_dai_link broxton_rt298_dais[] = {
273 /* Front End DAI links */ 273 /* Front End DAI links */
274 [BXT_DPCM_AUDIO_PB] 274 [BXT_DPCM_AUDIO_PB] =
275 { 275 {
276 .name = "Bxt Audio Port", 276 .name = "Bxt Audio Port",
277 .stream_name = "Audio", 277 .stream_name = "Audio",
@@ -286,7 +286,7 @@ static struct snd_soc_dai_link broxton_rt298_dais[] = {
286 .dpcm_playback = 1, 286 .dpcm_playback = 1,
287 .ops = &broxton_rt286_fe_ops, 287 .ops = &broxton_rt286_fe_ops,
288 }, 288 },
289 [BXT_DPCM_AUDIO_CP] 289 [BXT_DPCM_AUDIO_CP] =
290 { 290 {
291 .name = "Bxt Audio Capture Port", 291 .name = "Bxt Audio Capture Port",
292 .stream_name = "Audio Record", 292 .stream_name = "Audio Record",
@@ -300,7 +300,7 @@ static struct snd_soc_dai_link broxton_rt298_dais[] = {
300 .dpcm_capture = 1, 300 .dpcm_capture = 1,
301 .ops = &broxton_rt286_fe_ops, 301 .ops = &broxton_rt286_fe_ops,
302 }, 302 },
303 [BXT_DPCM_AUDIO_REF_CP] 303 [BXT_DPCM_AUDIO_REF_CP] =
304 { 304 {
305 .name = "Bxt Audio Reference cap", 305 .name = "Bxt Audio Reference cap",
306 .stream_name = "refcap", 306 .stream_name = "refcap",
@@ -313,7 +313,7 @@ static struct snd_soc_dai_link broxton_rt298_dais[] = {
313 .nonatomic = 1, 313 .nonatomic = 1,
314 .dynamic = 1, 314 .dynamic = 1,
315 }, 315 },
316 [BXT_DPCM_AUDIO_DMIC_CP] 316 [BXT_DPCM_AUDIO_DMIC_CP] =
317 { 317 {
318 .name = "Bxt Audio DMIC cap", 318 .name = "Bxt Audio DMIC cap",
319 .stream_name = "dmiccap", 319 .stream_name = "dmiccap",
@@ -327,7 +327,7 @@ static struct snd_soc_dai_link broxton_rt298_dais[] = {
327 .dynamic = 1, 327 .dynamic = 1,
328 .ops = &broxton_dmic_ops, 328 .ops = &broxton_dmic_ops,
329 }, 329 },
330 [BXT_DPCM_AUDIO_HDMI1_PB] 330 [BXT_DPCM_AUDIO_HDMI1_PB] =
331 { 331 {
332 .name = "Bxt HDMI Port1", 332 .name = "Bxt HDMI Port1",
333 .stream_name = "Hdmi1", 333 .stream_name = "Hdmi1",
@@ -340,7 +340,7 @@ static struct snd_soc_dai_link broxton_rt298_dais[] = {
340 .nonatomic = 1, 340 .nonatomic = 1,
341 .dynamic = 1, 341 .dynamic = 1,
342 }, 342 },
343 [BXT_DPCM_AUDIO_HDMI2_PB] 343 [BXT_DPCM_AUDIO_HDMI2_PB] =
344 { 344 {
345 .name = "Bxt HDMI Port2", 345 .name = "Bxt HDMI Port2",
346 .stream_name = "Hdmi2", 346 .stream_name = "Hdmi2",
@@ -353,7 +353,7 @@ static struct snd_soc_dai_link broxton_rt298_dais[] = {
353 .nonatomic = 1, 353 .nonatomic = 1,
354 .dynamic = 1, 354 .dynamic = 1,
355 }, 355 },
356 [BXT_DPCM_AUDIO_HDMI3_PB] 356 [BXT_DPCM_AUDIO_HDMI3_PB] =
357 { 357 {
358 .name = "Bxt HDMI Port3", 358 .name = "Bxt HDMI Port3",
359 .stream_name = "Hdmi3", 359 .stream_name = "Hdmi3",
diff --git a/sound/soc/intel/boards/bytcr_rt5640.c b/sound/soc/intel/boards/bytcr_rt5640.c
index 88efb62439ba..bff77a1f27fc 100644
--- a/sound/soc/intel/boards/bytcr_rt5640.c
+++ b/sound/soc/intel/boards/bytcr_rt5640.c
@@ -24,6 +24,9 @@
24#include <linux/device.h> 24#include <linux/device.h>
25#include <linux/dmi.h> 25#include <linux/dmi.h>
26#include <linux/slab.h> 26#include <linux/slab.h>
27#include <asm/cpu_device_id.h>
28#include <asm/platform_sst_audio.h>
29#include <linux/clk.h>
27#include <sound/pcm.h> 30#include <sound/pcm.h>
28#include <sound/pcm_params.h> 31#include <sound/pcm_params.h>
29#include <sound/soc.h> 32#include <sound/soc.h>
@@ -31,42 +34,153 @@
31#include "../../codecs/rt5640.h" 34#include "../../codecs/rt5640.h"
32#include "../atom/sst-atom-controls.h" 35#include "../atom/sst-atom-controls.h"
33#include "../common/sst-acpi.h" 36#include "../common/sst-acpi.h"
37#include "../common/sst-dsp.h"
34 38
35enum { 39enum {
36 BYT_RT5640_DMIC1_MAP, 40 BYT_RT5640_DMIC1_MAP,
37 BYT_RT5640_DMIC2_MAP, 41 BYT_RT5640_DMIC2_MAP,
38 BYT_RT5640_IN1_MAP, 42 BYT_RT5640_IN1_MAP,
43 BYT_RT5640_IN3_MAP,
39}; 44};
40 45
41#define BYT_RT5640_MAP(quirk) ((quirk) & 0xff) 46#define BYT_RT5640_MAP(quirk) ((quirk) & 0xff)
42#define BYT_RT5640_DMIC_EN BIT(16) 47#define BYT_RT5640_DMIC_EN BIT(16)
48#define BYT_RT5640_MONO_SPEAKER BIT(17)
49#define BYT_RT5640_DIFF_MIC BIT(18) /* defaut is single-ended */
50#define BYT_RT5640_SSP2_AIF2 BIT(19) /* default is using AIF1 */
51#define BYT_RT5640_SSP0_AIF1 BIT(20)
52#define BYT_RT5640_SSP0_AIF2 BIT(21)
53#define BYT_RT5640_MCLK_EN BIT(22)
54#define BYT_RT5640_MCLK_25MHZ BIT(23)
55
56struct byt_rt5640_private {
57 struct clk *mclk;
58};
43 59
44static unsigned long byt_rt5640_quirk = BYT_RT5640_DMIC1_MAP | 60static unsigned long byt_rt5640_quirk = BYT_RT5640_DMIC1_MAP |
45 BYT_RT5640_DMIC_EN; 61 BYT_RT5640_DMIC_EN |
62 BYT_RT5640_MCLK_EN;
63
64static void log_quirks(struct device *dev)
65{
66 if (BYT_RT5640_MAP(byt_rt5640_quirk) == BYT_RT5640_DMIC1_MAP)
67 dev_info(dev, "quirk DMIC1_MAP enabled");
68 if (BYT_RT5640_MAP(byt_rt5640_quirk) == BYT_RT5640_DMIC2_MAP)
69 dev_info(dev, "quirk DMIC2_MAP enabled");
70 if (BYT_RT5640_MAP(byt_rt5640_quirk) == BYT_RT5640_IN1_MAP)
71 dev_info(dev, "quirk IN1_MAP enabled");
72 if (BYT_RT5640_MAP(byt_rt5640_quirk) == BYT_RT5640_IN3_MAP)
73 dev_info(dev, "quirk IN3_MAP enabled");
74 if (byt_rt5640_quirk & BYT_RT5640_DMIC_EN)
75 dev_info(dev, "quirk DMIC enabled");
76 if (byt_rt5640_quirk & BYT_RT5640_MONO_SPEAKER)
77 dev_info(dev, "quirk MONO_SPEAKER enabled");
78 if (byt_rt5640_quirk & BYT_RT5640_DIFF_MIC)
79 dev_info(dev, "quirk DIFF_MIC enabled");
80 if (byt_rt5640_quirk & BYT_RT5640_SSP2_AIF2)
81 dev_info(dev, "quirk SSP2_AIF2 enabled");
82 if (byt_rt5640_quirk & BYT_RT5640_SSP0_AIF1)
83 dev_info(dev, "quirk SSP0_AIF1 enabled");
84 if (byt_rt5640_quirk & BYT_RT5640_SSP0_AIF2)
85 dev_info(dev, "quirk SSP0_AIF2 enabled");
86 if (byt_rt5640_quirk & BYT_RT5640_MCLK_EN)
87 dev_info(dev, "quirk MCLK_EN enabled");
88 if (byt_rt5640_quirk & BYT_RT5640_MCLK_25MHZ)
89 dev_info(dev, "quirk MCLK_25MHZ enabled");
90}
91
92
93#define BYT_CODEC_DAI1 "rt5640-aif1"
94#define BYT_CODEC_DAI2 "rt5640-aif2"
95
96static inline struct snd_soc_dai *byt_get_codec_dai(struct snd_soc_card *card)
97{
98 struct snd_soc_pcm_runtime *rtd;
99
100 list_for_each_entry(rtd, &card->rtd_list, list) {
101 if (!strncmp(rtd->codec_dai->name, BYT_CODEC_DAI1,
102 strlen(BYT_CODEC_DAI1)))
103 return rtd->codec_dai;
104 if (!strncmp(rtd->codec_dai->name, BYT_CODEC_DAI2,
105 strlen(BYT_CODEC_DAI2)))
106 return rtd->codec_dai;
107
108 }
109 return NULL;
110}
111
112static int platform_clock_control(struct snd_soc_dapm_widget *w,
113 struct snd_kcontrol *k, int event)
114{
115 struct snd_soc_dapm_context *dapm = w->dapm;
116 struct snd_soc_card *card = dapm->card;
117 struct snd_soc_dai *codec_dai;
118 struct byt_rt5640_private *priv = snd_soc_card_get_drvdata(card);
119 int ret;
120
121 codec_dai = byt_get_codec_dai(card);
122 if (!codec_dai) {
123 dev_err(card->dev,
124 "Codec dai not found; Unable to set platform clock\n");
125 return -EIO;
126 }
127
128 if (SND_SOC_DAPM_EVENT_ON(event)) {
129 if ((byt_rt5640_quirk & BYT_RT5640_MCLK_EN) && priv->mclk) {
130 ret = clk_prepare_enable(priv->mclk);
131 if (ret < 0) {
132 dev_err(card->dev,
133 "could not configure MCLK state");
134 return ret;
135 }
136 }
137 ret = snd_soc_dai_set_sysclk(codec_dai, RT5640_SCLK_S_PLL1,
138 48000 * 512,
139 SND_SOC_CLOCK_IN);
140 } else {
141 /*
142 * Set codec clock source to internal clock before
143 * turning off the platform clock. Codec needs clock
144 * for Jack detection and button press
145 */
146 ret = snd_soc_dai_set_sysclk(codec_dai, RT5640_SCLK_S_RCCLK,
147 0,
148 SND_SOC_CLOCK_IN);
149 if (!ret) {
150 if ((byt_rt5640_quirk & BYT_RT5640_MCLK_EN) && priv->mclk)
151 clk_disable_unprepare(priv->mclk);
152 }
153 }
154
155 if (ret < 0) {
156 dev_err(card->dev, "can't set codec sysclk: %d\n", ret);
157 return ret;
158 }
159
160 return 0;
161}
46 162
47static const struct snd_soc_dapm_widget byt_rt5640_widgets[] = { 163static const struct snd_soc_dapm_widget byt_rt5640_widgets[] = {
48 SND_SOC_DAPM_HP("Headphone", NULL), 164 SND_SOC_DAPM_HP("Headphone", NULL),
49 SND_SOC_DAPM_MIC("Headset Mic", NULL), 165 SND_SOC_DAPM_MIC("Headset Mic", NULL),
50 SND_SOC_DAPM_MIC("Internal Mic", NULL), 166 SND_SOC_DAPM_MIC("Internal Mic", NULL),
51 SND_SOC_DAPM_SPK("Speaker", NULL), 167 SND_SOC_DAPM_SPK("Speaker", NULL),
168 SND_SOC_DAPM_SUPPLY("Platform Clock", SND_SOC_NOPM, 0, 0,
169 platform_clock_control, SND_SOC_DAPM_PRE_PMU |
170 SND_SOC_DAPM_POST_PMD),
171
52}; 172};
53 173
54static const struct snd_soc_dapm_route byt_rt5640_audio_map[] = { 174static const struct snd_soc_dapm_route byt_rt5640_audio_map[] = {
55 {"AIF1 Playback", NULL, "ssp2 Tx"}, 175 {"Headphone", NULL, "Platform Clock"},
56 {"ssp2 Tx", NULL, "codec_out0"}, 176 {"Headset Mic", NULL, "Platform Clock"},
57 {"ssp2 Tx", NULL, "codec_out1"}, 177 {"Internal Mic", NULL, "Platform Clock"},
58 {"codec_in0", NULL, "ssp2 Rx"}, 178 {"Speaker", NULL, "Platform Clock"},
59 {"codec_in1", NULL, "ssp2 Rx"},
60 {"ssp2 Rx", NULL, "AIF1 Capture"},
61 179
62 {"Headset Mic", NULL, "MICBIAS1"}, 180 {"Headset Mic", NULL, "MICBIAS1"},
63 {"IN2P", NULL, "Headset Mic"}, 181 {"IN2P", NULL, "Headset Mic"},
64 {"Headphone", NULL, "HPOL"}, 182 {"Headphone", NULL, "HPOL"},
65 {"Headphone", NULL, "HPOR"}, 183 {"Headphone", NULL, "HPOR"},
66 {"Speaker", NULL, "SPOLP"},
67 {"Speaker", NULL, "SPOLN"},
68 {"Speaker", NULL, "SPORP"},
69 {"Speaker", NULL, "SPORN"},
70}; 184};
71 185
72static const struct snd_soc_dapm_route byt_rt5640_intmic_dmic1_map[] = { 186static const struct snd_soc_dapm_route byt_rt5640_intmic_dmic1_map[] = {
@@ -82,6 +196,59 @@ static const struct snd_soc_dapm_route byt_rt5640_intmic_in1_map[] = {
82 {"IN1P", NULL, "Internal Mic"}, 196 {"IN1P", NULL, "Internal Mic"},
83}; 197};
84 198
199static const struct snd_soc_dapm_route byt_rt5640_intmic_in3_map[] = {
200 {"Internal Mic", NULL, "MICBIAS1"},
201 {"IN3P", NULL, "Internal Mic"},
202};
203
204static const struct snd_soc_dapm_route byt_rt5640_ssp2_aif1_map[] = {
205 {"ssp2 Tx", NULL, "codec_out0"},
206 {"ssp2 Tx", NULL, "codec_out1"},
207 {"codec_in0", NULL, "ssp2 Rx"},
208 {"codec_in1", NULL, "ssp2 Rx"},
209
210 {"AIF1 Playback", NULL, "ssp2 Tx"},
211 {"ssp2 Rx", NULL, "AIF1 Capture"},
212};
213
214static const struct snd_soc_dapm_route byt_rt5640_ssp2_aif2_map[] = {
215 {"ssp2 Tx", NULL, "codec_out0"},
216 {"ssp2 Tx", NULL, "codec_out1"},
217 {"codec_in0", NULL, "ssp2 Rx"},
218 {"codec_in1", NULL, "ssp2 Rx"},
219
220 {"AIF2 Playback", NULL, "ssp2 Tx"},
221 {"ssp2 Rx", NULL, "AIF2 Capture"},
222};
223
224static const struct snd_soc_dapm_route byt_rt5640_ssp0_aif1_map[] = {
225 {"ssp0 Tx", NULL, "modem_out"},
226 {"modem_in", NULL, "ssp0 Rx"},
227
228 {"AIF1 Playback", NULL, "ssp0 Tx"},
229 {"ssp0 Rx", NULL, "AIF1 Capture"},
230};
231
232static const struct snd_soc_dapm_route byt_rt5640_ssp0_aif2_map[] = {
233 {"ssp0 Tx", NULL, "modem_out"},
234 {"modem_in", NULL, "ssp0 Rx"},
235
236 {"AIF2 Playback", NULL, "ssp0 Tx"},
237 {"ssp0 Rx", NULL, "AIF2 Capture"},
238};
239
240static const struct snd_soc_dapm_route byt_rt5640_stereo_spk_map[] = {
241 {"Speaker", NULL, "SPOLP"},
242 {"Speaker", NULL, "SPOLN"},
243 {"Speaker", NULL, "SPORP"},
244 {"Speaker", NULL, "SPORN"},
245};
246
247static const struct snd_soc_dapm_route byt_rt5640_mono_spk_map[] = {
248 {"Speaker", NULL, "SPOLP"},
249 {"Speaker", NULL, "SPOLN"},
250};
251
85static const struct snd_kcontrol_new byt_rt5640_controls[] = { 252static const struct snd_kcontrol_new byt_rt5640_controls[] = {
86 SOC_DAPM_PIN_SWITCH("Headphone"), 253 SOC_DAPM_PIN_SWITCH("Headphone"),
87 SOC_DAPM_PIN_SWITCH("Headset Mic"), 254 SOC_DAPM_PIN_SWITCH("Headset Mic"),
@@ -96,19 +263,46 @@ static int byt_rt5640_aif1_hw_params(struct snd_pcm_substream *substream,
96 struct snd_soc_dai *codec_dai = rtd->codec_dai; 263 struct snd_soc_dai *codec_dai = rtd->codec_dai;
97 int ret; 264 int ret;
98 265
99 snd_soc_dai_set_bclk_ratio(codec_dai, 50);
100
101 ret = snd_soc_dai_set_sysclk(codec_dai, RT5640_SCLK_S_PLL1, 266 ret = snd_soc_dai_set_sysclk(codec_dai, RT5640_SCLK_S_PLL1,
102 params_rate(params) * 512, 267 params_rate(params) * 512,
103 SND_SOC_CLOCK_IN); 268 SND_SOC_CLOCK_IN);
269
104 if (ret < 0) { 270 if (ret < 0) {
105 dev_err(rtd->dev, "can't set codec clock %d\n", ret); 271 dev_err(rtd->dev, "can't set codec clock %d\n", ret);
106 return ret; 272 return ret;
107 } 273 }
108 274
109 ret = snd_soc_dai_set_pll(codec_dai, 0, RT5640_PLL1_S_BCLK1, 275 if (!(byt_rt5640_quirk & BYT_RT5640_MCLK_EN)) {
110 params_rate(params) * 50, 276 /* use bitclock as PLL input */
111 params_rate(params) * 512); 277 if ((byt_rt5640_quirk & BYT_RT5640_SSP0_AIF1) ||
278 (byt_rt5640_quirk & BYT_RT5640_SSP0_AIF2)) {
279
280 /* 2x16 bit slots on SSP0 */
281 ret = snd_soc_dai_set_pll(codec_dai, 0,
282 RT5640_PLL1_S_BCLK1,
283 params_rate(params) * 32,
284 params_rate(params) * 512);
285 } else {
286 /* 2x15 bit slots on SSP2 */
287 ret = snd_soc_dai_set_pll(codec_dai, 0,
288 RT5640_PLL1_S_BCLK1,
289 params_rate(params) * 50,
290 params_rate(params) * 512);
291 }
292 } else {
293 if (byt_rt5640_quirk & BYT_RT5640_MCLK_25MHZ) {
294 ret = snd_soc_dai_set_pll(codec_dai, 0,
295 RT5640_PLL1_S_MCLK,
296 25000000,
297 params_rate(params) * 512);
298 } else {
299 ret = snd_soc_dai_set_pll(codec_dai, 0,
300 RT5640_PLL1_S_MCLK,
301 19200000,
302 params_rate(params) * 512);
303 }
304 }
305
112 if (ret < 0) { 306 if (ret < 0) {
113 dev_err(rtd->dev, "can't set codec pll: %d\n", ret); 307 dev_err(rtd->dev, "can't set codec pll: %d\n", ret);
114 return ret; 308 return ret;
@@ -127,27 +321,73 @@ static const struct dmi_system_id byt_rt5640_quirk_table[] = {
127 { 321 {
128 .callback = byt_rt5640_quirk_cb, 322 .callback = byt_rt5640_quirk_cb,
129 .matches = { 323 .matches = {
130 DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), 324 DMI_EXACT_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
131 DMI_MATCH(DMI_PRODUCT_NAME, "T100TA"), 325 DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "T100TA"),
326 },
327 .driver_data = (unsigned long *)(BYT_RT5640_IN1_MAP |
328 BYT_RT5640_MCLK_EN),
329 },
330 {
331 .callback = byt_rt5640_quirk_cb,
332 .matches = {
333 DMI_EXACT_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
334 DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "T100TAF"),
132 }, 335 },
133 .driver_data = (unsigned long *)BYT_RT5640_IN1_MAP, 336 .driver_data = (unsigned long *)(BYT_RT5640_IN1_MAP |
337 BYT_RT5640_MONO_SPEAKER |
338 BYT_RT5640_DIFF_MIC |
339 BYT_RT5640_SSP0_AIF2 |
340 BYT_RT5640_MCLK_EN
341 ),
134 }, 342 },
135 { 343 {
136 .callback = byt_rt5640_quirk_cb, 344 .callback = byt_rt5640_quirk_cb,
137 .matches = { 345 .matches = {
138 DMI_MATCH(DMI_SYS_VENDOR, "DellInc."), 346 DMI_EXACT_MATCH(DMI_SYS_VENDOR, "DellInc."),
139 DMI_MATCH(DMI_PRODUCT_NAME, "Venue 8 Pro 5830"), 347 DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Venue 8 Pro 5830"),
140 }, 348 },
141 .driver_data = (unsigned long *)(BYT_RT5640_DMIC2_MAP | 349 .driver_data = (unsigned long *)(BYT_RT5640_DMIC2_MAP |
350 BYT_RT5640_DMIC_EN |
351 BYT_RT5640_MCLK_EN),
352 },
353 {
354 .callback = byt_rt5640_quirk_cb,
355 .matches = {
356 DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
357 DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "HP ElitePad 1000 G2"),
358 },
359 .driver_data = (unsigned long *)(BYT_RT5640_IN1_MAP |
360 BYT_RT5640_MCLK_EN),
361 },
362 {
363 .callback = byt_rt5640_quirk_cb,
364 .matches = {
365 DMI_MATCH(DMI_SYS_VENDOR, "Circuitco"),
366 DMI_MATCH(DMI_PRODUCT_NAME, "Minnowboard Max B3 PLATFORM"),
367 },
368 .driver_data = (unsigned long *)(BYT_RT5640_DMIC1_MAP |
142 BYT_RT5640_DMIC_EN), 369 BYT_RT5640_DMIC_EN),
143 }, 370 },
144 { 371 {
145 .callback = byt_rt5640_quirk_cb, 372 .callback = byt_rt5640_quirk_cb,
146 .matches = { 373 .matches = {
147 DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), 374 DMI_MATCH(DMI_BOARD_VENDOR, "TECLAST"),
148 DMI_MATCH(DMI_PRODUCT_NAME, "HP ElitePad 1000 G2"), 375 DMI_MATCH(DMI_BOARD_NAME, "tPAD"),
149 }, 376 },
150 .driver_data = (unsigned long *)BYT_RT5640_IN1_MAP, 377 .driver_data = (unsigned long *)(BYT_RT5640_IN3_MAP |
378 BYT_RT5640_MCLK_EN |
379 BYT_RT5640_SSP0_AIF1),
380 },
381 {
382 .callback = byt_rt5640_quirk_cb,
383 .matches = {
384 DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
385 DMI_MATCH(DMI_PRODUCT_NAME, "Aspire SW5-012"),
386 },
387 .driver_data = (unsigned long *)(BYT_RT5640_IN1_MAP |
388 BYT_RT5640_MCLK_EN |
389 BYT_RT5640_SSP0_AIF1),
390
151 }, 391 },
152 {} 392 {}
153}; 393};
@@ -158,13 +398,18 @@ static int byt_rt5640_init(struct snd_soc_pcm_runtime *runtime)
158 struct snd_soc_codec *codec = runtime->codec; 398 struct snd_soc_codec *codec = runtime->codec;
159 struct snd_soc_card *card = runtime->card; 399 struct snd_soc_card *card = runtime->card;
160 const struct snd_soc_dapm_route *custom_map; 400 const struct snd_soc_dapm_route *custom_map;
401 struct byt_rt5640_private *priv = snd_soc_card_get_drvdata(card);
161 int num_routes; 402 int num_routes;
162 403
163 card->dapm.idle_bias_off = true; 404 card->dapm.idle_bias_off = true;
164 405
165 rt5640_sel_asrc_clk_src(codec, 406 rt5640_sel_asrc_clk_src(codec,
166 RT5640_DA_STEREO_FILTER | 407 RT5640_DA_STEREO_FILTER |
167 RT5640_AD_STEREO_FILTER, 408 RT5640_DA_MONO_L_FILTER |
409 RT5640_DA_MONO_R_FILTER |
410 RT5640_AD_STEREO_FILTER |
411 RT5640_AD_MONO_L_FILTER |
412 RT5640_AD_MONO_R_FILTER,
168 RT5640_CLK_SEL_ASRC); 413 RT5640_CLK_SEL_ASRC);
169 414
170 ret = snd_soc_add_card_controls(card, byt_rt5640_controls, 415 ret = snd_soc_add_card_controls(card, byt_rt5640_controls,
@@ -179,6 +424,10 @@ static int byt_rt5640_init(struct snd_soc_pcm_runtime *runtime)
179 custom_map = byt_rt5640_intmic_in1_map; 424 custom_map = byt_rt5640_intmic_in1_map;
180 num_routes = ARRAY_SIZE(byt_rt5640_intmic_in1_map); 425 num_routes = ARRAY_SIZE(byt_rt5640_intmic_in1_map);
181 break; 426 break;
427 case BYT_RT5640_IN3_MAP:
428 custom_map = byt_rt5640_intmic_in3_map;
429 num_routes = ARRAY_SIZE(byt_rt5640_intmic_in3_map);
430 break;
182 case BYT_RT5640_DMIC2_MAP: 431 case BYT_RT5640_DMIC2_MAP:
183 custom_map = byt_rt5640_intmic_dmic2_map; 432 custom_map = byt_rt5640_intmic_dmic2_map;
184 num_routes = ARRAY_SIZE(byt_rt5640_intmic_dmic2_map); 433 num_routes = ARRAY_SIZE(byt_rt5640_intmic_dmic2_map);
@@ -192,6 +441,43 @@ static int byt_rt5640_init(struct snd_soc_pcm_runtime *runtime)
192 if (ret) 441 if (ret)
193 return ret; 442 return ret;
194 443
444 if (byt_rt5640_quirk & BYT_RT5640_SSP2_AIF2) {
445 ret = snd_soc_dapm_add_routes(&card->dapm,
446 byt_rt5640_ssp2_aif2_map,
447 ARRAY_SIZE(byt_rt5640_ssp2_aif2_map));
448 } else if (byt_rt5640_quirk & BYT_RT5640_SSP0_AIF1) {
449 ret = snd_soc_dapm_add_routes(&card->dapm,
450 byt_rt5640_ssp0_aif1_map,
451 ARRAY_SIZE(byt_rt5640_ssp0_aif1_map));
452 } else if (byt_rt5640_quirk & BYT_RT5640_SSP0_AIF2) {
453 ret = snd_soc_dapm_add_routes(&card->dapm,
454 byt_rt5640_ssp0_aif2_map,
455 ARRAY_SIZE(byt_rt5640_ssp0_aif2_map));
456 } else {
457 ret = snd_soc_dapm_add_routes(&card->dapm,
458 byt_rt5640_ssp2_aif1_map,
459 ARRAY_SIZE(byt_rt5640_ssp2_aif1_map));
460 }
461 if (ret)
462 return ret;
463
464 if (byt_rt5640_quirk & BYT_RT5640_MONO_SPEAKER) {
465 ret = snd_soc_dapm_add_routes(&card->dapm,
466 byt_rt5640_mono_spk_map,
467 ARRAY_SIZE(byt_rt5640_mono_spk_map));
468 } else {
469 ret = snd_soc_dapm_add_routes(&card->dapm,
470 byt_rt5640_stereo_spk_map,
471 ARRAY_SIZE(byt_rt5640_stereo_spk_map));
472 }
473 if (ret)
474 return ret;
475
476 if (byt_rt5640_quirk & BYT_RT5640_DIFF_MIC) {
477 snd_soc_update_bits(codec, RT5640_IN1_IN2, RT5640_IN_DF1,
478 RT5640_IN_DF1);
479 }
480
195 if (byt_rt5640_quirk & BYT_RT5640_DMIC_EN) { 481 if (byt_rt5640_quirk & BYT_RT5640_DMIC_EN) {
196 ret = rt5640_dmic_enable(codec, 0, 0); 482 ret = rt5640_dmic_enable(codec, 0, 0);
197 if (ret) 483 if (ret)
@@ -201,6 +487,30 @@ static int byt_rt5640_init(struct snd_soc_pcm_runtime *runtime)
201 snd_soc_dapm_ignore_suspend(&card->dapm, "Headphone"); 487 snd_soc_dapm_ignore_suspend(&card->dapm, "Headphone");
202 snd_soc_dapm_ignore_suspend(&card->dapm, "Speaker"); 488 snd_soc_dapm_ignore_suspend(&card->dapm, "Speaker");
203 489
490 if ((byt_rt5640_quirk & BYT_RT5640_MCLK_EN) && priv->mclk) {
491 /*
492 * The firmware might enable the clock at
493 * boot (this information may or may not
494 * be reflected in the enable clock register).
495 * To change the rate we must disable the clock
496 * first to cover these cases. Due to common
497 * clock framework restrictions that do not allow
498 * to disable a clock that has not been enabled,
499 * we need to enable the clock first.
500 */
501 ret = clk_prepare_enable(priv->mclk);
502 if (!ret)
503 clk_disable_unprepare(priv->mclk);
504
505 if (byt_rt5640_quirk & BYT_RT5640_MCLK_25MHZ)
506 ret = clk_set_rate(priv->mclk, 25000000);
507 else
508 ret = clk_set_rate(priv->mclk, 19200000);
509
510 if (ret)
511 dev_err(card->dev, "unable to set MCLK rate\n");
512 }
513
204 return ret; 514 return ret;
205} 515}
206 516
@@ -221,34 +531,63 @@ static int byt_rt5640_codec_fixup(struct snd_soc_pcm_runtime *rtd,
221 SNDRV_PCM_HW_PARAM_CHANNELS); 531 SNDRV_PCM_HW_PARAM_CHANNELS);
222 int ret; 532 int ret;
223 533
224 /* The DSP will covert the FE rate to 48k, stereo, 24bits */ 534 /* The DSP will covert the FE rate to 48k, stereo */
225 rate->min = rate->max = 48000; 535 rate->min = rate->max = 48000;
226 channels->min = channels->max = 2; 536 channels->min = channels->max = 2;
227 537
228 /* set SSP2 to 24-bit */ 538 if ((byt_rt5640_quirk & BYT_RT5640_SSP0_AIF1) ||
229 params_set_format(params, SNDRV_PCM_FORMAT_S24_LE); 539 (byt_rt5640_quirk & BYT_RT5640_SSP0_AIF2)) {
540
541 /* set SSP0 to 16-bit */
542 params_set_format(params, SNDRV_PCM_FORMAT_S16_LE);
543
544 /*
545 * Default mode for SSP configuration is TDM 4 slot, override config
546 * with explicit setting to I2S 2ch 16-bit. The word length is set with
547 * dai_set_tdm_slot() since there is no other API exposed
548 */
549 ret = snd_soc_dai_set_fmt(rtd->cpu_dai,
550 SND_SOC_DAIFMT_I2S |
551 SND_SOC_DAIFMT_NB_IF |
552 SND_SOC_DAIFMT_CBS_CFS
553 );
554 if (ret < 0) {
555 dev_err(rtd->dev, "can't set format to I2S, err %d\n", ret);
556 return ret;
557 }
230 558
231 /* 559 ret = snd_soc_dai_set_tdm_slot(rtd->cpu_dai, 0x3, 0x3, 2, 16);
232 * Default mode for SSP configuration is TDM 4 slot, override config 560 if (ret < 0) {
233 * with explicit setting to I2S 2ch 24-bit. The word length is set with 561 dev_err(rtd->dev, "can't set I2S config, err %d\n", ret);
234 * dai_set_tdm_slot() since there is no other API exposed 562 return ret;
235 */ 563 }
236 ret = snd_soc_dai_set_fmt(rtd->cpu_dai,
237 SND_SOC_DAIFMT_I2S |
238 SND_SOC_DAIFMT_NB_IF |
239 SND_SOC_DAIFMT_CBS_CFS
240 );
241 if (ret < 0) {
242 dev_err(rtd->dev, "can't set format to I2S, err %d\n", ret);
243 return ret;
244 }
245 564
246 ret = snd_soc_dai_set_tdm_slot(rtd->cpu_dai, 0x3, 0x3, 2, 24); 565 } else {
247 if (ret < 0) { 566
248 dev_err(rtd->dev, "can't set I2S config, err %d\n", ret); 567 /* set SSP2 to 24-bit */
249 return ret; 568 params_set_format(params, SNDRV_PCM_FORMAT_S24_LE);
250 } 569
570 /*
571 * Default mode for SSP configuration is TDM 4 slot, override config
572 * with explicit setting to I2S 2ch 24-bit. The word length is set with
573 * dai_set_tdm_slot() since there is no other API exposed
574 */
575 ret = snd_soc_dai_set_fmt(rtd->cpu_dai,
576 SND_SOC_DAIFMT_I2S |
577 SND_SOC_DAIFMT_NB_IF |
578 SND_SOC_DAIFMT_CBS_CFS
579 );
580 if (ret < 0) {
581 dev_err(rtd->dev, "can't set format to I2S, err %d\n", ret);
582 return ret;
583 }
251 584
585 ret = snd_soc_dai_set_tdm_slot(rtd->cpu_dai, 0x3, 0x3, 2, 24);
586 if (ret < 0) {
587 dev_err(rtd->dev, "can't set I2S config, err %d\n", ret);
588 return ret;
589 }
590 }
252 return 0; 591 return 0;
253} 592}
254 593
@@ -305,10 +644,10 @@ static struct snd_soc_dai_link byt_rt5640_dais[] = {
305 { 644 {
306 .name = "SSP2-Codec", 645 .name = "SSP2-Codec",
307 .id = 1, 646 .id = 1,
308 .cpu_dai_name = "ssp2-port", 647 .cpu_dai_name = "ssp2-port", /* overwritten for ssp0 routing */
309 .platform_name = "sst-mfld-platform", 648 .platform_name = "sst-mfld-platform",
310 .no_pcm = 1, 649 .no_pcm = 1,
311 .codec_dai_name = "rt5640-aif1", 650 .codec_dai_name = "rt5640-aif1", /* changed w/ quirk */
312 .codec_name = "i2c-10EC5640:00", /* overwritten with HID */ 651 .codec_name = "i2c-10EC5640:00", /* overwritten with HID */
313 .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF 652 .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF
314 | SND_SOC_DAIFMT_CBS_CFS, 653 | SND_SOC_DAIFMT_CBS_CFS,
@@ -335,6 +674,21 @@ static struct snd_soc_card byt_rt5640_card = {
335}; 674};
336 675
337static char byt_rt5640_codec_name[16]; /* i2c-<HID>:00 with HID being 8 chars */ 676static char byt_rt5640_codec_name[16]; /* i2c-<HID>:00 with HID being 8 chars */
677static char byt_rt5640_codec_aif_name[12]; /* = "rt5640-aif[1|2]" */
678static char byt_rt5640_cpu_dai_name[10]; /* = "ssp[0|2]-port" */
679
680static bool is_valleyview(void)
681{
682 static const struct x86_cpu_id cpu_ids[] = {
683 { X86_VENDOR_INTEL, 6, 55 }, /* Valleyview, Bay Trail */
684 {}
685 };
686
687 if (!x86_match_cpu(cpu_ids))
688 return false;
689 return true;
690}
691
338 692
339static int snd_byt_rt5640_mc_probe(struct platform_device *pdev) 693static int snd_byt_rt5640_mc_probe(struct platform_device *pdev)
340{ 694{
@@ -343,10 +697,16 @@ static int snd_byt_rt5640_mc_probe(struct platform_device *pdev)
343 const char *i2c_name = NULL; 697 const char *i2c_name = NULL;
344 int i; 698 int i;
345 int dai_index; 699 int dai_index;
700 struct byt_rt5640_private *priv;
701
702 priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_ATOMIC);
703 if (!priv)
704 return -ENOMEM;
346 705
347 /* register the soc card */ 706 /* register the soc card */
348 byt_rt5640_card.dev = &pdev->dev; 707 byt_rt5640_card.dev = &pdev->dev;
349 mach = byt_rt5640_card.dev->platform_data; 708 mach = byt_rt5640_card.dev->platform_data;
709 snd_soc_card_set_drvdata(&byt_rt5640_card, priv);
350 710
351 /* fix index of codec dai */ 711 /* fix index of codec dai */
352 dai_index = MERR_DPCM_COMPR + 1; 712 dai_index = MERR_DPCM_COMPR + 1;
@@ -366,8 +726,57 @@ static int snd_byt_rt5640_mc_probe(struct platform_device *pdev)
366 byt_rt5640_dais[dai_index].codec_name = byt_rt5640_codec_name; 726 byt_rt5640_dais[dai_index].codec_name = byt_rt5640_codec_name;
367 } 727 }
368 728
729 /*
730 * swap SSP0 if bytcr is detected
731 * (will be overridden if DMI quirk is detected)
732 */
733 if (is_valleyview()) {
734 struct sst_platform_info *p_info = mach->pdata;
735 const struct sst_res_info *res_info = p_info->res_info;
736
737 /* TODO: use CHAN package info from BIOS to detect AIF1/AIF2 */
738 if (res_info->acpi_ipc_irq_index == 0) {
739 byt_rt5640_quirk |= BYT_RT5640_SSP0_AIF2;
740 }
741 }
742
369 /* check quirks before creating card */ 743 /* check quirks before creating card */
370 dmi_check_system(byt_rt5640_quirk_table); 744 dmi_check_system(byt_rt5640_quirk_table);
745 log_quirks(&pdev->dev);
746
747 if ((byt_rt5640_quirk & BYT_RT5640_SSP2_AIF2) ||
748 (byt_rt5640_quirk & BYT_RT5640_SSP0_AIF2)) {
749
750 /* fixup codec aif name */
751 snprintf(byt_rt5640_codec_aif_name,
752 sizeof(byt_rt5640_codec_aif_name),
753 "%s", "rt5640-aif2");
754
755 byt_rt5640_dais[dai_index].codec_dai_name =
756 byt_rt5640_codec_aif_name;
757 }
758
759 if ((byt_rt5640_quirk & BYT_RT5640_SSP0_AIF1) ||
760 (byt_rt5640_quirk & BYT_RT5640_SSP0_AIF2)) {
761
762 /* fixup cpu dai name name */
763 snprintf(byt_rt5640_cpu_dai_name,
764 sizeof(byt_rt5640_cpu_dai_name),
765 "%s", "ssp0-port");
766
767 byt_rt5640_dais[dai_index].cpu_dai_name =
768 byt_rt5640_cpu_dai_name;
769 }
770
771 if ((byt_rt5640_quirk & BYT_RT5640_MCLK_EN) && (is_valleyview())) {
772 priv->mclk = devm_clk_get(&pdev->dev, "pmc_plt_clk_3");
773 if (IS_ERR(priv->mclk)) {
774 dev_err(&pdev->dev,
775 "Failed to get MCLK from pmc_plt_clk_3: %ld\n",
776 PTR_ERR(priv->mclk));
777 return PTR_ERR(priv->mclk);
778 }
779 }
371 780
372 ret_val = devm_snd_soc_register_card(&pdev->dev, &byt_rt5640_card); 781 ret_val = devm_snd_soc_register_card(&pdev->dev, &byt_rt5640_card);
373 782
diff --git a/sound/soc/intel/common/sst-acpi.c b/sound/soc/intel/common/sst-acpi.c
index 2c5eda14d510..1285cc597b6b 100644
--- a/sound/soc/intel/common/sst-acpi.c
+++ b/sound/soc/intel/common/sst-acpi.c
@@ -199,6 +199,7 @@ static struct sst_acpi_desc sst_acpi_haswell_desc = {
199 199
200static struct sst_acpi_mach broadwell_machines[] = { 200static struct sst_acpi_mach broadwell_machines[] = {
201 { "INT343A", "broadwell-audio", "intel/IntcSST2.bin", NULL, NULL, NULL }, 201 { "INT343A", "broadwell-audio", "intel/IntcSST2.bin", NULL, NULL, NULL },
202 { "RT5677CE", "bdw-rt5677", "intel/IntcSST2.bin", NULL, NULL, NULL },
202 {} 203 {}
203}; 204};
204 205
diff --git a/sound/soc/intel/haswell/sst-haswell-pcm.c b/sound/soc/intel/haswell/sst-haswell-pcm.c
index 3154525c2b83..9e4094e2c6e3 100644
--- a/sound/soc/intel/haswell/sst-haswell-pcm.c
+++ b/sound/soc/intel/haswell/sst-haswell-pcm.c
@@ -871,7 +871,7 @@ out:
871 return ret; 871 return ret;
872} 872}
873 873
874static struct snd_pcm_ops hsw_pcm_ops = { 874static const struct snd_pcm_ops hsw_pcm_ops = {
875 .open = hsw_pcm_open, 875 .open = hsw_pcm_open,
876 .close = hsw_pcm_close, 876 .close = hsw_pcm_close,
877 .ioctl = snd_pcm_lib_ioctl, 877 .ioctl = snd_pcm_lib_ioctl,
diff --git a/sound/soc/intel/skylake/bxt-sst.c b/sound/soc/intel/skylake/bxt-sst.c
index 2663781278aa..1d251d59bcb9 100644
--- a/sound/soc/intel/skylake/bxt-sst.c
+++ b/sound/soc/intel/skylake/bxt-sst.c
@@ -23,6 +23,7 @@
23#include "../common/sst-dsp.h" 23#include "../common/sst-dsp.h"
24#include "../common/sst-dsp-priv.h" 24#include "../common/sst-dsp-priv.h"
25#include "skl-sst-ipc.h" 25#include "skl-sst-ipc.h"
26#include "skl-tplg-interface.h"
26 27
27#define BXT_BASEFW_TIMEOUT 3000 28#define BXT_BASEFW_TIMEOUT 3000
28#define BXT_INIT_TIMEOUT 500 29#define BXT_INIT_TIMEOUT 500
@@ -40,11 +41,73 @@
40#define BXT_INSTANCE_ID 0 41#define BXT_INSTANCE_ID 0
41#define BXT_BASE_FW_MODULE_ID 0 42#define BXT_BASE_FW_MODULE_ID 0
42 43
44#define BXT_ADSP_FW_BIN_HDR_OFFSET 0x2000
45
43static unsigned int bxt_get_errorcode(struct sst_dsp *ctx) 46static unsigned int bxt_get_errorcode(struct sst_dsp *ctx)
44{ 47{
45 return sst_dsp_shim_read(ctx, BXT_ADSP_ERROR_CODE); 48 return sst_dsp_shim_read(ctx, BXT_ADSP_ERROR_CODE);
46} 49}
47 50
51static int
52bxt_load_library(struct sst_dsp *ctx, struct skl_dfw_manifest *minfo)
53{
54 struct snd_dma_buffer dmab;
55 struct skl_sst *skl = ctx->thread_context;
56 const struct firmware *fw = NULL;
57 struct firmware stripped_fw;
58 int ret = 0, i, dma_id, stream_tag;
59
60 /* library indices start from 1 to N. 0 represents base FW */
61 for (i = 1; i < minfo->lib_count; i++) {
62 ret = request_firmware(&fw, minfo->lib[i].name, ctx->dev);
63 if (ret < 0) {
64 dev_err(ctx->dev, "Request lib %s failed:%d\n",
65 minfo->lib[i].name, ret);
66 return ret;
67 }
68
69 if (skl->is_first_boot) {
70 ret = snd_skl_parse_uuids(ctx, fw,
71 BXT_ADSP_FW_BIN_HDR_OFFSET, i);
72 if (ret < 0)
73 goto load_library_failed;
74 }
75
76 stripped_fw.data = fw->data;
77 stripped_fw.size = fw->size;
78 skl_dsp_strip_extended_manifest(&stripped_fw);
79
80 stream_tag = ctx->dsp_ops.prepare(ctx->dev, 0x40,
81 stripped_fw.size, &dmab);
82 if (stream_tag <= 0) {
83 dev_err(ctx->dev, "Lib prepare DMA err: %x\n",
84 stream_tag);
85 ret = stream_tag;
86 goto load_library_failed;
87 }
88
89 dma_id = stream_tag - 1;
90 memcpy(dmab.area, stripped_fw.data, stripped_fw.size);
91
92 ctx->dsp_ops.trigger(ctx->dev, true, stream_tag);
93 ret = skl_sst_ipc_load_library(&skl->ipc, dma_id, i);
94 if (ret < 0)
95 dev_err(ctx->dev, "IPC Load Lib for %s fail: %d\n",
96 minfo->lib[i].name, ret);
97
98 ctx->dsp_ops.trigger(ctx->dev, false, stream_tag);
99 ctx->dsp_ops.cleanup(ctx->dev, &dmab, stream_tag);
100 release_firmware(fw);
101 fw = NULL;
102 }
103
104 return ret;
105
106load_library_failed:
107 release_firmware(fw);
108 return ret;
109}
110
48/* 111/*
49 * First boot sequence has some extra steps. Core 0 waits for power 112 * First boot sequence has some extra steps. Core 0 waits for power
50 * status on core 1, so power up core 1 also momentarily, keep it in 113 * status on core 1, so power up core 1 also momentarily, keep it in
@@ -157,8 +220,6 @@ static int sst_transfer_fw_host_dma(struct sst_dsp *ctx)
157 return ret; 220 return ret;
158} 221}
159 222
160#define BXT_ADSP_FW_BIN_HDR_OFFSET 0x2000
161
162static int bxt_load_base_firmware(struct sst_dsp *ctx) 223static int bxt_load_base_firmware(struct sst_dsp *ctx)
163{ 224{
164 struct firmware stripped_fw; 225 struct firmware stripped_fw;
@@ -175,9 +236,12 @@ static int bxt_load_base_firmware(struct sst_dsp *ctx)
175 if (ctx->fw == NULL) 236 if (ctx->fw == NULL)
176 goto sst_load_base_firmware_failed; 237 goto sst_load_base_firmware_failed;
177 238
178 ret = snd_skl_parse_uuids(ctx, BXT_ADSP_FW_BIN_HDR_OFFSET); 239 /* prase uuids on first boot */
179 if (ret < 0) 240 if (skl->is_first_boot) {
180 goto sst_load_base_firmware_failed; 241 ret = snd_skl_parse_uuids(ctx, ctx->fw, BXT_ADSP_FW_BIN_HDR_OFFSET, 0);
242 if (ret < 0)
243 goto sst_load_base_firmware_failed;
244 }
181 245
182 stripped_fw.data = ctx->fw->data; 246 stripped_fw.data = ctx->fw->data;
183 stripped_fw.size = ctx->fw->size; 247 stripped_fw.size = ctx->fw->size;
@@ -230,12 +294,23 @@ static int bxt_set_dsp_D0(struct sst_dsp *ctx, unsigned int core_id)
230 int ret; 294 int ret;
231 struct skl_ipc_dxstate_info dx; 295 struct skl_ipc_dxstate_info dx;
232 unsigned int core_mask = SKL_DSP_CORE_MASK(core_id); 296 unsigned int core_mask = SKL_DSP_CORE_MASK(core_id);
297 struct skl_dfw_manifest *minfo = &skl->manifest;
233 298
234 if (skl->fw_loaded == false) { 299 if (skl->fw_loaded == false) {
235 skl->boot_complete = false; 300 skl->boot_complete = false;
236 ret = bxt_load_base_firmware(ctx); 301 ret = bxt_load_base_firmware(ctx);
237 if (ret < 0) 302 if (ret < 0) {
238 dev_err(ctx->dev, "reload fw failed: %d\n", ret); 303 dev_err(ctx->dev, "reload fw failed: %d\n", ret);
304 return ret;
305 }
306
307 if (minfo->lib_count > 1) {
308 ret = bxt_load_library(ctx, minfo);
309 if (ret < 0) {
310 dev_err(ctx->dev, "reload libs failed: %d\n", ret);
311 return ret;
312 }
313 }
239 return ret; 314 return ret;
240 } 315 }
241 316
@@ -329,7 +404,7 @@ static int bxt_set_dsp_D3(struct sst_dsp *ctx, unsigned int core_id)
329 404
330 ret = skl_dsp_disable_core(ctx, core_mask); 405 ret = skl_dsp_disable_core(ctx, core_mask);
331 if (ret < 0) { 406 if (ret < 0) {
332 dev_err(ctx->dev, "Failed to disable core %d", ret); 407 dev_err(ctx->dev, "Failed to disable core %d\n", ret);
333 return ret; 408 return ret;
334 } 409 }
335 skl->cores.state[core_id] = SKL_DSP_RESET; 410 skl->cores.state[core_id] = SKL_DSP_RESET;
@@ -341,6 +416,7 @@ static struct skl_dsp_fw_ops bxt_fw_ops = {
341 .set_state_D3 = bxt_set_dsp_D3, 416 .set_state_D3 = bxt_set_dsp_D3,
342 .load_fw = bxt_load_base_firmware, 417 .load_fw = bxt_load_base_firmware,
343 .get_fw_errcode = bxt_get_errorcode, 418 .get_fw_errcode = bxt_get_errorcode,
419 .load_library = bxt_load_library,
344}; 420};
345 421
346static struct sst_ops skl_ops = { 422static struct sst_ops skl_ops = {
@@ -397,22 +473,40 @@ int bxt_sst_dsp_init(struct device *dev, void __iomem *mmio_base, int irq,
397 skl->cores.count = 2; 473 skl->cores.count = 2;
398 skl->boot_complete = false; 474 skl->boot_complete = false;
399 init_waitqueue_head(&skl->boot_wait); 475 init_waitqueue_head(&skl->boot_wait);
476 skl->is_first_boot = true;
477
478 if (dsp)
479 *dsp = skl;
480
481 return 0;
482}
483EXPORT_SYMBOL_GPL(bxt_sst_dsp_init);
484
485int bxt_sst_init_fw(struct device *dev, struct skl_sst *ctx)
486{
487 int ret;
488 struct sst_dsp *sst = ctx->dsp;
400 489
401 ret = sst->fw_ops.load_fw(sst); 490 ret = sst->fw_ops.load_fw(sst);
402 if (ret < 0) { 491 if (ret < 0) {
403 dev_err(dev, "Load base fw failed: %x", ret); 492 dev_err(dev, "Load base fw failed: %x\n", ret);
404 return ret; 493 return ret;
405 } 494 }
406 495
407 skl_dsp_init_core_state(sst); 496 skl_dsp_init_core_state(sst);
408 497
409 if (dsp) 498 if (ctx->manifest.lib_count > 1) {
410 *dsp = skl; 499 ret = sst->fw_ops.load_library(sst, &ctx->manifest);
500 if (ret < 0) {
501 dev_err(dev, "Load Library failed : %x\n", ret);
502 return ret;
503 }
504 }
505 ctx->is_first_boot = false;
411 506
412 return 0; 507 return 0;
413} 508}
414EXPORT_SYMBOL_GPL(bxt_sst_dsp_init); 509EXPORT_SYMBOL_GPL(bxt_sst_init_fw);
415
416 510
417void bxt_sst_dsp_cleanup(struct device *dev, struct skl_sst *ctx) 511void bxt_sst_dsp_cleanup(struct device *dev, struct skl_sst *ctx)
418{ 512{
diff --git a/sound/soc/intel/skylake/skl-messages.c b/sound/soc/intel/skylake/skl-messages.c
index 44ab595ce21a..805b7f2173f3 100644
--- a/sound/soc/intel/skylake/skl-messages.c
+++ b/sound/soc/intel/skylake/skl-messages.c
@@ -203,32 +203,35 @@ static const struct skl_dsp_ops dsp_ops[] = {
203 .id = 0x9d70, 203 .id = 0x9d70,
204 .loader_ops = skl_get_loader_ops, 204 .loader_ops = skl_get_loader_ops,
205 .init = skl_sst_dsp_init, 205 .init = skl_sst_dsp_init,
206 .init_fw = skl_sst_init_fw,
206 .cleanup = skl_sst_dsp_cleanup 207 .cleanup = skl_sst_dsp_cleanup
207 }, 208 },
208 { 209 {
209 .id = 0x9d71, 210 .id = 0x9d71,
210 .loader_ops = skl_get_loader_ops, 211 .loader_ops = skl_get_loader_ops,
211 .init = skl_sst_dsp_init, 212 .init = skl_sst_dsp_init,
213 .init_fw = skl_sst_init_fw,
212 .cleanup = skl_sst_dsp_cleanup 214 .cleanup = skl_sst_dsp_cleanup
213 }, 215 },
214 { 216 {
215 .id = 0x5a98, 217 .id = 0x5a98,
216 .loader_ops = bxt_get_loader_ops, 218 .loader_ops = bxt_get_loader_ops,
217 .init = bxt_sst_dsp_init, 219 .init = bxt_sst_dsp_init,
220 .init_fw = bxt_sst_init_fw,
218 .cleanup = bxt_sst_dsp_cleanup 221 .cleanup = bxt_sst_dsp_cleanup
219 }, 222 },
220}; 223};
221 224
222static int skl_get_dsp_ops(int pci_id) 225const struct skl_dsp_ops *skl_get_dsp_ops(int pci_id)
223{ 226{
224 int i; 227 int i;
225 228
226 for (i = 0; i < ARRAY_SIZE(dsp_ops); i++) { 229 for (i = 0; i < ARRAY_SIZE(dsp_ops); i++) {
227 if (dsp_ops[i].id == pci_id) 230 if (dsp_ops[i].id == pci_id)
228 return i; 231 return &dsp_ops[i];
229 } 232 }
230 233
231 return -EINVAL; 234 return NULL;
232} 235}
233 236
234int skl_init_dsp(struct skl *skl) 237int skl_init_dsp(struct skl *skl)
@@ -238,7 +241,8 @@ int skl_init_dsp(struct skl *skl)
238 struct hdac_bus *bus = ebus_to_hbus(ebus); 241 struct hdac_bus *bus = ebus_to_hbus(ebus);
239 struct skl_dsp_loader_ops loader_ops; 242 struct skl_dsp_loader_ops loader_ops;
240 int irq = bus->irq; 243 int irq = bus->irq;
241 int ret, index; 244 const struct skl_dsp_ops *ops;
245 int ret;
242 246
243 /* enable ppcap interrupt */ 247 /* enable ppcap interrupt */
244 snd_hdac_ext_bus_ppcap_enable(&skl->ebus, true); 248 snd_hdac_ext_bus_ppcap_enable(&skl->ebus, true);
@@ -251,18 +255,18 @@ int skl_init_dsp(struct skl *skl)
251 return -ENXIO; 255 return -ENXIO;
252 } 256 }
253 257
254 index = skl_get_dsp_ops(skl->pci->device); 258 ops = skl_get_dsp_ops(skl->pci->device);
255 if (index < 0) 259 if (!ops)
256 return -EINVAL; 260 return -EIO;
257 261
258 loader_ops = dsp_ops[index].loader_ops(); 262 loader_ops = ops->loader_ops();
259 ret = dsp_ops[index].init(bus->dev, mmio_base, irq, 263 ret = ops->init(bus->dev, mmio_base, irq,
260 skl->fw_name, loader_ops, &skl->skl_sst); 264 skl->fw_name, loader_ops,
265 &skl->skl_sst);
261 266
262 if (ret < 0) 267 if (ret < 0)
263 return ret; 268 return ret;
264 269
265 skl_dsp_enable_notification(skl->skl_sst, false);
266 dev_dbg(bus->dev, "dsp registration status=%d\n", ret); 270 dev_dbg(bus->dev, "dsp registration status=%d\n", ret);
267 271
268 return ret; 272 return ret;
@@ -273,16 +277,16 @@ int skl_free_dsp(struct skl *skl)
273 struct hdac_ext_bus *ebus = &skl->ebus; 277 struct hdac_ext_bus *ebus = &skl->ebus;
274 struct hdac_bus *bus = ebus_to_hbus(ebus); 278 struct hdac_bus *bus = ebus_to_hbus(ebus);
275 struct skl_sst *ctx = skl->skl_sst; 279 struct skl_sst *ctx = skl->skl_sst;
276 int index; 280 const struct skl_dsp_ops *ops;
277 281
278 /* disable ppcap interrupt */ 282 /* disable ppcap interrupt */
279 snd_hdac_ext_bus_ppcap_int_enable(&skl->ebus, false); 283 snd_hdac_ext_bus_ppcap_int_enable(&skl->ebus, false);
280 284
281 index = skl_get_dsp_ops(skl->pci->device); 285 ops = skl_get_dsp_ops(skl->pci->device);
282 if (index < 0) 286 if (!ops)
283 return -EIO; 287 return -EIO;
284 288
285 dsp_ops[index].cleanup(bus->dev, ctx); 289 ops->cleanup(bus->dev, ctx);
286 290
287 if (ctx->dsp->addr.lpe) 291 if (ctx->dsp->addr.lpe)
288 iounmap(ctx->dsp->addr.lpe); 292 iounmap(ctx->dsp->addr.lpe);
@@ -296,7 +300,7 @@ int skl_suspend_dsp(struct skl *skl)
296 int ret; 300 int ret;
297 301
298 /* if ppcap is not supported return 0 */ 302 /* if ppcap is not supported return 0 */
299 if (!skl->ebus.ppcap) 303 if (!skl->ebus.bus.ppcap)
300 return 0; 304 return 0;
301 305
302 ret = skl_dsp_sleep(ctx->dsp); 306 ret = skl_dsp_sleep(ctx->dsp);
@@ -316,13 +320,17 @@ int skl_resume_dsp(struct skl *skl)
316 int ret; 320 int ret;
317 321
318 /* if ppcap is not supported return 0 */ 322 /* if ppcap is not supported return 0 */
319 if (!skl->ebus.ppcap) 323 if (!skl->ebus.bus.ppcap)
320 return 0; 324 return 0;
321 325
322 /* enable ppcap interrupt */ 326 /* enable ppcap interrupt */
323 snd_hdac_ext_bus_ppcap_enable(&skl->ebus, true); 327 snd_hdac_ext_bus_ppcap_enable(&skl->ebus, true);
324 snd_hdac_ext_bus_ppcap_int_enable(&skl->ebus, true); 328 snd_hdac_ext_bus_ppcap_int_enable(&skl->ebus, true);
325 329
330 /* check if DSP 1st boot is done */
331 if (skl->skl_sst->is_first_boot == true)
332 return 0;
333
326 ret = skl_dsp_wake(ctx->dsp); 334 ret = skl_dsp_wake(ctx->dsp);
327 if (ret < 0) 335 if (ret < 0)
328 return ret; 336 return ret;
@@ -672,6 +680,7 @@ static u16 skl_get_module_param_size(struct skl_sst *ctx,
672 return param_size; 680 return param_size;
673 681
674 case SKL_MODULE_TYPE_BASE_OUTFMT: 682 case SKL_MODULE_TYPE_BASE_OUTFMT:
683 case SKL_MODULE_TYPE_KPB:
675 return sizeof(struct skl_base_outfmt_cfg); 684 return sizeof(struct skl_base_outfmt_cfg);
676 685
677 default: 686 default:
@@ -725,6 +734,7 @@ static int skl_set_module_format(struct skl_sst *ctx,
725 break; 734 break;
726 735
727 case SKL_MODULE_TYPE_BASE_OUTFMT: 736 case SKL_MODULE_TYPE_BASE_OUTFMT:
737 case SKL_MODULE_TYPE_KPB:
728 skl_set_base_outfmt_format(ctx, module_config, *param_data); 738 skl_set_base_outfmt_format(ctx, module_config, *param_data);
729 break; 739 break;
730 740
@@ -779,6 +789,7 @@ static int skl_alloc_queue(struct skl_module_pin *mpin,
779 mpin[i].in_use = true; 789 mpin[i].in_use = true;
780 mpin[i].id.module_id = id.module_id; 790 mpin[i].id.module_id = id.module_id;
781 mpin[i].id.instance_id = id.instance_id; 791 mpin[i].id.instance_id = id.instance_id;
792 mpin[i].id.pvt_id = id.pvt_id;
782 mpin[i].tgt_mcfg = tgt_cfg; 793 mpin[i].tgt_mcfg = tgt_cfg;
783 return i; 794 return i;
784 } 795 }
@@ -802,6 +813,7 @@ static void skl_free_queue(struct skl_module_pin *mpin, int q_index)
802 mpin[q_index].in_use = false; 813 mpin[q_index].in_use = false;
803 mpin[q_index].id.module_id = 0; 814 mpin[q_index].id.module_id = 0;
804 mpin[q_index].id.instance_id = 0; 815 mpin[q_index].id.instance_id = 0;
816 mpin[q_index].id.pvt_id = 0;
805 } 817 }
806 mpin[q_index].pin_state = SKL_PIN_UNBIND; 818 mpin[q_index].pin_state = SKL_PIN_UNBIND;
807 mpin[q_index].tgt_mcfg = NULL; 819 mpin[q_index].tgt_mcfg = NULL;
@@ -842,7 +854,7 @@ int skl_init_module(struct skl_sst *ctx,
842 struct skl_ipc_init_instance_msg msg; 854 struct skl_ipc_init_instance_msg msg;
843 855
844 dev_dbg(ctx->dev, "%s: module_id = %d instance=%d\n", __func__, 856 dev_dbg(ctx->dev, "%s: module_id = %d instance=%d\n", __func__,
845 mconfig->id.module_id, mconfig->id.instance_id); 857 mconfig->id.module_id, mconfig->id.pvt_id);
846 858
847 if (mconfig->pipe->state != SKL_PIPE_CREATED) { 859 if (mconfig->pipe->state != SKL_PIPE_CREATED) {
848 dev_err(ctx->dev, "Pipe not created state= %d pipe_id= %d\n", 860 dev_err(ctx->dev, "Pipe not created state= %d pipe_id= %d\n",
@@ -858,10 +870,11 @@ int skl_init_module(struct skl_sst *ctx,
858 } 870 }
859 871
860 msg.module_id = mconfig->id.module_id; 872 msg.module_id = mconfig->id.module_id;
861 msg.instance_id = mconfig->id.instance_id; 873 msg.instance_id = mconfig->id.pvt_id;
862 msg.ppl_instance_id = mconfig->pipe->ppl_id; 874 msg.ppl_instance_id = mconfig->pipe->ppl_id;
863 msg.param_data_size = module_config_size; 875 msg.param_data_size = module_config_size;
864 msg.core_id = mconfig->core_id; 876 msg.core_id = mconfig->core_id;
877 msg.domain = mconfig->domain;
865 878
866 ret = skl_ipc_init_instance(&ctx->ipc, &msg, param_data); 879 ret = skl_ipc_init_instance(&ctx->ipc, &msg, param_data);
867 if (ret < 0) { 880 if (ret < 0) {
@@ -878,9 +891,9 @@ static void skl_dump_bind_info(struct skl_sst *ctx, struct skl_module_cfg
878 *src_module, struct skl_module_cfg *dst_module) 891 *src_module, struct skl_module_cfg *dst_module)
879{ 892{
880 dev_dbg(ctx->dev, "%s: src module_id = %d src_instance=%d\n", 893 dev_dbg(ctx->dev, "%s: src module_id = %d src_instance=%d\n",
881 __func__, src_module->id.module_id, src_module->id.instance_id); 894 __func__, src_module->id.module_id, src_module->id.pvt_id);
882 dev_dbg(ctx->dev, "%s: dst_module=%d dst_instacne=%d\n", __func__, 895 dev_dbg(ctx->dev, "%s: dst_module=%d dst_instacne=%d\n", __func__,
883 dst_module->id.module_id, dst_module->id.instance_id); 896 dst_module->id.module_id, dst_module->id.pvt_id);
884 897
885 dev_dbg(ctx->dev, "src_module state = %d dst module state = %d\n", 898 dev_dbg(ctx->dev, "src_module state = %d dst module state = %d\n",
886 src_module->m_state, dst_module->m_state); 899 src_module->m_state, dst_module->m_state);
@@ -927,9 +940,9 @@ int skl_unbind_modules(struct skl_sst *ctx,
927 return 0; 940 return 0;
928 941
929 msg.module_id = src_mcfg->id.module_id; 942 msg.module_id = src_mcfg->id.module_id;
930 msg.instance_id = src_mcfg->id.instance_id; 943 msg.instance_id = src_mcfg->id.pvt_id;
931 msg.dst_module_id = dst_mcfg->id.module_id; 944 msg.dst_module_id = dst_mcfg->id.module_id;
932 msg.dst_instance_id = dst_mcfg->id.instance_id; 945 msg.dst_instance_id = dst_mcfg->id.pvt_id;
933 msg.bind = false; 946 msg.bind = false;
934 947
935 ret = skl_ipc_bind_unbind(&ctx->ipc, &msg); 948 ret = skl_ipc_bind_unbind(&ctx->ipc, &msg);
@@ -988,9 +1001,9 @@ int skl_bind_modules(struct skl_sst *ctx,
988 msg.src_queue, msg.dst_queue); 1001 msg.src_queue, msg.dst_queue);
989 1002
990 msg.module_id = src_mcfg->id.module_id; 1003 msg.module_id = src_mcfg->id.module_id;
991 msg.instance_id = src_mcfg->id.instance_id; 1004 msg.instance_id = src_mcfg->id.pvt_id;
992 msg.dst_module_id = dst_mcfg->id.module_id; 1005 msg.dst_module_id = dst_mcfg->id.module_id;
993 msg.dst_instance_id = dst_mcfg->id.instance_id; 1006 msg.dst_instance_id = dst_mcfg->id.pvt_id;
994 msg.bind = true; 1007 msg.bind = true;
995 1008
996 ret = skl_ipc_bind_unbind(&ctx->ipc, &msg); 1009 ret = skl_ipc_bind_unbind(&ctx->ipc, &msg);
@@ -1168,7 +1181,7 @@ int skl_set_module_params(struct skl_sst *ctx, u32 *params, int size,
1168 struct skl_ipc_large_config_msg msg; 1181 struct skl_ipc_large_config_msg msg;
1169 1182
1170 msg.module_id = mcfg->id.module_id; 1183 msg.module_id = mcfg->id.module_id;
1171 msg.instance_id = mcfg->id.instance_id; 1184 msg.instance_id = mcfg->id.pvt_id;
1172 msg.param_data_size = size; 1185 msg.param_data_size = size;
1173 msg.large_param_id = param_id; 1186 msg.large_param_id = param_id;
1174 1187
@@ -1181,7 +1194,7 @@ int skl_get_module_params(struct skl_sst *ctx, u32 *params, int size,
1181 struct skl_ipc_large_config_msg msg; 1194 struct skl_ipc_large_config_msg msg;
1182 1195
1183 msg.module_id = mcfg->id.module_id; 1196 msg.module_id = mcfg->id.module_id;
1184 msg.instance_id = mcfg->id.instance_id; 1197 msg.instance_id = mcfg->id.pvt_id;
1185 msg.param_data_size = size; 1198 msg.param_data_size = size;
1186 msg.large_param_id = param_id; 1199 msg.large_param_id = param_id;
1187 1200
diff --git a/sound/soc/intel/skylake/skl-pcm.c b/sound/soc/intel/skylake/skl-pcm.c
index 6e05bf8622f7..58c728662600 100644
--- a/sound/soc/intel/skylake/skl-pcm.c
+++ b/sound/soc/intel/skylake/skl-pcm.c
@@ -106,7 +106,7 @@ static void skl_set_pcm_constrains(struct hdac_ext_bus *ebus,
106 106
107static enum hdac_ext_stream_type skl_get_host_stream_type(struct hdac_ext_bus *ebus) 107static enum hdac_ext_stream_type skl_get_host_stream_type(struct hdac_ext_bus *ebus)
108{ 108{
109 if (ebus->ppcap) 109 if ((ebus_to_hbus(ebus))->ppcap)
110 return HDAC_EXT_STREAM_TYPE_HOST; 110 return HDAC_EXT_STREAM_TYPE_HOST;
111 else 111 else
112 return HDAC_EXT_STREAM_TYPE_COUPLED; 112 return HDAC_EXT_STREAM_TYPE_COUPLED;
@@ -188,7 +188,7 @@ static int skl_get_format(struct snd_pcm_substream *substream,
188 struct hdac_ext_bus *ebus = dev_get_drvdata(dai->dev); 188 struct hdac_ext_bus *ebus = dev_get_drvdata(dai->dev);
189 int format_val = 0; 189 int format_val = 0;
190 190
191 if (ebus->ppcap) { 191 if ((ebus_to_hbus(ebus))->ppcap) {
192 struct snd_pcm_runtime *runtime = substream->runtime; 192 struct snd_pcm_runtime *runtime = substream->runtime;
193 193
194 format_val = snd_hdac_calc_stream_format(runtime->rate, 194 format_val = snd_hdac_calc_stream_format(runtime->rate,
@@ -648,7 +648,8 @@ static struct snd_soc_dai_driver skl_platform_dai[] = {
648 .channels_min = HDA_MONO, 648 .channels_min = HDA_MONO,
649 .channels_max = HDA_STEREO, 649 .channels_max = HDA_STEREO,
650 .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_8000, 650 .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_8000,
651 .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE, 651 .formats = SNDRV_PCM_FMTBIT_S16_LE |
652 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE,
652 }, 653 },
653 .capture = { 654 .capture = {
654 .stream_name = "System Capture", 655 .stream_name = "System Capture",
@@ -1020,7 +1021,7 @@ static int skl_platform_pcm_trigger(struct snd_pcm_substream *substream,
1020{ 1021{
1021 struct hdac_ext_bus *ebus = get_bus_ctx(substream); 1022 struct hdac_ext_bus *ebus = get_bus_ctx(substream);
1022 1023
1023 if (!ebus->ppcap) 1024 if (!(ebus_to_hbus(ebus))->ppcap)
1024 return skl_coupled_trigger(substream, cmd); 1025 return skl_coupled_trigger(substream, cmd);
1025 1026
1026 return 0; 1027 return 0;
@@ -1093,7 +1094,7 @@ static int skl_get_time_info(struct snd_pcm_substream *substream,
1093 return 0; 1094 return 0;
1094} 1095}
1095 1096
1096static struct snd_pcm_ops skl_platform_ops = { 1097static const struct snd_pcm_ops skl_platform_ops = {
1097 .open = skl_platform_open, 1098 .open = skl_platform_open,
1098 .ioctl = snd_pcm_lib_ioctl, 1099 .ioctl = snd_pcm_lib_ioctl,
1099 .trigger = skl_platform_pcm_trigger, 1100 .trigger = skl_platform_pcm_trigger,
@@ -1138,20 +1139,67 @@ static int skl_pcm_new(struct snd_soc_pcm_runtime *rtd)
1138 return retval; 1139 return retval;
1139} 1140}
1140 1141
1142static int skl_populate_modules(struct skl *skl)
1143{
1144 struct skl_pipeline *p;
1145 struct skl_pipe_module *m;
1146 struct snd_soc_dapm_widget *w;
1147 struct skl_module_cfg *mconfig;
1148 int ret;
1149
1150 list_for_each_entry(p, &skl->ppl_list, node) {
1151 list_for_each_entry(m, &p->pipe->w_list, node) {
1152
1153 w = m->w;
1154 mconfig = w->priv;
1155
1156 ret = snd_skl_get_module_info(skl->skl_sst, mconfig);
1157 if (ret < 0) {
1158 dev_err(skl->skl_sst->dev,
1159 "query module info failed:%d\n", ret);
1160 goto err;
1161 }
1162 }
1163 }
1164err:
1165 return ret;
1166}
1167
1141static int skl_platform_soc_probe(struct snd_soc_platform *platform) 1168static int skl_platform_soc_probe(struct snd_soc_platform *platform)
1142{ 1169{
1143 struct hdac_ext_bus *ebus = dev_get_drvdata(platform->dev); 1170 struct hdac_ext_bus *ebus = dev_get_drvdata(platform->dev);
1144 struct skl *skl = ebus_to_skl(ebus); 1171 struct skl *skl = ebus_to_skl(ebus);
1172 const struct skl_dsp_ops *ops;
1145 int ret; 1173 int ret;
1146 1174
1147 if (ebus->ppcap) { 1175 pm_runtime_get_sync(platform->dev);
1176 if ((ebus_to_hbus(ebus))->ppcap) {
1148 ret = skl_tplg_init(platform, ebus); 1177 ret = skl_tplg_init(platform, ebus);
1149 if (ret < 0) { 1178 if (ret < 0) {
1150 dev_err(platform->dev, "Failed to init topology!\n"); 1179 dev_err(platform->dev, "Failed to init topology!\n");
1151 return ret; 1180 return ret;
1152 } 1181 }
1153 skl->platform = platform; 1182 skl->platform = platform;
1183
1184 /* load the firmwares, since all is set */
1185 ops = skl_get_dsp_ops(skl->pci->device);
1186 if (!ops)
1187 return -EIO;
1188
1189 if (skl->skl_sst->is_first_boot == false) {
1190 dev_err(platform->dev, "DSP reports first boot done!!!\n");
1191 return -EIO;
1192 }
1193
1194 ret = ops->init_fw(platform->dev, skl->skl_sst);
1195 if (ret < 0) {
1196 dev_err(platform->dev, "Failed to boot first fw: %d\n", ret);
1197 return ret;
1198 }
1199 skl_populate_modules(skl);
1154 } 1200 }
1201 pm_runtime_mark_last_busy(platform->dev);
1202 pm_runtime_put_autosuspend(platform->dev);
1155 1203
1156 return 0; 1204 return 0;
1157} 1205}
diff --git a/sound/soc/intel/skylake/skl-sst-cldma.c b/sound/soc/intel/skylake/skl-sst-cldma.c
index da2329d17f4d..efa2532114ba 100644
--- a/sound/soc/intel/skylake/skl-sst-cldma.c
+++ b/sound/soc/intel/skylake/skl-sst-cldma.c
@@ -341,14 +341,14 @@ int skl_cldma_prepare(struct sst_dsp *ctx)
341 ret = ctx->dsp_ops.alloc_dma_buf(ctx->dev, 341 ret = ctx->dsp_ops.alloc_dma_buf(ctx->dev,
342 &ctx->cl_dev.dmab_data, ctx->cl_dev.bufsize); 342 &ctx->cl_dev.dmab_data, ctx->cl_dev.bufsize);
343 if (ret < 0) { 343 if (ret < 0) {
344 dev_err(ctx->dev, "Alloc buffer for base fw failed: %x", ret); 344 dev_err(ctx->dev, "Alloc buffer for base fw failed: %x\n", ret);
345 return ret; 345 return ret;
346 } 346 }
347 /* Setup Code loader BDL */ 347 /* Setup Code loader BDL */
348 ret = ctx->dsp_ops.alloc_dma_buf(ctx->dev, 348 ret = ctx->dsp_ops.alloc_dma_buf(ctx->dev,
349 &ctx->cl_dev.dmab_bdl, PAGE_SIZE); 349 &ctx->cl_dev.dmab_bdl, PAGE_SIZE);
350 if (ret < 0) { 350 if (ret < 0) {
351 dev_err(ctx->dev, "Alloc buffer for blde failed: %x", ret); 351 dev_err(ctx->dev, "Alloc buffer for blde failed: %x\n", ret);
352 ctx->dsp_ops.free_dma_buf(ctx->dev, &ctx->cl_dev.dmab_data); 352 ctx->dsp_ops.free_dma_buf(ctx->dev, &ctx->cl_dev.dmab_data);
353 return ret; 353 return ret;
354 } 354 }
diff --git a/sound/soc/intel/skylake/skl-sst-dsp.h b/sound/soc/intel/skylake/skl-sst-dsp.h
index 0f8629ef79ac..b9e71d051fb1 100644
--- a/sound/soc/intel/skylake/skl-sst-dsp.h
+++ b/sound/soc/intel/skylake/skl-sst-dsp.h
@@ -20,6 +20,7 @@
20#include <sound/memalloc.h> 20#include <sound/memalloc.h>
21#include "skl-sst-cldma.h" 21#include "skl-sst-cldma.h"
22#include "skl-tplg-interface.h" 22#include "skl-tplg-interface.h"
23#include "skl-topology.h"
23 24
24struct sst_dsp; 25struct sst_dsp;
25struct skl_sst; 26struct skl_sst;
@@ -133,6 +134,8 @@ enum skl_dsp_states {
133struct skl_dsp_fw_ops { 134struct skl_dsp_fw_ops {
134 int (*load_fw)(struct sst_dsp *ctx); 135 int (*load_fw)(struct sst_dsp *ctx);
135 /* FW module parser/loader */ 136 /* FW module parser/loader */
137 int (*load_library)(struct sst_dsp *ctx,
138 struct skl_dfw_manifest *minfo);
136 int (*parse_fw)(struct sst_dsp *ctx); 139 int (*parse_fw)(struct sst_dsp *ctx);
137 int (*set_state_D0)(struct sst_dsp *ctx, unsigned int core_id); 140 int (*set_state_D0)(struct sst_dsp *ctx, unsigned int core_id);
138 int (*set_state_D3)(struct sst_dsp *ctx, unsigned int core_id); 141 int (*set_state_D3)(struct sst_dsp *ctx, unsigned int core_id);
@@ -203,12 +206,21 @@ int skl_sst_dsp_init(struct device *dev, void __iomem *mmio_base, int irq,
203int bxt_sst_dsp_init(struct device *dev, void __iomem *mmio_base, int irq, 206int bxt_sst_dsp_init(struct device *dev, void __iomem *mmio_base, int irq,
204 const char *fw_name, struct skl_dsp_loader_ops dsp_ops, 207 const char *fw_name, struct skl_dsp_loader_ops dsp_ops,
205 struct skl_sst **dsp); 208 struct skl_sst **dsp);
209int skl_sst_init_fw(struct device *dev, struct skl_sst *ctx);
210int bxt_sst_init_fw(struct device *dev, struct skl_sst *ctx);
206void skl_sst_dsp_cleanup(struct device *dev, struct skl_sst *ctx); 211void skl_sst_dsp_cleanup(struct device *dev, struct skl_sst *ctx);
207void bxt_sst_dsp_cleanup(struct device *dev, struct skl_sst *ctx); 212void bxt_sst_dsp_cleanup(struct device *dev, struct skl_sst *ctx);
208 213
209int snd_skl_get_module_info(struct skl_sst *ctx, u8 *uuid, 214int snd_skl_get_module_info(struct skl_sst *ctx,
210 struct skl_dfw_module *dfw_config); 215 struct skl_module_cfg *mconfig);
211int snd_skl_parse_uuids(struct sst_dsp *ctx, unsigned int offset); 216int snd_skl_parse_uuids(struct sst_dsp *ctx, const struct firmware *fw,
217 unsigned int offset, int index);
218int skl_get_pvt_id(struct skl_sst *ctx,
219 struct skl_module_cfg *mconfig);
220int skl_put_pvt_id(struct skl_sst *ctx,
221 struct skl_module_cfg *mconfig);
222int skl_get_pvt_instance_id_map(struct skl_sst *ctx,
223 int module_id, int instance_id);
212void skl_freeup_uuid_list(struct skl_sst *ctx); 224void skl_freeup_uuid_list(struct skl_sst *ctx);
213 225
214int skl_dsp_strip_extended_manifest(struct firmware *fw); 226int skl_dsp_strip_extended_manifest(struct firmware *fw);
diff --git a/sound/soc/intel/skylake/skl-sst-ipc.c b/sound/soc/intel/skylake/skl-sst-ipc.c
index 96f2f6889b18..0bd01e62622c 100644
--- a/sound/soc/intel/skylake/skl-sst-ipc.c
+++ b/sound/soc/intel/skylake/skl-sst-ipc.c
@@ -114,6 +114,11 @@
114#define IPC_CORE_ID(x) (((x) & IPC_CORE_ID_MASK) \ 114#define IPC_CORE_ID(x) (((x) & IPC_CORE_ID_MASK) \
115 << IPC_CORE_ID_SHIFT) 115 << IPC_CORE_ID_SHIFT)
116 116
117#define IPC_DOMAIN_SHIFT 28
118#define IPC_DOMAIN_MASK 0x1
119#define IPC_DOMAIN(x) (((x) & IPC_DOMAIN_MASK) \
120 << IPC_DOMAIN_SHIFT)
121
117/* Bind/Unbind message extension register */ 122/* Bind/Unbind message extension register */
118#define IPC_DST_MOD_ID_SHIFT 0 123#define IPC_DST_MOD_ID_SHIFT 0
119#define IPC_DST_MOD_ID(x) (((x) & IPC_MOD_ID_MASK) \ 124#define IPC_DST_MOD_ID(x) (((x) & IPC_MOD_ID_MASK) \
@@ -190,6 +195,7 @@ enum skl_ipc_glb_type {
190 IPC_GLB_GET_PPL_CONTEXT_SIZE = 21, 195 IPC_GLB_GET_PPL_CONTEXT_SIZE = 21,
191 IPC_GLB_SAVE_PPL = 22, 196 IPC_GLB_SAVE_PPL = 22,
192 IPC_GLB_RESTORE_PPL = 23, 197 IPC_GLB_RESTORE_PPL = 23,
198 IPC_GLB_LOAD_LIBRARY = 24,
193 IPC_GLB_NOTIFY = 26, 199 IPC_GLB_NOTIFY = 26,
194 IPC_GLB_MAX_IPC_MSG_NUMBER = 31 /* Maximum message number */ 200 IPC_GLB_MAX_IPC_MSG_NUMBER = 31 /* Maximum message number */
195}; 201};
@@ -338,7 +344,7 @@ static int skl_ipc_process_notification(struct sst_generic_ipc *ipc,
338 break; 344 break;
339 345
340 default: 346 default:
341 dev_err(ipc->dev, "ipc: Unhandled error msg=%x", 347 dev_err(ipc->dev, "ipc: Unhandled error msg=%x\n",
342 header.primary); 348 header.primary);
343 break; 349 break;
344 } 350 }
@@ -379,13 +385,13 @@ static void skl_ipc_process_reply(struct sst_generic_ipc *ipc,
379 break; 385 break;
380 386
381 default: 387 default:
382 dev_err(ipc->dev, "Unknown ipc reply: 0x%x", reply); 388 dev_err(ipc->dev, "Unknown ipc reply: 0x%x\n", reply);
383 msg->errno = -EINVAL; 389 msg->errno = -EINVAL;
384 break; 390 break;
385 } 391 }
386 392
387 if (reply != IPC_GLB_REPLY_SUCCESS) { 393 if (reply != IPC_GLB_REPLY_SUCCESS) {
388 dev_err(ipc->dev, "ipc FW reply: reply=%d", reply); 394 dev_err(ipc->dev, "ipc FW reply: reply=%d\n", reply);
389 dev_err(ipc->dev, "FW Error Code: %u\n", 395 dev_err(ipc->dev, "FW Error Code: %u\n",
390 ipc->dsp->fw_ops.get_fw_errcode(ipc->dsp)); 396 ipc->dsp->fw_ops.get_fw_errcode(ipc->dsp));
391 } 397 }
@@ -434,9 +440,9 @@ irqreturn_t skl_dsp_irq_thread_handler(int irq, void *context)
434 hipcte = sst_dsp_shim_read_unlocked(dsp, SKL_ADSP_REG_HIPCTE); 440 hipcte = sst_dsp_shim_read_unlocked(dsp, SKL_ADSP_REG_HIPCTE);
435 header.primary = hipct; 441 header.primary = hipct;
436 header.extension = hipcte; 442 header.extension = hipcte;
437 dev_dbg(dsp->dev, "IPC irq: Firmware respond primary:%x", 443 dev_dbg(dsp->dev, "IPC irq: Firmware respond primary:%x\n",
438 header.primary); 444 header.primary);
439 dev_dbg(dsp->dev, "IPC irq: Firmware respond extension:%x", 445 dev_dbg(dsp->dev, "IPC irq: Firmware respond extension:%x\n",
440 header.extension); 446 header.extension);
441 447
442 if (IPC_GLB_NOTIFY_RSP_TYPE(header.primary)) { 448 if (IPC_GLB_NOTIFY_RSP_TYPE(header.primary)) {
@@ -704,6 +710,7 @@ int skl_ipc_init_instance(struct sst_generic_ipc *ipc,
704 header.extension = IPC_CORE_ID(msg->core_id); 710 header.extension = IPC_CORE_ID(msg->core_id);
705 header.extension |= IPC_PPL_INSTANCE_ID(msg->ppl_instance_id); 711 header.extension |= IPC_PPL_INSTANCE_ID(msg->ppl_instance_id);
706 header.extension |= IPC_PARAM_BLOCK_SIZE(param_block_size); 712 header.extension |= IPC_PARAM_BLOCK_SIZE(param_block_size);
713 header.extension |= IPC_DOMAIN(msg->domain);
707 714
708 dev_dbg(ipc->dev, "In %s primary =%x ext=%x\n", __func__, 715 dev_dbg(ipc->dev, "In %s primary =%x ext=%x\n", __func__,
709 header.primary, header.extension); 716 header.primary, header.extension);
@@ -742,7 +749,7 @@ int skl_ipc_bind_unbind(struct sst_generic_ipc *ipc,
742 header.extension); 749 header.extension);
743 ret = sst_ipc_tx_message_wait(ipc, *ipc_header, NULL, 0, NULL, 0); 750 ret = sst_ipc_tx_message_wait(ipc, *ipc_header, NULL, 0, NULL, 0);
744 if (ret < 0) { 751 if (ret < 0) {
745 dev_err(ipc->dev, "ipc: bind/unbind faileden"); 752 dev_err(ipc->dev, "ipc: bind/unbind failed\n");
746 return ret; 753 return ret;
747 } 754 }
748 755
@@ -902,3 +909,25 @@ int skl_ipc_get_large_config(struct sst_generic_ipc *ipc,
902 return ret; 909 return ret;
903} 910}
904EXPORT_SYMBOL_GPL(skl_ipc_get_large_config); 911EXPORT_SYMBOL_GPL(skl_ipc_get_large_config);
912
913int skl_sst_ipc_load_library(struct sst_generic_ipc *ipc,
914 u8 dma_id, u8 table_id)
915{
916 struct skl_ipc_header header = {0};
917 u64 *ipc_header = (u64 *)(&header);
918 int ret = 0;
919
920 header.primary = IPC_MSG_TARGET(IPC_FW_GEN_MSG);
921 header.primary |= IPC_MSG_DIR(IPC_MSG_REQUEST);
922 header.primary |= IPC_GLB_TYPE(IPC_GLB_LOAD_LIBRARY);
923 header.primary |= IPC_MOD_INSTANCE_ID(table_id);
924 header.primary |= IPC_MOD_ID(dma_id);
925
926 ret = sst_ipc_tx_message_wait(ipc, *ipc_header, NULL, 0, NULL, 0);
927
928 if (ret < 0)
929 dev_err(ipc->dev, "ipc: load lib failed\n");
930
931 return ret;
932}
933EXPORT_SYMBOL_GPL(skl_sst_ipc_load_library);
diff --git a/sound/soc/intel/skylake/skl-sst-ipc.h b/sound/soc/intel/skylake/skl-sst-ipc.h
index 2e3d4e80ef97..0334ed4af031 100644
--- a/sound/soc/intel/skylake/skl-sst-ipc.h
+++ b/sound/soc/intel/skylake/skl-sst-ipc.h
@@ -66,7 +66,7 @@ struct skl_sst {
66 66
67 /* callback for miscbdge */ 67 /* callback for miscbdge */
68 void (*enable_miscbdcge)(struct device *dev, bool enable); 68 void (*enable_miscbdcge)(struct device *dev, bool enable);
69 /*Is CGCTL.MISCBDCGE disabled*/ 69 /* Is CGCTL.MISCBDCGE disabled */
70 bool miscbdcg_disabled; 70 bool miscbdcg_disabled;
71 71
72 /* Populate module information */ 72 /* Populate module information */
@@ -75,8 +75,14 @@ struct skl_sst {
75 /* Is firmware loaded */ 75 /* Is firmware loaded */
76 bool fw_loaded; 76 bool fw_loaded;
77 77
78 /* first boot ? */
79 bool is_first_boot;
80
78 /* multi-core */ 81 /* multi-core */
79 struct skl_dsp_cores cores; 82 struct skl_dsp_cores cores;
83
84 /* tplg manifest */
85 struct skl_dfw_manifest manifest;
80}; 86};
81 87
82struct skl_ipc_init_instance_msg { 88struct skl_ipc_init_instance_msg {
@@ -85,6 +91,7 @@ struct skl_ipc_init_instance_msg {
85 u16 param_data_size; 91 u16 param_data_size;
86 u8 ppl_instance_id; 92 u8 ppl_instance_id;
87 u8 core_id; 93 u8 core_id;
94 u8 domain;
88}; 95};
89 96
90struct skl_ipc_bind_unbind_msg { 97struct skl_ipc_bind_unbind_msg {
@@ -145,6 +152,9 @@ int skl_ipc_set_large_config(struct sst_generic_ipc *ipc,
145int skl_ipc_get_large_config(struct sst_generic_ipc *ipc, 152int skl_ipc_get_large_config(struct sst_generic_ipc *ipc,
146 struct skl_ipc_large_config_msg *msg, u32 *param); 153 struct skl_ipc_large_config_msg *msg, u32 *param);
147 154
155int skl_sst_ipc_load_library(struct sst_generic_ipc *ipc,
156 u8 dma_id, u8 table_id);
157
148void skl_ipc_int_enable(struct sst_dsp *dsp); 158void skl_ipc_int_enable(struct sst_dsp *dsp);
149void skl_ipc_op_int_enable(struct sst_dsp *ctx); 159void skl_ipc_op_int_enable(struct sst_dsp *ctx);
150void skl_ipc_op_int_disable(struct sst_dsp *ctx); 160void skl_ipc_op_int_disable(struct sst_dsp *ctx);
diff --git a/sound/soc/intel/skylake/skl-sst-utils.c b/sound/soc/intel/skylake/skl-sst-utils.c
index ddcb52a51854..8dc03039b311 100644
--- a/sound/soc/intel/skylake/skl-sst-utils.c
+++ b/sound/soc/intel/skylake/skl-sst-utils.c
@@ -28,11 +28,6 @@
28/* FW Extended Manifest Header id = $AE1 */ 28/* FW Extended Manifest Header id = $AE1 */
29#define SKL_EXT_MANIFEST_HEADER_MAGIC 0x31454124 29#define SKL_EXT_MANIFEST_HEADER_MAGIC 0x31454124
30 30
31struct skl_dfw_module_mod {
32 char name[100];
33 struct skl_dfw_module skl_dfw_mod;
34};
35
36struct UUID { 31struct UUID {
37 u8 id[16]; 32 u8 id[16];
38}; 33};
@@ -99,10 +94,15 @@ struct adsp_fw_hdr {
99 u32 load_offset; 94 u32 load_offset;
100} __packed; 95} __packed;
101 96
97#define MAX_INSTANCE_BUFF 2
98
102struct uuid_module { 99struct uuid_module {
103 uuid_le uuid; 100 uuid_le uuid;
104 int id; 101 int id;
105 int is_loadable; 102 int is_loadable;
103 int max_instance;
104 u64 pvt_id[MAX_INSTANCE_BUFF];
105 int *instance_id;
106 106
107 struct list_head list; 107 struct list_head list;
108}; 108};
@@ -115,13 +115,13 @@ struct skl_ext_manifest_hdr {
115 u32 entries; 115 u32 entries;
116}; 116};
117 117
118int snd_skl_get_module_info(struct skl_sst *ctx, u8 *uuid, 118int snd_skl_get_module_info(struct skl_sst *ctx,
119 struct skl_dfw_module *dfw_config) 119 struct skl_module_cfg *mconfig)
120{ 120{
121 struct uuid_module *module; 121 struct uuid_module *module;
122 uuid_le *uuid_mod; 122 uuid_le *uuid_mod;
123 123
124 uuid_mod = (uuid_le *)uuid; 124 uuid_mod = (uuid_le *)mconfig->guid;
125 125
126 if (list_empty(&ctx->uuid_list)) { 126 if (list_empty(&ctx->uuid_list)) {
127 dev_err(ctx->dev, "Module list is empty\n"); 127 dev_err(ctx->dev, "Module list is empty\n");
@@ -130,8 +130,8 @@ int snd_skl_get_module_info(struct skl_sst *ctx, u8 *uuid,
130 130
131 list_for_each_entry(module, &ctx->uuid_list, list) { 131 list_for_each_entry(module, &ctx->uuid_list, list) {
132 if (uuid_le_cmp(*uuid_mod, module->uuid) == 0) { 132 if (uuid_le_cmp(*uuid_mod, module->uuid) == 0) {
133 dfw_config->module_id = module->id; 133 mconfig->id.module_id = module->id;
134 dfw_config->is_loadable = module->is_loadable; 134 mconfig->is_loadable = module->is_loadable;
135 135
136 return 0; 136 return 0;
137 } 137 }
@@ -141,15 +141,154 @@ int snd_skl_get_module_info(struct skl_sst *ctx, u8 *uuid,
141} 141}
142EXPORT_SYMBOL_GPL(snd_skl_get_module_info); 142EXPORT_SYMBOL_GPL(snd_skl_get_module_info);
143 143
144static int skl_get_pvtid_map(struct uuid_module *module, int instance_id)
145{
146 int pvt_id;
147
148 for (pvt_id = 0; pvt_id < module->max_instance; pvt_id++) {
149 if (module->instance_id[pvt_id] == instance_id)
150 return pvt_id;
151 }
152 return -EINVAL;
153}
154
155int skl_get_pvt_instance_id_map(struct skl_sst *ctx,
156 int module_id, int instance_id)
157{
158 struct uuid_module *module;
159
160 list_for_each_entry(module, &ctx->uuid_list, list) {
161 if (module->id == module_id)
162 return skl_get_pvtid_map(module, instance_id);
163 }
164
165 return -EINVAL;
166}
167EXPORT_SYMBOL_GPL(skl_get_pvt_instance_id_map);
168
169static inline int skl_getid_32(struct uuid_module *module, u64 *val,
170 int word1_mask, int word2_mask)
171{
172 int index, max_inst, pvt_id;
173 u32 mask_val;
174
175 max_inst = module->max_instance;
176 mask_val = (u32)(*val >> word1_mask);
177
178 if (mask_val != 0xffffffff) {
179 index = ffz(mask_val);
180 pvt_id = index + word1_mask + word2_mask;
181 if (pvt_id <= (max_inst - 1)) {
182 *val |= 1 << (index + word1_mask);
183 return pvt_id;
184 }
185 }
186
187 return -EINVAL;
188}
189
190static inline int skl_pvtid_128(struct uuid_module *module)
191{
192 int j, i, word1_mask, word2_mask = 0, pvt_id;
193
194 for (j = 0; j < MAX_INSTANCE_BUFF; j++) {
195 word1_mask = 0;
196
197 for (i = 0; i < 2; i++) {
198 pvt_id = skl_getid_32(module, &module->pvt_id[j],
199 word1_mask, word2_mask);
200 if (pvt_id >= 0)
201 return pvt_id;
202
203 word1_mask += 32;
204 if ((word1_mask + word2_mask) >= module->max_instance)
205 return -EINVAL;
206 }
207
208 word2_mask += 64;
209 if (word2_mask >= module->max_instance)
210 return -EINVAL;
211 }
212
213 return -EINVAL;
214}
215
216/**
217 * skl_get_pvt_id: generate a private id for use as module id
218 *
219 * @ctx: driver context
220 * @mconfig: module configuration data
221 *
222 * This generates a 128 bit private unique id for a module TYPE so that
223 * module instance is unique
224 */
225int skl_get_pvt_id(struct skl_sst *ctx, struct skl_module_cfg *mconfig)
226{
227 struct uuid_module *module;
228 uuid_le *uuid_mod;
229 int pvt_id;
230
231 uuid_mod = (uuid_le *)mconfig->guid;
232
233 list_for_each_entry(module, &ctx->uuid_list, list) {
234 if (uuid_le_cmp(*uuid_mod, module->uuid) == 0) {
235
236 pvt_id = skl_pvtid_128(module);
237 if (pvt_id >= 0) {
238 module->instance_id[pvt_id] =
239 mconfig->id.instance_id;
240 return pvt_id;
241 }
242 }
243 }
244
245 return -EINVAL;
246}
247EXPORT_SYMBOL_GPL(skl_get_pvt_id);
248
249/**
250 * skl_put_pvt_id: free up the private id allocated
251 *
252 * @ctx: driver context
253 * @mconfig: module configuration data
254 *
255 * This frees a 128 bit private unique id previously generated
256 */
257int skl_put_pvt_id(struct skl_sst *ctx, struct skl_module_cfg *mconfig)
258{
259 int i;
260 uuid_le *uuid_mod;
261 struct uuid_module *module;
262
263 uuid_mod = (uuid_le *)mconfig->guid;
264 list_for_each_entry(module, &ctx->uuid_list, list) {
265 if (uuid_le_cmp(*uuid_mod, module->uuid) == 0) {
266
267 if (mconfig->id.pvt_id != 0)
268 i = (mconfig->id.pvt_id) / 64;
269 else
270 i = 0;
271
272 module->pvt_id[i] &= ~(1 << (mconfig->id.pvt_id));
273 mconfig->id.pvt_id = -1;
274 return 0;
275 }
276 }
277
278 return -EINVAL;
279}
280EXPORT_SYMBOL_GPL(skl_put_pvt_id);
281
144/* 282/*
145 * Parse the firmware binary to get the UUID, module id 283 * Parse the firmware binary to get the UUID, module id
146 * and loadable flags 284 * and loadable flags
147 */ 285 */
148int snd_skl_parse_uuids(struct sst_dsp *ctx, unsigned int offset) 286int snd_skl_parse_uuids(struct sst_dsp *ctx, const struct firmware *fw,
287 unsigned int offset, int index)
149{ 288{
150 struct adsp_fw_hdr *adsp_hdr; 289 struct adsp_fw_hdr *adsp_hdr;
151 struct adsp_module_entry *mod_entry; 290 struct adsp_module_entry *mod_entry;
152 int i, num_entry; 291 int i, num_entry, size;
153 uuid_le *uuid_bin; 292 uuid_le *uuid_bin;
154 const char *buf; 293 const char *buf;
155 struct skl_sst *skl = ctx->thread_context; 294 struct skl_sst *skl = ctx->thread_context;
@@ -158,8 +297,8 @@ int snd_skl_parse_uuids(struct sst_dsp *ctx, unsigned int offset)
158 unsigned int safe_file; 297 unsigned int safe_file;
159 298
160 /* Get the FW pointer to derive ADSP header */ 299 /* Get the FW pointer to derive ADSP header */
161 stripped_fw.data = ctx->fw->data; 300 stripped_fw.data = fw->data;
162 stripped_fw.size = ctx->fw->size; 301 stripped_fw.size = fw->size;
163 302
164 skl_dsp_strip_extended_manifest(&stripped_fw); 303 skl_dsp_strip_extended_manifest(&stripped_fw);
165 304
@@ -210,8 +349,15 @@ int snd_skl_parse_uuids(struct sst_dsp *ctx, unsigned int offset)
210 uuid_bin = (uuid_le *)mod_entry->uuid.id; 349 uuid_bin = (uuid_le *)mod_entry->uuid.id;
211 memcpy(&module->uuid, uuid_bin, sizeof(module->uuid)); 350 memcpy(&module->uuid, uuid_bin, sizeof(module->uuid));
212 351
213 module->id = i; 352 module->id = (i | (index << 12));
214 module->is_loadable = mod_entry->type.load_type; 353 module->is_loadable = mod_entry->type.load_type;
354 module->max_instance = mod_entry->instance_max_count;
355 size = sizeof(int) * mod_entry->instance_max_count;
356 module->instance_id = devm_kzalloc(ctx->dev, size, GFP_KERNEL);
357 if (!module->instance_id) {
358 kfree(module);
359 return -ENOMEM;
360 }
215 361
216 list_add_tail(&module->list, &skl->uuid_list); 362 list_add_tail(&module->list, &skl->uuid_list);
217 363
diff --git a/sound/soc/intel/skylake/skl-sst.c b/sound/soc/intel/skylake/skl-sst.c
index 588f899ceb65..8fc3178bc79c 100644
--- a/sound/soc/intel/skylake/skl-sst.c
+++ b/sound/soc/intel/skylake/skl-sst.c
@@ -88,13 +88,15 @@ static int skl_load_base_firmware(struct sst_dsp *ctx)
88 } 88 }
89 } 89 }
90 90
91 ret = snd_skl_parse_uuids(ctx, SKL_ADSP_FW_BIN_HDR_OFFSET); 91 /* prase uuids on first boot */
92 if (ret < 0) { 92 if (skl->is_first_boot) {
93 dev_err(ctx->dev, 93 ret = snd_skl_parse_uuids(ctx, ctx->fw, SKL_ADSP_FW_BIN_HDR_OFFSET, 0);
94 "UUID parsing err: %d\n", ret); 94 if (ret < 0) {
95 release_firmware(ctx->fw); 95 dev_err(ctx->dev, "UUID parsing err: %d\n", ret);
96 skl_dsp_disable_core(ctx, SKL_DSP_CORE0_MASK); 96 release_firmware(ctx->fw);
97 return ret; 97 skl_dsp_disable_core(ctx, SKL_DSP_CORE0_MASK);
98 return ret;
99 }
98 } 100 }
99 101
100 /* check for extended manifest */ 102 /* check for extended manifest */
@@ -105,13 +107,13 @@ static int skl_load_base_firmware(struct sst_dsp *ctx)
105 107
106 ret = skl_dsp_boot(ctx); 108 ret = skl_dsp_boot(ctx);
107 if (ret < 0) { 109 if (ret < 0) {
108 dev_err(ctx->dev, "Boot dsp core failed ret: %d", ret); 110 dev_err(ctx->dev, "Boot dsp core failed ret: %d\n", ret);
109 goto skl_load_base_firmware_failed; 111 goto skl_load_base_firmware_failed;
110 } 112 }
111 113
112 ret = skl_cldma_prepare(ctx); 114 ret = skl_cldma_prepare(ctx);
113 if (ret < 0) { 115 if (ret < 0) {
114 dev_err(ctx->dev, "CL dma prepare failed : %d", ret); 116 dev_err(ctx->dev, "CL dma prepare failed : %d\n", ret);
115 goto skl_load_base_firmware_failed; 117 goto skl_load_base_firmware_failed;
116 } 118 }
117 119
@@ -484,25 +486,32 @@ int skl_sst_dsp_init(struct device *dev, void __iomem *mmio_base, int irq,
484 return ret; 486 return ret;
485 487
486 skl->cores.count = 2; 488 skl->cores.count = 2;
489 skl->is_first_boot = true;
490
491 if (dsp)
492 *dsp = skl;
493
494 return ret;
495}
496EXPORT_SYMBOL_GPL(skl_sst_dsp_init);
497
498int skl_sst_init_fw(struct device *dev, struct skl_sst *ctx)
499{
500 int ret;
501 struct sst_dsp *sst = ctx->dsp;
487 502
488 ret = sst->fw_ops.load_fw(sst); 503 ret = sst->fw_ops.load_fw(sst);
489 if (ret < 0) { 504 if (ret < 0) {
490 dev_err(dev, "Load base fw failed : %d", ret); 505 dev_err(dev, "Load base fw failed : %d\n", ret);
491 goto cleanup; 506 return ret;
492 } 507 }
493 508
494 skl_dsp_init_core_state(sst); 509 skl_dsp_init_core_state(sst);
510 ctx->is_first_boot = false;
495 511
496 if (dsp) 512 return 0;
497 *dsp = skl;
498
499 return ret;
500
501cleanup:
502 skl_sst_dsp_cleanup(dev, skl);
503 return ret;
504} 513}
505EXPORT_SYMBOL_GPL(skl_sst_dsp_init); 514EXPORT_SYMBOL_GPL(skl_sst_init_fw);
506 515
507void skl_sst_dsp_cleanup(struct device *dev, struct skl_sst *ctx) 516void skl_sst_dsp_cleanup(struct device *dev, struct skl_sst *ctx)
508{ 517{
diff --git a/sound/soc/intel/skylake/skl-topology.c b/sound/soc/intel/skylake/skl-topology.c
index cc0150fc2601..b5b1934d8550 100644
--- a/sound/soc/intel/skylake/skl-topology.c
+++ b/sound/soc/intel/skylake/skl-topology.c
@@ -21,6 +21,7 @@
21#include <linux/firmware.h> 21#include <linux/firmware.h>
22#include <sound/soc.h> 22#include <sound/soc.h>
23#include <sound/soc-topology.h> 23#include <sound/soc-topology.h>
24#include <uapi/sound/snd_sst_tokens.h>
24#include "skl-sst-dsp.h" 25#include "skl-sst-dsp.h"
25#include "skl-sst-ipc.h" 26#include "skl-sst-ipc.h"
26#include "skl-topology.h" 27#include "skl-topology.h"
@@ -32,6 +33,8 @@
32#define SKL_CH_FIXUP_MASK (1 << 0) 33#define SKL_CH_FIXUP_MASK (1 << 0)
33#define SKL_RATE_FIXUP_MASK (1 << 1) 34#define SKL_RATE_FIXUP_MASK (1 << 1)
34#define SKL_FMT_FIXUP_MASK (1 << 2) 35#define SKL_FMT_FIXUP_MASK (1 << 2)
36#define SKL_IN_DIR_BIT_MASK BIT(0)
37#define SKL_PIN_COUNT_MASK GENMASK(7, 4)
35 38
36/* 39/*
37 * SKL DSP driver modelling uses only few DAPM widgets so for rest we will 40 * SKL DSP driver modelling uses only few DAPM widgets so for rest we will
@@ -473,6 +476,14 @@ skl_tplg_init_pipe_modules(struct skl *skl, struct skl_pipe *pipe)
473 w = w_module->w; 476 w = w_module->w;
474 mconfig = w->priv; 477 mconfig = w->priv;
475 478
479 /* check if module ids are populated */
480 if (mconfig->id.module_id < 0) {
481 dev_err(skl->skl_sst->dev,
482 "module %pUL id not populated\n",
483 (uuid_le *)mconfig->guid);
484 return -EIO;
485 }
486
476 /* check resource available */ 487 /* check resource available */
477 if (!skl_is_pipe_mcps_avail(skl, mconfig)) 488 if (!skl_is_pipe_mcps_avail(skl, mconfig))
478 return -ENOMEM; 489 return -ENOMEM;
@@ -494,12 +505,15 @@ skl_tplg_init_pipe_modules(struct skl *skl, struct skl_pipe *pipe)
494 * FE/BE params 505 * FE/BE params
495 */ 506 */
496 skl_tplg_update_module_params(w, ctx); 507 skl_tplg_update_module_params(w, ctx);
497 508 mconfig->id.pvt_id = skl_get_pvt_id(ctx, mconfig);
509 if (mconfig->id.pvt_id < 0)
510 return ret;
498 skl_tplg_set_module_init_data(w); 511 skl_tplg_set_module_init_data(w);
499 ret = skl_init_module(ctx, mconfig); 512 ret = skl_init_module(ctx, mconfig);
500 if (ret < 0) 513 if (ret < 0) {
514 skl_put_pvt_id(ctx, mconfig);
501 return ret; 515 return ret;
502 516 }
503 skl_tplg_alloc_pipe_mcps(skl, mconfig); 517 skl_tplg_alloc_pipe_mcps(skl, mconfig);
504 ret = skl_tplg_set_module_params(w, ctx); 518 ret = skl_tplg_set_module_params(w, ctx);
505 if (ret < 0) 519 if (ret < 0)
@@ -512,6 +526,7 @@ skl_tplg_init_pipe_modules(struct skl *skl, struct skl_pipe *pipe)
512static int skl_tplg_unload_pipe_modules(struct skl_sst *ctx, 526static int skl_tplg_unload_pipe_modules(struct skl_sst *ctx,
513 struct skl_pipe *pipe) 527 struct skl_pipe *pipe)
514{ 528{
529 int ret;
515 struct skl_pipe_module *w_module = NULL; 530 struct skl_pipe_module *w_module = NULL;
516 struct skl_module_cfg *mconfig = NULL; 531 struct skl_module_cfg *mconfig = NULL;
517 532
@@ -519,9 +534,13 @@ static int skl_tplg_unload_pipe_modules(struct skl_sst *ctx,
519 mconfig = w_module->w->priv; 534 mconfig = w_module->w->priv;
520 535
521 if (mconfig->is_loadable && ctx->dsp->fw_ops.unload_mod && 536 if (mconfig->is_loadable && ctx->dsp->fw_ops.unload_mod &&
522 mconfig->m_state > SKL_MODULE_UNINIT) 537 mconfig->m_state > SKL_MODULE_UNINIT) {
523 return ctx->dsp->fw_ops.unload_mod(ctx->dsp, 538 ret = ctx->dsp->fw_ops.unload_mod(ctx->dsp,
524 mconfig->id.module_id); 539 mconfig->id.module_id);
540 if (ret < 0)
541 return -EIO;
542 }
543 skl_put_pvt_id(ctx, mconfig);
525 } 544 }
526 545
527 /* no modules to unload in this path, so return */ 546 /* no modules to unload in this path, so return */
@@ -588,6 +607,26 @@ static int skl_tplg_mixer_dapm_pre_pmu_event(struct snd_soc_dapm_widget *w,
588 return 0; 607 return 0;
589} 608}
590 609
610static int skl_fill_sink_instance_id(struct skl_sst *ctx,
611 struct skl_algo_data *alg_data)
612{
613 struct skl_kpb_params *params = (struct skl_kpb_params *)alg_data->params;
614 struct skl_mod_inst_map *inst;
615 int i, pvt_id;
616
617 inst = params->map;
618
619 for (i = 0; i < params->num_modules; i++) {
620 pvt_id = skl_get_pvt_instance_id_map(ctx,
621 inst->mod_id, inst->inst_id);
622 if (pvt_id < 0)
623 return -EINVAL;
624 inst->inst_id = pvt_id;
625 inst++;
626 }
627 return 0;
628}
629
591/* 630/*
592 * Some modules require params to be set after the module is bound to 631 * Some modules require params to be set after the module is bound to
593 * all pins connected. 632 * all pins connected.
@@ -636,6 +675,8 @@ static int skl_tplg_set_module_bind_params(struct snd_soc_dapm_widget *w,
636 bc = (struct skl_algo_data *)sb->dobj.private; 675 bc = (struct skl_algo_data *)sb->dobj.private;
637 676
638 if (bc->set_params == SKL_PARAM_BIND) { 677 if (bc->set_params == SKL_PARAM_BIND) {
678 if (mconfig->m_type == SKL_MODULE_TYPE_KPB)
679 skl_fill_sink_instance_id(ctx, bc);
639 ret = skl_set_module_params(ctx, 680 ret = skl_set_module_params(ctx,
640 (u32 *)bc->params, bc->max, 681 (u32 *)bc->params, bc->max,
641 bc->param_id, mconfig); 682 bc->param_id, mconfig);
@@ -1460,85 +1501,570 @@ static const struct snd_soc_tplg_bytes_ext_ops skl_tlv_ops[] = {
1460 skl_tplg_tlv_control_set}, 1501 skl_tplg_tlv_control_set},
1461}; 1502};
1462 1503
1463/* 1504static int skl_tplg_fill_pipe_tkn(struct device *dev,
1464 * The topology binary passes the pin info for a module so initialize the pin 1505 struct skl_pipe *pipe, u32 tkn,
1465 * info passed into module instance 1506 u32 tkn_val)
1466 */
1467static void skl_fill_module_pin_info(struct skl_dfw_module_pin *dfw_pin,
1468 struct skl_module_pin *m_pin,
1469 bool is_dynamic, int max_pin)
1470{ 1507{
1471 int i;
1472 1508
1473 for (i = 0; i < max_pin; i++) { 1509 switch (tkn) {
1474 m_pin[i].id.module_id = dfw_pin[i].module_id; 1510 case SKL_TKN_U32_PIPE_CONN_TYPE:
1475 m_pin[i].id.instance_id = dfw_pin[i].instance_id; 1511 pipe->conn_type = tkn_val;
1476 m_pin[i].in_use = false; 1512 break;
1477 m_pin[i].is_dynamic = is_dynamic; 1513
1478 m_pin[i].pin_state = SKL_PIN_UNBIND; 1514 case SKL_TKN_U32_PIPE_PRIORITY:
1515 pipe->pipe_priority = tkn_val;
1516 break;
1517
1518 case SKL_TKN_U32_PIPE_MEM_PGS:
1519 pipe->memory_pages = tkn_val;
1520 break;
1521
1522 default:
1523 dev_err(dev, "Token not handled %d\n", tkn);
1524 return -EINVAL;
1479 } 1525 }
1526
1527 return 0;
1480} 1528}
1481 1529
1482/* 1530/*
1483 * Add pipeline from topology binary into driver pipeline list 1531 * Add pipeline by parsing the relevant tokens
1484 * 1532 * Return an existing pipe if the pipe already exists.
1485 * If already added we return that instance
1486 * Otherwise we create a new instance and add into driver list
1487 */ 1533 */
1488static struct skl_pipe *skl_tplg_add_pipe(struct device *dev, 1534static int skl_tplg_add_pipe(struct device *dev,
1489 struct skl *skl, struct skl_dfw_pipe *dfw_pipe) 1535 struct skl_module_cfg *mconfig, struct skl *skl,
1536 struct snd_soc_tplg_vendor_value_elem *tkn_elem)
1490{ 1537{
1491 struct skl_pipeline *ppl; 1538 struct skl_pipeline *ppl;
1492 struct skl_pipe *pipe; 1539 struct skl_pipe *pipe;
1493 struct skl_pipe_params *params; 1540 struct skl_pipe_params *params;
1494 1541
1495 list_for_each_entry(ppl, &skl->ppl_list, node) { 1542 list_for_each_entry(ppl, &skl->ppl_list, node) {
1496 if (ppl->pipe->ppl_id == dfw_pipe->pipe_id) 1543 if (ppl->pipe->ppl_id == tkn_elem->value) {
1497 return ppl->pipe; 1544 mconfig->pipe = ppl->pipe;
1545 return EEXIST;
1546 }
1498 } 1547 }
1499 1548
1500 ppl = devm_kzalloc(dev, sizeof(*ppl), GFP_KERNEL); 1549 ppl = devm_kzalloc(dev, sizeof(*ppl), GFP_KERNEL);
1501 if (!ppl) 1550 if (!ppl)
1502 return NULL; 1551 return -ENOMEM;
1503 1552
1504 pipe = devm_kzalloc(dev, sizeof(*pipe), GFP_KERNEL); 1553 pipe = devm_kzalloc(dev, sizeof(*pipe), GFP_KERNEL);
1505 if (!pipe) 1554 if (!pipe)
1506 return NULL; 1555 return -ENOMEM;
1507 1556
1508 params = devm_kzalloc(dev, sizeof(*params), GFP_KERNEL); 1557 params = devm_kzalloc(dev, sizeof(*params), GFP_KERNEL);
1509 if (!params) 1558 if (!params)
1510 return NULL; 1559 return -ENOMEM;
1511 1560
1512 pipe->ppl_id = dfw_pipe->pipe_id;
1513 pipe->memory_pages = dfw_pipe->memory_pages;
1514 pipe->pipe_priority = dfw_pipe->pipe_priority;
1515 pipe->conn_type = dfw_pipe->conn_type;
1516 pipe->state = SKL_PIPE_INVALID;
1517 pipe->p_params = params; 1561 pipe->p_params = params;
1562 pipe->ppl_id = tkn_elem->value;
1518 INIT_LIST_HEAD(&pipe->w_list); 1563 INIT_LIST_HEAD(&pipe->w_list);
1519 1564
1520 ppl->pipe = pipe; 1565 ppl->pipe = pipe;
1521 list_add(&ppl->node, &skl->ppl_list); 1566 list_add(&ppl->node, &skl->ppl_list);
1522 1567
1523 return ppl->pipe; 1568 mconfig->pipe = pipe;
1569 mconfig->pipe->state = SKL_PIPE_INVALID;
1570
1571 return 0;
1572}
1573
1574static int skl_tplg_fill_pin(struct device *dev, u32 tkn,
1575 struct skl_module_pin *m_pin,
1576 int pin_index, u32 value)
1577{
1578 switch (tkn) {
1579 case SKL_TKN_U32_PIN_MOD_ID:
1580 m_pin[pin_index].id.module_id = value;
1581 break;
1582
1583 case SKL_TKN_U32_PIN_INST_ID:
1584 m_pin[pin_index].id.instance_id = value;
1585 break;
1586
1587 default:
1588 dev_err(dev, "%d Not a pin token\n", value);
1589 return -EINVAL;
1590 }
1591
1592 return 0;
1593}
1594
1595/*
1596 * Parse for pin config specific tokens to fill up the
1597 * module private data
1598 */
1599static int skl_tplg_fill_pins_info(struct device *dev,
1600 struct skl_module_cfg *mconfig,
1601 struct snd_soc_tplg_vendor_value_elem *tkn_elem,
1602 int dir, int pin_count)
1603{
1604 int ret;
1605 struct skl_module_pin *m_pin;
1606
1607 switch (dir) {
1608 case SKL_DIR_IN:
1609 m_pin = mconfig->m_in_pin;
1610 break;
1611
1612 case SKL_DIR_OUT:
1613 m_pin = mconfig->m_out_pin;
1614 break;
1615
1616 default:
1617 dev_err(dev, "Invalid direction value\n");
1618 return -EINVAL;
1619 }
1620
1621 ret = skl_tplg_fill_pin(dev, tkn_elem->token,
1622 m_pin, pin_count, tkn_elem->value);
1623
1624 if (ret < 0)
1625 return ret;
1626
1627 m_pin[pin_count].in_use = false;
1628 m_pin[pin_count].pin_state = SKL_PIN_UNBIND;
1629
1630 return 0;
1631}
1632
1633/*
1634 * Fill up input/output module config format based
1635 * on the direction
1636 */
1637static int skl_tplg_fill_fmt(struct device *dev,
1638 struct skl_module_cfg *mconfig, u32 tkn,
1639 u32 value, u32 dir, u32 pin_count)
1640{
1641 struct skl_module_fmt *dst_fmt;
1642
1643 switch (dir) {
1644 case SKL_DIR_IN:
1645 dst_fmt = mconfig->in_fmt;
1646 dst_fmt += pin_count;
1647 break;
1648
1649 case SKL_DIR_OUT:
1650 dst_fmt = mconfig->out_fmt;
1651 dst_fmt += pin_count;
1652 break;
1653
1654 default:
1655 dev_err(dev, "Invalid direction value\n");
1656 return -EINVAL;
1657 }
1658
1659 switch (tkn) {
1660 case SKL_TKN_U32_FMT_CH:
1661 dst_fmt->channels = value;
1662 break;
1663
1664 case SKL_TKN_U32_FMT_FREQ:
1665 dst_fmt->s_freq = value;
1666 break;
1667
1668 case SKL_TKN_U32_FMT_BIT_DEPTH:
1669 dst_fmt->bit_depth = value;
1670 break;
1671
1672 case SKL_TKN_U32_FMT_SAMPLE_SIZE:
1673 dst_fmt->valid_bit_depth = value;
1674 break;
1675
1676 case SKL_TKN_U32_FMT_CH_CONFIG:
1677 dst_fmt->ch_cfg = value;
1678 break;
1679
1680 case SKL_TKN_U32_FMT_INTERLEAVE:
1681 dst_fmt->interleaving_style = value;
1682 break;
1683
1684 case SKL_TKN_U32_FMT_SAMPLE_TYPE:
1685 dst_fmt->sample_type = value;
1686 break;
1687
1688 case SKL_TKN_U32_FMT_CH_MAP:
1689 dst_fmt->ch_map = value;
1690 break;
1691
1692 default:
1693 dev_err(dev, "Invalid token %d\n", tkn);
1694 return -EINVAL;
1695 }
1696
1697 return 0;
1524} 1698}
1525 1699
1526static void skl_tplg_fill_fmt(struct skl_module_fmt *dst_fmt, 1700static int skl_tplg_get_uuid(struct device *dev, struct skl_module_cfg *mconfig,
1527 struct skl_dfw_module_fmt *src_fmt, 1701 struct snd_soc_tplg_vendor_uuid_elem *uuid_tkn)
1528 int pins) 1702{
1703 if (uuid_tkn->token == SKL_TKN_UUID)
1704 memcpy(&mconfig->guid, &uuid_tkn->uuid, 16);
1705 else {
1706 dev_err(dev, "Not an UUID token tkn %d\n", uuid_tkn->token);
1707 return -EINVAL;
1708 }
1709
1710 return 0;
1711}
1712
1713static void skl_tplg_fill_pin_dynamic_val(
1714 struct skl_module_pin *mpin, u32 pin_count, u32 value)
1529{ 1715{
1530 int i; 1716 int i;
1531 1717
1532 for (i = 0; i < pins; i++) { 1718 for (i = 0; i < pin_count; i++)
1533 dst_fmt[i].channels = src_fmt[i].channels; 1719 mpin[i].is_dynamic = value;
1534 dst_fmt[i].s_freq = src_fmt[i].freq; 1720}
1535 dst_fmt[i].bit_depth = src_fmt[i].bit_depth; 1721
1536 dst_fmt[i].valid_bit_depth = src_fmt[i].valid_bit_depth; 1722/*
1537 dst_fmt[i].ch_cfg = src_fmt[i].ch_cfg; 1723 * Parse tokens to fill up the module private data
1538 dst_fmt[i].ch_map = src_fmt[i].ch_map; 1724 */
1539 dst_fmt[i].interleaving_style = src_fmt[i].interleaving_style; 1725static int skl_tplg_get_token(struct device *dev,
1540 dst_fmt[i].sample_type = src_fmt[i].sample_type; 1726 struct snd_soc_tplg_vendor_value_elem *tkn_elem,
1727 struct skl *skl, struct skl_module_cfg *mconfig)
1728{
1729 int tkn_count = 0;
1730 int ret;
1731 static int is_pipe_exists;
1732 static int pin_index, dir;
1733
1734 if (tkn_elem->token > SKL_TKN_MAX)
1735 return -EINVAL;
1736
1737 switch (tkn_elem->token) {
1738 case SKL_TKN_U8_IN_QUEUE_COUNT:
1739 mconfig->max_in_queue = tkn_elem->value;
1740 mconfig->m_in_pin = devm_kzalloc(dev, mconfig->max_in_queue *
1741 sizeof(*mconfig->m_in_pin),
1742 GFP_KERNEL);
1743 if (!mconfig->m_in_pin)
1744 return -ENOMEM;
1745
1746 break;
1747
1748 case SKL_TKN_U8_OUT_QUEUE_COUNT:
1749 mconfig->max_out_queue = tkn_elem->value;
1750 mconfig->m_out_pin = devm_kzalloc(dev, mconfig->max_out_queue *
1751 sizeof(*mconfig->m_out_pin),
1752 GFP_KERNEL);
1753
1754 if (!mconfig->m_out_pin)
1755 return -ENOMEM;
1756
1757 break;
1758
1759 case SKL_TKN_U8_DYN_IN_PIN:
1760 if (!mconfig->m_in_pin)
1761 return -ENOMEM;
1762
1763 skl_tplg_fill_pin_dynamic_val(mconfig->m_in_pin,
1764 mconfig->max_in_queue, tkn_elem->value);
1765
1766 break;
1767
1768 case SKL_TKN_U8_DYN_OUT_PIN:
1769 if (!mconfig->m_out_pin)
1770 return -ENOMEM;
1771
1772 skl_tplg_fill_pin_dynamic_val(mconfig->m_out_pin,
1773 mconfig->max_out_queue, tkn_elem->value);
1774
1775 break;
1776
1777 case SKL_TKN_U8_TIME_SLOT:
1778 mconfig->time_slot = tkn_elem->value;
1779 break;
1780
1781 case SKL_TKN_U8_CORE_ID:
1782 mconfig->core_id = tkn_elem->value;
1783
1784 case SKL_TKN_U8_MOD_TYPE:
1785 mconfig->m_type = tkn_elem->value;
1786 break;
1787
1788 case SKL_TKN_U8_DEV_TYPE:
1789 mconfig->dev_type = tkn_elem->value;
1790 break;
1791
1792 case SKL_TKN_U8_HW_CONN_TYPE:
1793 mconfig->hw_conn_type = tkn_elem->value;
1794 break;
1795
1796 case SKL_TKN_U16_MOD_INST_ID:
1797 mconfig->id.instance_id =
1798 tkn_elem->value;
1799 break;
1800
1801 case SKL_TKN_U32_MEM_PAGES:
1802 mconfig->mem_pages = tkn_elem->value;
1803 break;
1804
1805 case SKL_TKN_U32_MAX_MCPS:
1806 mconfig->mcps = tkn_elem->value;
1807 break;
1808
1809 case SKL_TKN_U32_OBS:
1810 mconfig->obs = tkn_elem->value;
1811 break;
1812
1813 case SKL_TKN_U32_IBS:
1814 mconfig->ibs = tkn_elem->value;
1815 break;
1816
1817 case SKL_TKN_U32_VBUS_ID:
1818 mconfig->vbus_id = tkn_elem->value;
1819 break;
1820
1821 case SKL_TKN_U32_PARAMS_FIXUP:
1822 mconfig->params_fixup = tkn_elem->value;
1823 break;
1824
1825 case SKL_TKN_U32_CONVERTER:
1826 mconfig->converter = tkn_elem->value;
1827 break;
1828
1829 case SKL_TKN_U32_PIPE_ID:
1830 ret = skl_tplg_add_pipe(dev,
1831 mconfig, skl, tkn_elem);
1832
1833 if (ret < 0)
1834 return is_pipe_exists;
1835
1836 if (ret == EEXIST)
1837 is_pipe_exists = 1;
1838
1839 break;
1840
1841 case SKL_TKN_U32_PIPE_CONN_TYPE:
1842 case SKL_TKN_U32_PIPE_PRIORITY:
1843 case SKL_TKN_U32_PIPE_MEM_PGS:
1844 if (is_pipe_exists) {
1845 ret = skl_tplg_fill_pipe_tkn(dev, mconfig->pipe,
1846 tkn_elem->token, tkn_elem->value);
1847 if (ret < 0)
1848 return ret;
1849 }
1850
1851 break;
1852
1853 /*
1854 * SKL_TKN_U32_DIR_PIN_COUNT token has the value for both
1855 * direction and the pin count. The first four bits represent
1856 * direction and next four the pin count.
1857 */
1858 case SKL_TKN_U32_DIR_PIN_COUNT:
1859 dir = tkn_elem->value & SKL_IN_DIR_BIT_MASK;
1860 pin_index = (tkn_elem->value &
1861 SKL_PIN_COUNT_MASK) >> 4;
1862
1863 break;
1864
1865 case SKL_TKN_U32_FMT_CH:
1866 case SKL_TKN_U32_FMT_FREQ:
1867 case SKL_TKN_U32_FMT_BIT_DEPTH:
1868 case SKL_TKN_U32_FMT_SAMPLE_SIZE:
1869 case SKL_TKN_U32_FMT_CH_CONFIG:
1870 case SKL_TKN_U32_FMT_INTERLEAVE:
1871 case SKL_TKN_U32_FMT_SAMPLE_TYPE:
1872 case SKL_TKN_U32_FMT_CH_MAP:
1873 ret = skl_tplg_fill_fmt(dev, mconfig, tkn_elem->token,
1874 tkn_elem->value, dir, pin_index);
1875
1876 if (ret < 0)
1877 return ret;
1878
1879 break;
1880
1881 case SKL_TKN_U32_PIN_MOD_ID:
1882 case SKL_TKN_U32_PIN_INST_ID:
1883 ret = skl_tplg_fill_pins_info(dev,
1884 mconfig, tkn_elem, dir,
1885 pin_index);
1886 if (ret < 0)
1887 return ret;
1888
1889 break;
1890
1891 case SKL_TKN_U32_CAPS_SIZE:
1892 mconfig->formats_config.caps_size =
1893 tkn_elem->value;
1894
1895 break;
1896
1897 case SKL_TKN_U32_PROC_DOMAIN:
1898 mconfig->domain =
1899 tkn_elem->value;
1900
1901 break;
1902
1903 case SKL_TKN_U8_IN_PIN_TYPE:
1904 case SKL_TKN_U8_OUT_PIN_TYPE:
1905 case SKL_TKN_U8_CONN_TYPE:
1906 break;
1907
1908 default:
1909 dev_err(dev, "Token %d not handled\n",
1910 tkn_elem->token);
1911 return -EINVAL;
1912 }
1913
1914 tkn_count++;
1915
1916 return tkn_count;
1917}
1918
1919/*
1920 * Parse the vendor array for specific tokens to construct
1921 * module private data
1922 */
1923static int skl_tplg_get_tokens(struct device *dev,
1924 char *pvt_data, struct skl *skl,
1925 struct skl_module_cfg *mconfig, int block_size)
1926{
1927 struct snd_soc_tplg_vendor_array *array;
1928 struct snd_soc_tplg_vendor_value_elem *tkn_elem;
1929 int tkn_count = 0, ret;
1930 int off = 0, tuple_size = 0;
1931
1932 if (block_size <= 0)
1933 return -EINVAL;
1934
1935 while (tuple_size < block_size) {
1936 array = (struct snd_soc_tplg_vendor_array *)(pvt_data + off);
1937
1938 off += array->size;
1939
1940 switch (array->type) {
1941 case SND_SOC_TPLG_TUPLE_TYPE_STRING:
1942 dev_warn(dev, "no string tokens expected for skl tplg\n");
1943 continue;
1944
1945 case SND_SOC_TPLG_TUPLE_TYPE_UUID:
1946 ret = skl_tplg_get_uuid(dev, mconfig, array->uuid);
1947 if (ret < 0)
1948 return ret;
1949
1950 tuple_size += sizeof(*array->uuid);
1951
1952 continue;
1953
1954 default:
1955 tkn_elem = array->value;
1956 tkn_count = 0;
1957 break;
1958 }
1959
1960 while (tkn_count <= (array->num_elems - 1)) {
1961 ret = skl_tplg_get_token(dev, tkn_elem,
1962 skl, mconfig);
1963
1964 if (ret < 0)
1965 return ret;
1966
1967 tkn_count = tkn_count + ret;
1968 tkn_elem++;
1969 }
1970
1971 tuple_size += tkn_count * sizeof(*tkn_elem);
1972 }
1973
1974 return 0;
1975}
1976
1977/*
1978 * Every data block is preceded by a descriptor to read the number
1979 * of data blocks, they type of the block and it's size
1980 */
1981static int skl_tplg_get_desc_blocks(struct device *dev,
1982 struct snd_soc_tplg_vendor_array *array)
1983{
1984 struct snd_soc_tplg_vendor_value_elem *tkn_elem;
1985
1986 tkn_elem = array->value;
1987
1988 switch (tkn_elem->token) {
1989 case SKL_TKN_U8_NUM_BLOCKS:
1990 case SKL_TKN_U8_BLOCK_TYPE:
1991 case SKL_TKN_U16_BLOCK_SIZE:
1992 return tkn_elem->value;
1993
1994 default:
1995 dev_err(dev, "Invalid descriptor token %d\n", tkn_elem->token);
1996 break;
1997 }
1998
1999 return -EINVAL;
2000}
2001
2002/*
2003 * Parse the private data for the token and corresponding value.
2004 * The private data can have multiple data blocks. So, a data block
2005 * is preceded by a descriptor for number of blocks and a descriptor
2006 * for the type and size of the suceeding data block.
2007 */
2008static int skl_tplg_get_pvt_data(struct snd_soc_tplg_dapm_widget *tplg_w,
2009 struct skl *skl, struct device *dev,
2010 struct skl_module_cfg *mconfig)
2011{
2012 struct snd_soc_tplg_vendor_array *array;
2013 int num_blocks, block_size = 0, block_type, off = 0;
2014 char *data;
2015 int ret;
2016
2017 /* Read the NUM_DATA_BLOCKS descriptor */
2018 array = (struct snd_soc_tplg_vendor_array *)tplg_w->priv.data;
2019 ret = skl_tplg_get_desc_blocks(dev, array);
2020 if (ret < 0)
2021 return ret;
2022 num_blocks = ret;
2023
2024 off += array->size;
2025 array = (struct snd_soc_tplg_vendor_array *)(tplg_w->priv.data + off);
2026
2027 /* Read the BLOCK_TYPE and BLOCK_SIZE descriptor */
2028 while (num_blocks > 0) {
2029 ret = skl_tplg_get_desc_blocks(dev, array);
2030
2031 if (ret < 0)
2032 return ret;
2033 block_type = ret;
2034 off += array->size;
2035
2036 array = (struct snd_soc_tplg_vendor_array *)
2037 (tplg_w->priv.data + off);
2038
2039 ret = skl_tplg_get_desc_blocks(dev, array);
2040
2041 if (ret < 0)
2042 return ret;
2043 block_size = ret;
2044 off += array->size;
2045
2046 array = (struct snd_soc_tplg_vendor_array *)
2047 (tplg_w->priv.data + off);
2048
2049 data = (tplg_w->priv.data + off);
2050
2051 if (block_type == SKL_TYPE_TUPLE) {
2052 ret = skl_tplg_get_tokens(dev, data,
2053 skl, mconfig, block_size);
2054
2055 if (ret < 0)
2056 return ret;
2057
2058 --num_blocks;
2059 } else {
2060 if (mconfig->formats_config.caps_size > 0)
2061 memcpy(mconfig->formats_config.caps, data,
2062 mconfig->formats_config.caps_size);
2063 --num_blocks;
2064 }
1541 } 2065 }
2066
2067 return 0;
1542} 2068}
1543 2069
1544static void skl_clear_pin_config(struct snd_soc_platform *platform, 2070static void skl_clear_pin_config(struct snd_soc_platform *platform,
@@ -1606,9 +2132,6 @@ static int skl_tplg_widget_load(struct snd_soc_component *cmpnt,
1606 struct skl *skl = ebus_to_skl(ebus); 2132 struct skl *skl = ebus_to_skl(ebus);
1607 struct hdac_bus *bus = ebus_to_hbus(ebus); 2133 struct hdac_bus *bus = ebus_to_hbus(ebus);
1608 struct skl_module_cfg *mconfig; 2134 struct skl_module_cfg *mconfig;
1609 struct skl_pipe *pipe;
1610 struct skl_dfw_module *dfw_config =
1611 (struct skl_dfw_module *)tplg_w->priv.data;
1612 2135
1613 if (!tplg_w->priv.size) 2136 if (!tplg_w->priv.size)
1614 goto bind_event; 2137 goto bind_event;
@@ -1619,76 +2142,17 @@ static int skl_tplg_widget_load(struct snd_soc_component *cmpnt,
1619 return -ENOMEM; 2142 return -ENOMEM;
1620 2143
1621 w->priv = mconfig; 2144 w->priv = mconfig;
1622 memcpy(&mconfig->guid, &dfw_config->uuid, 16);
1623 2145
1624 ret = snd_skl_get_module_info(skl->skl_sst, mconfig->guid, dfw_config); 2146 /*
2147 * module binary can be loaded later, so set it to query when
2148 * module is load for a use case
2149 */
2150 mconfig->id.module_id = -1;
2151
2152 /* Parse private data for tuples */
2153 ret = skl_tplg_get_pvt_data(tplg_w, skl, bus->dev, mconfig);
1625 if (ret < 0) 2154 if (ret < 0)
1626 return ret; 2155 return ret;
1627
1628 mconfig->id.module_id = dfw_config->module_id;
1629 mconfig->id.instance_id = dfw_config->instance_id;
1630 mconfig->mcps = dfw_config->max_mcps;
1631 mconfig->ibs = dfw_config->ibs;
1632 mconfig->obs = dfw_config->obs;
1633 mconfig->core_id = dfw_config->core_id;
1634 mconfig->max_in_queue = dfw_config->max_in_queue;
1635 mconfig->max_out_queue = dfw_config->max_out_queue;
1636 mconfig->is_loadable = dfw_config->is_loadable;
1637 skl_tplg_fill_fmt(mconfig->in_fmt, dfw_config->in_fmt,
1638 MODULE_MAX_IN_PINS);
1639 skl_tplg_fill_fmt(mconfig->out_fmt, dfw_config->out_fmt,
1640 MODULE_MAX_OUT_PINS);
1641
1642 mconfig->params_fixup = dfw_config->params_fixup;
1643 mconfig->converter = dfw_config->converter;
1644 mconfig->m_type = dfw_config->module_type;
1645 mconfig->vbus_id = dfw_config->vbus_id;
1646 mconfig->mem_pages = dfw_config->mem_pages;
1647
1648 pipe = skl_tplg_add_pipe(bus->dev, skl, &dfw_config->pipe);
1649 if (pipe)
1650 mconfig->pipe = pipe;
1651
1652 mconfig->dev_type = dfw_config->dev_type;
1653 mconfig->hw_conn_type = dfw_config->hw_conn_type;
1654 mconfig->time_slot = dfw_config->time_slot;
1655 mconfig->formats_config.caps_size = dfw_config->caps.caps_size;
1656
1657 mconfig->m_in_pin = devm_kzalloc(bus->dev, (mconfig->max_in_queue) *
1658 sizeof(*mconfig->m_in_pin),
1659 GFP_KERNEL);
1660 if (!mconfig->m_in_pin)
1661 return -ENOMEM;
1662
1663 mconfig->m_out_pin = devm_kzalloc(bus->dev, (mconfig->max_out_queue) *
1664 sizeof(*mconfig->m_out_pin),
1665 GFP_KERNEL);
1666 if (!mconfig->m_out_pin)
1667 return -ENOMEM;
1668
1669 skl_fill_module_pin_info(dfw_config->in_pin, mconfig->m_in_pin,
1670 dfw_config->is_dynamic_in_pin,
1671 mconfig->max_in_queue);
1672
1673 skl_fill_module_pin_info(dfw_config->out_pin, mconfig->m_out_pin,
1674 dfw_config->is_dynamic_out_pin,
1675 mconfig->max_out_queue);
1676
1677
1678 if (mconfig->formats_config.caps_size == 0)
1679 goto bind_event;
1680
1681 mconfig->formats_config.caps = (u32 *)devm_kzalloc(bus->dev,
1682 mconfig->formats_config.caps_size, GFP_KERNEL);
1683
1684 if (mconfig->formats_config.caps == NULL)
1685 return -ENOMEM;
1686
1687 memcpy(mconfig->formats_config.caps, dfw_config->caps.caps,
1688 dfw_config->caps.caps_size);
1689 mconfig->formats_config.param_id = dfw_config->caps.param_id;
1690 mconfig->formats_config.set_params = dfw_config->caps.set_params;
1691
1692bind_event: 2156bind_event:
1693 if (tplg_w->event_type == 0) { 2157 if (tplg_w->event_type == 0) {
1694 dev_dbg(bus->dev, "ASoC: No event handler required\n"); 2158 dev_dbg(bus->dev, "ASoC: No event handler required\n");
@@ -1767,11 +2231,229 @@ static int skl_tplg_control_load(struct snd_soc_component *cmpnt,
1767 return 0; 2231 return 0;
1768} 2232}
1769 2233
2234static int skl_tplg_fill_str_mfest_tkn(struct device *dev,
2235 struct snd_soc_tplg_vendor_string_elem *str_elem,
2236 struct skl_dfw_manifest *minfo)
2237{
2238 int tkn_count = 0;
2239 static int ref_count;
2240
2241 switch (str_elem->token) {
2242 case SKL_TKN_STR_LIB_NAME:
2243 if (ref_count > minfo->lib_count - 1) {
2244 ref_count = 0;
2245 return -EINVAL;
2246 }
2247
2248 strncpy(minfo->lib[ref_count].name, str_elem->string,
2249 ARRAY_SIZE(minfo->lib[ref_count].name));
2250 ref_count++;
2251 tkn_count++;
2252 break;
2253
2254 default:
2255 dev_err(dev, "Not a string token %d\n", str_elem->token);
2256 break;
2257 }
2258
2259 return tkn_count;
2260}
2261
2262static int skl_tplg_get_str_tkn(struct device *dev,
2263 struct snd_soc_tplg_vendor_array *array,
2264 struct skl_dfw_manifest *minfo)
2265{
2266 int tkn_count = 0, ret;
2267 struct snd_soc_tplg_vendor_string_elem *str_elem;
2268
2269 str_elem = (struct snd_soc_tplg_vendor_string_elem *)array->value;
2270 while (tkn_count < array->num_elems) {
2271 ret = skl_tplg_fill_str_mfest_tkn(dev, str_elem, minfo);
2272 str_elem++;
2273
2274 if (ret < 0)
2275 return ret;
2276
2277 tkn_count = tkn_count + ret;
2278 }
2279
2280 return tkn_count;
2281}
2282
2283static int skl_tplg_get_int_tkn(struct device *dev,
2284 struct snd_soc_tplg_vendor_value_elem *tkn_elem,
2285 struct skl_dfw_manifest *minfo)
2286{
2287 int tkn_count = 0;
2288
2289 switch (tkn_elem->token) {
2290 case SKL_TKN_U32_LIB_COUNT:
2291 minfo->lib_count = tkn_elem->value;
2292 tkn_count++;
2293 break;
2294
2295 default:
2296 dev_err(dev, "Not a manifest token %d\n", tkn_elem->token);
2297 return -EINVAL;
2298 }
2299
2300 return tkn_count;
2301}
2302
2303/*
2304 * Fill the manifest structure by parsing the tokens based on the
2305 * type.
2306 */
2307static int skl_tplg_get_manifest_tkn(struct device *dev,
2308 char *pvt_data, struct skl_dfw_manifest *minfo,
2309 int block_size)
2310{
2311 int tkn_count = 0, ret;
2312 int off = 0, tuple_size = 0;
2313 struct snd_soc_tplg_vendor_array *array;
2314 struct snd_soc_tplg_vendor_value_elem *tkn_elem;
2315
2316 if (block_size <= 0)
2317 return -EINVAL;
2318
2319 while (tuple_size < block_size) {
2320 array = (struct snd_soc_tplg_vendor_array *)(pvt_data + off);
2321 off += array->size;
2322 switch (array->type) {
2323 case SND_SOC_TPLG_TUPLE_TYPE_STRING:
2324 ret = skl_tplg_get_str_tkn(dev, array, minfo);
2325
2326 if (ret < 0)
2327 return ret;
2328 tkn_count += ret;
2329
2330 tuple_size += tkn_count *
2331 sizeof(struct snd_soc_tplg_vendor_string_elem);
2332 continue;
2333
2334 case SND_SOC_TPLG_TUPLE_TYPE_UUID:
2335 dev_warn(dev, "no uuid tokens for skl tplf manifest\n");
2336 continue;
2337
2338 default:
2339 tkn_elem = array->value;
2340 tkn_count = 0;
2341 break;
2342 }
2343
2344 while (tkn_count <= array->num_elems - 1) {
2345 ret = skl_tplg_get_int_tkn(dev,
2346 tkn_elem, minfo);
2347 if (ret < 0)
2348 return ret;
2349
2350 tkn_count = tkn_count + ret;
2351 tkn_elem++;
2352 tuple_size += tkn_count *
2353 sizeof(struct snd_soc_tplg_vendor_value_elem);
2354 break;
2355 }
2356 tkn_count = 0;
2357 }
2358
2359 return 0;
2360}
2361
2362/*
2363 * Parse manifest private data for tokens. The private data block is
2364 * preceded by descriptors for type and size of data block.
2365 */
2366static int skl_tplg_get_manifest_data(struct snd_soc_tplg_manifest *manifest,
2367 struct device *dev, struct skl_dfw_manifest *minfo)
2368{
2369 struct snd_soc_tplg_vendor_array *array;
2370 int num_blocks, block_size = 0, block_type, off = 0;
2371 char *data;
2372 int ret;
2373
2374 /* Read the NUM_DATA_BLOCKS descriptor */
2375 array = (struct snd_soc_tplg_vendor_array *)manifest->priv.data;
2376 ret = skl_tplg_get_desc_blocks(dev, array);
2377 if (ret < 0)
2378 return ret;
2379 num_blocks = ret;
2380
2381 off += array->size;
2382 array = (struct snd_soc_tplg_vendor_array *)
2383 (manifest->priv.data + off);
2384
2385 /* Read the BLOCK_TYPE and BLOCK_SIZE descriptor */
2386 while (num_blocks > 0) {
2387 ret = skl_tplg_get_desc_blocks(dev, array);
2388
2389 if (ret < 0)
2390 return ret;
2391 block_type = ret;
2392 off += array->size;
2393
2394 array = (struct snd_soc_tplg_vendor_array *)
2395 (manifest->priv.data + off);
2396
2397 ret = skl_tplg_get_desc_blocks(dev, array);
2398
2399 if (ret < 0)
2400 return ret;
2401 block_size = ret;
2402 off += array->size;
2403
2404 array = (struct snd_soc_tplg_vendor_array *)
2405 (manifest->priv.data + off);
2406
2407 data = (manifest->priv.data + off);
2408
2409 if (block_type == SKL_TYPE_TUPLE) {
2410 ret = skl_tplg_get_manifest_tkn(dev, data, minfo,
2411 block_size);
2412
2413 if (ret < 0)
2414 return ret;
2415
2416 --num_blocks;
2417 } else {
2418 return -EINVAL;
2419 }
2420 }
2421
2422 return 0;
2423}
2424
2425static int skl_manifest_load(struct snd_soc_component *cmpnt,
2426 struct snd_soc_tplg_manifest *manifest)
2427{
2428 struct skl_dfw_manifest *minfo;
2429 struct hdac_ext_bus *ebus = snd_soc_component_get_drvdata(cmpnt);
2430 struct hdac_bus *bus = ebus_to_hbus(ebus);
2431 struct skl *skl = ebus_to_skl(ebus);
2432 int ret = 0;
2433
2434 /* proceed only if we have private data defined */
2435 if (manifest->priv.size == 0)
2436 return 0;
2437
2438 minfo = &skl->skl_sst->manifest;
2439
2440 skl_tplg_get_manifest_data(manifest, bus->dev, minfo);
2441
2442 if (minfo->lib_count > HDA_MAX_LIB) {
2443 dev_err(bus->dev, "Exceeding max Library count. Got:%d\n",
2444 minfo->lib_count);
2445 ret = -EINVAL;
2446 }
2447
2448 return ret;
2449}
2450
1770static struct snd_soc_tplg_ops skl_tplg_ops = { 2451static struct snd_soc_tplg_ops skl_tplg_ops = {
1771 .widget_load = skl_tplg_widget_load, 2452 .widget_load = skl_tplg_widget_load,
1772 .control_load = skl_tplg_control_load, 2453 .control_load = skl_tplg_control_load,
1773 .bytes_ext_ops = skl_tlv_ops, 2454 .bytes_ext_ops = skl_tlv_ops,
1774 .bytes_ext_ops_count = ARRAY_SIZE(skl_tlv_ops), 2455 .bytes_ext_ops_count = ARRAY_SIZE(skl_tlv_ops),
2456 .manifest = skl_manifest_load,
1775}; 2457};
1776 2458
1777/* 2459/*
diff --git a/sound/soc/intel/skylake/skl-topology.h b/sound/soc/intel/skylake/skl-topology.h
index 22d3ef83817d..a519360f42a6 100644
--- a/sound/soc/intel/skylake/skl-topology.h
+++ b/sound/soc/intel/skylake/skl-topology.h
@@ -133,7 +133,7 @@ struct skl_i2s_config_blob {
133struct skl_dma_control { 133struct skl_dma_control {
134 u32 node_id; 134 u32 node_id;
135 u32 config_length; 135 u32 config_length;
136 u32 config_data[1]; 136 u32 config_data[0];
137} __packed; 137} __packed;
138 138
139struct skl_cpr_cfg { 139struct skl_cpr_cfg {
@@ -215,9 +215,20 @@ struct skl_module_fmt {
215 215
216struct skl_module_cfg; 216struct skl_module_cfg;
217 217
218struct skl_mod_inst_map {
219 u16 mod_id;
220 u16 inst_id;
221};
222
223struct skl_kpb_params {
224 u32 num_modules;
225 struct skl_mod_inst_map map[0];
226};
227
218struct skl_module_inst_id { 228struct skl_module_inst_id {
219 u32 module_id; 229 int module_id;
220 u32 instance_id; 230 u32 instance_id;
231 int pvt_id;
221}; 232};
222 233
223enum skl_module_pin_state { 234enum skl_module_pin_state {
diff --git a/sound/soc/intel/skylake/skl-tplg-interface.h b/sound/soc/intel/skylake/skl-tplg-interface.h
index a32e5e9cc530..2f6281e056d6 100644
--- a/sound/soc/intel/skylake/skl-tplg-interface.h
+++ b/sound/soc/intel/skylake/skl-tplg-interface.h
@@ -80,7 +80,8 @@ enum skl_module_type {
80 SKL_MODULE_TYPE_UPDWMIX, 80 SKL_MODULE_TYPE_UPDWMIX,
81 SKL_MODULE_TYPE_SRCINT, 81 SKL_MODULE_TYPE_SRCINT,
82 SKL_MODULE_TYPE_ALGO, 82 SKL_MODULE_TYPE_ALGO,
83 SKL_MODULE_TYPE_BASE_OUTFMT 83 SKL_MODULE_TYPE_BASE_OUTFMT,
84 SKL_MODULE_TYPE_KPB,
84}; 85};
85 86
86enum skl_core_affinity { 87enum skl_core_affinity {
@@ -148,84 +149,34 @@ enum skl_module_param_type {
148 SKL_PARAM_BIND 149 SKL_PARAM_BIND
149}; 150};
150 151
151struct skl_dfw_module_pin { 152struct skl_dfw_algo_data {
152 u16 module_id;
153 u16 instance_id;
154} __packed;
155
156struct skl_dfw_module_fmt {
157 u32 channels;
158 u32 freq;
159 u32 bit_depth;
160 u32 valid_bit_depth;
161 u32 ch_cfg;
162 u32 interleaving_style;
163 u32 sample_type;
164 u32 ch_map;
165} __packed;
166
167struct skl_dfw_module_caps {
168 u32 set_params:2; 153 u32 set_params:2;
169 u32 rsvd:30; 154 u32 rsvd:30;
170 u32 param_id; 155 u32 param_id;
171 u32 caps_size; 156 u32 max;
172 u32 caps[HDA_SST_CFG_MAX]; 157 char params[0];
173};
174
175struct skl_dfw_pipe {
176 u8 pipe_id;
177 u8 pipe_priority;
178 u16 conn_type:4;
179 u16 rsvd:4;
180 u16 memory_pages:8;
181} __packed; 158} __packed;
182 159
183struct skl_dfw_module { 160#define LIB_NAME_LENGTH 128
184 u8 uuid[16]; 161#define HDA_MAX_LIB 16
185 162
186 u16 module_id; 163struct lib_info {
187 u16 instance_id; 164 char name[LIB_NAME_LENGTH];
188 u32 max_mcps;
189 u32 mem_pages;
190 u32 obs;
191 u32 ibs;
192 u32 vbus_id;
193
194 u32 max_in_queue:8;
195 u32 max_out_queue:8;
196 u32 time_slot:8;
197 u32 core_id:4;
198 u32 rsvd1:4;
199
200 u32 module_type:8;
201 u32 conn_type:4;
202 u32 dev_type:4;
203 u32 hw_conn_type:4;
204 u32 rsvd2:12;
205
206 u32 params_fixup:8;
207 u32 converter:8;
208 u32 input_pin_type:1;
209 u32 output_pin_type:1;
210 u32 is_dynamic_in_pin:1;
211 u32 is_dynamic_out_pin:1;
212 u32 is_loadable:1;
213 u32 rsvd3:11;
214
215 struct skl_dfw_pipe pipe;
216 struct skl_dfw_module_fmt in_fmt[MAX_IN_QUEUE];
217 struct skl_dfw_module_fmt out_fmt[MAX_OUT_QUEUE];
218 struct skl_dfw_module_pin in_pin[MAX_IN_QUEUE];
219 struct skl_dfw_module_pin out_pin[MAX_OUT_QUEUE];
220 struct skl_dfw_module_caps caps;
221} __packed; 165} __packed;
222 166
223struct skl_dfw_algo_data { 167struct skl_dfw_manifest {
224 u32 set_params:2; 168 u32 lib_count;
225 u32 rsvd:30; 169 struct lib_info lib[HDA_MAX_LIB];
226 u32 param_id;
227 u32 max;
228 char params[0];
229} __packed; 170} __packed;
230 171
172enum skl_tkn_dir {
173 SKL_DIR_IN,
174 SKL_DIR_OUT
175};
176
177enum skl_tuple_type {
178 SKL_TYPE_TUPLE,
179 SKL_TYPE_DATA
180};
181
231#endif 182#endif
diff --git a/sound/soc/intel/skylake/skl.c b/sound/soc/intel/skylake/skl.c
index e3e764167765..2989c164dafe 100644
--- a/sound/soc/intel/skylake/skl.c
+++ b/sound/soc/intel/skylake/skl.c
@@ -587,7 +587,7 @@ static int skl_first_init(struct hdac_ext_bus *ebus)
587 return -ENXIO; 587 return -ENXIO;
588 } 588 }
589 589
590 snd_hdac_ext_bus_parse_capabilities(ebus); 590 snd_hdac_bus_parse_capabilities(bus);
591 591
592 if (skl_acquire_irq(ebus, 0) < 0) 592 if (skl_acquire_irq(ebus, 0) < 0)
593 return -EBUSY; 593 return -EBUSY;
@@ -684,7 +684,7 @@ static int skl_probe(struct pci_dev *pci,
684 skl_dmic_data.dmic_num = skl_get_dmic_geo(skl); 684 skl_dmic_data.dmic_num = skl_get_dmic_geo(skl);
685 685
686 /* check if dsp is there */ 686 /* check if dsp is there */
687 if (ebus->ppcap) { 687 if (bus->ppcap) {
688 err = skl_machine_device_register(skl, 688 err = skl_machine_device_register(skl,
689 (void *)pci_id->driver_data); 689 (void *)pci_id->driver_data);
690 if (err < 0) 690 if (err < 0)
@@ -698,7 +698,7 @@ static int skl_probe(struct pci_dev *pci,
698 skl->skl_sst->enable_miscbdcge = skl_enable_miscbdcge; 698 skl->skl_sst->enable_miscbdcge = skl_enable_miscbdcge;
699 699
700 } 700 }
701 if (ebus->mlcap) 701 if (bus->mlcap)
702 snd_hdac_ext_bus_get_ml_capabilities(ebus); 702 snd_hdac_ext_bus_get_ml_capabilities(ebus);
703 703
704 /* create device for soc dmic */ 704 /* create device for soc dmic */
diff --git a/sound/soc/intel/skylake/skl.h b/sound/soc/intel/skylake/skl.h
index 9064e5b0d676..5d4fbb094c48 100644
--- a/sound/soc/intel/skylake/skl.h
+++ b/sound/soc/intel/skylake/skl.h
@@ -105,6 +105,7 @@ struct skl_dsp_ops {
105 int irq, const char *fw_name, 105 int irq, const char *fw_name,
106 struct skl_dsp_loader_ops loader_ops, 106 struct skl_dsp_loader_ops loader_ops,
107 struct skl_sst **skl_sst); 107 struct skl_sst **skl_sst);
108 int (*init_fw)(struct device *dev, struct skl_sst *ctx);
108 void (*cleanup)(struct device *dev, struct skl_sst *ctx); 109 void (*cleanup)(struct device *dev, struct skl_sst *ctx);
109}; 110};
110 111
@@ -123,4 +124,5 @@ int skl_free_dsp(struct skl *skl);
123int skl_suspend_dsp(struct skl *skl); 124int skl_suspend_dsp(struct skl *skl);
124int skl_resume_dsp(struct skl *skl); 125int skl_resume_dsp(struct skl *skl);
125void skl_cleanup_resources(struct skl *skl); 126void skl_cleanup_resources(struct skl *skl);
127const struct skl_dsp_ops *skl_get_dsp_ops(int pci_id);
126#endif /* __SOUND_SOC_SKL_H */ 128#endif /* __SOUND_SOC_SKL_H */
diff --git a/sound/soc/kirkwood/kirkwood-dma.c b/sound/soc/kirkwood/kirkwood-dma.c
index dbfdfe99c69d..dafd22e874e9 100644
--- a/sound/soc/kirkwood/kirkwood-dma.c
+++ b/sound/soc/kirkwood/kirkwood-dma.c
@@ -242,7 +242,7 @@ static snd_pcm_uframes_t kirkwood_dma_pointer(struct snd_pcm_substream
242 return count; 242 return count;
243} 243}
244 244
245static struct snd_pcm_ops kirkwood_dma_ops = { 245static const struct snd_pcm_ops kirkwood_dma_ops = {
246 .open = kirkwood_dma_open, 246 .open = kirkwood_dma_open,
247 .close = kirkwood_dma_close, 247 .close = kirkwood_dma_close,
248 .ioctl = snd_pcm_lib_ioctl, 248 .ioctl = snd_pcm_lib_ioctl,
diff --git a/sound/soc/mediatek/common/mtk-afe-fe-dai.c b/sound/soc/mediatek/common/mtk-afe-fe-dai.c
index b788791b0a35..ac231d33d8fe 100644
--- a/sound/soc/mediatek/common/mtk-afe-fe-dai.c
+++ b/sound/soc/mediatek/common/mtk-afe-fe-dai.c
@@ -23,7 +23,8 @@
23 23
24#define AFE_BASE_END_OFFSET 8 24#define AFE_BASE_END_OFFSET 8
25 25
26int mtk_regmap_update_bits(struct regmap *map, int reg, unsigned int mask, 26static int mtk_regmap_update_bits(struct regmap *map, int reg,
27 unsigned int mask,
27 unsigned int val) 28 unsigned int val)
28{ 29{
29 if (reg < 0) 30 if (reg < 0)
@@ -31,7 +32,7 @@ int mtk_regmap_update_bits(struct regmap *map, int reg, unsigned int mask,
31 return regmap_update_bits(map, reg, mask, val); 32 return regmap_update_bits(map, reg, mask, val);
32} 33}
33 34
34int mtk_regmap_write(struct regmap *map, int reg, unsigned int val) 35static int mtk_regmap_write(struct regmap *map, int reg, unsigned int val)
35{ 36{
36 if (reg < 0) 37 if (reg < 0)
37 return 0; 38 return 0;
diff --git a/sound/soc/omap/mcbsp.c b/sound/soc/omap/mcbsp.c
index 76ce33199bf9..06fec5699cc8 100644
--- a/sound/soc/omap/mcbsp.c
+++ b/sound/soc/omap/mcbsp.c
@@ -221,7 +221,8 @@ void omap_mcbsp_config(struct omap_mcbsp *mcbsp,
221 221
222 /* Enable TX/RX sync error interrupts by default */ 222 /* Enable TX/RX sync error interrupts by default */
223 if (mcbsp->irq) 223 if (mcbsp->irq)
224 MCBSP_WRITE(mcbsp, IRQEN, RSYNCERREN | XSYNCERREN); 224 MCBSP_WRITE(mcbsp, IRQEN, RSYNCERREN | XSYNCERREN |
225 RUNDFLEN | ROVFLEN | XUNDFLEN | XOVFLEN);
225} 226}
226 227
227/** 228/**
diff --git a/sound/soc/omap/omap-abe-twl6040.c b/sound/soc/omap/omap-abe-twl6040.c
index f61b3b58083b..89fe95e877db 100644
--- a/sound/soc/omap/omap-abe-twl6040.c
+++ b/sound/soc/omap/omap-abe-twl6040.c
@@ -305,23 +305,14 @@ static int omap_abe_probe(struct platform_device *pdev)
305 305
306 snd_soc_card_set_drvdata(card, priv); 306 snd_soc_card_set_drvdata(card, priv);
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, "devm_snd_soc_register_card() failed: %d\n",
311 ret); 311 ret);
312 312
313 return ret; 313 return ret;
314} 314}
315 315
316static int omap_abe_remove(struct platform_device *pdev)
317{
318 struct snd_soc_card *card = platform_get_drvdata(pdev);
319
320 snd_soc_unregister_card(card);
321
322 return 0;
323}
324
325static const struct of_device_id omap_abe_of_match[] = { 316static const struct of_device_id omap_abe_of_match[] = {
326 {.compatible = "ti,abe-twl6040", }, 317 {.compatible = "ti,abe-twl6040", },
327 { }, 318 { },
@@ -335,7 +326,6 @@ static struct platform_driver omap_abe_driver = {
335 .of_match_table = omap_abe_of_match, 326 .of_match_table = omap_abe_of_match,
336 }, 327 },
337 .probe = omap_abe_probe, 328 .probe = omap_abe_probe,
338 .remove = omap_abe_remove,
339}; 329};
340 330
341static int __init omap_abe_init(void) 331static int __init omap_abe_init(void)
diff --git a/sound/soc/omap/omap-pcm.c b/sound/soc/omap/omap-pcm.c
index a84f677234f0..94e9ff791f3a 100644
--- a/sound/soc/omap/omap-pcm.c
+++ b/sound/soc/omap/omap-pcm.c
@@ -58,7 +58,7 @@ static void omap_pcm_limit_supported_formats(void)
58{ 58{
59 int i; 59 int i;
60 60
61 for (i = 0; i < SNDRV_PCM_FORMAT_LAST; i++) { 61 for (i = 0; i <= SNDRV_PCM_FORMAT_LAST; i++) {
62 switch (snd_pcm_format_physical_width(i)) { 62 switch (snd_pcm_format_physical_width(i)) {
63 case 8: 63 case 8:
64 case 16: 64 case 16:
diff --git a/sound/soc/qcom/apq8016_sbc.c b/sound/soc/qcom/apq8016_sbc.c
index 1289543c8fb2..07f91e918b23 100644
--- a/sound/soc/qcom/apq8016_sbc.c
+++ b/sound/soc/qcom/apq8016_sbc.c
@@ -85,6 +85,15 @@ static struct apq8016_sbc_data *apq8016_sbc_parse_of(struct snd_soc_card *card)
85 return ERR_PTR(ret); 85 return ERR_PTR(ret);
86 } 86 }
87 87
88 /* DAPM routes */
89 if (of_property_read_bool(node, "qcom,audio-routing")) {
90 ret = snd_soc_of_parse_audio_routing(card,
91 "qcom,audio-routing");
92 if (ret)
93 return ERR_PTR(ret);
94 }
95
96
88 /* Populate links */ 97 /* Populate links */
89 num_links = of_get_child_count(node); 98 num_links = of_get_child_count(node);
90 99
@@ -147,6 +156,15 @@ static struct apq8016_sbc_data *apq8016_sbc_parse_of(struct snd_soc_card *card)
147 return data; 156 return data;
148} 157}
149 158
159static const struct snd_soc_dapm_widget apq8016_sbc_dapm_widgets[] = {
160
161 SND_SOC_DAPM_MIC("Handset Mic", NULL),
162 SND_SOC_DAPM_MIC("Headset Mic", NULL),
163 SND_SOC_DAPM_MIC("Secondary Mic", NULL),
164 SND_SOC_DAPM_MIC("Digital Mic1", NULL),
165 SND_SOC_DAPM_MIC("Digital Mic2", NULL),
166};
167
150static int apq8016_sbc_platform_probe(struct platform_device *pdev) 168static int apq8016_sbc_platform_probe(struct platform_device *pdev)
151{ 169{
152 struct device *dev = &pdev->dev; 170 struct device *dev = &pdev->dev;
@@ -159,6 +177,8 @@ static int apq8016_sbc_platform_probe(struct platform_device *pdev)
159 return -ENOMEM; 177 return -ENOMEM;
160 178
161 card->dev = dev; 179 card->dev = dev;
180 card->dapm_widgets = apq8016_sbc_dapm_widgets;
181 card->num_dapm_widgets = ARRAY_SIZE(apq8016_sbc_dapm_widgets);
162 data = apq8016_sbc_parse_of(card); 182 data = apq8016_sbc_parse_of(card);
163 if (IS_ERR(data)) { 183 if (IS_ERR(data)) {
164 dev_err(&pdev->dev, "Error resolving dai links: %ld\n", 184 dev_err(&pdev->dev, "Error resolving dai links: %ld\n",
diff --git a/sound/soc/qcom/lpass-platform.c b/sound/soc/qcom/lpass-platform.c
index db000c6987a1..e2ff538a8aa5 100644
--- a/sound/soc/qcom/lpass-platform.c
+++ b/sound/soc/qcom/lpass-platform.c
@@ -84,9 +84,9 @@ static int lpass_platform_pcmops_hw_params(struct snd_pcm_substream *substream,
84 struct snd_pcm_hw_params *params) 84 struct snd_pcm_hw_params *params)
85{ 85{
86 struct snd_soc_pcm_runtime *soc_runtime = substream->private_data; 86 struct snd_soc_pcm_runtime *soc_runtime = substream->private_data;
87 struct lpass_pcm_data *pcm_data = snd_soc_pcm_get_drvdata(soc_runtime);
88 struct lpass_data *drvdata = 87 struct lpass_data *drvdata =
89 snd_soc_platform_get_drvdata(soc_runtime->platform); 88 snd_soc_platform_get_drvdata(soc_runtime->platform);
89 struct lpass_pcm_data *pcm_data = drvdata->private_data;
90 struct lpass_variant *v = drvdata->variant; 90 struct lpass_variant *v = drvdata->variant;
91 snd_pcm_format_t format = params_format(params); 91 snd_pcm_format_t format = params_format(params);
92 unsigned int channels = params_channels(params); 92 unsigned int channels = params_channels(params);
@@ -177,9 +177,9 @@ static int lpass_platform_pcmops_hw_params(struct snd_pcm_substream *substream,
177static int lpass_platform_pcmops_hw_free(struct snd_pcm_substream *substream) 177static int lpass_platform_pcmops_hw_free(struct snd_pcm_substream *substream)
178{ 178{
179 struct snd_soc_pcm_runtime *soc_runtime = substream->private_data; 179 struct snd_soc_pcm_runtime *soc_runtime = substream->private_data;
180 struct lpass_pcm_data *pcm_data = snd_soc_pcm_get_drvdata(soc_runtime);
181 struct lpass_data *drvdata = 180 struct lpass_data *drvdata =
182 snd_soc_platform_get_drvdata(soc_runtime->platform); 181 snd_soc_platform_get_drvdata(soc_runtime->platform);
182 struct lpass_pcm_data *pcm_data = drvdata->private_data;
183 struct lpass_variant *v = drvdata->variant; 183 struct lpass_variant *v = drvdata->variant;
184 unsigned int reg; 184 unsigned int reg;
185 int ret; 185 int ret;
@@ -201,9 +201,9 @@ static int lpass_platform_pcmops_prepare(struct snd_pcm_substream *substream)
201{ 201{
202 struct snd_pcm_runtime *runtime = substream->runtime; 202 struct snd_pcm_runtime *runtime = substream->runtime;
203 struct snd_soc_pcm_runtime *soc_runtime = substream->private_data; 203 struct snd_soc_pcm_runtime *soc_runtime = substream->private_data;
204 struct lpass_pcm_data *pcm_data = snd_soc_pcm_get_drvdata(soc_runtime);
205 struct lpass_data *drvdata = 204 struct lpass_data *drvdata =
206 snd_soc_platform_get_drvdata(soc_runtime->platform); 205 snd_soc_platform_get_drvdata(soc_runtime->platform);
206 struct lpass_pcm_data *pcm_data = drvdata->private_data;
207 struct lpass_variant *v = drvdata->variant; 207 struct lpass_variant *v = drvdata->variant;
208 int ret, ch, dir = substream->stream; 208 int ret, ch, dir = substream->stream;
209 209
@@ -255,9 +255,9 @@ static int lpass_platform_pcmops_trigger(struct snd_pcm_substream *substream,
255 int cmd) 255 int cmd)
256{ 256{
257 struct snd_soc_pcm_runtime *soc_runtime = substream->private_data; 257 struct snd_soc_pcm_runtime *soc_runtime = substream->private_data;
258 struct lpass_pcm_data *pcm_data = snd_soc_pcm_get_drvdata(soc_runtime);
259 struct lpass_data *drvdata = 258 struct lpass_data *drvdata =
260 snd_soc_platform_get_drvdata(soc_runtime->platform); 259 snd_soc_platform_get_drvdata(soc_runtime->platform);
260 struct lpass_pcm_data *pcm_data = drvdata->private_data;
261 struct lpass_variant *v = drvdata->variant; 261 struct lpass_variant *v = drvdata->variant;
262 int ret, ch, dir = substream->stream; 262 int ret, ch, dir = substream->stream;
263 263
@@ -331,9 +331,9 @@ static snd_pcm_uframes_t lpass_platform_pcmops_pointer(
331 struct snd_pcm_substream *substream) 331 struct snd_pcm_substream *substream)
332{ 332{
333 struct snd_soc_pcm_runtime *soc_runtime = substream->private_data; 333 struct snd_soc_pcm_runtime *soc_runtime = substream->private_data;
334 struct lpass_pcm_data *pcm_data = snd_soc_pcm_get_drvdata(soc_runtime);
335 struct lpass_data *drvdata = 334 struct lpass_data *drvdata =
336 snd_soc_platform_get_drvdata(soc_runtime->platform); 335 snd_soc_platform_get_drvdata(soc_runtime->platform);
336 struct lpass_pcm_data *pcm_data = drvdata->private_data;
337 struct lpass_variant *v = drvdata->variant; 337 struct lpass_variant *v = drvdata->variant;
338 unsigned int base_addr, curr_addr; 338 unsigned int base_addr, curr_addr;
339 int ret, ch, dir = substream->stream; 339 int ret, ch, dir = substream->stream;
@@ -372,7 +372,7 @@ static int lpass_platform_pcmops_mmap(struct snd_pcm_substream *substream,
372 runtime->dma_bytes); 372 runtime->dma_bytes);
373} 373}
374 374
375static struct snd_pcm_ops lpass_platform_pcm_ops = { 375static const struct snd_pcm_ops lpass_platform_pcm_ops = {
376 .open = lpass_platform_pcmops_open, 376 .open = lpass_platform_pcmops_open,
377 .ioctl = snd_pcm_lib_ioctl, 377 .ioctl = snd_pcm_lib_ioctl,
378 .hw_params = lpass_platform_pcmops_hw_params, 378 .hw_params = lpass_platform_pcmops_hw_params,
@@ -483,7 +483,7 @@ static int lpass_platform_pcm_new(struct snd_soc_pcm_runtime *soc_runtime)
483 return -ENOMEM; 483 return -ENOMEM;
484 484
485 data->i2s_port = cpu_dai->driver->id; 485 data->i2s_port = cpu_dai->driver->id;
486 snd_soc_pcm_set_drvdata(soc_runtime, data); 486 drvdata->private_data = data;
487 487
488 psubstream = pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream; 488 psubstream = pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream;
489 if (psubstream) { 489 if (psubstream) {
@@ -570,8 +570,8 @@ static void lpass_platform_pcm_free(struct snd_pcm *pcm)
570 substream = pcm->streams[i].substream; 570 substream = pcm->streams[i].substream;
571 if (substream) { 571 if (substream) {
572 rt = substream->private_data; 572 rt = substream->private_data;
573 data = snd_soc_pcm_get_drvdata(rt);
574 drvdata = snd_soc_platform_get_drvdata(rt->platform); 573 drvdata = snd_soc_platform_get_drvdata(rt->platform);
574 data = drvdata->private_data;
575 575
576 ch = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 576 ch = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
577 ? data->rdma_ch 577 ? data->rdma_ch
diff --git a/sound/soc/qcom/lpass.h b/sound/soc/qcom/lpass.h
index 30714ad1e138..35b3cea8207d 100644
--- a/sound/soc/qcom/lpass.h
+++ b/sound/soc/qcom/lpass.h
@@ -58,6 +58,8 @@ struct lpass_data {
58 /* 8016 specific */ 58 /* 8016 specific */
59 struct clk *pcnoc_mport_clk; 59 struct clk *pcnoc_mport_clk;
60 struct clk *pcnoc_sway_clk; 60 struct clk *pcnoc_sway_clk;
61
62 void *private_data;
61}; 63};
62 64
63/* Vairant data per each SOC */ 65/* Vairant data per each SOC */
diff --git a/sound/soc/rockchip/Kconfig b/sound/soc/rockchip/Kconfig
index f1e0c703e0d2..c783f9a22595 100644
--- a/sound/soc/rockchip/Kconfig
+++ b/sound/soc/rockchip/Kconfig
@@ -41,3 +41,15 @@ config SND_SOC_ROCKCHIP_RT5645
41 help 41 help
42 Say Y or M here if you want to add support for SoC audio on Rockchip 42 Say Y or M here if you want to add support for SoC audio on Rockchip
43 boards using the RT5645/RT5650 codec, such as Veyron. 43 boards using the RT5645/RT5650 codec, such as Veyron.
44
45config SND_SOC_RK3399_GRU_SOUND
46 tristate "ASoC support multiple codecs for Rockchip RK3399 GRU boards"
47 depends on SND_SOC_ROCKCHIP && I2C && GPIOLIB && CLKDEV_LOOKUP && SPI
48 select SND_SOC_ROCKCHIP_I2S
49 select SND_SOC_MAX98357A
50 select SND_SOC_RT5514
51 select SND_SOC_DA7219
52 select SND_SOC_RT5514_SPI
53 help
54 Say Y or M here if you want to add support multiple codecs for SoC
55 audio on Rockchip RK3399 GRU boards.
diff --git a/sound/soc/rockchip/Makefile b/sound/soc/rockchip/Makefile
index c0bf560125f3..84e5c7c700e7 100644
--- a/sound/soc/rockchip/Makefile
+++ b/sound/soc/rockchip/Makefile
@@ -7,6 +7,8 @@ obj-$(CONFIG_SND_SOC_ROCKCHIP_SPDIF) += snd-soc-rockchip-spdif.o
7 7
8snd-soc-rockchip-max98090-objs := rockchip_max98090.o 8snd-soc-rockchip-max98090-objs := rockchip_max98090.o
9snd-soc-rockchip-rt5645-objs := rockchip_rt5645.o 9snd-soc-rockchip-rt5645-objs := rockchip_rt5645.o
10snd-soc-rk3399-gru-sound-objs := rk3399_gru_sound.o
10 11
11obj-$(CONFIG_SND_SOC_ROCKCHIP_MAX98090) += snd-soc-rockchip-max98090.o 12obj-$(CONFIG_SND_SOC_ROCKCHIP_MAX98090) += snd-soc-rockchip-max98090.o
12obj-$(CONFIG_SND_SOC_ROCKCHIP_RT5645) += snd-soc-rockchip-rt5645.o 13obj-$(CONFIG_SND_SOC_ROCKCHIP_RT5645) += snd-soc-rockchip-rt5645.o
14obj-$(CONFIG_SND_SOC_RK3399_GRU_SOUND) += snd-soc-rk3399-gru-sound.o
diff --git a/sound/soc/rockchip/rk3399_gru_sound.c b/sound/soc/rockchip/rk3399_gru_sound.c
new file mode 100644
index 000000000000..9ed735a6cf49
--- /dev/null
+++ b/sound/soc/rockchip/rk3399_gru_sound.c
@@ -0,0 +1,397 @@
1/*
2 * Rockchip machine ASoC driver for boards using MAX98357A/RT5514/DA7219
3 *
4 * Copyright (c) 2016, ROCKCHIP CORPORATION. All rights reserved.
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms and conditions of the GNU General Public License,
8 * version 2, as published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
13 * more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19#include <linux/module.h>
20#include <linux/platform_device.h>
21#include <linux/slab.h>
22#include <linux/gpio.h>
23#include <linux/of_gpio.h>
24#include <linux/delay.h>
25#include <linux/spi/spi.h>
26#include <linux/input.h>
27#include <sound/core.h>
28#include <sound/jack.h>
29#include <sound/pcm.h>
30#include <sound/pcm_params.h>
31#include <sound/soc.h>
32#include "rockchip_i2s.h"
33#include "../codecs/da7219.h"
34#include "../codecs/da7219-aad.h"
35#include "../codecs/rt5514.h"
36
37#define DRV_NAME "rk3399-gru-sound"
38
39#define SOUND_FS 256
40
41unsigned int rt5514_dmic_delay;
42
43static struct snd_soc_jack rockchip_sound_jack;
44
45static const struct snd_soc_dapm_widget rockchip_dapm_widgets[] = {
46 SND_SOC_DAPM_HP("Headphones", NULL),
47 SND_SOC_DAPM_SPK("Speakers", NULL),
48 SND_SOC_DAPM_MIC("Headset Mic", NULL),
49 SND_SOC_DAPM_MIC("Int Mic", NULL),
50};
51
52static const struct snd_soc_dapm_route rockchip_dapm_routes[] = {
53 /* Input Lines */
54 {"MIC", NULL, "Headset Mic"},
55 {"DMIC1L", NULL, "Int Mic"},
56 {"DMIC1R", NULL, "Int Mic"},
57
58 /* Output Lines */
59 {"Headphones", NULL, "HPL"},
60 {"Headphones", NULL, "HPR"},
61 {"Speakers", NULL, "Speaker"},
62};
63
64static const struct snd_kcontrol_new rockchip_controls[] = {
65 SOC_DAPM_PIN_SWITCH("Headphones"),
66 SOC_DAPM_PIN_SWITCH("Speakers"),
67 SOC_DAPM_PIN_SWITCH("Headset Mic"),
68 SOC_DAPM_PIN_SWITCH("Int Mic"),
69};
70
71static int rockchip_sound_max98357a_hw_params(struct snd_pcm_substream *substream,
72 struct snd_pcm_hw_params *params)
73{
74 struct snd_soc_pcm_runtime *rtd = substream->private_data;
75 unsigned int mclk;
76 int ret;
77
78 /* max98357a supports these sample rates */
79 switch (params_rate(params)) {
80 case 8000:
81 case 16000:
82 case 48000:
83 case 96000:
84 mclk = params_rate(params) * SOUND_FS;
85 break;
86 default:
87 dev_err(rtd->card->dev, "%s() doesn't support this sample rate: %d\n",
88 __func__, params_rate(params));
89 return -EINVAL;
90 }
91
92 ret = snd_soc_dai_set_sysclk(rtd->cpu_dai, 0, mclk, 0);
93 if (ret) {
94 dev_err(rtd->card->dev, "%s() error setting sysclk to %u: %d\n",
95 __func__, mclk, ret);
96 return ret;
97 }
98
99 return 0;
100}
101
102static int rockchip_sound_rt5514_hw_params(struct snd_pcm_substream *substream,
103 struct snd_pcm_hw_params *params)
104{
105 struct snd_soc_pcm_runtime *rtd = substream->private_data;
106 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
107 struct snd_soc_dai *codec_dai = rtd->codec_dai;
108 unsigned int mclk;
109 int ret;
110
111 mclk = params_rate(params) * SOUND_FS;
112
113 ret = snd_soc_dai_set_sysclk(cpu_dai, 0, mclk,
114 SND_SOC_CLOCK_OUT);
115 if (ret < 0) {
116 dev_err(rtd->card->dev, "Can't set cpu clock out %d\n", ret);
117 return ret;
118 }
119
120 ret = snd_soc_dai_set_sysclk(codec_dai, RT5514_SCLK_S_MCLK,
121 mclk, SND_SOC_CLOCK_IN);
122 if (ret) {
123 dev_err(rtd->card->dev, "%s() error setting sysclk to %u: %d\n",
124 __func__, params_rate(params) * 512, ret);
125 return ret;
126 }
127
128 /* Wait for DMIC stable */
129 msleep(rt5514_dmic_delay);
130
131 return 0;
132}
133
134static int rockchip_sound_da7219_hw_params(struct snd_pcm_substream *substream,
135 struct snd_pcm_hw_params *params)
136{
137 struct snd_soc_pcm_runtime *rtd = substream->private_data;
138 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
139 struct snd_soc_dai *codec_dai = rtd->codec_dai;
140 int mclk, ret;
141
142 /* in bypass mode, the mclk has to be one of the frequencies below */
143 switch (params_rate(params)) {
144 case 8000:
145 case 16000:
146 case 24000:
147 case 32000:
148 case 48000:
149 case 64000:
150 case 96000:
151 mclk = 12288000;
152 break;
153 case 11025:
154 case 22050:
155 case 44100:
156 case 88200:
157 mclk = 11289600;
158 break;
159 default:
160 return -EINVAL;
161 }
162
163 ret = snd_soc_dai_set_sysclk(cpu_dai, 0, mclk,
164 SND_SOC_CLOCK_OUT);
165 if (ret < 0) {
166 dev_err(codec_dai->dev, "Can't set cpu clock out %d\n", ret);
167 return ret;
168 }
169
170 ret = snd_soc_dai_set_sysclk(codec_dai, 0, mclk,
171 SND_SOC_CLOCK_IN);
172 if (ret < 0) {
173 dev_err(codec_dai->dev, "Can't set codec clock in %d\n", ret);
174 return ret;
175 }
176
177 ret = snd_soc_dai_set_pll(codec_dai, 0, DA7219_SYSCLK_MCLK, 0, 0);
178 if (ret < 0) {
179 dev_err(codec_dai->dev, "Can't set pll sysclk mclk %d\n", ret);
180 return ret;
181 }
182
183 return 0;
184}
185
186static int rockchip_sound_da7219_init(struct snd_soc_pcm_runtime *rtd)
187{
188 struct snd_soc_codec *codec = rtd->codec_dais[0]->codec;
189 struct snd_soc_dai *codec_dai = rtd->codec_dai;
190 int ret;
191
192 /* We need default MCLK and PLL settings for the accessory detection */
193 ret = snd_soc_dai_set_sysclk(codec_dai, 0, 12288000,
194 SND_SOC_CLOCK_IN);
195 if (ret < 0) {
196 dev_err(codec_dai->dev, "Init can't set codec clock in %d\n", ret);
197 return ret;
198 }
199
200 ret = snd_soc_dai_set_pll(codec_dai, 0, DA7219_SYSCLK_MCLK, 0, 0);
201 if (ret < 0) {
202 dev_err(codec_dai->dev, "Init can't set pll sysclk mclk %d\n", ret);
203 return ret;
204 }
205
206 /* Enable Headset and 4 Buttons Jack detection */
207 ret = snd_soc_card_jack_new(rtd->card, "Headset Jack",
208 SND_JACK_HEADSET | SND_JACK_LINEOUT |
209 SND_JACK_BTN_0 | SND_JACK_BTN_1 |
210 SND_JACK_BTN_2 | SND_JACK_BTN_3,
211 &rockchip_sound_jack, NULL, 0);
212
213 if (ret) {
214 dev_err(rtd->card->dev, "New Headset Jack failed! (%d)\n", ret);
215 return ret;
216 }
217
218 snd_jack_set_key(rockchip_sound_jack.jack, SND_JACK_BTN_0, KEY_MEDIA);
219 snd_jack_set_key(
220 rockchip_sound_jack.jack, SND_JACK_BTN_1, KEY_VOLUMEUP);
221 snd_jack_set_key(
222 rockchip_sound_jack.jack, SND_JACK_BTN_2, KEY_VOLUMEDOWN);
223 snd_jack_set_key(
224 rockchip_sound_jack.jack, SND_JACK_BTN_3, KEY_VOICECOMMAND);
225
226 da7219_aad_jack_det(codec, &rockchip_sound_jack);
227
228 return 0;
229}
230
231static struct snd_soc_ops rockchip_sound_max98357a_ops = {
232 .hw_params = rockchip_sound_max98357a_hw_params,
233};
234
235static struct snd_soc_ops rockchip_sound_rt5514_ops = {
236 .hw_params = rockchip_sound_rt5514_hw_params,
237};
238
239static struct snd_soc_ops rockchip_sound_da7219_ops = {
240 .hw_params = rockchip_sound_da7219_hw_params,
241};
242
243enum {
244 DAILINK_MAX98357A,
245 DAILINK_RT5514,
246 DAILINK_DA7219,
247 DAILINK_RT5514_DSP,
248};
249
250#define DAILINK_ENTITIES (DAILINK_DA7219 + 1)
251
252static struct snd_soc_dai_link rockchip_dailinks[] = {
253 [DAILINK_MAX98357A] = {
254 .name = "MAX98357A",
255 .stream_name = "MAX98357A PCM",
256 .codec_dai_name = "HiFi",
257 .ops = &rockchip_sound_max98357a_ops,
258 /* set max98357a as slave */
259 .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
260 SND_SOC_DAIFMT_CBS_CFS,
261 },
262 [DAILINK_RT5514] = {
263 .name = "RT5514",
264 .stream_name = "RT5514 PCM",
265 .codec_dai_name = "rt5514-aif1",
266 .ops = &rockchip_sound_rt5514_ops,
267 /* set rt5514 as slave */
268 .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
269 SND_SOC_DAIFMT_CBS_CFS,
270 },
271 [DAILINK_DA7219] = {
272 .name = "DA7219",
273 .stream_name = "DA7219 PCM",
274 .codec_dai_name = "da7219-hifi",
275 .init = rockchip_sound_da7219_init,
276 .ops = &rockchip_sound_da7219_ops,
277 /* set da7219 as slave */
278 .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
279 SND_SOC_DAIFMT_CBS_CFS,
280 },
281 /* RT5514 DSP for voice wakeup via spi bus */
282 [DAILINK_RT5514_DSP] = {
283 .name = "RT5514 DSP",
284 .stream_name = "Wake on Voice",
285 .codec_name = "snd-soc-dummy",
286 .codec_dai_name = "snd-soc-dummy-dai",
287 },
288};
289
290static struct snd_soc_card rockchip_sound_card = {
291 .name = "rk3399-gru-sound",
292 .owner = THIS_MODULE,
293 .dai_link = rockchip_dailinks,
294 .num_links = ARRAY_SIZE(rockchip_dailinks),
295 .dapm_widgets = rockchip_dapm_widgets,
296 .num_dapm_widgets = ARRAY_SIZE(rockchip_dapm_widgets),
297 .dapm_routes = rockchip_dapm_routes,
298 .num_dapm_routes = ARRAY_SIZE(rockchip_dapm_routes),
299 .controls = rockchip_controls,
300 .num_controls = ARRAY_SIZE(rockchip_controls),
301};
302
303static int rockchip_sound_match_stub(struct device *dev, void *data)
304{
305 return 1;
306}
307
308static int rockchip_sound_probe(struct platform_device *pdev)
309{
310 struct snd_soc_card *card = &rockchip_sound_card;
311 struct device_node *cpu_node;
312 struct device *dev;
313 struct device_driver *drv;
314 int i, ret;
315
316 cpu_node = of_parse_phandle(pdev->dev.of_node, "rockchip,cpu", 0);
317 if (!cpu_node) {
318 dev_err(&pdev->dev, "Property 'rockchip,cpu' missing or invalid\n");
319 return -EINVAL;
320 }
321
322 for (i = 0; i < DAILINK_ENTITIES; i++) {
323 rockchip_dailinks[i].platform_of_node = cpu_node;
324 rockchip_dailinks[i].cpu_of_node = cpu_node;
325
326 rockchip_dailinks[i].codec_of_node =
327 of_parse_phandle(pdev->dev.of_node, "rockchip,codec", i);
328 if (!rockchip_dailinks[i].codec_of_node) {
329 dev_err(&pdev->dev,
330 "Property[%d] 'rockchip,codec' missing or invalid\n", i);
331 return -EINVAL;
332 }
333 }
334
335 /**
336 * To acquire the spi driver of the rt5514 and set the dai-links names
337 * for soc_bind_dai_link
338 */
339 drv = driver_find("rt5514", &spi_bus_type);
340 if (!drv) {
341 dev_err(&pdev->dev, "Can not find the rt5514 driver at the spi bus\n");
342 return -EINVAL;
343 }
344
345 dev = driver_find_device(drv, NULL, NULL, rockchip_sound_match_stub);
346 if (!dev) {
347 dev_err(&pdev->dev, "Can not find the rt5514 device\n");
348 return -ENODEV;
349 }
350
351 /* Set DMIC delay */
352 ret = device_property_read_u32(&pdev->dev, "dmic-delay",
353 &rt5514_dmic_delay);
354 if (ret) {
355 rt5514_dmic_delay = 0;
356 dev_dbg(&pdev->dev,
357 "no optional property 'dmic-delay' found, default: no delay\n");
358 }
359
360 rockchip_dailinks[DAILINK_RT5514_DSP].cpu_name = kstrdup_const(dev_name(dev), GFP_KERNEL);
361 rockchip_dailinks[DAILINK_RT5514_DSP].cpu_dai_name = kstrdup_const(dev_name(dev), GFP_KERNEL);
362 rockchip_dailinks[DAILINK_RT5514_DSP].platform_name = kstrdup_const(dev_name(dev), GFP_KERNEL);
363
364 card->dev = &pdev->dev;
365 platform_set_drvdata(pdev, card);
366
367 ret = devm_snd_soc_register_card(&pdev->dev, card);
368 if (ret)
369 dev_err(&pdev->dev, "%s snd_soc_register_card fail %d\n",
370 __func__, ret);
371
372 return ret;
373}
374
375static const struct of_device_id rockchip_sound_of_match[] = {
376 { .compatible = "rockchip,rk3399-gru-sound", },
377 {},
378};
379
380static struct platform_driver rockchip_sound_driver = {
381 .probe = rockchip_sound_probe,
382 .driver = {
383 .name = DRV_NAME,
384 .of_match_table = rockchip_sound_of_match,
385#ifdef CONFIG_PM
386 .pm = &snd_soc_pm_ops,
387#endif
388 },
389};
390
391module_platform_driver(rockchip_sound_driver);
392
393MODULE_AUTHOR("Xing Zheng <zhengxing@rock-chips.com>");
394MODULE_DESCRIPTION("Rockchip ASoC Machine Driver");
395MODULE_LICENSE("GPL v2");
396MODULE_ALIAS("platform:" DRV_NAME);
397MODULE_DEVICE_TABLE(of, rockchip_sound_of_match);
diff --git a/sound/soc/rockchip/rockchip_i2s.c b/sound/soc/rockchip/rockchip_i2s.c
index 652e8c5ea166..974915cb4c4f 100644
--- a/sound/soc/rockchip/rockchip_i2s.c
+++ b/sound/soc/rockchip/rockchip_i2s.c
@@ -57,6 +57,7 @@ static int i2s_runtime_suspend(struct device *dev)
57{ 57{
58 struct rk_i2s_dev *i2s = dev_get_drvdata(dev); 58 struct rk_i2s_dev *i2s = dev_get_drvdata(dev);
59 59
60 regcache_cache_only(i2s->regmap, true);
60 clk_disable_unprepare(i2s->mclk); 61 clk_disable_unprepare(i2s->mclk);
61 62
62 return 0; 63 return 0;
@@ -73,7 +74,14 @@ static int i2s_runtime_resume(struct device *dev)
73 return ret; 74 return ret;
74 } 75 }
75 76
76 return 0; 77 regcache_cache_only(i2s->regmap, false);
78 regcache_mark_dirty(i2s->regmap);
79
80 ret = regcache_sync(i2s->regmap);
81 if (ret)
82 clk_disable_unprepare(i2s->mclk);
83
84 return ret;
77} 85}
78 86
79static inline struct rk_i2s_dev *to_info(struct snd_soc_dai *dai) 87static inline struct rk_i2s_dev *to_info(struct snd_soc_dai *dai)
diff --git a/sound/soc/rockchip/rockchip_spdif.c b/sound/soc/rockchip/rockchip_spdif.c
index 4ca265737eda..fa8101d1e16f 100644
--- a/sound/soc/rockchip/rockchip_spdif.c
+++ b/sound/soc/rockchip/rockchip_spdif.c
@@ -65,6 +65,7 @@ static int __maybe_unused rk_spdif_runtime_suspend(struct device *dev)
65{ 65{
66 struct rk_spdif_dev *spdif = dev_get_drvdata(dev); 66 struct rk_spdif_dev *spdif = dev_get_drvdata(dev);
67 67
68 regcache_cache_only(spdif->regmap, true);
68 clk_disable_unprepare(spdif->mclk); 69 clk_disable_unprepare(spdif->mclk);
69 clk_disable_unprepare(spdif->hclk); 70 clk_disable_unprepare(spdif->hclk);
70 71
@@ -88,7 +89,16 @@ static int __maybe_unused rk_spdif_runtime_resume(struct device *dev)
88 return ret; 89 return ret;
89 } 90 }
90 91
91 return 0; 92 regcache_cache_only(spdif->regmap, false);
93 regcache_mark_dirty(spdif->regmap);
94
95 ret = regcache_sync(spdif->regmap);
96 if (ret) {
97 clk_disable_unprepare(spdif->mclk);
98 clk_disable_unprepare(spdif->hclk);
99 }
100
101 return ret;
92} 102}
93 103
94static int rk_spdif_hw_params(struct snd_pcm_substream *substream, 104static int rk_spdif_hw_params(struct snd_pcm_substream *substream,
diff --git a/sound/soc/samsung/Kconfig b/sound/soc/samsung/Kconfig
index 7b722b0094d9..f6023b46c107 100644
--- a/sound/soc/samsung/Kconfig
+++ b/sound/soc/samsung/Kconfig
@@ -1,12 +1,14 @@
1config SND_SOC_SAMSUNG 1menuconfig SND_SOC_SAMSUNG
2 tristate "ASoC support for Samsung" 2 tristate "ASoC support for Samsung"
3 depends on (PLAT_SAMSUNG || ARCH_EXYNOS) 3 depends on (PLAT_SAMSUNG || ARCH_EXYNOS)
4 select SND_SOC_GENERIC_DMAENGINE_PCM 4 select SND_SOC_GENERIC_DMAENGINE_PCM
5 help 5 ---help---
6 Say Y or M if you want to add support for codecs attached to 6 Say Y or M if you want to add support for codecs attached to
7 the Samsung SoCs' Audio interfaces. You will also need to 7 the Samsung SoCs' Audio interfaces. You will also need to
8 select the audio interfaces to support below. 8 select the audio interfaces to support below.
9 9
10if SND_SOC_SAMSUNG
11
10config SND_S3C24XX_I2S 12config SND_S3C24XX_I2S
11 tristate 13 tristate
12 14
@@ -18,22 +20,22 @@ config SND_S3C2412_SOC_I2S
18 select SND_S3C_I2SV2_SOC 20 select SND_S3C_I2SV2_SOC
19 21
20config SND_SAMSUNG_PCM 22config SND_SAMSUNG_PCM
21 tristate 23 tristate "Samsung PCM interface support"
22 24
23config SND_SAMSUNG_AC97 25config SND_SAMSUNG_AC97
24 tristate 26 tristate
25 select SND_SOC_AC97_BUS 27 select SND_SOC_AC97_BUS
26 28
27config SND_SAMSUNG_SPDIF 29config SND_SAMSUNG_SPDIF
28 tristate 30 tristate "Samsung SPDIF transmitter support"
29 select SND_SOC_SPDIF 31 select SND_SOC_SPDIF
30 32
31config SND_SAMSUNG_I2S 33config SND_SAMSUNG_I2S
32 tristate 34 tristate "Samsung I2S interface support"
33 35
34config SND_SOC_SAMSUNG_NEO1973_WM8753 36config SND_SOC_SAMSUNG_NEO1973_WM8753
35 tristate "Audio support for Openmoko Neo1973 Smartphones (GTA02)" 37 tristate "Audio support for Openmoko Neo1973 Smartphones (GTA02)"
36 depends on SND_SOC_SAMSUNG && MACH_NEO1973_GTA02 38 depends on MACH_NEO1973_GTA02
37 select SND_S3C24XX_I2S 39 select SND_S3C24XX_I2S
38 select SND_SOC_WM8753 40 select SND_SOC_WM8753
39 select SND_SOC_BT_SCO 41 select SND_SOC_BT_SCO
@@ -43,7 +45,7 @@ config SND_SOC_SAMSUNG_NEO1973_WM8753
43 45
44config SND_SOC_SAMSUNG_JIVE_WM8750 46config SND_SOC_SAMSUNG_JIVE_WM8750
45 tristate "SoC I2S Audio support for Jive" 47 tristate "SoC I2S Audio support for Jive"
46 depends on SND_SOC_SAMSUNG && MACH_JIVE && I2C 48 depends on MACH_JIVE && I2C
47 select SND_SOC_WM8750 49 select SND_SOC_WM8750
48 select SND_S3C2412_SOC_I2S 50 select SND_S3C2412_SOC_I2S
49 help 51 help
@@ -51,7 +53,7 @@ config SND_SOC_SAMSUNG_JIVE_WM8750
51 53
52config SND_SOC_SAMSUNG_SMDK_WM8580 54config SND_SOC_SAMSUNG_SMDK_WM8580
53 tristate "SoC I2S Audio support for WM8580 on SMDK" 55 tristate "SoC I2S Audio support for WM8580 on SMDK"
54 depends on SND_SOC_SAMSUNG && (MACH_SMDK6410 || MACH_SMDKC100 || MACH_SMDKV210 || MACH_SMDKC110) 56 depends on MACH_SMDK6410 || MACH_SMDKC100 || MACH_SMDKV210 || MACH_SMDKC110
55 depends on I2C 57 depends on I2C
56 select SND_SOC_WM8580 58 select SND_SOC_WM8580
57 select SND_SAMSUNG_I2S 59 select SND_SAMSUNG_I2S
@@ -60,7 +62,6 @@ config SND_SOC_SAMSUNG_SMDK_WM8580
60 62
61config SND_SOC_SAMSUNG_SMDK_WM8994 63config SND_SOC_SAMSUNG_SMDK_WM8994
62 tristate "SoC I2S Audio support for WM8994 on SMDK" 64 tristate "SoC I2S Audio support for WM8994 on SMDK"
63 depends on SND_SOC_SAMSUNG
64 depends on I2C=y 65 depends on I2C=y
65 select MFD_WM8994 66 select MFD_WM8994
66 select SND_SOC_WM8994 67 select SND_SOC_WM8994
@@ -70,7 +71,7 @@ config SND_SOC_SAMSUNG_SMDK_WM8994
70 71
71config SND_SOC_SAMSUNG_SMDK2443_WM9710 72config SND_SOC_SAMSUNG_SMDK2443_WM9710
72 tristate "SoC AC97 Audio support for SMDK2443 - WM9710" 73 tristate "SoC AC97 Audio support for SMDK2443 - WM9710"
73 depends on SND_SOC_SAMSUNG && MACH_SMDK2443 74 depends on MACH_SMDK2443
74 select AC97_BUS 75 select AC97_BUS
75 select SND_SOC_AC97_CODEC 76 select SND_SOC_AC97_CODEC
76 select SND_SAMSUNG_AC97 77 select SND_SAMSUNG_AC97
@@ -80,7 +81,7 @@ config SND_SOC_SAMSUNG_SMDK2443_WM9710
80 81
81config SND_SOC_SAMSUNG_LN2440SBC_ALC650 82config SND_SOC_SAMSUNG_LN2440SBC_ALC650
82 tristate "SoC AC97 Audio support for LN2440SBC - ALC650" 83 tristate "SoC AC97 Audio support for LN2440SBC - ALC650"
83 depends on SND_SOC_SAMSUNG && ARCH_S3C24XX 84 depends on ARCH_S3C24XX
84 select AC97_BUS 85 select AC97_BUS
85 select SND_SOC_AC97_CODEC 86 select SND_SOC_AC97_CODEC
86 select SND_SAMSUNG_AC97 87 select SND_SAMSUNG_AC97
@@ -90,7 +91,7 @@ config SND_SOC_SAMSUNG_LN2440SBC_ALC650
90 91
91config SND_SOC_SAMSUNG_S3C24XX_UDA134X 92config SND_SOC_SAMSUNG_S3C24XX_UDA134X
92 tristate "SoC I2S Audio support UDA134X wired to a S3C24XX" 93 tristate "SoC I2S Audio support UDA134X wired to a S3C24XX"
93 depends on SND_SOC_SAMSUNG && ARCH_S3C24XX 94 depends on ARCH_S3C24XX
94 select SND_S3C24XX_I2S 95 select SND_S3C24XX_I2S
95 select SND_SOC_L3 96 select SND_SOC_L3
96 select SND_SOC_UDA134X 97 select SND_SOC_UDA134X
@@ -102,21 +103,21 @@ config SND_SOC_SAMSUNG_SIMTEC
102 103
103config SND_SOC_SAMSUNG_SIMTEC_TLV320AIC23 104config SND_SOC_SAMSUNG_SIMTEC_TLV320AIC23
104 tristate "SoC I2S Audio support for TLV320AIC23 on Simtec boards" 105 tristate "SoC I2S Audio support for TLV320AIC23 on Simtec boards"
105 depends on SND_SOC_SAMSUNG && ARCH_S3C24XX && I2C 106 depends on ARCH_S3C24XX && I2C
106 select SND_S3C24XX_I2S 107 select SND_S3C24XX_I2S
107 select SND_SOC_TLV320AIC23_I2C 108 select SND_SOC_TLV320AIC23_I2C
108 select SND_SOC_SAMSUNG_SIMTEC 109 select SND_SOC_SAMSUNG_SIMTEC
109 110
110config SND_SOC_SAMSUNG_SIMTEC_HERMES 111config SND_SOC_SAMSUNG_SIMTEC_HERMES
111 tristate "SoC I2S Audio support for Simtec Hermes board" 112 tristate "SoC I2S Audio support for Simtec Hermes board"
112 depends on SND_SOC_SAMSUNG && ARCH_S3C24XX && I2C 113 depends on ARCH_S3C24XX && I2C
113 select SND_S3C24XX_I2S 114 select SND_S3C24XX_I2S
114 select SND_SOC_TLV320AIC3X 115 select SND_SOC_TLV320AIC3X
115 select SND_SOC_SAMSUNG_SIMTEC 116 select SND_SOC_SAMSUNG_SIMTEC
116 117
117config SND_SOC_SAMSUNG_H1940_UDA1380 118config SND_SOC_SAMSUNG_H1940_UDA1380
118 tristate "Audio support for the HP iPAQ H1940" 119 tristate "Audio support for the HP iPAQ H1940"
119 depends on SND_SOC_SAMSUNG && ARCH_H1940 && I2C 120 depends on ARCH_H1940 && I2C
120 select SND_S3C24XX_I2S 121 select SND_S3C24XX_I2S
121 select SND_SOC_UDA1380 122 select SND_SOC_UDA1380
122 help 123 help
@@ -124,7 +125,7 @@ config SND_SOC_SAMSUNG_H1940_UDA1380
124 125
125config SND_SOC_SAMSUNG_RX1950_UDA1380 126config SND_SOC_SAMSUNG_RX1950_UDA1380
126 tristate "Audio support for the HP iPAQ RX1950" 127 tristate "Audio support for the HP iPAQ RX1950"
127 depends on SND_SOC_SAMSUNG && MACH_RX1950 && I2C 128 depends on MACH_RX1950 && I2C
128 select SND_S3C24XX_I2S 129 select SND_S3C24XX_I2S
129 select SND_SOC_UDA1380 130 select SND_SOC_UDA1380
130 help 131 help
@@ -132,7 +133,7 @@ config SND_SOC_SAMSUNG_RX1950_UDA1380
132 133
133config SND_SOC_SAMSUNG_SMDK_WM9713 134config SND_SOC_SAMSUNG_SMDK_WM9713
134 tristate "SoC AC97 Audio support for SMDK with WM9713" 135 tristate "SoC AC97 Audio support for SMDK with WM9713"
135 depends on SND_SOC_SAMSUNG && (MACH_SMDK6410 || MACH_SMDKC100 || MACH_SMDKV210 || MACH_SMDKC110) 136 depends on MACH_SMDK6410 || MACH_SMDKC100 || MACH_SMDKV210 || MACH_SMDKC110
136 select SND_SOC_WM9713 137 select SND_SOC_WM9713
137 select SND_SAMSUNG_AC97 138 select SND_SAMSUNG_AC97
138 help 139 help
@@ -140,20 +141,19 @@ config SND_SOC_SAMSUNG_SMDK_WM9713
140 141
141config SND_SOC_SMARTQ 142config SND_SOC_SMARTQ
142 tristate "SoC I2S Audio support for SmartQ board" 143 tristate "SoC I2S Audio support for SmartQ board"
143 depends on SND_SOC_SAMSUNG && MACH_SMARTQ && I2C 144 depends on MACH_SMARTQ && I2C
144 select SND_SAMSUNG_I2S 145 select SND_SAMSUNG_I2S
145 select SND_SOC_WM8750 146 select SND_SOC_WM8750
146 147
147config SND_SOC_SAMSUNG_SMDK_SPDIF 148config SND_SOC_SAMSUNG_SMDK_SPDIF
148 tristate "SoC S/PDIF Audio support for SMDK" 149 tristate "SoC S/PDIF Audio support for SMDK"
149 depends on SND_SOC_SAMSUNG
150 select SND_SAMSUNG_SPDIF 150 select SND_SAMSUNG_SPDIF
151 help 151 help
152 Say Y if you want to add support for SoC S/PDIF audio on the SMDK. 152 Say Y if you want to add support for SoC S/PDIF audio on the SMDK.
153 153
154config SND_SOC_SMDK_WM8580_PCM 154config SND_SOC_SMDK_WM8580_PCM
155 tristate "SoC PCM Audio support for WM8580 on SMDK" 155 tristate "SoC PCM Audio support for WM8580 on SMDK"
156 depends on SND_SOC_SAMSUNG && (MACH_SMDKV210 || MACH_SMDKC110) 156 depends on MACH_SMDKV210 || MACH_SMDKC110
157 depends on I2C 157 depends on I2C
158 select SND_SOC_WM8580 158 select SND_SOC_WM8580
159 select SND_SAMSUNG_PCM 159 select SND_SAMSUNG_PCM
@@ -162,7 +162,6 @@ config SND_SOC_SMDK_WM8580_PCM
162 162
163config SND_SOC_SMDK_WM8994_PCM 163config SND_SOC_SMDK_WM8994_PCM
164 tristate "SoC PCM Audio support for WM8994 on SMDK" 164 tristate "SoC PCM Audio support for WM8994 on SMDK"
165 depends on SND_SOC_SAMSUNG
166 depends on I2C=y 165 depends on I2C=y
167 select MFD_WM8994 166 select MFD_WM8994
168 select SND_SOC_WM8994 167 select SND_SOC_WM8994
@@ -172,7 +171,7 @@ config SND_SOC_SMDK_WM8994_PCM
172 171
173config SND_SOC_SPEYSIDE 172config SND_SOC_SPEYSIDE
174 tristate "Audio support for Wolfson Speyside" 173 tristate "Audio support for Wolfson Speyside"
175 depends on SND_SOC_SAMSUNG && I2C && SPI_MASTER 174 depends on I2C && SPI_MASTER
176 depends on MACH_WLF_CRAGG_6410 || COMPILE_TEST 175 depends on MACH_WLF_CRAGG_6410 || COMPILE_TEST
177 select SND_SAMSUNG_I2S 176 select SND_SAMSUNG_I2S
178 select SND_SOC_WM8996 177 select SND_SOC_WM8996
@@ -182,14 +181,14 @@ config SND_SOC_SPEYSIDE
182 181
183config SND_SOC_TOBERMORY 182config SND_SOC_TOBERMORY
184 tristate "Audio support for Wolfson Tobermory" 183 tristate "Audio support for Wolfson Tobermory"
185 depends on SND_SOC_SAMSUNG && INPUT && I2C 184 depends on INPUT && I2C
186 depends on MACH_WLF_CRAGG_6410 || COMPILE_TEST 185 depends on MACH_WLF_CRAGG_6410 || COMPILE_TEST
187 select SND_SAMSUNG_I2S 186 select SND_SAMSUNG_I2S
188 select SND_SOC_WM8962 187 select SND_SOC_WM8962
189 188
190config SND_SOC_BELLS 189config SND_SOC_BELLS
191 tristate "Audio support for Wolfson Bells" 190 tristate "Audio support for Wolfson Bells"
192 depends on SND_SOC_SAMSUNG && MFD_ARIZONA && I2C && SPI_MASTER 191 depends on MFD_ARIZONA && I2C && SPI_MASTER
193 depends on MACH_WLF_CRAGG_6410 || COMPILE_TEST 192 depends on MACH_WLF_CRAGG_6410 || COMPILE_TEST
194 select SND_SAMSUNG_I2S 193 select SND_SAMSUNG_I2S
195 select SND_SOC_WM5102 194 select SND_SOC_WM5102
@@ -200,7 +199,7 @@ config SND_SOC_BELLS
200 199
201config SND_SOC_LOWLAND 200config SND_SOC_LOWLAND
202 tristate "Audio support for Wolfson Lowland" 201 tristate "Audio support for Wolfson Lowland"
203 depends on SND_SOC_SAMSUNG && I2C 202 depends on I2C
204 depends on MACH_WLF_CRAGG_6410 || COMPILE_TEST 203 depends on MACH_WLF_CRAGG_6410 || COMPILE_TEST
205 select SND_SAMSUNG_I2S 204 select SND_SAMSUNG_I2S
206 select SND_SOC_WM5100 205 select SND_SOC_WM5100
@@ -208,7 +207,7 @@ config SND_SOC_LOWLAND
208 207
209config SND_SOC_LITTLEMILL 208config SND_SOC_LITTLEMILL
210 tristate "Audio support for Wolfson Littlemill" 209 tristate "Audio support for Wolfson Littlemill"
211 depends on SND_SOC_SAMSUNG && I2C 210 depends on I2C
212 depends on MACH_WLF_CRAGG_6410 || COMPILE_TEST 211 depends on MACH_WLF_CRAGG_6410 || COMPILE_TEST
213 select SND_SAMSUNG_I2S 212 select SND_SAMSUNG_I2S
214 select MFD_WM8994 213 select MFD_WM8994
@@ -216,7 +215,7 @@ config SND_SOC_LITTLEMILL
216 215
217config SND_SOC_SNOW 216config SND_SOC_SNOW
218 tristate "Audio support for Google Snow boards" 217 tristate "Audio support for Google Snow boards"
219 depends on SND_SOC_SAMSUNG && I2C 218 depends on I2C
220 select SND_SOC_MAX98090 219 select SND_SOC_MAX98090
221 select SND_SOC_MAX98095 220 select SND_SOC_MAX98095
222 select SND_SAMSUNG_I2S 221 select SND_SAMSUNG_I2S
@@ -226,6 +225,8 @@ config SND_SOC_SNOW
226 225
227config SND_SOC_ARNDALE_RT5631_ALC5631 226config SND_SOC_ARNDALE_RT5631_ALC5631
228 tristate "Audio support for RT5631(ALC5631) on Arndale Board" 227 tristate "Audio support for RT5631(ALC5631) on Arndale Board"
229 depends on SND_SOC_SAMSUNG && I2C 228 depends on I2C
230 select SND_SAMSUNG_I2S 229 select SND_SAMSUNG_I2S
231 select SND_SOC_RT5631 230 select SND_SOC_RT5631
231
232endif #SND_SOC_SAMSUNG
diff --git a/sound/soc/samsung/ac97.c b/sound/soc/samsung/ac97.c
index 547d31032088..97d6700b1009 100644
--- a/sound/soc/samsung/ac97.c
+++ b/sound/soc/samsung/ac97.c
@@ -38,16 +38,16 @@ struct s3c_ac97_info {
38}; 38};
39static struct s3c_ac97_info s3c_ac97; 39static struct s3c_ac97_info s3c_ac97;
40 40
41static struct s3c_dma_params s3c_ac97_pcm_out = { 41static struct snd_dmaengine_dai_dma_data s3c_ac97_pcm_out = {
42 .dma_size = 4, 42 .addr_width = 4,
43}; 43};
44 44
45static struct s3c_dma_params s3c_ac97_pcm_in = { 45static struct snd_dmaengine_dai_dma_data s3c_ac97_pcm_in = {
46 .dma_size = 4, 46 .addr_width = 4,
47}; 47};
48 48
49static struct s3c_dma_params s3c_ac97_mic_in = { 49static struct snd_dmaengine_dai_dma_data s3c_ac97_mic_in = {
50 .dma_size = 4, 50 .addr_width = 4,
51}; 51};
52 52
53static void s3c_ac97_activate(struct snd_ac97 *ac97) 53static void s3c_ac97_activate(struct snd_ac97 *ac97)
@@ -74,7 +74,7 @@ static void s3c_ac97_activate(struct snd_ac97 *ac97)
74 writel(ac_glbctrl, s3c_ac97.regs + S3C_AC97_GLBCTRL); 74 writel(ac_glbctrl, s3c_ac97.regs + S3C_AC97_GLBCTRL);
75 75
76 if (!wait_for_completion_timeout(&s3c_ac97.done, HZ)) 76 if (!wait_for_completion_timeout(&s3c_ac97.done, HZ))
77 pr_err("AC97: Unable to activate!"); 77 pr_err("AC97: Unable to activate!\n");
78} 78}
79 79
80static unsigned short s3c_ac97_read(struct snd_ac97 *ac97, 80static unsigned short s3c_ac97_read(struct snd_ac97 *ac97,
@@ -100,7 +100,7 @@ static unsigned short s3c_ac97_read(struct snd_ac97 *ac97,
100 writel(ac_glbctrl, s3c_ac97.regs + S3C_AC97_GLBCTRL); 100 writel(ac_glbctrl, s3c_ac97.regs + S3C_AC97_GLBCTRL);
101 101
102 if (!wait_for_completion_timeout(&s3c_ac97.done, HZ)) 102 if (!wait_for_completion_timeout(&s3c_ac97.done, HZ))
103 pr_err("AC97: Unable to read!"); 103 pr_err("AC97: Unable to read!\n");
104 104
105 stat = readl(s3c_ac97.regs + S3C_AC97_STAT); 105 stat = readl(s3c_ac97.regs + S3C_AC97_STAT);
106 addr = (stat >> 16) & 0x7f; 106 addr = (stat >> 16) & 0x7f;
@@ -137,7 +137,7 @@ static void s3c_ac97_write(struct snd_ac97 *ac97, unsigned short reg,
137 writel(ac_glbctrl, s3c_ac97.regs + S3C_AC97_GLBCTRL); 137 writel(ac_glbctrl, s3c_ac97.regs + S3C_AC97_GLBCTRL);
138 138
139 if (!wait_for_completion_timeout(&s3c_ac97.done, HZ)) 139 if (!wait_for_completion_timeout(&s3c_ac97.done, HZ))
140 pr_err("AC97: Unable to write!"); 140 pr_err("AC97: Unable to write!\n");
141 141
142 ac_codec_cmd = readl(s3c_ac97.regs + S3C_AC97_CODEC_CMD); 142 ac_codec_cmd = readl(s3c_ac97.regs + S3C_AC97_CODEC_CMD);
143 ac_codec_cmd |= S3C_AC97_CODEC_CMD_READ; 143 ac_codec_cmd |= S3C_AC97_CODEC_CMD_READ;
@@ -273,14 +273,14 @@ static const struct snd_soc_dai_ops s3c_ac97_mic_dai_ops = {
273 273
274static int s3c_ac97_dai_probe(struct snd_soc_dai *dai) 274static int s3c_ac97_dai_probe(struct snd_soc_dai *dai)
275{ 275{
276 samsung_asoc_init_dma_data(dai, &s3c_ac97_pcm_out, &s3c_ac97_pcm_in); 276 snd_soc_dai_init_dma_data(dai, &s3c_ac97_pcm_out, &s3c_ac97_pcm_in);
277 277
278 return 0; 278 return 0;
279} 279}
280 280
281static int s3c_ac97_mic_dai_probe(struct snd_soc_dai *dai) 281static int s3c_ac97_mic_dai_probe(struct snd_soc_dai *dai)
282{ 282{
283 samsung_asoc_init_dma_data(dai, NULL, &s3c_ac97_mic_in); 283 snd_soc_dai_init_dma_data(dai, NULL, &s3c_ac97_mic_in);
284 284
285 return 0; 285 return 0;
286} 286}
@@ -346,12 +346,12 @@ static int s3c_ac97_probe(struct platform_device *pdev)
346 if (IS_ERR(s3c_ac97.regs)) 346 if (IS_ERR(s3c_ac97.regs))
347 return PTR_ERR(s3c_ac97.regs); 347 return PTR_ERR(s3c_ac97.regs);
348 348
349 s3c_ac97_pcm_out.slave = ac97_pdata->dma_playback; 349 s3c_ac97_pcm_out.filter_data = ac97_pdata->dma_playback;
350 s3c_ac97_pcm_out.dma_addr = mem_res->start + S3C_AC97_PCM_DATA; 350 s3c_ac97_pcm_out.addr = mem_res->start + S3C_AC97_PCM_DATA;
351 s3c_ac97_pcm_in.slave = ac97_pdata->dma_capture; 351 s3c_ac97_pcm_in.filter_data = ac97_pdata->dma_capture;
352 s3c_ac97_pcm_in.dma_addr = mem_res->start + S3C_AC97_PCM_DATA; 352 s3c_ac97_pcm_in.addr = mem_res->start + S3C_AC97_PCM_DATA;
353 s3c_ac97_mic_in.slave = ac97_pdata->dma_capture_mic; 353 s3c_ac97_mic_in.filter_data = ac97_pdata->dma_capture_mic;
354 s3c_ac97_mic_in.dma_addr = mem_res->start + S3C_AC97_MIC_DATA; 354 s3c_ac97_mic_in.addr = mem_res->start + S3C_AC97_MIC_DATA;
355 355
356 init_completion(&s3c_ac97.done); 356 init_completion(&s3c_ac97.done);
357 mutex_init(&s3c_ac97.lock); 357 mutex_init(&s3c_ac97.lock);
diff --git a/sound/soc/samsung/dma.h b/sound/soc/samsung/dma.h
index 3830f297e0b6..7ae580d677c8 100644
--- a/sound/soc/samsung/dma.h
+++ b/sound/soc/samsung/dma.h
@@ -1,6 +1,4 @@
1/* 1/*
2 * dma.h --
3 *
4 * This program is free software; you can redistribute it and/or modify it 2 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License as published by the 3 * under the terms of the GNU General Public License as published by the
6 * Free Software Foundation; either version 2 of the License, or (at your 4 * Free Software Foundation; either version 2 of the License, or (at your
@@ -9,27 +7,15 @@
9 * ALSA PCM interface for the Samsung SoC 7 * ALSA PCM interface for the Samsung SoC
10 */ 8 */
11 9
12#ifndef _S3C_AUDIO_H 10#ifndef _SAMSUNG_DMA_H
13#define _S3C_AUDIO_H 11#define _SAMSUNG_DMA_H
14 12
15#include <sound/dmaengine_pcm.h> 13#include <sound/dmaengine_pcm.h>
16#include <linux/dmaengine.h>
17
18struct s3c_dma_params {
19 void *slave; /* Channel ID */
20 dma_addr_t dma_addr;
21 int dma_size; /* Size of the DMA transfer */
22 char *ch_name;
23 struct snd_dmaengine_dai_dma_data dma_data;
24};
25 14
26void samsung_asoc_init_dma_data(struct snd_soc_dai *dai,
27 struct s3c_dma_params *playback,
28 struct s3c_dma_params *capture);
29/* 15/*
30 * @tx, @rx arguments can be NULL if the DMA channel names are "tx", "rx", 16 * @tx, @rx arguments can be NULL if the DMA channel names are "tx", "rx",
31 * otherwise actual DMA channel names must be passed to this function. 17 * otherwise actual DMA channel names must be passed to this function.
32 */ 18 */
33int samsung_asoc_dma_platform_register(struct device *dev, dma_filter_fn filter, 19int samsung_asoc_dma_platform_register(struct device *dev, dma_filter_fn filter,
34 const char *tx, const char *rx); 20 const char *tx, const char *rx);
35#endif 21#endif /* _SAMSUNG_DMA_H */
diff --git a/sound/soc/samsung/dmaengine.c b/sound/soc/samsung/dmaengine.c
index 2c87f380bfc4..9104c98deeb7 100644
--- a/sound/soc/samsung/dmaengine.c
+++ b/sound/soc/samsung/dmaengine.c
@@ -16,49 +16,18 @@
16 */ 16 */
17 17
18#include <linux/module.h> 18#include <linux/module.h>
19#include <linux/amba/pl08x.h>
20#include <linux/platform_data/dma-s3c24xx.h>
21
22#include <sound/core.h> 19#include <sound/core.h>
23#include <sound/pcm.h> 20#include <sound/pcm.h>
24#include <sound/pcm_params.h> 21#include <sound/pcm_params.h>
25#include <sound/dmaengine_pcm.h> 22#include <sound/dmaengine_pcm.h>
26#include <sound/soc.h> 23#include <sound/soc.h>
27#include <sound/soc-dai.h>
28 24
29#include "dma.h" 25#include "dma.h"
30 26
31void samsung_asoc_init_dma_data(struct snd_soc_dai *dai,
32 struct s3c_dma_params *playback,
33 struct s3c_dma_params *capture)
34{
35 struct snd_dmaengine_dai_dma_data *playback_data = NULL;
36 struct snd_dmaengine_dai_dma_data *capture_data = NULL;
37
38 if (playback) {
39 playback_data = &playback->dma_data;
40 playback_data->filter_data = playback->slave;
41 playback_data->chan_name = playback->ch_name;
42 playback_data->addr = playback->dma_addr;
43 playback_data->addr_width = playback->dma_size;
44 }
45 if (capture) {
46 capture_data = &capture->dma_data;
47 capture_data->filter_data = capture->slave;
48 capture_data->chan_name = capture->ch_name;
49 capture_data->addr = capture->dma_addr;
50 capture_data->addr_width = capture->dma_size;
51 }
52
53 snd_soc_dai_init_dma_data(dai, playback_data, capture_data);
54}
55EXPORT_SYMBOL_GPL(samsung_asoc_init_dma_data);
56
57int samsung_asoc_dma_platform_register(struct device *dev, dma_filter_fn filter, 27int samsung_asoc_dma_platform_register(struct device *dev, dma_filter_fn filter,
58 const char *tx, const char *rx) 28 const char *tx, const char *rx)
59{ 29{
60 unsigned int flags = SND_DMAENGINE_PCM_FLAG_COMPAT; 30 unsigned int flags = SND_DMAENGINE_PCM_FLAG_COMPAT;
61
62 struct snd_dmaengine_pcm_config *pcm_conf; 31 struct snd_dmaengine_pcm_config *pcm_conf;
63 32
64 pcm_conf = devm_kzalloc(dev, sizeof(*pcm_conf), GFP_KERNEL); 33 pcm_conf = devm_kzalloc(dev, sizeof(*pcm_conf), GFP_KERNEL);
diff --git a/sound/soc/samsung/i2s.c b/sound/soc/samsung/i2s.c
index 50635ee8ff20..7e32cf4581f8 100644
--- a/sound/soc/samsung/i2s.c
+++ b/sound/soc/samsung/i2s.c
@@ -87,9 +87,9 @@ struct i2s_dai {
87 /* Driver for this DAI */ 87 /* Driver for this DAI */
88 struct snd_soc_dai_driver i2s_dai_drv; 88 struct snd_soc_dai_driver i2s_dai_drv;
89 /* DMA parameters */ 89 /* DMA parameters */
90 struct s3c_dma_params dma_playback; 90 struct snd_dmaengine_dai_dma_data dma_playback;
91 struct s3c_dma_params dma_capture; 91 struct snd_dmaengine_dai_dma_data dma_capture;
92 struct s3c_dma_params idma_playback; 92 struct snd_dmaengine_dai_dma_data idma_playback;
93 dma_filter_fn filter; 93 dma_filter_fn filter;
94 u32 quirks; 94 u32 quirks;
95 u32 suspend_i2smod; 95 u32 suspend_i2smod;
@@ -692,15 +692,15 @@ static int i2s_hw_params(struct snd_pcm_substream *substream,
692 break; 692 break;
693 case 2: 693 case 2:
694 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 694 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
695 i2s->dma_playback.dma_size = 4; 695 i2s->dma_playback.addr_width = 4;
696 else 696 else
697 i2s->dma_capture.dma_size = 4; 697 i2s->dma_capture.addr_width = 4;
698 break; 698 break;
699 case 1: 699 case 1:
700 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 700 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
701 i2s->dma_playback.dma_size = 2; 701 i2s->dma_playback.addr_width = 2;
702 else 702 else
703 i2s->dma_capture.dma_size = 2; 703 i2s->dma_capture.addr_width = 2;
704 704
705 break; 705 break;
706 default: 706 default:
@@ -754,7 +754,7 @@ static int i2s_hw_params(struct snd_pcm_substream *substream,
754 writel(mod, i2s->addr + I2SMOD); 754 writel(mod, i2s->addr + I2SMOD);
755 spin_unlock_irqrestore(i2s->lock, flags); 755 spin_unlock_irqrestore(i2s->lock, flags);
756 756
757 samsung_asoc_init_dma_data(dai, &i2s->dma_playback, &i2s->dma_capture); 757 snd_soc_dai_init_dma_data(dai, &i2s->dma_playback, &i2s->dma_capture);
758 758
759 i2s->frmclk = params_rate(params); 759 i2s->frmclk = params_rate(params);
760 760
@@ -991,10 +991,10 @@ static int samsung_i2s_dai_probe(struct snd_soc_dai *dai)
991 unsigned long flags; 991 unsigned long flags;
992 992
993 if (is_secondary(i2s)) { /* If this is probe on the secondary DAI */ 993 if (is_secondary(i2s)) { /* If this is probe on the secondary DAI */
994 samsung_asoc_init_dma_data(dai, &other->sec_dai->dma_playback, 994 snd_soc_dai_init_dma_data(dai, &other->sec_dai->dma_playback,
995 NULL); 995 NULL);
996 } else { 996 } else {
997 samsung_asoc_init_dma_data(dai, &i2s->dma_playback, 997 snd_soc_dai_init_dma_data(dai, &i2s->dma_playback,
998 &i2s->dma_capture); 998 &i2s->dma_capture);
999 999
1000 if (i2s->quirks & QUIRK_NEED_RSTCLR) 1000 if (i2s->quirks & QUIRK_NEED_RSTCLR)
@@ -1002,7 +1002,7 @@ static int samsung_i2s_dai_probe(struct snd_soc_dai *dai)
1002 1002
1003 if (i2s->quirks & QUIRK_SUPPORTS_IDMA) 1003 if (i2s->quirks & QUIRK_SUPPORTS_IDMA)
1004 idma_reg_addr_init(i2s->addr, 1004 idma_reg_addr_init(i2s->addr,
1005 i2s->sec_dai->idma_playback.dma_addr); 1005 i2s->sec_dai->idma_playback.addr);
1006 } 1006 }
1007 1007
1008 /* Reset any constraint on RFS and BFS */ 1008 /* Reset any constraint on RFS and BFS */
@@ -1262,8 +1262,8 @@ static int samsung_i2s_probe(struct platform_device *pdev)
1262 return -EINVAL; 1262 return -EINVAL;
1263 } 1263 }
1264 1264
1265 pri_dai->dma_playback.slave = i2s_pdata->dma_playback; 1265 pri_dai->dma_playback.filter_data = i2s_pdata->dma_playback;
1266 pri_dai->dma_capture.slave = i2s_pdata->dma_capture; 1266 pri_dai->dma_capture.filter_data = i2s_pdata->dma_capture;
1267 pri_dai->filter = i2s_pdata->dma_filter; 1267 pri_dai->filter = i2s_pdata->dma_filter;
1268 1268
1269 if (&i2s_pdata->type) 1269 if (&i2s_pdata->type)
@@ -1302,12 +1302,12 @@ static int samsung_i2s_probe(struct platform_device *pdev)
1302 dev_err(&pdev->dev, "failed to enable clock: %d\n", ret); 1302 dev_err(&pdev->dev, "failed to enable clock: %d\n", ret);
1303 return ret; 1303 return ret;
1304 } 1304 }
1305 pri_dai->dma_playback.dma_addr = regs_base + I2STXD; 1305 pri_dai->dma_playback.addr = regs_base + I2STXD;
1306 pri_dai->dma_capture.dma_addr = regs_base + I2SRXD; 1306 pri_dai->dma_capture.addr = regs_base + I2SRXD;
1307 pri_dai->dma_playback.ch_name = "tx"; 1307 pri_dai->dma_playback.chan_name = "tx";
1308 pri_dai->dma_capture.ch_name = "rx"; 1308 pri_dai->dma_capture.chan_name = "rx";
1309 pri_dai->dma_playback.dma_size = 4; 1309 pri_dai->dma_playback.addr_width = 4;
1310 pri_dai->dma_capture.dma_size = 4; 1310 pri_dai->dma_capture.addr_width = 4;
1311 pri_dai->quirks = quirks; 1311 pri_dai->quirks = quirks;
1312 pri_dai->variant_regs = i2s_dai_data->i2s_variant_regs; 1312 pri_dai->variant_regs = i2s_dai_data->i2s_variant_regs;
1313 1313
@@ -1318,31 +1318,33 @@ static int samsung_i2s_probe(struct platform_device *pdev)
1318 sec_dai = i2s_alloc_dai(pdev, true); 1318 sec_dai = i2s_alloc_dai(pdev, true);
1319 if (!sec_dai) { 1319 if (!sec_dai) {
1320 dev_err(&pdev->dev, "Unable to alloc I2S_sec\n"); 1320 dev_err(&pdev->dev, "Unable to alloc I2S_sec\n");
1321 return -ENOMEM; 1321 ret = -ENOMEM;
1322 goto err_disable_clk;
1322 } 1323 }
1323 1324
1324 sec_dai->lock = &pri_dai->spinlock; 1325 sec_dai->lock = &pri_dai->spinlock;
1325 sec_dai->variant_regs = pri_dai->variant_regs; 1326 sec_dai->variant_regs = pri_dai->variant_regs;
1326 sec_dai->dma_playback.dma_addr = regs_base + I2STXDS; 1327 sec_dai->dma_playback.addr = regs_base + I2STXDS;
1327 sec_dai->dma_playback.ch_name = "tx-sec"; 1328 sec_dai->dma_playback.chan_name = "tx-sec";
1328 1329
1329 if (!np) { 1330 if (!np) {
1330 sec_dai->dma_playback.slave = i2s_pdata->dma_play_sec; 1331 sec_dai->dma_playback.filter_data = i2s_pdata->dma_play_sec;
1331 sec_dai->filter = i2s_pdata->dma_filter; 1332 sec_dai->filter = i2s_pdata->dma_filter;
1332 } 1333 }
1333 1334
1334 sec_dai->dma_playback.dma_size = 4; 1335 sec_dai->dma_playback.addr_width = 4;
1335 sec_dai->addr = pri_dai->addr; 1336 sec_dai->addr = pri_dai->addr;
1336 sec_dai->clk = pri_dai->clk; 1337 sec_dai->clk = pri_dai->clk;
1337 sec_dai->quirks = quirks; 1338 sec_dai->quirks = quirks;
1338 sec_dai->idma_playback.dma_addr = idma_addr; 1339 sec_dai->idma_playback.addr = idma_addr;
1339 sec_dai->pri_dai = pri_dai; 1340 sec_dai->pri_dai = pri_dai;
1340 pri_dai->sec_dai = sec_dai; 1341 pri_dai->sec_dai = sec_dai;
1341 } 1342 }
1342 1343
1343 if (i2s_pdata && i2s_pdata->cfg_gpio && i2s_pdata->cfg_gpio(pdev)) { 1344 if (i2s_pdata && i2s_pdata->cfg_gpio && i2s_pdata->cfg_gpio(pdev)) {
1344 dev_err(&pdev->dev, "Unable to configure gpio\n"); 1345 dev_err(&pdev->dev, "Unable to configure gpio\n");
1345 return -EINVAL; 1346 ret = -EINVAL;
1347 goto err_disable_clk;
1346 } 1348 }
1347 1349
1348 ret = devm_snd_soc_register_component(&pri_dai->pdev->dev, 1350 ret = devm_snd_soc_register_component(&pri_dai->pdev->dev,
@@ -1366,6 +1368,8 @@ static int samsung_i2s_probe(struct platform_device *pdev)
1366err_free_dai: 1368err_free_dai:
1367 if (sec_dai) 1369 if (sec_dai)
1368 i2s_free_sec_dai(sec_dai); 1370 i2s_free_sec_dai(sec_dai);
1371err_disable_clk:
1372 clk_disable_unprepare(pri_dai->clk);
1369 return ret; 1373 return ret;
1370} 1374}
1371 1375
diff --git a/sound/soc/samsung/idma.c b/sound/soc/samsung/idma.c
index 4ed29ffc1c54..3e408158625d 100644
--- a/sound/soc/samsung/idma.c
+++ b/sound/soc/samsung/idma.c
@@ -22,7 +22,6 @@
22 22
23#include "i2s.h" 23#include "i2s.h"
24#include "idma.h" 24#include "idma.h"
25#include "dma.h"
26#include "i2s-regs.h" 25#include "i2s-regs.h"
27 26
28#define ST_RUNNING (1<<0) 27#define ST_RUNNING (1<<0)
diff --git a/sound/soc/samsung/pcm.c b/sound/soc/samsung/pcm.c
index 490c1a87fd66..43e367a9acc3 100644
--- a/sound/soc/samsung/pcm.c
+++ b/sound/soc/samsung/pcm.c
@@ -127,25 +127,25 @@ struct s3c_pcm_info {
127 struct clk *pclk; 127 struct clk *pclk;
128 struct clk *cclk; 128 struct clk *cclk;
129 129
130 struct s3c_dma_params *dma_playback; 130 struct snd_dmaengine_dai_dma_data *dma_playback;
131 struct s3c_dma_params *dma_capture; 131 struct snd_dmaengine_dai_dma_data *dma_capture;
132}; 132};
133 133
134static struct s3c_dma_params s3c_pcm_stereo_out[] = { 134static struct snd_dmaengine_dai_dma_data s3c_pcm_stereo_out[] = {
135 [0] = { 135 [0] = {
136 .dma_size = 4, 136 .addr_width = 4,
137 }, 137 },
138 [1] = { 138 [1] = {
139 .dma_size = 4, 139 .addr_width = 4,
140 }, 140 },
141}; 141};
142 142
143static struct s3c_dma_params s3c_pcm_stereo_in[] = { 143static struct snd_dmaengine_dai_dma_data s3c_pcm_stereo_in[] = {
144 [0] = { 144 [0] = {
145 .dma_size = 4, 145 .addr_width = 4,
146 }, 146 },
147 [1] = { 147 [1] = {
148 .dma_size = 4, 148 .addr_width = 4,
149 }, 149 },
150}; 150};
151 151
@@ -552,15 +552,13 @@ static int s3c_pcm_dev_probe(struct platform_device *pdev)
552 } 552 }
553 clk_prepare_enable(pcm->pclk); 553 clk_prepare_enable(pcm->pclk);
554 554
555 s3c_pcm_stereo_in[pdev->id].dma_addr = mem_res->start 555 s3c_pcm_stereo_in[pdev->id].addr = mem_res->start + S3C_PCM_RXFIFO;
556 + S3C_PCM_RXFIFO; 556 s3c_pcm_stereo_out[pdev->id].addr = mem_res->start + S3C_PCM_TXFIFO;
557 s3c_pcm_stereo_out[pdev->id].dma_addr = mem_res->start
558 + S3C_PCM_TXFIFO;
559 557
560 filter = NULL; 558 filter = NULL;
561 if (pcm_pdata) { 559 if (pcm_pdata) {
562 s3c_pcm_stereo_in[pdev->id].slave = pcm_pdata->dma_capture; 560 s3c_pcm_stereo_in[pdev->id].filter_data = pcm_pdata->dma_capture;
563 s3c_pcm_stereo_out[pdev->id].slave = pcm_pdata->dma_playback; 561 s3c_pcm_stereo_out[pdev->id].filter_data = pcm_pdata->dma_playback;
564 filter = pcm_pdata->dma_filter; 562 filter = pcm_pdata->dma_filter;
565 } 563 }
566 564
diff --git a/sound/soc/samsung/s3c-i2s-v2.c b/sound/soc/samsung/s3c-i2s-v2.c
index bf8ae79b0fd2..644f186fd35c 100644
--- a/sound/soc/samsung/s3c-i2s-v2.c
+++ b/sound/soc/samsung/s3c-i2s-v2.c
@@ -24,7 +24,6 @@
24 24
25#include "regs-i2s-v2.h" 25#include "regs-i2s-v2.h"
26#include "s3c-i2s-v2.h" 26#include "s3c-i2s-v2.h"
27#include "dma.h"
28 27
29#undef S3C_IIS_V2_SUPPORTED 28#undef S3C_IIS_V2_SUPPORTED
30 29
@@ -302,7 +301,7 @@ static int s3c_i2sv2_hw_params(struct snd_pcm_substream *substream,
302 struct snd_soc_dai *dai) 301 struct snd_soc_dai *dai)
303{ 302{
304 struct s3c_i2sv2_info *i2s = to_info(dai); 303 struct s3c_i2sv2_info *i2s = to_info(dai);
305 struct s3c_dma_params *dma_data; 304 struct snd_dmaengine_dai_dma_data *dma_data;
306 u32 iismod; 305 u32 iismod;
307 306
308 pr_debug("Entered %s\n", __func__); 307 pr_debug("Entered %s\n", __func__);
diff --git a/sound/soc/samsung/s3c-i2s-v2.h b/sound/soc/samsung/s3c-i2s-v2.h
index d0684145ed1f..182d80564e37 100644
--- a/sound/soc/samsung/s3c-i2s-v2.h
+++ b/sound/soc/samsung/s3c-i2s-v2.h
@@ -60,8 +60,8 @@ struct s3c_i2sv2_info {
60 60
61 unsigned char master; 61 unsigned char master;
62 62
63 struct s3c_dma_params *dma_playback; 63 struct snd_dmaengine_dai_dma_data *dma_playback;
64 struct s3c_dma_params *dma_capture; 64 struct snd_dmaengine_dai_dma_data *dma_capture;
65 65
66 u32 suspend_iismod; 66 u32 suspend_iismod;
67 u32 suspend_iiscon; 67 u32 suspend_iiscon;
diff --git a/sound/soc/samsung/s3c2412-i2s.c b/sound/soc/samsung/s3c2412-i2s.c
index d45dffb297d8..3e89fbc0c51d 100644
--- a/sound/soc/samsung/s3c2412-i2s.c
+++ b/sound/soc/samsung/s3c2412-i2s.c
@@ -34,14 +34,14 @@
34 34
35#include <linux/platform_data/asoc-s3c.h> 35#include <linux/platform_data/asoc-s3c.h>
36 36
37static struct s3c_dma_params s3c2412_i2s_pcm_stereo_out = { 37static struct snd_dmaengine_dai_dma_data s3c2412_i2s_pcm_stereo_out = {
38 .ch_name = "tx", 38 .chan_name = "tx",
39 .dma_size = 4, 39 .addr_width = 4,
40}; 40};
41 41
42static struct s3c_dma_params s3c2412_i2s_pcm_stereo_in = { 42static struct snd_dmaengine_dai_dma_data s3c2412_i2s_pcm_stereo_in = {
43 .ch_name = "rx", 43 .chan_name = "rx",
44 .dma_size = 4, 44 .addr_width = 4,
45}; 45};
46 46
47static struct s3c_i2sv2_info s3c2412_i2s; 47static struct s3c_i2sv2_info s3c2412_i2s;
@@ -52,8 +52,8 @@ static int s3c2412_i2s_probe(struct snd_soc_dai *dai)
52 52
53 pr_debug("Entered %s\n", __func__); 53 pr_debug("Entered %s\n", __func__);
54 54
55 samsung_asoc_init_dma_data(dai, &s3c2412_i2s_pcm_stereo_out, 55 snd_soc_dai_init_dma_data(dai, &s3c2412_i2s_pcm_stereo_out,
56 &s3c2412_i2s_pcm_stereo_in); 56 &s3c2412_i2s_pcm_stereo_in);
57 57
58 ret = s3c_i2sv2_probe(dai, &s3c2412_i2s, S3C2410_PA_IIS); 58 ret = s3c_i2sv2_probe(dai, &s3c2412_i2s, S3C2410_PA_IIS);
59 if (ret) 59 if (ret)
@@ -163,10 +163,10 @@ static int s3c2412_iis_dev_probe(struct platform_device *pdev)
163 if (IS_ERR(s3c2412_i2s.regs)) 163 if (IS_ERR(s3c2412_i2s.regs))
164 return PTR_ERR(s3c2412_i2s.regs); 164 return PTR_ERR(s3c2412_i2s.regs);
165 165
166 s3c2412_i2s_pcm_stereo_out.dma_addr = res->start + S3C2412_IISTXD; 166 s3c2412_i2s_pcm_stereo_out.addr = res->start + S3C2412_IISTXD;
167 s3c2412_i2s_pcm_stereo_out.slave = pdata->dma_playback; 167 s3c2412_i2s_pcm_stereo_out.filter_data = pdata->dma_playback;
168 s3c2412_i2s_pcm_stereo_in.dma_addr = res->start + S3C2412_IISRXD; 168 s3c2412_i2s_pcm_stereo_in.addr = res->start + S3C2412_IISRXD;
169 s3c2412_i2s_pcm_stereo_in.slave = pdata->dma_capture; 169 s3c2412_i2s_pcm_stereo_in.filter_data = pdata->dma_capture;
170 170
171 ret = s3c_i2sv2_register_component(&pdev->dev, -1, 171 ret = s3c_i2sv2_register_component(&pdev->dev, -1,
172 &s3c2412_i2s_component, 172 &s3c2412_i2s_component,
diff --git a/sound/soc/samsung/s3c24xx-i2s.c b/sound/soc/samsung/s3c24xx-i2s.c
index 3e76f2a75a24..c78a936a3099 100644
--- a/sound/soc/samsung/s3c24xx-i2s.c
+++ b/sound/soc/samsung/s3c24xx-i2s.c
@@ -32,14 +32,14 @@
32 32
33#include <linux/platform_data/asoc-s3c.h> 33#include <linux/platform_data/asoc-s3c.h>
34 34
35static struct s3c_dma_params s3c24xx_i2s_pcm_stereo_out = { 35static struct snd_dmaengine_dai_dma_data s3c24xx_i2s_pcm_stereo_out = {
36 .ch_name = "tx", 36 .chan_name = "tx",
37 .dma_size = 2, 37 .addr_width = 2,
38}; 38};
39 39
40static struct s3c_dma_params s3c24xx_i2s_pcm_stereo_in = { 40static struct snd_dmaengine_dai_dma_data s3c24xx_i2s_pcm_stereo_in = {
41 .ch_name = "rx", 41 .chan_name = "rx",
42 .dma_size = 2, 42 .addr_width = 2,
43}; 43};
44 44
45struct s3c24xx_i2s_info { 45struct s3c24xx_i2s_info {
@@ -360,8 +360,8 @@ static int s3c24xx_i2s_probe(struct snd_soc_dai *dai)
360{ 360{
361 pr_debug("Entered %s\n", __func__); 361 pr_debug("Entered %s\n", __func__);
362 362
363 samsung_asoc_init_dma_data(dai, &s3c24xx_i2s_pcm_stereo_out, 363 snd_soc_dai_init_dma_data(dai, &s3c24xx_i2s_pcm_stereo_out,
364 &s3c24xx_i2s_pcm_stereo_in); 364 &s3c24xx_i2s_pcm_stereo_in);
365 365
366 s3c24xx_i2s.iis_clk = devm_clk_get(dai->dev, "iis"); 366 s3c24xx_i2s.iis_clk = devm_clk_get(dai->dev, "iis");
367 if (IS_ERR(s3c24xx_i2s.iis_clk)) { 367 if (IS_ERR(s3c24xx_i2s.iis_clk)) {
@@ -469,10 +469,10 @@ static int s3c24xx_iis_dev_probe(struct platform_device *pdev)
469 if (IS_ERR(s3c24xx_i2s.regs)) 469 if (IS_ERR(s3c24xx_i2s.regs))
470 return PTR_ERR(s3c24xx_i2s.regs); 470 return PTR_ERR(s3c24xx_i2s.regs);
471 471
472 s3c24xx_i2s_pcm_stereo_out.dma_addr = res->start + S3C2410_IISFIFO; 472 s3c24xx_i2s_pcm_stereo_out.addr = res->start + S3C2410_IISFIFO;
473 s3c24xx_i2s_pcm_stereo_out.slave = pdata->dma_playback; 473 s3c24xx_i2s_pcm_stereo_out.filter_data = pdata->dma_playback;
474 s3c24xx_i2s_pcm_stereo_in.dma_addr = res->start + S3C2410_IISFIFO; 474 s3c24xx_i2s_pcm_stereo_in.addr = res->start + S3C2410_IISFIFO;
475 s3c24xx_i2s_pcm_stereo_in.slave = pdata->dma_capture; 475 s3c24xx_i2s_pcm_stereo_in.filter_data = pdata->dma_capture;
476 476
477 ret = devm_snd_soc_register_component(&pdev->dev, 477 ret = devm_snd_soc_register_component(&pdev->dev,
478 &s3c24xx_i2s_component, &s3c24xx_i2s_dai, 1); 478 &s3c24xx_i2s_component, &s3c24xx_i2s_dai, 1);
diff --git a/sound/soc/samsung/s3c24xx_uda134x.c b/sound/soc/samsung/s3c24xx_uda134x.c
index 92e88bca386e..7853fbe6ccc9 100644
--- a/sound/soc/samsung/s3c24xx_uda134x.c
+++ b/sound/soc/samsung/s3c24xx_uda134x.c
@@ -54,8 +54,6 @@ static struct snd_pcm_hw_constraint_list hw_constraints_rates = {
54}; 54};
55#endif 55#endif
56 56
57static struct platform_device *s3c24xx_uda134x_snd_device;
58
59static int s3c24xx_uda134x_startup(struct snd_pcm_substream *substream) 57static int s3c24xx_uda134x_startup(struct snd_pcm_substream *substream)
60{ 58{
61 struct snd_soc_pcm_runtime *rtd = substream->private_data; 59 struct snd_soc_pcm_runtime *rtd = substream->private_data;
@@ -66,17 +64,17 @@ static int s3c24xx_uda134x_startup(struct snd_pcm_substream *substream)
66 int ret = 0; 64 int ret = 0;
67 65
68 mutex_lock(&clk_lock); 66 mutex_lock(&clk_lock);
69 pr_debug("%s %d\n", __func__, clk_users); 67
70 if (clk_users == 0) { 68 if (clk_users == 0) {
71 xtal = clk_get(&s3c24xx_uda134x_snd_device->dev, "xtal"); 69 xtal = clk_get(rtd->dev, "xtal");
72 if (IS_ERR(xtal)) { 70 if (IS_ERR(xtal)) {
73 printk(KERN_ERR "%s cannot get xtal\n", __func__); 71 dev_err(rtd->dev, "%s cannot get xtal\n", __func__);
74 ret = PTR_ERR(xtal); 72 ret = PTR_ERR(xtal);
75 } else { 73 } else {
76 pclk = clk_get(cpu_dai->dev, "iis"); 74 pclk = clk_get(cpu_dai->dev, "iis");
77 if (IS_ERR(pclk)) { 75 if (IS_ERR(pclk)) {
78 printk(KERN_ERR "%s cannot get pclk\n", 76 dev_err(rtd->dev, "%s cannot get pclk\n",
79 __func__); 77 __func__);
80 clk_put(xtal); 78 clk_put(xtal);
81 ret = PTR_ERR(pclk); 79 ret = PTR_ERR(pclk);
82 } 80 }
@@ -102,8 +100,8 @@ static int s3c24xx_uda134x_startup(struct snd_pcm_substream *substream)
102 SNDRV_PCM_HW_PARAM_RATE, 100 SNDRV_PCM_HW_PARAM_RATE,
103 &hw_constraints_rates); 101 &hw_constraints_rates);
104 if (ret < 0) 102 if (ret < 0)
105 printk(KERN_ERR "%s cannot set constraints\n", 103 dev_err(rtd->dev, "%s cannot set constraints\n",
106 __func__); 104 __func__);
107#endif 105#endif
108 } 106 }
109 return ret; 107 return ret;
@@ -112,7 +110,6 @@ static int s3c24xx_uda134x_startup(struct snd_pcm_substream *substream)
112static void s3c24xx_uda134x_shutdown(struct snd_pcm_substream *substream) 110static void s3c24xx_uda134x_shutdown(struct snd_pcm_substream *substream)
113{ 111{
114 mutex_lock(&clk_lock); 112 mutex_lock(&clk_lock);
115 pr_debug("%s %d\n", __func__, clk_users);
116 clk_users -= 1; 113 clk_users -= 1;
117 if (clk_users == 0) { 114 if (clk_users == 0) {
118 clk_put(xtal); 115 clk_put(xtal);
@@ -159,18 +156,19 @@ static int s3c24xx_uda134x_hw_params(struct snd_pcm_substream *substream,
159 clk_source = S3C24XX_CLKSRC_PCLK; 156 clk_source = S3C24XX_CLKSRC_PCLK;
160 div = bi % 33; 157 div = bi % 33;
161 } 158 }
162 pr_debug("%s desired rate %lu, %d\n", __func__, rate, bi); 159
160 dev_dbg(rtd->dev, "%s desired rate %lu, %d\n", __func__, rate, bi);
163 161
164 clk = (fs_mode == S3C2410_IISMOD_384FS ? 384 : 256) * rate; 162 clk = (fs_mode == S3C2410_IISMOD_384FS ? 384 : 256) * rate;
165 pr_debug("%s will use: %s %s %d sysclk %d err %ld\n", __func__, 163
166 fs_mode == S3C2410_IISMOD_384FS ? "384FS" : "256FS", 164 dev_dbg(rtd->dev, "%s will use: %s %s %d sysclk %d err %ld\n", __func__,
167 clk_source == S3C24XX_CLKSRC_MPLL ? "MPLLin" : "PCLK", 165 fs_mode == S3C2410_IISMOD_384FS ? "384FS" : "256FS",
168 div, clk, err); 166 clk_source == S3C24XX_CLKSRC_MPLL ? "MPLLin" : "PCLK",
167 div, clk, err);
169 168
170 if ((err * 100 / rate) > 5) { 169 if ((err * 100 / rate) > 5) {
171 printk(KERN_ERR "S3C24XX_UDA134X: effective frequency " 170 dev_err(rtd->dev, "effective frequency too different "
172 "too different from desired (%ld%%)\n", 171 "from desired (%ld%%)\n", err * 100 / rate);
173 err * 100 / rate);
174 return -EINVAL; 172 return -EINVAL;
175 } 173 }
176 174
@@ -227,115 +225,27 @@ static struct snd_soc_card snd_soc_s3c24xx_uda134x = {
227 .num_links = 1, 225 .num_links = 1,
228}; 226};
229 227
230static struct s3c24xx_uda134x_platform_data *s3c24xx_uda134x_l3_pins;
231
232static void setdat(int v)
233{
234 gpio_set_value(s3c24xx_uda134x_l3_pins->l3_data, v > 0);
235}
236
237static void setclk(int v)
238{
239 gpio_set_value(s3c24xx_uda134x_l3_pins->l3_clk, v > 0);
240}
241
242static void setmode(int v)
243{
244 gpio_set_value(s3c24xx_uda134x_l3_pins->l3_mode, v > 0);
245}
246
247/* FIXME - This must be codec platform data but in which board file ?? */
248static struct uda134x_platform_data s3c24xx_uda134x = {
249 .l3 = {
250 .setdat = setdat,
251 .setclk = setclk,
252 .setmode = setmode,
253 .data_hold = 1,
254 .data_setup = 1,
255 .clock_high = 1,
256 .mode_hold = 1,
257 .mode = 1,
258 .mode_setup = 1,
259 },
260};
261
262static int s3c24xx_uda134x_setup_pin(int pin, char *fun)
263{
264 if (gpio_request(pin, "s3c24xx_uda134x") < 0) {
265 printk(KERN_ERR "S3C24XX_UDA134X SoC Audio: "
266 "l3 %s pin already in use", fun);
267 return -EBUSY;
268 }
269 gpio_direction_output(pin, 0);
270 return 0;
271}
272
273static int s3c24xx_uda134x_probe(struct platform_device *pdev) 228static int s3c24xx_uda134x_probe(struct platform_device *pdev)
274{ 229{
230 struct snd_soc_card *card = &snd_soc_s3c24xx_uda134x;
275 int ret; 231 int ret;
276 232
277 printk(KERN_INFO "S3C24XX_UDA134X SoC Audio driver\n"); 233 platform_set_drvdata(pdev, card);
234 card->dev = &pdev->dev;
278 235
279 s3c24xx_uda134x_l3_pins = pdev->dev.platform_data; 236 ret = devm_snd_soc_register_card(&pdev->dev, card);
280 if (s3c24xx_uda134x_l3_pins == NULL) { 237 if (ret)
281 printk(KERN_ERR "S3C24XX_UDA134X SoC Audio: " 238 dev_err(&pdev->dev, "failed to register card: %d\n", ret);
282 "unable to find platform data\n");
283 return -ENODEV;
284 }
285 s3c24xx_uda134x.power = s3c24xx_uda134x_l3_pins->power;
286 s3c24xx_uda134x.model = s3c24xx_uda134x_l3_pins->model;
287
288 if (s3c24xx_uda134x_setup_pin(s3c24xx_uda134x_l3_pins->l3_data,
289 "data") < 0)
290 return -EBUSY;
291 if (s3c24xx_uda134x_setup_pin(s3c24xx_uda134x_l3_pins->l3_clk,
292 "clk") < 0) {
293 gpio_free(s3c24xx_uda134x_l3_pins->l3_data);
294 return -EBUSY;
295 }
296 if (s3c24xx_uda134x_setup_pin(s3c24xx_uda134x_l3_pins->l3_mode,
297 "mode") < 0) {
298 gpio_free(s3c24xx_uda134x_l3_pins->l3_data);
299 gpio_free(s3c24xx_uda134x_l3_pins->l3_clk);
300 return -EBUSY;
301 }
302
303 s3c24xx_uda134x_snd_device = platform_device_alloc("soc-audio", -1);
304 if (!s3c24xx_uda134x_snd_device) {
305 printk(KERN_ERR "S3C24XX_UDA134X SoC Audio: "
306 "Unable to register\n");
307 return -ENOMEM;
308 }
309
310 platform_set_drvdata(s3c24xx_uda134x_snd_device,
311 &snd_soc_s3c24xx_uda134x);
312 platform_device_add_data(s3c24xx_uda134x_snd_device, &s3c24xx_uda134x, sizeof(s3c24xx_uda134x));
313 ret = platform_device_add(s3c24xx_uda134x_snd_device);
314 if (ret) {
315 printk(KERN_ERR "S3C24XX_UDA134X SoC Audio: Unable to add\n");
316 platform_device_put(s3c24xx_uda134x_snd_device);
317 }
318 239
319 return ret; 240 return ret;
320} 241}
321 242
322static int s3c24xx_uda134x_remove(struct platform_device *pdev)
323{
324 platform_device_unregister(s3c24xx_uda134x_snd_device);
325 gpio_free(s3c24xx_uda134x_l3_pins->l3_data);
326 gpio_free(s3c24xx_uda134x_l3_pins->l3_clk);
327 gpio_free(s3c24xx_uda134x_l3_pins->l3_mode);
328 return 0;
329}
330
331static struct platform_driver s3c24xx_uda134x_driver = { 243static struct platform_driver s3c24xx_uda134x_driver = {
332 .probe = s3c24xx_uda134x_probe, 244 .probe = s3c24xx_uda134x_probe,
333 .remove = s3c24xx_uda134x_remove,
334 .driver = { 245 .driver = {
335 .name = "s3c24xx_uda134x", 246 .name = "s3c24xx_uda134x",
336 }, 247 },
337}; 248};
338
339module_platform_driver(s3c24xx_uda134x_driver); 249module_platform_driver(s3c24xx_uda134x_driver);
340 250
341MODULE_AUTHOR("Zoltan Devai, Christian Pellegrin <chripell@evolware.org>"); 251MODULE_AUTHOR("Zoltan Devai, Christian Pellegrin <chripell@evolware.org>");
diff --git a/sound/soc/samsung/smdk_wm8580pcm.c b/sound/soc/samsung/smdk_wm8580pcm.c
index 6deec5234c92..a6d223310c67 100644
--- a/sound/soc/samsung/smdk_wm8580pcm.c
+++ b/sound/soc/samsung/smdk_wm8580pcm.c
@@ -16,7 +16,6 @@
16#include <asm/mach-types.h> 16#include <asm/mach-types.h>
17 17
18#include "../codecs/wm8580.h" 18#include "../codecs/wm8580.h"
19#include "dma.h"
20#include "pcm.h" 19#include "pcm.h"
21 20
22/* 21/*
diff --git a/sound/soc/samsung/smdk_wm8994pcm.c b/sound/soc/samsung/smdk_wm8994pcm.c
index b1c89ec2d999..2e621496be8b 100644
--- a/sound/soc/samsung/smdk_wm8994pcm.c
+++ b/sound/soc/samsung/smdk_wm8994pcm.c
@@ -15,7 +15,6 @@
15#include <sound/pcm_params.h> 15#include <sound/pcm_params.h>
16 16
17#include "../codecs/wm8994.h" 17#include "../codecs/wm8994.h"
18#include "dma.h"
19#include "pcm.h" 18#include "pcm.h"
20 19
21/* 20/*
diff --git a/sound/soc/samsung/spdif.c b/sound/soc/samsung/spdif.c
index 0cb9c8567546..26c1fbed4d35 100644
--- a/sound/soc/samsung/spdif.c
+++ b/sound/soc/samsung/spdif.c
@@ -90,10 +90,10 @@ struct samsung_spdif_info {
90 u32 saved_clkcon; 90 u32 saved_clkcon;
91 u32 saved_con; 91 u32 saved_con;
92 u32 saved_cstas; 92 u32 saved_cstas;
93 struct s3c_dma_params *dma_playback; 93 struct snd_dmaengine_dai_dma_data *dma_playback;
94}; 94};
95 95
96static struct s3c_dma_params spdif_stereo_out; 96static struct snd_dmaengine_dai_dma_data spdif_stereo_out;
97static struct samsung_spdif_info spdif_info; 97static struct samsung_spdif_info spdif_info;
98 98
99static inline struct samsung_spdif_info *to_info(struct snd_soc_dai *cpu_dai) 99static inline struct samsung_spdif_info *to_info(struct snd_soc_dai *cpu_dai)
@@ -179,7 +179,7 @@ static int spdif_hw_params(struct snd_pcm_substream *substream,
179 struct snd_soc_pcm_runtime *rtd = substream->private_data; 179 struct snd_soc_pcm_runtime *rtd = substream->private_data;
180 struct samsung_spdif_info *spdif = to_info(rtd->cpu_dai); 180 struct samsung_spdif_info *spdif = to_info(rtd->cpu_dai);
181 void __iomem *regs = spdif->regs; 181 void __iomem *regs = spdif->regs;
182 struct s3c_dma_params *dma_data; 182 struct snd_dmaengine_dai_dma_data *dma_data;
183 u32 con, clkcon, cstas; 183 u32 con, clkcon, cstas;
184 unsigned long flags; 184 unsigned long flags;
185 int i, ratio; 185 int i, ratio;
@@ -425,11 +425,11 @@ static int spdif_probe(struct platform_device *pdev)
425 goto err4; 425 goto err4;
426 } 426 }
427 427
428 spdif_stereo_out.dma_size = 2; 428 spdif_stereo_out.addr_width = 2;
429 spdif_stereo_out.dma_addr = mem_res->start + DATA_OUTBUF; 429 spdif_stereo_out.addr = mem_res->start + DATA_OUTBUF;
430 filter = NULL; 430 filter = NULL;
431 if (spdif_pdata) { 431 if (spdif_pdata) {
432 spdif_stereo_out.slave = spdif_pdata->dma_playback; 432 spdif_stereo_out.filter_data = spdif_pdata->dma_playback;
433 filter = spdif_pdata->dma_filter; 433 filter = spdif_pdata->dma_filter;
434 } 434 }
435 435
diff --git a/sound/soc/sh/Kconfig b/sound/soc/sh/Kconfig
index 9311f119feb5..6db6405d952f 100644
--- a/sound/soc/sh/Kconfig
+++ b/sound/soc/sh/Kconfig
@@ -42,12 +42,6 @@ config SND_SOC_RCAR
42 help 42 help
43 This option enables R-Car SRU/SCU/SSIU/SSI sound support 43 This option enables R-Car SRU/SCU/SSIU/SSI sound support
44 44
45config SND_SOC_RSRC_CARD
46 tristate "Renesas Sampling Rate Convert Sound Card"
47 select SND_SIMPLE_CARD_UTILS
48 help
49 This option enables simple sound if you need sampling rate convert
50
51## 45##
52## Boards 46## Boards
53## 47##
diff --git a/sound/soc/sh/rcar/Makefile b/sound/soc/sh/rcar/Makefile
index a89ddf758695..9c3d5aed99d1 100644
--- a/sound/soc/sh/rcar/Makefile
+++ b/sound/soc/sh/rcar/Makefile
@@ -1,5 +1,2 @@
1snd-soc-rcar-objs := core.o gen.o dma.o adg.o ssi.o ssiu.o src.o ctu.o mix.o dvc.o cmd.o 1snd-soc-rcar-objs := core.o gen.o dma.o adg.o ssi.o ssiu.o src.o ctu.o mix.o dvc.o cmd.o
2obj-$(CONFIG_SND_SOC_RCAR) += snd-soc-rcar.o 2obj-$(CONFIG_SND_SOC_RCAR) += snd-soc-rcar.o
3
4snd-soc-rsrc-card-objs := rsrc-card.o
5obj-$(CONFIG_SND_SOC_RSRC_CARD) += snd-soc-rsrc-card.o
diff --git a/sound/soc/sh/rcar/core.c b/sound/soc/sh/rcar/core.c
index 3351a701c60e..f18141098b50 100644
--- a/sound/soc/sh/rcar/core.c
+++ b/sound/soc/sh/rcar/core.c
@@ -110,6 +110,7 @@ MODULE_DEVICE_TABLE(of, rsnd_of_match);
110/* 110/*
111 * rsnd_mod functions 111 * rsnd_mod functions
112 */ 112 */
113#ifdef DEBUG
113void rsnd_mod_make_sure(struct rsnd_mod *mod, enum rsnd_mod_type type) 114void rsnd_mod_make_sure(struct rsnd_mod *mod, enum rsnd_mod_type type)
114{ 115{
115 if (mod->type != type) { 116 if (mod->type != type) {
@@ -120,6 +121,7 @@ void rsnd_mod_make_sure(struct rsnd_mod *mod, enum rsnd_mod_type type)
120 rsnd_mod_name(mod), rsnd_mod_id(mod)); 121 rsnd_mod_name(mod), rsnd_mod_id(mod));
121 } 122 }
122} 123}
124#endif
123 125
124char *rsnd_mod_name(struct rsnd_mod *mod) 126char *rsnd_mod_name(struct rsnd_mod *mod)
125{ 127{
@@ -574,6 +576,7 @@ static int rsnd_soc_dai_trigger(struct snd_pcm_substream *substream, int cmd,
574 576
575 switch (cmd) { 577 switch (cmd) {
576 case SNDRV_PCM_TRIGGER_START: 578 case SNDRV_PCM_TRIGGER_START:
579 case SNDRV_PCM_TRIGGER_RESUME:
577 rsnd_dai_stream_init(io, substream); 580 rsnd_dai_stream_init(io, substream);
578 581
579 ret = rsnd_dai_call(init, io, priv); 582 ret = rsnd_dai_call(init, io, priv);
@@ -590,6 +593,7 @@ static int rsnd_soc_dai_trigger(struct snd_pcm_substream *substream, int cmd,
590 593
591 break; 594 break;
592 case SNDRV_PCM_TRIGGER_STOP: 595 case SNDRV_PCM_TRIGGER_STOP:
596 case SNDRV_PCM_TRIGGER_SUSPEND:
593 ret = rsnd_dai_call(irq, io, priv, 0); 597 ret = rsnd_dai_call(irq, io, priv, 0);
594 598
595 ret |= rsnd_dai_call(stop, io, priv); 599 ret |= rsnd_dai_call(stop, io, priv);
diff --git a/sound/soc/sh/rcar/rsrc-card.c b/sound/soc/sh/rcar/rsrc-card.c
deleted file mode 100644
index fa37f842b62f..000000000000
--- a/sound/soc/sh/rcar/rsrc-card.c
+++ /dev/null
@@ -1,486 +0,0 @@
1/*
2 * Renesas Sampling Rate Convert Sound Card for DPCM
3 *
4 * Copyright (C) 2015 Renesas Solutions Corp.
5 * Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
6 *
7 * based on ${LINUX}/sound/soc/generic/simple-card.c
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 version 2 as
11 * published by the Free Software Foundation.
12 */
13#include <linux/clk.h>
14#include <linux/device.h>
15#include <linux/module.h>
16#include <linux/of.h>
17#include <linux/of_device.h>
18#include <linux/platform_device.h>
19#include <linux/string.h>
20#include <sound/jack.h>
21#include <sound/soc.h>
22#include <sound/soc-dai.h>
23#include <sound/simple_card_utils.h>
24
25struct rsrc_card_of_data {
26 const char *prefix;
27 const struct snd_soc_dapm_route *routes;
28 int num_routes;
29};
30
31static const struct snd_soc_dapm_route routes_ssi0_ak4642[] = {
32 {"ak4642 Playback", NULL, "DAI0 Playback"},
33 {"DAI0 Capture", NULL, "ak4642 Capture"},
34};
35
36static const struct rsrc_card_of_data routes_of_ssi0_ak4642 = {
37 .prefix = "ak4642",
38 .routes = routes_ssi0_ak4642,
39 .num_routes = ARRAY_SIZE(routes_ssi0_ak4642),
40};
41
42static const struct of_device_id rsrc_card_of_match[] = {
43 { .compatible = "renesas,rsrc-card,lager", .data = &routes_of_ssi0_ak4642 },
44 { .compatible = "renesas,rsrc-card,koelsch", .data = &routes_of_ssi0_ak4642 },
45 { .compatible = "renesas,rsrc-card", },
46 {},
47};
48MODULE_DEVICE_TABLE(of, rsrc_card_of_match);
49
50#define IDX_CPU 0
51#define IDX_CODEC 1
52struct rsrc_card_priv {
53 struct snd_soc_card snd_card;
54 struct snd_soc_codec_conf codec_conf;
55 struct asoc_simple_dai *dai_props;
56 struct snd_soc_dai_link *dai_link;
57 u32 convert_rate;
58 u32 convert_channels;
59};
60
61#define rsrc_priv_to_dev(priv) ((priv)->snd_card.dev)
62#define rsrc_priv_to_link(priv, i) ((priv)->snd_card.dai_link + (i))
63#define rsrc_priv_to_props(priv, i) ((priv)->dai_props + (i))
64
65static int rsrc_card_startup(struct snd_pcm_substream *substream)
66{
67 struct snd_soc_pcm_runtime *rtd = substream->private_data;
68 struct rsrc_card_priv *priv = snd_soc_card_get_drvdata(rtd->card);
69 struct asoc_simple_dai *dai_props =
70 rsrc_priv_to_props(priv, rtd->num);
71
72 return clk_prepare_enable(dai_props->clk);
73}
74
75static void rsrc_card_shutdown(struct snd_pcm_substream *substream)
76{
77 struct snd_soc_pcm_runtime *rtd = substream->private_data;
78 struct rsrc_card_priv *priv = snd_soc_card_get_drvdata(rtd->card);
79 struct asoc_simple_dai *dai_props =
80 rsrc_priv_to_props(priv, rtd->num);
81
82 clk_disable_unprepare(dai_props->clk);
83}
84
85static struct snd_soc_ops rsrc_card_ops = {
86 .startup = rsrc_card_startup,
87 .shutdown = rsrc_card_shutdown,
88};
89
90static int rsrc_card_dai_init(struct snd_soc_pcm_runtime *rtd)
91{
92 struct rsrc_card_priv *priv = snd_soc_card_get_drvdata(rtd->card);
93 struct snd_soc_dai *dai;
94 struct snd_soc_dai_link *dai_link;
95 struct asoc_simple_dai *dai_props;
96 int num = rtd->num;
97 int ret;
98
99 dai_link = rsrc_priv_to_link(priv, num);
100 dai_props = rsrc_priv_to_props(priv, num);
101 dai = dai_link->dynamic ?
102 rtd->cpu_dai :
103 rtd->codec_dai;
104
105 if (dai_props->sysclk) {
106 ret = snd_soc_dai_set_sysclk(dai, 0, dai_props->sysclk, 0);
107 if (ret && ret != -ENOTSUPP) {
108 dev_err(dai->dev, "set_sysclk error\n");
109 goto err;
110 }
111 }
112
113 if (dai_props->slots) {
114 ret = snd_soc_dai_set_tdm_slot(dai,
115 dai_props->tx_slot_mask,
116 dai_props->rx_slot_mask,
117 dai_props->slots,
118 dai_props->slot_width);
119 if (ret && ret != -ENOTSUPP) {
120 dev_err(dai->dev, "set_tdm_slot error\n");
121 goto err;
122 }
123 }
124
125 ret = 0;
126
127err:
128 return ret;
129}
130
131static int rsrc_card_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
132 struct snd_pcm_hw_params *params)
133{
134 struct rsrc_card_priv *priv = snd_soc_card_get_drvdata(rtd->card);
135 struct snd_interval *rate = hw_param_interval(params,
136 SNDRV_PCM_HW_PARAM_RATE);
137 struct snd_interval *channels = hw_param_interval(params,
138 SNDRV_PCM_HW_PARAM_CHANNELS);
139
140 if (priv->convert_rate)
141 rate->min =
142 rate->max = priv->convert_rate;
143
144 if (priv->convert_channels)
145 channels->min =
146 channels->max = priv->convert_channels;
147
148 return 0;
149}
150
151static int rsrc_card_parse_links(struct device_node *np,
152 struct rsrc_card_priv *priv,
153 int idx, bool is_fe)
154{
155 struct device *dev = rsrc_priv_to_dev(priv);
156 struct snd_soc_dai_link *dai_link = rsrc_priv_to_link(priv, idx);
157 struct asoc_simple_dai *dai_props = rsrc_priv_to_props(priv, idx);
158 struct of_phandle_args args;
159 int ret;
160
161 /*
162 * Get node via "sound-dai = <&phandle port>"
163 * it will be used as xxx_of_node on soc_bind_dai_link()
164 */
165 ret = of_parse_phandle_with_args(np, "sound-dai",
166 "#sound-dai-cells", 0, &args);
167 if (ret)
168 return ret;
169
170 /* Parse TDM slot */
171 ret = snd_soc_of_parse_tdm_slot(np,
172 &dai_props->tx_slot_mask,
173 &dai_props->rx_slot_mask,
174 &dai_props->slots,
175 &dai_props->slot_width);
176 if (ret)
177 return ret;
178
179 if (is_fe) {
180 /* BE is dummy */
181 dai_link->codec_of_node = NULL;
182 dai_link->codec_dai_name = "snd-soc-dummy-dai";
183 dai_link->codec_name = "snd-soc-dummy";
184
185 /* FE settings */
186 dai_link->dynamic = 1;
187 dai_link->dpcm_merged_format = 1;
188 dai_link->cpu_of_node = args.np;
189 ret = snd_soc_of_get_dai_name(np, &dai_link->cpu_dai_name);
190 if (ret < 0)
191 return ret;
192
193 ret = asoc_simple_card_set_dailink_name(dev, dai_link,
194 "fe.%s",
195 dai_link->cpu_dai_name);
196 if (ret < 0)
197 return ret;
198
199 /*
200 * In soc_bind_dai_link() will check cpu name after
201 * of_node matching if dai_link has cpu_dai_name.
202 * but, it will never match if name was created by
203 * fmt_single_name() remove cpu_dai_name if cpu_args
204 * was 0. See:
205 * fmt_single_name()
206 * fmt_multiple_name()
207 */
208 if (!args.args_count)
209 dai_link->cpu_dai_name = NULL;
210 } else {
211 const struct rsrc_card_of_data *of_data;
212
213 of_data = of_device_get_match_data(dev);
214
215 /* FE is dummy */
216 dai_link->cpu_of_node = NULL;
217 dai_link->cpu_dai_name = "snd-soc-dummy-dai";
218 dai_link->cpu_name = "snd-soc-dummy";
219
220 /* BE settings */
221 dai_link->no_pcm = 1;
222 dai_link->be_hw_params_fixup = rsrc_card_be_hw_params_fixup;
223 dai_link->codec_of_node = args.np;
224 ret = snd_soc_of_get_dai_name(np, &dai_link->codec_dai_name);
225 if (ret < 0)
226 return ret;
227
228 ret = asoc_simple_card_set_dailink_name(dev, dai_link,
229 "be.%s",
230 dai_link->codec_dai_name);
231 if (ret < 0)
232 return ret;
233
234 /* additional name prefix */
235 if (of_data) {
236 priv->codec_conf.of_node = dai_link->codec_of_node;
237 priv->codec_conf.name_prefix = of_data->prefix;
238 } else {
239 snd_soc_of_parse_audio_prefix(&priv->snd_card,
240 &priv->codec_conf,
241 dai_link->codec_of_node,
242 "audio-prefix");
243 }
244 }
245
246 /* Simple Card assumes platform == cpu */
247 dai_link->platform_of_node = dai_link->cpu_of_node;
248 dai_link->dpcm_playback = 1;
249 dai_link->dpcm_capture = 1;
250 dai_link->ops = &rsrc_card_ops;
251 dai_link->init = rsrc_card_dai_init;
252
253 return 0;
254}
255
256static int rsrc_card_parse_clk(struct device_node *np,
257 struct rsrc_card_priv *priv,
258 int idx, bool is_fe)
259{
260 struct snd_soc_dai_link *dai_link = rsrc_priv_to_link(priv, idx);
261 struct asoc_simple_dai *dai_props = rsrc_priv_to_props(priv, idx);
262 struct clk *clk;
263 struct device_node *of_np = is_fe ? dai_link->cpu_of_node :
264 dai_link->codec_of_node;
265 u32 val;
266
267 /*
268 * Parse dai->sysclk come from "clocks = <&xxx>"
269 * (if system has common clock)
270 * or "system-clock-frequency = <xxx>"
271 * or device's module clock.
272 */
273 if (of_property_read_bool(np, "clocks")) {
274 clk = of_clk_get(np, 0);
275 if (IS_ERR(clk))
276 return PTR_ERR(clk);
277
278 dai_props->sysclk = clk_get_rate(clk);
279 dai_props->clk = clk;
280 } else if (!of_property_read_u32(np, "system-clock-frequency", &val)) {
281 dai_props->sysclk = val;
282 } else {
283 clk = of_clk_get(of_np, 0);
284 if (!IS_ERR(clk))
285 dai_props->sysclk = clk_get_rate(clk);
286 }
287
288 return 0;
289}
290
291static int rsrc_card_dai_sub_link_of(struct device_node *node,
292 struct device_node *np,
293 struct rsrc_card_priv *priv,
294 int idx, bool is_fe)
295{
296 struct device *dev = rsrc_priv_to_dev(priv);
297 struct snd_soc_dai_link *dai_link = rsrc_priv_to_link(priv, idx);
298 struct asoc_simple_dai *dai_props = rsrc_priv_to_props(priv, idx);
299 int ret;
300
301 ret = rsrc_card_parse_links(np, priv, idx, is_fe);
302 if (ret < 0)
303 return ret;
304
305 ret = rsrc_card_parse_clk(np, priv, idx, is_fe);
306 if (ret < 0)
307 return ret;
308
309 dev_dbg(dev, "\t%s / %04x / %d\n",
310 dai_link->name,
311 dai_link->dai_fmt,
312 dai_props->sysclk);
313
314 return ret;
315}
316
317static int rsrc_card_dai_link_of(struct device_node *node,
318 struct rsrc_card_priv *priv)
319{
320 struct device *dev = rsrc_priv_to_dev(priv);
321 struct snd_soc_dai_link *dai_link;
322 struct device_node *np;
323 unsigned int daifmt = 0;
324 int ret, i;
325 bool is_fe;
326
327 /* find 1st codec */
328 i = 0;
329 for_each_child_of_node(node, np) {
330 dai_link = rsrc_priv_to_link(priv, i);
331
332 if (strcmp(np->name, "codec") == 0) {
333 ret = asoc_simple_card_parse_daifmt(dev, node, np,
334 NULL, &daifmt);
335 if (ret < 0)
336 return ret;
337 break;
338 }
339 i++;
340 }
341
342 i = 0;
343 for_each_child_of_node(node, np) {
344 dai_link = rsrc_priv_to_link(priv, i);
345 dai_link->dai_fmt = daifmt;
346
347 is_fe = false;
348 if (strcmp(np->name, "cpu") == 0)
349 is_fe = true;
350
351 ret = rsrc_card_dai_sub_link_of(node, np, priv, i, is_fe);
352 if (ret < 0)
353 return ret;
354 i++;
355 }
356
357 return 0;
358}
359
360static int rsrc_card_parse_of(struct device_node *node,
361 struct rsrc_card_priv *priv,
362 struct device *dev)
363{
364 const struct rsrc_card_of_data *of_data = of_device_get_match_data(dev);
365 struct asoc_simple_dai *props;
366 struct snd_soc_dai_link *links;
367 int ret;
368 int num;
369
370 if (!node)
371 return -EINVAL;
372
373 num = of_get_child_count(node);
374 props = devm_kzalloc(dev, sizeof(*props) * num, GFP_KERNEL);
375 links = devm_kzalloc(dev, sizeof(*links) * num, GFP_KERNEL);
376 if (!props || !links)
377 return -ENOMEM;
378
379 priv->dai_props = props;
380 priv->dai_link = links;
381
382 /* Init snd_soc_card */
383 priv->snd_card.owner = THIS_MODULE;
384 priv->snd_card.dev = dev;
385 priv->snd_card.dai_link = priv->dai_link;
386 priv->snd_card.num_links = num;
387 priv->snd_card.codec_conf = &priv->codec_conf;
388 priv->snd_card.num_configs = 1;
389
390 if (of_data) {
391 priv->snd_card.of_dapm_routes = of_data->routes;
392 priv->snd_card.num_of_dapm_routes = of_data->num_routes;
393 } else {
394 snd_soc_of_parse_audio_routing(&priv->snd_card,
395 "audio-routing");
396 }
397
398 /* sampling rate convert */
399 of_property_read_u32(node, "convert-rate", &priv->convert_rate);
400
401 /* channels transfer */
402 of_property_read_u32(node, "convert-channels", &priv->convert_channels);
403
404 dev_dbg(dev, "New rsrc-audio-card: %s\n",
405 priv->snd_card.name ? priv->snd_card.name : "");
406 dev_dbg(dev, "SRC : convert_rate %d\n", priv->convert_rate);
407 dev_dbg(dev, "CTU : convert_channels %d\n", priv->convert_channels);
408
409 ret = rsrc_card_dai_link_of(node, priv);
410 if (ret < 0)
411 return ret;
412
413 ret = asoc_simple_card_parse_card_name(&priv->snd_card, "card-");
414 if (ret < 0)
415 return ret;
416
417 return 0;
418}
419
420/* Decrease the reference count of the device nodes */
421static int rsrc_card_unref(struct snd_soc_card *card)
422{
423 struct snd_soc_dai_link *dai_link;
424 int num_links;
425
426 for (num_links = 0, dai_link = card->dai_link;
427 num_links < card->num_links;
428 num_links++, dai_link++) {
429 of_node_put(dai_link->cpu_of_node);
430 of_node_put(dai_link->codec_of_node);
431 }
432 return 0;
433}
434
435static int rsrc_card_probe(struct platform_device *pdev)
436{
437 struct rsrc_card_priv *priv;
438 struct device_node *np = pdev->dev.of_node;
439 struct device *dev = &pdev->dev;
440 int ret;
441
442 /* Allocate the private data */
443 priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
444 if (!priv)
445 return -ENOMEM;
446
447 ret = rsrc_card_parse_of(np, priv, dev);
448 if (ret < 0) {
449 if (ret != -EPROBE_DEFER)
450 dev_err(dev, "parse error %d\n", ret);
451 goto err;
452 }
453
454 snd_soc_card_set_drvdata(&priv->snd_card, priv);
455
456 ret = devm_snd_soc_register_card(&pdev->dev, &priv->snd_card);
457 if (ret >= 0)
458 return ret;
459err:
460 rsrc_card_unref(&priv->snd_card);
461
462 return ret;
463}
464
465static int rsrc_card_remove(struct platform_device *pdev)
466{
467 struct snd_soc_card *card = platform_get_drvdata(pdev);
468
469 return rsrc_card_unref(card);
470}
471
472static struct platform_driver rsrc_card = {
473 .driver = {
474 .name = "renesas-src-audio-card",
475 .of_match_table = rsrc_card_of_match,
476 },
477 .probe = rsrc_card_probe,
478 .remove = rsrc_card_remove,
479};
480
481module_platform_driver(rsrc_card);
482
483MODULE_ALIAS("platform:renesas-src-audio-card");
484MODULE_LICENSE("GPL");
485MODULE_DESCRIPTION("Renesas Sampling Rate Convert Sound Card");
486MODULE_AUTHOR("Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>");
diff --git a/sound/soc/sh/rcar/ssi.c b/sound/soc/sh/rcar/ssi.c
index 5f848f054745..6cb6db005fc4 100644
--- a/sound/soc/sh/rcar/ssi.c
+++ b/sound/soc/sh/rcar/ssi.c
@@ -928,7 +928,7 @@ int rsnd_ssi_probe(struct rsnd_priv *priv)
928 } 928 }
929 929
930 ops = &rsnd_ssi_non_ops; 930 ops = &rsnd_ssi_non_ops;
931 if (of_get_property(np, "pio-transfer", NULL)) 931 if (of_property_read_bool(np, "pio-transfer"))
932 ops = &rsnd_ssi_pio_ops; 932 ops = &rsnd_ssi_pio_ops;
933 else 933 else
934 ops = &rsnd_ssi_dma_ops; 934 ops = &rsnd_ssi_dma_ops;
diff --git a/sound/soc/soc-ac97.c b/sound/soc/soc-ac97.c
index bc4a55bb3fd9..6c8b0b0c56ec 100644
--- a/sound/soc/soc-ac97.c
+++ b/sound/soc/soc-ac97.c
@@ -116,7 +116,7 @@ static int snd_soc_ac97_gpio_direction_out(struct gpio_chip *chip,
116 return snd_soc_update_bits(codec, AC97_GPIO_CFG, 1 << offset, 0); 116 return snd_soc_update_bits(codec, AC97_GPIO_CFG, 1 << offset, 0);
117} 117}
118 118
119static struct gpio_chip snd_soc_ac97_gpio_chip = { 119static const struct gpio_chip snd_soc_ac97_gpio_chip = {
120 .label = "snd_soc_ac97", 120 .label = "snd_soc_ac97",
121 .owner = THIS_MODULE, 121 .owner = THIS_MODULE,
122 .request = snd_soc_ac97_gpio_request, 122 .request = snd_soc_ac97_gpio_request,
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index 4afa8dba5e98..c0bbcd903261 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -3332,19 +3332,6 @@ int snd_soc_register_codec(struct device *dev,
3332 if (ret) 3332 if (ret)
3333 goto err_free; 3333 goto err_free;
3334 3334
3335 if (codec_drv->controls) {
3336 codec->component.controls = codec_drv->controls;
3337 codec->component.num_controls = codec_drv->num_controls;
3338 }
3339 if (codec_drv->dapm_widgets) {
3340 codec->component.dapm_widgets = codec_drv->dapm_widgets;
3341 codec->component.num_dapm_widgets = codec_drv->num_dapm_widgets;
3342 }
3343 if (codec_drv->dapm_routes) {
3344 codec->component.dapm_routes = codec_drv->dapm_routes;
3345 codec->component.num_dapm_routes = codec_drv->num_dapm_routes;
3346 }
3347
3348 if (codec_drv->probe) 3335 if (codec_drv->probe)
3349 codec->component.probe = snd_soc_codec_drv_probe; 3336 codec->component.probe = snd_soc_codec_drv_probe;
3350 if (codec_drv->remove) 3337 if (codec_drv->remove)
@@ -3732,7 +3719,7 @@ unsigned int snd_soc_of_parse_daifmt(struct device_node *np,
3732 * SND_SOC_DAIFMT_CLOCK_MASK area 3719 * SND_SOC_DAIFMT_CLOCK_MASK area
3733 */ 3720 */
3734 snprintf(prop, sizeof(prop), "%scontinuous-clock", prefix); 3721 snprintf(prop, sizeof(prop), "%scontinuous-clock", prefix);
3735 if (of_get_property(np, prop, NULL)) 3722 if (of_property_read_bool(np, prop))
3736 format |= SND_SOC_DAIFMT_CONT; 3723 format |= SND_SOC_DAIFMT_CONT;
3737 else 3724 else
3738 format |= SND_SOC_DAIFMT_GATED; 3725 format |= SND_SOC_DAIFMT_GATED;
diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c
index d908ff8f9755..3bbe32ee4630 100644
--- a/sound/soc/soc-dapm.c
+++ b/sound/soc/soc-dapm.c
@@ -823,6 +823,7 @@ static int dapm_create_or_share_kcontrol(struct snd_soc_dapm_widget *w,
823 case snd_soc_dapm_switch: 823 case snd_soc_dapm_switch:
824 case snd_soc_dapm_mixer: 824 case snd_soc_dapm_mixer:
825 case snd_soc_dapm_pga: 825 case snd_soc_dapm_pga:
826 case snd_soc_dapm_out_drv:
826 wname_in_long_name = true; 827 wname_in_long_name = true;
827 kcname_in_long_name = true; 828 kcname_in_long_name = true;
828 break; 829 break;
@@ -1169,7 +1170,7 @@ static int is_connected_input_ep(struct snd_soc_dapm_widget *widget,
1169 * @custom_stop_condition: (optional) a function meant to stop the widget graph 1170 * @custom_stop_condition: (optional) a function meant to stop the widget graph
1170 * walk based on custom logic. 1171 * walk based on custom logic.
1171 * 1172 *
1172 * Queries DAPM graph as to whether an valid audio stream path exists for 1173 * Queries DAPM graph as to whether a valid audio stream path exists for
1173 * the initial stream specified by name. This takes into account 1174 * the initial stream specified by name. This takes into account
1174 * current mixer and mux kcontrol settings. Creates list of valid widgets. 1175 * current mixer and mux kcontrol settings. Creates list of valid widgets.
1175 * 1176 *
@@ -1294,8 +1295,7 @@ static int dapm_widget_power_check(struct snd_soc_dapm_widget *w)
1294 return w->new_power; 1295 return w->new_power;
1295} 1296}
1296 1297
1297/* Generic check to see if a widget should be powered. 1298/* Generic check to see if a widget should be powered. */
1298 */
1299static int dapm_generic_check_power(struct snd_soc_dapm_widget *w) 1299static int dapm_generic_check_power(struct snd_soc_dapm_widget *w)
1300{ 1300{
1301 int in, out; 1301 int in, out;
@@ -1646,7 +1646,7 @@ static void dapm_pre_sequence_async(void *data, async_cookie_t cookie)
1646 struct snd_soc_dapm_context *d = data; 1646 struct snd_soc_dapm_context *d = data;
1647 int ret; 1647 int ret;
1648 1648
1649 /* If we're off and we're not supposed to be go into STANDBY */ 1649 /* If we're off and we're not supposed to go into STANDBY */
1650 if (d->bias_level == SND_SOC_BIAS_OFF && 1650 if (d->bias_level == SND_SOC_BIAS_OFF &&
1651 d->target_bias_level != SND_SOC_BIAS_OFF) { 1651 d->target_bias_level != SND_SOC_BIAS_OFF) {
1652 if (d->dev) 1652 if (d->dev)
@@ -1798,7 +1798,7 @@ static bool dapm_idle_bias_off(struct snd_soc_dapm_context *dapm)
1798 * A complete path is a route that has valid endpoints i.e.:- 1798 * A complete path is a route that has valid endpoints i.e.:-
1799 * 1799 *
1800 * o DAC to output pin. 1800 * o DAC to output pin.
1801 * o Input Pin to ADC. 1801 * o Input pin to ADC.
1802 * o Input pin to Output pin (bypass, sidetone) 1802 * o Input pin to Output pin (bypass, sidetone)
1803 * o DAC to ADC (loopback). 1803 * o DAC to ADC (loopback).
1804 */ 1804 */
@@ -2114,7 +2114,7 @@ static inline void dapm_debugfs_cleanup(struct snd_soc_dapm_context *dapm)
2114 * soc_dapm_connect_path() - Connects or disconnects a path 2114 * soc_dapm_connect_path() - Connects or disconnects a path
2115 * @path: The path to update 2115 * @path: The path to update
2116 * @connect: The new connect state of the path. True if the path is connected, 2116 * @connect: The new connect state of the path. True if the path is connected,
2117 * false if it is disconneted. 2117 * false if it is disconnected.
2118 * @reason: The reason why the path changed (for debugging only) 2118 * @reason: The reason why the path changed (for debugging only)
2119 */ 2119 */
2120static void soc_dapm_connect_path(struct snd_soc_dapm_path *path, 2120static void soc_dapm_connect_path(struct snd_soc_dapm_path *path,
@@ -2233,7 +2233,7 @@ static ssize_t dapm_widget_show_component(struct snd_soc_component *cmpnt,
2233 if (w->dapm != dapm) 2233 if (w->dapm != dapm)
2234 continue; 2234 continue;
2235 2235
2236 /* only display widgets that burnm power */ 2236 /* only display widgets that burn power */
2237 switch (w->id) { 2237 switch (w->id) {
2238 case snd_soc_dapm_hp: 2238 case snd_soc_dapm_hp:
2239 case snd_soc_dapm_mic: 2239 case snd_soc_dapm_mic:
@@ -2461,7 +2461,7 @@ static void dapm_update_widget_flags(struct snd_soc_dapm_widget *w)
2461 2461
2462 switch (w->id) { 2462 switch (w->id) {
2463 case snd_soc_dapm_input: 2463 case snd_soc_dapm_input:
2464 /* On a fully routed card a input is never a source */ 2464 /* On a fully routed card an input is never a source */
2465 if (w->dapm->card->fully_routed) 2465 if (w->dapm->card->fully_routed)
2466 return; 2466 return;
2467 ep = SND_SOC_DAPM_EP_SOURCE; 2467 ep = SND_SOC_DAPM_EP_SOURCE;
@@ -3049,6 +3049,9 @@ int snd_soc_dapm_get_volsw(struct snd_kcontrol *kcontrol,
3049 } 3049 }
3050 mutex_unlock(&card->dapm_mutex); 3050 mutex_unlock(&card->dapm_mutex);
3051 3051
3052 if (ret)
3053 return ret;
3054
3052 if (invert) 3055 if (invert)
3053 ucontrol->value.integer.value[0] = max - val; 3056 ucontrol->value.integer.value[0] = max - val;
3054 else 3057 else
@@ -3200,7 +3203,7 @@ int snd_soc_dapm_put_enum_double(struct snd_kcontrol *kcontrol,
3200 if (e->shift_l != e->shift_r) { 3203 if (e->shift_l != e->shift_r) {
3201 if (item[1] > e->items) 3204 if (item[1] > e->items)
3202 return -EINVAL; 3205 return -EINVAL;
3203 val |= snd_soc_enum_item_to_val(e, item[1]) << e->shift_l; 3206 val |= snd_soc_enum_item_to_val(e, item[1]) << e->shift_r;
3204 mask |= e->mask << e->shift_r; 3207 mask |= e->mask << e->shift_r;
3205 } 3208 }
3206 3209
@@ -3445,7 +3448,7 @@ snd_soc_dapm_new_control_unlocked(struct snd_soc_dapm_context *dapm,
3445 w->endpoints[dir] = -1; 3448 w->endpoints[dir] = -1;
3446 } 3449 }
3447 3450
3448 /* machine layer set ups unconnected pins and insertions */ 3451 /* machine layer sets up unconnected pins and insertions */
3449 w->connected = 1; 3452 w->connected = 1;
3450 return w; 3453 return w;
3451} 3454}
diff --git a/sound/soc/soc-ops.c b/sound/soc/soc-ops.c
index a513a34a51d2..9fc1a7bb8b95 100644
--- a/sound/soc/soc-ops.c
+++ b/sound/soc/soc-ops.c
@@ -77,7 +77,7 @@ int snd_soc_get_enum_double(struct snd_kcontrol *kcontrol,
77 item = snd_soc_enum_val_to_item(e, val); 77 item = snd_soc_enum_val_to_item(e, val);
78 ucontrol->value.enumerated.item[0] = item; 78 ucontrol->value.enumerated.item[0] = item;
79 if (e->shift_l != e->shift_r) { 79 if (e->shift_l != e->shift_r) {
80 val = (reg_val >> e->shift_l) & e->mask; 80 val = (reg_val >> e->shift_r) & e->mask;
81 item = snd_soc_enum_val_to_item(e, val); 81 item = snd_soc_enum_val_to_item(e, val);
82 ucontrol->value.enumerated.item[1] = item; 82 ucontrol->value.enumerated.item[1] = item;
83 } 83 }
diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c
index 60d702f8b9f0..d56a16a0f6fa 100644
--- a/sound/soc/soc-pcm.c
+++ b/sound/soc/soc-pcm.c
@@ -1694,6 +1694,9 @@ static int dpcm_apply_symmetry(struct snd_pcm_substream *fe_substream,
1694 struct snd_soc_pcm_runtime *rtd = be_substream->private_data; 1694 struct snd_soc_pcm_runtime *rtd = be_substream->private_data;
1695 int i; 1695 int i;
1696 1696
1697 if (rtd->dai_link->be_hw_params_fixup)
1698 continue;
1699
1697 if (soc_pcm_has_symmetry(be_substream)) 1700 if (soc_pcm_has_symmetry(be_substream))
1698 be_substream->runtime->hw.info |= SNDRV_PCM_INFO_JOINT_DUPLEX; 1701 be_substream->runtime->hw.info |= SNDRV_PCM_INFO_JOINT_DUPLEX;
1699 1702
@@ -1790,7 +1793,7 @@ int dpcm_be_dai_shutdown(struct snd_soc_pcm_runtime *fe, int stream)
1790 continue; 1793 continue;
1791 1794
1792 dev_dbg(be->dev, "ASoC: close BE %s\n", 1795 dev_dbg(be->dev, "ASoC: close BE %s\n",
1793 dpcm->fe->dai_link->name); 1796 be->dai_link->name);
1794 1797
1795 soc_pcm_close(be_substream); 1798 soc_pcm_close(be_substream);
1796 be_substream->runtime = NULL; 1799 be_substream->runtime = NULL;
@@ -1856,7 +1859,7 @@ int dpcm_be_dai_hw_free(struct snd_soc_pcm_runtime *fe, int stream)
1856 continue; 1859 continue;
1857 1860
1858 dev_dbg(be->dev, "ASoC: hw_free BE %s\n", 1861 dev_dbg(be->dev, "ASoC: hw_free BE %s\n",
1859 dpcm->fe->dai_link->name); 1862 be->dai_link->name);
1860 1863
1861 soc_pcm_hw_free(be_substream); 1864 soc_pcm_hw_free(be_substream);
1862 1865
@@ -1934,7 +1937,7 @@ int dpcm_be_dai_hw_params(struct snd_soc_pcm_runtime *fe, int stream)
1934 continue; 1937 continue;
1935 1938
1936 dev_dbg(be->dev, "ASoC: hw_params BE %s\n", 1939 dev_dbg(be->dev, "ASoC: hw_params BE %s\n",
1937 dpcm->fe->dai_link->name); 1940 be->dai_link->name);
1938 1941
1939 ret = soc_pcm_hw_params(be_substream, &dpcm->hw_params); 1942 ret = soc_pcm_hw_params(be_substream, &dpcm->hw_params);
1940 if (ret < 0) { 1943 if (ret < 0) {
@@ -2014,7 +2017,7 @@ static int dpcm_do_trigger(struct snd_soc_dpcm *dpcm,
2014 int ret; 2017 int ret;
2015 2018
2016 dev_dbg(dpcm->be->dev, "ASoC: trigger BE %s cmd %d\n", 2019 dev_dbg(dpcm->be->dev, "ASoC: trigger BE %s cmd %d\n",
2017 dpcm->fe->dai_link->name, cmd); 2020 dpcm->be->dai_link->name, cmd);
2018 2021
2019 ret = soc_pcm_trigger(substream, cmd); 2022 ret = soc_pcm_trigger(substream, cmd);
2020 if (ret < 0) 2023 if (ret < 0)
@@ -2229,7 +2232,7 @@ int dpcm_be_dai_prepare(struct snd_soc_pcm_runtime *fe, int stream)
2229 continue; 2232 continue;
2230 2233
2231 dev_dbg(be->dev, "ASoC: prepare BE %s\n", 2234 dev_dbg(be->dev, "ASoC: prepare BE %s\n",
2232 dpcm->fe->dai_link->name); 2235 be->dai_link->name);
2233 2236
2234 ret = soc_pcm_prepare(be_substream); 2237 ret = soc_pcm_prepare(be_substream);
2235 if (ret < 0) { 2238 if (ret < 0) {
diff --git a/sound/soc/soc-topology.c b/sound/soc/soc-topology.c
index ee7f15aa46fc..6b05047a4134 100644
--- a/sound/soc/soc-topology.c
+++ b/sound/soc/soc-topology.c
@@ -48,9 +48,10 @@
48#define SOC_TPLG_PASS_PCM_DAI 4 48#define SOC_TPLG_PASS_PCM_DAI 4
49#define SOC_TPLG_PASS_GRAPH 5 49#define SOC_TPLG_PASS_GRAPH 5
50#define SOC_TPLG_PASS_PINS 6 50#define SOC_TPLG_PASS_PINS 6
51#define SOC_TPLG_PASS_BE_DAI 7
51 52
52#define SOC_TPLG_PASS_START SOC_TPLG_PASS_MANIFEST 53#define SOC_TPLG_PASS_START SOC_TPLG_PASS_MANIFEST
53#define SOC_TPLG_PASS_END SOC_TPLG_PASS_PINS 54#define SOC_TPLG_PASS_END SOC_TPLG_PASS_BE_DAI
54 55
55struct soc_tplg { 56struct soc_tplg {
56 const struct firmware *fw; 57 const struct firmware *fw;
@@ -1475,6 +1476,7 @@ widget:
1475 if (widget == NULL) { 1476 if (widget == NULL) {
1476 dev_err(tplg->dev, "ASoC: failed to create widget %s controls\n", 1477 dev_err(tplg->dev, "ASoC: failed to create widget %s controls\n",
1477 w->name); 1478 w->name);
1479 ret = -ENOMEM;
1478 goto hdr_err; 1480 goto hdr_err;
1479 } 1481 }
1480 1482
@@ -1554,6 +1556,25 @@ static void set_stream_info(struct snd_soc_pcm_stream *stream,
1554 stream->rate_min = caps->rate_min; 1556 stream->rate_min = caps->rate_min;
1555 stream->rate_max = caps->rate_max; 1557 stream->rate_max = caps->rate_max;
1556 stream->formats = caps->formats; 1558 stream->formats = caps->formats;
1559 stream->sig_bits = caps->sig_bits;
1560}
1561
1562static void set_dai_flags(struct snd_soc_dai_driver *dai_drv,
1563 unsigned int flag_mask, unsigned int flags)
1564{
1565 if (flag_mask & SND_SOC_TPLG_DAI_FLGBIT_SYMMETRIC_RATES)
1566 dai_drv->symmetric_rates =
1567 flags & SND_SOC_TPLG_DAI_FLGBIT_SYMMETRIC_RATES ? 1 : 0;
1568
1569 if (flag_mask & SND_SOC_TPLG_DAI_FLGBIT_SYMMETRIC_CHANNELS)
1570 dai_drv->symmetric_channels =
1571 flags & SND_SOC_TPLG_DAI_FLGBIT_SYMMETRIC_CHANNELS ?
1572 1 : 0;
1573
1574 if (flag_mask & SND_SOC_TPLG_DAI_FLGBIT_SYMMETRIC_SAMPLEBITS)
1575 dai_drv->symmetric_samplebits =
1576 flags & SND_SOC_TPLG_DAI_FLGBIT_SYMMETRIC_SAMPLEBITS ?
1577 1 : 0;
1557} 1578}
1558 1579
1559static int soc_tplg_dai_create(struct soc_tplg *tplg, 1580static int soc_tplg_dai_create(struct soc_tplg *tplg,
@@ -1690,8 +1711,96 @@ static int soc_tplg_pcm_elems_load(struct soc_tplg *tplg,
1690 return 0; 1711 return 0;
1691} 1712}
1692 1713
1714/* *
1715 * soc_tplg_be_dai_config - Find and configure an existing BE DAI.
1716 * @tplg: topology context
1717 * @be: topology BE DAI configs.
1718 *
1719 * The BE dai should already be registered by the platform driver. The
1720 * platform driver should specify the BE DAI name and ID for matching.
1721 */
1722static int soc_tplg_be_dai_config(struct soc_tplg *tplg,
1723 struct snd_soc_tplg_be_dai *be)
1724{
1725 struct snd_soc_dai_link_component dai_component = {0};
1726 struct snd_soc_dai *dai;
1727 struct snd_soc_dai_driver *dai_drv;
1728 struct snd_soc_pcm_stream *stream;
1729 struct snd_soc_tplg_stream_caps *caps;
1730 int ret;
1731
1732 dai_component.dai_name = be->dai_name;
1733 dai = snd_soc_find_dai(&dai_component);
1734 if (!dai) {
1735 dev_err(tplg->dev, "ASoC: BE DAI %s not registered\n",
1736 be->dai_name);
1737 return -EINVAL;
1738 }
1739
1740 if (be->dai_id != dai->id) {
1741 dev_err(tplg->dev, "ASoC: BE DAI %s id mismatch\n",
1742 be->dai_name);
1743 return -EINVAL;
1744 }
1745
1746 dai_drv = dai->driver;
1747 if (!dai_drv)
1748 return -EINVAL;
1749
1750 if (be->playback) {
1751 stream = &dai_drv->playback;
1752 caps = &be->caps[SND_SOC_TPLG_STREAM_PLAYBACK];
1753 set_stream_info(stream, caps);
1754 }
1755
1756 if (be->capture) {
1757 stream = &dai_drv->capture;
1758 caps = &be->caps[SND_SOC_TPLG_STREAM_CAPTURE];
1759 set_stream_info(stream, caps);
1760 }
1761
1762 if (be->flag_mask)
1763 set_dai_flags(dai_drv, be->flag_mask, be->flags);
1764
1765 /* pass control to component driver for optional further init */
1766 ret = soc_tplg_dai_load(tplg, dai_drv);
1767 if (ret < 0) {
1768 dev_err(tplg->comp->dev, "ASoC: DAI loading failed\n");
1769 return ret;
1770 }
1771
1772 return 0;
1773}
1774
1775static int soc_tplg_be_dai_elems_load(struct soc_tplg *tplg,
1776 struct snd_soc_tplg_hdr *hdr)
1777{
1778 struct snd_soc_tplg_be_dai *be;
1779 int count = hdr->count;
1780 int i;
1781
1782 if (tplg->pass != SOC_TPLG_PASS_BE_DAI)
1783 return 0;
1784
1785 /* config the existing BE DAIs */
1786 for (i = 0; i < count; i++) {
1787 be = (struct snd_soc_tplg_be_dai *)tplg->pos;
1788 if (be->size != sizeof(*be)) {
1789 dev_err(tplg->dev, "ASoC: invalid BE DAI size\n");
1790 return -EINVAL;
1791 }
1792
1793 soc_tplg_be_dai_config(tplg, be);
1794 tplg->pos += (sizeof(*be) + be->priv.size);
1795 }
1796
1797 dev_dbg(tplg->dev, "ASoC: Configure %d BE DAIs\n", count);
1798 return 0;
1799}
1800
1801
1693static int soc_tplg_manifest_load(struct soc_tplg *tplg, 1802static int soc_tplg_manifest_load(struct soc_tplg *tplg,
1694 struct snd_soc_tplg_hdr *hdr) 1803 struct snd_soc_tplg_hdr *hdr)
1695{ 1804{
1696 struct snd_soc_tplg_manifest *manifest; 1805 struct snd_soc_tplg_manifest *manifest;
1697 1806
@@ -1793,6 +1902,8 @@ static int soc_tplg_load_header(struct soc_tplg *tplg,
1793 return soc_tplg_dapm_widget_elems_load(tplg, hdr); 1902 return soc_tplg_dapm_widget_elems_load(tplg, hdr);
1794 case SND_SOC_TPLG_TYPE_PCM: 1903 case SND_SOC_TPLG_TYPE_PCM:
1795 return soc_tplg_pcm_elems_load(tplg, hdr); 1904 return soc_tplg_pcm_elems_load(tplg, hdr);
1905 case SND_SOC_TPLG_TYPE_BE_DAI:
1906 return soc_tplg_be_dai_elems_load(tplg, hdr);
1796 case SND_SOC_TPLG_TYPE_MANIFEST: 1907 case SND_SOC_TPLG_TYPE_MANIFEST:
1797 return soc_tplg_manifest_load(tplg, hdr); 1908 return soc_tplg_manifest_load(tplg, hdr);
1798 default: 1909 default:
diff --git a/sound/soc/soc-utils.c b/sound/soc/soc-utils.c
index 53dd085d3ee2..393e8f0fe2cc 100644
--- a/sound/soc/soc-utils.c
+++ b/sound/soc/soc-utils.c
@@ -80,7 +80,7 @@ static int dummy_dma_open(struct snd_pcm_substream *substream)
80 return 0; 80 return 0;
81} 81}
82 82
83static struct snd_pcm_ops dummy_dma_ops = { 83static const struct snd_pcm_ops dummy_dma_ops = {
84 .open = dummy_dma_open, 84 .open = dummy_dma_open,
85 .ioctl = snd_pcm_lib_ioctl, 85 .ioctl = snd_pcm_lib_ioctl,
86}; 86};
diff --git a/sound/soc/sti/sti_uniperif.c b/sound/soc/sti/sti_uniperif.c
index 488ef4ed8fba..549fac349fa0 100644
--- a/sound/soc/sti/sti_uniperif.c
+++ b/sound/soc/sti/sti_uniperif.c
@@ -19,6 +19,84 @@
19#define UNIPERIF_MAX_FRAME_SZ 0x20 19#define UNIPERIF_MAX_FRAME_SZ 0x20
20#define UNIPERIF_ALLOWED_FRAME_SZ (0x08 | 0x10 | 0x18 | UNIPERIF_MAX_FRAME_SZ) 20#define UNIPERIF_ALLOWED_FRAME_SZ (0x08 | 0x10 | 0x18 | UNIPERIF_MAX_FRAME_SZ)
21 21
22struct sti_uniperiph_dev_data {
23 unsigned int id; /* Nb available player instances */
24 unsigned int version; /* player IP version */
25 unsigned int stream;
26 const char *dai_names;
27 enum uniperif_type type;
28};
29
30static const struct sti_uniperiph_dev_data sti_uniplayer_hdmi = {
31 .id = 0,
32 .version = SND_ST_UNIPERIF_VERSION_UNI_PLR_TOP_1_0,
33 .stream = SNDRV_PCM_STREAM_PLAYBACK,
34 .dai_names = "Uni Player #0 (HDMI)",
35 .type = SND_ST_UNIPERIF_TYPE_HDMI
36};
37
38static const struct sti_uniperiph_dev_data sti_uniplayer_pcm_out = {
39 .id = 1,
40 .version = SND_ST_UNIPERIF_VERSION_UNI_PLR_TOP_1_0,
41 .stream = SNDRV_PCM_STREAM_PLAYBACK,
42 .dai_names = "Uni Player #1 (PCM OUT)",
43 .type = SND_ST_UNIPERIF_TYPE_PCM | SND_ST_UNIPERIF_TYPE_TDM,
44};
45
46static const struct sti_uniperiph_dev_data sti_uniplayer_dac = {
47 .id = 2,
48 .version = SND_ST_UNIPERIF_VERSION_UNI_PLR_TOP_1_0,
49 .stream = SNDRV_PCM_STREAM_PLAYBACK,
50 .dai_names = "Uni Player #2 (DAC)",
51 .type = SND_ST_UNIPERIF_TYPE_PCM,
52};
53
54static const struct sti_uniperiph_dev_data sti_uniplayer_spdif = {
55 .id = 3,
56 .version = SND_ST_UNIPERIF_VERSION_UNI_PLR_TOP_1_0,
57 .stream = SNDRV_PCM_STREAM_PLAYBACK,
58 .dai_names = "Uni Player #3 (SPDIF)",
59 .type = SND_ST_UNIPERIF_TYPE_SPDIF
60};
61
62static const struct sti_uniperiph_dev_data sti_unireader_pcm_in = {
63 .id = 0,
64 .version = SND_ST_UNIPERIF_VERSION_UNI_RDR_1_0,
65 .stream = SNDRV_PCM_STREAM_CAPTURE,
66 .dai_names = "Uni Reader #0 (PCM IN)",
67 .type = SND_ST_UNIPERIF_TYPE_PCM | SND_ST_UNIPERIF_TYPE_TDM,
68};
69
70static const struct sti_uniperiph_dev_data sti_unireader_hdmi_in = {
71 .id = 1,
72 .version = SND_ST_UNIPERIF_VERSION_UNI_RDR_1_0,
73 .stream = SNDRV_PCM_STREAM_CAPTURE,
74 .dai_names = "Uni Reader #1 (HDMI IN)",
75 .type = SND_ST_UNIPERIF_TYPE_PCM,
76};
77
78static const struct of_device_id snd_soc_sti_match[] = {
79 { .compatible = "st,stih407-uni-player-hdmi",
80 .data = &sti_uniplayer_hdmi
81 },
82 { .compatible = "st,stih407-uni-player-pcm-out",
83 .data = &sti_uniplayer_pcm_out
84 },
85 { .compatible = "st,stih407-uni-player-dac",
86 .data = &sti_uniplayer_dac
87 },
88 { .compatible = "st,stih407-uni-player-spdif",
89 .data = &sti_uniplayer_spdif
90 },
91 { .compatible = "st,stih407-uni-reader-pcm_in",
92 .data = &sti_unireader_pcm_in
93 },
94 { .compatible = "st,stih407-uni-reader-hdmi",
95 .data = &sti_unireader_hdmi_in
96 },
97 {},
98};
99
22int sti_uniperiph_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask, 100int sti_uniperiph_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
23 unsigned int rx_mask, int slots, 101 unsigned int rx_mask, int slots,
24 int slot_width) 102 int slot_width)
@@ -167,8 +245,8 @@ static int sti_uniperiph_dai_create_ctrl(struct snd_soc_dai *dai)
167 * Uniperipheral instance ID 245 * Uniperipheral instance ID
168 */ 246 */
169 ctrl = &uni->snd_ctrls[i]; 247 ctrl = &uni->snd_ctrls[i];
170 ctrl->index = uni->info->id; 248 ctrl->index = uni->id;
171 ctrl->device = uni->info->id; 249 ctrl->device = uni->id;
172 } 250 }
173 251
174 return snd_soc_add_dai_controls(dai, uni->snd_ctrls, uni->num_ctrls); 252 return snd_soc_add_dai_controls(dai, uni->snd_ctrls, uni->num_ctrls);
@@ -186,7 +264,7 @@ int sti_uniperiph_dai_hw_params(struct snd_pcm_substream *substream,
186 struct snd_dmaengine_dai_dma_data *dma_data; 264 struct snd_dmaengine_dai_dma_data *dma_data;
187 int transfer_size; 265 int transfer_size;
188 266
189 if (uni->info->type == SND_ST_UNIPERIF_TYPE_TDM) 267 if (uni->type == SND_ST_UNIPERIF_TYPE_TDM)
190 /* transfer size = user frame size (in 32-bits FIFO cell) */ 268 /* transfer size = user frame size (in 32-bits FIFO cell) */
191 transfer_size = snd_soc_params_to_frame_size(params) / 32; 269 transfer_size = snd_soc_params_to_frame_size(params) / 32;
192 else 270 else
@@ -235,7 +313,7 @@ static int sti_uniperiph_dai_resume(struct snd_soc_dai *dai)
235 struct uniperif *uni = priv->dai_data.uni; 313 struct uniperif *uni = priv->dai_data.uni;
236 int ret; 314 int ret;
237 315
238 if (of_device_is_compatible(dai->dev->of_node, "st,sti-uni-player")) { 316 if (priv->dai_data.stream == SNDRV_PCM_STREAM_PLAYBACK) {
239 ret = uni_player_resume(uni); 317 ret = uni_player_resume(uni);
240 if (ret) 318 if (ret)
241 return ret; 319 return ret;
@@ -256,7 +334,7 @@ static int sti_uniperiph_dai_probe(struct snd_soc_dai *dai)
256 struct sti_uniperiph_dai *dai_data = &priv->dai_data; 334 struct sti_uniperiph_dai *dai_data = &priv->dai_data;
257 335
258 /* DMA settings*/ 336 /* DMA settings*/
259 if (of_device_is_compatible(dai->dev->of_node, "st,sti-uni-player")) 337 if (priv->dai_data.stream == SNDRV_PCM_STREAM_PLAYBACK)
260 snd_soc_dai_init_dma_data(dai, &dai_data->dma_data, NULL); 338 snd_soc_dai_init_dma_data(dai, &dai_data->dma_data, NULL);
261 else 339 else
262 snd_soc_dai_init_dma_data(dai, NULL, &dai_data->dma_data); 340 snd_soc_dai_init_dma_data(dai, NULL, &dai_data->dma_data);
@@ -280,25 +358,32 @@ static const struct snd_soc_component_driver sti_uniperiph_dai_component = {
280static int sti_uniperiph_cpu_dai_of(struct device_node *node, 358static int sti_uniperiph_cpu_dai_of(struct device_node *node,
281 struct sti_uniperiph_data *priv) 359 struct sti_uniperiph_data *priv)
282{ 360{
283 const char *str;
284 int ret;
285 struct device *dev = &priv->pdev->dev; 361 struct device *dev = &priv->pdev->dev;
286 struct sti_uniperiph_dai *dai_data = &priv->dai_data; 362 struct sti_uniperiph_dai *dai_data = &priv->dai_data;
287 struct snd_soc_dai_driver *dai = priv->dai; 363 struct snd_soc_dai_driver *dai = priv->dai;
288 struct snd_soc_pcm_stream *stream; 364 struct snd_soc_pcm_stream *stream;
289 struct uniperif *uni; 365 struct uniperif *uni;
366 const struct of_device_id *of_id;
367 const struct sti_uniperiph_dev_data *dev_data;
368 const char *mode;
369
370 /* Populate data structure depending on compatibility */
371 of_id = of_match_node(snd_soc_sti_match, node);
372 if (!of_id->data) {
373 dev_err(dev, "data associated to device is missing");
374 return -EINVAL;
375 }
376 dev_data = (struct sti_uniperiph_dev_data *)of_id->data;
290 377
291 uni = devm_kzalloc(dev, sizeof(*uni), GFP_KERNEL); 378 uni = devm_kzalloc(dev, sizeof(*uni), GFP_KERNEL);
292 if (!uni) 379 if (!uni)
293 return -ENOMEM; 380 return -ENOMEM;
294 381
382 uni->id = dev_data->id;
383 uni->ver = dev_data->version;
384
295 *dai = sti_uniperiph_dai_template; 385 *dai = sti_uniperiph_dai_template;
296 ret = of_property_read_string(node, "dai-name", &str); 386 dai->name = dev_data->dai_names;
297 if (ret < 0) {
298 dev_err(dev, "%s: dai name missing.\n", __func__);
299 return -EINVAL;
300 }
301 dai->name = str;
302 387
303 /* Get resources */ 388 /* Get resources */
304 uni->mem_region = platform_get_resource(priv->pdev, IORESOURCE_MEM, 0); 389 uni->mem_region = platform_get_resource(priv->pdev, IORESOURCE_MEM, 0);
@@ -322,9 +407,20 @@ static int sti_uniperiph_cpu_dai_of(struct device_node *node,
322 return -ENXIO; 407 return -ENXIO;
323 } 408 }
324 409
410 uni->type = dev_data->type;
411
412 /* check if player should be configured for tdm */
413 if (dev_data->type & SND_ST_UNIPERIF_TYPE_TDM) {
414 if (!of_property_read_string(node, "st,tdm-mode", &mode))
415 uni->type = SND_ST_UNIPERIF_TYPE_TDM;
416 else
417 uni->type = SND_ST_UNIPERIF_TYPE_PCM;
418 }
419
325 dai_data->uni = uni; 420 dai_data->uni = uni;
421 dai_data->stream = dev_data->stream;
326 422
327 if (of_device_is_compatible(node, "st,sti-uni-player")) { 423 if (priv->dai_data.stream == SNDRV_PCM_STREAM_PLAYBACK) {
328 uni_player_init(priv->pdev, uni); 424 uni_player_init(priv->pdev, uni);
329 stream = &dai->playback; 425 stream = &dai->playback;
330 } else { 426 } else {
@@ -376,12 +472,6 @@ static int sti_uniperiph_probe(struct platform_device *pdev)
376 &dmaengine_pcm_config, 0); 472 &dmaengine_pcm_config, 0);
377} 473}
378 474
379static const struct of_device_id snd_soc_sti_match[] = {
380 { .compatible = "st,sti-uni-player", },
381 { .compatible = "st,sti-uni-reader", },
382 {},
383};
384
385static struct platform_driver sti_uniperiph_driver = { 475static struct platform_driver sti_uniperiph_driver = {
386 .driver = { 476 .driver = {
387 .name = "sti-uniperiph-dai", 477 .name = "sti-uniperiph-dai",
diff --git a/sound/soc/sti/uniperif.h b/sound/soc/sti/uniperif.h
index eb9933c62ad6..1993c655fb79 100644
--- a/sound/soc/sti/uniperif.h
+++ b/sound/soc/sti/uniperif.h
@@ -1220,16 +1220,16 @@
1220#define UNIPERIF_FIFO_FRAMES 4 /* FDMA trigger limit in frames */ 1220#define UNIPERIF_FIFO_FRAMES 4 /* FDMA trigger limit in frames */
1221 1221
1222#define UNIPERIF_TYPE_IS_HDMI(p) \ 1222#define UNIPERIF_TYPE_IS_HDMI(p) \
1223 ((p)->info->type == SND_ST_UNIPERIF_TYPE_HDMI) 1223 ((p)->type == SND_ST_UNIPERIF_TYPE_HDMI)
1224#define UNIPERIF_TYPE_IS_PCM(p) \ 1224#define UNIPERIF_TYPE_IS_PCM(p) \
1225 ((p)->info->type == SND_ST_UNIPERIF_TYPE_PCM) 1225 ((p)->type == SND_ST_UNIPERIF_TYPE_PCM)
1226#define UNIPERIF_TYPE_IS_SPDIF(p) \ 1226#define UNIPERIF_TYPE_IS_SPDIF(p) \
1227 ((p)->info->type == SND_ST_UNIPERIF_TYPE_SPDIF) 1227 ((p)->type == SND_ST_UNIPERIF_TYPE_SPDIF)
1228#define UNIPERIF_TYPE_IS_IEC958(p) \ 1228#define UNIPERIF_TYPE_IS_IEC958(p) \
1229 (UNIPERIF_TYPE_IS_HDMI(p) || \ 1229 (UNIPERIF_TYPE_IS_HDMI(p) || \
1230 UNIPERIF_TYPE_IS_SPDIF(p)) 1230 UNIPERIF_TYPE_IS_SPDIF(p))
1231#define UNIPERIF_TYPE_IS_TDM(p) \ 1231#define UNIPERIF_TYPE_IS_TDM(p) \
1232 ((p)->info->type == SND_ST_UNIPERIF_TYPE_TDM) 1232 ((p)->type == SND_ST_UNIPERIF_TYPE_TDM)
1233 1233
1234/* 1234/*
1235 * Uniperipheral IP revisions 1235 * Uniperipheral IP revisions
@@ -1249,11 +1249,11 @@ enum uniperif_version {
1249}; 1249};
1250 1250
1251enum uniperif_type { 1251enum uniperif_type {
1252 SND_ST_UNIPERIF_TYPE_NONE, 1252 SND_ST_UNIPERIF_TYPE_NONE = 0x00,
1253 SND_ST_UNIPERIF_TYPE_HDMI, 1253 SND_ST_UNIPERIF_TYPE_HDMI = 0x01,
1254 SND_ST_UNIPERIF_TYPE_PCM, 1254 SND_ST_UNIPERIF_TYPE_PCM = 0x02,
1255 SND_ST_UNIPERIF_TYPE_SPDIF, 1255 SND_ST_UNIPERIF_TYPE_SPDIF = 0x04,
1256 SND_ST_UNIPERIF_TYPE_TDM 1256 SND_ST_UNIPERIF_TYPE_TDM = 0x08
1257}; 1257};
1258 1258
1259enum uniperif_state { 1259enum uniperif_state {
@@ -1278,12 +1278,6 @@ enum uniperif_word_pos {
1278 WORD_MAX 1278 WORD_MAX
1279}; 1279};
1280 1280
1281struct uniperif_info {
1282 int id; /* instance value of the uniperipheral IP */
1283 enum uniperif_type type;
1284 int underflow_enabled; /* Underflow recovery mode */
1285};
1286
1287struct uniperif_iec958_settings { 1281struct uniperif_iec958_settings {
1288 enum uniperif_iec958_encoding_mode encoding_mode; 1282 enum uniperif_iec958_encoding_mode encoding_mode;
1289 struct snd_aes_iec958 iec958; 1283 struct snd_aes_iec958 iec958;
@@ -1298,8 +1292,10 @@ struct dai_tdm_slot {
1298 1292
1299struct uniperif { 1293struct uniperif {
1300 /* System information */ 1294 /* System information */
1301 struct uniperif_info *info; 1295 enum uniperif_type type;
1296 int underflow_enabled; /* Underflow recovery mode */
1302 struct device *dev; 1297 struct device *dev;
1298 int id; /* instance value of the uniperipheral IP */
1303 int ver; /* IP version, used by register access macros */ 1299 int ver; /* IP version, used by register access macros */
1304 struct regmap_field *clk_sel; 1300 struct regmap_field *clk_sel;
1305 struct regmap_field *valid_sel; 1301 struct regmap_field *valid_sel;
diff --git a/sound/soc/sti/uniperif_player.c b/sound/soc/sti/uniperif_player.c
index 1ac2db205a0d..1bc8ebc2528e 100644
--- a/sound/soc/sti/uniperif_player.c
+++ b/sound/soc/sti/uniperif_player.c
@@ -100,7 +100,7 @@ static irqreturn_t uni_player_irq_handler(int irq, void *dev_id)
100 dev_err(player->dev, "FIFO underflow error detected"); 100 dev_err(player->dev, "FIFO underflow error detected");
101 101
102 /* Interrupt is just for information when underflow recovery */ 102 /* Interrupt is just for information when underflow recovery */
103 if (player->info->underflow_enabled) { 103 if (player->underflow_enabled) {
104 /* Update state to underflow */ 104 /* Update state to underflow */
105 player->state = UNIPERIF_STATE_UNDERFLOW; 105 player->state = UNIPERIF_STATE_UNDERFLOW;
106 106
@@ -134,7 +134,7 @@ static irqreturn_t uni_player_irq_handler(int irq, void *dev_id)
134 134
135 /* Check for underflow recovery done */ 135 /* Check for underflow recovery done */
136 if (unlikely(status & UNIPERIF_ITM_UNDERFLOW_REC_DONE_MASK(player))) { 136 if (unlikely(status & UNIPERIF_ITM_UNDERFLOW_REC_DONE_MASK(player))) {
137 if (!player->info->underflow_enabled) { 137 if (!player->underflow_enabled) {
138 dev_err(player->dev, "unexpected Underflow recovering"); 138 dev_err(player->dev, "unexpected Underflow recovering");
139 return -EPERM; 139 return -EPERM;
140 } 140 }
@@ -764,7 +764,7 @@ static int uni_player_prepare(struct snd_pcm_substream *substream,
764 } 764 }
765 765
766 /* Calculate transfer size (in fifo cells and bytes) for frame count */ 766 /* Calculate transfer size (in fifo cells and bytes) for frame count */
767 if (player->info->type == SND_ST_UNIPERIF_TYPE_TDM) { 767 if (player->type == SND_ST_UNIPERIF_TYPE_TDM) {
768 /* transfer size = user frame size (in 32 bits FIFO cell) */ 768 /* transfer size = user frame size (in 32 bits FIFO cell) */
769 transfer_size = 769 transfer_size =
770 sti_uniperiph_get_user_frame_size(runtime) / 4; 770 sti_uniperiph_get_user_frame_size(runtime) / 4;
@@ -794,7 +794,7 @@ static int uni_player_prepare(struct snd_pcm_substream *substream,
794 SET_UNIPERIF_CONFIG_DMA_TRIG_LIMIT(player, trigger_limit); 794 SET_UNIPERIF_CONFIG_DMA_TRIG_LIMIT(player, trigger_limit);
795 795
796 /* Uniperipheral setup depends on player type */ 796 /* Uniperipheral setup depends on player type */
797 switch (player->info->type) { 797 switch (player->type) {
798 case SND_ST_UNIPERIF_TYPE_HDMI: 798 case SND_ST_UNIPERIF_TYPE_HDMI:
799 ret = uni_player_prepare_iec958(player, runtime); 799 ret = uni_player_prepare_iec958(player, runtime);
800 break; 800 break;
@@ -884,7 +884,7 @@ static int uni_player_start(struct uniperif *player)
884 SET_UNIPERIF_ITM_BSET_FIFO_ERROR(player); 884 SET_UNIPERIF_ITM_BSET_FIFO_ERROR(player);
885 885
886 /* Enable underflow recovery interrupts */ 886 /* Enable underflow recovery interrupts */
887 if (player->info->underflow_enabled) { 887 if (player->underflow_enabled) {
888 SET_UNIPERIF_ITM_BSET_UNDERFLOW_REC_DONE(player); 888 SET_UNIPERIF_ITM_BSET_UNDERFLOW_REC_DONE(player);
889 SET_UNIPERIF_ITM_BSET_UNDERFLOW_REC_FAILED(player); 889 SET_UNIPERIF_ITM_BSET_UNDERFLOW_REC_FAILED(player);
890 } 890 }
@@ -893,8 +893,10 @@ static int uni_player_start(struct uniperif *player)
893 SET_UNIPERIF_SOFT_RST_SOFT_RST(player); 893 SET_UNIPERIF_SOFT_RST_SOFT_RST(player);
894 894
895 ret = reset_player(player); 895 ret = reset_player(player);
896 if (ret < 0) 896 if (ret < 0) {
897 clk_disable_unprepare(player->clk);
897 return ret; 898 return ret;
899 }
898 900
899 /* 901 /*
900 * Does not use IEC61937 features of the uniperipheral hardware. 902 * Does not use IEC61937 features of the uniperipheral hardware.
@@ -1021,8 +1023,8 @@ static int uni_player_parse_dt_audio_glue(struct platform_device *pdev,
1021 struct reg_field regfield[2] = { 1023 struct reg_field regfield[2] = {
1022 /* PCM_CLK_SEL */ 1024 /* PCM_CLK_SEL */
1023 REG_FIELD(SYS_CFG_AUDIO_GLUE, 1025 REG_FIELD(SYS_CFG_AUDIO_GLUE,
1024 8 + player->info->id, 1026 8 + player->id,
1025 8 + player->info->id), 1027 8 + player->id),
1026 /* PCMP_VALID_SEL */ 1028 /* PCMP_VALID_SEL */
1027 REG_FIELD(SYS_CFG_AUDIO_GLUE, 0, 1) 1029 REG_FIELD(SYS_CFG_AUDIO_GLUE, 0, 1)
1028 }; 1030 };
@@ -1040,60 +1042,6 @@ static int uni_player_parse_dt_audio_glue(struct platform_device *pdev,
1040 return 0; 1042 return 0;
1041} 1043}
1042 1044
1043static int uni_player_parse_dt(struct platform_device *pdev,
1044 struct uniperif *player)
1045{
1046 struct uniperif_info *info;
1047 struct device *dev = &pdev->dev;
1048 struct device_node *pnode = pdev->dev.of_node;
1049 const char *mode;
1050
1051 /* Allocate memory for the info structure */
1052 info = devm_kzalloc(dev, sizeof(*info), GFP_KERNEL);
1053 if (!info)
1054 return -ENOMEM;
1055
1056 if (of_property_read_u32(pnode, "st,version", &player->ver) ||
1057 player->ver == SND_ST_UNIPERIF_VERSION_UNKNOWN) {
1058 dev_err(dev, "Unknown uniperipheral version ");
1059 return -EINVAL;
1060 }
1061 /* Underflow recovery is only supported on later ip revisions */
1062 if (player->ver >= SND_ST_UNIPERIF_VERSION_UNI_PLR_TOP_1_0)
1063 info->underflow_enabled = 1;
1064
1065 if (of_property_read_u32(pnode, "st,uniperiph-id", &info->id)) {
1066 dev_err(dev, "uniperipheral id not defined");
1067 return -EINVAL;
1068 }
1069
1070 /* Read the device mode property */
1071 if (of_property_read_string(pnode, "st,mode", &mode)) {
1072 dev_err(dev, "uniperipheral mode not defined");
1073 return -EINVAL;
1074 }
1075
1076 if (strcasecmp(mode, "hdmi") == 0)
1077 info->type = SND_ST_UNIPERIF_TYPE_HDMI;
1078 else if (strcasecmp(mode, "pcm") == 0)
1079 info->type = SND_ST_UNIPERIF_TYPE_PCM;
1080 else if (strcasecmp(mode, "spdif") == 0)
1081 info->type = SND_ST_UNIPERIF_TYPE_SPDIF;
1082 else if (strcasecmp(mode, "tdm") == 0)
1083 info->type = SND_ST_UNIPERIF_TYPE_TDM;
1084 else
1085 info->type = SND_ST_UNIPERIF_TYPE_NONE;
1086
1087 /* Save the info structure */
1088 player->info = info;
1089
1090 /* Get PCM_CLK_SEL & PCMP_VALID_SEL from audio-glue-ctrl SoC reg */
1091 if (uni_player_parse_dt_audio_glue(pdev, player))
1092 return -EINVAL;
1093
1094 return 0;
1095}
1096
1097static const struct snd_soc_dai_ops uni_player_dai_ops = { 1045static const struct snd_soc_dai_ops uni_player_dai_ops = {
1098 .startup = uni_player_startup, 1046 .startup = uni_player_startup,
1099 .shutdown = uni_player_shutdown, 1047 .shutdown = uni_player_shutdown,
@@ -1114,13 +1062,18 @@ int uni_player_init(struct platform_device *pdev,
1114 player->state = UNIPERIF_STATE_STOPPED; 1062 player->state = UNIPERIF_STATE_STOPPED;
1115 player->dai_ops = &uni_player_dai_ops; 1063 player->dai_ops = &uni_player_dai_ops;
1116 1064
1117 ret = uni_player_parse_dt(pdev, player); 1065 /* Get PCM_CLK_SEL & PCMP_VALID_SEL from audio-glue-ctrl SoC reg */
1066 ret = uni_player_parse_dt_audio_glue(pdev, player);
1118 1067
1119 if (ret < 0) { 1068 if (ret < 0) {
1120 dev_err(player->dev, "Failed to parse DeviceTree"); 1069 dev_err(player->dev, "Failed to parse DeviceTree");
1121 return ret; 1070 return ret;
1122 } 1071 }
1123 1072
1073 /* Underflow recovery is only supported on later ip revisions */
1074 if (player->ver >= SND_ST_UNIPERIF_VERSION_UNI_PLR_TOP_1_0)
1075 player->underflow_enabled = 1;
1076
1124 if (UNIPERIF_TYPE_IS_TDM(player)) 1077 if (UNIPERIF_TYPE_IS_TDM(player))
1125 player->hw = &uni_tdm_hw; 1078 player->hw = &uni_tdm_hw;
1126 else 1079 else
@@ -1144,8 +1097,8 @@ int uni_player_init(struct platform_device *pdev,
1144 1097
1145 /* connect to I2S/TDM TX bus */ 1098 /* connect to I2S/TDM TX bus */
1146 if (player->valid_sel && 1099 if (player->valid_sel &&
1147 (player->info->id == UNIPERIF_PLAYER_I2S_OUT)) { 1100 (player->id == UNIPERIF_PLAYER_I2S_OUT)) {
1148 ret = regmap_field_write(player->valid_sel, player->info->id); 1101 ret = regmap_field_write(player->valid_sel, player->id);
1149 if (ret) { 1102 if (ret) {
1150 dev_err(player->dev, 1103 dev_err(player->dev,
1151 "%s: unable to connect to tdm bus", __func__); 1104 "%s: unable to connect to tdm bus", __func__);
diff --git a/sound/soc/sti/uniperif_reader.c b/sound/soc/sti/uniperif_reader.c
index eb74a328c928..0e1c3ee56675 100644
--- a/sound/soc/sti/uniperif_reader.c
+++ b/sound/soc/sti/uniperif_reader.c
@@ -13,6 +13,7 @@
13 13
14#include "uniperif.h" 14#include "uniperif.h"
15 15
16#define UNIPERIF_READER_I2S_IN 0 /* reader id connected to I2S/TDM TX bus */
16/* 17/*
17 * Note: snd_pcm_hardware is linked to DMA controller but is declared here to 18 * Note: snd_pcm_hardware is linked to DMA controller but is declared here to
18 * integrate unireader capability in term of rate and supported channels 19 * integrate unireader capability in term of rate and supported channels
@@ -195,7 +196,7 @@ static int uni_reader_prepare(struct snd_pcm_substream *substream,
195 } 196 }
196 197
197 /* Calculate transfer size (in fifo cells and bytes) for frame count */ 198 /* Calculate transfer size (in fifo cells and bytes) for frame count */
198 if (reader->info->type == SND_ST_UNIPERIF_TYPE_TDM) { 199 if (reader->type == SND_ST_UNIPERIF_TYPE_TDM) {
199 /* transfer size = unip frame size (in 32 bits FIFO cell) */ 200 /* transfer size = unip frame size (in 32 bits FIFO cell) */
200 transfer_size = 201 transfer_size =
201 sti_uniperiph_get_user_frame_size(runtime) / 4; 202 sti_uniperiph_get_user_frame_size(runtime) / 4;
@@ -280,7 +281,7 @@ static int uni_reader_prepare(struct snd_pcm_substream *substream,
280 SET_UNIPERIF_ITM_BSET_MEM_BLK_READ(reader); 281 SET_UNIPERIF_ITM_BSET_MEM_BLK_READ(reader);
281 282
282 /* Enable underflow recovery interrupts */ 283 /* Enable underflow recovery interrupts */
283 if (reader->info->underflow_enabled) { 284 if (reader->underflow_enabled) {
284 SET_UNIPERIF_ITM_BSET_UNDERFLOW_REC_DONE(reader); 285 SET_UNIPERIF_ITM_BSET_UNDERFLOW_REC_DONE(reader);
285 SET_UNIPERIF_ITM_BSET_UNDERFLOW_REC_FAILED(reader); 286 SET_UNIPERIF_ITM_BSET_UNDERFLOW_REC_FAILED(reader);
286 } 287 }
@@ -394,41 +395,6 @@ static void uni_reader_shutdown(struct snd_pcm_substream *substream,
394 } 395 }
395} 396}
396 397
397static int uni_reader_parse_dt(struct platform_device *pdev,
398 struct uniperif *reader)
399{
400 struct uniperif_info *info;
401 struct device_node *node = pdev->dev.of_node;
402 const char *mode;
403
404 /* Allocate memory for the info structure */
405 info = devm_kzalloc(&pdev->dev, sizeof(*info), GFP_KERNEL);
406 if (!info)
407 return -ENOMEM;
408
409 if (of_property_read_u32(node, "st,version", &reader->ver) ||
410 reader->ver == SND_ST_UNIPERIF_VERSION_UNKNOWN) {
411 dev_err(&pdev->dev, "Unknown uniperipheral version ");
412 return -EINVAL;
413 }
414
415 /* Read the device mode property */
416 if (of_property_read_string(node, "st,mode", &mode)) {
417 dev_err(&pdev->dev, "uniperipheral mode not defined");
418 return -EINVAL;
419 }
420
421 if (strcasecmp(mode, "tdm") == 0)
422 info->type = SND_ST_UNIPERIF_TYPE_TDM;
423 else
424 info->type = SND_ST_UNIPERIF_TYPE_PCM;
425
426 /* Save the info structure */
427 reader->info = info;
428
429 return 0;
430}
431
432static const struct snd_soc_dai_ops uni_reader_dai_ops = { 398static const struct snd_soc_dai_ops uni_reader_dai_ops = {
433 .startup = uni_reader_startup, 399 .startup = uni_reader_startup,
434 .shutdown = uni_reader_shutdown, 400 .shutdown = uni_reader_shutdown,
@@ -448,12 +414,6 @@ int uni_reader_init(struct platform_device *pdev,
448 reader->state = UNIPERIF_STATE_STOPPED; 414 reader->state = UNIPERIF_STATE_STOPPED;
449 reader->dai_ops = &uni_reader_dai_ops; 415 reader->dai_ops = &uni_reader_dai_ops;
450 416
451 ret = uni_reader_parse_dt(pdev, reader);
452 if (ret < 0) {
453 dev_err(reader->dev, "Failed to parse DeviceTree");
454 return ret;
455 }
456
457 if (UNIPERIF_TYPE_IS_TDM(reader)) 417 if (UNIPERIF_TYPE_IS_TDM(reader))
458 reader->hw = &uni_tdm_hw; 418 reader->hw = &uni_tdm_hw;
459 else 419 else
diff --git a/sound/soc/sunxi/Kconfig b/sound/soc/sunxi/Kconfig
index 2a954bd01fd8..dd2368297fd3 100644
--- a/sound/soc/sunxi/Kconfig
+++ b/sound/soc/sunxi/Kconfig
@@ -1,4 +1,5 @@
1menu "Allwinner SoC Audio support" 1menu "Allwinner SoC Audio support"
2 depends on ARCH_SUNXI || COMPILE_TEST
2 3
3config SND_SUN4I_CODEC 4config SND_SUN4I_CODEC
4 tristate "Allwinner A10 Codec Support" 5 tristate "Allwinner A10 Codec Support"
diff --git a/sound/soc/sunxi/sun4i-codec.c b/sound/soc/sunxi/sun4i-codec.c
index 44f170c73b06..e047ec06d538 100644
--- a/sound/soc/sunxi/sun4i-codec.c
+++ b/sound/soc/sunxi/sun4i-codec.c
@@ -96,8 +96,8 @@
96/* Other various ADC registers */ 96/* Other various ADC registers */
97#define SUN4I_CODEC_DAC_TXCNT (0x30) 97#define SUN4I_CODEC_DAC_TXCNT (0x30)
98#define SUN4I_CODEC_ADC_RXCNT (0x34) 98#define SUN4I_CODEC_ADC_RXCNT (0x34)
99#define SUN4I_CODEC_AC_SYS_VERI (0x38) 99#define SUN7I_CODEC_AC_DAC_CAL (0x38)
100#define SUN4I_CODEC_AC_MIC_PHONE_CAL (0x3c) 100#define SUN7I_CODEC_AC_MIC_PHONE_CAL (0x3c)
101 101
102struct sun4i_codec { 102struct sun4i_codec {
103 struct device *dev; 103 struct device *dev;
@@ -509,7 +509,7 @@ static const struct snd_kcontrol_new sun4i_codec_pa_mute =
509 509
510static DECLARE_TLV_DB_SCALE(sun4i_codec_pa_volume_scale, -6300, 100, 1); 510static DECLARE_TLV_DB_SCALE(sun4i_codec_pa_volume_scale, -6300, 100, 1);
511 511
512static const struct snd_kcontrol_new sun4i_codec_widgets[] = { 512static const struct snd_kcontrol_new sun4i_codec_controls[] = {
513 SOC_SINGLE_TLV("Power Amplifier Volume", SUN4I_CODEC_DAC_ACTL, 513 SOC_SINGLE_TLV("Power Amplifier Volume", SUN4I_CODEC_DAC_ACTL,
514 SUN4I_CODEC_DAC_ACTL_PA_VOL, 0x3F, 0, 514 SUN4I_CODEC_DAC_ACTL_PA_VOL, 0x3F, 0,
515 sun4i_codec_pa_volume_scale), 515 sun4i_codec_pa_volume_scale),
@@ -628,12 +628,14 @@ static const struct snd_soc_dapm_route sun4i_codec_codec_dapm_routes[] = {
628}; 628};
629 629
630static struct snd_soc_codec_driver sun4i_codec_codec = { 630static struct snd_soc_codec_driver sun4i_codec_codec = {
631 .controls = sun4i_codec_widgets, 631 .component_driver = {
632 .num_controls = ARRAY_SIZE(sun4i_codec_widgets), 632 .controls = sun4i_codec_controls,
633 .dapm_widgets = sun4i_codec_codec_dapm_widgets, 633 .num_controls = ARRAY_SIZE(sun4i_codec_controls),
634 .num_dapm_widgets = ARRAY_SIZE(sun4i_codec_codec_dapm_widgets), 634 .dapm_widgets = sun4i_codec_codec_dapm_widgets,
635 .dapm_routes = sun4i_codec_codec_dapm_routes, 635 .num_dapm_widgets = ARRAY_SIZE(sun4i_codec_codec_dapm_widgets),
636 .num_dapm_routes = ARRAY_SIZE(sun4i_codec_codec_dapm_routes), 636 .dapm_routes = sun4i_codec_codec_dapm_routes,
637 .num_dapm_routes = ARRAY_SIZE(sun4i_codec_codec_dapm_routes),
638 },
637}; 639};
638 640
639static const struct snd_soc_component_driver sun4i_codec_component = { 641static const struct snd_soc_component_driver sun4i_codec_component = {
@@ -680,12 +682,37 @@ static const struct regmap_config sun4i_codec_regmap_config = {
680 .reg_bits = 32, 682 .reg_bits = 32,
681 .reg_stride = 4, 683 .reg_stride = 4,
682 .val_bits = 32, 684 .val_bits = 32,
683 .max_register = SUN4I_CODEC_AC_MIC_PHONE_CAL, 685 .max_register = SUN4I_CODEC_ADC_RXCNT,
686};
687
688static const struct regmap_config sun7i_codec_regmap_config = {
689 .reg_bits = 32,
690 .reg_stride = 4,
691 .val_bits = 32,
692 .max_register = SUN7I_CODEC_AC_MIC_PHONE_CAL,
693};
694
695struct sun4i_codec_quirks {
696 const struct regmap_config *regmap_config;
697};
698
699static const struct sun4i_codec_quirks sun4i_codec_quirks = {
700 .regmap_config = &sun4i_codec_regmap_config,
701};
702
703static const struct sun4i_codec_quirks sun7i_codec_quirks = {
704 .regmap_config = &sun7i_codec_regmap_config,
684}; 705};
685 706
686static const struct of_device_id sun4i_codec_of_match[] = { 707static const struct of_device_id sun4i_codec_of_match[] = {
687 { .compatible = "allwinner,sun4i-a10-codec" }, 708 {
688 { .compatible = "allwinner,sun7i-a20-codec" }, 709 .compatible = "allwinner,sun4i-a10-codec",
710 .data = &sun4i_codec_quirks,
711 },
712 {
713 .compatible = "allwinner,sun7i-a20-codec",
714 .data = &sun7i_codec_quirks,
715 },
689 {} 716 {}
690}; 717};
691MODULE_DEVICE_TABLE(of, sun4i_codec_of_match); 718MODULE_DEVICE_TABLE(of, sun4i_codec_of_match);
@@ -758,6 +785,7 @@ static int sun4i_codec_probe(struct platform_device *pdev)
758{ 785{
759 struct snd_soc_card *card; 786 struct snd_soc_card *card;
760 struct sun4i_codec *scodec; 787 struct sun4i_codec *scodec;
788 const struct sun4i_codec_quirks *quirks;
761 struct resource *res; 789 struct resource *res;
762 void __iomem *base; 790 void __iomem *base;
763 int ret; 791 int ret;
@@ -775,8 +803,14 @@ static int sun4i_codec_probe(struct platform_device *pdev)
775 return PTR_ERR(base); 803 return PTR_ERR(base);
776 } 804 }
777 805
806 quirks = of_device_get_match_data(&pdev->dev);
807 if (quirks == NULL) {
808 dev_err(&pdev->dev, "Failed to determine the quirks to use\n");
809 return -ENODEV;
810 }
811
778 scodec->regmap = devm_regmap_init_mmio(&pdev->dev, base, 812 scodec->regmap = devm_regmap_init_mmio(&pdev->dev, base,
779 &sun4i_codec_regmap_config); 813 quirks->regmap_config);
780 if (IS_ERR(scodec->regmap)) { 814 if (IS_ERR(scodec->regmap)) {
781 dev_err(&pdev->dev, "Failed to create our regmap\n"); 815 dev_err(&pdev->dev, "Failed to create our regmap\n");
782 return PTR_ERR(scodec->regmap); 816 return PTR_ERR(scodec->regmap);
diff --git a/sound/soc/sunxi/sun4i-spdif.c b/sound/soc/sunxi/sun4i-spdif.c
index 0b04fb02125c..88fbb3a1e660 100644
--- a/sound/soc/sunxi/sun4i-spdif.c
+++ b/sound/soc/sunxi/sun4i-spdif.c
@@ -29,6 +29,7 @@
29#include <linux/module.h> 29#include <linux/module.h>
30#include <linux/platform_device.h> 30#include <linux/platform_device.h>
31#include <linux/pm_runtime.h> 31#include <linux/pm_runtime.h>
32#include <linux/reset.h>
32#include <sound/dmaengine_pcm.h> 33#include <sound/dmaengine_pcm.h>
33#include <sound/pcm_params.h> 34#include <sound/pcm_params.h>
34#include <sound/soc.h> 35#include <sound/soc.h>
@@ -162,6 +163,7 @@ struct sun4i_spdif_dev {
162 struct platform_device *pdev; 163 struct platform_device *pdev;
163 struct clk *spdif_clk; 164 struct clk *spdif_clk;
164 struct clk *apb_clk; 165 struct clk *apb_clk;
166 struct reset_control *rst;
165 struct snd_soc_dai_driver cpu_dai_drv; 167 struct snd_soc_dai_driver cpu_dai_drv;
166 struct regmap *regmap; 168 struct regmap *regmap;
167 struct snd_dmaengine_dai_dma_data dma_params_tx; 169 struct snd_dmaengine_dai_dma_data dma_params_tx;
@@ -411,6 +413,7 @@ static const struct snd_soc_dapm_route dit_routes[] = {
411 413
412static const struct of_device_id sun4i_spdif_of_match[] = { 414static const struct of_device_id sun4i_spdif_of_match[] = {
413 { .compatible = "allwinner,sun4i-a10-spdif", }, 415 { .compatible = "allwinner,sun4i-a10-spdif", },
416 { .compatible = "allwinner,sun6i-a31-spdif", },
414 { /* sentinel */ } 417 { /* sentinel */ }
415}; 418};
416MODULE_DEVICE_TABLE(of, sun4i_spdif_of_match); 419MODULE_DEVICE_TABLE(of, sun4i_spdif_of_match);
@@ -482,11 +485,23 @@ static int sun4i_spdif_probe(struct platform_device *pdev)
482 } 485 }
483 486
484 host->dma_params_tx.addr = res->start + SUN4I_SPDIF_TXFIFO; 487 host->dma_params_tx.addr = res->start + SUN4I_SPDIF_TXFIFO;
485 host->dma_params_tx.maxburst = 4; 488 host->dma_params_tx.maxburst = 8;
486 host->dma_params_tx.addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES; 489 host->dma_params_tx.addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES;
487 490
488 platform_set_drvdata(pdev, host); 491 platform_set_drvdata(pdev, host);
489 492
493 if (of_device_is_compatible(pdev->dev.of_node,
494 "allwinner,sun6i-a31-spdif")) {
495 host->rst = devm_reset_control_get_optional(&pdev->dev, NULL);
496 if (IS_ERR(host->rst) && PTR_ERR(host->rst) == -EPROBE_DEFER) {
497 ret = -EPROBE_DEFER;
498 dev_err(&pdev->dev, "Failed to get reset: %d\n", ret);
499 goto err_disable_apb_clk;
500 }
501 if (!IS_ERR(host->rst))
502 reset_control_deassert(host->rst);
503 }
504
490 ret = devm_snd_soc_register_component(&pdev->dev, 505 ret = devm_snd_soc_register_component(&pdev->dev,
491 &sun4i_spdif_component, &sun4i_spdif_dai, 1); 506 &sun4i_spdif_component, &sun4i_spdif_dai, 1);
492 if (ret) 507 if (ret)
diff --git a/sound/soc/tegra/Kconfig b/sound/soc/tegra/Kconfig
index a6768f832c6f..efbe8d4c019e 100644
--- a/sound/soc/tegra/Kconfig
+++ b/sound/soc/tegra/Kconfig
@@ -138,3 +138,14 @@ config SND_SOC_TEGRA_RT5677
138 help 138 help
139 Say Y or M here if you want to add support for SoC audio on Tegra 139 Say Y or M here if you want to add support for SoC audio on Tegra
140 boards using the RT5677 codec, such as Ryu. 140 boards using the RT5677 codec, such as Ryu.
141
142config SND_SOC_TEGRA_SGTL5000
143 tristate "SoC Audio support for Tegra boards using a SGTL5000 codec"
144 depends on SND_SOC_TEGRA && I2C && GPIOLIB
145 select SND_SOC_TEGRA20_I2S if ARCH_TEGRA_2x_SOC
146 select SND_SOC_TEGRA30_I2S if ARCH_TEGRA_3x_SOC
147 select SND_SOC_SGTL5000
148 help
149 Say Y or M here if you want to add support for SoC audio on Tegra
150 boards using the SGTL5000 codec, such as Apalis T30, Apalis TK1 or
151 Colibri T30.
diff --git a/sound/soc/tegra/Makefile b/sound/soc/tegra/Makefile
index 9171655ad843..f214a3fd0024 100644
--- a/sound/soc/tegra/Makefile
+++ b/sound/soc/tegra/Makefile
@@ -26,6 +26,7 @@ snd-soc-tegra-wm9712-objs := tegra_wm9712.o
26snd-soc-tegra-trimslice-objs := trimslice.o 26snd-soc-tegra-trimslice-objs := trimslice.o
27snd-soc-tegra-alc5632-objs := tegra_alc5632.o 27snd-soc-tegra-alc5632-objs := tegra_alc5632.o
28snd-soc-tegra-max98090-objs := tegra_max98090.o 28snd-soc-tegra-max98090-objs := tegra_max98090.o
29snd-soc-tegra-sgtl5000-objs := tegra_sgtl5000.o
29 30
30obj-$(CONFIG_SND_SOC_TEGRA_RT5640) += snd-soc-tegra-rt5640.o 31obj-$(CONFIG_SND_SOC_TEGRA_RT5640) += snd-soc-tegra-rt5640.o
31obj-$(CONFIG_SND_SOC_TEGRA_RT5677) += snd-soc-tegra-rt5677.o 32obj-$(CONFIG_SND_SOC_TEGRA_RT5677) += snd-soc-tegra-rt5677.o
@@ -35,3 +36,4 @@ obj-$(CONFIG_SND_SOC_TEGRA_WM9712) += snd-soc-tegra-wm9712.o
35obj-$(CONFIG_SND_SOC_TEGRA_TRIMSLICE) += snd-soc-tegra-trimslice.o 36obj-$(CONFIG_SND_SOC_TEGRA_TRIMSLICE) += snd-soc-tegra-trimslice.o
36obj-$(CONFIG_SND_SOC_TEGRA_ALC5632) += snd-soc-tegra-alc5632.o 37obj-$(CONFIG_SND_SOC_TEGRA_ALC5632) += snd-soc-tegra-alc5632.o
37obj-$(CONFIG_SND_SOC_TEGRA_MAX98090) += snd-soc-tegra-max98090.o 38obj-$(CONFIG_SND_SOC_TEGRA_MAX98090) += snd-soc-tegra-max98090.o
39obj-$(CONFIG_SND_SOC_TEGRA_SGTL5000) += snd-soc-tegra-sgtl5000.o \ No newline at end of file
diff --git a/sound/soc/tegra/tegra_rt5640.c b/sound/soc/tegra/tegra_rt5640.c
index 773daecaa5e8..e5ef4e9c4ac5 100644
--- a/sound/soc/tegra/tegra_rt5640.c
+++ b/sound/soc/tegra/tegra_rt5640.c
@@ -1,5 +1,5 @@
1/* 1/*
2* tegra_rt5640.c - Tegra machine ASoC driver for boards using WM8903 codec. 2* tegra_rt5640.c - Tegra machine ASoC driver for boards using RT5640 codec.
3 * 3 *
4 * Copyright (c) 2013, NVIDIA CORPORATION. All rights reserved. 4 * Copyright (c) 2013, NVIDIA CORPORATION. All rights reserved.
5 * 5 *
diff --git a/sound/soc/tegra/tegra_sgtl5000.c b/sound/soc/tegra/tegra_sgtl5000.c
new file mode 100644
index 000000000000..1e76869dd488
--- /dev/null
+++ b/sound/soc/tegra/tegra_sgtl5000.c
@@ -0,0 +1,212 @@
1/*
2 * tegra_sgtl5000.c - Tegra machine ASoC driver for boards using SGTL5000 codec
3 *
4 * Author: Marcel Ziswiler <marcel@ziswiler.com>
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms and conditions of the GNU General Public License,
8 * version 2, as published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
13 * more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 *
18 * Based on code copyright/by:
19 *
20 * Copyright (C) 2010-2012 - NVIDIA, Inc.
21 * (c) 2009, 2010 Nvidia Graphics Pvt. Ltd.
22 * Copyright 2007 Wolfson Microelectronics PLC.
23 */
24
25#include <linux/module.h>
26#include <linux/platform_device.h>
27#include <linux/slab.h>
28#include <linux/gpio.h>
29#include <linux/of_gpio.h>
30
31#include <sound/core.h>
32#include <sound/pcm.h>
33#include <sound/pcm_params.h>
34#include <sound/soc.h>
35
36#include "../codecs/sgtl5000.h"
37
38#include "tegra_asoc_utils.h"
39
40#define DRV_NAME "tegra-snd-sgtl5000"
41
42struct tegra_sgtl5000 {
43 struct tegra_asoc_utils_data util_data;
44};
45
46static int tegra_sgtl5000_hw_params(struct snd_pcm_substream *substream,
47 struct snd_pcm_hw_params *params)
48{
49 struct snd_soc_pcm_runtime *rtd = substream->private_data;
50 struct snd_soc_dai *codec_dai = rtd->codec_dai;
51 struct snd_soc_card *card = rtd->card;
52 struct tegra_sgtl5000 *machine = snd_soc_card_get_drvdata(card);
53 int srate, mclk;
54 int err;
55
56 srate = params_rate(params);
57 switch (srate) {
58 case 11025:
59 case 22050:
60 case 44100:
61 case 88200:
62 mclk = 11289600;
63 break;
64 default:
65 mclk = 12288000;
66 break;
67 }
68
69 err = tegra_asoc_utils_set_rate(&machine->util_data, srate, mclk);
70 if (err < 0) {
71 dev_err(card->dev, "Can't configure clocks\n");
72 return err;
73 }
74
75 err = snd_soc_dai_set_sysclk(codec_dai, SGTL5000_SYSCLK, mclk,
76 SND_SOC_CLOCK_IN);
77 if (err < 0) {
78 dev_err(card->dev, "codec_dai clock not set\n");
79 return err;
80 }
81
82 return 0;
83}
84
85static struct snd_soc_ops tegra_sgtl5000_ops = {
86 .hw_params = tegra_sgtl5000_hw_params,
87};
88
89static const struct snd_soc_dapm_widget tegra_sgtl5000_dapm_widgets[] = {
90 SND_SOC_DAPM_HP("Headphone Jack", NULL),
91 SND_SOC_DAPM_LINE("Line In Jack", NULL),
92 SND_SOC_DAPM_MIC("Mic Jack", NULL),
93};
94
95static struct snd_soc_dai_link tegra_sgtl5000_dai = {
96 .name = "sgtl5000",
97 .stream_name = "HiFi",
98 .codec_dai_name = "sgtl5000",
99 .ops = &tegra_sgtl5000_ops,
100 .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
101 SND_SOC_DAIFMT_CBS_CFS,
102};
103
104static struct snd_soc_card snd_soc_tegra_sgtl5000 = {
105 .name = "tegra-sgtl5000",
106 .owner = THIS_MODULE,
107 .dai_link = &tegra_sgtl5000_dai,
108 .num_links = 1,
109 .dapm_widgets = tegra_sgtl5000_dapm_widgets,
110 .num_dapm_widgets = ARRAY_SIZE(tegra_sgtl5000_dapm_widgets),
111 .fully_routed = true,
112};
113
114static int tegra_sgtl5000_driver_probe(struct platform_device *pdev)
115{
116 struct device_node *np = pdev->dev.of_node;
117 struct snd_soc_card *card = &snd_soc_tegra_sgtl5000;
118 struct tegra_sgtl5000 *machine;
119 int ret;
120
121 machine = devm_kzalloc(&pdev->dev, sizeof(struct tegra_sgtl5000),
122 GFP_KERNEL);
123 if (!machine) {
124 dev_err(&pdev->dev, "Can't allocate tegra_sgtl5000 struct\n");
125 return -ENOMEM;
126 }
127
128 card->dev = &pdev->dev;
129 platform_set_drvdata(pdev, card);
130 snd_soc_card_set_drvdata(card, machine);
131
132 ret = snd_soc_of_parse_card_name(card, "nvidia,model");
133 if (ret)
134 goto err;
135
136 ret = snd_soc_of_parse_audio_routing(card, "nvidia,audio-routing");
137 if (ret)
138 goto err;
139
140 tegra_sgtl5000_dai.codec_of_node = of_parse_phandle(np,
141 "nvidia,audio-codec", 0);
142 if (!tegra_sgtl5000_dai.codec_of_node) {
143 dev_err(&pdev->dev,
144 "Property 'nvidia,audio-codec' missing or invalid\n");
145 ret = -EINVAL;
146 goto err;
147 }
148
149 tegra_sgtl5000_dai.cpu_of_node = of_parse_phandle(np,
150 "nvidia,i2s-controller", 0);
151 if (!tegra_sgtl5000_dai.cpu_of_node) {
152 dev_err(&pdev->dev,
153 "Property 'nvidia,i2s-controller' missing/invalid\n");
154 ret = -EINVAL;
155 goto err;
156 }
157
158 tegra_sgtl5000_dai.platform_of_node = tegra_sgtl5000_dai.cpu_of_node;
159
160 ret = tegra_asoc_utils_init(&machine->util_data, &pdev->dev);
161 if (ret)
162 goto err;
163
164 ret = snd_soc_register_card(card);
165 if (ret) {
166 dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n",
167 ret);
168 goto err_fini_utils;
169 }
170
171 return 0;
172
173err_fini_utils:
174 tegra_asoc_utils_fini(&machine->util_data);
175err:
176 return ret;
177}
178
179static int tegra_sgtl5000_driver_remove(struct platform_device *pdev)
180{
181 struct snd_soc_card *card = platform_get_drvdata(pdev);
182 struct tegra_sgtl5000 *machine = snd_soc_card_get_drvdata(card);
183 int ret;
184
185 ret = snd_soc_unregister_card(card);
186
187 tegra_asoc_utils_fini(&machine->util_data);
188
189 return ret;
190}
191
192static const struct of_device_id tegra_sgtl5000_of_match[] = {
193 { .compatible = "nvidia,tegra-audio-sgtl5000", },
194 { /* sentinel */ },
195};
196
197static struct platform_driver tegra_sgtl5000_driver = {
198 .driver = {
199 .name = DRV_NAME,
200 .pm = &snd_soc_pm_ops,
201 .of_match_table = tegra_sgtl5000_of_match,
202 },
203 .probe = tegra_sgtl5000_driver_probe,
204 .remove = tegra_sgtl5000_driver_remove,
205};
206module_platform_driver(tegra_sgtl5000_driver);
207
208MODULE_AUTHOR("Marcel Ziswiler <marcel@ziswiler.com>");
209MODULE_DESCRIPTION("Tegra SGTL5000 machine ASoC driver");
210MODULE_LICENSE("GPL v2");
211MODULE_ALIAS("platform:" DRV_NAME);
212MODULE_DEVICE_TABLE(of, tegra_sgtl5000_of_match);
diff --git a/sound/soc/ux500/ux500_msp_dai.c b/sound/soc/ux500/ux500_msp_dai.c
index 6d5698b25bd4..b343efd9be5b 100644
--- a/sound/soc/ux500/ux500_msp_dai.c
+++ b/sound/soc/ux500/ux500_msp_dai.c
@@ -187,7 +187,7 @@ static int setup_clocking(struct snd_soc_dai *dai,
187 187
188 default: 188 default:
189 dev_err(dai->dev, 189 dev_err(dai->dev,
190 "%s: Error: Unsopported inversion (fmt = 0x%x)!\n", 190 "%s: Error: Unsupported inversion (fmt = 0x%x)!\n",
191 __func__, fmt); 191 __func__, fmt);
192 192
193 return -EINVAL; 193 return -EINVAL;
@@ -218,7 +218,7 @@ static int setup_clocking(struct snd_soc_dai *dai,
218 break; 218 break;
219 219
220 default: 220 default:
221 dev_err(dai->dev, "%s: Error: Unsopported master (fmt = 0x%x)!\n", 221 dev_err(dai->dev, "%s: Error: Unsupported master (fmt = 0x%x)!\n",
222 __func__, fmt); 222 __func__, fmt);
223 223
224 return -EINVAL; 224 return -EINVAL;
@@ -374,7 +374,7 @@ static int setup_msp_config(struct snd_pcm_substream *substream,
374 break; 374 break;
375 375
376 default: 376 default:
377 dev_err(dai->dev, "%s: Error: Unsopported format (%d)!\n", 377 dev_err(dai->dev, "%s: Error: Unsupported format (%d)!\n",
378 __func__, fmt); 378 __func__, fmt);
379 return -EINVAL; 379 return -EINVAL;
380 } 380 }
diff --git a/sound/usb/caiaq/audio.c b/sound/usb/caiaq/audio.c
index 327f8642ca80..8f66ba730d69 100644
--- a/sound/usb/caiaq/audio.c
+++ b/sound/usb/caiaq/audio.c
@@ -739,7 +739,6 @@ static struct urb **alloc_urbs(struct snd_usb_caiaqdev *cdev, int dir, int *ret)
739 for (i = 0; i < N_URBS; i++) { 739 for (i = 0; i < N_URBS; i++) {
740 urbs[i] = usb_alloc_urb(FRAMES_PER_URB, GFP_KERNEL); 740 urbs[i] = usb_alloc_urb(FRAMES_PER_URB, GFP_KERNEL);
741 if (!urbs[i]) { 741 if (!urbs[i]) {
742 dev_err(dev, "unable to usb_alloc_urb(), OOM!?\n");
743 *ret = -ENOMEM; 742 *ret = -ENOMEM;
744 return urbs; 743 return urbs;
745 } 744 }
diff --git a/sound/usb/card.h b/sound/usb/card.h
index 71778ca4b26a..111b0f009afa 100644
--- a/sound/usb/card.h
+++ b/sound/usb/card.h
@@ -92,7 +92,7 @@ struct snd_usb_endpoint {
92 unsigned int curframesize; /* current packet size in frames (for capture) */ 92 unsigned int curframesize; /* current packet size in frames (for capture) */
93 unsigned int syncmaxsize; /* sync endpoint packet size */ 93 unsigned int syncmaxsize; /* sync endpoint packet size */
94 unsigned int fill_max:1; /* fill max packet size always */ 94 unsigned int fill_max:1; /* fill max packet size always */
95 unsigned int udh01_fb_quirk:1; /* corrupted feedback data */ 95 unsigned int tenor_fb_quirk:1; /* corrupted feedback data */
96 unsigned int datainterval; /* log_2 of data packet interval */ 96 unsigned int datainterval; /* log_2 of data packet interval */
97 unsigned int syncinterval; /* P for adaptive mode, 0 otherwise */ 97 unsigned int syncinterval; /* P for adaptive mode, 0 otherwise */
98 unsigned char silence_value; 98 unsigned char silence_value;
diff --git a/sound/usb/endpoint.c b/sound/usb/endpoint.c
index c07a7eda42a2..c470251cea4b 100644
--- a/sound/usb/endpoint.c
+++ b/sound/usb/endpoint.c
@@ -502,10 +502,6 @@ struct snd_usb_endpoint *snd_usb_add_endpoint(struct snd_usb_audio *chip,
502 ep->syncinterval = 3; 502 ep->syncinterval = 3;
503 503
504 ep->syncmaxsize = le16_to_cpu(get_endpoint(alts, 1)->wMaxPacketSize); 504 ep->syncmaxsize = le16_to_cpu(get_endpoint(alts, 1)->wMaxPacketSize);
505
506 if (chip->usb_id == USB_ID(0x0644, 0x8038) /* TEAC UD-H01 */ &&
507 ep->syncmaxsize == 4)
508 ep->udh01_fb_quirk = 1;
509 } 505 }
510 506
511 list_add_tail(&ep->list, &chip->ep_list); 507 list_add_tail(&ep->list, &chip->ep_list);
@@ -1171,15 +1167,16 @@ void snd_usb_handle_sync_urb(struct snd_usb_endpoint *ep,
1171 if (f == 0) 1167 if (f == 0)
1172 return; 1168 return;
1173 1169
1174 if (unlikely(sender->udh01_fb_quirk)) { 1170 if (unlikely(sender->tenor_fb_quirk)) {
1175 /* 1171 /*
1176 * The TEAC UD-H01 firmware sometimes changes the feedback value 1172 * Devices based on Tenor 8802 chipsets (TEAC UD-H01
1173 * and others) sometimes change the feedback value
1177 * by +/- 0x1.0000. 1174 * by +/- 0x1.0000.
1178 */ 1175 */
1179 if (f < ep->freqn - 0x8000) 1176 if (f < ep->freqn - 0x8000)
1180 f += 0x10000; 1177 f += 0xf000;
1181 else if (f > ep->freqn + 0x8000) 1178 else if (f > ep->freqn + 0x8000)
1182 f -= 0x10000; 1179 f -= 0xf000;
1183 } else if (unlikely(ep->freqshift == INT_MIN)) { 1180 } else if (unlikely(ep->freqshift == INT_MIN)) {
1184 /* 1181 /*
1185 * The first time we see a feedback value, determine its format 1182 * The first time we see a feedback value, determine its format
diff --git a/sound/usb/format.c b/sound/usb/format.c
index 789d19ec035d..2c44386e5569 100644
--- a/sound/usb/format.c
+++ b/sound/usb/format.c
@@ -176,10 +176,8 @@ static int parse_audio_format_rates_v1(struct snd_usb_audio *chip, struct audiof
176 int r, idx; 176 int r, idx;
177 177
178 fp->rate_table = kmalloc(sizeof(int) * nr_rates, GFP_KERNEL); 178 fp->rate_table = kmalloc(sizeof(int) * nr_rates, GFP_KERNEL);
179 if (fp->rate_table == NULL) { 179 if (fp->rate_table == NULL)
180 usb_audio_err(chip, "cannot malloc\n");
181 return -ENOMEM; 180 return -ENOMEM;
182 }
183 181
184 fp->nr_rates = 0; 182 fp->nr_rates = 0;
185 fp->rate_min = fp->rate_max = 0; 183 fp->rate_min = fp->rate_max = 0;
diff --git a/sound/usb/line6/Kconfig b/sound/usb/line6/Kconfig
index f4585d378ef3..39b400392d71 100644
--- a/sound/usb/line6/Kconfig
+++ b/sound/usb/line6/Kconfig
@@ -2,6 +2,7 @@ config SND_USB_LINE6
2 tristate 2 tristate
3 select SND_RAWMIDI 3 select SND_RAWMIDI
4 select SND_PCM 4 select SND_PCM
5 select SND_HWDEP
5 6
6config SND_USB_POD 7config SND_USB_POD
7 tristate "Line 6 POD USB support" 8 tristate "Line 6 POD USB support"
@@ -21,10 +22,10 @@ config SND_USB_POD
21 re-amping) 22 re-amping)
22 23
23config SND_USB_PODHD 24config SND_USB_PODHD
24 tristate "Line 6 POD HD300/400/500 USB support" 25 tristate "Line 6 POD X3/HD300/400/500 USB support"
25 select SND_USB_LINE6 26 select SND_USB_LINE6
26 help 27 help
27 This is a driver for POD HD300, 400 and 500 devices. 28 This is a driver for POD X3, HD300, 400 and 500 devices.
28 29
29config SND_USB_TONEPORT 30config SND_USB_TONEPORT
30 tristate "TonePort GX, UX1 and UX2 USB support" 31 tristate "TonePort GX, UX1 and UX2 USB support"
diff --git a/sound/usb/line6/capture.c b/sound/usb/line6/capture.c
index f518fbbe88de..7c812565f90d 100644
--- a/sound/usb/line6/capture.c
+++ b/sound/usb/line6/capture.c
@@ -29,10 +29,10 @@ static int submit_audio_in_urb(struct snd_line6_pcm *line6pcm)
29 int ret; 29 int ret;
30 struct urb *urb_in; 30 struct urb *urb_in;
31 31
32 index = 32 index = find_first_zero_bit(&line6pcm->in.active_urbs,
33 find_first_zero_bit(&line6pcm->in.active_urbs, LINE6_ISO_BUFFERS); 33 line6pcm->line6->iso_buffers);
34 34
35 if (index < 0 || index >= LINE6_ISO_BUFFERS) { 35 if (index < 0 || index >= line6pcm->line6->iso_buffers) {
36 dev_err(line6pcm->line6->ifcdev, "no free URB found\n"); 36 dev_err(line6pcm->line6->ifcdev, "no free URB found\n");
37 return -EINVAL; 37 return -EINVAL;
38 } 38 }
@@ -44,13 +44,13 @@ static int submit_audio_in_urb(struct snd_line6_pcm *line6pcm)
44 struct usb_iso_packet_descriptor *fin = 44 struct usb_iso_packet_descriptor *fin =
45 &urb_in->iso_frame_desc[i]; 45 &urb_in->iso_frame_desc[i];
46 fin->offset = urb_size; 46 fin->offset = urb_size;
47 fin->length = line6pcm->max_packet_size; 47 fin->length = line6pcm->max_packet_size_in;
48 urb_size += line6pcm->max_packet_size; 48 urb_size += line6pcm->max_packet_size_in;
49 } 49 }
50 50
51 urb_in->transfer_buffer = 51 urb_in->transfer_buffer =
52 line6pcm->in.buffer + 52 line6pcm->in.buffer +
53 index * LINE6_ISO_PACKETS * line6pcm->max_packet_size; 53 index * LINE6_ISO_PACKETS * line6pcm->max_packet_size_in;
54 urb_in->transfer_buffer_length = urb_size; 54 urb_in->transfer_buffer_length = urb_size;
55 urb_in->context = line6pcm; 55 urb_in->context = line6pcm;
56 56
@@ -73,7 +73,7 @@ int line6_submit_audio_in_all_urbs(struct snd_line6_pcm *line6pcm)
73{ 73{
74 int ret = 0, i; 74 int ret = 0, i;
75 75
76 for (i = 0; i < LINE6_ISO_BUFFERS; ++i) { 76 for (i = 0; i < line6pcm->line6->iso_buffers; ++i) {
77 ret = submit_audio_in_urb(line6pcm); 77 ret = submit_audio_in_urb(line6pcm);
78 if (ret < 0) 78 if (ret < 0)
79 break; 79 break;
@@ -90,7 +90,9 @@ void line6_capture_copy(struct snd_line6_pcm *line6pcm, char *fbuf, int fsize)
90 struct snd_pcm_substream *substream = 90 struct snd_pcm_substream *substream =
91 get_substream(line6pcm, SNDRV_PCM_STREAM_CAPTURE); 91 get_substream(line6pcm, SNDRV_PCM_STREAM_CAPTURE);
92 struct snd_pcm_runtime *runtime = substream->runtime; 92 struct snd_pcm_runtime *runtime = substream->runtime;
93 const int bytes_per_frame = line6pcm->properties->bytes_per_frame; 93 const int bytes_per_frame =
94 line6pcm->properties->bytes_per_channel *
95 line6pcm->properties->capture_hw.channels_max;
94 int frames = fsize / bytes_per_frame; 96 int frames = fsize / bytes_per_frame;
95 97
96 if (runtime == NULL) 98 if (runtime == NULL)
@@ -154,7 +156,7 @@ static void audio_in_callback(struct urb *urb)
154 line6pcm->in.last_frame = urb->start_frame; 156 line6pcm->in.last_frame = urb->start_frame;
155 157
156 /* find index of URB */ 158 /* find index of URB */
157 for (index = 0; index < LINE6_ISO_BUFFERS; ++index) 159 for (index = 0; index < line6pcm->line6->iso_buffers; ++index)
158 if (urb == line6pcm->in.urbs[index]) 160 if (urb == line6pcm->in.urbs[index])
159 break; 161 break;
160 162
@@ -173,17 +175,27 @@ static void audio_in_callback(struct urb *urb)
173 fbuf = urb->transfer_buffer + fin->offset; 175 fbuf = urb->transfer_buffer + fin->offset;
174 fsize = fin->actual_length; 176 fsize = fin->actual_length;
175 177
176 if (fsize > line6pcm->max_packet_size) { 178 if (fsize > line6pcm->max_packet_size_in) {
177 dev_err(line6pcm->line6->ifcdev, 179 dev_err(line6pcm->line6->ifcdev,
178 "driver and/or device bug: packet too large (%d > %d)\n", 180 "driver and/or device bug: packet too large (%d > %d)\n",
179 fsize, line6pcm->max_packet_size); 181 fsize, line6pcm->max_packet_size_in);
180 } 182 }
181 183
182 length += fsize; 184 length += fsize;
183 185
184 /* the following assumes LINE6_ISO_PACKETS == 1: */ 186 BUILD_BUG_ON_MSG(LINE6_ISO_PACKETS != 1,
187 "The following code assumes LINE6_ISO_PACKETS == 1");
188 /* TODO:
189 * Also, if iso_buffers != 2, the prev frame is almost random at
190 * playback side.
191 * This needs to be redesigned. It should be "stable", but we may
192 * experience sync problems on such high-speed configs.
193 */
194
185 line6pcm->prev_fbuf = fbuf; 195 line6pcm->prev_fbuf = fbuf;
186 line6pcm->prev_fsize = fsize; 196 line6pcm->prev_fsize = fsize /
197 (line6pcm->properties->bytes_per_channel *
198 line6pcm->properties->capture_hw.channels_max);
187 199
188 if (!test_bit(LINE6_STREAM_IMPULSE, &line6pcm->in.running) && 200 if (!test_bit(LINE6_STREAM_IMPULSE, &line6pcm->in.running) &&
189 test_bit(LINE6_STREAM_PCM, &line6pcm->in.running) && 201 test_bit(LINE6_STREAM_PCM, &line6pcm->in.running) &&
@@ -220,6 +232,8 @@ static int snd_line6_capture_open(struct snd_pcm_substream *substream)
220 if (err < 0) 232 if (err < 0)
221 return err; 233 return err;
222 234
235 line6_pcm_acquire(line6pcm, LINE6_STREAM_CAPTURE_HELPER, false);
236
223 runtime->hw = line6pcm->properties->capture_hw; 237 runtime->hw = line6pcm->properties->capture_hw;
224 return 0; 238 return 0;
225} 239}
@@ -227,6 +241,9 @@ static int snd_line6_capture_open(struct snd_pcm_substream *substream)
227/* close capture callback */ 241/* close capture callback */
228static int snd_line6_capture_close(struct snd_pcm_substream *substream) 242static int snd_line6_capture_close(struct snd_pcm_substream *substream)
229{ 243{
244 struct snd_line6_pcm *line6pcm = snd_pcm_substream_chip(substream);
245
246 line6_pcm_release(line6pcm, LINE6_STREAM_CAPTURE_HELPER);
230 return 0; 247 return 0;
231} 248}
232 249
@@ -247,8 +264,13 @@ int line6_create_audio_in_urbs(struct snd_line6_pcm *line6pcm)
247 struct usb_line6 *line6 = line6pcm->line6; 264 struct usb_line6 *line6 = line6pcm->line6;
248 int i; 265 int i;
249 266
267 line6pcm->in.urbs = kzalloc(
268 sizeof(struct urb *) * line6->iso_buffers, GFP_KERNEL);
269 if (line6pcm->in.urbs == NULL)
270 return -ENOMEM;
271
250 /* create audio URBs and fill in constant values: */ 272 /* create audio URBs and fill in constant values: */
251 for (i = 0; i < LINE6_ISO_BUFFERS; ++i) { 273 for (i = 0; i < line6->iso_buffers; ++i) {
252 struct urb *urb; 274 struct urb *urb;
253 275
254 /* URB for audio in: */ 276 /* URB for audio in: */
diff --git a/sound/usb/line6/driver.c b/sound/usb/line6/driver.c
index 81b7da8e56d3..14e587e70655 100644
--- a/sound/usb/line6/driver.c
+++ b/sound/usb/line6/driver.c
@@ -17,6 +17,7 @@
17 17
18#include <sound/core.h> 18#include <sound/core.h>
19#include <sound/initval.h> 19#include <sound/initval.h>
20#include <sound/hwdep.h>
20 21
21#include "capture.h" 22#include "capture.h"
22#include "driver.h" 23#include "driver.h"
@@ -29,7 +30,7 @@
29/* 30/*
30 This is Line 6's MIDI manufacturer ID. 31 This is Line 6's MIDI manufacturer ID.
31*/ 32*/
32const unsigned char line6_midi_id[] = { 33const unsigned char line6_midi_id[3] = {
33 0x00, 0x01, 0x0c 34 0x00, 0x01, 0x0c
34}; 35};
35EXPORT_SYMBOL_GPL(line6_midi_id); 36EXPORT_SYMBOL_GPL(line6_midi_id);
@@ -66,10 +67,17 @@ static int line6_start_listen(struct usb_line6 *line6)
66{ 67{
67 int err; 68 int err;
68 69
69 usb_fill_int_urb(line6->urb_listen, line6->usbdev, 70 if (line6->properties->capabilities & LINE6_CAP_CONTROL_MIDI) {
70 usb_rcvintpipe(line6->usbdev, line6->properties->ep_ctrl_r), 71 usb_fill_int_urb(line6->urb_listen, line6->usbdev,
71 line6->buffer_listen, LINE6_BUFSIZE_LISTEN, 72 usb_rcvintpipe(line6->usbdev, line6->properties->ep_ctrl_r),
72 line6_data_received, line6, line6->interval); 73 line6->buffer_listen, LINE6_BUFSIZE_LISTEN,
74 line6_data_received, line6, line6->interval);
75 } else {
76 usb_fill_bulk_urb(line6->urb_listen, line6->usbdev,
77 usb_rcvbulkpipe(line6->usbdev, line6->properties->ep_ctrl_r),
78 line6->buffer_listen, LINE6_BUFSIZE_LISTEN,
79 line6_data_received, line6);
80 }
73 line6->urb_listen->actual_length = 0; 81 line6->urb_listen->actual_length = 0;
74 err = usb_submit_urb(line6->urb_listen, GFP_ATOMIC); 82 err = usb_submit_urb(line6->urb_listen, GFP_ATOMIC);
75 return err; 83 return err;
@@ -90,6 +98,7 @@ static int line6_send_raw_message(struct usb_line6 *line6, const char *buffer,
90 int size) 98 int size)
91{ 99{
92 int i, done = 0; 100 int i, done = 0;
101 const struct line6_properties *properties = line6->properties;
93 102
94 for (i = 0; i < size; i += line6->max_packet_size) { 103 for (i = 0; i < size; i += line6->max_packet_size) {
95 int partial; 104 int partial;
@@ -97,15 +106,21 @@ static int line6_send_raw_message(struct usb_line6 *line6, const char *buffer,
97 int frag_size = min(line6->max_packet_size, size - i); 106 int frag_size = min(line6->max_packet_size, size - i);
98 int retval; 107 int retval;
99 108
100 retval = usb_interrupt_msg(line6->usbdev, 109 if (properties->capabilities & LINE6_CAP_CONTROL_MIDI) {
101 usb_sndintpipe(line6->usbdev, 110 retval = usb_interrupt_msg(line6->usbdev,
102 line6->properties->ep_ctrl_w), 111 usb_sndintpipe(line6->usbdev, properties->ep_ctrl_w),
103 (char *)frag_buf, frag_size, 112 (char *)frag_buf, frag_size,
104 &partial, LINE6_TIMEOUT * HZ); 113 &partial, LINE6_TIMEOUT * HZ);
114 } else {
115 retval = usb_bulk_msg(line6->usbdev,
116 usb_sndbulkpipe(line6->usbdev, properties->ep_ctrl_w),
117 (char *)frag_buf, frag_size,
118 &partial, LINE6_TIMEOUT * HZ);
119 }
105 120
106 if (retval) { 121 if (retval) {
107 dev_err(line6->ifcdev, 122 dev_err(line6->ifcdev,
108 "usb_interrupt_msg failed (%d)\n", retval); 123 "usb_bulk_msg failed (%d)\n", retval);
109 break; 124 break;
110 } 125 }
111 126
@@ -140,10 +155,17 @@ static int line6_send_raw_message_async_part(struct message *msg,
140 int done = msg->done; 155 int done = msg->done;
141 int bytes = min(msg->size - done, line6->max_packet_size); 156 int bytes = min(msg->size - done, line6->max_packet_size);
142 157
143 usb_fill_int_urb(urb, line6->usbdev, 158 if (line6->properties->capabilities & LINE6_CAP_CONTROL_MIDI) {
144 usb_sndintpipe(line6->usbdev, line6->properties->ep_ctrl_w), 159 usb_fill_int_urb(urb, line6->usbdev,
145 (char *)msg->buffer + done, bytes, 160 usb_sndintpipe(line6->usbdev, line6->properties->ep_ctrl_w),
146 line6_async_request_sent, msg, line6->interval); 161 (char *)msg->buffer + done, bytes,
162 line6_async_request_sent, msg, line6->interval);
163 } else {
164 usb_fill_bulk_urb(urb, line6->usbdev,
165 usb_sndbulkpipe(line6->usbdev, line6->properties->ep_ctrl_w),
166 (char *)msg->buffer + done, bytes,
167 line6_async_request_sent, msg);
168 }
147 169
148 msg->done += bytes; 170 msg->done += bytes;
149 retval = usb_submit_urb(urb, GFP_ATOMIC); 171 retval = usb_submit_urb(urb, GFP_ATOMIC);
@@ -269,28 +291,36 @@ static void line6_data_received(struct urb *urb)
269 if (urb->status == -ESHUTDOWN) 291 if (urb->status == -ESHUTDOWN)
270 return; 292 return;
271 293
272 done = 294 if (line6->properties->capabilities & LINE6_CAP_CONTROL_MIDI) {
273 line6_midibuf_write(mb, urb->transfer_buffer, urb->actual_length); 295 done =
296 line6_midibuf_write(mb, urb->transfer_buffer, urb->actual_length);
274 297
275 if (done < urb->actual_length) { 298 if (done < urb->actual_length) {
276 line6_midibuf_ignore(mb, done); 299 line6_midibuf_ignore(mb, done);
277 dev_dbg(line6->ifcdev, "%d %d buffer overflow - message skipped\n", 300 dev_dbg(line6->ifcdev, "%d %d buffer overflow - message skipped\n",
278 done, urb->actual_length); 301 done, urb->actual_length);
279 } 302 }
280 303
281 for (;;) { 304 for (;;) {
282 done = 305 done =
283 line6_midibuf_read(mb, line6->buffer_message, 306 line6_midibuf_read(mb, line6->buffer_message,
284 LINE6_MESSAGE_MAXLEN); 307 LINE6_MIDI_MESSAGE_MAXLEN);
285 308
286 if (done == 0) 309 if (done == 0)
287 break; 310 break;
288 311
289 line6->message_length = done; 312 line6->message_length = done;
290 line6_midi_receive(line6, line6->buffer_message, done); 313 line6_midi_receive(line6, line6->buffer_message, done);
291 314
315 if (line6->process_message)
316 line6->process_message(line6);
317 }
318 } else {
319 line6->buffer_message = urb->transfer_buffer;
320 line6->message_length = urb->actual_length;
292 if (line6->process_message) 321 if (line6->process_message)
293 line6->process_message(line6); 322 line6->process_message(line6);
323 line6->buffer_message = NULL;
294 } 324 }
295 325
296 line6_start_listen(line6); 326 line6_start_listen(line6);
@@ -447,12 +477,16 @@ static void line6_destruct(struct snd_card *card)
447 struct usb_line6 *line6 = card->private_data; 477 struct usb_line6 *line6 = card->private_data;
448 struct usb_device *usbdev = line6->usbdev; 478 struct usb_device *usbdev = line6->usbdev;
449 479
450 /* free buffer memory first: */ 480 /* Free buffer memory first. We cannot depend on the existence of private
481 * data from the (podhd) module, it may be gone already during this call
482 */
451 kfree(line6->buffer_message); 483 kfree(line6->buffer_message);
484
452 kfree(line6->buffer_listen); 485 kfree(line6->buffer_listen);
453 486
454 /* then free URBs: */ 487 /* then free URBs: */
455 usb_free_urb(line6->urb_listen); 488 usb_free_urb(line6->urb_listen);
489 line6->urb_listen = NULL;
456 490
457 /* decrement reference counters: */ 491 /* decrement reference counters: */
458 usb_put_dev(usbdev); 492 usb_put_dev(usbdev);
@@ -462,13 +496,29 @@ static void line6_destruct(struct snd_card *card)
462static void line6_get_interval(struct usb_line6 *line6) 496static void line6_get_interval(struct usb_line6 *line6)
463{ 497{
464 struct usb_device *usbdev = line6->usbdev; 498 struct usb_device *usbdev = line6->usbdev;
499 const struct line6_properties *properties = line6->properties;
500 int pipe;
465 struct usb_host_endpoint *ep; 501 struct usb_host_endpoint *ep;
466 unsigned pipe = usb_rcvintpipe(usbdev, line6->properties->ep_ctrl_r);
467 unsigned epnum = usb_pipeendpoint(pipe);
468 502
469 ep = usbdev->ep_in[epnum]; 503 if (properties->capabilities & LINE6_CAP_CONTROL_MIDI) {
504 pipe =
505 usb_rcvintpipe(line6->usbdev, line6->properties->ep_ctrl_r);
506 } else {
507 pipe =
508 usb_rcvbulkpipe(line6->usbdev, line6->properties->ep_ctrl_r);
509 }
510 ep = usbdev->ep_in[usb_pipeendpoint(pipe)];
511
470 if (ep) { 512 if (ep) {
471 line6->interval = ep->desc.bInterval; 513 line6->interval = ep->desc.bInterval;
514 if (usbdev->speed == USB_SPEED_LOW) {
515 line6->intervals_per_second = USB_LOW_INTERVALS_PER_SECOND;
516 line6->iso_buffers = USB_LOW_ISO_BUFFERS;
517 } else {
518 line6->intervals_per_second = USB_HIGH_INTERVALS_PER_SECOND;
519 line6->iso_buffers = USB_HIGH_ISO_BUFFERS;
520 }
521
472 line6->max_packet_size = le16_to_cpu(ep->desc.wMaxPacketSize); 522 line6->max_packet_size = le16_to_cpu(ep->desc.wMaxPacketSize);
473 } else { 523 } else {
474 dev_err(line6->ifcdev, 524 dev_err(line6->ifcdev,
@@ -478,6 +528,138 @@ static void line6_get_interval(struct usb_line6 *line6)
478 } 528 }
479} 529}
480 530
531
532/* Enable buffering of incoming messages, flush the buffer */
533static int line6_hwdep_open(struct snd_hwdep *hw, struct file *file)
534{
535 struct usb_line6 *line6 = hw->private_data;
536
537 /* NOTE: hwdep layer provides atomicity here */
538
539 line6->messages.active = 1;
540
541 return 0;
542}
543
544/* Stop buffering */
545static int line6_hwdep_release(struct snd_hwdep *hw, struct file *file)
546{
547 struct usb_line6 *line6 = hw->private_data;
548
549 line6->messages.active = 0;
550
551 return 0;
552}
553
554/* Read from circular buffer, return to user */
555static long
556line6_hwdep_read(struct snd_hwdep *hwdep, char __user *buf, long count,
557 loff_t *offset)
558{
559 struct usb_line6 *line6 = hwdep->private_data;
560 long rv = 0;
561 unsigned int out_count;
562
563 if (mutex_lock_interruptible(&line6->messages.read_lock))
564 return -ERESTARTSYS;
565
566 while (kfifo_len(&line6->messages.fifo) == 0) {
567 mutex_unlock(&line6->messages.read_lock);
568
569 rv = wait_event_interruptible(
570 line6->messages.wait_queue,
571 kfifo_len(&line6->messages.fifo) != 0);
572 if (rv < 0)
573 return rv;
574
575 if (mutex_lock_interruptible(&line6->messages.read_lock))
576 return -ERESTARTSYS;
577 }
578
579 if (kfifo_peek_len(&line6->messages.fifo) > count) {
580 /* Buffer too small; allow re-read of the current item... */
581 rv = -EINVAL;
582 } else {
583 rv = kfifo_to_user(&line6->messages.fifo, buf, count, &out_count);
584 if (rv == 0)
585 rv = out_count;
586 }
587
588 mutex_unlock(&line6->messages.read_lock);
589 return rv;
590}
591
592/* Write directly (no buffering) to device by user*/
593static long
594line6_hwdep_write(struct snd_hwdep *hwdep, const char __user *data, long count,
595 loff_t *offset)
596{
597 struct usb_line6 *line6 = hwdep->private_data;
598 int rv;
599 char *data_copy;
600
601 if (count > line6->max_packet_size * LINE6_RAW_MESSAGES_MAXCOUNT) {
602 /* This is an arbitrary limit - still better than nothing... */
603 return -EINVAL;
604 }
605
606 data_copy = memdup_user(data, count);
607 if (IS_ERR(ERR_PTR))
608 return -ENOMEM;
609
610 rv = line6_send_raw_message(line6, data_copy, count);
611
612 kfree(data_copy);
613 return rv;
614}
615
616static const struct snd_hwdep_ops hwdep_ops = {
617 .open = line6_hwdep_open,
618 .release = line6_hwdep_release,
619 .read = line6_hwdep_read,
620 .write = line6_hwdep_write,
621};
622
623/* Insert into circular buffer */
624static void line6_hwdep_push_message(struct usb_line6 *line6)
625{
626 if (!line6->messages.active)
627 return;
628
629 if (kfifo_avail(&line6->messages.fifo) >= line6->message_length) {
630 /* No race condition here, there's only one writer */
631 kfifo_in(&line6->messages.fifo,
632 line6->buffer_message, line6->message_length);
633 } /* else TODO: signal overflow */
634
635 wake_up_interruptible(&line6->messages.wait_queue);
636}
637
638static int line6_hwdep_init(struct usb_line6 *line6)
639{
640 int err;
641 struct snd_hwdep *hwdep;
642
643 /* TODO: usb_driver_claim_interface(); */
644 line6->process_message = line6_hwdep_push_message;
645 line6->messages.active = 0;
646 init_waitqueue_head(&line6->messages.wait_queue);
647 mutex_init(&line6->messages.read_lock);
648 INIT_KFIFO(line6->messages.fifo);
649
650 err = snd_hwdep_new(line6->card, "config", 0, &hwdep);
651 if (err < 0)
652 goto end;
653 strcpy(hwdep->name, "config");
654 hwdep->iface = SNDRV_HWDEP_IFACE_LINE6;
655 hwdep->ops = hwdep_ops;
656 hwdep->private_data = line6;
657 hwdep->exclusive = true;
658
659end:
660 return err;
661}
662
481static int line6_init_cap_control(struct usb_line6 *line6) 663static int line6_init_cap_control(struct usb_line6 *line6)
482{ 664{
483 int ret; 665 int ret;
@@ -487,14 +669,20 @@ static int line6_init_cap_control(struct usb_line6 *line6)
487 if (!line6->buffer_listen) 669 if (!line6->buffer_listen)
488 return -ENOMEM; 670 return -ENOMEM;
489 671
490 line6->buffer_message = kmalloc(LINE6_MESSAGE_MAXLEN, GFP_KERNEL);
491 if (!line6->buffer_message)
492 return -ENOMEM;
493
494 line6->urb_listen = usb_alloc_urb(0, GFP_KERNEL); 672 line6->urb_listen = usb_alloc_urb(0, GFP_KERNEL);
495 if (!line6->urb_listen) 673 if (!line6->urb_listen)
496 return -ENOMEM; 674 return -ENOMEM;
497 675
676 if (line6->properties->capabilities & LINE6_CAP_CONTROL_MIDI) {
677 line6->buffer_message = kmalloc(LINE6_MIDI_MESSAGE_MAXLEN, GFP_KERNEL);
678 if (!line6->buffer_message)
679 return -ENOMEM;
680 } else {
681 ret = line6_hwdep_init(line6);
682 if (ret < 0)
683 return ret;
684 }
685
498 ret = line6_start_listen(line6); 686 ret = line6_start_listen(line6);
499 if (ret < 0) { 687 if (ret < 0) {
500 dev_err(line6->ifcdev, "cannot start listening: %d\n", ret); 688 dev_err(line6->ifcdev, "cannot start listening: %d\n", ret);
@@ -558,6 +746,7 @@ int line6_probe(struct usb_interface *interface,
558 /* query interface number */ 746 /* query interface number */
559 interface_number = interface->cur_altsetting->desc.bInterfaceNumber; 747 interface_number = interface->cur_altsetting->desc.bInterfaceNumber;
560 748
749 /* TODO reserves the bus bandwidth even without actual transfer */
561 ret = usb_set_interface(usbdev, interface_number, 750 ret = usb_set_interface(usbdev, interface_number,
562 properties->altsetting); 751 properties->altsetting);
563 if (ret < 0) { 752 if (ret < 0) {
@@ -565,9 +754,8 @@ int line6_probe(struct usb_interface *interface,
565 goto error; 754 goto error;
566 } 755 }
567 756
568 line6_get_interval(line6);
569
570 if (properties->capabilities & LINE6_CAP_CONTROL) { 757 if (properties->capabilities & LINE6_CAP_CONTROL) {
758 line6_get_interval(line6);
571 ret = line6_init_cap_control(line6); 759 ret = line6_init_cap_control(line6);
572 if (ret < 0) 760 if (ret < 0)
573 goto error; 761 goto error;
@@ -670,3 +858,4 @@ EXPORT_SYMBOL_GPL(line6_resume);
670MODULE_AUTHOR(DRIVER_AUTHOR); 858MODULE_AUTHOR(DRIVER_AUTHOR);
671MODULE_DESCRIPTION(DRIVER_DESC); 859MODULE_DESCRIPTION(DRIVER_DESC);
672MODULE_LICENSE("GPL"); 860MODULE_LICENSE("GPL");
861
diff --git a/sound/usb/line6/driver.h b/sound/usb/line6/driver.h
index 7da643e79e3b..7e3a3aada222 100644
--- a/sound/usb/line6/driver.h
+++ b/sound/usb/line6/driver.h
@@ -12,21 +12,37 @@
12#ifndef DRIVER_H 12#ifndef DRIVER_H
13#define DRIVER_H 13#define DRIVER_H
14 14
15#include <linux/spinlock.h>
16#include <linux/usb.h> 15#include <linux/usb.h>
16#include <linux/mutex.h>
17#include <linux/kfifo.h>
17#include <sound/core.h> 18#include <sound/core.h>
18 19
19#include "midi.h" 20#include "midi.h"
20 21
21#define USB_INTERVALS_PER_SECOND 1000 22/* USB 1.1 speed configuration */
23#define USB_LOW_INTERVALS_PER_SECOND 1000
24#define USB_LOW_ISO_BUFFERS 2
25
26/* USB 2.0+ speed configuration */
27#define USB_HIGH_INTERVALS_PER_SECOND 8000
28#define USB_HIGH_ISO_BUFFERS 16
22 29
23/* Fallback USB interval and max packet size values */ 30/* Fallback USB interval and max packet size values */
24#define LINE6_FALLBACK_INTERVAL 10 31#define LINE6_FALLBACK_INTERVAL 10
25#define LINE6_FALLBACK_MAXPACKETSIZE 16 32#define LINE6_FALLBACK_MAXPACKETSIZE 16
26 33
27#define LINE6_TIMEOUT 1 34#define LINE6_TIMEOUT 1
28#define LINE6_BUFSIZE_LISTEN 32 35#define LINE6_BUFSIZE_LISTEN 64
29#define LINE6_MESSAGE_MAXLEN 256 36#define LINE6_MIDI_MESSAGE_MAXLEN 256
37
38#define LINE6_RAW_MESSAGES_MAXCOUNT_ORDER 7
39/* 4k packets are common, BUFSIZE * MAXCOUNT should be bigger... */
40#define LINE6_RAW_MESSAGES_MAXCOUNT (1 << LINE6_RAW_MESSAGES_MAXCOUNT_ORDER)
41
42
43#if LINE6_BUFSIZE_LISTEN > 65535
44#error "Use dynamic fifo instead"
45#endif
30 46
31/* 47/*
32 Line 6 MIDI control commands 48 Line 6 MIDI control commands
@@ -94,8 +110,12 @@ enum {
94 LINE6_CAP_CONTROL = 1 << 0, 110 LINE6_CAP_CONTROL = 1 << 0,
95 /* device supports PCM input/output via USB */ 111 /* device supports PCM input/output via USB */
96 LINE6_CAP_PCM = 1 << 1, 112 LINE6_CAP_PCM = 1 << 1,
97 /* device support hardware monitoring */ 113 /* device supports hardware monitoring */
98 LINE6_CAP_HWMON = 1 << 2, 114 LINE6_CAP_HWMON = 1 << 2,
115 /* device requires output data when input is read */
116 LINE6_CAP_IN_NEEDS_OUT = 1 << 3,
117 /* device uses raw MIDI via USB (data endpoints) */
118 LINE6_CAP_CONTROL_MIDI = 1 << 4,
99}; 119};
100 120
101/* 121/*
@@ -109,10 +129,15 @@ struct usb_line6 {
109 /* Properties */ 129 /* Properties */
110 const struct line6_properties *properties; 130 const struct line6_properties *properties;
111 131
112 /* Interval (ms) */ 132 /* Interval for data USB packets */
113 int interval; 133 int interval;
134 /* ...for isochronous transfers framing */
135 int intervals_per_second;
136
137 /* Number of isochronous URBs used for frame transfers */
138 int iso_buffers;
114 139
115 /* Maximum size of USB packet */ 140 /* Maximum size of data USB packet */
116 int max_packet_size; 141 int max_packet_size;
117 142
118 /* Device representing the USB interface */ 143 /* Device representing the USB interface */
@@ -129,18 +154,30 @@ struct usb_line6 {
129 /* Line 6 MIDI device data structure */ 154 /* Line 6 MIDI device data structure */
130 struct snd_line6_midi *line6midi; 155 struct snd_line6_midi *line6midi;
131 156
132 /* URB for listening to PODxt Pro control endpoint */ 157 /* URB for listening to POD data endpoint */
133 struct urb *urb_listen; 158 struct urb *urb_listen;
134 159
135 /* Buffer for listening to PODxt Pro control endpoint */ 160 /* Buffer for incoming data from POD data endpoint */
136 unsigned char *buffer_listen; 161 unsigned char *buffer_listen;
137 162
138 /* Buffer for message to be processed */ 163 /* Buffer for message to be processed, generated from MIDI layer */
139 unsigned char *buffer_message; 164 unsigned char *buffer_message;
140 165
141 /* Length of message to be processed */ 166 /* Length of message to be processed, generated from MIDI layer */
142 int message_length; 167 int message_length;
143 168
169 /* Circular buffer for non-MIDI control messages */
170 struct {
171 struct mutex read_lock;
172 wait_queue_head_t wait_queue;
173 unsigned int active:1;
174 STRUCT_KFIFO_REC_2(LINE6_BUFSIZE_LISTEN * LINE6_RAW_MESSAGES_MAXCOUNT)
175 fifo;
176 } messages;
177
178 /* If MIDI is supported, buffer_message contains the pre-processed data;
179 * otherwise the data is only in urb_listen (buffer_incoming).
180 */
144 void (*process_message)(struct usb_line6 *); 181 void (*process_message)(struct usb_line6 *);
145 void (*disconnect)(struct usb_line6 *line6); 182 void (*disconnect)(struct usb_line6 *line6);
146}; 183};
diff --git a/sound/usb/line6/midi.c b/sound/usb/line6/midi.c
index cebea9b7f769..d0fb2f205bd9 100644
--- a/sound/usb/line6/midi.c
+++ b/sound/usb/line6/midi.c
@@ -258,7 +258,7 @@ int line6_init_midi(struct usb_line6 *line6)
258 struct snd_rawmidi *rmidi; 258 struct snd_rawmidi *rmidi;
259 struct snd_line6_midi *line6midi; 259 struct snd_line6_midi *line6midi;
260 260
261 if (!(line6->properties->capabilities & LINE6_CAP_CONTROL)) { 261 if (!(line6->properties->capabilities & LINE6_CAP_CONTROL_MIDI)) {
262 /* skip MIDI initialization and report success */ 262 /* skip MIDI initialization and report success */
263 return 0; 263 return 0;
264 } 264 }
diff --git a/sound/usb/line6/pcm.c b/sound/usb/line6/pcm.c
index 41aa3355e920..fab53f58d447 100644
--- a/sound/usb/line6/pcm.c
+++ b/sound/usb/line6/pcm.c
@@ -52,7 +52,7 @@ static int snd_line6_impulse_volume_put(struct snd_kcontrol *kcontrol,
52 52
53 line6pcm->impulse_volume = value; 53 line6pcm->impulse_volume = value;
54 if (value > 0) { 54 if (value > 0) {
55 err = line6_pcm_acquire(line6pcm, LINE6_STREAM_IMPULSE); 55 err = line6_pcm_acquire(line6pcm, LINE6_STREAM_IMPULSE, true);
56 if (err < 0) { 56 if (err < 0) {
57 line6pcm->impulse_volume = 0; 57 line6pcm->impulse_volume = 0;
58 return err; 58 return err;
@@ -104,7 +104,7 @@ static void line6_unlink_audio_urbs(struct snd_line6_pcm *line6pcm,
104{ 104{
105 int i; 105 int i;
106 106
107 for (i = 0; i < LINE6_ISO_BUFFERS; i++) { 107 for (i = 0; i < line6pcm->line6->iso_buffers; i++) {
108 if (test_bit(i, &pcms->active_urbs)) { 108 if (test_bit(i, &pcms->active_urbs)) {
109 if (!test_and_set_bit(i, &pcms->unlink_urbs)) 109 if (!test_and_set_bit(i, &pcms->unlink_urbs))
110 usb_unlink_urb(pcms->urbs[i]); 110 usb_unlink_urb(pcms->urbs[i]);
@@ -124,7 +124,7 @@ static void line6_wait_clear_audio_urbs(struct snd_line6_pcm *line6pcm,
124 124
125 do { 125 do {
126 alive = 0; 126 alive = 0;
127 for (i = 0; i < LINE6_ISO_BUFFERS; i++) { 127 for (i = 0; i < line6pcm->line6->iso_buffers; i++) {
128 if (test_bit(i, &pcms->active_urbs)) 128 if (test_bit(i, &pcms->active_urbs))
129 alive++; 129 alive++;
130 } 130 }
@@ -146,15 +146,20 @@ get_stream(struct snd_line6_pcm *line6pcm, int direction)
146} 146}
147 147
148/* allocate a buffer if not opened yet; 148/* allocate a buffer if not opened yet;
149 * call this in line6pcm.state_change mutex 149 * call this in line6pcm.state_mutex
150 */ 150 */
151static int line6_buffer_acquire(struct snd_line6_pcm *line6pcm, 151static int line6_buffer_acquire(struct snd_line6_pcm *line6pcm,
152 struct line6_pcm_stream *pstr, int type) 152 struct line6_pcm_stream *pstr, int direction, int type)
153{ 153{
154 const int pkt_size =
155 (direction == SNDRV_PCM_STREAM_PLAYBACK) ?
156 line6pcm->max_packet_size_out :
157 line6pcm->max_packet_size_in;
158
154 /* Invoked multiple times in a row so allocate once only */ 159 /* Invoked multiple times in a row so allocate once only */
155 if (!test_and_set_bit(type, &pstr->opened) && !pstr->buffer) { 160 if (!test_and_set_bit(type, &pstr->opened) && !pstr->buffer) {
156 pstr->buffer = kmalloc(LINE6_ISO_BUFFERS * LINE6_ISO_PACKETS * 161 pstr->buffer = kmalloc(line6pcm->line6->iso_buffers *
157 line6pcm->max_packet_size, GFP_KERNEL); 162 LINE6_ISO_PACKETS * pkt_size, GFP_KERNEL);
158 if (!pstr->buffer) 163 if (!pstr->buffer)
159 return -ENOMEM; 164 return -ENOMEM;
160 } 165 }
@@ -162,12 +167,11 @@ static int line6_buffer_acquire(struct snd_line6_pcm *line6pcm,
162} 167}
163 168
164/* free a buffer if all streams are closed; 169/* free a buffer if all streams are closed;
165 * call this in line6pcm.state_change mutex 170 * call this in line6pcm.state_mutex
166 */ 171 */
167static void line6_buffer_release(struct snd_line6_pcm *line6pcm, 172static void line6_buffer_release(struct snd_line6_pcm *line6pcm,
168 struct line6_pcm_stream *pstr, int type) 173 struct line6_pcm_stream *pstr, int type)
169{ 174{
170
171 clear_bit(type, &pstr->opened); 175 clear_bit(type, &pstr->opened);
172 if (!pstr->opened) { 176 if (!pstr->opened) {
173 line6_wait_clear_audio_urbs(line6pcm, pstr); 177 line6_wait_clear_audio_urbs(line6pcm, pstr);
@@ -194,6 +198,7 @@ static int line6_stream_start(struct snd_line6_pcm *line6pcm, int direction,
194 else 198 else
195 ret = line6_submit_audio_in_all_urbs(line6pcm); 199 ret = line6_submit_audio_in_all_urbs(line6pcm);
196 } 200 }
201
197 if (ret < 0) 202 if (ret < 0)
198 clear_bit(type, &pstr->running); 203 clear_bit(type, &pstr->running);
199 spin_unlock_irqrestore(&pstr->lock, flags); 204 spin_unlock_irqrestore(&pstr->lock, flags);
@@ -237,6 +242,14 @@ int snd_line6_trigger(struct snd_pcm_substream *substream, int cmd)
237 switch (cmd) { 242 switch (cmd) {
238 case SNDRV_PCM_TRIGGER_START: 243 case SNDRV_PCM_TRIGGER_START:
239 case SNDRV_PCM_TRIGGER_RESUME: 244 case SNDRV_PCM_TRIGGER_RESUME:
245 if (s->stream == SNDRV_PCM_STREAM_CAPTURE &&
246 (line6pcm->line6->properties->capabilities &
247 LINE6_CAP_IN_NEEDS_OUT)) {
248 err = line6_stream_start(line6pcm, SNDRV_PCM_STREAM_PLAYBACK,
249 LINE6_STREAM_CAPTURE_HELPER);
250 if (err < 0)
251 return err;
252 }
240 err = line6_stream_start(line6pcm, s->stream, 253 err = line6_stream_start(line6pcm, s->stream,
241 LINE6_STREAM_PCM); 254 LINE6_STREAM_PCM);
242 if (err < 0) 255 if (err < 0)
@@ -245,6 +258,12 @@ int snd_line6_trigger(struct snd_pcm_substream *substream, int cmd)
245 258
246 case SNDRV_PCM_TRIGGER_STOP: 259 case SNDRV_PCM_TRIGGER_STOP:
247 case SNDRV_PCM_TRIGGER_SUSPEND: 260 case SNDRV_PCM_TRIGGER_SUSPEND:
261 if (s->stream == SNDRV_PCM_STREAM_CAPTURE &&
262 (line6pcm->line6->properties->capabilities &
263 LINE6_CAP_IN_NEEDS_OUT)) {
264 line6_stream_stop(line6pcm, SNDRV_PCM_STREAM_PLAYBACK,
265 LINE6_STREAM_CAPTURE_HELPER);
266 }
248 line6_stream_stop(line6pcm, s->stream, 267 line6_stream_stop(line6pcm, s->stream,
249 LINE6_STREAM_PCM); 268 LINE6_STREAM_PCM);
250 break; 269 break;
@@ -278,27 +297,30 @@ snd_pcm_uframes_t snd_line6_pointer(struct snd_pcm_substream *substream)
278 return pstr->pos_done; 297 return pstr->pos_done;
279} 298}
280 299
281/* Acquire and start duplex streams: 300/* Acquire and optionally start duplex streams:
282 * type is either LINE6_STREAM_IMPULSE or LINE6_STREAM_MONITOR 301 * type is either LINE6_STREAM_IMPULSE or LINE6_STREAM_MONITOR
283 */ 302 */
284int line6_pcm_acquire(struct snd_line6_pcm *line6pcm, int type) 303int line6_pcm_acquire(struct snd_line6_pcm *line6pcm, int type, bool start)
285{ 304{
286 struct line6_pcm_stream *pstr; 305 struct line6_pcm_stream *pstr;
287 int ret = 0, dir; 306 int ret = 0, dir;
288 307
308 /* TODO: We should assert SNDRV_PCM_STREAM_PLAYBACK/CAPTURE == 0/1 */
289 mutex_lock(&line6pcm->state_mutex); 309 mutex_lock(&line6pcm->state_mutex);
290 for (dir = 0; dir < 2; dir++) { 310 for (dir = 0; dir < 2; dir++) {
291 pstr = get_stream(line6pcm, dir); 311 pstr = get_stream(line6pcm, dir);
292 ret = line6_buffer_acquire(line6pcm, pstr, type); 312 ret = line6_buffer_acquire(line6pcm, pstr, dir, type);
293 if (ret < 0) 313 if (ret < 0)
294 goto error; 314 goto error;
295 if (!pstr->running) 315 if (!pstr->running)
296 line6_wait_clear_audio_urbs(line6pcm, pstr); 316 line6_wait_clear_audio_urbs(line6pcm, pstr);
297 } 317 }
298 for (dir = 0; dir < 2; dir++) { 318 if (start) {
299 ret = line6_stream_start(line6pcm, dir, type); 319 for (dir = 0; dir < 2; dir++) {
300 if (ret < 0) 320 ret = line6_stream_start(line6pcm, dir, type);
301 goto error; 321 if (ret < 0)
322 goto error;
323 }
302 } 324 }
303 error: 325 error:
304 mutex_unlock(&line6pcm->state_mutex); 326 mutex_unlock(&line6pcm->state_mutex);
@@ -334,7 +356,8 @@ int snd_line6_hw_params(struct snd_pcm_substream *substream,
334 struct line6_pcm_stream *pstr = get_stream(line6pcm, substream->stream); 356 struct line6_pcm_stream *pstr = get_stream(line6pcm, substream->stream);
335 357
336 mutex_lock(&line6pcm->state_mutex); 358 mutex_lock(&line6pcm->state_mutex);
337 ret = line6_buffer_acquire(line6pcm, pstr, LINE6_STREAM_PCM); 359 ret = line6_buffer_acquire(line6pcm, pstr, substream->stream,
360 LINE6_STREAM_PCM);
338 if (ret < 0) 361 if (ret < 0)
339 goto error; 362 goto error;
340 363
@@ -434,24 +457,30 @@ static struct snd_kcontrol_new line6_controls[] = {
434/* 457/*
435 Cleanup the PCM device. 458 Cleanup the PCM device.
436*/ 459*/
437static void cleanup_urbs(struct line6_pcm_stream *pcms) 460static void cleanup_urbs(struct line6_pcm_stream *pcms, int iso_buffers)
438{ 461{
439 int i; 462 int i;
440 463
441 for (i = 0; i < LINE6_ISO_BUFFERS; i++) { 464 /* Most likely impossible in current code... */
465 if (pcms->urbs == NULL)
466 return;
467
468 for (i = 0; i < iso_buffers; i++) {
442 if (pcms->urbs[i]) { 469 if (pcms->urbs[i]) {
443 usb_kill_urb(pcms->urbs[i]); 470 usb_kill_urb(pcms->urbs[i]);
444 usb_free_urb(pcms->urbs[i]); 471 usb_free_urb(pcms->urbs[i]);
445 } 472 }
446 } 473 }
474 kfree(pcms->urbs);
475 pcms->urbs = NULL;
447} 476}
448 477
449static void line6_cleanup_pcm(struct snd_pcm *pcm) 478static void line6_cleanup_pcm(struct snd_pcm *pcm)
450{ 479{
451 struct snd_line6_pcm *line6pcm = snd_pcm_chip(pcm); 480 struct snd_line6_pcm *line6pcm = snd_pcm_chip(pcm);
452 481
453 cleanup_urbs(&line6pcm->out); 482 cleanup_urbs(&line6pcm->out, line6pcm->line6->iso_buffers);
454 cleanup_urbs(&line6pcm->in); 483 cleanup_urbs(&line6pcm->in, line6pcm->line6->iso_buffers);
455 kfree(line6pcm); 484 kfree(line6pcm);
456} 485}
457 486
@@ -523,12 +552,12 @@ int line6_init_pcm(struct usb_line6 *line6,
523 line6pcm->volume_monitor = 255; 552 line6pcm->volume_monitor = 255;
524 line6pcm->line6 = line6; 553 line6pcm->line6 = line6;
525 554
526 /* Read and write buffers are sized identically, so choose minimum */ 555 line6pcm->max_packet_size_in =
527 line6pcm->max_packet_size = min( 556 usb_maxpacket(line6->usbdev,
528 usb_maxpacket(line6->usbdev, 557 usb_rcvisocpipe(line6->usbdev, ep_read), 0);
529 usb_rcvisocpipe(line6->usbdev, ep_read), 0), 558 line6pcm->max_packet_size_out =
530 usb_maxpacket(line6->usbdev, 559 usb_maxpacket(line6->usbdev,
531 usb_sndisocpipe(line6->usbdev, ep_write), 1)); 560 usb_sndisocpipe(line6->usbdev, ep_write), 1);
532 561
533 spin_lock_init(&line6pcm->out.lock); 562 spin_lock_init(&line6pcm->out.lock);
534 spin_lock_init(&line6pcm->in.lock); 563 spin_lock_init(&line6pcm->in.lock);
diff --git a/sound/usb/line6/pcm.h b/sound/usb/line6/pcm.h
index 508410adbd51..bb0c9cbf2a78 100644
--- a/sound/usb/line6/pcm.h
+++ b/sound/usb/line6/pcm.h
@@ -20,9 +20,6 @@
20 20
21#include "driver.h" 21#include "driver.h"
22 22
23/* number of URBs */
24#define LINE6_ISO_BUFFERS 2
25
26/* 23/*
27 number of USB frames per URB 24 number of USB frames per URB
28 The Line 6 Windows driver always transmits two frames per packet, but 25 The Line 6 Windows driver always transmits two frames per packet, but
@@ -31,7 +28,9 @@
31*/ 28*/
32#define LINE6_ISO_PACKETS 1 29#define LINE6_ISO_PACKETS 1
33 30
34/* in a "full speed" device (such as the PODxt Pro) this means 1ms */ 31/* in a "full speed" device (such as the PODxt Pro) this means 1ms,
32 * for "high speed" it's 1/8ms
33 */
35#define LINE6_ISO_INTERVAL 1 34#define LINE6_ISO_INTERVAL 1
36 35
37#define LINE6_IMPULSE_DEFAULT_PERIOD 100 36#define LINE6_IMPULSE_DEFAULT_PERIOD 100
@@ -74,6 +73,7 @@ enum {
74 LINE6_STREAM_PCM, 73 LINE6_STREAM_PCM,
75 LINE6_STREAM_MONITOR, 74 LINE6_STREAM_MONITOR,
76 LINE6_STREAM_IMPULSE, 75 LINE6_STREAM_IMPULSE,
76 LINE6_STREAM_CAPTURE_HELPER,
77}; 77};
78 78
79/* misc bit flags for PCM operation */ 79/* misc bit flags for PCM operation */
@@ -85,12 +85,12 @@ enum {
85struct line6_pcm_properties { 85struct line6_pcm_properties {
86 struct snd_pcm_hardware playback_hw, capture_hw; 86 struct snd_pcm_hardware playback_hw, capture_hw;
87 struct snd_pcm_hw_constraint_ratdens rates; 87 struct snd_pcm_hw_constraint_ratdens rates;
88 int bytes_per_frame; 88 int bytes_per_channel;
89}; 89};
90 90
91struct line6_pcm_stream { 91struct line6_pcm_stream {
92 /* allocated URBs */ 92 /* allocated URBs */
93 struct urb *urbs[LINE6_ISO_BUFFERS]; 93 struct urb **urbs;
94 94
95 /* Temporary buffer; 95 /* Temporary buffer;
96 * Since the packet size is not known in advance, this buffer is 96 * Since the packet size is not known in advance, this buffer is
@@ -157,11 +157,12 @@ struct snd_line6_pcm {
157 /* Previously captured frame (for software monitoring) */ 157 /* Previously captured frame (for software monitoring) */
158 unsigned char *prev_fbuf; 158 unsigned char *prev_fbuf;
159 159
160 /* Size of previously captured frame (for software monitoring) */ 160 /* Size of previously captured frame (for software monitoring/sync) */
161 int prev_fsize; 161 int prev_fsize;
162 162
163 /* Maximum size of USB packet */ 163 /* Maximum size of USB packet */
164 int max_packet_size; 164 int max_packet_size_in;
165 int max_packet_size_out;
165 166
166 /* PCM playback volume (left and right) */ 167 /* PCM playback volume (left and right) */
167 int volume_playback[2]; 168 int volume_playback[2];
@@ -191,7 +192,8 @@ extern int snd_line6_hw_params(struct snd_pcm_substream *substream,
191extern int snd_line6_hw_free(struct snd_pcm_substream *substream); 192extern int snd_line6_hw_free(struct snd_pcm_substream *substream);
192extern snd_pcm_uframes_t snd_line6_pointer(struct snd_pcm_substream *substream); 193extern snd_pcm_uframes_t snd_line6_pointer(struct snd_pcm_substream *substream);
193extern void line6_pcm_disconnect(struct snd_line6_pcm *line6pcm); 194extern void line6_pcm_disconnect(struct snd_line6_pcm *line6pcm);
194extern int line6_pcm_acquire(struct snd_line6_pcm *line6pcm, int type); 195extern int line6_pcm_acquire(struct snd_line6_pcm *line6pcm, int type,
196 bool start);
195extern void line6_pcm_release(struct snd_line6_pcm *line6pcm, int type); 197extern void line6_pcm_release(struct snd_line6_pcm *line6pcm, int type);
196 198
197#endif 199#endif
diff --git a/sound/usb/line6/playback.c b/sound/usb/line6/playback.c
index 97ed593f6010..812d18191e01 100644
--- a/sound/usb/line6/playback.c
+++ b/sound/usb/line6/playback.c
@@ -146,18 +146,20 @@ static int submit_audio_out_urb(struct snd_line6_pcm *line6pcm)
146 int index; 146 int index;
147 int i, urb_size, urb_frames; 147 int i, urb_size, urb_frames;
148 int ret; 148 int ret;
149 const int bytes_per_frame = line6pcm->properties->bytes_per_frame; 149 const int bytes_per_frame =
150 line6pcm->properties->bytes_per_channel *
151 line6pcm->properties->playback_hw.channels_max;
150 const int frame_increment = 152 const int frame_increment =
151 line6pcm->properties->rates.rats[0].num_min; 153 line6pcm->properties->rates.rats[0].num_min;
152 const int frame_factor = 154 const int frame_factor =
153 line6pcm->properties->rates.rats[0].den * 155 line6pcm->properties->rates.rats[0].den *
154 (USB_INTERVALS_PER_SECOND / LINE6_ISO_INTERVAL); 156 (line6pcm->line6->intervals_per_second / LINE6_ISO_INTERVAL);
155 struct urb *urb_out; 157 struct urb *urb_out;
156 158
157 index = 159 index = find_first_zero_bit(&line6pcm->out.active_urbs,
158 find_first_zero_bit(&line6pcm->out.active_urbs, LINE6_ISO_BUFFERS); 160 line6pcm->line6->iso_buffers);
159 161
160 if (index < 0 || index >= LINE6_ISO_BUFFERS) { 162 if (index < 0 || index >= line6pcm->line6->iso_buffers) {
161 dev_err(line6pcm->line6->ifcdev, "no free URB found\n"); 163 dev_err(line6pcm->line6->ifcdev, "no free URB found\n");
162 return -EINVAL; 164 return -EINVAL;
163 } 165 }
@@ -165,6 +167,7 @@ static int submit_audio_out_urb(struct snd_line6_pcm *line6pcm)
165 urb_out = line6pcm->out.urbs[index]; 167 urb_out = line6pcm->out.urbs[index];
166 urb_size = 0; 168 urb_size = 0;
167 169
170 /* TODO: this may not work for LINE6_ISO_PACKETS != 1 */
168 for (i = 0; i < LINE6_ISO_PACKETS; ++i) { 171 for (i = 0; i < LINE6_ISO_PACKETS; ++i) {
169 /* compute frame size for given sampling rate */ 172 /* compute frame size for given sampling rate */
170 int fsize = 0; 173 int fsize = 0;
@@ -178,9 +181,11 @@ static int submit_audio_out_urb(struct snd_line6_pcm *line6pcm)
178 line6pcm->out.count += frame_increment; 181 line6pcm->out.count += frame_increment;
179 n = line6pcm->out.count / frame_factor; 182 n = line6pcm->out.count / frame_factor;
180 line6pcm->out.count -= n * frame_factor; 183 line6pcm->out.count -= n * frame_factor;
181 fsize = n * bytes_per_frame; 184 fsize = n;
182 } 185 }
183 186
187 fsize *= bytes_per_frame;
188
184 fout->offset = urb_size; 189 fout->offset = urb_size;
185 fout->length = fsize; 190 fout->length = fsize;
186 urb_size += fsize; 191 urb_size += fsize;
@@ -195,7 +200,7 @@ static int submit_audio_out_urb(struct snd_line6_pcm *line6pcm)
195 urb_frames = urb_size / bytes_per_frame; 200 urb_frames = urb_size / bytes_per_frame;
196 urb_out->transfer_buffer = 201 urb_out->transfer_buffer =
197 line6pcm->out.buffer + 202 line6pcm->out.buffer +
198 index * LINE6_ISO_PACKETS * line6pcm->max_packet_size; 203 index * LINE6_ISO_PACKETS * line6pcm->max_packet_size_out;
199 urb_out->transfer_buffer_length = urb_size; 204 urb_out->transfer_buffer_length = urb_size;
200 urb_out->context = line6pcm; 205 urb_out->context = line6pcm;
201 206
@@ -286,7 +291,7 @@ int line6_submit_audio_out_all_urbs(struct snd_line6_pcm *line6pcm)
286{ 291{
287 int ret = 0, i; 292 int ret = 0, i;
288 293
289 for (i = 0; i < LINE6_ISO_BUFFERS; ++i) { 294 for (i = 0; i < line6pcm->line6->iso_buffers; ++i) {
290 ret = submit_audio_out_urb(line6pcm); 295 ret = submit_audio_out_urb(line6pcm);
291 if (ret < 0) 296 if (ret < 0)
292 break; 297 break;
@@ -305,6 +310,9 @@ static void audio_out_callback(struct urb *urb)
305 struct snd_line6_pcm *line6pcm = (struct snd_line6_pcm *)urb->context; 310 struct snd_line6_pcm *line6pcm = (struct snd_line6_pcm *)urb->context;
306 struct snd_pcm_substream *substream = 311 struct snd_pcm_substream *substream =
307 get_substream(line6pcm, SNDRV_PCM_STREAM_PLAYBACK); 312 get_substream(line6pcm, SNDRV_PCM_STREAM_PLAYBACK);
313 const int bytes_per_frame =
314 line6pcm->properties->bytes_per_channel *
315 line6pcm->properties->playback_hw.channels_max;
308 316
309#if USE_CLEAR_BUFFER_WORKAROUND 317#if USE_CLEAR_BUFFER_WORKAROUND
310 memset(urb->transfer_buffer, 0, urb->transfer_buffer_length); 318 memset(urb->transfer_buffer, 0, urb->transfer_buffer_length);
@@ -313,11 +321,11 @@ static void audio_out_callback(struct urb *urb)
313 line6pcm->out.last_frame = urb->start_frame; 321 line6pcm->out.last_frame = urb->start_frame;
314 322
315 /* find index of URB */ 323 /* find index of URB */
316 for (index = 0; index < LINE6_ISO_BUFFERS; index++) 324 for (index = 0; index < line6pcm->line6->iso_buffers; index++)
317 if (urb == line6pcm->out.urbs[index]) 325 if (urb == line6pcm->out.urbs[index])
318 break; 326 break;
319 327
320 if (index >= LINE6_ISO_BUFFERS) 328 if (index >= line6pcm->line6->iso_buffers)
321 return; /* URB has been unlinked asynchronously */ 329 return; /* URB has been unlinked asynchronously */
322 330
323 for (i = 0; i < LINE6_ISO_PACKETS; i++) 331 for (i = 0; i < LINE6_ISO_PACKETS; i++)
@@ -329,7 +337,7 @@ static void audio_out_callback(struct urb *urb)
329 struct snd_pcm_runtime *runtime = substream->runtime; 337 struct snd_pcm_runtime *runtime = substream->runtime;
330 338
331 line6pcm->out.pos_done += 339 line6pcm->out.pos_done +=
332 length / line6pcm->properties->bytes_per_frame; 340 length / bytes_per_frame;
333 341
334 if (line6pcm->out.pos_done >= runtime->buffer_size) 342 if (line6pcm->out.pos_done >= runtime->buffer_size)
335 line6pcm->out.pos_done -= runtime->buffer_size; 343 line6pcm->out.pos_done -= runtime->buffer_size;
@@ -401,8 +409,13 @@ int line6_create_audio_out_urbs(struct snd_line6_pcm *line6pcm)
401 struct usb_line6 *line6 = line6pcm->line6; 409 struct usb_line6 *line6 = line6pcm->line6;
402 int i; 410 int i;
403 411
412 line6pcm->out.urbs = kzalloc(
413 sizeof(struct urb *) * line6->iso_buffers, GFP_KERNEL);
414 if (line6pcm->out.urbs == NULL)
415 return -ENOMEM;
416
404 /* create audio URBs and fill in constant values: */ 417 /* create audio URBs and fill in constant values: */
405 for (i = 0; i < LINE6_ISO_BUFFERS; ++i) { 418 for (i = 0; i < line6->iso_buffers; ++i) {
406 struct urb *urb; 419 struct urb *urb;
407 420
408 /* URB for audio out: */ 421 /* URB for audio out: */
diff --git a/sound/usb/line6/pod.c b/sound/usb/line6/pod.c
index 45dd34874f43..17aa616e61f5 100644
--- a/sound/usb/line6/pod.c
+++ b/sound/usb/line6/pod.c
@@ -83,7 +83,6 @@ struct usb_line6_pod {
83}; 83};
84 84
85#define POD_SYSEX_CODE 3 85#define POD_SYSEX_CODE 3
86#define POD_BYTES_PER_FRAME 6 /* 24bit audio (stereo) */
87 86
88/* *INDENT-OFF* */ 87/* *INDENT-OFF* */
89 88
@@ -167,7 +166,7 @@ static struct line6_pcm_properties pod_pcm_properties = {
167 .rates = { 166 .rates = {
168 .nrats = 1, 167 .nrats = 1,
169 .rats = &pod_ratden}, 168 .rats = &pod_ratden},
170 .bytes_per_frame = POD_BYTES_PER_FRAME 169 .bytes_per_channel = 3 /* SNDRV_PCM_FMTBIT_S24_3LE */
171}; 170};
172 171
173static const char pod_version_header[] = { 172static const char pod_version_header[] = {
@@ -476,6 +475,7 @@ static const struct line6_properties pod_properties_table[] = {
476 .id = "BassPODxt", 475 .id = "BassPODxt",
477 .name = "BassPODxt", 476 .name = "BassPODxt",
478 .capabilities = LINE6_CAP_CONTROL 477 .capabilities = LINE6_CAP_CONTROL
478 | LINE6_CAP_CONTROL_MIDI
479 | LINE6_CAP_PCM 479 | LINE6_CAP_PCM
480 | LINE6_CAP_HWMON, 480 | LINE6_CAP_HWMON,
481 .altsetting = 5, 481 .altsetting = 5,
@@ -488,6 +488,7 @@ static const struct line6_properties pod_properties_table[] = {
488 .id = "BassPODxtLive", 488 .id = "BassPODxtLive",
489 .name = "BassPODxt Live", 489 .name = "BassPODxt Live",
490 .capabilities = LINE6_CAP_CONTROL 490 .capabilities = LINE6_CAP_CONTROL
491 | LINE6_CAP_CONTROL_MIDI
491 | LINE6_CAP_PCM 492 | LINE6_CAP_PCM
492 | LINE6_CAP_HWMON, 493 | LINE6_CAP_HWMON,
493 .altsetting = 1, 494 .altsetting = 1,
@@ -500,6 +501,7 @@ static const struct line6_properties pod_properties_table[] = {
500 .id = "BassPODxtPro", 501 .id = "BassPODxtPro",
501 .name = "BassPODxt Pro", 502 .name = "BassPODxt Pro",
502 .capabilities = LINE6_CAP_CONTROL 503 .capabilities = LINE6_CAP_CONTROL
504 | LINE6_CAP_CONTROL_MIDI
503 | LINE6_CAP_PCM 505 | LINE6_CAP_PCM
504 | LINE6_CAP_HWMON, 506 | LINE6_CAP_HWMON,
505 .altsetting = 5, 507 .altsetting = 5,
@@ -511,7 +513,8 @@ static const struct line6_properties pod_properties_table[] = {
511 [LINE6_POCKETPOD] = { 513 [LINE6_POCKETPOD] = {
512 .id = "PocketPOD", 514 .id = "PocketPOD",
513 .name = "Pocket POD", 515 .name = "Pocket POD",
514 .capabilities = LINE6_CAP_CONTROL, 516 .capabilities = LINE6_CAP_CONTROL
517 | LINE6_CAP_CONTROL_MIDI,
515 .altsetting = 0, 518 .altsetting = 0,
516 .ep_ctrl_r = 0x82, 519 .ep_ctrl_r = 0x82,
517 .ep_ctrl_w = 0x02, 520 .ep_ctrl_w = 0x02,
@@ -521,6 +524,7 @@ static const struct line6_properties pod_properties_table[] = {
521 .id = "PODxt", 524 .id = "PODxt",
522 .name = "PODxt", 525 .name = "PODxt",
523 .capabilities = LINE6_CAP_CONTROL 526 .capabilities = LINE6_CAP_CONTROL
527 | LINE6_CAP_CONTROL_MIDI
524 | LINE6_CAP_PCM 528 | LINE6_CAP_PCM
525 | LINE6_CAP_HWMON, 529 | LINE6_CAP_HWMON,
526 .altsetting = 5, 530 .altsetting = 5,
@@ -533,6 +537,7 @@ static const struct line6_properties pod_properties_table[] = {
533 .id = "PODxtLive", 537 .id = "PODxtLive",
534 .name = "PODxt Live", 538 .name = "PODxt Live",
535 .capabilities = LINE6_CAP_CONTROL 539 .capabilities = LINE6_CAP_CONTROL
540 | LINE6_CAP_CONTROL_MIDI
536 | LINE6_CAP_PCM 541 | LINE6_CAP_PCM
537 | LINE6_CAP_HWMON, 542 | LINE6_CAP_HWMON,
538 .altsetting = 1, 543 .altsetting = 1,
@@ -545,6 +550,7 @@ static const struct line6_properties pod_properties_table[] = {
545 .id = "PODxtPro", 550 .id = "PODxtPro",
546 .name = "PODxt Pro", 551 .name = "PODxt Pro",
547 .capabilities = LINE6_CAP_CONTROL 552 .capabilities = LINE6_CAP_CONTROL
553 | LINE6_CAP_CONTROL_MIDI
548 | LINE6_CAP_PCM 554 | LINE6_CAP_PCM
549 | LINE6_CAP_HWMON, 555 | LINE6_CAP_HWMON,
550 .altsetting = 5, 556 .altsetting = 5,
diff --git a/sound/usb/line6/podhd.c b/sound/usb/line6/podhd.c
index 63dcaef41ac3..9352a44ae6e4 100644
--- a/sound/usb/line6/podhd.c
+++ b/sound/usb/line6/podhd.c
@@ -2,6 +2,7 @@
2 * Line 6 Pod HD 2 * Line 6 Pod HD
3 * 3 *
4 * Copyright (C) 2011 Stefan Hajnoczi <stefanha@gmail.com> 4 * Copyright (C) 2011 Stefan Hajnoczi <stefanha@gmail.com>
5 * Copyright (C) 2015 Andrej Krutak <dev@andree.sk>
5 * 6 *
6 * This program is free software; you can redistribute it and/or 7 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License as 8 * modify it under the terms of the GNU General Public License as
@@ -18,14 +19,46 @@
18#include "driver.h" 19#include "driver.h"
19#include "pcm.h" 20#include "pcm.h"
20 21
22#define PODHD_STARTUP_DELAY 500
23
24/*
25 * Stages of POD startup procedure
26 */
27enum {
28 PODHD_STARTUP_INIT = 1,
29 PODHD_STARTUP_SCHEDULE_WORKQUEUE,
30 PODHD_STARTUP_SETUP,
31 PODHD_STARTUP_LAST = PODHD_STARTUP_SETUP - 1
32};
33
21enum { 34enum {
22 LINE6_PODHD300, 35 LINE6_PODHD300,
23 LINE6_PODHD400, 36 LINE6_PODHD400,
24 LINE6_PODHD500_0, 37 LINE6_PODHD500_0,
25 LINE6_PODHD500_1, 38 LINE6_PODHD500_1,
39 LINE6_PODX3,
40 LINE6_PODX3LIVE
26}; 41};
27 42
28#define PODHD_BYTES_PER_FRAME 6 /* 24bit audio (stereo) */ 43struct usb_line6_podhd {
44 /* Generic Line 6 USB data */
45 struct usb_line6 line6;
46
47 /* Timer for device initialization */
48 struct timer_list startup_timer;
49
50 /* Work handler for device initialization */
51 struct work_struct startup_work;
52
53 /* Current progress in startup procedure */
54 int startup_progress;
55
56 /* Serial number of device */
57 u32 serial_number;
58
59 /* Firmware version */
60 int firmware_version;
61};
29 62
30static struct snd_ratden podhd_ratden = { 63static struct snd_ratden podhd_ratden = {
31 .num_min = 48000, 64 .num_min = 48000,
@@ -73,29 +106,233 @@ static struct line6_pcm_properties podhd_pcm_properties = {
73 .rates = { 106 .rates = {
74 .nrats = 1, 107 .nrats = 1,
75 .rats = &podhd_ratden}, 108 .rats = &podhd_ratden},
76 .bytes_per_frame = PODHD_BYTES_PER_FRAME 109 .bytes_per_channel = 3 /* SNDRV_PCM_FMTBIT_S24_3LE */
110};
111
112static struct line6_pcm_properties podx3_pcm_properties = {
113 .playback_hw = {
114 .info = (SNDRV_PCM_INFO_MMAP |
115 SNDRV_PCM_INFO_INTERLEAVED |
116 SNDRV_PCM_INFO_BLOCK_TRANSFER |
117 SNDRV_PCM_INFO_MMAP_VALID |
118 SNDRV_PCM_INFO_PAUSE |
119 SNDRV_PCM_INFO_SYNC_START),
120 .formats = SNDRV_PCM_FMTBIT_S24_3LE,
121 .rates = SNDRV_PCM_RATE_48000,
122 .rate_min = 48000,
123 .rate_max = 48000,
124 .channels_min = 2,
125 .channels_max = 2,
126 .buffer_bytes_max = 60000,
127 .period_bytes_min = 64,
128 .period_bytes_max = 8192,
129 .periods_min = 1,
130 .periods_max = 1024},
131 .capture_hw = {
132 .info = (SNDRV_PCM_INFO_MMAP |
133 SNDRV_PCM_INFO_INTERLEAVED |
134 SNDRV_PCM_INFO_BLOCK_TRANSFER |
135 SNDRV_PCM_INFO_MMAP_VALID |
136 SNDRV_PCM_INFO_SYNC_START),
137 .formats = SNDRV_PCM_FMTBIT_S24_3LE,
138 .rates = SNDRV_PCM_RATE_48000,
139 .rate_min = 48000,
140 .rate_max = 48000,
141 /* 1+2: Main signal (out), 3+4: Tone 1,
142 * 5+6: Tone 2, 7+8: raw
143 */
144 .channels_min = 8,
145 .channels_max = 8,
146 .buffer_bytes_max = 60000,
147 .period_bytes_min = 64,
148 .period_bytes_max = 8192,
149 .periods_min = 1,
150 .periods_max = 1024},
151 .rates = {
152 .nrats = 1,
153 .rats = &podhd_ratden},
154 .bytes_per_channel = 3 /* SNDRV_PCM_FMTBIT_S24_3LE */
155};
156
157static void podhd_startup_start_workqueue(unsigned long data);
158static void podhd_startup_workqueue(struct work_struct *work);
159static int podhd_startup_finalize(struct usb_line6_podhd *pod);
160
161static ssize_t serial_number_show(struct device *dev,
162 struct device_attribute *attr, char *buf)
163{
164 struct snd_card *card = dev_to_snd_card(dev);
165 struct usb_line6_podhd *pod = card->private_data;
166
167 return sprintf(buf, "%u\n", pod->serial_number);
168}
169
170static ssize_t firmware_version_show(struct device *dev,
171 struct device_attribute *attr, char *buf)
172{
173 struct snd_card *card = dev_to_snd_card(dev);
174 struct usb_line6_podhd *pod = card->private_data;
175
176 return sprintf(buf, "%06x\n", pod->firmware_version);
177}
178
179static DEVICE_ATTR_RO(firmware_version);
180static DEVICE_ATTR_RO(serial_number);
181
182static struct attribute *podhd_dev_attrs[] = {
183 &dev_attr_firmware_version.attr,
184 &dev_attr_serial_number.attr,
185 NULL
186};
187
188static const struct attribute_group podhd_dev_attr_group = {
189 .name = "podhd",
190 .attrs = podhd_dev_attrs,
77}; 191};
78 192
79/* 193/*
194 * POD X3 startup procedure.
195 *
196 * May be compatible with other POD HD's, since it's also similar to the
197 * previous POD setup. In any case, it doesn't seem to be required for the
198 * audio nor bulk interfaces to work.
199 */
200
201static void podhd_startup(struct usb_line6_podhd *pod)
202{
203 CHECK_STARTUP_PROGRESS(pod->startup_progress, PODHD_STARTUP_INIT);
204
205 /* delay startup procedure: */
206 line6_start_timer(&pod->startup_timer, PODHD_STARTUP_DELAY,
207 podhd_startup_start_workqueue, (unsigned long)pod);
208}
209
210static void podhd_startup_start_workqueue(unsigned long data)
211{
212 struct usb_line6_podhd *pod = (struct usb_line6_podhd *)data;
213
214 CHECK_STARTUP_PROGRESS(pod->startup_progress,
215 PODHD_STARTUP_SCHEDULE_WORKQUEUE);
216
217 /* schedule work for global work queue: */
218 schedule_work(&pod->startup_work);
219}
220
221static int podhd_dev_start(struct usb_line6_podhd *pod)
222{
223 int ret;
224 u8 init_bytes[8];
225 int i;
226 struct usb_device *usbdev = pod->line6.usbdev;
227
228 ret = usb_control_msg(usbdev, usb_sndctrlpipe(usbdev, 0),
229 0x67, USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_OUT,
230 0x11, 0,
231 NULL, 0, LINE6_TIMEOUT * HZ);
232 if (ret < 0) {
233 dev_err(pod->line6.ifcdev, "read request failed (error %d)\n", ret);
234 return ret;
235 }
236
237 /* NOTE: looks like some kind of ping message */
238 ret = usb_control_msg(usbdev, usb_rcvctrlpipe(usbdev, 0), 0x67,
239 USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN,
240 0x11, 0x0,
241 &init_bytes, 3, LINE6_TIMEOUT * HZ);
242 if (ret < 0) {
243 dev_err(pod->line6.ifcdev,
244 "receive length failed (error %d)\n", ret);
245 return ret;
246 }
247
248 pod->firmware_version =
249 (init_bytes[0] << 16) | (init_bytes[1] << 8) | (init_bytes[2] << 0);
250
251 for (i = 0; i <= 16; i++) {
252 ret = line6_read_data(&pod->line6, 0xf000 + 0x08 * i, init_bytes, 8);
253 if (ret < 0)
254 return ret;
255 }
256
257 ret = usb_control_msg(usbdev, usb_sndctrlpipe(usbdev, 0),
258 USB_REQ_SET_FEATURE,
259 USB_TYPE_STANDARD | USB_RECIP_DEVICE | USB_DIR_OUT,
260 1, 0,
261 NULL, 0, LINE6_TIMEOUT * HZ);
262 if (ret < 0)
263 return ret;
264
265 return 0;
266}
267
268static void podhd_startup_workqueue(struct work_struct *work)
269{
270 struct usb_line6_podhd *pod =
271 container_of(work, struct usb_line6_podhd, startup_work);
272
273 CHECK_STARTUP_PROGRESS(pod->startup_progress, PODHD_STARTUP_SETUP);
274
275 podhd_dev_start(pod);
276 line6_read_serial_number(&pod->line6, &pod->serial_number);
277
278 podhd_startup_finalize(pod);
279}
280
281static int podhd_startup_finalize(struct usb_line6_podhd *pod)
282{
283 struct usb_line6 *line6 = &pod->line6;
284
285 /* ALSA audio interface: */
286 return snd_card_register(line6->card);
287}
288
289static void podhd_disconnect(struct usb_line6 *line6)
290{
291 struct usb_line6_podhd *pod = (struct usb_line6_podhd *)line6;
292
293 if (pod->line6.properties->capabilities & LINE6_CAP_CONTROL) {
294 del_timer_sync(&pod->startup_timer);
295 cancel_work_sync(&pod->startup_work);
296 }
297}
298
299/*
80 Try to init POD HD device. 300 Try to init POD HD device.
81*/ 301*/
82static int podhd_init(struct usb_line6 *line6, 302static int podhd_init(struct usb_line6 *line6,
83 const struct usb_device_id *id) 303 const struct usb_device_id *id)
84{ 304{
85 int err; 305 int err;
306 struct usb_line6_podhd *pod = (struct usb_line6_podhd *) line6;
86 307
87 /* initialize MIDI subsystem: */ 308 line6->disconnect = podhd_disconnect;
88 err = line6_init_midi(line6);
89 if (err < 0)
90 return err;
91 309
92 /* initialize PCM subsystem: */ 310 if (pod->line6.properties->capabilities & LINE6_CAP_CONTROL) {
93 err = line6_init_pcm(line6, &podhd_pcm_properties); 311 /* create sysfs entries: */
94 if (err < 0) 312 err = snd_card_add_dev_attr(line6->card, &podhd_dev_attr_group);
95 return err; 313 if (err < 0)
314 return err;
315 }
96 316
97 /* register USB audio system: */ 317 if (pod->line6.properties->capabilities & LINE6_CAP_PCM) {
98 return snd_card_register(line6->card); 318 /* initialize PCM subsystem: */
319 err = line6_init_pcm(line6,
320 (id->driver_info == LINE6_PODX3) ? &podx3_pcm_properties :
321 &podhd_pcm_properties);
322 if (err < 0)
323 return err;
324 }
325
326 if (!(pod->line6.properties->capabilities & LINE6_CAP_CONTROL)) {
327 /* register USB audio system directly */
328 return podhd_startup_finalize(pod);
329 }
330
331 /* init device and delay registering */
332 init_timer(&pod->startup_timer);
333 INIT_WORK(&pod->startup_work, podhd_startup_workqueue);
334 podhd_startup(pod);
335 return 0;
99} 336}
100 337
101#define LINE6_DEVICE(prod) USB_DEVICE(0x0e41, prod) 338#define LINE6_DEVICE(prod) USB_DEVICE(0x0e41, prod)
@@ -103,10 +340,13 @@ static int podhd_init(struct usb_line6 *line6,
103 340
104/* table of devices that work with this driver */ 341/* table of devices that work with this driver */
105static const struct usb_device_id podhd_id_table[] = { 342static const struct usb_device_id podhd_id_table[] = {
343 /* TODO: no need to alloc data interfaces when only audio is used */
106 { LINE6_DEVICE(0x5057), .driver_info = LINE6_PODHD300 }, 344 { LINE6_DEVICE(0x5057), .driver_info = LINE6_PODHD300 },
107 { LINE6_DEVICE(0x5058), .driver_info = LINE6_PODHD400 }, 345 { LINE6_DEVICE(0x5058), .driver_info = LINE6_PODHD400 },
108 { LINE6_IF_NUM(0x414D, 0), .driver_info = LINE6_PODHD500_0 }, 346 { LINE6_IF_NUM(0x414D, 0), .driver_info = LINE6_PODHD500_0 },
109 { LINE6_IF_NUM(0x414D, 1), .driver_info = LINE6_PODHD500_1 }, 347 { LINE6_IF_NUM(0x414D, 1), .driver_info = LINE6_PODHD500_1 },
348 { LINE6_IF_NUM(0x414A, 0), .driver_info = LINE6_PODX3 },
349 { LINE6_IF_NUM(0x414B, 0), .driver_info = LINE6_PODX3LIVE },
110 {} 350 {}
111}; 351};
112 352
@@ -116,8 +356,7 @@ static const struct line6_properties podhd_properties_table[] = {
116 [LINE6_PODHD300] = { 356 [LINE6_PODHD300] = {
117 .id = "PODHD300", 357 .id = "PODHD300",
118 .name = "POD HD300", 358 .name = "POD HD300",
119 .capabilities = LINE6_CAP_CONTROL 359 .capabilities = LINE6_CAP_PCM
120 | LINE6_CAP_PCM
121 | LINE6_CAP_HWMON, 360 | LINE6_CAP_HWMON,
122 .altsetting = 5, 361 .altsetting = 5,
123 .ep_ctrl_r = 0x84, 362 .ep_ctrl_r = 0x84,
@@ -128,8 +367,7 @@ static const struct line6_properties podhd_properties_table[] = {
128 [LINE6_PODHD400] = { 367 [LINE6_PODHD400] = {
129 .id = "PODHD400", 368 .id = "PODHD400",
130 .name = "POD HD400", 369 .name = "POD HD400",
131 .capabilities = LINE6_CAP_CONTROL 370 .capabilities = LINE6_CAP_PCM
132 | LINE6_CAP_PCM
133 | LINE6_CAP_HWMON, 371 | LINE6_CAP_HWMON,
134 .altsetting = 5, 372 .altsetting = 5,
135 .ep_ctrl_r = 0x84, 373 .ep_ctrl_r = 0x84,
@@ -140,8 +378,7 @@ static const struct line6_properties podhd_properties_table[] = {
140 [LINE6_PODHD500_0] = { 378 [LINE6_PODHD500_0] = {
141 .id = "PODHD500", 379 .id = "PODHD500",
142 .name = "POD HD500", 380 .name = "POD HD500",
143 .capabilities = LINE6_CAP_CONTROL 381 .capabilities = LINE6_CAP_PCM
144 | LINE6_CAP_PCM
145 | LINE6_CAP_HWMON, 382 | LINE6_CAP_HWMON,
146 .altsetting = 1, 383 .altsetting = 1,
147 .ep_ctrl_r = 0x81, 384 .ep_ctrl_r = 0x81,
@@ -152,8 +389,7 @@ static const struct line6_properties podhd_properties_table[] = {
152 [LINE6_PODHD500_1] = { 389 [LINE6_PODHD500_1] = {
153 .id = "PODHD500", 390 .id = "PODHD500",
154 .name = "POD HD500", 391 .name = "POD HD500",
155 .capabilities = LINE6_CAP_CONTROL 392 .capabilities = LINE6_CAP_PCM
156 | LINE6_CAP_PCM
157 | LINE6_CAP_HWMON, 393 | LINE6_CAP_HWMON,
158 .altsetting = 1, 394 .altsetting = 1,
159 .ep_ctrl_r = 0x81, 395 .ep_ctrl_r = 0x81,
@@ -161,6 +397,28 @@ static const struct line6_properties podhd_properties_table[] = {
161 .ep_audio_r = 0x86, 397 .ep_audio_r = 0x86,
162 .ep_audio_w = 0x02, 398 .ep_audio_w = 0x02,
163 }, 399 },
400 [LINE6_PODX3] = {
401 .id = "PODX3",
402 .name = "POD X3",
403 .capabilities = LINE6_CAP_CONTROL
404 | LINE6_CAP_PCM | LINE6_CAP_HWMON | LINE6_CAP_IN_NEEDS_OUT,
405 .altsetting = 1,
406 .ep_ctrl_r = 0x81,
407 .ep_ctrl_w = 0x01,
408 .ep_audio_r = 0x86,
409 .ep_audio_w = 0x02,
410 },
411 [LINE6_PODX3LIVE] = {
412 .id = "PODX3LIVE",
413 .name = "POD X3 LIVE",
414 .capabilities = LINE6_CAP_CONTROL
415 | LINE6_CAP_PCM | LINE6_CAP_HWMON | LINE6_CAP_IN_NEEDS_OUT,
416 .altsetting = 1,
417 .ep_ctrl_r = 0x81,
418 .ep_ctrl_w = 0x01,
419 .ep_audio_r = 0x86,
420 .ep_audio_w = 0x02,
421 },
164}; 422};
165 423
166/* 424/*
@@ -171,7 +429,7 @@ static int podhd_probe(struct usb_interface *interface,
171{ 429{
172 return line6_probe(interface, id, "Line6-PODHD", 430 return line6_probe(interface, id, "Line6-PODHD",
173 &podhd_properties_table[id->driver_info], 431 &podhd_properties_table[id->driver_info],
174 podhd_init, sizeof(struct usb_line6)); 432 podhd_init, sizeof(struct usb_line6_podhd));
175} 433}
176 434
177static struct usb_driver podhd_driver = { 435static struct usb_driver podhd_driver = {
diff --git a/sound/usb/line6/toneport.c b/sound/usb/line6/toneport.c
index 6d4c50c9b17d..8e22f430d700 100644
--- a/sound/usb/line6/toneport.c
+++ b/sound/usb/line6/toneport.c
@@ -114,7 +114,7 @@ static struct line6_pcm_properties toneport_pcm_properties = {
114 .rates = { 114 .rates = {
115 .nrats = 1, 115 .nrats = 1,
116 .rats = &toneport_ratden}, 116 .rats = &toneport_ratden},
117 .bytes_per_frame = 4 117 .bytes_per_channel = 2
118}; 118};
119 119
120static const struct { 120static const struct {
@@ -177,7 +177,7 @@ static int snd_toneport_monitor_put(struct snd_kcontrol *kcontrol,
177 line6pcm->volume_monitor = ucontrol->value.integer.value[0]; 177 line6pcm->volume_monitor = ucontrol->value.integer.value[0];
178 178
179 if (line6pcm->volume_monitor > 0) { 179 if (line6pcm->volume_monitor > 0) {
180 err = line6_pcm_acquire(line6pcm, LINE6_STREAM_MONITOR); 180 err = line6_pcm_acquire(line6pcm, LINE6_STREAM_MONITOR, true);
181 if (err < 0) { 181 if (err < 0) {
182 line6pcm->volume_monitor = 0; 182 line6pcm->volume_monitor = 0;
183 line6_pcm_release(line6pcm, LINE6_STREAM_MONITOR); 183 line6_pcm_release(line6pcm, LINE6_STREAM_MONITOR);
@@ -246,7 +246,7 @@ static void toneport_start_pcm(unsigned long arg)
246 struct usb_line6_toneport *toneport = (struct usb_line6_toneport *)arg; 246 struct usb_line6_toneport *toneport = (struct usb_line6_toneport *)arg;
247 struct usb_line6 *line6 = &toneport->line6; 247 struct usb_line6 *line6 = &toneport->line6;
248 248
249 line6_pcm_acquire(line6->line6pcm, LINE6_STREAM_MONITOR); 249 line6_pcm_acquire(line6->line6pcm, LINE6_STREAM_MONITOR, true);
250} 250}
251 251
252/* control definition */ 252/* control definition */
diff --git a/sound/usb/line6/variax.c b/sound/usb/line6/variax.c
index ddc23ddf0750..0c4512d0382e 100644
--- a/sound/usb/line6/variax.c
+++ b/sound/usb/line6/variax.c
@@ -259,7 +259,8 @@ static const struct line6_properties variax_properties_table[] = {
259 [LINE6_PODXTLIVE_VARIAX] = { 259 [LINE6_PODXTLIVE_VARIAX] = {
260 .id = "PODxtLive", 260 .id = "PODxtLive",
261 .name = "PODxt Live", 261 .name = "PODxt Live",
262 .capabilities = LINE6_CAP_CONTROL, 262 .capabilities = LINE6_CAP_CONTROL
263 | LINE6_CAP_CONTROL_MIDI,
263 .altsetting = 1, 264 .altsetting = 1,
264 .ep_ctrl_r = 0x86, 265 .ep_ctrl_r = 0x86,
265 .ep_ctrl_w = 0x05, 266 .ep_ctrl_w = 0x05,
@@ -269,7 +270,8 @@ static const struct line6_properties variax_properties_table[] = {
269 [LINE6_VARIAX] = { 270 [LINE6_VARIAX] = {
270 .id = "Variax", 271 .id = "Variax",
271 .name = "Variax Workbench", 272 .name = "Variax Workbench",
272 .capabilities = LINE6_CAP_CONTROL, 273 .capabilities = LINE6_CAP_CONTROL
274 | LINE6_CAP_CONTROL_MIDI,
273 .altsetting = 1, 275 .altsetting = 1,
274 .ep_ctrl_r = 0x82, 276 .ep_ctrl_r = 0x82,
275 .ep_ctrl_w = 0x01, 277 .ep_ctrl_w = 0x01,
diff --git a/sound/usb/mixer_quirks.c b/sound/usb/mixer_quirks.c
index f6c3bf79af9a..04991b009132 100644
--- a/sound/usb/mixer_quirks.c
+++ b/sound/usb/mixer_quirks.c
@@ -1831,6 +1831,7 @@ void snd_usb_mixer_rc_memory_change(struct usb_mixer_interface *mixer,
1831} 1831}
1832 1832
1833static void snd_dragonfly_quirk_db_scale(struct usb_mixer_interface *mixer, 1833static void snd_dragonfly_quirk_db_scale(struct usb_mixer_interface *mixer,
1834 struct usb_mixer_elem_info *cval,
1834 struct snd_kcontrol *kctl) 1835 struct snd_kcontrol *kctl)
1835{ 1836{
1836 /* Approximation using 10 ranges based on output measurement on hw v1.2. 1837 /* Approximation using 10 ranges based on output measurement on hw v1.2.
@@ -1848,10 +1849,19 @@ static void snd_dragonfly_quirk_db_scale(struct usb_mixer_interface *mixer,
1848 41, 50, TLV_DB_MINMAX_ITEM(-441, 0), 1849 41, 50, TLV_DB_MINMAX_ITEM(-441, 0),
1849 ); 1850 );
1850 1851
1851 usb_audio_info(mixer->chip, "applying DragonFly dB scale quirk\n"); 1852 if (cval->min == 0 && cval->max == 50) {
1852 kctl->tlv.p = scale; 1853 usb_audio_info(mixer->chip, "applying DragonFly dB scale quirk (0-50 variant)\n");
1853 kctl->vd[0].access |= SNDRV_CTL_ELEM_ACCESS_TLV_READ; 1854 kctl->tlv.p = scale;
1854 kctl->vd[0].access &= ~SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK; 1855 kctl->vd[0].access |= SNDRV_CTL_ELEM_ACCESS_TLV_READ;
1856 kctl->vd[0].access &= ~SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK;
1857
1858 } else if (cval->min == 0 && cval->max <= 1000) {
1859 /* Some other clearly broken DragonFly variant.
1860 * At least a 0..53 variant (hw v1.0) exists.
1861 */
1862 usb_audio_info(mixer->chip, "ignoring too narrow dB range on a DragonFly device");
1863 kctl->vd[0].access &= ~SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK;
1864 }
1855} 1865}
1856 1866
1857void snd_usb_mixer_fu_apply_quirk(struct usb_mixer_interface *mixer, 1867void snd_usb_mixer_fu_apply_quirk(struct usb_mixer_interface *mixer,
@@ -1860,8 +1870,8 @@ void snd_usb_mixer_fu_apply_quirk(struct usb_mixer_interface *mixer,
1860{ 1870{
1861 switch (mixer->chip->usb_id) { 1871 switch (mixer->chip->usb_id) {
1862 case USB_ID(0x21b4, 0x0081): /* AudioQuest DragonFly */ 1872 case USB_ID(0x21b4, 0x0081): /* AudioQuest DragonFly */
1863 if (unitid == 7 && cval->min == 0 && cval->max == 50) 1873 if (unitid == 7 && cval->control == UAC_FU_VOLUME)
1864 snd_dragonfly_quirk_db_scale(mixer, kctl); 1874 snd_dragonfly_quirk_db_scale(mixer, cval, kctl);
1865 break; 1875 break;
1866 } 1876 }
1867} 1877}
diff --git a/sound/usb/quirks.c b/sound/usb/quirks.c
index 152292e5ee2b..2782155ae3ce 100644
--- a/sound/usb/quirks.c
+++ b/sound/usb/quirks.c
@@ -1217,6 +1217,12 @@ void snd_usb_endpoint_start_quirk(struct snd_usb_endpoint *ep)
1217 ep->chip->usb_id == USB_ID(0x0763, 0x2031)) && 1217 ep->chip->usb_id == USB_ID(0x0763, 0x2031)) &&
1218 ep->type == SND_USB_ENDPOINT_TYPE_DATA) 1218 ep->type == SND_USB_ENDPOINT_TYPE_DATA)
1219 ep->skip_packets = 16; 1219 ep->skip_packets = 16;
1220
1221 /* Work around devices that report unreasonable feedback data */
1222 if ((ep->chip->usb_id == USB_ID(0x0644, 0x8038) || /* TEAC UD-H01 */
1223 ep->chip->usb_id == USB_ID(0x1852, 0x5034)) && /* T+A Dac8 */
1224 ep->syncmaxsize == 4)
1225 ep->tenor_fb_quirk = 1;
1220} 1226}
1221 1227
1222void snd_usb_set_interface_quirk(struct usb_device *dev) 1228void snd_usb_set_interface_quirk(struct usb_device *dev)