summaryrefslogtreecommitdiffstats
path: root/sound
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2016-01-17 15:05:31 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2016-01-17 15:05:31 -0500
commita016af2e70bfca23f2f5de7d8708157b86ea374d (patch)
treebfe3c0c6ea9d52d4ec6ea021b0626a53c83e7d9f /sound
parente535d74bc50df2357d3253f8f3ca48c66d0d892a (diff)
parentc3b1681375dc6e71d89a3ae00cc3ce9e775a8917 (diff)
Merge tag 'sound-4.5-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound
Pull sound updates from Takashi Iwai: "We've had quite busy weeks in this cycle. Looking at ALSA core, the significant changes are a few fixes wrt timer and sequencer ioctls that have been revealed by fuzzer recently. Other than that, ASoC core got a few updates about DAI link handling, but these are rather straightforward refactoring. In drivers scene, ASoC received quite lots of new drivers in addition to bunch of updates for still ongoing Intel Skylake support and topology API. HD-audio gained a new HDMI/DP hotplug notification via component. FireWire got a pile of code refactoring/updates with SCS.1x driver integration. More highlights are shown below. [ NOTE: this contains also many commits for DRM. This is due to the pull of drm stable branch into sound tree, as the base of i915 audio component work for HD-audio. The highlights below don't contain these DRM changes, as these are supposed to be pulled via drm tree in anyway sooner or later. ] Core: - Handful fixes to harden ALSA timer and sequencer ioctls against races reported by syzkaller fuzzer - Irq description string can be unique to each card; only for HD-audio for now ASoC: - Conversion of the array of DAI links to a list for supporting dynamically adding and removing DAI links - Topology API enhancements to make everything more component based and being able to specify PCM links via topology - Some more fixes for the topology code, though it is still not final and ready for enabling in production; we really need to get to the point where that can be done - A pile of changes for Intel SkyLake drivers which hopefully deliver some useful initial functionality for systems with this chipset, though there is more work still to come - Lots of new features and cleanups for the Renesas drivers - ANC support for WM5110 - New drivers: Imagination Technologies IPs, Atmel class D speaker, Cirrus CS47L24 and WM1831, Dialog DA7128, Realtek RT5659 and RT56156, Rockchip RK3036, TI PC3168A, and AMD ACP - Rename PCM1792a driver to be generic pcm179x HD-Audio: - Use audio component for i915 HDMI/DP hotplug handling - On-demand binding with i915 driver - bdl_pos_adj parameter adjustment for Baytrail controllers - Enable power_save_node for CX20722; this shouldn't lead to regression, hopefully - Kabylake HDMI/DP codec support - Quirks for Lenovo E50-80, Dell Latitude E-series, and other Dell machines - A few code refactoring FireWire: - Lots of code cleanup and refactoring - Integrate the support of SCS.1x devices into snd-oxfw driver; snd-scs1x driver is obsoleted USB-audio: - Fix possible NULL dereference at disconnection - A regression fix for Native Instruments devices Misc: - A few code cleanups of fm801 driver" * tag 'sound-4.5-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound: (722 commits) ALSA: timer: Code cleanup ALSA: timer: Harden slave timer list handling ALSA: hda - Add fixup for Dell Latitidue E6540 ALSA: timer: Fix race among timer ioctls ALSA: hda - add codec support for Kabylake display audio codec ALSA: timer: Fix double unlink of active_list ALSA: usb-audio: Fix mixer ctl regression of Native Instrument devices ALSA: hda - fix the headset mic detection problem for a Dell laptop ALSA: hda - Fix white noise on Dell Latitude E5550 ALSA: hda_intel: add card number to irq description ALSA: seq: Fix race at timer setup and close ALSA: seq: Fix missing NULL check at remove_events ioctl ALSA: usb-audio: Avoid calling usb_autopm_put_interface() at disconnect ASoC: hdac_hdmi: remove unused hdac_hdmi_query_pin_connlist ASoC: AMD: Add missing include file ALSA: hda - Fixup inverted internal mic for Lenovo E50-80 ALSA: usb: Add native DSD support for Oppo HA-1 ASoC: Make aux_dev more like a generic component ASoC: bcm2835: cleanup includes by ordering them alphabetically ASoC: AMD: Manage ACP 2.x SRAM banks power ...
Diffstat (limited to 'sound')
-rw-r--r--sound/core/compress_offload.c99
-rw-r--r--sound/core/init.c3
-rw-r--r--sound/core/oss/mixer_oss.c8
-rw-r--r--sound/core/oss/pcm_oss.c10
-rw-r--r--sound/core/pcm_native.c26
-rw-r--r--sound/core/seq/oss/seq_oss.c7
-rw-r--r--sound/core/seq/seq_clientmgr.c2
-rw-r--r--sound/core/seq/seq_queue.c2
-rw-r--r--sound/core/seq/seq_virmidi.c2
-rw-r--r--sound/core/timer.c76
-rw-r--r--sound/drivers/dummy.c4
-rw-r--r--sound/firewire/Kconfig12
-rw-r--r--sound/firewire/Makefile2
-rw-r--r--sound/firewire/dice/dice-transaction.c123
-rw-r--r--sound/firewire/dice/dice.c227
-rw-r--r--sound/firewire/dice/dice.h3
-rw-r--r--sound/firewire/fireworks/fireworks.h4
-rw-r--r--sound/firewire/fireworks/fireworks_midi.c16
-rw-r--r--sound/firewire/fireworks/fireworks_pcm.c28
-rw-r--r--sound/firewire/fireworks/fireworks_stream.c32
-rw-r--r--sound/firewire/oxfw/Makefile4
-rw-r--r--sound/firewire/oxfw/oxfw-scs1x.c406
-rw-r--r--sound/firewire/oxfw/oxfw-spkr.c (renamed from sound/firewire/oxfw/oxfw-control.c)142
-rw-r--r--sound/firewire/oxfw/oxfw.c110
-rw-r--r--sound/firewire/oxfw/oxfw.h23
-rw-r--r--sound/firewire/scs1x.c530
-rw-r--r--sound/hda/ext/hdac_ext_controller.c29
-rw-r--r--sound/hda/ext/hdac_ext_stream.c72
-rw-r--r--sound/hda/hdac_i915.c66
-rw-r--r--sound/i2c/i2c.c2
-rw-r--r--sound/oss/Kconfig2
-rw-r--r--sound/pci/atiixp.c6
-rw-r--r--sound/pci/atiixp_modem.c4
-rw-r--r--sound/pci/azt3328.c2
-rw-r--r--sound/pci/cs5535audio/cs5535audio_pcm.c4
-rw-r--r--sound/pci/fm801.c145
-rw-r--r--sound/pci/hda/hda_controller.c10
-rw-r--r--sound/pci/hda/hda_controller.h14
-rw-r--r--sound/pci/hda/hda_eld.c1
-rw-r--r--sound/pci/hda/hda_generic.c108
-rw-r--r--sound/pci/hda/hda_generic.h5
-rw-r--r--sound/pci/hda/hda_intel.c78
-rw-r--r--sound/pci/hda/hda_tegra.c5
-rw-r--r--sound/pci/hda/patch_conexant.c3
-rw-r--r--sound/pci/hda/patch_hdmi.c245
-rw-r--r--sound/pci/hda/patch_realtek.c14
-rw-r--r--sound/pci/ice1712/delta.c2
-rw-r--r--sound/soc/Kconfig2
-rw-r--r--sound/soc/Makefile2
-rw-r--r--sound/soc/amd/Kconfig4
-rw-r--r--sound/soc/amd/Makefile3
-rw-r--r--sound/soc/amd/acp-pcm-dma.c1043
-rw-r--r--sound/soc/amd/acp.h118
-rw-r--r--sound/soc/amd/include/acp_2_2_d.h609
-rw-r--r--sound/soc/amd/include/acp_2_2_enum.h1068
-rw-r--r--sound/soc/amd/include/acp_2_2_sh_mask.h2292
-rw-r--r--sound/soc/atmel/Kconfig9
-rw-r--r--sound/soc/atmel/Makefile2
-rw-r--r--sound/soc/atmel/atmel-classd.c26
-rw-r--r--sound/soc/atmel/atmel-pdmic.c738
-rw-r--r--sound/soc/atmel/atmel-pdmic.h80
-rw-r--r--sound/soc/atmel/atmel_wm8904.c1
-rw-r--r--sound/soc/bcm/bcm2835-i2s.c12
-rw-r--r--sound/soc/codecs/Kconfig62
-rw-r--r--sound/soc/codecs/Makefile22
-rw-r--r--sound/soc/codecs/ak4613.c118
-rw-r--r--sound/soc/codecs/arizona.c146
-rw-r--r--sound/soc/codecs/arizona.h17
-rw-r--r--sound/soc/codecs/cs47l24.c1148
-rw-r--r--sound/soc/codecs/cs47l24.h23
-rw-r--r--sound/soc/codecs/da7218.c3341
-rw-r--r--sound/soc/codecs/da7218.h1414
-rw-r--r--sound/soc/codecs/da7219.c163
-rw-r--r--sound/soc/codecs/da7219.h9
-rw-r--r--sound/soc/codecs/hdac_hdmi.c697
-rw-r--r--sound/soc/codecs/inno_rk3036.c490
-rw-r--r--sound/soc/codecs/inno_rk3036.h123
-rw-r--r--sound/soc/codecs/max98357a.c10
-rw-r--r--sound/soc/codecs/pcm1792a.c271
-rw-r--r--sound/soc/codecs/pcm179x.c271
-rw-r--r--sound/soc/codecs/pcm179x.h (renamed from sound/soc/codecs/pcm1792a.h)6
-rw-r--r--sound/soc/codecs/pcm3168a-i2c.c66
-rw-r--r--sound/soc/codecs/pcm3168a-spi.c65
-rw-r--r--sound/soc/codecs/pcm3168a.c767
-rw-r--r--sound/soc/codecs/pcm3168a.h100
-rw-r--r--sound/soc/codecs/rt286.c6
-rw-r--r--sound/soc/codecs/rt298.c2
-rw-r--r--sound/soc/codecs/rt5616.c1381
-rw-r--r--sound/soc/codecs/rt5616.h1819
-rw-r--r--sound/soc/codecs/rt5640.c103
-rw-r--r--sound/soc/codecs/rt5640.h17
-rw-r--r--sound/soc/codecs/rt5645.c322
-rw-r--r--sound/soc/codecs/rt5651.c31
-rw-r--r--sound/soc/codecs/rt5659.c4223
-rw-r--r--sound/soc/codecs/rt5659.h1819
-rw-r--r--sound/soc/codecs/rt5677.c13
-rw-r--r--sound/soc/codecs/ssm2518.c2
-rw-r--r--sound/soc/codecs/twl6040.c3
-rw-r--r--sound/soc/codecs/wm5110.c252
-rw-r--r--sound/soc/codecs/wm8903.c2
-rw-r--r--sound/soc/codecs/wm8904.c2
-rw-r--r--sound/soc/codecs/wm8960.c24
-rw-r--r--sound/soc/codecs/wm8962.c3
-rw-r--r--sound/soc/codecs/wm8974.c7
-rw-r--r--sound/soc/codecs/wm8998.c46
-rw-r--r--sound/soc/codecs/wm9713.c296
-rw-r--r--sound/soc/codecs/wm_adsp.c1095
-rw-r--r--sound/soc/codecs/wm_adsp.h28
-rw-r--r--sound/soc/dwc/designware_i2s.c117
-rw-r--r--sound/soc/fsl/fsl-asoc-card.c21
-rw-r--r--sound/soc/fsl/fsl_asrc.c62
-rw-r--r--sound/soc/fsl/fsl_asrc.h9
-rw-r--r--sound/soc/fsl/fsl_esai.c63
-rw-r--r--sound/soc/fsl/fsl_sai.c98
-rw-r--r--sound/soc/fsl/fsl_sai.h3
-rw-r--r--sound/soc/fsl/fsl_spdif.c35
-rw-r--r--sound/soc/fsl/fsl_ssi.c49
-rw-r--r--sound/soc/fsl/imx-pcm-dma.c2
-rw-r--r--sound/soc/fsl/imx-pcm-fiq.c4
-rw-r--r--sound/soc/fsl/imx-wm8962.c10
-rw-r--r--sound/soc/fsl/mpc8610_hpcd.c3
-rw-r--r--sound/soc/fsl/p1022_ds.c3
-rw-r--r--sound/soc/fsl/p1022_rdk.c3
-rw-r--r--sound/soc/generic/simple-card.c12
-rw-r--r--sound/soc/img/Kconfig52
-rw-r--r--sound/soc/img/Makefile7
-rw-r--r--sound/soc/img/img-i2s-in.c516
-rw-r--r--sound/soc/img/img-i2s-out.c565
-rw-r--r--sound/soc/img/img-parallel-out.c327
-rw-r--r--sound/soc/img/img-spdif-in.c806
-rw-r--r--sound/soc/img/img-spdif-out.c441
-rw-r--r--sound/soc/img/pistachio-internal-dac.c287
-rw-r--r--sound/soc/intel/Kconfig58
-rw-r--r--sound/soc/intel/atom/sst-atom-controls.c5
-rw-r--r--sound/soc/intel/atom/sst-atom-controls.h1
-rw-r--r--sound/soc/intel/atom/sst-mfld-platform-pcm.c32
-rw-r--r--sound/soc/intel/atom/sst/sst_acpi.c82
-rw-r--r--sound/soc/intel/atom/sst/sst_stream.c2
-rw-r--r--sound/soc/intel/baytrail/sst-baytrail-pcm.c2
-rw-r--r--sound/soc/intel/boards/Makefile6
-rw-r--r--sound/soc/intel/boards/bytcr_rt5640.c266
-rw-r--r--sound/soc/intel/boards/bytcr_rt5651.c332
-rw-r--r--sound/soc/intel/boards/cht_bsw_max98090_ti.c19
-rw-r--r--sound/soc/intel/boards/cht_bsw_rt5645.c19
-rw-r--r--sound/soc/intel/boards/cht_bsw_rt5672.c19
-rw-r--r--sound/soc/intel/boards/skl_nau88l25_max98357a.c485
-rw-r--r--sound/soc/intel/boards/skl_nau88l25_ssm4567.c536
-rw-r--r--sound/soc/intel/boards/skl_rt286.c128
-rw-r--r--sound/soc/intel/common/Makefile12
-rw-r--r--sound/soc/intel/common/sst-acpi.c41
-rw-r--r--sound/soc/intel/common/sst-acpi.h33
-rw-r--r--sound/soc/intel/common/sst-dsp-priv.h8
-rw-r--r--sound/soc/intel/common/sst-dsp.c2
-rw-r--r--sound/soc/intel/common/sst-dsp.h2
-rw-r--r--sound/soc/intel/common/sst-firmware.c20
-rw-r--r--sound/soc/intel/common/sst-match-acpi.c43
-rw-r--r--sound/soc/intel/haswell/sst-haswell-dsp.c2
-rw-r--r--sound/soc/intel/haswell/sst-haswell-ipc.c31
-rw-r--r--sound/soc/intel/skylake/skl-messages.c280
-rw-r--r--sound/soc/intel/skylake/skl-nhlt.c19
-rw-r--r--sound/soc/intel/skylake/skl-pcm.c310
-rw-r--r--sound/soc/intel/skylake/skl-sst-cldma.c97
-rw-r--r--sound/soc/intel/skylake/skl-sst-dsp.h21
-rw-r--r--sound/soc/intel/skylake/skl-sst-ipc.c123
-rw-r--r--sound/soc/intel/skylake/skl-sst-ipc.h14
-rw-r--r--sound/soc/intel/skylake/skl-sst.c217
-rw-r--r--sound/soc/intel/skylake/skl-topology.c658
-rw-r--r--sound/soc/intel/skylake/skl-topology.h63
-rw-r--r--sound/soc/intel/skylake/skl-tplg-interface.h105
-rw-r--r--sound/soc/intel/skylake/skl.c213
-rw-r--r--sound/soc/intel/skylake/skl.h8
-rw-r--r--sound/soc/mediatek/mtk-afe-common.h1
-rw-r--r--sound/soc/mediatek/mtk-afe-pcm.c59
-rw-r--r--sound/soc/omap/omap-hdmi-audio.c2
-rw-r--r--sound/soc/pxa/brownstone.c3
-rw-r--r--sound/soc/pxa/mioa701_wm9713.c6
-rw-r--r--sound/soc/qcom/lpass-cpu.c1
-rw-r--r--sound/soc/rockchip/rockchip_i2s.c139
-rw-r--r--sound/soc/rockchip/rockchip_max98090.c6
-rw-r--r--sound/soc/rockchip/rockchip_rt5645.c6
-rw-r--r--sound/soc/samsung/Kconfig2
-rw-r--r--sound/soc/samsung/ac97.c29
-rw-r--r--sound/soc/samsung/bells.c40
-rw-r--r--sound/soc/samsung/dma.h6
-rw-r--r--sound/soc/samsung/dmaengine.c20
-rw-r--r--sound/soc/samsung/i2s.c31
-rw-r--r--sound/soc/samsung/littlemill.c32
-rw-r--r--sound/soc/samsung/odroidx2_max98090.c9
-rw-r--r--sound/soc/samsung/pcm.c25
-rw-r--r--sound/soc/samsung/s3c2412-i2s.c16
-rw-r--r--sound/soc/samsung/s3c24xx-i2s.c16
-rw-r--r--sound/soc/samsung/snow.c9
-rw-r--r--sound/soc/samsung/spdif.c17
-rw-r--r--sound/soc/samsung/speyside.c12
-rw-r--r--sound/soc/samsung/tobermory.c21
-rw-r--r--sound/soc/sh/Kconfig1
-rw-r--r--sound/soc/sh/fsi.c11
-rw-r--r--sound/soc/sh/rcar/Makefile2
-rw-r--r--sound/soc/sh/rcar/adg.c118
-rw-r--r--sound/soc/sh/rcar/cmd.c171
-rw-r--r--sound/soc/sh/rcar/core.c586
-rw-r--r--sound/soc/sh/rcar/ctu.c99
-rw-r--r--sound/soc/sh/rcar/dma.c245
-rw-r--r--sound/soc/sh/rcar/dvc.c273
-rw-r--r--sound/soc/sh/rcar/gen.c133
-rw-r--r--sound/soc/sh/rcar/mix.c158
-rw-r--r--sound/soc/sh/rcar/rcar_snd.h117
-rw-r--r--sound/soc/sh/rcar/rsnd.h335
-rw-r--r--sound/soc/sh/rcar/rsrc-card.c129
-rw-r--r--sound/soc/sh/rcar/src.c898
-rw-r--r--sound/soc/sh/rcar/ssi.c755
-rw-r--r--sound/soc/sh/rcar/ssiu.c225
-rw-r--r--sound/soc/soc-ac97.c125
-rw-r--r--sound/soc/soc-compress.c31
-rw-r--r--sound/soc/soc-core.c866
-rw-r--r--sound/soc/soc-dapm.c14
-rw-r--r--sound/soc/soc-ops.c4
-rw-r--r--sound/soc/soc-pcm.c110
-rw-r--r--sound/soc/sti/uniperif_player.c3
-rw-r--r--sound/soc/sunxi/sun4i-codec.c279
-rw-r--r--sound/soc/tegra/tegra_alc5632.c12
-rw-r--r--sound/soc/tegra/tegra_wm8903.c3
-rw-r--r--sound/synth/emux/emux_nrpn.c9
-rw-r--r--sound/usb/card.c2
-rw-r--r--sound/usb/midi.c27
-rw-r--r--sound/usb/misc/ua101.c4
-rw-r--r--sound/usb/mixer_quirks.c2
-rw-r--r--sound/usb/quirks.c1
-rw-r--r--sound/usb/stream.c6
-rw-r--r--sound/usb/usx2y/usbusx2yaudio.c2
230 files changed, 37942 insertions, 5683 deletions
diff --git a/sound/core/compress_offload.c b/sound/core/compress_offload.c
index b123c42e7dc8..18b8dc45bb8f 100644
--- a/sound/core/compress_offload.c
+++ b/sound/core/compress_offload.c
@@ -38,8 +38,10 @@
38#include <linux/uio.h> 38#include <linux/uio.h>
39#include <linux/uaccess.h> 39#include <linux/uaccess.h>
40#include <linux/module.h> 40#include <linux/module.h>
41#include <linux/compat.h>
41#include <sound/core.h> 42#include <sound/core.h>
42#include <sound/initval.h> 43#include <sound/initval.h>
44#include <sound/info.h>
43#include <sound/compress_params.h> 45#include <sound/compress_params.h>
44#include <sound/compress_offload.h> 46#include <sound/compress_offload.h>
45#include <sound/compress_driver.h> 47#include <sound/compress_driver.h>
@@ -847,6 +849,15 @@ static long snd_compr_ioctl(struct file *f, unsigned int cmd, unsigned long arg)
847 return retval; 849 return retval;
848} 850}
849 851
852/* support of 32bit userspace on 64bit platforms */
853#ifdef CONFIG_COMPAT
854static long snd_compr_ioctl_compat(struct file *file, unsigned int cmd,
855 unsigned long arg)
856{
857 return snd_compr_ioctl(file, cmd, (unsigned long)compat_ptr(arg));
858}
859#endif
860
850static const struct file_operations snd_compr_file_ops = { 861static const struct file_operations snd_compr_file_ops = {
851 .owner = THIS_MODULE, 862 .owner = THIS_MODULE,
852 .open = snd_compr_open, 863 .open = snd_compr_open,
@@ -854,6 +865,9 @@ static const struct file_operations snd_compr_file_ops = {
854 .write = snd_compr_write, 865 .write = snd_compr_write,
855 .read = snd_compr_read, 866 .read = snd_compr_read,
856 .unlocked_ioctl = snd_compr_ioctl, 867 .unlocked_ioctl = snd_compr_ioctl,
868#ifdef CONFIG_COMPAT
869 .compat_ioctl = snd_compr_ioctl_compat,
870#endif
857 .mmap = snd_compr_mmap, 871 .mmap = snd_compr_mmap,
858 .poll = snd_compr_poll, 872 .poll = snd_compr_poll,
859}; 873};
@@ -891,11 +905,85 @@ static int snd_compress_dev_disconnect(struct snd_device *device)
891 return 0; 905 return 0;
892} 906}
893 907
908#ifdef CONFIG_SND_VERBOSE_PROCFS
909static void snd_compress_proc_info_read(struct snd_info_entry *entry,
910 struct snd_info_buffer *buffer)
911{
912 struct snd_compr *compr = (struct snd_compr *)entry->private_data;
913
914 snd_iprintf(buffer, "card: %d\n", compr->card->number);
915 snd_iprintf(buffer, "device: %d\n", compr->device);
916 snd_iprintf(buffer, "stream: %s\n",
917 compr->direction == SND_COMPRESS_PLAYBACK
918 ? "PLAYBACK" : "CAPTURE");
919 snd_iprintf(buffer, "id: %s\n", compr->id);
920}
921
922static int snd_compress_proc_init(struct snd_compr *compr)
923{
924 struct snd_info_entry *entry;
925 char name[16];
926
927 sprintf(name, "compr%i", compr->device);
928 entry = snd_info_create_card_entry(compr->card, name,
929 compr->card->proc_root);
930 if (!entry)
931 return -ENOMEM;
932 entry->mode = S_IFDIR | S_IRUGO | S_IXUGO;
933 if (snd_info_register(entry) < 0) {
934 snd_info_free_entry(entry);
935 return -ENOMEM;
936 }
937 compr->proc_root = entry;
938
939 entry = snd_info_create_card_entry(compr->card, "info",
940 compr->proc_root);
941 if (entry) {
942 snd_info_set_text_ops(entry, compr,
943 snd_compress_proc_info_read);
944 if (snd_info_register(entry) < 0) {
945 snd_info_free_entry(entry);
946 entry = NULL;
947 }
948 }
949 compr->proc_info_entry = entry;
950
951 return 0;
952}
953
954static void snd_compress_proc_done(struct snd_compr *compr)
955{
956 snd_info_free_entry(compr->proc_info_entry);
957 compr->proc_info_entry = NULL;
958 snd_info_free_entry(compr->proc_root);
959 compr->proc_root = NULL;
960}
961
962static inline void snd_compress_set_id(struct snd_compr *compr, const char *id)
963{
964 strlcpy(compr->id, id, sizeof(compr->id));
965}
966#else
967static inline int snd_compress_proc_init(struct snd_compr *compr)
968{
969 return 0;
970}
971
972static inline void snd_compress_proc_done(struct snd_compr *compr)
973{
974}
975
976static inline void snd_compress_set_id(struct snd_compr *compr, const char *id)
977{
978}
979#endif
980
894static int snd_compress_dev_free(struct snd_device *device) 981static int snd_compress_dev_free(struct snd_device *device)
895{ 982{
896 struct snd_compr *compr; 983 struct snd_compr *compr;
897 984
898 compr = device->device_data; 985 compr = device->device_data;
986 snd_compress_proc_done(compr);
899 put_device(&compr->dev); 987 put_device(&compr->dev);
900 return 0; 988 return 0;
901} 989}
@@ -908,22 +996,29 @@ static int snd_compress_dev_free(struct snd_device *device)
908 * @compr: compress device pointer 996 * @compr: compress device pointer
909 */ 997 */
910int snd_compress_new(struct snd_card *card, int device, 998int snd_compress_new(struct snd_card *card, int device,
911 int dirn, struct snd_compr *compr) 999 int dirn, const char *id, struct snd_compr *compr)
912{ 1000{
913 static struct snd_device_ops ops = { 1001 static struct snd_device_ops ops = {
914 .dev_free = snd_compress_dev_free, 1002 .dev_free = snd_compress_dev_free,
915 .dev_register = snd_compress_dev_register, 1003 .dev_register = snd_compress_dev_register,
916 .dev_disconnect = snd_compress_dev_disconnect, 1004 .dev_disconnect = snd_compress_dev_disconnect,
917 }; 1005 };
1006 int ret;
918 1007
919 compr->card = card; 1008 compr->card = card;
920 compr->device = device; 1009 compr->device = device;
921 compr->direction = dirn; 1010 compr->direction = dirn;
922 1011
1012 snd_compress_set_id(compr, id);
1013
923 snd_device_initialize(&compr->dev, card); 1014 snd_device_initialize(&compr->dev, card);
924 dev_set_name(&compr->dev, "comprC%iD%i", card->number, device); 1015 dev_set_name(&compr->dev, "comprC%iD%i", card->number, device);
925 1016
926 return snd_device_new(card, SNDRV_DEV_COMPRESS, compr, &ops); 1017 ret = snd_device_new(card, SNDRV_DEV_COMPRESS, compr, &ops);
1018 if (ret == 0)
1019 snd_compress_proc_init(compr);
1020
1021 return ret;
927} 1022}
928EXPORT_SYMBOL_GPL(snd_compress_new); 1023EXPORT_SYMBOL_GPL(snd_compress_new);
929 1024
diff --git a/sound/core/init.c b/sound/core/init.c
index 20f37fb3800e..6bda8436d765 100644
--- a/sound/core/init.c
+++ b/sound/core/init.c
@@ -268,6 +268,9 @@ int snd_card_new(struct device *parent, int idx, const char *xid,
268 if (err < 0) 268 if (err < 0)
269 goto __error; 269 goto __error;
270 270
271 snprintf(card->irq_descr, sizeof(card->irq_descr), "%s:%s",
272 dev_driver_string(card->dev), dev_name(&card->card_dev));
273
271 /* the control interface cannot be accessed from the user space until */ 274 /* the control interface cannot be accessed from the user space until */
272 /* snd_cards_bitmask and snd_cards are set with snd_card_register */ 275 /* snd_cards_bitmask and snd_cards are set with snd_card_register */
273 err = snd_ctl_create(card); 276 err = snd_ctl_create(card);
diff --git a/sound/core/oss/mixer_oss.c b/sound/core/oss/mixer_oss.c
index 7a8c79dd9734..2ff9c12d664a 100644
--- a/sound/core/oss/mixer_oss.c
+++ b/sound/core/oss/mixer_oss.c
@@ -24,6 +24,7 @@
24#include <linux/time.h> 24#include <linux/time.h>
25#include <linux/string.h> 25#include <linux/string.h>
26#include <linux/module.h> 26#include <linux/module.h>
27#include <linux/compat.h>
27#include <sound/core.h> 28#include <sound/core.h>
28#include <sound/minors.h> 29#include <sound/minors.h>
29#include <sound/control.h> 30#include <sound/control.h>
@@ -397,7 +398,12 @@ int snd_mixer_oss_ioctl_card(struct snd_card *card, unsigned int cmd, unsigned l
397 398
398#ifdef CONFIG_COMPAT 399#ifdef CONFIG_COMPAT
399/* all compatible */ 400/* all compatible */
400#define snd_mixer_oss_ioctl_compat snd_mixer_oss_ioctl 401static long snd_mixer_oss_ioctl_compat(struct file *file, unsigned int cmd,
402 unsigned long arg)
403{
404 return snd_mixer_oss_ioctl1(file->private_data, cmd,
405 (unsigned long)compat_ptr(arg));
406}
401#else 407#else
402#define snd_mixer_oss_ioctl_compat NULL 408#define snd_mixer_oss_ioctl_compat NULL
403#endif 409#endif
diff --git a/sound/core/oss/pcm_oss.c b/sound/core/oss/pcm_oss.c
index 58550cc93f28..0e73d03b30e3 100644
--- a/sound/core/oss/pcm_oss.c
+++ b/sound/core/oss/pcm_oss.c
@@ -33,6 +33,7 @@
33#include <linux/module.h> 33#include <linux/module.h>
34#include <linux/math64.h> 34#include <linux/math64.h>
35#include <linux/string.h> 35#include <linux/string.h>
36#include <linux/compat.h>
36#include <sound/core.h> 37#include <sound/core.h>
37#include <sound/minors.h> 38#include <sound/minors.h>
38#include <sound/pcm.h> 39#include <sound/pcm.h>
@@ -850,7 +851,7 @@ static int snd_pcm_oss_change_params(struct snd_pcm_substream *substream)
850 851
851 if (mutex_lock_interruptible(&runtime->oss.params_lock)) 852 if (mutex_lock_interruptible(&runtime->oss.params_lock))
852 return -EINTR; 853 return -EINTR;
853 sw_params = kmalloc(sizeof(*sw_params), GFP_KERNEL); 854 sw_params = kzalloc(sizeof(*sw_params), GFP_KERNEL);
854 params = kmalloc(sizeof(*params), GFP_KERNEL); 855 params = kmalloc(sizeof(*params), GFP_KERNEL);
855 sparams = kmalloc(sizeof(*sparams), GFP_KERNEL); 856 sparams = kmalloc(sizeof(*sparams), GFP_KERNEL);
856 if (!sw_params || !params || !sparams) { 857 if (!sw_params || !params || !sparams) {
@@ -988,7 +989,6 @@ static int snd_pcm_oss_change_params(struct snd_pcm_substream *substream)
988 goto failure; 989 goto failure;
989 } 990 }
990 991
991 memset(sw_params, 0, sizeof(*sw_params));
992 if (runtime->oss.trigger) { 992 if (runtime->oss.trigger) {
993 sw_params->start_threshold = 1; 993 sw_params->start_threshold = 1;
994 } else { 994 } else {
@@ -2648,7 +2648,11 @@ static long snd_pcm_oss_ioctl(struct file *file, unsigned int cmd, unsigned long
2648 2648
2649#ifdef CONFIG_COMPAT 2649#ifdef CONFIG_COMPAT
2650/* all compatible */ 2650/* all compatible */
2651#define snd_pcm_oss_ioctl_compat snd_pcm_oss_ioctl 2651static long snd_pcm_oss_ioctl_compat(struct file *file, unsigned int cmd,
2652 unsigned long arg)
2653{
2654 return snd_pcm_oss_ioctl(file, cmd, (unsigned long)compat_ptr(arg));
2655}
2652#else 2656#else
2653#define snd_pcm_oss_ioctl_compat NULL 2657#define snd_pcm_oss_ioctl_compat NULL
2654#endif 2658#endif
diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c
index a8b27cdc2844..fadd3eb8e8bb 100644
--- a/sound/core/pcm_native.c
+++ b/sound/core/pcm_native.c
@@ -875,7 +875,7 @@ struct action_ops {
875 * Note: the stream state might be changed also on failure 875 * Note: the stream state might be changed also on failure
876 * Note2: call with calling stream lock + link lock 876 * Note2: call with calling stream lock + link lock
877 */ 877 */
878static int snd_pcm_action_group(struct action_ops *ops, 878static int snd_pcm_action_group(const struct action_ops *ops,
879 struct snd_pcm_substream *substream, 879 struct snd_pcm_substream *substream,
880 int state, int do_lock) 880 int state, int do_lock)
881{ 881{
@@ -932,7 +932,7 @@ static int snd_pcm_action_group(struct action_ops *ops,
932/* 932/*
933 * Note: call with stream lock 933 * Note: call with stream lock
934 */ 934 */
935static int snd_pcm_action_single(struct action_ops *ops, 935static int snd_pcm_action_single(const struct action_ops *ops,
936 struct snd_pcm_substream *substream, 936 struct snd_pcm_substream *substream,
937 int state) 937 int state)
938{ 938{
@@ -952,7 +952,7 @@ static int snd_pcm_action_single(struct action_ops *ops,
952/* 952/*
953 * Note: call with stream lock 953 * Note: call with stream lock
954 */ 954 */
955static int snd_pcm_action(struct action_ops *ops, 955static int snd_pcm_action(const struct action_ops *ops,
956 struct snd_pcm_substream *substream, 956 struct snd_pcm_substream *substream,
957 int state) 957 int state)
958{ 958{
@@ -984,7 +984,7 @@ static int snd_pcm_action(struct action_ops *ops,
984/* 984/*
985 * Note: don't use any locks before 985 * Note: don't use any locks before
986 */ 986 */
987static int snd_pcm_action_lock_irq(struct action_ops *ops, 987static int snd_pcm_action_lock_irq(const struct action_ops *ops,
988 struct snd_pcm_substream *substream, 988 struct snd_pcm_substream *substream,
989 int state) 989 int state)
990{ 990{
@@ -998,7 +998,7 @@ static int snd_pcm_action_lock_irq(struct action_ops *ops,
998 998
999/* 999/*
1000 */ 1000 */
1001static int snd_pcm_action_nonatomic(struct action_ops *ops, 1001static int snd_pcm_action_nonatomic(const struct action_ops *ops,
1002 struct snd_pcm_substream *substream, 1002 struct snd_pcm_substream *substream,
1003 int state) 1003 int state)
1004{ 1004{
@@ -1056,7 +1056,7 @@ static void snd_pcm_post_start(struct snd_pcm_substream *substream, int state)
1056 snd_pcm_timer_notify(substream, SNDRV_TIMER_EVENT_MSTART); 1056 snd_pcm_timer_notify(substream, SNDRV_TIMER_EVENT_MSTART);
1057} 1057}
1058 1058
1059static struct action_ops snd_pcm_action_start = { 1059static const struct action_ops snd_pcm_action_start = {
1060 .pre_action = snd_pcm_pre_start, 1060 .pre_action = snd_pcm_pre_start,
1061 .do_action = snd_pcm_do_start, 1061 .do_action = snd_pcm_do_start,
1062 .undo_action = snd_pcm_undo_start, 1062 .undo_action = snd_pcm_undo_start,
@@ -1107,7 +1107,7 @@ static void snd_pcm_post_stop(struct snd_pcm_substream *substream, int state)
1107 wake_up(&runtime->tsleep); 1107 wake_up(&runtime->tsleep);
1108} 1108}
1109 1109
1110static struct action_ops snd_pcm_action_stop = { 1110static const struct action_ops snd_pcm_action_stop = {
1111 .pre_action = snd_pcm_pre_stop, 1111 .pre_action = snd_pcm_pre_stop,
1112 .do_action = snd_pcm_do_stop, 1112 .do_action = snd_pcm_do_stop,
1113 .post_action = snd_pcm_post_stop 1113 .post_action = snd_pcm_post_stop
@@ -1224,7 +1224,7 @@ static void snd_pcm_post_pause(struct snd_pcm_substream *substream, int push)
1224 } 1224 }
1225} 1225}
1226 1226
1227static struct action_ops snd_pcm_action_pause = { 1227static const struct action_ops snd_pcm_action_pause = {
1228 .pre_action = snd_pcm_pre_pause, 1228 .pre_action = snd_pcm_pre_pause,
1229 .do_action = snd_pcm_do_pause, 1229 .do_action = snd_pcm_do_pause,
1230 .undo_action = snd_pcm_undo_pause, 1230 .undo_action = snd_pcm_undo_pause,
@@ -1273,7 +1273,7 @@ static void snd_pcm_post_suspend(struct snd_pcm_substream *substream, int state)
1273 wake_up(&runtime->tsleep); 1273 wake_up(&runtime->tsleep);
1274} 1274}
1275 1275
1276static struct action_ops snd_pcm_action_suspend = { 1276static const struct action_ops snd_pcm_action_suspend = {
1277 .pre_action = snd_pcm_pre_suspend, 1277 .pre_action = snd_pcm_pre_suspend,
1278 .do_action = snd_pcm_do_suspend, 1278 .do_action = snd_pcm_do_suspend,
1279 .post_action = snd_pcm_post_suspend 1279 .post_action = snd_pcm_post_suspend
@@ -1375,7 +1375,7 @@ static void snd_pcm_post_resume(struct snd_pcm_substream *substream, int state)
1375 snd_pcm_timer_notify(substream, SNDRV_TIMER_EVENT_MRESUME); 1375 snd_pcm_timer_notify(substream, SNDRV_TIMER_EVENT_MRESUME);
1376} 1376}
1377 1377
1378static struct action_ops snd_pcm_action_resume = { 1378static const struct action_ops snd_pcm_action_resume = {
1379 .pre_action = snd_pcm_pre_resume, 1379 .pre_action = snd_pcm_pre_resume,
1380 .do_action = snd_pcm_do_resume, 1380 .do_action = snd_pcm_do_resume,
1381 .undo_action = snd_pcm_undo_resume, 1381 .undo_action = snd_pcm_undo_resume,
@@ -1478,7 +1478,7 @@ static void snd_pcm_post_reset(struct snd_pcm_substream *substream, int state)
1478 snd_pcm_playback_silence(substream, ULONG_MAX); 1478 snd_pcm_playback_silence(substream, ULONG_MAX);
1479} 1479}
1480 1480
1481static struct action_ops snd_pcm_action_reset = { 1481static const struct action_ops snd_pcm_action_reset = {
1482 .pre_action = snd_pcm_pre_reset, 1482 .pre_action = snd_pcm_pre_reset,
1483 .do_action = snd_pcm_do_reset, 1483 .do_action = snd_pcm_do_reset,
1484 .post_action = snd_pcm_post_reset 1484 .post_action = snd_pcm_post_reset
@@ -1522,7 +1522,7 @@ static void snd_pcm_post_prepare(struct snd_pcm_substream *substream, int state)
1522 snd_pcm_set_state(substream, SNDRV_PCM_STATE_PREPARED); 1522 snd_pcm_set_state(substream, SNDRV_PCM_STATE_PREPARED);
1523} 1523}
1524 1524
1525static struct action_ops snd_pcm_action_prepare = { 1525static const struct action_ops snd_pcm_action_prepare = {
1526 .pre_action = snd_pcm_pre_prepare, 1526 .pre_action = snd_pcm_pre_prepare,
1527 .do_action = snd_pcm_do_prepare, 1527 .do_action = snd_pcm_do_prepare,
1528 .post_action = snd_pcm_post_prepare 1528 .post_action = snd_pcm_post_prepare
@@ -1618,7 +1618,7 @@ static void snd_pcm_post_drain_init(struct snd_pcm_substream *substream, int sta
1618{ 1618{
1619} 1619}
1620 1620
1621static struct action_ops snd_pcm_action_drain_init = { 1621static const struct action_ops snd_pcm_action_drain_init = {
1622 .pre_action = snd_pcm_pre_drain_init, 1622 .pre_action = snd_pcm_pre_drain_init,
1623 .do_action = snd_pcm_do_drain_init, 1623 .do_action = snd_pcm_do_drain_init,
1624 .post_action = snd_pcm_post_drain_init 1624 .post_action = snd_pcm_post_drain_init
diff --git a/sound/core/seq/oss/seq_oss.c b/sound/core/seq/oss/seq_oss.c
index 7354b8bed860..8db156b207f1 100644
--- a/sound/core/seq/oss/seq_oss.c
+++ b/sound/core/seq/oss/seq_oss.c
@@ -23,6 +23,7 @@
23#include <linux/init.h> 23#include <linux/init.h>
24#include <linux/module.h> 24#include <linux/module.h>
25#include <linux/mutex.h> 25#include <linux/mutex.h>
26#include <linux/compat.h>
26#include <sound/core.h> 27#include <sound/core.h>
27#include <sound/minors.h> 28#include <sound/minors.h>
28#include <sound/initval.h> 29#include <sound/initval.h>
@@ -189,7 +190,11 @@ odev_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
189} 190}
190 191
191#ifdef CONFIG_COMPAT 192#ifdef CONFIG_COMPAT
192#define odev_ioctl_compat odev_ioctl 193static long odev_ioctl_compat(struct file *file, unsigned int cmd,
194 unsigned long arg)
195{
196 return odev_ioctl(file, cmd, (unsigned long)compat_ptr(arg));
197}
193#else 198#else
194#define odev_ioctl_compat NULL 199#define odev_ioctl_compat NULL
195#endif 200#endif
diff --git a/sound/core/seq/seq_clientmgr.c b/sound/core/seq/seq_clientmgr.c
index b64f20deba90..13cfa815732d 100644
--- a/sound/core/seq/seq_clientmgr.c
+++ b/sound/core/seq/seq_clientmgr.c
@@ -1962,7 +1962,7 @@ static int snd_seq_ioctl_remove_events(struct snd_seq_client *client,
1962 * No restrictions so for a user client we can clear 1962 * No restrictions so for a user client we can clear
1963 * the whole fifo 1963 * the whole fifo
1964 */ 1964 */
1965 if (client->type == USER_CLIENT) 1965 if (client->type == USER_CLIENT && client->data.user.fifo)
1966 snd_seq_fifo_clear(client->data.user.fifo); 1966 snd_seq_fifo_clear(client->data.user.fifo);
1967 } 1967 }
1968 1968
diff --git a/sound/core/seq/seq_queue.c b/sound/core/seq/seq_queue.c
index 7dfd0f429410..0bec02e89d51 100644
--- a/sound/core/seq/seq_queue.c
+++ b/sound/core/seq/seq_queue.c
@@ -142,8 +142,10 @@ static struct snd_seq_queue *queue_new(int owner, int locked)
142static void queue_delete(struct snd_seq_queue *q) 142static void queue_delete(struct snd_seq_queue *q)
143{ 143{
144 /* stop and release the timer */ 144 /* stop and release the timer */
145 mutex_lock(&q->timer_mutex);
145 snd_seq_timer_stop(q->timer); 146 snd_seq_timer_stop(q->timer);
146 snd_seq_timer_close(q); 147 snd_seq_timer_close(q);
148 mutex_unlock(&q->timer_mutex);
147 /* wait until access free */ 149 /* wait until access free */
148 snd_use_lock_sync(&q->use_lock); 150 snd_use_lock_sync(&q->use_lock);
149 /* release resources... */ 151 /* release resources... */
diff --git a/sound/core/seq/seq_virmidi.c b/sound/core/seq/seq_virmidi.c
index 56e0f4cd3f82..3da2d48610b3 100644
--- a/sound/core/seq/seq_virmidi.c
+++ b/sound/core/seq/seq_virmidi.c
@@ -468,7 +468,7 @@ static int snd_virmidi_dev_unregister(struct snd_rawmidi *rmidi)
468/* 468/*
469 * 469 *
470 */ 470 */
471static struct snd_rawmidi_global_ops snd_virmidi_global_ops = { 471static const struct snd_rawmidi_global_ops snd_virmidi_global_ops = {
472 .dev_register = snd_virmidi_dev_register, 472 .dev_register = snd_virmidi_dev_register,
473 .dev_unregister = snd_virmidi_dev_unregister, 473 .dev_unregister = snd_virmidi_dev_unregister,
474}; 474};
diff --git a/sound/core/timer.c b/sound/core/timer.c
index 31f40f03e5b7..cb25aded5349 100644
--- a/sound/core/timer.c
+++ b/sound/core/timer.c
@@ -73,7 +73,7 @@ struct snd_timer_user {
73 struct timespec tstamp; /* trigger tstamp */ 73 struct timespec tstamp; /* trigger tstamp */
74 wait_queue_head_t qchange_sleep; 74 wait_queue_head_t qchange_sleep;
75 struct fasync_struct *fasync; 75 struct fasync_struct *fasync;
76 struct mutex tread_sem; 76 struct mutex ioctl_lock;
77}; 77};
78 78
79/* list of timers */ 79/* list of timers */
@@ -215,11 +215,13 @@ static void snd_timer_check_master(struct snd_timer_instance *master)
215 slave->slave_id == master->slave_id) { 215 slave->slave_id == master->slave_id) {
216 list_move_tail(&slave->open_list, &master->slave_list_head); 216 list_move_tail(&slave->open_list, &master->slave_list_head);
217 spin_lock_irq(&slave_active_lock); 217 spin_lock_irq(&slave_active_lock);
218 spin_lock(&master->timer->lock);
218 slave->master = master; 219 slave->master = master;
219 slave->timer = master->timer; 220 slave->timer = master->timer;
220 if (slave->flags & SNDRV_TIMER_IFLG_RUNNING) 221 if (slave->flags & SNDRV_TIMER_IFLG_RUNNING)
221 list_add_tail(&slave->active_list, 222 list_add_tail(&slave->active_list,
222 &master->slave_active_head); 223 &master->slave_active_head);
224 spin_unlock(&master->timer->lock);
223 spin_unlock_irq(&slave_active_lock); 225 spin_unlock_irq(&slave_active_lock);
224 } 226 }
225 } 227 }
@@ -299,8 +301,7 @@ int snd_timer_open(struct snd_timer_instance **ti,
299 return 0; 301 return 0;
300} 302}
301 303
302static int _snd_timer_stop(struct snd_timer_instance *timeri, 304static int _snd_timer_stop(struct snd_timer_instance *timeri, int event);
303 int keep_flag, int event);
304 305
305/* 306/*
306 * close a timer instance 307 * close a timer instance
@@ -342,19 +343,22 @@ int snd_timer_close(struct snd_timer_instance *timeri)
342 spin_unlock_irq(&timer->lock); 343 spin_unlock_irq(&timer->lock);
343 mutex_lock(&register_mutex); 344 mutex_lock(&register_mutex);
344 list_del(&timeri->open_list); 345 list_del(&timeri->open_list);
345 if (timer && list_empty(&timer->open_list_head) && 346 if (list_empty(&timer->open_list_head) &&
346 timer->hw.close) 347 timer->hw.close)
347 timer->hw.close(timer); 348 timer->hw.close(timer);
348 /* remove slave links */ 349 /* remove slave links */
350 spin_lock_irq(&slave_active_lock);
351 spin_lock(&timer->lock);
349 list_for_each_entry_safe(slave, tmp, &timeri->slave_list_head, 352 list_for_each_entry_safe(slave, tmp, &timeri->slave_list_head,
350 open_list) { 353 open_list) {
351 spin_lock_irq(&slave_active_lock);
352 _snd_timer_stop(slave, 1, SNDRV_TIMER_EVENT_RESOLUTION);
353 list_move_tail(&slave->open_list, &snd_timer_slave_list); 354 list_move_tail(&slave->open_list, &snd_timer_slave_list);
354 slave->master = NULL; 355 slave->master = NULL;
355 slave->timer = NULL; 356 slave->timer = NULL;
356 spin_unlock_irq(&slave_active_lock); 357 list_del_init(&slave->ack_list);
358 list_del_init(&slave->active_list);
357 } 359 }
360 spin_unlock(&timer->lock);
361 spin_unlock_irq(&slave_active_lock);
358 mutex_unlock(&register_mutex); 362 mutex_unlock(&register_mutex);
359 } 363 }
360 out: 364 out:
@@ -441,9 +445,12 @@ static int snd_timer_start_slave(struct snd_timer_instance *timeri)
441 445
442 spin_lock_irqsave(&slave_active_lock, flags); 446 spin_lock_irqsave(&slave_active_lock, flags);
443 timeri->flags |= SNDRV_TIMER_IFLG_RUNNING; 447 timeri->flags |= SNDRV_TIMER_IFLG_RUNNING;
444 if (timeri->master) 448 if (timeri->master && timeri->timer) {
449 spin_lock(&timeri->timer->lock);
445 list_add_tail(&timeri->active_list, 450 list_add_tail(&timeri->active_list,
446 &timeri->master->slave_active_head); 451 &timeri->master->slave_active_head);
452 spin_unlock(&timeri->timer->lock);
453 }
447 spin_unlock_irqrestore(&slave_active_lock, flags); 454 spin_unlock_irqrestore(&slave_active_lock, flags);
448 return 1; /* delayed start */ 455 return 1; /* delayed start */
449} 456}
@@ -476,8 +483,7 @@ int snd_timer_start(struct snd_timer_instance *timeri, unsigned int ticks)
476 return result; 483 return result;
477} 484}
478 485
479static int _snd_timer_stop(struct snd_timer_instance * timeri, 486static int _snd_timer_stop(struct snd_timer_instance *timeri, int event)
480 int keep_flag, int event)
481{ 487{
482 struct snd_timer *timer; 488 struct snd_timer *timer;
483 unsigned long flags; 489 unsigned long flags;
@@ -486,11 +492,11 @@ static int _snd_timer_stop(struct snd_timer_instance * timeri,
486 return -ENXIO; 492 return -ENXIO;
487 493
488 if (timeri->flags & SNDRV_TIMER_IFLG_SLAVE) { 494 if (timeri->flags & SNDRV_TIMER_IFLG_SLAVE) {
489 if (!keep_flag) { 495 spin_lock_irqsave(&slave_active_lock, flags);
490 spin_lock_irqsave(&slave_active_lock, flags); 496 timeri->flags &= ~SNDRV_TIMER_IFLG_RUNNING;
491 timeri->flags &= ~SNDRV_TIMER_IFLG_RUNNING; 497 list_del_init(&timeri->ack_list);
492 spin_unlock_irqrestore(&slave_active_lock, flags); 498 list_del_init(&timeri->active_list);
493 } 499 spin_unlock_irqrestore(&slave_active_lock, flags);
494 goto __end; 500 goto __end;
495 } 501 }
496 timer = timeri->timer; 502 timer = timeri->timer;
@@ -511,9 +517,7 @@ static int _snd_timer_stop(struct snd_timer_instance * timeri,
511 } 517 }
512 } 518 }
513 } 519 }
514 if (!keep_flag) 520 timeri->flags &= ~(SNDRV_TIMER_IFLG_RUNNING | SNDRV_TIMER_IFLG_START);
515 timeri->flags &=
516 ~(SNDRV_TIMER_IFLG_RUNNING | SNDRV_TIMER_IFLG_START);
517 spin_unlock_irqrestore(&timer->lock, flags); 521 spin_unlock_irqrestore(&timer->lock, flags);
518 __end: 522 __end:
519 if (event != SNDRV_TIMER_EVENT_RESOLUTION) 523 if (event != SNDRV_TIMER_EVENT_RESOLUTION)
@@ -532,7 +536,7 @@ int snd_timer_stop(struct snd_timer_instance *timeri)
532 unsigned long flags; 536 unsigned long flags;
533 int err; 537 int err;
534 538
535 err = _snd_timer_stop(timeri, 0, SNDRV_TIMER_EVENT_STOP); 539 err = _snd_timer_stop(timeri, SNDRV_TIMER_EVENT_STOP);
536 if (err < 0) 540 if (err < 0)
537 return err; 541 return err;
538 timer = timeri->timer; 542 timer = timeri->timer;
@@ -576,7 +580,7 @@ int snd_timer_continue(struct snd_timer_instance *timeri)
576 */ 580 */
577int snd_timer_pause(struct snd_timer_instance * timeri) 581int snd_timer_pause(struct snd_timer_instance * timeri)
578{ 582{
579 return _snd_timer_stop(timeri, 0, SNDRV_TIMER_EVENT_PAUSE); 583 return _snd_timer_stop(timeri, SNDRV_TIMER_EVENT_PAUSE);
580} 584}
581 585
582/* 586/*
@@ -694,7 +698,7 @@ void snd_timer_interrupt(struct snd_timer * timer, unsigned long ticks_left)
694 } else { 698 } else {
695 ti->flags &= ~SNDRV_TIMER_IFLG_RUNNING; 699 ti->flags &= ~SNDRV_TIMER_IFLG_RUNNING;
696 if (--timer->running) 700 if (--timer->running)
697 list_del(&ti->active_list); 701 list_del_init(&ti->active_list);
698 } 702 }
699 if ((timer->hw.flags & SNDRV_TIMER_HW_TASKLET) || 703 if ((timer->hw.flags & SNDRV_TIMER_HW_TASKLET) ||
700 (ti->flags & SNDRV_TIMER_IFLG_FAST)) 704 (ti->flags & SNDRV_TIMER_IFLG_FAST))
@@ -1253,7 +1257,7 @@ static int snd_timer_user_open(struct inode *inode, struct file *file)
1253 return -ENOMEM; 1257 return -ENOMEM;
1254 spin_lock_init(&tu->qlock); 1258 spin_lock_init(&tu->qlock);
1255 init_waitqueue_head(&tu->qchange_sleep); 1259 init_waitqueue_head(&tu->qchange_sleep);
1256 mutex_init(&tu->tread_sem); 1260 mutex_init(&tu->ioctl_lock);
1257 tu->ticks = 1; 1261 tu->ticks = 1;
1258 tu->queue_size = 128; 1262 tu->queue_size = 128;
1259 tu->queue = kmalloc(tu->queue_size * sizeof(struct snd_timer_read), 1263 tu->queue = kmalloc(tu->queue_size * sizeof(struct snd_timer_read),
@@ -1273,8 +1277,10 @@ static int snd_timer_user_release(struct inode *inode, struct file *file)
1273 if (file->private_data) { 1277 if (file->private_data) {
1274 tu = file->private_data; 1278 tu = file->private_data;
1275 file->private_data = NULL; 1279 file->private_data = NULL;
1280 mutex_lock(&tu->ioctl_lock);
1276 if (tu->timeri) 1281 if (tu->timeri)
1277 snd_timer_close(tu->timeri); 1282 snd_timer_close(tu->timeri);
1283 mutex_unlock(&tu->ioctl_lock);
1278 kfree(tu->queue); 1284 kfree(tu->queue);
1279 kfree(tu->tqueue); 1285 kfree(tu->tqueue);
1280 kfree(tu); 1286 kfree(tu);
@@ -1512,7 +1518,6 @@ static int snd_timer_user_tselect(struct file *file,
1512 int err = 0; 1518 int err = 0;
1513 1519
1514 tu = file->private_data; 1520 tu = file->private_data;
1515 mutex_lock(&tu->tread_sem);
1516 if (tu->timeri) { 1521 if (tu->timeri) {
1517 snd_timer_close(tu->timeri); 1522 snd_timer_close(tu->timeri);
1518 tu->timeri = NULL; 1523 tu->timeri = NULL;
@@ -1556,7 +1561,6 @@ static int snd_timer_user_tselect(struct file *file,
1556 } 1561 }
1557 1562
1558 __err: 1563 __err:
1559 mutex_unlock(&tu->tread_sem);
1560 return err; 1564 return err;
1561} 1565}
1562 1566
@@ -1769,7 +1773,7 @@ enum {
1769 SNDRV_TIMER_IOCTL_PAUSE_OLD = _IO('T', 0x23), 1773 SNDRV_TIMER_IOCTL_PAUSE_OLD = _IO('T', 0x23),
1770}; 1774};
1771 1775
1772static long snd_timer_user_ioctl(struct file *file, unsigned int cmd, 1776static long __snd_timer_user_ioctl(struct file *file, unsigned int cmd,
1773 unsigned long arg) 1777 unsigned long arg)
1774{ 1778{
1775 struct snd_timer_user *tu; 1779 struct snd_timer_user *tu;
@@ -1786,17 +1790,11 @@ static long snd_timer_user_ioctl(struct file *file, unsigned int cmd,
1786 { 1790 {
1787 int xarg; 1791 int xarg;
1788 1792
1789 mutex_lock(&tu->tread_sem); 1793 if (tu->timeri) /* too late */
1790 if (tu->timeri) { /* too late */
1791 mutex_unlock(&tu->tread_sem);
1792 return -EBUSY; 1794 return -EBUSY;
1793 } 1795 if (get_user(xarg, p))
1794 if (get_user(xarg, p)) {
1795 mutex_unlock(&tu->tread_sem);
1796 return -EFAULT; 1796 return -EFAULT;
1797 }
1798 tu->tread = xarg ? 1 : 0; 1797 tu->tread = xarg ? 1 : 0;
1799 mutex_unlock(&tu->tread_sem);
1800 return 0; 1798 return 0;
1801 } 1799 }
1802 case SNDRV_TIMER_IOCTL_GINFO: 1800 case SNDRV_TIMER_IOCTL_GINFO:
@@ -1829,6 +1827,18 @@ static long snd_timer_user_ioctl(struct file *file, unsigned int cmd,
1829 return -ENOTTY; 1827 return -ENOTTY;
1830} 1828}
1831 1829
1830static long snd_timer_user_ioctl(struct file *file, unsigned int cmd,
1831 unsigned long arg)
1832{
1833 struct snd_timer_user *tu = file->private_data;
1834 long ret;
1835
1836 mutex_lock(&tu->ioctl_lock);
1837 ret = __snd_timer_user_ioctl(file, cmd, arg);
1838 mutex_unlock(&tu->ioctl_lock);
1839 return ret;
1840}
1841
1832static int snd_timer_user_fasync(int fd, struct file * file, int on) 1842static int snd_timer_user_fasync(int fd, struct file * file, int on)
1833{ 1843{
1834 struct snd_timer_user *tu; 1844 struct snd_timer_user *tu;
diff --git a/sound/drivers/dummy.c b/sound/drivers/dummy.c
index 016e451ed506..75b74850c005 100644
--- a/sound/drivers/dummy.c
+++ b/sound/drivers/dummy.c
@@ -351,7 +351,7 @@ static void dummy_systimer_free(struct snd_pcm_substream *substream)
351 kfree(substream->runtime->private_data); 351 kfree(substream->runtime->private_data);
352} 352}
353 353
354static struct dummy_timer_ops dummy_systimer_ops = { 354static const struct dummy_timer_ops dummy_systimer_ops = {
355 .create = dummy_systimer_create, 355 .create = dummy_systimer_create,
356 .free = dummy_systimer_free, 356 .free = dummy_systimer_free,
357 .prepare = dummy_systimer_prepare, 357 .prepare = dummy_systimer_prepare,
@@ -475,7 +475,7 @@ static void dummy_hrtimer_free(struct snd_pcm_substream *substream)
475 kfree(dpcm); 475 kfree(dpcm);
476} 476}
477 477
478static struct dummy_timer_ops dummy_hrtimer_ops = { 478static const struct dummy_timer_ops dummy_hrtimer_ops = {
479 .create = dummy_hrtimer_create, 479 .create = dummy_hrtimer_create,
480 .free = dummy_hrtimer_free, 480 .free = dummy_hrtimer_free,
481 .prepare = dummy_hrtimer_prepare, 481 .prepare = dummy_hrtimer_prepare,
diff --git a/sound/firewire/Kconfig b/sound/firewire/Kconfig
index e92a6d949847..2a779c2f63ab 100644
--- a/sound/firewire/Kconfig
+++ b/sound/firewire/Kconfig
@@ -39,6 +39,7 @@ config SND_OXFW
39 * Mackie(Loud) d.2 pro/d.4 pro 39 * Mackie(Loud) d.2 pro/d.4 pro
40 * Mackie(Loud) U.420/U.420d 40 * Mackie(Loud) U.420/U.420d
41 * TASCAM FireOne 41 * TASCAM FireOne
42 * Stanton Controllers & Systems 1 Deck/Mixer
42 43
43 To compile this driver as a module, choose M here: the module 44 To compile this driver as a module, choose M here: the module
44 will be called snd-oxfw. 45 will be called snd-oxfw.
@@ -53,17 +54,6 @@ config SND_ISIGHT
53 To compile this driver as a module, choose M here: the module 54 To compile this driver as a module, choose M here: the module
54 will be called snd-isight. 55 will be called snd-isight.
55 56
56config SND_SCS1X
57 tristate "Stanton Control System 1 MIDI"
58 select SND_FIREWIRE_LIB
59 help
60 Say Y here to include support for the MIDI ports of the Stanton
61 SCS.1d/SCS.1m DJ controllers. (SCS.1m audio is still handled
62 by FFADO.)
63
64 To compile this driver as a module, choose M here: the module
65 will be called snd-scs1x.
66
67config SND_FIREWORKS 57config SND_FIREWORKS
68 tristate "Echo Fireworks board module support" 58 tristate "Echo Fireworks board module support"
69 select SND_FIREWIRE_LIB 59 select SND_FIREWIRE_LIB
diff --git a/sound/firewire/Makefile b/sound/firewire/Makefile
index f5fb62551c60..003c09029786 100644
--- a/sound/firewire/Makefile
+++ b/sound/firewire/Makefile
@@ -1,13 +1,11 @@
1snd-firewire-lib-objs := lib.o iso-resources.o packets-buffer.o \ 1snd-firewire-lib-objs := lib.o iso-resources.o packets-buffer.o \
2 fcp.o cmp.o amdtp-stream.o amdtp-am824.o 2 fcp.o cmp.o amdtp-stream.o amdtp-am824.o
3snd-isight-objs := isight.o 3snd-isight-objs := isight.o
4snd-scs1x-objs := scs1x.o
5 4
6obj-$(CONFIG_SND_FIREWIRE_LIB) += snd-firewire-lib.o 5obj-$(CONFIG_SND_FIREWIRE_LIB) += snd-firewire-lib.o
7obj-$(CONFIG_SND_DICE) += dice/ 6obj-$(CONFIG_SND_DICE) += dice/
8obj-$(CONFIG_SND_OXFW) += oxfw/ 7obj-$(CONFIG_SND_OXFW) += oxfw/
9obj-$(CONFIG_SND_ISIGHT) += snd-isight.o 8obj-$(CONFIG_SND_ISIGHT) += snd-isight.o
10obj-$(CONFIG_SND_SCS1X) += snd-scs1x.o
11obj-$(CONFIG_SND_FIREWORKS) += fireworks/ 9obj-$(CONFIG_SND_FIREWORKS) += fireworks/
12obj-$(CONFIG_SND_BEBOB) += bebob/ 10obj-$(CONFIG_SND_BEBOB) += bebob/
13obj-$(CONFIG_SND_FIREWIRE_DIGI00X) += digi00x/ 11obj-$(CONFIG_SND_FIREWIRE_DIGI00X) += digi00x/
diff --git a/sound/firewire/dice/dice-transaction.c b/sound/firewire/dice/dice-transaction.c
index aee746187665..a4ff4e0bc0af 100644
--- a/sound/firewire/dice/dice-transaction.c
+++ b/sound/firewire/dice/dice-transaction.c
@@ -9,7 +9,7 @@
9 9
10#include "dice.h" 10#include "dice.h"
11 11
12#define NOTIFICATION_TIMEOUT_MS 100 12#define NOTIFICATION_TIMEOUT_MS (2 * MSEC_PER_SEC)
13 13
14static u64 get_subaddr(struct snd_dice *dice, enum snd_dice_addr_type type, 14static u64 get_subaddr(struct snd_dice *dice, enum snd_dice_addr_type type,
15 u64 offset) 15 u64 offset)
@@ -65,16 +65,15 @@ static unsigned int get_clock_info(struct snd_dice *dice, __be32 *info)
65static int set_clock_info(struct snd_dice *dice, 65static int set_clock_info(struct snd_dice *dice,
66 unsigned int rate, unsigned int source) 66 unsigned int rate, unsigned int source)
67{ 67{
68 unsigned int retries = 3;
69 unsigned int i; 68 unsigned int i;
70 __be32 info; 69 __be32 info;
71 u32 mask; 70 u32 mask;
72 u32 clock; 71 u32 clock;
73 int err; 72 int err;
74retry: 73
75 err = get_clock_info(dice, &info); 74 err = get_clock_info(dice, &info);
76 if (err < 0) 75 if (err < 0)
77 goto end; 76 return err;
78 77
79 clock = be32_to_cpu(info); 78 clock = be32_to_cpu(info);
80 if (source != UINT_MAX) { 79 if (source != UINT_MAX) {
@@ -87,10 +86,8 @@ retry:
87 if (snd_dice_rates[i] == rate) 86 if (snd_dice_rates[i] == rate)
88 break; 87 break;
89 } 88 }
90 if (i == ARRAY_SIZE(snd_dice_rates)) { 89 if (i == ARRAY_SIZE(snd_dice_rates))
91 err = -EINVAL; 90 return -EINVAL;
92 goto end;
93 }
94 91
95 mask = CLOCK_RATE_MASK; 92 mask = CLOCK_RATE_MASK;
96 clock &= ~mask; 93 clock &= ~mask;
@@ -104,25 +101,13 @@ retry:
104 err = snd_dice_transaction_write_global(dice, GLOBAL_CLOCK_SELECT, 101 err = snd_dice_transaction_write_global(dice, GLOBAL_CLOCK_SELECT,
105 &info, 4); 102 &info, 4);
106 if (err < 0) 103 if (err < 0)
107 goto end; 104 return err;
108 105
109 /* Timeout means it's invalid request, probably bus reset occurred. */
110 if (wait_for_completion_timeout(&dice->clock_accepted, 106 if (wait_for_completion_timeout(&dice->clock_accepted,
111 msecs_to_jiffies(NOTIFICATION_TIMEOUT_MS)) == 0) { 107 msecs_to_jiffies(NOTIFICATION_TIMEOUT_MS)) == 0)
112 if (retries-- == 0) { 108 return -ETIMEDOUT;
113 err = -ETIMEDOUT;
114 goto end;
115 }
116 109
117 err = snd_dice_transaction_reinit(dice); 110 return 0;
118 if (err < 0)
119 goto end;
120
121 msleep(500); /* arbitrary */
122 goto retry;
123 }
124end:
125 return err;
126} 111}
127 112
128int snd_dice_transaction_get_clock_source(struct snd_dice *dice, 113int snd_dice_transaction_get_clock_source(struct snd_dice *dice,
@@ -331,39 +316,60 @@ int snd_dice_transaction_reinit(struct snd_dice *dice)
331 return register_notification_address(dice, false); 316 return register_notification_address(dice, false);
332} 317}
333 318
334int snd_dice_transaction_init(struct snd_dice *dice) 319static int get_subaddrs(struct snd_dice *dice)
335{ 320{
336 struct fw_address_handler *handler = &dice->notification_handler; 321 static const int min_values[10] = {
322 10, 0x64 / 4,
323 10, 0x18 / 4,
324 10, 0x18 / 4,
325 0, 0,
326 0, 0,
327 };
337 __be32 *pointers; 328 __be32 *pointers;
329 __be32 version;
330 u32 data;
331 unsigned int i;
338 int err; 332 int err;
339 333
340 /* Use the same way which dice_interface_check() does. */ 334 pointers = kmalloc_array(ARRAY_SIZE(min_values), sizeof(__be32),
341 pointers = kmalloc(sizeof(__be32) * 10, GFP_KERNEL); 335 GFP_KERNEL);
342 if (pointers == NULL) 336 if (pointers == NULL)
343 return -ENOMEM; 337 return -ENOMEM;
344 338
345 /* Get offsets for sub-addresses */ 339 /*
340 * Check that the sub address spaces exist and are located inside the
341 * private address space. The minimum values are chosen so that all
342 * minimally required registers are included.
343 */
346 err = snd_fw_transaction(dice->unit, TCODE_READ_BLOCK_REQUEST, 344 err = snd_fw_transaction(dice->unit, TCODE_READ_BLOCK_REQUEST,
347 DICE_PRIVATE_SPACE, 345 DICE_PRIVATE_SPACE, pointers,
348 pointers, sizeof(__be32) * 10, 0); 346 sizeof(__be32) * ARRAY_SIZE(min_values), 0);
349 if (err < 0) 347 if (err < 0)
350 goto end; 348 goto end;
351 349
352 /* Allocation callback in address space over host controller */ 350 for (i = 0; i < ARRAY_SIZE(min_values); ++i) {
353 handler->length = 4; 351 data = be32_to_cpu(pointers[i]);
354 handler->address_callback = dice_notification; 352 if (data < min_values[i] || data >= 0x40000) {
355 handler->callback_data = dice; 353 err = -ENODEV;
356 err = fw_core_add_address_handler(handler, &fw_high_memory_region); 354 goto end;
357 if (err < 0) { 355 }
358 handler->callback_data = NULL;
359 goto end;
360 } 356 }
361 357
362 /* Register the address space */ 358 /*
363 err = register_notification_address(dice, true); 359 * Check that the implemented DICE driver specification major version
364 if (err < 0) { 360 * number matches.
365 fw_core_remove_address_handler(handler); 361 */
366 handler->callback_data = NULL; 362 err = snd_fw_transaction(dice->unit, TCODE_READ_QUADLET_REQUEST,
363 DICE_PRIVATE_SPACE +
364 be32_to_cpu(pointers[0]) * 4 + GLOBAL_VERSION,
365 &version, sizeof(version), 0);
366 if (err < 0)
367 goto end;
368
369 if ((version & cpu_to_be32(0xff000000)) != cpu_to_be32(0x01000000)) {
370 dev_err(&dice->unit->device,
371 "unknown DICE version: 0x%08x\n", be32_to_cpu(version));
372 err = -ENODEV;
367 goto end; 373 goto end;
368 } 374 }
369 375
@@ -380,3 +386,32 @@ end:
380 kfree(pointers); 386 kfree(pointers);
381 return err; 387 return err;
382} 388}
389
390int snd_dice_transaction_init(struct snd_dice *dice)
391{
392 struct fw_address_handler *handler = &dice->notification_handler;
393 int err;
394
395 err = get_subaddrs(dice);
396 if (err < 0)
397 return err;
398
399 /* Allocation callback in address space over host controller */
400 handler->length = 4;
401 handler->address_callback = dice_notification;
402 handler->callback_data = dice;
403 err = fw_core_add_address_handler(handler, &fw_high_memory_region);
404 if (err < 0) {
405 handler->callback_data = NULL;
406 return err;
407 }
408
409 /* Register the address space */
410 err = register_notification_address(dice, true);
411 if (err < 0) {
412 fw_core_remove_address_handler(handler);
413 handler->callback_data = NULL;
414 }
415
416 return err;
417}
diff --git a/sound/firewire/dice/dice.c b/sound/firewire/dice/dice.c
index 0cda05c72f50..b91b3739c810 100644
--- a/sound/firewire/dice/dice.c
+++ b/sound/firewire/dice/dice.c
@@ -18,27 +18,14 @@ MODULE_LICENSE("GPL v2");
18#define WEISS_CATEGORY_ID 0x00 18#define WEISS_CATEGORY_ID 0x00
19#define LOUD_CATEGORY_ID 0x10 19#define LOUD_CATEGORY_ID 0x10
20 20
21static int dice_interface_check(struct fw_unit *unit) 21#define PROBE_DELAY_MS (2 * MSEC_PER_SEC)
22
23static int check_dice_category(struct fw_unit *unit)
22{ 24{
23 static const int min_values[10] = {
24 10, 0x64 / 4,
25 10, 0x18 / 4,
26 10, 0x18 / 4,
27 0, 0,
28 0, 0,
29 };
30 struct fw_device *device = fw_parent_device(unit); 25 struct fw_device *device = fw_parent_device(unit);
31 struct fw_csr_iterator it; 26 struct fw_csr_iterator it;
32 int key, val, vendor = -1, model = -1, err; 27 int key, val, vendor = -1, model = -1;
33 unsigned int category, i; 28 unsigned int category;
34 __be32 *pointers;
35 u32 value;
36 __be32 version;
37
38 pointers = kmalloc_array(ARRAY_SIZE(min_values), sizeof(__be32),
39 GFP_KERNEL);
40 if (pointers == NULL)
41 return -ENOMEM;
42 29
43 /* 30 /*
44 * Check that GUID and unit directory are constructed according to DICE 31 * Check that GUID and unit directory are constructed according to DICE
@@ -64,51 +51,10 @@ static int dice_interface_check(struct fw_unit *unit)
64 else 51 else
65 category = DICE_CATEGORY_ID; 52 category = DICE_CATEGORY_ID;
66 if (device->config_rom[3] != ((vendor << 8) | category) || 53 if (device->config_rom[3] != ((vendor << 8) | category) ||
67 device->config_rom[4] >> 22 != model) { 54 device->config_rom[4] >> 22 != model)
68 err = -ENODEV; 55 return -ENODEV;
69 goto end;
70 }
71
72 /*
73 * Check that the sub address spaces exist and are located inside the
74 * private address space. The minimum values are chosen so that all
75 * minimally required registers are included.
76 */
77 err = snd_fw_transaction(unit, TCODE_READ_BLOCK_REQUEST,
78 DICE_PRIVATE_SPACE, pointers,
79 sizeof(__be32) * ARRAY_SIZE(min_values), 0);
80 if (err < 0) {
81 err = -ENODEV;
82 goto end;
83 }
84 for (i = 0; i < ARRAY_SIZE(min_values); ++i) {
85 value = be32_to_cpu(pointers[i]);
86 if (value < min_values[i] || value >= 0x40000) {
87 err = -ENODEV;
88 goto end;
89 }
90 }
91 56
92 /* 57 return 0;
93 * Check that the implemented DICE driver specification major version
94 * number matches.
95 */
96 err = snd_fw_transaction(unit, TCODE_READ_QUADLET_REQUEST,
97 DICE_PRIVATE_SPACE +
98 be32_to_cpu(pointers[0]) * 4 + GLOBAL_VERSION,
99 &version, 4, 0);
100 if (err < 0) {
101 err = -ENODEV;
102 goto end;
103 }
104 if ((version & cpu_to_be32(0xff000000)) != cpu_to_be32(0x01000000)) {
105 dev_err(&unit->device,
106 "unknown DICE version: 0x%08x\n", be32_to_cpu(version));
107 err = -ENODEV;
108 goto end;
109 }
110end:
111 return err;
112} 58}
113 59
114static int highest_supported_mode_rate(struct snd_dice *dice, 60static int highest_supported_mode_rate(struct snd_dice *dice,
@@ -231,6 +177,16 @@ static void dice_card_strings(struct snd_dice *dice)
231 strcpy(card->mixername, "DICE"); 177 strcpy(card->mixername, "DICE");
232} 178}
233 179
180static void dice_free(struct snd_dice *dice)
181{
182 snd_dice_stream_destroy_duplex(dice);
183 snd_dice_transaction_destroy(dice);
184 fw_unit_put(dice->unit);
185
186 mutex_destroy(&dice->mutex);
187 kfree(dice);
188}
189
234/* 190/*
235 * This module releases the FireWire unit data after all ALSA character devices 191 * This module releases the FireWire unit data after all ALSA character devices
236 * are released by applications. This is for releasing stream data or finishing 192 * are released by applications. This is for releasing stream data or finishing
@@ -239,39 +195,21 @@ static void dice_card_strings(struct snd_dice *dice)
239 */ 195 */
240static void dice_card_free(struct snd_card *card) 196static void dice_card_free(struct snd_card *card)
241{ 197{
242 struct snd_dice *dice = card->private_data; 198 dice_free(card->private_data);
243
244 snd_dice_stream_destroy_duplex(dice);
245 snd_dice_transaction_destroy(dice);
246 fw_unit_put(dice->unit);
247
248 mutex_destroy(&dice->mutex);
249} 199}
250 200
251static int dice_probe(struct fw_unit *unit, const struct ieee1394_device_id *id) 201static void do_registration(struct work_struct *work)
252{ 202{
253 struct snd_card *card; 203 struct snd_dice *dice = container_of(work, struct snd_dice, dwork.work);
254 struct snd_dice *dice;
255 int err; 204 int err;
256 205
257 err = dice_interface_check(unit); 206 if (dice->registered)
258 if (err < 0) 207 return;
259 goto end;
260 208
261 err = snd_card_new(&unit->device, -1, NULL, THIS_MODULE, 209 err = snd_card_new(&dice->unit->device, -1, NULL, THIS_MODULE, 0,
262 sizeof(*dice), &card); 210 &dice->card);
263 if (err < 0) 211 if (err < 0)
264 goto end; 212 return;
265
266 dice = card->private_data;
267 dice->card = card;
268 dice->unit = fw_unit_get(unit);
269 card->private_free = dice_card_free;
270
271 spin_lock_init(&dice->lock);
272 mutex_init(&dice->mutex);
273 init_completion(&dice->clock_accepted);
274 init_waitqueue_head(&dice->hwdep_wait);
275 213
276 err = snd_dice_transaction_init(dice); 214 err = snd_dice_transaction_init(dice);
277 if (err < 0) 215 if (err < 0)
@@ -283,56 +221,131 @@ static int dice_probe(struct fw_unit *unit, const struct ieee1394_device_id *id)
283 221
284 dice_card_strings(dice); 222 dice_card_strings(dice);
285 223
224 snd_dice_create_proc(dice);
225
286 err = snd_dice_create_pcm(dice); 226 err = snd_dice_create_pcm(dice);
287 if (err < 0) 227 if (err < 0)
288 goto error; 228 goto error;
289 229
290 err = snd_dice_create_hwdep(dice); 230 err = snd_dice_create_midi(dice);
291 if (err < 0) 231 if (err < 0)
292 goto error; 232 goto error;
293 233
294 snd_dice_create_proc(dice); 234 err = snd_dice_create_hwdep(dice);
295
296 err = snd_dice_create_midi(dice);
297 if (err < 0) 235 if (err < 0)
298 goto error; 236 goto error;
299 237
300 err = snd_dice_stream_init_duplex(dice); 238 err = snd_card_register(dice->card);
301 if (err < 0) 239 if (err < 0)
302 goto error; 240 goto error;
303 241
304 err = snd_card_register(card); 242 /*
243 * After registered, dice instance can be released corresponding to
244 * releasing the sound card instance.
245 */
246 dice->card->private_free = dice_card_free;
247 dice->card->private_data = dice;
248 dice->registered = true;
249
250 return;
251error:
252 snd_dice_transaction_destroy(dice);
253 snd_card_free(dice->card);
254 dev_info(&dice->unit->device,
255 "Sound card registration failed: %d\n", err);
256}
257
258static void schedule_registration(struct snd_dice *dice)
259{
260 struct fw_card *fw_card = fw_parent_device(dice->unit)->card;
261 u64 now, delay;
262
263 now = get_jiffies_64();
264 delay = fw_card->reset_jiffies + msecs_to_jiffies(PROBE_DELAY_MS);
265
266 if (time_after64(delay, now))
267 delay -= now;
268 else
269 delay = 0;
270
271 mod_delayed_work(system_wq, &dice->dwork, delay);
272}
273
274static int dice_probe(struct fw_unit *unit, const struct ieee1394_device_id *id)
275{
276 struct snd_dice *dice;
277 int err;
278
279 err = check_dice_category(unit);
280 if (err < 0)
281 return -ENODEV;
282
283 /* Allocate this independent of sound card instance. */
284 dice = kzalloc(sizeof(struct snd_dice), GFP_KERNEL);
285 if (dice == NULL)
286 return -ENOMEM;
287
288 dice->unit = fw_unit_get(unit);
289 dev_set_drvdata(&unit->device, dice);
290
291 spin_lock_init(&dice->lock);
292 mutex_init(&dice->mutex);
293 init_completion(&dice->clock_accepted);
294 init_waitqueue_head(&dice->hwdep_wait);
295
296 err = snd_dice_stream_init_duplex(dice);
305 if (err < 0) { 297 if (err < 0) {
306 snd_dice_stream_destroy_duplex(dice); 298 dice_free(dice);
307 goto error; 299 return err;
308 } 300 }
309 301
310 dev_set_drvdata(&unit->device, dice); 302 /* Allocate and register this sound card later. */
311end: 303 INIT_DEFERRABLE_WORK(&dice->dwork, do_registration);
312 return err; 304 schedule_registration(dice);
313error: 305
314 snd_card_free(card); 306 return 0;
315 return err;
316} 307}
317 308
318static void dice_remove(struct fw_unit *unit) 309static void dice_remove(struct fw_unit *unit)
319{ 310{
320 struct snd_dice *dice = dev_get_drvdata(&unit->device); 311 struct snd_dice *dice = dev_get_drvdata(&unit->device);
321 312
322 /* No need to wait for releasing card object in this context. */ 313 /*
323 snd_card_free_when_closed(dice->card); 314 * Confirm to stop the work for registration before the sound card is
315 * going to be released. The work is not scheduled again because bus
316 * reset handler is not called anymore.
317 */
318 cancel_delayed_work_sync(&dice->dwork);
319
320 if (dice->registered) {
321 /* No need to wait for releasing card object in this context. */
322 snd_card_free_when_closed(dice->card);
323 } else {
324 /* Don't forget this case. */
325 dice_free(dice);
326 }
324} 327}
325 328
326static void dice_bus_reset(struct fw_unit *unit) 329static void dice_bus_reset(struct fw_unit *unit)
327{ 330{
328 struct snd_dice *dice = dev_get_drvdata(&unit->device); 331 struct snd_dice *dice = dev_get_drvdata(&unit->device);
329 332
333 /* Postpone a workqueue for deferred registration. */
334 if (!dice->registered)
335 schedule_registration(dice);
336
330 /* The handler address register becomes initialized. */ 337 /* The handler address register becomes initialized. */
331 snd_dice_transaction_reinit(dice); 338 snd_dice_transaction_reinit(dice);
332 339
333 mutex_lock(&dice->mutex); 340 /*
334 snd_dice_stream_update_duplex(dice); 341 * After registration, userspace can start packet streaming, then this
335 mutex_unlock(&dice->mutex); 342 * code block works fine.
343 */
344 if (dice->registered) {
345 mutex_lock(&dice->mutex);
346 snd_dice_stream_update_duplex(dice);
347 mutex_unlock(&dice->mutex);
348 }
336} 349}
337 350
338#define DICE_INTERFACE 0x000001 351#define DICE_INTERFACE 0x000001
diff --git a/sound/firewire/dice/dice.h b/sound/firewire/dice/dice.h
index 101550ac1a24..3d5ebebe61ea 100644
--- a/sound/firewire/dice/dice.h
+++ b/sound/firewire/dice/dice.h
@@ -45,6 +45,9 @@ struct snd_dice {
45 spinlock_t lock; 45 spinlock_t lock;
46 struct mutex mutex; 46 struct mutex mutex;
47 47
48 bool registered;
49 struct delayed_work dwork;
50
48 /* Offsets for sub-addresses */ 51 /* Offsets for sub-addresses */
49 unsigned int global_offset; 52 unsigned int global_offset;
50 unsigned int rx_offset; 53 unsigned int rx_offset;
diff --git a/sound/firewire/fireworks/fireworks.h b/sound/firewire/fireworks/fireworks.h
index c7cb7deafe48..96c4e0c6a9bd 100644
--- a/sound/firewire/fireworks/fireworks.h
+++ b/sound/firewire/fireworks/fireworks.h
@@ -86,8 +86,8 @@ struct snd_efw {
86 struct amdtp_stream rx_stream; 86 struct amdtp_stream rx_stream;
87 struct cmp_connection out_conn; 87 struct cmp_connection out_conn;
88 struct cmp_connection in_conn; 88 struct cmp_connection in_conn;
89 atomic_t capture_substreams; 89 unsigned int capture_substreams;
90 atomic_t playback_substreams; 90 unsigned int playback_substreams;
91 91
92 /* hardware metering parameters */ 92 /* hardware metering parameters */
93 unsigned int phys_out; 93 unsigned int phys_out;
diff --git a/sound/firewire/fireworks/fireworks_midi.c b/sound/firewire/fireworks/fireworks_midi.c
index fba01bbba456..3e8c4cf9fe1e 100644
--- a/sound/firewire/fireworks/fireworks_midi.c
+++ b/sound/firewire/fireworks/fireworks_midi.c
@@ -17,8 +17,10 @@ static int midi_capture_open(struct snd_rawmidi_substream *substream)
17 if (err < 0) 17 if (err < 0)
18 goto end; 18 goto end;
19 19
20 atomic_inc(&efw->capture_substreams); 20 mutex_lock(&efw->mutex);
21 efw->capture_substreams++;
21 err = snd_efw_stream_start_duplex(efw, 0); 22 err = snd_efw_stream_start_duplex(efw, 0);
23 mutex_unlock(&efw->mutex);
22 if (err < 0) 24 if (err < 0)
23 snd_efw_stream_lock_release(efw); 25 snd_efw_stream_lock_release(efw);
24 26
@@ -35,8 +37,10 @@ static int midi_playback_open(struct snd_rawmidi_substream *substream)
35 if (err < 0) 37 if (err < 0)
36 goto end; 38 goto end;
37 39
38 atomic_inc(&efw->playback_substreams); 40 mutex_lock(&efw->mutex);
41 efw->playback_substreams++;
39 err = snd_efw_stream_start_duplex(efw, 0); 42 err = snd_efw_stream_start_duplex(efw, 0);
43 mutex_unlock(&efw->mutex);
40 if (err < 0) 44 if (err < 0)
41 snd_efw_stream_lock_release(efw); 45 snd_efw_stream_lock_release(efw);
42end: 46end:
@@ -47,8 +51,10 @@ static int midi_capture_close(struct snd_rawmidi_substream *substream)
47{ 51{
48 struct snd_efw *efw = substream->rmidi->private_data; 52 struct snd_efw *efw = substream->rmidi->private_data;
49 53
50 atomic_dec(&efw->capture_substreams); 54 mutex_lock(&efw->mutex);
55 efw->capture_substreams--;
51 snd_efw_stream_stop_duplex(efw); 56 snd_efw_stream_stop_duplex(efw);
57 mutex_unlock(&efw->mutex);
52 58
53 snd_efw_stream_lock_release(efw); 59 snd_efw_stream_lock_release(efw);
54 return 0; 60 return 0;
@@ -58,8 +64,10 @@ static int midi_playback_close(struct snd_rawmidi_substream *substream)
58{ 64{
59 struct snd_efw *efw = substream->rmidi->private_data; 65 struct snd_efw *efw = substream->rmidi->private_data;
60 66
61 atomic_dec(&efw->playback_substreams); 67 mutex_lock(&efw->mutex);
68 efw->playback_substreams--;
62 snd_efw_stream_stop_duplex(efw); 69 snd_efw_stream_stop_duplex(efw);
70 mutex_unlock(&efw->mutex);
63 71
64 snd_efw_stream_lock_release(efw); 72 snd_efw_stream_lock_release(efw);
65 return 0; 73 return 0;
diff --git a/sound/firewire/fireworks/fireworks_pcm.c b/sound/firewire/fireworks/fireworks_pcm.c
index d27135bac513..f4fbf75ed198 100644
--- a/sound/firewire/fireworks/fireworks_pcm.c
+++ b/sound/firewire/fireworks/fireworks_pcm.c
@@ -251,8 +251,11 @@ static int pcm_capture_hw_params(struct snd_pcm_substream *substream,
251 if (err < 0) 251 if (err < 0)
252 return err; 252 return err;
253 253
254 if (substream->runtime->status->state == SNDRV_PCM_STATE_OPEN) 254 if (substream->runtime->status->state == SNDRV_PCM_STATE_OPEN) {
255 atomic_inc(&efw->capture_substreams); 255 mutex_lock(&efw->mutex);
256 efw->capture_substreams++;
257 mutex_unlock(&efw->mutex);
258 }
256 259
257 amdtp_am824_set_pcm_format(&efw->tx_stream, params_format(hw_params)); 260 amdtp_am824_set_pcm_format(&efw->tx_stream, params_format(hw_params));
258 261
@@ -269,8 +272,11 @@ static int pcm_playback_hw_params(struct snd_pcm_substream *substream,
269 if (err < 0) 272 if (err < 0)
270 return err; 273 return err;
271 274
272 if (substream->runtime->status->state == SNDRV_PCM_STATE_OPEN) 275 if (substream->runtime->status->state == SNDRV_PCM_STATE_OPEN) {
273 atomic_inc(&efw->playback_substreams); 276 mutex_lock(&efw->mutex);
277 efw->playback_substreams++;
278 mutex_unlock(&efw->mutex);
279 }
274 280
275 amdtp_am824_set_pcm_format(&efw->rx_stream, params_format(hw_params)); 281 amdtp_am824_set_pcm_format(&efw->rx_stream, params_format(hw_params));
276 282
@@ -281,8 +287,11 @@ static int pcm_capture_hw_free(struct snd_pcm_substream *substream)
281{ 287{
282 struct snd_efw *efw = substream->private_data; 288 struct snd_efw *efw = substream->private_data;
283 289
284 if (substream->runtime->status->state != SNDRV_PCM_STATE_OPEN) 290 if (substream->runtime->status->state != SNDRV_PCM_STATE_OPEN) {
285 atomic_dec(&efw->capture_substreams); 291 mutex_lock(&efw->mutex);
292 efw->capture_substreams--;
293 mutex_unlock(&efw->mutex);
294 }
286 295
287 snd_efw_stream_stop_duplex(efw); 296 snd_efw_stream_stop_duplex(efw);
288 297
@@ -292,8 +301,11 @@ static int pcm_playback_hw_free(struct snd_pcm_substream *substream)
292{ 301{
293 struct snd_efw *efw = substream->private_data; 302 struct snd_efw *efw = substream->private_data;
294 303
295 if (substream->runtime->status->state != SNDRV_PCM_STATE_OPEN) 304 if (substream->runtime->status->state != SNDRV_PCM_STATE_OPEN) {
296 atomic_dec(&efw->playback_substreams); 305 mutex_lock(&efw->mutex);
306 efw->playback_substreams--;
307 mutex_unlock(&efw->mutex);
308 }
297 309
298 snd_efw_stream_stop_duplex(efw); 310 snd_efw_stream_stop_duplex(efw);
299 311
diff --git a/sound/firewire/fireworks/fireworks_stream.c b/sound/firewire/fireworks/fireworks_stream.c
index 759f6e3ed44a..968a40a1beb2 100644
--- a/sound/firewire/fireworks/fireworks_stream.c
+++ b/sound/firewire/fireworks/fireworks_stream.c
@@ -209,16 +209,13 @@ end:
209int snd_efw_stream_start_duplex(struct snd_efw *efw, unsigned int rate) 209int snd_efw_stream_start_duplex(struct snd_efw *efw, unsigned int rate)
210{ 210{
211 struct amdtp_stream *master, *slave; 211 struct amdtp_stream *master, *slave;
212 atomic_t *slave_substreams; 212 unsigned int slave_substreams;
213 enum cip_flags sync_mode; 213 enum cip_flags sync_mode;
214 unsigned int curr_rate; 214 unsigned int curr_rate;
215 int err = 0; 215 int err = 0;
216 216
217 mutex_lock(&efw->mutex);
218
219 /* Need no substreams */ 217 /* Need no substreams */
220 if ((atomic_read(&efw->playback_substreams) == 0) && 218 if (efw->playback_substreams == 0 && efw->capture_substreams == 0)
221 (atomic_read(&efw->capture_substreams) == 0))
222 goto end; 219 goto end;
223 220
224 err = get_sync_mode(efw, &sync_mode); 221 err = get_sync_mode(efw, &sync_mode);
@@ -227,11 +224,11 @@ int snd_efw_stream_start_duplex(struct snd_efw *efw, unsigned int rate)
227 if (sync_mode == CIP_SYNC_TO_DEVICE) { 224 if (sync_mode == CIP_SYNC_TO_DEVICE) {
228 master = &efw->tx_stream; 225 master = &efw->tx_stream;
229 slave = &efw->rx_stream; 226 slave = &efw->rx_stream;
230 slave_substreams = &efw->playback_substreams; 227 slave_substreams = efw->playback_substreams;
231 } else { 228 } else {
232 master = &efw->rx_stream; 229 master = &efw->rx_stream;
233 slave = &efw->tx_stream; 230 slave = &efw->tx_stream;
234 slave_substreams = &efw->capture_substreams; 231 slave_substreams = efw->capture_substreams;
235 } 232 }
236 233
237 /* 234 /*
@@ -277,7 +274,7 @@ int snd_efw_stream_start_duplex(struct snd_efw *efw, unsigned int rate)
277 } 274 }
278 275
279 /* start slave if needed */ 276 /* start slave if needed */
280 if (atomic_read(slave_substreams) > 0 && !amdtp_stream_running(slave)) { 277 if (slave_substreams > 0 && !amdtp_stream_running(slave)) {
281 err = start_stream(efw, slave, rate); 278 err = start_stream(efw, slave, rate);
282 if (err < 0) { 279 if (err < 0) {
283 dev_err(&efw->unit->device, 280 dev_err(&efw->unit->device,
@@ -286,37 +283,32 @@ int snd_efw_stream_start_duplex(struct snd_efw *efw, unsigned int rate)
286 } 283 }
287 } 284 }
288end: 285end:
289 mutex_unlock(&efw->mutex);
290 return err; 286 return err;
291} 287}
292 288
293void snd_efw_stream_stop_duplex(struct snd_efw *efw) 289void snd_efw_stream_stop_duplex(struct snd_efw *efw)
294{ 290{
295 struct amdtp_stream *master, *slave; 291 struct amdtp_stream *master, *slave;
296 atomic_t *master_substreams, *slave_substreams; 292 unsigned int master_substreams, slave_substreams;
297 293
298 if (efw->master == &efw->rx_stream) { 294 if (efw->master == &efw->rx_stream) {
299 slave = &efw->tx_stream; 295 slave = &efw->tx_stream;
300 master = &efw->rx_stream; 296 master = &efw->rx_stream;
301 slave_substreams = &efw->capture_substreams; 297 slave_substreams = efw->capture_substreams;
302 master_substreams = &efw->playback_substreams; 298 master_substreams = efw->playback_substreams;
303 } else { 299 } else {
304 slave = &efw->rx_stream; 300 slave = &efw->rx_stream;
305 master = &efw->tx_stream; 301 master = &efw->tx_stream;
306 slave_substreams = &efw->playback_substreams; 302 slave_substreams = efw->playback_substreams;
307 master_substreams = &efw->capture_substreams; 303 master_substreams = efw->capture_substreams;
308 } 304 }
309 305
310 mutex_lock(&efw->mutex); 306 if (slave_substreams == 0) {
311
312 if (atomic_read(slave_substreams) == 0) {
313 stop_stream(efw, slave); 307 stop_stream(efw, slave);
314 308
315 if (atomic_read(master_substreams) == 0) 309 if (master_substreams == 0)
316 stop_stream(efw, master); 310 stop_stream(efw, master);
317 } 311 }
318
319 mutex_unlock(&efw->mutex);
320} 312}
321 313
322void snd_efw_stream_update_duplex(struct snd_efw *efw) 314void snd_efw_stream_update_duplex(struct snd_efw *efw)
diff --git a/sound/firewire/oxfw/Makefile b/sound/firewire/oxfw/Makefile
index 06ff50f4e6c0..b474da7c6a1f 100644
--- a/sound/firewire/oxfw/Makefile
+++ b/sound/firewire/oxfw/Makefile
@@ -1,3 +1,3 @@
1snd-oxfw-objs := oxfw-command.o oxfw-stream.o oxfw-control.o oxfw-pcm.o \ 1snd-oxfw-objs := oxfw-command.o oxfw-stream.o oxfw-pcm.o oxfw-proc.o \
2 oxfw-proc.o oxfw-midi.o oxfw-hwdep.o oxfw.o 2 oxfw-midi.o oxfw-hwdep.o oxfw-spkr.o oxfw-scs1x.o oxfw.o
3obj-$(CONFIG_SND_OXFW) += snd-oxfw.o 3obj-$(CONFIG_SND_OXFW) += snd-oxfw.o
diff --git a/sound/firewire/oxfw/oxfw-scs1x.c b/sound/firewire/oxfw/oxfw-scs1x.c
new file mode 100644
index 000000000000..bb53eb35721b
--- /dev/null
+++ b/sound/firewire/oxfw/oxfw-scs1x.c
@@ -0,0 +1,406 @@
1/*
2 * oxfw-scs1x.c - a part of driver for OXFW970/971 based devices
3 *
4 * Copyright (c) Clemens Ladisch <clemens@ladisch.de>
5 * Copyright (c) 2015 Takashi Sakamoto <o-takashi@sakamocchi.jp>
6 *
7 * Licensed under the terms of the GNU General Public License, version 2.
8 */
9
10#include "oxfw.h"
11
12#define HSS1394_ADDRESS 0xc007dedadadaULL
13#define HSS1394_MAX_PACKET_SIZE 64
14#define HSS1394_TAG_USER_DATA 0x00
15#define HSS1394_TAG_CHANGE_ADDRESS 0xf1
16
17struct fw_scs1x {
18 struct fw_address_handler hss_handler;
19 u8 input_escape_count;
20 struct snd_rawmidi_substream *input;
21
22 /* For MIDI playback. */
23 struct snd_rawmidi_substream *output;
24 bool output_idle;
25 u8 output_status;
26 u8 output_bytes;
27 bool output_escaped;
28 bool output_escape_high_nibble;
29 struct tasklet_struct tasklet;
30 wait_queue_head_t idle_wait;
31 u8 buffer[HSS1394_MAX_PACKET_SIZE];
32 bool transaction_running;
33 struct fw_transaction transaction;
34 struct fw_device *fw_dev;
35};
36
37static const u8 sysex_escape_prefix[] = {
38 0xf0, /* SysEx begin */
39 0x00, 0x01, 0x60, /* Stanton DJ */
40 0x48, 0x53, 0x53, /* "HSS" */
41};
42
43static void midi_input_escaped_byte(struct snd_rawmidi_substream *stream,
44 u8 byte)
45{
46 u8 nibbles[2];
47
48 nibbles[0] = byte >> 4;
49 nibbles[1] = byte & 0x0f;
50 snd_rawmidi_receive(stream, nibbles, 2);
51}
52
53static void midi_input_byte(struct fw_scs1x *scs,
54 struct snd_rawmidi_substream *stream, u8 byte)
55{
56 const u8 eox = 0xf7;
57
58 if (scs->input_escape_count > 0) {
59 midi_input_escaped_byte(stream, byte);
60 scs->input_escape_count--;
61 if (scs->input_escape_count == 0)
62 snd_rawmidi_receive(stream, &eox, sizeof(eox));
63 } else if (byte == 0xf9) {
64 snd_rawmidi_receive(stream, sysex_escape_prefix,
65 ARRAY_SIZE(sysex_escape_prefix));
66 midi_input_escaped_byte(stream, 0x00);
67 midi_input_escaped_byte(stream, 0xf9);
68 scs->input_escape_count = 3;
69 } else {
70 snd_rawmidi_receive(stream, &byte, 1);
71 }
72}
73
74static void midi_input_packet(struct fw_scs1x *scs,
75 struct snd_rawmidi_substream *stream,
76 const u8 *data, unsigned int bytes)
77{
78 unsigned int i;
79 const u8 eox = 0xf7;
80
81 if (data[0] == HSS1394_TAG_USER_DATA) {
82 for (i = 1; i < bytes; ++i)
83 midi_input_byte(scs, stream, data[i]);
84 } else {
85 snd_rawmidi_receive(stream, sysex_escape_prefix,
86 ARRAY_SIZE(sysex_escape_prefix));
87 for (i = 0; i < bytes; ++i)
88 midi_input_escaped_byte(stream, data[i]);
89 snd_rawmidi_receive(stream, &eox, sizeof(eox));
90 }
91}
92
93static void handle_hss(struct fw_card *card, struct fw_request *request,
94 int tcode, int destination, int source, int generation,
95 unsigned long long offset, void *data, size_t length,
96 void *callback_data)
97{
98 struct fw_scs1x *scs = callback_data;
99 struct snd_rawmidi_substream *stream;
100 int rcode;
101
102 if (offset != scs->hss_handler.offset) {
103 rcode = RCODE_ADDRESS_ERROR;
104 goto end;
105 }
106 if (tcode != TCODE_WRITE_QUADLET_REQUEST &&
107 tcode != TCODE_WRITE_BLOCK_REQUEST) {
108 rcode = RCODE_TYPE_ERROR;
109 goto end;
110 }
111
112 if (length >= 1) {
113 stream = ACCESS_ONCE(scs->input);
114 if (stream)
115 midi_input_packet(scs, stream, data, length);
116 }
117
118 rcode = RCODE_COMPLETE;
119end:
120 fw_send_response(card, request, rcode);
121}
122
123static void scs_write_callback(struct fw_card *card, int rcode,
124 void *data, size_t length, void *callback_data)
125{
126 struct fw_scs1x *scs = callback_data;
127
128 if (rcode == RCODE_GENERATION)
129 ; /* TODO: retry this packet */
130
131 scs->transaction_running = false;
132 tasklet_schedule(&scs->tasklet);
133}
134
135static bool is_valid_running_status(u8 status)
136{
137 return status >= 0x80 && status <= 0xef;
138}
139
140static bool is_one_byte_cmd(u8 status)
141{
142 return status == 0xf6 ||
143 status >= 0xf8;
144}
145
146static bool is_two_bytes_cmd(u8 status)
147{
148 return (status >= 0xc0 && status <= 0xdf) ||
149 status == 0xf1 ||
150 status == 0xf3;
151}
152
153static bool is_three_bytes_cmd(u8 status)
154{
155 return (status >= 0x80 && status <= 0xbf) ||
156 (status >= 0xe0 && status <= 0xef) ||
157 status == 0xf2;
158}
159
160static bool is_invalid_cmd(u8 status)
161{
162 return status == 0xf4 ||
163 status == 0xf5 ||
164 status == 0xf9 ||
165 status == 0xfd;
166}
167
168static void scs_output_tasklet(unsigned long data)
169{
170 struct fw_scs1x *scs = (struct fw_scs1x *)data;
171 struct snd_rawmidi_substream *stream;
172 unsigned int i;
173 u8 byte;
174 int generation;
175
176 if (scs->transaction_running)
177 return;
178
179 stream = ACCESS_ONCE(scs->output);
180 if (!stream) {
181 scs->output_idle = true;
182 wake_up(&scs->idle_wait);
183 return;
184 }
185
186 i = scs->output_bytes;
187 for (;;) {
188 if (snd_rawmidi_transmit(stream, &byte, 1) != 1) {
189 scs->output_bytes = i;
190 scs->output_idle = true;
191 wake_up(&scs->idle_wait);
192 return;
193 }
194 /*
195 * Convert from real MIDI to what I think the device expects (no
196 * running status, one command per packet, unescaped SysExs).
197 */
198 if (scs->output_escaped && byte < 0x80) {
199 if (scs->output_escape_high_nibble) {
200 if (i < HSS1394_MAX_PACKET_SIZE) {
201 scs->buffer[i] = byte << 4;
202 scs->output_escape_high_nibble = false;
203 }
204 } else {
205 scs->buffer[i++] |= byte & 0x0f;
206 scs->output_escape_high_nibble = true;
207 }
208 } else if (byte < 0x80) {
209 if (i == 1) {
210 if (!is_valid_running_status(
211 scs->output_status))
212 continue;
213 scs->buffer[0] = HSS1394_TAG_USER_DATA;
214 scs->buffer[i++] = scs->output_status;
215 }
216 scs->buffer[i++] = byte;
217 if ((i == 3 && is_two_bytes_cmd(scs->output_status)) ||
218 (i == 4 && is_three_bytes_cmd(scs->output_status)))
219 break;
220 if (i == 1 + ARRAY_SIZE(sysex_escape_prefix) &&
221 !memcmp(scs->buffer + 1, sysex_escape_prefix,
222 ARRAY_SIZE(sysex_escape_prefix))) {
223 scs->output_escaped = true;
224 scs->output_escape_high_nibble = true;
225 i = 0;
226 }
227 if (i >= HSS1394_MAX_PACKET_SIZE)
228 i = 1;
229 } else if (byte == 0xf7) {
230 if (scs->output_escaped) {
231 if (i >= 1 && scs->output_escape_high_nibble &&
232 scs->buffer[0] !=
233 HSS1394_TAG_CHANGE_ADDRESS)
234 break;
235 } else {
236 if (i > 1 && scs->output_status == 0xf0) {
237 scs->buffer[i++] = 0xf7;
238 break;
239 }
240 }
241 i = 1;
242 scs->output_escaped = false;
243 } else if (!is_invalid_cmd(byte) && byte < 0xf8) {
244 i = 1;
245 scs->buffer[0] = HSS1394_TAG_USER_DATA;
246 scs->buffer[i++] = byte;
247 scs->output_status = byte;
248 scs->output_escaped = false;
249 if (is_one_byte_cmd(byte))
250 break;
251 }
252 }
253 scs->output_bytes = 1;
254 scs->output_escaped = false;
255
256 scs->transaction_running = true;
257 generation = scs->fw_dev->generation;
258 smp_rmb(); /* node_id vs. generation */
259 fw_send_request(scs->fw_dev->card, &scs->transaction,
260 TCODE_WRITE_BLOCK_REQUEST, scs->fw_dev->node_id,
261 generation, scs->fw_dev->max_speed, HSS1394_ADDRESS,
262 scs->buffer, i, scs_write_callback, scs);
263}
264
265static int midi_capture_open(struct snd_rawmidi_substream *stream)
266{
267 return 0;
268}
269
270static int midi_capture_close(struct snd_rawmidi_substream *stream)
271{
272 return 0;
273}
274
275static void midi_capture_trigger(struct snd_rawmidi_substream *stream, int up)
276{
277 struct fw_scs1x *scs = stream->rmidi->private_data;
278
279 if (up) {
280 scs->input_escape_count = 0;
281 ACCESS_ONCE(scs->input) = stream;
282 } else {
283 ACCESS_ONCE(scs->input) = NULL;
284 }
285}
286
287static struct snd_rawmidi_ops midi_capture_ops = {
288 .open = midi_capture_open,
289 .close = midi_capture_close,
290 .trigger = midi_capture_trigger,
291};
292
293static int midi_playback_open(struct snd_rawmidi_substream *stream)
294{
295 return 0;
296}
297
298static int midi_playback_close(struct snd_rawmidi_substream *stream)
299{
300 return 0;
301}
302
303static void midi_playback_trigger(struct snd_rawmidi_substream *stream, int up)
304{
305 struct fw_scs1x *scs = stream->rmidi->private_data;
306
307 if (up) {
308 scs->output_status = 0;
309 scs->output_bytes = 1;
310 scs->output_escaped = false;
311 scs->output_idle = false;
312
313 ACCESS_ONCE(scs->output) = stream;
314 tasklet_schedule(&scs->tasklet);
315 } else {
316 ACCESS_ONCE(scs->output) = NULL;
317 }
318}
319static void midi_playback_drain(struct snd_rawmidi_substream *stream)
320{
321 struct fw_scs1x *scs = stream->rmidi->private_data;
322
323 wait_event(scs->idle_wait, scs->output_idle);
324}
325
326static struct snd_rawmidi_ops midi_playback_ops = {
327 .open = midi_playback_open,
328 .close = midi_playback_close,
329 .trigger = midi_playback_trigger,
330 .drain = midi_playback_drain,
331};
332static int register_address(struct snd_oxfw *oxfw)
333{
334 struct fw_scs1x *scs = oxfw->spec;
335 __be64 data;
336
337 data = cpu_to_be64(((u64)HSS1394_TAG_CHANGE_ADDRESS << 56) |
338 scs->hss_handler.offset);
339 return snd_fw_transaction(oxfw->unit, TCODE_WRITE_BLOCK_REQUEST,
340 HSS1394_ADDRESS, &data, sizeof(data), 0);
341}
342
343static void remove_scs1x(struct snd_rawmidi *rmidi)
344{
345 struct fw_scs1x *scs = rmidi->private_data;
346
347 fw_core_remove_address_handler(&scs->hss_handler);
348}
349
350void snd_oxfw_scs1x_update(struct snd_oxfw *oxfw)
351{
352 register_address(oxfw);
353}
354
355int snd_oxfw_scs1x_add(struct snd_oxfw *oxfw)
356{
357 struct snd_rawmidi *rmidi;
358 struct fw_scs1x *scs;
359 int err;
360
361 scs = kzalloc(sizeof(struct fw_scs1x), GFP_KERNEL);
362 if (scs == NULL)
363 return -ENOMEM;
364 scs->fw_dev = fw_parent_device(oxfw->unit);
365 oxfw->spec = scs;
366
367 /* Allocate own handler for imcoming asynchronous transaction. */
368 scs->hss_handler.length = HSS1394_MAX_PACKET_SIZE;
369 scs->hss_handler.address_callback = handle_hss;
370 scs->hss_handler.callback_data = scs;
371 err = fw_core_add_address_handler(&scs->hss_handler,
372 &fw_high_memory_region);
373 if (err < 0)
374 return err;
375
376 err = register_address(oxfw);
377 if (err < 0)
378 goto err_allocated;
379
380 /* Use unique name for backward compatibility to scs1x module. */
381 err = snd_rawmidi_new(oxfw->card, "SCS.1x", 0, 1, 1, &rmidi);
382 if (err < 0)
383 goto err_allocated;
384 rmidi->private_data = scs;
385 rmidi->private_free = remove_scs1x;
386
387 snprintf(rmidi->name, sizeof(rmidi->name),
388 "%s MIDI", oxfw->card->shortname);
389
390 rmidi->info_flags = SNDRV_RAWMIDI_INFO_INPUT |
391 SNDRV_RAWMIDI_INFO_OUTPUT |
392 SNDRV_RAWMIDI_INFO_DUPLEX;
393 snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_INPUT,
394 &midi_capture_ops);
395 snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_OUTPUT,
396 &midi_playback_ops);
397
398 tasklet_init(&scs->tasklet, scs_output_tasklet, (unsigned long)scs);
399 init_waitqueue_head(&scs->idle_wait);
400 scs->output_idle = true;
401
402 return 0;
403err_allocated:
404 fw_core_remove_address_handler(&scs->hss_handler);
405 return err;
406}
diff --git a/sound/firewire/oxfw/oxfw-control.c b/sound/firewire/oxfw/oxfw-spkr.c
index 02a1cb90f20d..cb905af0660d 100644
--- a/sound/firewire/oxfw/oxfw-control.c
+++ b/sound/firewire/oxfw/oxfw-spkr.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * oxfw_stream.c - a part of driver for OXFW970/971 based devices 2 * oxfw-spkr.c - a part of driver for OXFW970/971 based devices
3 * 3 *
4 * Copyright (c) Clemens Ladisch <clemens@ladisch.de> 4 * Copyright (c) Clemens Ladisch <clemens@ladisch.de>
5 * Licensed under the terms of the GNU General Public License, version 2. 5 * Licensed under the terms of the GNU General Public License, version 2.
@@ -7,6 +7,17 @@
7 7
8#include "oxfw.h" 8#include "oxfw.h"
9 9
10struct fw_spkr {
11 bool mute;
12 s16 volume[6];
13 s16 volume_min;
14 s16 volume_max;
15
16 unsigned int mixer_channels;
17 u8 mute_fb_id;
18 u8 volume_fb_id;
19};
20
10enum control_action { CTL_READ, CTL_WRITE }; 21enum control_action { CTL_READ, CTL_WRITE };
11enum control_attribute { 22enum control_attribute {
12 CTL_MIN = 0x02, 23 CTL_MIN = 0x02,
@@ -14,8 +25,8 @@ enum control_attribute {
14 CTL_CURRENT = 0x10, 25 CTL_CURRENT = 0x10,
15}; 26};
16 27
17static int oxfw_mute_command(struct snd_oxfw *oxfw, bool *value, 28static int avc_audio_feature_mute(struct fw_unit *unit, u8 fb_id, bool *value,
18 enum control_action action) 29 enum control_action action)
19{ 30{
20 u8 *buf; 31 u8 *buf;
21 u8 response_ok; 32 u8 response_ok;
@@ -35,7 +46,7 @@ static int oxfw_mute_command(struct snd_oxfw *oxfw, bool *value,
35 buf[1] = 0x08; /* audio unit 0 */ 46 buf[1] = 0x08; /* audio unit 0 */
36 buf[2] = 0xb8; /* FUNCTION BLOCK */ 47 buf[2] = 0xb8; /* FUNCTION BLOCK */
37 buf[3] = 0x81; /* function block type: feature */ 48 buf[3] = 0x81; /* function block type: feature */
38 buf[4] = oxfw->device_info->mute_fb_id; /* function block ID */ 49 buf[4] = fb_id; /* function block ID */
39 buf[5] = 0x10; /* control attribute: current */ 50 buf[5] = 0x10; /* control attribute: current */
40 buf[6] = 0x02; /* selector length */ 51 buf[6] = 0x02; /* selector length */
41 buf[7] = 0x00; /* audio channel number */ 52 buf[7] = 0x00; /* audio channel number */
@@ -46,16 +57,16 @@ static int oxfw_mute_command(struct snd_oxfw *oxfw, bool *value,
46 else 57 else
47 buf[10] = *value ? 0x70 : 0x60; 58 buf[10] = *value ? 0x70 : 0x60;
48 59
49 err = fcp_avc_transaction(oxfw->unit, buf, 11, buf, 11, 0x3fe); 60 err = fcp_avc_transaction(unit, buf, 11, buf, 11, 0x3fe);
50 if (err < 0) 61 if (err < 0)
51 goto error; 62 goto error;
52 if (err < 11) { 63 if (err < 11) {
53 dev_err(&oxfw->unit->device, "short FCP response\n"); 64 dev_err(&unit->device, "short FCP response\n");
54 err = -EIO; 65 err = -EIO;
55 goto error; 66 goto error;
56 } 67 }
57 if (buf[0] != response_ok) { 68 if (buf[0] != response_ok) {
58 dev_err(&oxfw->unit->device, "mute command failed\n"); 69 dev_err(&unit->device, "mute command failed\n");
59 err = -EIO; 70 err = -EIO;
60 goto error; 71 goto error;
61 } 72 }
@@ -70,10 +81,10 @@ error:
70 return err; 81 return err;
71} 82}
72 83
73static int oxfw_volume_command(struct snd_oxfw *oxfw, s16 *value, 84static int avc_audio_feature_volume(struct fw_unit *unit, u8 fb_id, s16 *value,
74 unsigned int channel, 85 unsigned int channel,
75 enum control_attribute attribute, 86 enum control_attribute attribute,
76 enum control_action action) 87 enum control_action action)
77{ 88{
78 u8 *buf; 89 u8 *buf;
79 u8 response_ok; 90 u8 response_ok;
@@ -93,7 +104,7 @@ static int oxfw_volume_command(struct snd_oxfw *oxfw, s16 *value,
93 buf[1] = 0x08; /* audio unit 0 */ 104 buf[1] = 0x08; /* audio unit 0 */
94 buf[2] = 0xb8; /* FUNCTION BLOCK */ 105 buf[2] = 0xb8; /* FUNCTION BLOCK */
95 buf[3] = 0x81; /* function block type: feature */ 106 buf[3] = 0x81; /* function block type: feature */
96 buf[4] = oxfw->device_info->volume_fb_id; /* function block ID */ 107 buf[4] = fb_id; /* function block ID */
97 buf[5] = attribute; /* control attribute */ 108 buf[5] = attribute; /* control attribute */
98 buf[6] = 0x02; /* selector length */ 109 buf[6] = 0x02; /* selector length */
99 buf[7] = channel; /* audio channel number */ 110 buf[7] = channel; /* audio channel number */
@@ -107,16 +118,16 @@ static int oxfw_volume_command(struct snd_oxfw *oxfw, s16 *value,
107 buf[11] = *value; 118 buf[11] = *value;
108 } 119 }
109 120
110 err = fcp_avc_transaction(oxfw->unit, buf, 12, buf, 12, 0x3fe); 121 err = fcp_avc_transaction(unit, buf, 12, buf, 12, 0x3fe);
111 if (err < 0) 122 if (err < 0)
112 goto error; 123 goto error;
113 if (err < 12) { 124 if (err < 12) {
114 dev_err(&oxfw->unit->device, "short FCP response\n"); 125 dev_err(&unit->device, "short FCP response\n");
115 err = -EIO; 126 err = -EIO;
116 goto error; 127 goto error;
117 } 128 }
118 if (buf[0] != response_ok) { 129 if (buf[0] != response_ok) {
119 dev_err(&oxfw->unit->device, "volume command failed\n"); 130 dev_err(&unit->device, "volume command failed\n");
120 err = -EIO; 131 err = -EIO;
121 goto error; 132 goto error;
122 } 133 }
@@ -131,75 +142,81 @@ error:
131 return err; 142 return err;
132} 143}
133 144
134static int oxfw_mute_get(struct snd_kcontrol *control, 145static int spkr_mute_get(struct snd_kcontrol *control,
135 struct snd_ctl_elem_value *value) 146 struct snd_ctl_elem_value *value)
136{ 147{
137 struct snd_oxfw *oxfw = control->private_data; 148 struct snd_oxfw *oxfw = control->private_data;
149 struct fw_spkr *spkr = oxfw->spec;
138 150
139 value->value.integer.value[0] = !oxfw->mute; 151 value->value.integer.value[0] = !spkr->mute;
140 152
141 return 0; 153 return 0;
142} 154}
143 155
144static int oxfw_mute_put(struct snd_kcontrol *control, 156static int spkr_mute_put(struct snd_kcontrol *control,
145 struct snd_ctl_elem_value *value) 157 struct snd_ctl_elem_value *value)
146{ 158{
147 struct snd_oxfw *oxfw = control->private_data; 159 struct snd_oxfw *oxfw = control->private_data;
160 struct fw_spkr *spkr = oxfw->spec;
148 bool mute; 161 bool mute;
149 int err; 162 int err;
150 163
151 mute = !value->value.integer.value[0]; 164 mute = !value->value.integer.value[0];
152 165
153 if (mute == oxfw->mute) 166 if (mute == spkr->mute)
154 return 0; 167 return 0;
155 168
156 err = oxfw_mute_command(oxfw, &mute, CTL_WRITE); 169 err = avc_audio_feature_mute(oxfw->unit, spkr->mute_fb_id, &mute,
170 CTL_WRITE);
157 if (err < 0) 171 if (err < 0)
158 return err; 172 return err;
159 oxfw->mute = mute; 173 spkr->mute = mute;
160 174
161 return 1; 175 return 1;
162} 176}
163 177
164static int oxfw_volume_info(struct snd_kcontrol *control, 178static int spkr_volume_info(struct snd_kcontrol *control,
165 struct snd_ctl_elem_info *info) 179 struct snd_ctl_elem_info *info)
166{ 180{
167 struct snd_oxfw *oxfw = control->private_data; 181 struct snd_oxfw *oxfw = control->private_data;
182 struct fw_spkr *spkr = oxfw->spec;
168 183
169 info->type = SNDRV_CTL_ELEM_TYPE_INTEGER; 184 info->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
170 info->count = oxfw->device_info->mixer_channels; 185 info->count = spkr->mixer_channels;
171 info->value.integer.min = oxfw->volume_min; 186 info->value.integer.min = spkr->volume_min;
172 info->value.integer.max = oxfw->volume_max; 187 info->value.integer.max = spkr->volume_max;
173 188
174 return 0; 189 return 0;
175} 190}
176 191
177static const u8 channel_map[6] = { 0, 1, 4, 5, 2, 3 }; 192static const u8 channel_map[6] = { 0, 1, 4, 5, 2, 3 };
178 193
179static int oxfw_volume_get(struct snd_kcontrol *control, 194static int spkr_volume_get(struct snd_kcontrol *control,
180 struct snd_ctl_elem_value *value) 195 struct snd_ctl_elem_value *value)
181{ 196{
182 struct snd_oxfw *oxfw = control->private_data; 197 struct snd_oxfw *oxfw = control->private_data;
198 struct fw_spkr *spkr = oxfw->spec;
183 unsigned int i; 199 unsigned int i;
184 200
185 for (i = 0; i < oxfw->device_info->mixer_channels; ++i) 201 for (i = 0; i < spkr->mixer_channels; ++i)
186 value->value.integer.value[channel_map[i]] = oxfw->volume[i]; 202 value->value.integer.value[channel_map[i]] = spkr->volume[i];
187 203
188 return 0; 204 return 0;
189} 205}
190 206
191static int oxfw_volume_put(struct snd_kcontrol *control, 207static int spkr_volume_put(struct snd_kcontrol *control,
192 struct snd_ctl_elem_value *value) 208 struct snd_ctl_elem_value *value)
193{ 209{
194 struct snd_oxfw *oxfw = control->private_data; 210 struct snd_oxfw *oxfw = control->private_data;
211 struct fw_spkr *spkr = oxfw->spec;
195 unsigned int i, changed_channels; 212 unsigned int i, changed_channels;
196 bool equal_values = true; 213 bool equal_values = true;
197 s16 volume; 214 s16 volume;
198 int err; 215 int err;
199 216
200 for (i = 0; i < oxfw->device_info->mixer_channels; ++i) { 217 for (i = 0; i < spkr->mixer_channels; ++i) {
201 if (value->value.integer.value[i] < oxfw->volume_min || 218 if (value->value.integer.value[i] < spkr->volume_min ||
202 value->value.integer.value[i] > oxfw->volume_max) 219 value->value.integer.value[i] > spkr->volume_max)
203 return -EINVAL; 220 return -EINVAL;
204 if (value->value.integer.value[i] != 221 if (value->value.integer.value[i] !=
205 value->value.integer.value[0]) 222 value->value.integer.value[0])
@@ -207,67 +224,86 @@ static int oxfw_volume_put(struct snd_kcontrol *control,
207 } 224 }
208 225
209 changed_channels = 0; 226 changed_channels = 0;
210 for (i = 0; i < oxfw->device_info->mixer_channels; ++i) 227 for (i = 0; i < spkr->mixer_channels; ++i)
211 if (value->value.integer.value[channel_map[i]] != 228 if (value->value.integer.value[channel_map[i]] !=
212 oxfw->volume[i]) 229 spkr->volume[i])
213 changed_channels |= 1 << (i + 1); 230 changed_channels |= 1 << (i + 1);
214 231
215 if (equal_values && changed_channels != 0) 232 if (equal_values && changed_channels != 0)
216 changed_channels = 1 << 0; 233 changed_channels = 1 << 0;
217 234
218 for (i = 0; i <= oxfw->device_info->mixer_channels; ++i) { 235 for (i = 0; i <= spkr->mixer_channels; ++i) {
219 volume = value->value.integer.value[channel_map[i ? i - 1 : 0]]; 236 volume = value->value.integer.value[channel_map[i ? i - 1 : 0]];
220 if (changed_channels & (1 << i)) { 237 if (changed_channels & (1 << i)) {
221 err = oxfw_volume_command(oxfw, &volume, i, 238 err = avc_audio_feature_volume(oxfw->unit,
222 CTL_CURRENT, CTL_WRITE); 239 spkr->volume_fb_id, &volume,
240 i, CTL_CURRENT, CTL_WRITE);
223 if (err < 0) 241 if (err < 0)
224 return err; 242 return err;
225 } 243 }
226 if (i > 0) 244 if (i > 0)
227 oxfw->volume[i - 1] = volume; 245 spkr->volume[i - 1] = volume;
228 } 246 }
229 247
230 return changed_channels != 0; 248 return changed_channels != 0;
231} 249}
232 250
233int snd_oxfw_create_mixer(struct snd_oxfw *oxfw) 251int snd_oxfw_add_spkr(struct snd_oxfw *oxfw, bool is_lacie)
234{ 252{
235 static const struct snd_kcontrol_new controls[] = { 253 static const struct snd_kcontrol_new controls[] = {
236 { 254 {
237 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 255 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
238 .name = "PCM Playback Switch", 256 .name = "PCM Playback Switch",
239 .info = snd_ctl_boolean_mono_info, 257 .info = snd_ctl_boolean_mono_info,
240 .get = oxfw_mute_get, 258 .get = spkr_mute_get,
241 .put = oxfw_mute_put, 259 .put = spkr_mute_put,
242 }, 260 },
243 { 261 {
244 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 262 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
245 .name = "PCM Playback Volume", 263 .name = "PCM Playback Volume",
246 .info = oxfw_volume_info, 264 .info = spkr_volume_info,
247 .get = oxfw_volume_get, 265 .get = spkr_volume_get,
248 .put = oxfw_volume_put, 266 .put = spkr_volume_put,
249 }, 267 },
250 }; 268 };
269 struct fw_spkr *spkr;
251 unsigned int i, first_ch; 270 unsigned int i, first_ch;
252 int err; 271 int err;
253 272
254 err = oxfw_volume_command(oxfw, &oxfw->volume_min, 273 spkr = kzalloc(sizeof(struct fw_spkr), GFP_KERNEL);
255 0, CTL_MIN, CTL_READ); 274 if (spkr == NULL)
275 return -ENOMEM;
276 oxfw->spec = spkr;
277
278 if (is_lacie) {
279 spkr->mixer_channels = 1;
280 spkr->mute_fb_id = 0x01;
281 spkr->volume_fb_id = 0x01;
282 } else {
283 spkr->mixer_channels = 6;
284 spkr->mute_fb_id = 0x01;
285 spkr->volume_fb_id = 0x02;
286 }
287
288 err = avc_audio_feature_volume(oxfw->unit, spkr->volume_fb_id,
289 &spkr->volume_min, 0, CTL_MIN, CTL_READ);
256 if (err < 0) 290 if (err < 0)
257 return err; 291 return err;
258 err = oxfw_volume_command(oxfw, &oxfw->volume_max, 292 err = avc_audio_feature_volume(oxfw->unit, spkr->volume_fb_id,
259 0, CTL_MAX, CTL_READ); 293 &spkr->volume_max, 0, CTL_MAX, CTL_READ);
260 if (err < 0) 294 if (err < 0)
261 return err; 295 return err;
262 296
263 err = oxfw_mute_command(oxfw, &oxfw->mute, CTL_READ); 297 err = avc_audio_feature_mute(oxfw->unit, spkr->mute_fb_id, &spkr->mute,
298 CTL_READ);
264 if (err < 0) 299 if (err < 0)
265 return err; 300 return err;
266 301
267 first_ch = oxfw->device_info->mixer_channels == 1 ? 0 : 1; 302 first_ch = spkr->mixer_channels == 1 ? 0 : 1;
268 for (i = 0; i < oxfw->device_info->mixer_channels; ++i) { 303 for (i = 0; i < spkr->mixer_channels; ++i) {
269 err = oxfw_volume_command(oxfw, &oxfw->volume[i], 304 err = avc_audio_feature_volume(oxfw->unit, spkr->volume_fb_id,
270 first_ch + i, CTL_CURRENT, CTL_READ); 305 &spkr->volume[i], first_ch + i,
306 CTL_CURRENT, CTL_READ);
271 if (err < 0) 307 if (err < 0)
272 return err; 308 return err;
273 } 309 }
diff --git a/sound/firewire/oxfw/oxfw.c b/sound/firewire/oxfw/oxfw.c
index 588b93f20c2e..abedc2207261 100644
--- a/sound/firewire/oxfw/oxfw.c
+++ b/sound/firewire/oxfw/oxfw.c
@@ -19,6 +19,7 @@
19#define VENDOR_BEHRINGER 0x001564 19#define VENDOR_BEHRINGER 0x001564
20#define VENDOR_LACIE 0x00d04b 20#define VENDOR_LACIE 0x00d04b
21#define VENDOR_TASCAM 0x00022e 21#define VENDOR_TASCAM 0x00022e
22#define OUI_STANTON 0x001260
22 23
23#define MODEL_SATELLITE 0x00200f 24#define MODEL_SATELLITE 0x00200f
24 25
@@ -29,6 +30,13 @@ MODULE_DESCRIPTION("Oxford Semiconductor FW970/971 driver");
29MODULE_AUTHOR("Clemens Ladisch <clemens@ladisch.de>"); 30MODULE_AUTHOR("Clemens Ladisch <clemens@ladisch.de>");
30MODULE_LICENSE("GPL v2"); 31MODULE_LICENSE("GPL v2");
31MODULE_ALIAS("snd-firewire-speakers"); 32MODULE_ALIAS("snd-firewire-speakers");
33MODULE_ALIAS("snd-scs1x");
34
35struct compat_info {
36 const char *driver_name;
37 const char *vendor_name;
38 const char *model_name;
39};
32 40
33static bool detect_loud_models(struct fw_unit *unit) 41static bool detect_loud_models(struct fw_unit *unit)
34{ 42{
@@ -59,6 +67,7 @@ static bool detect_loud_models(struct fw_unit *unit)
59static int name_card(struct snd_oxfw *oxfw) 67static int name_card(struct snd_oxfw *oxfw)
60{ 68{
61 struct fw_device *fw_dev = fw_parent_device(oxfw->unit); 69 struct fw_device *fw_dev = fw_parent_device(oxfw->unit);
70 const struct compat_info *info;
62 char vendor[24]; 71 char vendor[24];
63 char model[32]; 72 char model[32];
64 const char *d, *v, *m; 73 const char *d, *v, *m;
@@ -84,10 +93,12 @@ static int name_card(struct snd_oxfw *oxfw)
84 be32_to_cpus(&firmware); 93 be32_to_cpus(&firmware);
85 94
86 /* to apply card definitions */ 95 /* to apply card definitions */
87 if (oxfw->device_info) { 96 if (oxfw->entry->vendor_id == VENDOR_GRIFFIN ||
88 d = oxfw->device_info->driver_name; 97 oxfw->entry->vendor_id == VENDOR_LACIE) {
89 v = oxfw->device_info->vendor_name; 98 info = (const struct compat_info *)oxfw->entry->driver_data;
90 m = oxfw->device_info->model_name; 99 d = info->driver_name;
100 v = info->vendor_name;
101 m = info->model_name;
91 } else { 102 } else {
92 d = "OXFW"; 103 d = "OXFW";
93 v = vendor; 104 v = vendor;
@@ -129,16 +140,51 @@ static void oxfw_card_free(struct snd_card *card)
129 kfree(oxfw->rx_stream_formats[i]); 140 kfree(oxfw->rx_stream_formats[i]);
130 } 141 }
131 142
143 kfree(oxfw->spec);
132 mutex_destroy(&oxfw->mutex); 144 mutex_destroy(&oxfw->mutex);
133} 145}
134 146
135static void detect_quirks(struct snd_oxfw *oxfw) 147static int detect_quirks(struct snd_oxfw *oxfw)
136{ 148{
137 struct fw_device *fw_dev = fw_parent_device(oxfw->unit); 149 struct fw_device *fw_dev = fw_parent_device(oxfw->unit);
138 struct fw_csr_iterator it; 150 struct fw_csr_iterator it;
139 int key, val; 151 int key, val;
140 int vendor, model; 152 int vendor, model;
141 153
154 /*
155 * Add ALSA control elements for two models to keep compatibility to
156 * old firewire-speaker module.
157 */
158 if (oxfw->entry->vendor_id == VENDOR_GRIFFIN)
159 return snd_oxfw_add_spkr(oxfw, false);
160 if (oxfw->entry->vendor_id == VENDOR_LACIE)
161 return snd_oxfw_add_spkr(oxfw, true);
162
163 /*
164 * Stanton models supports asynchronous transactions for unique MIDI
165 * messages.
166 */
167 if (oxfw->entry->vendor_id == OUI_STANTON) {
168 /* No physical MIDI ports. */
169 oxfw->midi_input_ports = 0;
170 oxfw->midi_output_ports = 0;
171
172 /* Output stream exists but no data channels are useful. */
173 oxfw->has_output = false;
174
175 return snd_oxfw_scs1x_add(oxfw);
176 }
177
178 /*
179 * TASCAM FireOne has physical control and requires a pair of additional
180 * MIDI ports.
181 */
182 if (oxfw->entry->vendor_id == VENDOR_TASCAM) {
183 oxfw->midi_input_ports++;
184 oxfw->midi_output_ports++;
185 return 0;
186 }
187
142 /* Seek from Root Directory of Config ROM. */ 188 /* Seek from Root Directory of Config ROM. */
143 vendor = model = 0; 189 vendor = model = 0;
144 fw_csr_iterator_init(&it, fw_dev->config_rom + 5); 190 fw_csr_iterator_init(&it, fw_dev->config_rom + 5);
@@ -156,24 +202,17 @@ static void detect_quirks(struct snd_oxfw *oxfw)
156 if (vendor == VENDOR_LOUD && model == MODEL_SATELLITE) 202 if (vendor == VENDOR_LOUD && model == MODEL_SATELLITE)
157 oxfw->wrong_dbs = true; 203 oxfw->wrong_dbs = true;
158 204
159 /* 205 return 0;
160 * TASCAM FireOne has physical control and requires a pair of additional
161 * MIDI ports.
162 */
163 if (vendor == VENDOR_TASCAM) {
164 oxfw->midi_input_ports++;
165 oxfw->midi_output_ports++;
166 }
167} 206}
168 207
169static int oxfw_probe(struct fw_unit *unit, 208static int oxfw_probe(struct fw_unit *unit,
170 const struct ieee1394_device_id *id) 209 const struct ieee1394_device_id *entry)
171{ 210{
172 struct snd_card *card; 211 struct snd_card *card;
173 struct snd_oxfw *oxfw; 212 struct snd_oxfw *oxfw;
174 int err; 213 int err;
175 214
176 if ((id->vendor_id == VENDOR_LOUD) && !detect_loud_models(unit)) 215 if (entry->vendor_id == VENDOR_LOUD && !detect_loud_models(unit))
177 return -ENODEV; 216 return -ENODEV;
178 217
179 err = snd_card_new(&unit->device, -1, NULL, THIS_MODULE, 218 err = snd_card_new(&unit->device, -1, NULL, THIS_MODULE,
@@ -186,7 +225,7 @@ static int oxfw_probe(struct fw_unit *unit,
186 oxfw->card = card; 225 oxfw->card = card;
187 mutex_init(&oxfw->mutex); 226 mutex_init(&oxfw->mutex);
188 oxfw->unit = fw_unit_get(unit); 227 oxfw->unit = fw_unit_get(unit);
189 oxfw->device_info = (const struct device_info *)id->driver_data; 228 oxfw->entry = entry;
190 spin_lock_init(&oxfw->lock); 229 spin_lock_init(&oxfw->lock);
191 init_waitqueue_head(&oxfw->hwdep_wait); 230 init_waitqueue_head(&oxfw->hwdep_wait);
192 231
@@ -194,21 +233,17 @@ static int oxfw_probe(struct fw_unit *unit,
194 if (err < 0) 233 if (err < 0)
195 goto error; 234 goto error;
196 235
197 detect_quirks(oxfw);
198
199 err = name_card(oxfw); 236 err = name_card(oxfw);
200 if (err < 0) 237 if (err < 0)
201 goto error; 238 goto error;
202 239
203 err = snd_oxfw_create_pcm(oxfw); 240 err = detect_quirks(oxfw);
204 if (err < 0) 241 if (err < 0)
205 goto error; 242 goto error;
206 243
207 if (oxfw->device_info) { 244 err = snd_oxfw_create_pcm(oxfw);
208 err = snd_oxfw_create_mixer(oxfw); 245 if (err < 0)
209 if (err < 0) 246 goto error;
210 goto error;
211 }
212 247
213 snd_oxfw_proc_init(oxfw); 248 snd_oxfw_proc_init(oxfw);
214 249
@@ -257,6 +292,9 @@ static void oxfw_bus_reset(struct fw_unit *unit)
257 snd_oxfw_stream_update_simplex(oxfw, &oxfw->tx_stream); 292 snd_oxfw_stream_update_simplex(oxfw, &oxfw->tx_stream);
258 293
259 mutex_unlock(&oxfw->mutex); 294 mutex_unlock(&oxfw->mutex);
295
296 if (oxfw->entry->vendor_id == OUI_STANTON)
297 snd_oxfw_scs1x_update(oxfw);
260} 298}
261 299
262static void oxfw_remove(struct fw_unit *unit) 300static void oxfw_remove(struct fw_unit *unit)
@@ -267,22 +305,16 @@ static void oxfw_remove(struct fw_unit *unit)
267 snd_card_free_when_closed(oxfw->card); 305 snd_card_free_when_closed(oxfw->card);
268} 306}
269 307
270static const struct device_info griffin_firewave = { 308static const struct compat_info griffin_firewave = {
271 .driver_name = "FireWave", 309 .driver_name = "FireWave",
272 .vendor_name = "Griffin", 310 .vendor_name = "Griffin",
273 .model_name = "FireWave", 311 .model_name = "FireWave",
274 .mixer_channels = 6,
275 .mute_fb_id = 0x01,
276 .volume_fb_id = 0x02,
277}; 312};
278 313
279static const struct device_info lacie_speakers = { 314static const struct compat_info lacie_speakers = {
280 .driver_name = "FWSpeakers", 315 .driver_name = "FWSpeakers",
281 .vendor_name = "LaCie", 316 .vendor_name = "LaCie",
282 .model_name = "FireWire Speakers", 317 .model_name = "FireWire Speakers",
283 .mixer_channels = 1,
284 .mute_fb_id = 0x01,
285 .volume_fb_id = 0x01,
286}; 318};
287 319
288static const struct ieee1394_device_id oxfw_id_table[] = { 320static const struct ieee1394_device_id oxfw_id_table[] = {
@@ -340,6 +372,20 @@ static const struct ieee1394_device_id oxfw_id_table[] = {
340 .vendor_id = VENDOR_TASCAM, 372 .vendor_id = VENDOR_TASCAM,
341 .model_id = 0x800007, 373 .model_id = 0x800007,
342 }, 374 },
375 /* Stanton, Stanton Controllers & Systems 1 Mixer (SCS.1m) */
376 {
377 .match_flags = IEEE1394_MATCH_VENDOR_ID |
378 IEEE1394_MATCH_MODEL_ID,
379 .vendor_id = OUI_STANTON,
380 .model_id = 0x001000,
381 },
382 /* Stanton, Stanton Controllers & Systems 1 Deck (SCS.1d) */
383 {
384 .match_flags = IEEE1394_MATCH_VENDOR_ID |
385 IEEE1394_MATCH_MODEL_ID,
386 .vendor_id = OUI_STANTON,
387 .model_id = 0x002000,
388 },
343 { } 389 { }
344}; 390};
345MODULE_DEVICE_TABLE(ieee1394, oxfw_id_table); 391MODULE_DEVICE_TABLE(ieee1394, oxfw_id_table);
diff --git a/sound/firewire/oxfw/oxfw.h b/sound/firewire/oxfw/oxfw.h
index 8392c424ad1d..9beecc214767 100644
--- a/sound/firewire/oxfw/oxfw.h
+++ b/sound/firewire/oxfw/oxfw.h
@@ -31,15 +31,6 @@
31#include "../amdtp-am824.h" 31#include "../amdtp-am824.h"
32#include "../cmp.h" 32#include "../cmp.h"
33 33
34struct device_info {
35 const char *driver_name;
36 const char *vendor_name;
37 const char *model_name;
38 unsigned int mixer_channels;
39 u8 mute_fb_id;
40 u8 volume_fb_id;
41};
42
43/* This is an arbitrary number for convinience. */ 34/* This is an arbitrary number for convinience. */
44#define SND_OXFW_STREAM_FORMAT_ENTRIES 10 35#define SND_OXFW_STREAM_FORMAT_ENTRIES 10
45struct snd_oxfw { 36struct snd_oxfw {
@@ -64,14 +55,12 @@ struct snd_oxfw {
64 unsigned int midi_input_ports; 55 unsigned int midi_input_ports;
65 unsigned int midi_output_ports; 56 unsigned int midi_output_ports;
66 57
67 bool mute;
68 s16 volume[6];
69 s16 volume_min;
70 s16 volume_max;
71
72 int dev_lock_count; 58 int dev_lock_count;
73 bool dev_lock_changed; 59 bool dev_lock_changed;
74 wait_queue_head_t hwdep_wait; 60 wait_queue_head_t hwdep_wait;
61
62 const struct ieee1394_device_id *entry;
63 void *spec;
75}; 64};
76 65
77/* 66/*
@@ -138,10 +127,12 @@ void snd_oxfw_stream_lock_release(struct snd_oxfw *oxfw);
138 127
139int snd_oxfw_create_pcm(struct snd_oxfw *oxfw); 128int snd_oxfw_create_pcm(struct snd_oxfw *oxfw);
140 129
141int snd_oxfw_create_mixer(struct snd_oxfw *oxfw);
142
143void snd_oxfw_proc_init(struct snd_oxfw *oxfw); 130void snd_oxfw_proc_init(struct snd_oxfw *oxfw);
144 131
145int snd_oxfw_create_midi(struct snd_oxfw *oxfw); 132int snd_oxfw_create_midi(struct snd_oxfw *oxfw);
146 133
147int snd_oxfw_create_hwdep(struct snd_oxfw *oxfw); 134int snd_oxfw_create_hwdep(struct snd_oxfw *oxfw);
135
136int snd_oxfw_add_spkr(struct snd_oxfw *oxfw, bool is_lacie);
137int snd_oxfw_scs1x_add(struct snd_oxfw *oxfw);
138void snd_oxfw_scs1x_update(struct snd_oxfw *oxfw);
diff --git a/sound/firewire/scs1x.c b/sound/firewire/scs1x.c
deleted file mode 100644
index 2dba848a781f..000000000000
--- a/sound/firewire/scs1x.c
+++ /dev/null
@@ -1,530 +0,0 @@
1/*
2 * Stanton Control System 1 MIDI driver
3 *
4 * Copyright (c) Clemens Ladisch <clemens@ladisch.de>
5 * Licensed under the terms of the GNU General Public License, version 2.
6 */
7
8#include <linux/device.h>
9#include <linux/firewire.h>
10#include <linux/firewire-constants.h>
11#include <linux/interrupt.h>
12#include <linux/module.h>
13#include <linux/mod_devicetable.h>
14#include <linux/slab.h>
15#include <linux/string.h>
16#include <linux/wait.h>
17#include <sound/core.h>
18#include <sound/initval.h>
19#include <sound/rawmidi.h>
20#include "lib.h"
21
22#define OUI_STANTON 0x001260
23#define MODEL_SCS_1M 0x001000
24#define MODEL_SCS_1D 0x002000
25
26#define HSS1394_ADDRESS 0xc007dedadadaULL
27#define HSS1394_MAX_PACKET_SIZE 64
28
29#define HSS1394_TAG_USER_DATA 0x00
30#define HSS1394_TAG_CHANGE_ADDRESS 0xf1
31
32struct scs {
33 struct snd_card *card;
34 struct fw_unit *unit;
35 struct fw_address_handler hss_handler;
36 struct fw_transaction transaction;
37 bool transaction_running;
38 bool output_idle;
39 u8 output_status;
40 u8 output_bytes;
41 bool output_escaped;
42 bool output_escape_high_nibble;
43 u8 input_escape_count;
44 struct snd_rawmidi_substream *output;
45 struct snd_rawmidi_substream *input;
46 struct tasklet_struct tasklet;
47 wait_queue_head_t idle_wait;
48 u8 *buffer;
49};
50
51static const u8 sysex_escape_prefix[] = {
52 0xf0, /* SysEx begin */
53 0x00, 0x01, 0x60, /* Stanton DJ */
54 0x48, 0x53, 0x53, /* "HSS" */
55};
56
57static int scs_output_open(struct snd_rawmidi_substream *stream)
58{
59 struct scs *scs = stream->rmidi->private_data;
60
61 scs->output_status = 0;
62 scs->output_bytes = 1;
63 scs->output_escaped = false;
64
65 return 0;
66}
67
68static int scs_output_close(struct snd_rawmidi_substream *stream)
69{
70 return 0;
71}
72
73static void scs_output_trigger(struct snd_rawmidi_substream *stream, int up)
74{
75 struct scs *scs = stream->rmidi->private_data;
76
77 ACCESS_ONCE(scs->output) = up ? stream : NULL;
78 if (up) {
79 scs->output_idle = false;
80 tasklet_schedule(&scs->tasklet);
81 }
82}
83
84static void scs_write_callback(struct fw_card *card, int rcode,
85 void *data, size_t length, void *callback_data)
86{
87 struct scs *scs = callback_data;
88
89 if (rcode == RCODE_GENERATION) {
90 /* TODO: retry this packet */
91 }
92
93 scs->transaction_running = false;
94 tasklet_schedule(&scs->tasklet);
95}
96
97static bool is_valid_running_status(u8 status)
98{
99 return status >= 0x80 && status <= 0xef;
100}
101
102static bool is_one_byte_cmd(u8 status)
103{
104 return status == 0xf6 ||
105 status >= 0xf8;
106}
107
108static bool is_two_bytes_cmd(u8 status)
109{
110 return (status >= 0xc0 && status <= 0xdf) ||
111 status == 0xf1 ||
112 status == 0xf3;
113}
114
115static bool is_three_bytes_cmd(u8 status)
116{
117 return (status >= 0x80 && status <= 0xbf) ||
118 (status >= 0xe0 && status <= 0xef) ||
119 status == 0xf2;
120}
121
122static bool is_invalid_cmd(u8 status)
123{
124 return status == 0xf4 ||
125 status == 0xf5 ||
126 status == 0xf9 ||
127 status == 0xfd;
128}
129
130static void scs_output_tasklet(unsigned long data)
131{
132 struct scs *scs = (void *)data;
133 struct snd_rawmidi_substream *stream;
134 unsigned int i;
135 u8 byte;
136 struct fw_device *dev;
137 int generation;
138
139 if (scs->transaction_running)
140 return;
141
142 stream = ACCESS_ONCE(scs->output);
143 if (!stream) {
144 scs->output_idle = true;
145 wake_up(&scs->idle_wait);
146 return;
147 }
148
149 i = scs->output_bytes;
150 for (;;) {
151 if (snd_rawmidi_transmit(stream, &byte, 1) != 1) {
152 scs->output_bytes = i;
153 scs->output_idle = true;
154 wake_up(&scs->idle_wait);
155 return;
156 }
157 /*
158 * Convert from real MIDI to what I think the device expects (no
159 * running status, one command per packet, unescaped SysExs).
160 */
161 if (scs->output_escaped && byte < 0x80) {
162 if (scs->output_escape_high_nibble) {
163 if (i < HSS1394_MAX_PACKET_SIZE) {
164 scs->buffer[i] = byte << 4;
165 scs->output_escape_high_nibble = false;
166 }
167 } else {
168 scs->buffer[i++] |= byte & 0x0f;
169 scs->output_escape_high_nibble = true;
170 }
171 } else if (byte < 0x80) {
172 if (i == 1) {
173 if (!is_valid_running_status(scs->output_status))
174 continue;
175 scs->buffer[0] = HSS1394_TAG_USER_DATA;
176 scs->buffer[i++] = scs->output_status;
177 }
178 scs->buffer[i++] = byte;
179 if ((i == 3 && is_two_bytes_cmd(scs->output_status)) ||
180 (i == 4 && is_three_bytes_cmd(scs->output_status)))
181 break;
182 if (i == 1 + ARRAY_SIZE(sysex_escape_prefix) &&
183 !memcmp(scs->buffer + 1, sysex_escape_prefix,
184 ARRAY_SIZE(sysex_escape_prefix))) {
185 scs->output_escaped = true;
186 scs->output_escape_high_nibble = true;
187 i = 0;
188 }
189 if (i >= HSS1394_MAX_PACKET_SIZE)
190 i = 1;
191 } else if (byte == 0xf7) {
192 if (scs->output_escaped) {
193 if (i >= 1 && scs->output_escape_high_nibble &&
194 scs->buffer[0] != HSS1394_TAG_CHANGE_ADDRESS)
195 break;
196 } else {
197 if (i > 1 && scs->output_status == 0xf0) {
198 scs->buffer[i++] = 0xf7;
199 break;
200 }
201 }
202 i = 1;
203 scs->output_escaped = false;
204 } else if (!is_invalid_cmd(byte) &&
205 byte < 0xf8) {
206 i = 1;
207 scs->buffer[0] = HSS1394_TAG_USER_DATA;
208 scs->buffer[i++] = byte;
209 scs->output_status = byte;
210 scs->output_escaped = false;
211 if (is_one_byte_cmd(byte))
212 break;
213 }
214 }
215 scs->output_bytes = 1;
216 scs->output_escaped = false;
217
218 scs->transaction_running = true;
219 dev = fw_parent_device(scs->unit);
220 generation = dev->generation;
221 smp_rmb(); /* node_id vs. generation */
222 fw_send_request(dev->card, &scs->transaction, TCODE_WRITE_BLOCK_REQUEST,
223 dev->node_id, generation, dev->max_speed,
224 HSS1394_ADDRESS, scs->buffer, i,
225 scs_write_callback, scs);
226}
227
228static void scs_output_drain(struct snd_rawmidi_substream *stream)
229{
230 struct scs *scs = stream->rmidi->private_data;
231
232 wait_event(scs->idle_wait, scs->output_idle);
233}
234
235static struct snd_rawmidi_ops output_ops = {
236 .open = scs_output_open,
237 .close = scs_output_close,
238 .trigger = scs_output_trigger,
239 .drain = scs_output_drain,
240};
241
242static int scs_input_open(struct snd_rawmidi_substream *stream)
243{
244 struct scs *scs = stream->rmidi->private_data;
245
246 scs->input_escape_count = 0;
247
248 return 0;
249}
250
251static int scs_input_close(struct snd_rawmidi_substream *stream)
252{
253 return 0;
254}
255
256static void scs_input_trigger(struct snd_rawmidi_substream *stream, int up)
257{
258 struct scs *scs = stream->rmidi->private_data;
259
260 ACCESS_ONCE(scs->input) = up ? stream : NULL;
261}
262
263static void scs_input_escaped_byte(struct snd_rawmidi_substream *stream,
264 u8 byte)
265{
266 u8 nibbles[2];
267
268 nibbles[0] = byte >> 4;
269 nibbles[1] = byte & 0x0f;
270 snd_rawmidi_receive(stream, nibbles, 2);
271}
272
273static void scs_input_midi_byte(struct scs *scs,
274 struct snd_rawmidi_substream *stream,
275 u8 byte)
276{
277 if (scs->input_escape_count > 0) {
278 scs_input_escaped_byte(stream, byte);
279 scs->input_escape_count--;
280 if (scs->input_escape_count == 0)
281 snd_rawmidi_receive(stream, (const u8[]) { 0xf7 }, 1);
282 } else if (byte == 0xf9) {
283 snd_rawmidi_receive(stream, sysex_escape_prefix,
284 ARRAY_SIZE(sysex_escape_prefix));
285 scs_input_escaped_byte(stream, 0x00);
286 scs_input_escaped_byte(stream, 0xf9);
287 scs->input_escape_count = 3;
288 } else {
289 snd_rawmidi_receive(stream, &byte, 1);
290 }
291}
292
293static void scs_input_packet(struct scs *scs,
294 struct snd_rawmidi_substream *stream,
295 const u8 *data, unsigned int bytes)
296{
297 unsigned int i;
298
299 if (data[0] == HSS1394_TAG_USER_DATA) {
300 for (i = 1; i < bytes; ++i)
301 scs_input_midi_byte(scs, stream, data[i]);
302 } else {
303 snd_rawmidi_receive(stream, sysex_escape_prefix,
304 ARRAY_SIZE(sysex_escape_prefix));
305 for (i = 0; i < bytes; ++i)
306 scs_input_escaped_byte(stream, data[i]);
307 snd_rawmidi_receive(stream, (const u8[]) { 0xf7 }, 1);
308 }
309}
310
311static struct snd_rawmidi_ops input_ops = {
312 .open = scs_input_open,
313 .close = scs_input_close,
314 .trigger = scs_input_trigger,
315};
316
317static int scs_create_midi(struct scs *scs)
318{
319 struct snd_rawmidi *rmidi;
320 int err;
321
322 err = snd_rawmidi_new(scs->card, "SCS.1x", 0, 1, 1, &rmidi);
323 if (err < 0)
324 return err;
325 snprintf(rmidi->name, sizeof(rmidi->name),
326 "%s MIDI", scs->card->shortname);
327 rmidi->info_flags = SNDRV_RAWMIDI_INFO_OUTPUT |
328 SNDRV_RAWMIDI_INFO_INPUT |
329 SNDRV_RAWMIDI_INFO_DUPLEX;
330 rmidi->private_data = scs;
331 snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_OUTPUT, &output_ops);
332 snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_INPUT, &input_ops);
333
334 return 0;
335}
336
337static void handle_hss(struct fw_card *card, struct fw_request *request,
338 int tcode, int destination, int source, int generation,
339 unsigned long long offset, void *data, size_t length,
340 void *callback_data)
341{
342 struct scs *scs = callback_data;
343 struct snd_rawmidi_substream *stream;
344
345 if (offset != scs->hss_handler.offset) {
346 fw_send_response(card, request, RCODE_ADDRESS_ERROR);
347 return;
348 }
349 if (tcode != TCODE_WRITE_QUADLET_REQUEST &&
350 tcode != TCODE_WRITE_BLOCK_REQUEST) {
351 fw_send_response(card, request, RCODE_TYPE_ERROR);
352 return;
353 }
354
355 if (length >= 1) {
356 stream = ACCESS_ONCE(scs->input);
357 if (stream)
358 scs_input_packet(scs, stream, data, length);
359 }
360
361 fw_send_response(card, request, RCODE_COMPLETE);
362}
363
364static int scs_init_hss_address(struct scs *scs)
365{
366 __be64 data;
367 int err;
368
369 data = cpu_to_be64(((u64)HSS1394_TAG_CHANGE_ADDRESS << 56) |
370 scs->hss_handler.offset);
371 err = snd_fw_transaction(scs->unit, TCODE_WRITE_BLOCK_REQUEST,
372 HSS1394_ADDRESS, &data, 8, 0);
373 if (err < 0)
374 dev_err(&scs->unit->device, "HSS1394 communication failed\n");
375
376 return err;
377}
378
379static void scs_card_free(struct snd_card *card)
380{
381 struct scs *scs = card->private_data;
382
383 fw_core_remove_address_handler(&scs->hss_handler);
384 kfree(scs->buffer);
385}
386
387static int scs_probe(struct fw_unit *unit, const struct ieee1394_device_id *id)
388{
389 struct fw_device *fw_dev = fw_parent_device(unit);
390 struct snd_card *card;
391 struct scs *scs;
392 int err;
393
394 err = snd_card_new(&unit->device, -16, NULL, THIS_MODULE,
395 sizeof(*scs), &card);
396 if (err < 0)
397 return err;
398
399 scs = card->private_data;
400 scs->card = card;
401 scs->unit = unit;
402 tasklet_init(&scs->tasklet, scs_output_tasklet, (unsigned long)scs);
403 init_waitqueue_head(&scs->idle_wait);
404 scs->output_idle = true;
405
406 scs->buffer = kmalloc(HSS1394_MAX_PACKET_SIZE, GFP_KERNEL);
407 if (!scs->buffer) {
408 err = -ENOMEM;
409 goto err_card;
410 }
411
412 scs->hss_handler.length = HSS1394_MAX_PACKET_SIZE;
413 scs->hss_handler.address_callback = handle_hss;
414 scs->hss_handler.callback_data = scs;
415 err = fw_core_add_address_handler(&scs->hss_handler,
416 &fw_high_memory_region);
417 if (err < 0)
418 goto err_buffer;
419
420 card->private_free = scs_card_free;
421
422 strcpy(card->driver, "SCS.1x");
423 strcpy(card->shortname, "SCS.1x");
424 fw_csr_string(unit->directory, CSR_MODEL,
425 card->shortname, sizeof(card->shortname));
426 snprintf(card->longname, sizeof(card->longname),
427 "Stanton DJ %s (GUID %08x%08x) at %s, S%d",
428 card->shortname, fw_dev->config_rom[3], fw_dev->config_rom[4],
429 dev_name(&unit->device), 100 << fw_dev->max_speed);
430 strcpy(card->mixername, card->shortname);
431
432 err = scs_init_hss_address(scs);
433 if (err < 0)
434 goto err_card;
435
436 err = scs_create_midi(scs);
437 if (err < 0)
438 goto err_card;
439
440 err = snd_card_register(card);
441 if (err < 0)
442 goto err_card;
443
444 dev_set_drvdata(&unit->device, scs);
445
446 return 0;
447
448err_buffer:
449 kfree(scs->buffer);
450err_card:
451 snd_card_free(card);
452 return err;
453}
454
455static void scs_update(struct fw_unit *unit)
456{
457 struct scs *scs = dev_get_drvdata(&unit->device);
458 int generation;
459 __be64 data;
460
461 data = cpu_to_be64(((u64)HSS1394_TAG_CHANGE_ADDRESS << 56) |
462 scs->hss_handler.offset);
463 generation = fw_parent_device(unit)->generation;
464 smp_rmb(); /* node_id vs. generation */
465 snd_fw_transaction(scs->unit, TCODE_WRITE_BLOCK_REQUEST,
466 HSS1394_ADDRESS, &data, 8,
467 FW_FIXED_GENERATION | generation);
468}
469
470static void scs_remove(struct fw_unit *unit)
471{
472 struct scs *scs = dev_get_drvdata(&unit->device);
473
474 snd_card_disconnect(scs->card);
475
476 ACCESS_ONCE(scs->output) = NULL;
477 ACCESS_ONCE(scs->input) = NULL;
478
479 wait_event(scs->idle_wait, scs->output_idle);
480
481 tasklet_kill(&scs->tasklet);
482
483 snd_card_free_when_closed(scs->card);
484}
485
486static const struct ieee1394_device_id scs_id_table[] = {
487 {
488 .match_flags = IEEE1394_MATCH_VENDOR_ID |
489 IEEE1394_MATCH_MODEL_ID,
490 .vendor_id = OUI_STANTON,
491 .model_id = MODEL_SCS_1M,
492 },
493 {
494 .match_flags = IEEE1394_MATCH_VENDOR_ID |
495 IEEE1394_MATCH_MODEL_ID,
496 .vendor_id = OUI_STANTON,
497 .model_id = MODEL_SCS_1D,
498 },
499 {}
500};
501MODULE_DEVICE_TABLE(ieee1394, scs_id_table);
502
503MODULE_DESCRIPTION("SCS.1x MIDI driver");
504MODULE_AUTHOR("Clemens Ladisch <clemens@ladisch.de>");
505MODULE_LICENSE("GPL v2");
506
507static struct fw_driver scs_driver = {
508 .driver = {
509 .owner = THIS_MODULE,
510 .name = KBUILD_MODNAME,
511 .bus = &fw_bus_type,
512 },
513 .probe = scs_probe,
514 .update = scs_update,
515 .remove = scs_remove,
516 .id_table = scs_id_table,
517};
518
519static int __init alsa_scs1x_init(void)
520{
521 return driver_register(&scs_driver.driver);
522}
523
524static void __exit alsa_scs1x_exit(void)
525{
526 driver_unregister(&scs_driver.driver);
527}
528
529module_init(alsa_scs1x_init);
530module_exit(alsa_scs1x_exit);
diff --git a/sound/hda/ext/hdac_ext_controller.c b/sound/hda/ext/hdac_ext_controller.c
index 63215b17247c..548cc1e4114b 100644
--- a/sound/hda/ext/hdac_ext_controller.c
+++ b/sound/hda/ext/hdac_ext_controller.c
@@ -77,6 +77,12 @@ int snd_hdac_ext_bus_parse_capabilities(struct hdac_ext_bus *ebus)
77 ebus->spbcap = bus->remap_addr + offset; 77 ebus->spbcap = bus->remap_addr + offset;
78 break; 78 break;
79 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
80 default: 86 default:
81 dev_dbg(bus->dev, "Unknown capability %d\n", cur_cap); 87 dev_dbg(bus->dev, "Unknown capability %d\n", cur_cap);
82 break; 88 break;
@@ -240,7 +246,7 @@ static int check_hdac_link_power_active(struct hdac_ext_link *link, bool enable)
240 int mask = (1 << AZX_MLCTL_CPA); 246 int mask = (1 << AZX_MLCTL_CPA);
241 247
242 udelay(3); 248 udelay(3);
243 timeout = 50; 249 timeout = 150;
244 250
245 do { 251 do {
246 val = readl(link->ml_addr + AZX_REG_ML_LCTL); 252 val = readl(link->ml_addr + AZX_REG_ML_LCTL);
@@ -282,6 +288,27 @@ int snd_hdac_ext_bus_link_power_down(struct hdac_ext_link *link)
282EXPORT_SYMBOL_GPL(snd_hdac_ext_bus_link_power_down); 288EXPORT_SYMBOL_GPL(snd_hdac_ext_bus_link_power_down);
283 289
284/** 290/**
291 * snd_hdac_ext_bus_link_power_up_all -power up all hda link
292 * @ebus: HD-audio extended bus
293 */
294int snd_hdac_ext_bus_link_power_up_all(struct hdac_ext_bus *ebus)
295{
296 struct hdac_ext_link *hlink = NULL;
297 int ret;
298
299 list_for_each_entry(hlink, &ebus->hlink_list, list) {
300 snd_hdac_updatel(hlink->ml_addr,
301 AZX_REG_ML_LCTL, 0, AZX_MLCTL_SPA);
302 ret = check_hdac_link_power_active(hlink, true);
303 if (ret < 0)
304 return ret;
305 }
306
307 return 0;
308}
309EXPORT_SYMBOL_GPL(snd_hdac_ext_bus_link_power_up_all);
310
311/**
285 * snd_hdac_ext_bus_link_power_down_all -power down all hda link 312 * snd_hdac_ext_bus_link_power_down_all -power down all hda link
286 * @ebus: HD-audio extended bus 313 * @ebus: HD-audio extended bus
287 */ 314 */
diff --git a/sound/hda/ext/hdac_ext_stream.c b/sound/hda/ext/hdac_ext_stream.c
index cb89ec7c8147..023cc4cad5c1 100644
--- a/sound/hda/ext/hdac_ext_stream.c
+++ b/sound/hda/ext/hdac_ext_stream.c
@@ -59,6 +59,10 @@ void snd_hdac_ext_stream_init(struct hdac_ext_bus *ebus,
59 AZX_SPB_MAXFIFO; 59 AZX_SPB_MAXFIFO;
60 } 60 }
61 61
62 if (ebus->drsmcap)
63 stream->dpibr_addr = ebus->drsmcap + AZX_DRSM_BASE +
64 AZX_DRSM_INTERVAL * idx;
65
62 stream->decoupled = false; 66 stream->decoupled = false;
63 snd_hdac_stream_init(bus, &stream->hstream, idx, direction, tag); 67 snd_hdac_stream_init(bus, &stream->hstream, idx, direction, tag);
64} 68}
@@ -107,6 +111,7 @@ void snd_hdac_stream_free_all(struct hdac_ext_bus *ebus)
107 while (!list_empty(&bus->stream_list)) { 111 while (!list_empty(&bus->stream_list)) {
108 s = list_first_entry(&bus->stream_list, struct hdac_stream, list); 112 s = list_first_entry(&bus->stream_list, struct hdac_stream, list);
109 stream = stream_to_hdac_ext_stream(s); 113 stream = stream_to_hdac_ext_stream(s);
114 snd_hdac_ext_stream_decouple(ebus, stream, false);
110 list_del(&s->list); 115 list_del(&s->list);
111 kfree(stream); 116 kfree(stream);
112 } 117 }
@@ -497,3 +502,70 @@ void snd_hdac_ext_stop_streams(struct hdac_ext_bus *ebus)
497 } 502 }
498} 503}
499EXPORT_SYMBOL_GPL(snd_hdac_ext_stop_streams); 504EXPORT_SYMBOL_GPL(snd_hdac_ext_stop_streams);
505
506/**
507 * snd_hdac_ext_stream_drsm_enable - enable DMA resume for a stream
508 * @ebus: HD-audio ext core bus
509 * @enable: flag to enable/disable DRSM
510 * @index: stream index for which DRSM need to be enabled
511 */
512void snd_hdac_ext_stream_drsm_enable(struct hdac_ext_bus *ebus,
513 bool enable, int index)
514{
515 u32 mask = 0;
516 u32 register_mask = 0;
517 struct hdac_bus *bus = &ebus->bus;
518
519 if (!ebus->drsmcap) {
520 dev_err(bus->dev, "Address of DRSM capability is NULL");
521 return;
522 }
523
524 mask |= (1 << index);
525
526 register_mask = readl(ebus->drsmcap + AZX_REG_SPB_SPBFCCTL);
527
528 mask |= register_mask;
529
530 if (enable)
531 snd_hdac_updatel(ebus->drsmcap, AZX_REG_DRSM_CTL, 0, mask);
532 else
533 snd_hdac_updatel(ebus->drsmcap, AZX_REG_DRSM_CTL, mask, 0);
534}
535EXPORT_SYMBOL_GPL(snd_hdac_ext_stream_drsm_enable);
536
537/**
538 * snd_hdac_ext_stream_set_dpibr - sets the dpibr value of a stream
539 * @ebus: HD-audio ext core bus
540 * @stream: hdac_ext_stream
541 * @value: dpib value to set
542 */
543int snd_hdac_ext_stream_set_dpibr(struct hdac_ext_bus *ebus,
544 struct hdac_ext_stream *stream, u32 value)
545{
546 struct hdac_bus *bus = &ebus->bus;
547
548 if (!ebus->drsmcap) {
549 dev_err(bus->dev, "Address of DRSM capability is NULL");
550 return -EINVAL;
551 }
552
553 writel(value, stream->dpibr_addr);
554
555 return 0;
556}
557EXPORT_SYMBOL_GPL(snd_hdac_ext_stream_set_dpibr);
558
559/**
560 * snd_hdac_ext_stream_set_lpib - sets the lpib value of a stream
561 * @ebus: HD-audio ext core bus
562 * @stream: hdac_ext_stream
563 * @value: lpib value to set
564 */
565int snd_hdac_ext_stream_set_lpib(struct hdac_ext_stream *stream, u32 value)
566{
567 snd_hdac_stream_writel(&stream->hstream, SD_LPIB, value);
568
569 return 0;
570}
571EXPORT_SYMBOL_GPL(snd_hdac_ext_stream_set_lpib);
diff --git a/sound/hda/hdac_i915.c b/sound/hda/hdac_i915.c
index 8fef1b8d1fd8..c50177fb469f 100644
--- a/sound/hda/hdac_i915.c
+++ b/sound/hda/hdac_i915.c
@@ -118,6 +118,72 @@ int snd_hdac_get_display_clk(struct hdac_bus *bus)
118} 118}
119EXPORT_SYMBOL_GPL(snd_hdac_get_display_clk); 119EXPORT_SYMBOL_GPL(snd_hdac_get_display_clk);
120 120
121/* There is a fixed mapping between audio pin node and display port
122 * on current Intel platforms:
123 * Pin Widget 5 - PORT B (port = 1 in i915 driver)
124 * Pin Widget 6 - PORT C (port = 2 in i915 driver)
125 * Pin Widget 7 - PORT D (port = 3 in i915 driver)
126 */
127static int pin2port(hda_nid_t pin_nid)
128{
129 return pin_nid - 4;
130}
131
132/**
133 * snd_hdac_sync_audio_rate - Set N/CTS based on the sample rate
134 * @bus: HDA core bus
135 * @nid: the pin widget NID
136 * @rate: the sample rate to set
137 *
138 * This function is supposed to be used only by a HD-audio controller
139 * driver that needs the interaction with i915 graphics.
140 *
141 * This function sets N/CTS value based on the given sample rate.
142 * Returns zero for success, or a negative error code.
143 */
144int snd_hdac_sync_audio_rate(struct hdac_bus *bus, hda_nid_t nid, int rate)
145{
146 struct i915_audio_component *acomp = bus->audio_component;
147
148 if (!acomp || !acomp->ops || !acomp->ops->sync_audio_rate)
149 return -ENODEV;
150 return acomp->ops->sync_audio_rate(acomp->dev, pin2port(nid), rate);
151}
152EXPORT_SYMBOL_GPL(snd_hdac_sync_audio_rate);
153
154/**
155 * snd_hdac_acomp_get_eld - Get the audio state and ELD via component
156 * @bus: HDA core bus
157 * @nid: the pin widget NID
158 * @audio_enabled: the pointer to store the current audio state
159 * @buffer: the buffer pointer to store ELD bytes
160 * @max_bytes: the max bytes to be stored on @buffer
161 *
162 * This function is supposed to be used only by a HD-audio controller
163 * driver that needs the interaction with i915 graphics.
164 *
165 * This function queries the current state of the audio on the given
166 * digital port and fetches the ELD bytes onto the given buffer.
167 * It returns the number of bytes for the total ELD data, zero for
168 * invalid ELD, or a negative error code.
169 *
170 * The return size is the total bytes required for the whole ELD bytes,
171 * thus it may be over @max_bytes. If it's over @max_bytes, it implies
172 * that only a part of ELD bytes have been fetched.
173 */
174int snd_hdac_acomp_get_eld(struct hdac_bus *bus, hda_nid_t nid,
175 bool *audio_enabled, char *buffer, int max_bytes)
176{
177 struct i915_audio_component *acomp = bus->audio_component;
178
179 if (!acomp || !acomp->ops || !acomp->ops->get_eld)
180 return -ENODEV;
181
182 return acomp->ops->get_eld(acomp->dev, pin2port(nid), audio_enabled,
183 buffer, max_bytes);
184}
185EXPORT_SYMBOL_GPL(snd_hdac_acomp_get_eld);
186
121static int hdac_component_master_bind(struct device *dev) 187static int hdac_component_master_bind(struct device *dev)
122{ 188{
123 struct i915_audio_component *acomp = hdac_acomp; 189 struct i915_audio_component *acomp = hdac_acomp;
diff --git a/sound/i2c/i2c.c b/sound/i2c/i2c.c
index 4677037f0c8e..ef2a9afe9e19 100644
--- a/sound/i2c/i2c.c
+++ b/sound/i2c/i2c.c
@@ -39,7 +39,7 @@ static int snd_i2c_bit_readbytes(struct snd_i2c_device *device,
39static int snd_i2c_bit_probeaddr(struct snd_i2c_bus *bus, 39static int snd_i2c_bit_probeaddr(struct snd_i2c_bus *bus,
40 unsigned short addr); 40 unsigned short addr);
41 41
42static struct snd_i2c_ops snd_i2c_bit_ops = { 42static const struct snd_i2c_ops snd_i2c_bit_ops = {
43 .sendbytes = snd_i2c_bit_sendbytes, 43 .sendbytes = snd_i2c_bit_sendbytes,
44 .readbytes = snd_i2c_bit_readbytes, 44 .readbytes = snd_i2c_bit_readbytes,
45 .probeaddr = snd_i2c_bit_probeaddr, 45 .probeaddr = snd_i2c_bit_probeaddr,
diff --git a/sound/oss/Kconfig b/sound/oss/Kconfig
index 48568fdf847f..4033fe58f0cf 100644
--- a/sound/oss/Kconfig
+++ b/sound/oss/Kconfig
@@ -240,7 +240,7 @@ config MSND_FIFOSIZE
240 240
241menuconfig SOUND_OSS 241menuconfig SOUND_OSS
242 tristate "OSS sound modules" 242 tristate "OSS sound modules"
243 depends on ISA_DMA_API && VIRT_TO_BUS 243 depends on ISA_DMA_API && (VIRT_TO_BUS || ARCH_RPC || ARCH_NETWINDER)
244 depends on !GENERIC_ISA_DMA_SUPPORT_BROKEN 244 depends on !GENERIC_ISA_DMA_SUPPORT_BROKEN
245 help 245 help
246 OSS is the Open Sound System suite of sound card drivers. They make 246 OSS is the Open Sound System suite of sound card drivers. They make
diff --git a/sound/pci/atiixp.c b/sound/pci/atiixp.c
index 1028fc8bdff5..2ce0022dbc46 100644
--- a/sound/pci/atiixp.c
+++ b/sound/pci/atiixp.c
@@ -1219,7 +1219,7 @@ static struct ac97_pcm atiixp_pcm_defs[] = {
1219 }, 1219 },
1220}; 1220};
1221 1221
1222static struct atiixp_dma_ops snd_atiixp_playback_dma_ops = { 1222static const struct atiixp_dma_ops snd_atiixp_playback_dma_ops = {
1223 .type = ATI_DMA_PLAYBACK, 1223 .type = ATI_DMA_PLAYBACK,
1224 .llp_offset = ATI_REG_OUT_DMA_LINKPTR, 1224 .llp_offset = ATI_REG_OUT_DMA_LINKPTR,
1225 .dt_cur = ATI_REG_OUT_DMA_DT_CUR, 1225 .dt_cur = ATI_REG_OUT_DMA_DT_CUR,
@@ -1228,7 +1228,7 @@ static struct atiixp_dma_ops snd_atiixp_playback_dma_ops = {
1228 .flush_dma = atiixp_out_flush_dma, 1228 .flush_dma = atiixp_out_flush_dma,
1229}; 1229};
1230 1230
1231static struct atiixp_dma_ops snd_atiixp_capture_dma_ops = { 1231static const struct atiixp_dma_ops snd_atiixp_capture_dma_ops = {
1232 .type = ATI_DMA_CAPTURE, 1232 .type = ATI_DMA_CAPTURE,
1233 .llp_offset = ATI_REG_IN_DMA_LINKPTR, 1233 .llp_offset = ATI_REG_IN_DMA_LINKPTR,
1234 .dt_cur = ATI_REG_IN_DMA_DT_CUR, 1234 .dt_cur = ATI_REG_IN_DMA_DT_CUR,
@@ -1237,7 +1237,7 @@ static struct atiixp_dma_ops snd_atiixp_capture_dma_ops = {
1237 .flush_dma = atiixp_in_flush_dma, 1237 .flush_dma = atiixp_in_flush_dma,
1238}; 1238};
1239 1239
1240static struct atiixp_dma_ops snd_atiixp_spdif_dma_ops = { 1240static const struct atiixp_dma_ops snd_atiixp_spdif_dma_ops = {
1241 .type = ATI_DMA_SPDIF, 1241 .type = ATI_DMA_SPDIF,
1242 .llp_offset = ATI_REG_SPDF_DMA_LINKPTR, 1242 .llp_offset = ATI_REG_SPDF_DMA_LINKPTR,
1243 .dt_cur = ATI_REG_SPDF_DMA_DT_CUR, 1243 .dt_cur = ATI_REG_SPDF_DMA_DT_CUR,
diff --git a/sound/pci/atiixp_modem.c b/sound/pci/atiixp_modem.c
index 27ed678a46df..c534552963e7 100644
--- a/sound/pci/atiixp_modem.c
+++ b/sound/pci/atiixp_modem.c
@@ -970,7 +970,7 @@ static struct snd_pcm_ops snd_atiixp_capture_ops = {
970 .pointer = snd_atiixp_pcm_pointer, 970 .pointer = snd_atiixp_pcm_pointer,
971}; 971};
972 972
973static struct atiixp_dma_ops snd_atiixp_playback_dma_ops = { 973static const struct atiixp_dma_ops snd_atiixp_playback_dma_ops = {
974 .type = ATI_DMA_PLAYBACK, 974 .type = ATI_DMA_PLAYBACK,
975 .llp_offset = ATI_REG_MODEM_OUT_DMA1_LINKPTR, 975 .llp_offset = ATI_REG_MODEM_OUT_DMA1_LINKPTR,
976 .dt_cur = ATI_REG_MODEM_OUT_DMA1_DT_CUR, 976 .dt_cur = ATI_REG_MODEM_OUT_DMA1_DT_CUR,
@@ -979,7 +979,7 @@ static struct atiixp_dma_ops snd_atiixp_playback_dma_ops = {
979 .flush_dma = atiixp_out_flush_dma, 979 .flush_dma = atiixp_out_flush_dma,
980}; 980};
981 981
982static struct atiixp_dma_ops snd_atiixp_capture_dma_ops = { 982static const struct atiixp_dma_ops snd_atiixp_capture_dma_ops = {
983 .type = ATI_DMA_CAPTURE, 983 .type = ATI_DMA_CAPTURE,
984 .llp_offset = ATI_REG_MODEM_IN_DMA_LINKPTR, 984 .llp_offset = ATI_REG_MODEM_IN_DMA_LINKPTR,
985 .dt_cur = ATI_REG_MODEM_IN_DMA_DT_CUR, 985 .dt_cur = ATI_REG_MODEM_IN_DMA_DT_CUR,
diff --git a/sound/pci/azt3328.c b/sound/pci/azt3328.c
index 07a4acc99541..5e2ef0bb7057 100644
--- a/sound/pci/azt3328.c
+++ b/sound/pci/azt3328.c
@@ -2294,8 +2294,6 @@ snd_azf3328_free(struct snd_azf3328 *chip)
2294 snd_azf3328_timer_stop(chip->timer); 2294 snd_azf3328_timer_stop(chip->timer);
2295 snd_azf3328_gameport_free(chip); 2295 snd_azf3328_gameport_free(chip);
2296 2296
2297 if (chip->irq >= 0)
2298 synchronize_irq(chip->irq);
2299__end_hw: 2297__end_hw:
2300 if (chip->irq >= 0) 2298 if (chip->irq >= 0)
2301 free_irq(chip->irq, chip); 2299 free_irq(chip->irq, chip);
diff --git a/sound/pci/cs5535audio/cs5535audio_pcm.c b/sound/pci/cs5535audio/cs5535audio_pcm.c
index 9c2dc911d8d7..27fa57da8dc4 100644
--- a/sound/pci/cs5535audio/cs5535audio_pcm.c
+++ b/sound/pci/cs5535audio/cs5535audio_pcm.c
@@ -402,7 +402,7 @@ static struct snd_pcm_ops snd_cs5535audio_capture_ops = {
402 .pointer = snd_cs5535audio_pcm_pointer, 402 .pointer = snd_cs5535audio_pcm_pointer,
403}; 403};
404 404
405static struct cs5535audio_dma_ops snd_cs5535audio_playback_dma_ops = { 405static const struct cs5535audio_dma_ops snd_cs5535audio_playback_dma_ops = {
406 .type = CS5535AUDIO_DMA_PLAYBACK, 406 .type = CS5535AUDIO_DMA_PLAYBACK,
407 .enable_dma = cs5535audio_playback_enable_dma, 407 .enable_dma = cs5535audio_playback_enable_dma,
408 .disable_dma = cs5535audio_playback_disable_dma, 408 .disable_dma = cs5535audio_playback_disable_dma,
@@ -412,7 +412,7 @@ static struct cs5535audio_dma_ops snd_cs5535audio_playback_dma_ops = {
412 .read_dma_pntr = cs5535audio_playback_read_dma_pntr, 412 .read_dma_pntr = cs5535audio_playback_read_dma_pntr,
413}; 413};
414 414
415static struct cs5535audio_dma_ops snd_cs5535audio_capture_dma_ops = { 415static const struct cs5535audio_dma_ops snd_cs5535audio_capture_dma_ops = {
416 .type = CS5535AUDIO_DMA_CAPTURE, 416 .type = CS5535AUDIO_DMA_CAPTURE,
417 .enable_dma = cs5535audio_capture_enable_dma, 417 .enable_dma = cs5535audio_capture_enable_dma,
418 .disable_dma = cs5535audio_capture_disable_dma, 418 .disable_dma = cs5535audio_capture_disable_dma,
diff --git a/sound/pci/fm801.c b/sound/pci/fm801.c
index 759295aa8366..bade9b907b92 100644
--- a/sound/pci/fm801.c
+++ b/sound/pci/fm801.c
@@ -163,6 +163,7 @@ MODULE_PARM_DESC(radio_nr, "Radio device numbers");
163 * @cap_ctrl: capture control 163 * @cap_ctrl: capture control
164 */ 164 */
165struct fm801 { 165struct fm801 {
166 struct device *dev;
166 int irq; 167 int irq;
167 168
168 unsigned long port; 169 unsigned long port;
@@ -190,7 +191,6 @@ struct fm801 {
190 struct snd_ac97 *ac97; 191 struct snd_ac97 *ac97;
191 struct snd_ac97 *ac97_sec; 192 struct snd_ac97 *ac97_sec;
192 193
193 struct pci_dev *pci;
194 struct snd_card *card; 194 struct snd_card *card;
195 struct snd_pcm *pcm; 195 struct snd_pcm *pcm;
196 struct snd_rawmidi *rmidi; 196 struct snd_rawmidi *rmidi;
@@ -212,6 +212,20 @@ struct fm801 {
212#endif 212#endif
213}; 213};
214 214
215/*
216 * IO accessors
217 */
218
219static inline void fm801_iowrite16(struct fm801 *chip, unsigned short offset, u16 value)
220{
221 outw(value, chip->port + offset);
222}
223
224static inline u16 fm801_ioread16(struct fm801 *chip, unsigned short offset)
225{
226 return inw(chip->port + offset);
227}
228
215static const struct pci_device_id snd_fm801_ids[] = { 229static const struct pci_device_id snd_fm801_ids[] = {
216 { 0x1319, 0x0801, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_MULTIMEDIA_AUDIO << 8, 0xffff00, 0, }, /* FM801 */ 230 { 0x1319, 0x0801, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_MULTIMEDIA_AUDIO << 8, 0xffff00, 0, }, /* FM801 */
217 { 0x5213, 0x0510, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_MULTIMEDIA_AUDIO << 8, 0xffff00, 0, }, /* Gallant Odyssey Sound 4 */ 231 { 0x5213, 0x0510, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_MULTIMEDIA_AUDIO << 8, 0xffff00, 0, }, /* Gallant Odyssey Sound 4 */
@@ -256,11 +270,11 @@ static int snd_fm801_update_bits(struct fm801 *chip, unsigned short reg,
256 unsigned short old, new; 270 unsigned short old, new;
257 271
258 spin_lock_irqsave(&chip->reg_lock, flags); 272 spin_lock_irqsave(&chip->reg_lock, flags);
259 old = inw(chip->port + reg); 273 old = fm801_ioread16(chip, reg);
260 new = (old & ~mask) | value; 274 new = (old & ~mask) | value;
261 change = old != new; 275 change = old != new;
262 if (change) 276 if (change)
263 outw(new, chip->port + reg); 277 fm801_iowrite16(chip, reg, new);
264 spin_unlock_irqrestore(&chip->reg_lock, flags); 278 spin_unlock_irqrestore(&chip->reg_lock, flags);
265 return change; 279 return change;
266} 280}
@@ -578,8 +592,9 @@ static irqreturn_t snd_fm801_interrupt(int irq, void *dev_id)
578 } 592 }
579 if (chip->rmidi && (status & FM801_IRQ_MPU)) 593 if (chip->rmidi && (status & FM801_IRQ_MPU))
580 snd_mpu401_uart_interrupt(irq, chip->rmidi->private_data); 594 snd_mpu401_uart_interrupt(irq, chip->rmidi->private_data);
581 if (status & FM801_IRQ_VOLUME) 595 if (status & FM801_IRQ_VOLUME) {
582 ;/* TODO */ 596 /* TODO */
597 }
583 598
584 return IRQ_HANDLED; 599 return IRQ_HANDLED;
585} 600}
@@ -700,6 +715,7 @@ static struct snd_pcm_ops snd_fm801_capture_ops = {
700 715
701static int snd_fm801_pcm(struct fm801 *chip, int device) 716static int snd_fm801_pcm(struct fm801 *chip, int device)
702{ 717{
718 struct pci_dev *pdev = to_pci_dev(chip->dev);
703 struct snd_pcm *pcm; 719 struct snd_pcm *pcm;
704 int err; 720 int err;
705 721
@@ -715,7 +731,7 @@ static int snd_fm801_pcm(struct fm801 *chip, int device)
715 chip->pcm = pcm; 731 chip->pcm = pcm;
716 732
717 snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV, 733 snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
718 snd_dma_pci_data(chip->pci), 734 snd_dma_pci_data(pdev),
719 chip->multichannel ? 128*1024 : 64*1024, 128*1024); 735 chip->multichannel ? 128*1024 : 64*1024, 128*1024);
720 736
721 return snd_pcm_add_chmap_ctls(pcm, SNDRV_PCM_STREAM_PLAYBACK, 737 return snd_pcm_add_chmap_ctls(pcm, SNDRV_PCM_STREAM_PLAYBACK,
@@ -851,10 +867,11 @@ static int snd_fm801_get_single(struct snd_kcontrol *kcontrol,
851 int shift = (kcontrol->private_value >> 8) & 0xff; 867 int shift = (kcontrol->private_value >> 8) & 0xff;
852 int mask = (kcontrol->private_value >> 16) & 0xff; 868 int mask = (kcontrol->private_value >> 16) & 0xff;
853 int invert = (kcontrol->private_value >> 24) & 0xff; 869 int invert = (kcontrol->private_value >> 24) & 0xff;
870 long *value = ucontrol->value.integer.value;
854 871
855 ucontrol->value.integer.value[0] = (inw(chip->port + reg) >> shift) & mask; 872 value[0] = (fm801_ioread16(chip, reg) >> shift) & mask;
856 if (invert) 873 if (invert)
857 ucontrol->value.integer.value[0] = mask - ucontrol->value.integer.value[0]; 874 value[0] = mask - value[0];
858 return 0; 875 return 0;
859} 876}
860 877
@@ -907,14 +924,15 @@ static int snd_fm801_get_double(struct snd_kcontrol *kcontrol,
907 int shift_right = (kcontrol->private_value >> 12) & 0x0f; 924 int shift_right = (kcontrol->private_value >> 12) & 0x0f;
908 int mask = (kcontrol->private_value >> 16) & 0xff; 925 int mask = (kcontrol->private_value >> 16) & 0xff;
909 int invert = (kcontrol->private_value >> 24) & 0xff; 926 int invert = (kcontrol->private_value >> 24) & 0xff;
927 long *value = ucontrol->value.integer.value;
910 928
911 spin_lock_irq(&chip->reg_lock); 929 spin_lock_irq(&chip->reg_lock);
912 ucontrol->value.integer.value[0] = (inw(chip->port + reg) >> shift_left) & mask; 930 value[0] = (fm801_ioread16(chip, reg) >> shift_left) & mask;
913 ucontrol->value.integer.value[1] = (inw(chip->port + reg) >> shift_right) & mask; 931 value[1] = (fm801_ioread16(chip, reg) >> shift_right) & mask;
914 spin_unlock_irq(&chip->reg_lock); 932 spin_unlock_irq(&chip->reg_lock);
915 if (invert) { 933 if (invert) {
916 ucontrol->value.integer.value[0] = mask - ucontrol->value.integer.value[0]; 934 value[0] = mask - value[0];
917 ucontrol->value.integer.value[1] = mask - ucontrol->value.integer.value[1]; 935 value[1] = mask - value[1];
918 } 936 }
919 return 0; 937 return 0;
920} 938}
@@ -1080,26 +1098,20 @@ static int wait_for_codec(struct fm801 *chip, unsigned int codec_id,
1080 return -EIO; 1098 return -EIO;
1081} 1099}
1082 1100
1083static int snd_fm801_chip_init(struct fm801 *chip, int resume) 1101static int reset_codec(struct fm801 *chip)
1084{ 1102{
1085 unsigned short cmdw;
1086
1087 if (chip->tea575x_tuner & TUNER_ONLY)
1088 goto __ac97_ok;
1089
1090 /* codec cold reset + AC'97 warm reset */ 1103 /* codec cold reset + AC'97 warm reset */
1091 fm801_writew(chip, CODEC_CTRL, (1 << 5) | (1 << 6)); 1104 fm801_writew(chip, CODEC_CTRL, (1 << 5) | (1 << 6));
1092 fm801_readw(chip, CODEC_CTRL); /* flush posting data */ 1105 fm801_readw(chip, CODEC_CTRL); /* flush posting data */
1093 udelay(100); 1106 udelay(100);
1094 fm801_writew(chip, CODEC_CTRL, 0); 1107 fm801_writew(chip, CODEC_CTRL, 0);
1095 1108
1096 if (wait_for_codec(chip, 0, AC97_RESET, msecs_to_jiffies(750)) < 0) 1109 return wait_for_codec(chip, 0, AC97_RESET, msecs_to_jiffies(750));
1097 if (!resume) { 1110}
1098 dev_info(chip->card->dev, 1111
1099 "Primary AC'97 codec not found, assume SF64-PCR (tuner-only)\n"); 1112static void snd_fm801_chip_multichannel_init(struct fm801 *chip)
1100 chip->tea575x_tuner = 3 | TUNER_ONLY; 1113{
1101 goto __ac97_ok; 1114 unsigned short cmdw;
1102 }
1103 1115
1104 if (chip->multichannel) { 1116 if (chip->multichannel) {
1105 if (chip->secondary_addr) { 1117 if (chip->secondary_addr) {
@@ -1126,8 +1138,11 @@ static int snd_fm801_chip_init(struct fm801 *chip, int resume)
1126 /* cause timeout problems */ 1138 /* cause timeout problems */
1127 wait_for_codec(chip, 0, AC97_VENDOR_ID1, msecs_to_jiffies(750)); 1139 wait_for_codec(chip, 0, AC97_VENDOR_ID1, msecs_to_jiffies(750));
1128 } 1140 }
1141}
1129 1142
1130 __ac97_ok: 1143static void snd_fm801_chip_init(struct fm801 *chip)
1144{
1145 unsigned short cmdw;
1131 1146
1132 /* init volume */ 1147 /* init volume */
1133 fm801_writew(chip, PCM_VOL, 0x0808); 1148 fm801_writew(chip, PCM_VOL, 0x0808);
@@ -1148,11 +1163,8 @@ static int snd_fm801_chip_init(struct fm801 *chip, int resume)
1148 /* interrupt clear */ 1163 /* interrupt clear */
1149 fm801_writew(chip, IRQ_STATUS, 1164 fm801_writew(chip, IRQ_STATUS,
1150 FM801_IRQ_PLAYBACK | FM801_IRQ_CAPTURE | FM801_IRQ_MPU); 1165 FM801_IRQ_PLAYBACK | FM801_IRQ_CAPTURE | FM801_IRQ_MPU);
1151
1152 return 0;
1153} 1166}
1154 1167
1155
1156static int snd_fm801_free(struct fm801 *chip) 1168static int snd_fm801_free(struct fm801 *chip)
1157{ 1169{
1158 unsigned short cmdw; 1170 unsigned short cmdw;
@@ -1165,6 +1177,8 @@ static int snd_fm801_free(struct fm801 *chip)
1165 cmdw |= 0x00c3; 1177 cmdw |= 0x00c3;
1166 fm801_writew(chip, IRQ_MASK, cmdw); 1178 fm801_writew(chip, IRQ_MASK, cmdw);
1167 1179
1180 devm_free_irq(chip->dev, chip->irq, chip);
1181
1168 __end_hw: 1182 __end_hw:
1169#ifdef CONFIG_SND_FM801_TEA575X_BOOL 1183#ifdef CONFIG_SND_FM801_TEA575X_BOOL
1170 if (!(chip->tea575x_tuner & TUNER_DISABLED)) { 1184 if (!(chip->tea575x_tuner & TUNER_DISABLED)) {
@@ -1201,13 +1215,29 @@ static int snd_fm801_create(struct snd_card *card,
1201 return -ENOMEM; 1215 return -ENOMEM;
1202 spin_lock_init(&chip->reg_lock); 1216 spin_lock_init(&chip->reg_lock);
1203 chip->card = card; 1217 chip->card = card;
1204 chip->pci = pci; 1218 chip->dev = &pci->dev;
1205 chip->irq = -1; 1219 chip->irq = -1;
1206 chip->tea575x_tuner = tea575x_tuner; 1220 chip->tea575x_tuner = tea575x_tuner;
1207 if ((err = pci_request_regions(pci, "FM801")) < 0) 1221 if ((err = pci_request_regions(pci, "FM801")) < 0)
1208 return err; 1222 return err;
1209 chip->port = pci_resource_start(pci, 0); 1223 chip->port = pci_resource_start(pci, 0);
1210 if ((tea575x_tuner & TUNER_ONLY) == 0) { 1224
1225 if (pci->revision >= 0xb1) /* FM801-AU */
1226 chip->multichannel = 1;
1227
1228 if (!(chip->tea575x_tuner & TUNER_ONLY)) {
1229 if (reset_codec(chip) < 0) {
1230 dev_info(chip->card->dev,
1231 "Primary AC'97 codec not found, assume SF64-PCR (tuner-only)\n");
1232 chip->tea575x_tuner = 3 | TUNER_ONLY;
1233 } else {
1234 snd_fm801_chip_multichannel_init(chip);
1235 }
1236 }
1237
1238 snd_fm801_chip_init(chip);
1239
1240 if ((chip->tea575x_tuner & TUNER_ONLY) == 0) {
1211 if (devm_request_irq(&pci->dev, pci->irq, snd_fm801_interrupt, 1241 if (devm_request_irq(&pci->dev, pci->irq, snd_fm801_interrupt,
1212 IRQF_SHARED, KBUILD_MODNAME, chip)) { 1242 IRQF_SHARED, KBUILD_MODNAME, chip)) {
1213 dev_err(card->dev, "unable to grab IRQ %d\n", pci->irq); 1243 dev_err(card->dev, "unable to grab IRQ %d\n", pci->irq);
@@ -1218,13 +1248,6 @@ static int snd_fm801_create(struct snd_card *card,
1218 pci_set_master(pci); 1248 pci_set_master(pci);
1219 } 1249 }
1220 1250
1221 if (pci->revision >= 0xb1) /* FM801-AU */
1222 chip->multichannel = 1;
1223
1224 snd_fm801_chip_init(chip, 0);
1225 /* init might set tuner access method */
1226 tea575x_tuner = chip->tea575x_tuner;
1227
1228 if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) < 0) { 1251 if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) < 0) {
1229 snd_fm801_free(chip); 1252 snd_fm801_free(chip);
1230 return err; 1253 return err;
@@ -1241,14 +1264,16 @@ static int snd_fm801_create(struct snd_card *card,
1241 chip->tea.private_data = chip; 1264 chip->tea.private_data = chip;
1242 chip->tea.ops = &snd_fm801_tea_ops; 1265 chip->tea.ops = &snd_fm801_tea_ops;
1243 sprintf(chip->tea.bus_info, "PCI:%s", pci_name(pci)); 1266 sprintf(chip->tea.bus_info, "PCI:%s", pci_name(pci));
1244 if ((tea575x_tuner & TUNER_TYPE_MASK) > 0 && 1267 if ((chip->tea575x_tuner & TUNER_TYPE_MASK) > 0 &&
1245 (tea575x_tuner & TUNER_TYPE_MASK) < 4) { 1268 (chip->tea575x_tuner & TUNER_TYPE_MASK) < 4) {
1246 if (snd_tea575x_init(&chip->tea, THIS_MODULE)) { 1269 if (snd_tea575x_init(&chip->tea, THIS_MODULE)) {
1247 dev_err(card->dev, "TEA575x radio not found\n"); 1270 dev_err(card->dev, "TEA575x radio not found\n");
1248 snd_fm801_free(chip); 1271 snd_fm801_free(chip);
1249 return -ENODEV; 1272 return -ENODEV;
1250 } 1273 }
1251 } else if ((tea575x_tuner & TUNER_TYPE_MASK) == 0) { 1274 } else if ((chip->tea575x_tuner & TUNER_TYPE_MASK) == 0) {
1275 unsigned int tuner_only = chip->tea575x_tuner & TUNER_ONLY;
1276
1252 /* autodetect tuner connection */ 1277 /* autodetect tuner connection */
1253 for (tea575x_tuner = 1; tea575x_tuner <= 3; tea575x_tuner++) { 1278 for (tea575x_tuner = 1; tea575x_tuner <= 3; tea575x_tuner++) {
1254 chip->tea575x_tuner = tea575x_tuner; 1279 chip->tea575x_tuner = tea575x_tuner;
@@ -1263,6 +1288,8 @@ static int snd_fm801_create(struct snd_card *card,
1263 dev_err(card->dev, "TEA575x radio not found\n"); 1288 dev_err(card->dev, "TEA575x radio not found\n");
1264 chip->tea575x_tuner = TUNER_DISABLED; 1289 chip->tea575x_tuner = TUNER_DISABLED;
1265 } 1290 }
1291
1292 chip->tea575x_tuner |= tuner_only;
1266 } 1293 }
1267 if (!(chip->tea575x_tuner & TUNER_DISABLED)) { 1294 if (!(chip->tea575x_tuner & TUNER_DISABLED)) {
1268 strlcpy(chip->tea.card, get_tea575x_gpio(chip)->name, 1295 strlcpy(chip->tea.card, get_tea575x_gpio(chip)->name,
@@ -1366,12 +1393,18 @@ static int snd_fm801_suspend(struct device *dev)
1366 int i; 1393 int i;
1367 1394
1368 snd_power_change_state(card, SNDRV_CTL_POWER_D3hot); 1395 snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
1369 snd_pcm_suspend_all(chip->pcm); 1396
1370 snd_ac97_suspend(chip->ac97);
1371 snd_ac97_suspend(chip->ac97_sec);
1372 for (i = 0; i < ARRAY_SIZE(saved_regs); i++) 1397 for (i = 0; i < ARRAY_SIZE(saved_regs); i++)
1373 chip->saved_regs[i] = inw(chip->port + saved_regs[i]); 1398 chip->saved_regs[i] = fm801_ioread16(chip, saved_regs[i]);
1374 /* FIXME: tea575x suspend */ 1399
1400 if (chip->tea575x_tuner & TUNER_ONLY) {
1401 /* FIXME: tea575x suspend */
1402 } else {
1403 snd_pcm_suspend_all(chip->pcm);
1404 snd_ac97_suspend(chip->ac97);
1405 snd_ac97_suspend(chip->ac97_sec);
1406 }
1407
1375 return 0; 1408 return 0;
1376} 1409}
1377 1410
@@ -1381,11 +1414,23 @@ static int snd_fm801_resume(struct device *dev)
1381 struct fm801 *chip = card->private_data; 1414 struct fm801 *chip = card->private_data;
1382 int i; 1415 int i;
1383 1416
1384 snd_fm801_chip_init(chip, 1); 1417 if (chip->tea575x_tuner & TUNER_ONLY) {
1385 snd_ac97_resume(chip->ac97); 1418 snd_fm801_chip_init(chip);
1386 snd_ac97_resume(chip->ac97_sec); 1419 } else {
1420 reset_codec(chip);
1421 snd_fm801_chip_multichannel_init(chip);
1422 snd_fm801_chip_init(chip);
1423 snd_ac97_resume(chip->ac97);
1424 snd_ac97_resume(chip->ac97_sec);
1425 }
1426
1387 for (i = 0; i < ARRAY_SIZE(saved_regs); i++) 1427 for (i = 0; i < ARRAY_SIZE(saved_regs); i++)
1388 outw(chip->saved_regs[i], chip->port + saved_regs[i]); 1428 fm801_iowrite16(chip, saved_regs[i], chip->saved_regs[i]);
1429
1430#ifdef CONFIG_SND_FM801_TEA575X_BOOL
1431 if (!(chip->tea575x_tuner & TUNER_DISABLED))
1432 snd_tea575x_set_freq(&chip->tea);
1433#endif
1389 1434
1390 snd_power_change_state(card, SNDRV_CTL_POWER_D0); 1435 snd_power_change_state(card, SNDRV_CTL_POWER_D0);
1391 return 0; 1436 return 0;
diff --git a/sound/pci/hda/hda_controller.c b/sound/pci/hda/hda_controller.c
index 22dbfa563919..37cf9cee9835 100644
--- a/sound/pci/hda/hda_controller.c
+++ b/sound/pci/hda/hda_controller.c
@@ -956,7 +956,7 @@ irqreturn_t azx_interrupt(int irq, void *dev_id)
956 status = azx_readb(chip, RIRBSTS); 956 status = azx_readb(chip, RIRBSTS);
957 if (status & RIRB_INT_MASK) { 957 if (status & RIRB_INT_MASK) {
958 if (status & RIRB_INT_RESPONSE) { 958 if (status & RIRB_INT_RESPONSE) {
959 if (chip->driver_caps & AZX_DCAPS_RIRB_PRE_DELAY) 959 if (chip->driver_caps & AZX_DCAPS_CTX_WORKAROUND)
960 udelay(80); 960 udelay(80);
961 snd_hdac_bus_update_rirb(bus); 961 snd_hdac_bus_update_rirb(bus);
962 } 962 }
@@ -1050,16 +1050,10 @@ int azx_bus_init(struct azx *chip, const char *model,
1050 if (chip->get_position[0] != azx_get_pos_lpib || 1050 if (chip->get_position[0] != azx_get_pos_lpib ||
1051 chip->get_position[1] != azx_get_pos_lpib) 1051 chip->get_position[1] != azx_get_pos_lpib)
1052 bus->core.use_posbuf = true; 1052 bus->core.use_posbuf = true;
1053 if (chip->bdl_pos_adj) 1053 bus->core.bdl_pos_adj = chip->bdl_pos_adj;
1054 bus->core.bdl_pos_adj = chip->bdl_pos_adj[chip->dev_index];
1055 if (chip->driver_caps & AZX_DCAPS_CORBRP_SELF_CLEAR) 1054 if (chip->driver_caps & AZX_DCAPS_CORBRP_SELF_CLEAR)
1056 bus->core.corbrp_self_clear = true; 1055 bus->core.corbrp_self_clear = true;
1057 1056
1058 if (chip->driver_caps & AZX_DCAPS_RIRB_DELAY) {
1059 dev_dbg(chip->card->dev, "Enable delay in RIRB handling\n");
1060 bus->needs_damn_long_delay = 1;
1061 }
1062
1063 if (chip->driver_caps & AZX_DCAPS_4K_BDLE_BOUNDARY) 1057 if (chip->driver_caps & AZX_DCAPS_4K_BDLE_BOUNDARY)
1064 bus->core.align_bdle_4k = true; 1058 bus->core.align_bdle_4k = true;
1065 1059
diff --git a/sound/pci/hda/hda_controller.h b/sound/pci/hda/hda_controller.h
index 7b635d68cfe1..ec63bbf1ec6d 100644
--- a/sound/pci/hda/hda_controller.h
+++ b/sound/pci/hda/hda_controller.h
@@ -32,21 +32,25 @@
32#define AZX_DCAPS_NO_MSI (1 << 9) /* No MSI support */ 32#define AZX_DCAPS_NO_MSI (1 << 9) /* No MSI support */
33#define AZX_DCAPS_SNOOP_MASK (3 << 10) /* snoop type mask */ 33#define AZX_DCAPS_SNOOP_MASK (3 << 10) /* snoop type mask */
34#define AZX_DCAPS_SNOOP_OFF (1 << 12) /* snoop default off */ 34#define AZX_DCAPS_SNOOP_OFF (1 << 12) /* snoop default off */
35#define AZX_DCAPS_RIRB_DELAY (1 << 13) /* Long delay in read loop */ 35/* 13 unused */
36#define AZX_DCAPS_RIRB_PRE_DELAY (1 << 14) /* Put a delay before read */ 36/* 14 unused */
37#define AZX_DCAPS_CTX_WORKAROUND (1 << 15) /* X-Fi workaround */ 37#define AZX_DCAPS_CTX_WORKAROUND (1 << 15) /* X-Fi workaround */
38#define AZX_DCAPS_POSFIX_LPIB (1 << 16) /* Use LPIB as default */ 38#define AZX_DCAPS_POSFIX_LPIB (1 << 16) /* Use LPIB as default */
39#define AZX_DCAPS_POSFIX_VIA (1 << 17) /* Use VIACOMBO as default */ 39/* 17 unused */
40#define AZX_DCAPS_NO_64BIT (1 << 18) /* No 64bit address */ 40#define AZX_DCAPS_NO_64BIT (1 << 18) /* No 64bit address */
41#define AZX_DCAPS_SYNC_WRITE (1 << 19) /* sync each cmd write */ 41#define AZX_DCAPS_SYNC_WRITE (1 << 19) /* sync each cmd write */
42#define AZX_DCAPS_OLD_SSYNC (1 << 20) /* Old SSYNC reg for ICH */ 42#define AZX_DCAPS_OLD_SSYNC (1 << 20) /* Old SSYNC reg for ICH */
43#define AZX_DCAPS_NO_ALIGN_BUFSIZE (1 << 21) /* no buffer size alignment */ 43#define AZX_DCAPS_NO_ALIGN_BUFSIZE (1 << 21) /* no buffer size alignment */
44/* 22 unused */ 44/* 22 unused */
45#define AZX_DCAPS_4K_BDLE_BOUNDARY (1 << 23) /* BDLE in 4k boundary */ 45#define AZX_DCAPS_4K_BDLE_BOUNDARY (1 << 23) /* BDLE in 4k boundary */
46#define AZX_DCAPS_REVERSE_ASSIGN (1 << 24) /* Assign devices in reverse order */ 46/* 24 unused */
47#define AZX_DCAPS_COUNT_LPIB_DELAY (1 << 25) /* Take LPIB as delay */ 47#define AZX_DCAPS_COUNT_LPIB_DELAY (1 << 25) /* Take LPIB as delay */
48#define AZX_DCAPS_PM_RUNTIME (1 << 26) /* runtime PM support */ 48#define AZX_DCAPS_PM_RUNTIME (1 << 26) /* runtime PM support */
49#ifdef CONFIG_SND_HDA_I915
49#define AZX_DCAPS_I915_POWERWELL (1 << 27) /* HSW i915 powerwell support */ 50#define AZX_DCAPS_I915_POWERWELL (1 << 27) /* HSW i915 powerwell support */
51#else
52#define AZX_DCAPS_I915_POWERWELL 0 /* NOP */
53#endif
50#define AZX_DCAPS_CORBRP_SELF_CLEAR (1 << 28) /* CORBRP clears itself after reset */ 54#define AZX_DCAPS_CORBRP_SELF_CLEAR (1 << 28) /* CORBRP clears itself after reset */
51#define AZX_DCAPS_NO_MSI64 (1 << 29) /* Stick to 32-bit MSIs */ 55#define AZX_DCAPS_NO_MSI64 (1 << 29) /* Stick to 32-bit MSIs */
52#define AZX_DCAPS_SEPARATE_STREAM_TAG (1 << 30) /* capture and playback use separate stream tag */ 56#define AZX_DCAPS_SEPARATE_STREAM_TAG (1 << 30) /* capture and playback use separate stream tag */
@@ -143,7 +147,7 @@ struct azx {
143#endif 147#endif
144 148
145 /* flags */ 149 /* flags */
146 const int *bdl_pos_adj; 150 int bdl_pos_adj;
147 int poll_count; 151 int poll_count;
148 unsigned int running:1; 152 unsigned int running:1;
149 unsigned int single_cmd:1; 153 unsigned int single_cmd:1;
diff --git a/sound/pci/hda/hda_eld.c b/sound/pci/hda/hda_eld.c
index 563984dd2562..bc2e08257c2e 100644
--- a/sound/pci/hda/hda_eld.c
+++ b/sound/pci/hda/hda_eld.c
@@ -253,6 +253,7 @@ int snd_hdmi_parse_eld(struct hda_codec *codec, struct parsed_hdmi_eld *e,
253 int mnl; 253 int mnl;
254 int i; 254 int i;
255 255
256 memset(e, 0, sizeof(*e));
256 e->eld_ver = GRAB_BITS(buf, 0, 3, 5); 257 e->eld_ver = GRAB_BITS(buf, 0, 3, 5);
257 if (e->eld_ver != ELD_VER_CEA_861D && 258 if (e->eld_ver != ELD_VER_CEA_861D &&
258 e->eld_ver != ELD_VER_PARTIAL) { 259 e->eld_ver != ELD_VER_PARTIAL) {
diff --git a/sound/pci/hda/hda_generic.c b/sound/pci/hda/hda_generic.c
index c6e8a651cea1..30c8efe0f80a 100644
--- a/sound/pci/hda/hda_generic.c
+++ b/sound/pci/hda/hda_generic.c
@@ -279,22 +279,6 @@ static struct nid_path *get_nid_path(struct hda_codec *codec,
279} 279}
280 280
281/** 281/**
282 * snd_hda_get_nid_path - get the path between the given NIDs
283 * @codec: the HDA codec
284 * @from_nid: the NID where the path start from
285 * @to_nid: the NID where the path ends at
286 *
287 * Return the found nid_path object or NULL for error.
288 * Passing 0 to either @from_nid or @to_nid behaves as a wildcard.
289 */
290struct nid_path *snd_hda_get_nid_path(struct hda_codec *codec,
291 hda_nid_t from_nid, hda_nid_t to_nid)
292{
293 return get_nid_path(codec, from_nid, to_nid, 0);
294}
295EXPORT_SYMBOL_GPL(snd_hda_get_nid_path);
296
297/**
298 * snd_hda_get_path_idx - get the index number corresponding to the path 282 * snd_hda_get_path_idx - get the index number corresponding to the path
299 * instance 283 * instance
300 * @codec: the HDA codec 284 * @codec: the HDA codec
@@ -451,7 +435,7 @@ static bool __parse_nid_path(struct hda_codec *codec,
451 return true; 435 return true;
452} 436}
453 437
454/** 438/*
455 * snd_hda_parse_nid_path - parse the widget path from the given nid to 439 * snd_hda_parse_nid_path - parse the widget path from the given nid to
456 * the target nid 440 * the target nid
457 * @codec: the HDA codec 441 * @codec: the HDA codec
@@ -470,7 +454,7 @@ static bool __parse_nid_path(struct hda_codec *codec,
470 * with the negative of given value are excluded, only other paths are chosen. 454 * with the negative of given value are excluded, only other paths are chosen.
471 * when @anchor_nid is zero, no special handling about path selection. 455 * when @anchor_nid is zero, no special handling about path selection.
472 */ 456 */
473bool snd_hda_parse_nid_path(struct hda_codec *codec, hda_nid_t from_nid, 457static bool snd_hda_parse_nid_path(struct hda_codec *codec, hda_nid_t from_nid,
474 hda_nid_t to_nid, int anchor_nid, 458 hda_nid_t to_nid, int anchor_nid,
475 struct nid_path *path) 459 struct nid_path *path)
476{ 460{
@@ -481,7 +465,6 @@ bool snd_hda_parse_nid_path(struct hda_codec *codec, hda_nid_t from_nid,
481 } 465 }
482 return false; 466 return false;
483} 467}
484EXPORT_SYMBOL_GPL(snd_hda_parse_nid_path);
485 468
486/** 469/**
487 * snd_hda_add_new_path - parse the path between the given NIDs and 470 * snd_hda_add_new_path - parse the path between the given NIDs and
@@ -771,9 +754,6 @@ static void activate_amp(struct hda_codec *codec, hda_nid_t nid, int dir,
771 unsigned int caps; 754 unsigned int caps;
772 unsigned int mask, val; 755 unsigned int mask, val;
773 756
774 if (!enable && is_active_nid(codec, nid, dir, idx_to_check))
775 return;
776
777 caps = query_amp_caps(codec, nid, dir); 757 caps = query_amp_caps(codec, nid, dir);
778 val = get_amp_val_to_activate(codec, nid, dir, caps, enable); 758 val = get_amp_val_to_activate(codec, nid, dir, caps, enable);
779 mask = get_amp_mask_to_modify(codec, nid, dir, idx_to_check, caps); 759 mask = get_amp_mask_to_modify(codec, nid, dir, idx_to_check, caps);
@@ -784,12 +764,22 @@ static void activate_amp(struct hda_codec *codec, hda_nid_t nid, int dir,
784 update_amp(codec, nid, dir, idx, mask, val); 764 update_amp(codec, nid, dir, idx, mask, val);
785} 765}
786 766
767static void check_and_activate_amp(struct hda_codec *codec, hda_nid_t nid,
768 int dir, int idx, int idx_to_check,
769 bool enable)
770{
771 /* check whether the given amp is still used by others */
772 if (!enable && is_active_nid(codec, nid, dir, idx_to_check))
773 return;
774 activate_amp(codec, nid, dir, idx, idx_to_check, enable);
775}
776
787static void activate_amp_out(struct hda_codec *codec, struct nid_path *path, 777static void activate_amp_out(struct hda_codec *codec, struct nid_path *path,
788 int i, bool enable) 778 int i, bool enable)
789{ 779{
790 hda_nid_t nid = path->path[i]; 780 hda_nid_t nid = path->path[i];
791 init_amp(codec, nid, HDA_OUTPUT, 0); 781 init_amp(codec, nid, HDA_OUTPUT, 0);
792 activate_amp(codec, nid, HDA_OUTPUT, 0, 0, enable); 782 check_and_activate_amp(codec, nid, HDA_OUTPUT, 0, 0, enable);
793} 783}
794 784
795static void activate_amp_in(struct hda_codec *codec, struct nid_path *path, 785static void activate_amp_in(struct hda_codec *codec, struct nid_path *path,
@@ -817,9 +807,16 @@ static void activate_amp_in(struct hda_codec *codec, struct nid_path *path,
817 * when aa-mixer is available, we need to enable the path as well 807 * when aa-mixer is available, we need to enable the path as well
818 */ 808 */
819 for (n = 0; n < nums; n++) { 809 for (n = 0; n < nums; n++) {
820 if (n != idx && (!add_aamix || conn[n] != spec->mixer_merge_nid)) 810 if (n != idx) {
821 continue; 811 if (conn[n] != spec->mixer_merge_nid)
822 activate_amp(codec, nid, HDA_INPUT, n, idx, enable); 812 continue;
813 /* when aamix is disabled, force to off */
814 if (!add_aamix) {
815 activate_amp(codec, nid, HDA_INPUT, n, n, false);
816 continue;
817 }
818 }
819 check_and_activate_amp(codec, nid, HDA_INPUT, n, idx, enable);
823 } 820 }
824} 821}
825 822
@@ -1580,6 +1577,12 @@ static bool map_singles(struct hda_codec *codec, int outs,
1580 return found; 1577 return found;
1581} 1578}
1582 1579
1580static inline bool has_aamix_out_paths(struct hda_gen_spec *spec)
1581{
1582 return spec->aamix_out_paths[0] || spec->aamix_out_paths[1] ||
1583 spec->aamix_out_paths[2];
1584}
1585
1583/* create a new path including aamix if available, and return its index */ 1586/* create a new path including aamix if available, and return its index */
1584static int check_aamix_out_path(struct hda_codec *codec, int path_idx) 1587static int check_aamix_out_path(struct hda_codec *codec, int path_idx)
1585{ 1588{
@@ -2422,25 +2425,51 @@ static void update_aamix_paths(struct hda_codec *codec, bool do_mix,
2422 } 2425 }
2423} 2426}
2424 2427
2428/* re-initialize the output paths; only called from loopback_mixing_put() */
2429static void update_output_paths(struct hda_codec *codec, int num_outs,
2430 const int *paths)
2431{
2432 struct hda_gen_spec *spec = codec->spec;
2433 struct nid_path *path;
2434 int i;
2435
2436 for (i = 0; i < num_outs; i++) {
2437 path = snd_hda_get_path_from_idx(codec, paths[i]);
2438 if (path)
2439 snd_hda_activate_path(codec, path, path->active,
2440 spec->aamix_mode);
2441 }
2442}
2443
2425static int loopback_mixing_put(struct snd_kcontrol *kcontrol, 2444static int loopback_mixing_put(struct snd_kcontrol *kcontrol,
2426 struct snd_ctl_elem_value *ucontrol) 2445 struct snd_ctl_elem_value *ucontrol)
2427{ 2446{
2428 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 2447 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2429 struct hda_gen_spec *spec = codec->spec; 2448 struct hda_gen_spec *spec = codec->spec;
2449 const struct auto_pin_cfg *cfg = &spec->autocfg;
2430 unsigned int val = ucontrol->value.enumerated.item[0]; 2450 unsigned int val = ucontrol->value.enumerated.item[0];
2431 2451
2432 if (val == spec->aamix_mode) 2452 if (val == spec->aamix_mode)
2433 return 0; 2453 return 0;
2434 spec->aamix_mode = val; 2454 spec->aamix_mode = val;
2435 update_aamix_paths(codec, val, spec->out_paths[0], 2455 if (has_aamix_out_paths(spec)) {
2436 spec->aamix_out_paths[0], 2456 update_aamix_paths(codec, val, spec->out_paths[0],
2437 spec->autocfg.line_out_type); 2457 spec->aamix_out_paths[0],
2438 update_aamix_paths(codec, val, spec->hp_paths[0], 2458 cfg->line_out_type);
2439 spec->aamix_out_paths[1], 2459 update_aamix_paths(codec, val, spec->hp_paths[0],
2440 AUTO_PIN_HP_OUT); 2460 spec->aamix_out_paths[1],
2441 update_aamix_paths(codec, val, spec->speaker_paths[0], 2461 AUTO_PIN_HP_OUT);
2442 spec->aamix_out_paths[2], 2462 update_aamix_paths(codec, val, spec->speaker_paths[0],
2443 AUTO_PIN_SPEAKER_OUT); 2463 spec->aamix_out_paths[2],
2464 AUTO_PIN_SPEAKER_OUT);
2465 } else {
2466 update_output_paths(codec, cfg->line_outs, spec->out_paths);
2467 if (cfg->line_out_type != AUTO_PIN_HP_OUT)
2468 update_output_paths(codec, cfg->hp_outs, spec->hp_paths);
2469 if (cfg->line_out_type != AUTO_PIN_SPEAKER_OUT)
2470 update_output_paths(codec, cfg->speaker_outs,
2471 spec->speaker_paths);
2472 }
2444 return 1; 2473 return 1;
2445} 2474}
2446 2475
@@ -2458,12 +2487,13 @@ static int create_loopback_mixing_ctl(struct hda_codec *codec)
2458 2487
2459 if (!spec->mixer_nid) 2488 if (!spec->mixer_nid)
2460 return 0; 2489 return 0;
2461 if (!(spec->aamix_out_paths[0] || spec->aamix_out_paths[1] ||
2462 spec->aamix_out_paths[2]))
2463 return 0;
2464 if (!snd_hda_gen_add_kctl(spec, NULL, &loopback_mixing_enum)) 2490 if (!snd_hda_gen_add_kctl(spec, NULL, &loopback_mixing_enum))
2465 return -ENOMEM; 2491 return -ENOMEM;
2466 spec->have_aamix_ctl = 1; 2492 spec->have_aamix_ctl = 1;
2493 /* if no explicit aamix path is present (e.g. for Realtek codecs),
2494 * enable aamix as default -- just for compatibility
2495 */
2496 spec->aamix_mode = !has_aamix_out_paths(spec);
2467 return 0; 2497 return 0;
2468} 2498}
2469 2499
@@ -5664,6 +5694,8 @@ static void init_aamix_paths(struct hda_codec *codec)
5664 5694
5665 if (!spec->have_aamix_ctl) 5695 if (!spec->have_aamix_ctl)
5666 return; 5696 return;
5697 if (!has_aamix_out_paths(spec))
5698 return;
5667 update_aamix_paths(codec, spec->aamix_mode, spec->out_paths[0], 5699 update_aamix_paths(codec, spec->aamix_mode, spec->out_paths[0],
5668 spec->aamix_out_paths[0], 5700 spec->aamix_out_paths[0],
5669 spec->autocfg.line_out_type); 5701 spec->autocfg.line_out_type);
diff --git a/sound/pci/hda/hda_generic.h b/sound/pci/hda/hda_generic.h
index 56e4139b9032..f66fc7e25e07 100644
--- a/sound/pci/hda/hda_generic.h
+++ b/sound/pci/hda/hda_generic.h
@@ -306,13 +306,8 @@ int snd_hda_gen_spec_init(struct hda_gen_spec *spec);
306int snd_hda_gen_init(struct hda_codec *codec); 306int snd_hda_gen_init(struct hda_codec *codec);
307void snd_hda_gen_free(struct hda_codec *codec); 307void snd_hda_gen_free(struct hda_codec *codec);
308 308
309struct nid_path *snd_hda_get_nid_path(struct hda_codec *codec,
310 hda_nid_t from_nid, hda_nid_t to_nid);
311int snd_hda_get_path_idx(struct hda_codec *codec, struct nid_path *path); 309int snd_hda_get_path_idx(struct hda_codec *codec, struct nid_path *path);
312struct nid_path *snd_hda_get_path_from_idx(struct hda_codec *codec, int idx); 310struct nid_path *snd_hda_get_path_from_idx(struct hda_codec *codec, int idx);
313bool snd_hda_parse_nid_path(struct hda_codec *codec, hda_nid_t from_nid,
314 hda_nid_t to_nid, int anchor_nid,
315 struct nid_path *path);
316struct nid_path * 311struct nid_path *
317snd_hda_add_new_path(struct hda_codec *codec, hda_nid_t from_nid, 312snd_hda_add_new_path(struct hda_codec *codec, hda_nid_t from_nid,
318 hda_nid_t to_nid, int anchor_nid); 313 hda_nid_t to_nid, int anchor_nid);
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c
index 3b3658297070..c0bef11afa7e 100644
--- a/sound/pci/hda/hda_intel.c
+++ b/sound/pci/hda/hda_intel.c
@@ -284,13 +284,19 @@ enum {
284 (AZX_DCAPS_OLD_SSYNC | AZX_DCAPS_NO_ALIGN_BUFSIZE) 284 (AZX_DCAPS_OLD_SSYNC | AZX_DCAPS_NO_ALIGN_BUFSIZE)
285 285
286/* quirks for Intel PCH */ 286/* quirks for Intel PCH */
287#define AZX_DCAPS_INTEL_PCH_NOPM \ 287#define AZX_DCAPS_INTEL_PCH_BASE \
288 (AZX_DCAPS_NO_ALIGN_BUFSIZE | AZX_DCAPS_COUNT_LPIB_DELAY |\ 288 (AZX_DCAPS_NO_ALIGN_BUFSIZE | AZX_DCAPS_COUNT_LPIB_DELAY |\
289 AZX_DCAPS_REVERSE_ASSIGN | AZX_DCAPS_SNOOP_TYPE(SCH)) 289 AZX_DCAPS_SNOOP_TYPE(SCH))
290
291/* PCH up to IVB; no runtime PM */
292#define AZX_DCAPS_INTEL_PCH_NOPM \
293 (AZX_DCAPS_INTEL_PCH_BASE)
290 294
295/* PCH for HSW/BDW; with runtime PM */
291#define AZX_DCAPS_INTEL_PCH \ 296#define AZX_DCAPS_INTEL_PCH \
292 (AZX_DCAPS_INTEL_PCH_NOPM | AZX_DCAPS_PM_RUNTIME) 297 (AZX_DCAPS_INTEL_PCH_BASE | AZX_DCAPS_PM_RUNTIME)
293 298
299/* HSW HDMI */
294#define AZX_DCAPS_INTEL_HASWELL \ 300#define AZX_DCAPS_INTEL_HASWELL \
295 (/*AZX_DCAPS_ALIGN_BUFSIZE |*/ AZX_DCAPS_COUNT_LPIB_DELAY |\ 301 (/*AZX_DCAPS_ALIGN_BUFSIZE |*/ AZX_DCAPS_COUNT_LPIB_DELAY |\
296 AZX_DCAPS_PM_RUNTIME | AZX_DCAPS_I915_POWERWELL |\ 302 AZX_DCAPS_PM_RUNTIME | AZX_DCAPS_I915_POWERWELL |\
@@ -332,7 +338,7 @@ enum {
332 338
333/* quirks for Nvidia */ 339/* quirks for Nvidia */
334#define AZX_DCAPS_PRESET_NVIDIA \ 340#define AZX_DCAPS_PRESET_NVIDIA \
335 (AZX_DCAPS_RIRB_DELAY | AZX_DCAPS_NO_MSI | /*AZX_DCAPS_ALIGN_BUFSIZE |*/ \ 341 (AZX_DCAPS_NO_MSI | /*AZX_DCAPS_ALIGN_BUFSIZE |*/ \
336 AZX_DCAPS_NO_64BIT | AZX_DCAPS_CORBRP_SELF_CLEAR |\ 342 AZX_DCAPS_NO_64BIT | AZX_DCAPS_CORBRP_SELF_CLEAR |\
337 AZX_DCAPS_SNOOP_TYPE(NVIDIA)) 343 AZX_DCAPS_SNOOP_TYPE(NVIDIA))
338 344
@@ -649,7 +655,7 @@ static int azx_position_ok(struct azx *chip, struct azx_dev *azx_dev)
649 if (wallclk < (azx_dev->core.period_wallclk * 5) / 4 && 655 if (wallclk < (azx_dev->core.period_wallclk * 5) / 4 &&
650 pos % azx_dev->core.period_bytes > azx_dev->core.period_bytes / 2) 656 pos % azx_dev->core.period_bytes > azx_dev->core.period_bytes / 2)
651 /* NG - it's below the first next period boundary */ 657 /* NG - it's below the first next period boundary */
652 return chip->bdl_pos_adj[chip->dev_index] ? 0 : -1; 658 return chip->bdl_pos_adj ? 0 : -1;
653 azx_dev->core.start_wallclk += wallclk; 659 azx_dev->core.start_wallclk += wallclk;
654 return 1; /* OK, it's fine */ 660 return 1; /* OK, it's fine */
655} 661}
@@ -719,7 +725,7 @@ static int azx_acquire_irq(struct azx *chip, int do_disconnect)
719 725
720 if (request_irq(chip->pci->irq, azx_interrupt, 726 if (request_irq(chip->pci->irq, azx_interrupt,
721 chip->msi ? 0 : IRQF_SHARED, 727 chip->msi ? 0 : IRQF_SHARED,
722 KBUILD_MODNAME, chip)) { 728 chip->card->irq_descr, chip)) {
723 dev_err(chip->card->dev, 729 dev_err(chip->card->dev,
724 "unable to grab IRQ %d, disabling device\n", 730 "unable to grab IRQ %d, disabling device\n",
725 chip->pci->irq); 731 chip->pci->irq);
@@ -1376,7 +1382,7 @@ static int check_position_fix(struct azx *chip, int fix)
1376 } 1382 }
1377 1383
1378 /* Check VIA/ATI HD Audio Controller exist */ 1384 /* Check VIA/ATI HD Audio Controller exist */
1379 if (chip->driver_caps & AZX_DCAPS_POSFIX_VIA) { 1385 if (chip->driver_type == AZX_DRIVER_VIA) {
1380 dev_dbg(chip->card->dev, "Using VIACOMBO position fix\n"); 1386 dev_dbg(chip->card->dev, "Using VIACOMBO position fix\n");
1381 return POS_FIX_VIACOMBO; 1387 return POS_FIX_VIACOMBO;
1382 } 1388 }
@@ -1539,6 +1545,26 @@ static void azx_probe_work(struct work_struct *work)
1539 azx_probe_continue(&hda->chip); 1545 azx_probe_continue(&hda->chip);
1540} 1546}
1541 1547
1548static int default_bdl_pos_adj(struct azx *chip)
1549{
1550 /* some exceptions: Atoms seem problematic with value 1 */
1551 if (chip->pci->vendor == PCI_VENDOR_ID_INTEL) {
1552 switch (chip->pci->device) {
1553 case 0x0f04: /* Baytrail */
1554 case 0x2284: /* Braswell */
1555 return 32;
1556 }
1557 }
1558
1559 switch (chip->driver_type) {
1560 case AZX_DRIVER_ICH:
1561 case AZX_DRIVER_PCH:
1562 return 1;
1563 default:
1564 return 32;
1565 }
1566}
1567
1542/* 1568/*
1543 * constructor 1569 * constructor
1544 */ 1570 */
@@ -1592,18 +1618,10 @@ static int azx_create(struct snd_card *card, struct pci_dev *pci,
1592 chip->single_cmd = single_cmd; 1618 chip->single_cmd = single_cmd;
1593 azx_check_snoop_available(chip); 1619 azx_check_snoop_available(chip);
1594 1620
1595 if (bdl_pos_adj[dev] < 0) { 1621 if (bdl_pos_adj[dev] < 0)
1596 switch (chip->driver_type) { 1622 chip->bdl_pos_adj = default_bdl_pos_adj(chip);
1597 case AZX_DRIVER_ICH: 1623 else
1598 case AZX_DRIVER_PCH: 1624 chip->bdl_pos_adj = bdl_pos_adj[dev];
1599 bdl_pos_adj[dev] = 1;
1600 break;
1601 default:
1602 bdl_pos_adj[dev] = 32;
1603 break;
1604 }
1605 }
1606 chip->bdl_pos_adj = bdl_pos_adj;
1607 1625
1608 err = azx_bus_init(chip, model[dev], &pci_hda_io_ops); 1626 err = azx_bus_init(chip, model[dev], &pci_hda_io_ops);
1609 if (err < 0) { 1627 if (err < 0) {
@@ -1612,6 +1630,11 @@ static int azx_create(struct snd_card *card, struct pci_dev *pci,
1612 return err; 1630 return err;
1613 } 1631 }
1614 1632
1633 if (chip->driver_type == AZX_DRIVER_NVIDIA) {
1634 dev_dbg(chip->card->dev, "Enable delay in RIRB handling\n");
1635 chip->bus.needs_damn_long_delay = 1;
1636 }
1637
1615 err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops); 1638 err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops);
1616 if (err < 0) { 1639 if (err < 0) {
1617 dev_err(card->dev, "Error creating device [card]!\n"); 1640 dev_err(card->dev, "Error creating device [card]!\n");
@@ -2005,8 +2028,8 @@ static int azx_probe(struct pci_dev *pci,
2005#endif /* CONFIG_SND_HDA_PATCH_LOADER */ 2028#endif /* CONFIG_SND_HDA_PATCH_LOADER */
2006 2029
2007#ifndef CONFIG_SND_HDA_I915 2030#ifndef CONFIG_SND_HDA_I915
2008 if (chip->driver_caps & AZX_DCAPS_I915_POWERWELL) 2031 if (CONTROLLER_IN_GPU(pci))
2009 dev_err(card->dev, "Haswell must build in CONFIG_SND_HDA_I915\n"); 2032 dev_err(card->dev, "Haswell/Broadwell HDMI/DP must build in CONFIG_SND_HDA_I915\n");
2010#endif 2033#endif
2011 2034
2012 if (schedule_probe) 2035 if (schedule_probe)
@@ -2203,10 +2226,10 @@ static const struct pci_device_id azx_ids[] = {
2203 .driver_data = AZX_DRIVER_SCH | AZX_DCAPS_INTEL_PCH_NOPM }, 2226 .driver_data = AZX_DRIVER_SCH | AZX_DCAPS_INTEL_PCH_NOPM },
2204 /* Poulsbo */ 2227 /* Poulsbo */
2205 { PCI_DEVICE(0x8086, 0x811b), 2228 { PCI_DEVICE(0x8086, 0x811b),
2206 .driver_data = AZX_DRIVER_SCH | AZX_DCAPS_INTEL_PCH_NOPM }, 2229 .driver_data = AZX_DRIVER_SCH | AZX_DCAPS_INTEL_PCH_BASE },
2207 /* Oaktrail */ 2230 /* Oaktrail */
2208 { PCI_DEVICE(0x8086, 0x080a), 2231 { PCI_DEVICE(0x8086, 0x080a),
2209 .driver_data = AZX_DRIVER_SCH | AZX_DCAPS_INTEL_PCH_NOPM }, 2232 .driver_data = AZX_DRIVER_SCH | AZX_DCAPS_INTEL_PCH_BASE },
2210 /* BayTrail */ 2233 /* BayTrail */
2211 { PCI_DEVICE(0x8086, 0x0f04), 2234 { PCI_DEVICE(0x8086, 0x0f04),
2212 .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_BAYTRAIL }, 2235 .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_BAYTRAIL },
@@ -2318,8 +2341,7 @@ static const struct pci_device_id azx_ids[] = {
2318 { PCI_DEVICE(0x1002, 0xaae8), 2341 { PCI_DEVICE(0x1002, 0xaae8),
2319 .driver_data = AZX_DRIVER_ATIHDMI_NS | AZX_DCAPS_PRESET_ATI_HDMI_NS }, 2342 .driver_data = AZX_DRIVER_ATIHDMI_NS | AZX_DCAPS_PRESET_ATI_HDMI_NS },
2320 /* VIA VT8251/VT8237A */ 2343 /* VIA VT8251/VT8237A */
2321 { PCI_DEVICE(0x1106, 0x3288), 2344 { PCI_DEVICE(0x1106, 0x3288), .driver_data = AZX_DRIVER_VIA },
2322 .driver_data = AZX_DRIVER_VIA | AZX_DCAPS_POSFIX_VIA },
2323 /* VIA GFX VT7122/VX900 */ 2345 /* VIA GFX VT7122/VX900 */
2324 { PCI_DEVICE(0x1106, 0x9170), .driver_data = AZX_DRIVER_GENERIC }, 2346 { PCI_DEVICE(0x1106, 0x9170), .driver_data = AZX_DRIVER_GENERIC },
2325 /* VIA GFX VT6122/VX11 */ 2347 /* VIA GFX VT6122/VX11 */
@@ -2353,14 +2375,12 @@ static const struct pci_device_id azx_ids[] = {
2353 .class = PCI_CLASS_MULTIMEDIA_HD_AUDIO << 8, 2375 .class = PCI_CLASS_MULTIMEDIA_HD_AUDIO << 8,
2354 .class_mask = 0xffffff, 2376 .class_mask = 0xffffff,
2355 .driver_data = AZX_DRIVER_CTX | AZX_DCAPS_CTX_WORKAROUND | 2377 .driver_data = AZX_DRIVER_CTX | AZX_DCAPS_CTX_WORKAROUND |
2356 AZX_DCAPS_NO_64BIT | 2378 AZX_DCAPS_NO_64BIT | AZX_DCAPS_POSFIX_LPIB },
2357 AZX_DCAPS_RIRB_PRE_DELAY | AZX_DCAPS_POSFIX_LPIB },
2358#else 2379#else
2359 /* this entry seems still valid -- i.e. without emu20kx chip */ 2380 /* this entry seems still valid -- i.e. without emu20kx chip */
2360 { PCI_DEVICE(0x1102, 0x0009), 2381 { PCI_DEVICE(0x1102, 0x0009),
2361 .driver_data = AZX_DRIVER_CTX | AZX_DCAPS_CTX_WORKAROUND | 2382 .driver_data = AZX_DRIVER_CTX | AZX_DCAPS_CTX_WORKAROUND |
2362 AZX_DCAPS_NO_64BIT | 2383 AZX_DCAPS_NO_64BIT | AZX_DCAPS_POSFIX_LPIB },
2363 AZX_DCAPS_RIRB_PRE_DELAY | AZX_DCAPS_POSFIX_LPIB },
2364#endif 2384#endif
2365 /* CM8888 */ 2385 /* CM8888 */
2366 { PCI_DEVICE(0x13f6, 0x5011), 2386 { PCI_DEVICE(0x13f6, 0x5011),
diff --git a/sound/pci/hda/hda_tegra.c b/sound/pci/hda/hda_tegra.c
index 58c0aad37284..17fd81736d3d 100644
--- a/sound/pci/hda/hda_tegra.c
+++ b/sound/pci/hda/hda_tegra.c
@@ -464,6 +464,8 @@ static int hda_tegra_create(struct snd_card *card,
464 if (err < 0) 464 if (err < 0)
465 return err; 465 return err;
466 466
467 chip->bus.needs_damn_long_delay = 1;
468
467 err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops); 469 err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops);
468 if (err < 0) { 470 if (err < 0) {
469 dev_err(card->dev, "Error creating device\n"); 471 dev_err(card->dev, "Error creating device\n");
@@ -481,8 +483,7 @@ MODULE_DEVICE_TABLE(of, hda_tegra_match);
481 483
482static int hda_tegra_probe(struct platform_device *pdev) 484static int hda_tegra_probe(struct platform_device *pdev)
483{ 485{
484 const unsigned int driver_flags = AZX_DCAPS_RIRB_DELAY | 486 const unsigned int driver_flags = AZX_DCAPS_CORBRP_SELF_CLEAR;
485 AZX_DCAPS_CORBRP_SELF_CLEAR;
486 struct snd_card *card; 487 struct snd_card *card;
487 struct azx *chip; 488 struct azx *chip;
488 struct hda_tegra *hda; 489 struct hda_tegra *hda;
diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c
index ef198903c0c3..6122b8ca872f 100644
--- a/sound/pci/hda/patch_conexant.c
+++ b/sound/pci/hda/patch_conexant.c
@@ -901,6 +901,9 @@ static int patch_conexant_auto(struct hda_codec *codec)
901 snd_hda_pick_fixup(codec, cxt5051_fixup_models, 901 snd_hda_pick_fixup(codec, cxt5051_fixup_models,
902 cxt5051_fixups, cxt_fixups); 902 cxt5051_fixups, cxt_fixups);
903 break; 903 break;
904 case 0x14f150f2:
905 codec->power_save_node = 1;
906 /* Fall through */
904 default: 907 default:
905 codec->pin_amp_workaround = 1; 908 codec->pin_amp_workaround = 1;
906 snd_hda_pick_fixup(codec, cxt5066_fixup_models, 909 snd_hda_pick_fixup(codec, cxt5066_fixup_models,
diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c
index 4b6fb668c91c..426a29a1c19b 100644
--- a/sound/pci/hda/patch_hdmi.c
+++ b/sound/pci/hda/patch_hdmi.c
@@ -51,8 +51,10 @@ MODULE_PARM_DESC(static_hdmi_pcm, "Don't restrict PCM parameters per ELD info");
51#define is_broadwell(codec) ((codec)->core.vendor_id == 0x80862808) 51#define is_broadwell(codec) ((codec)->core.vendor_id == 0x80862808)
52#define is_skylake(codec) ((codec)->core.vendor_id == 0x80862809) 52#define is_skylake(codec) ((codec)->core.vendor_id == 0x80862809)
53#define is_broxton(codec) ((codec)->core.vendor_id == 0x8086280a) 53#define is_broxton(codec) ((codec)->core.vendor_id == 0x8086280a)
54#define is_kabylake(codec) ((codec)->core.vendor_id == 0x8086280b)
54#define is_haswell_plus(codec) (is_haswell(codec) || is_broadwell(codec) \ 55#define is_haswell_plus(codec) (is_haswell(codec) || is_broadwell(codec) \
55 || is_skylake(codec) || is_broxton(codec)) 56 || is_skylake(codec) || is_broxton(codec) \
57 || is_kabylake(codec))
56 58
57#define is_valleyview(codec) ((codec)->core.vendor_id == 0x80862882) 59#define is_valleyview(codec) ((codec)->core.vendor_id == 0x80862882)
58#define is_cherryview(codec) ((codec)->core.vendor_id == 0x80862883) 60#define is_cherryview(codec) ((codec)->core.vendor_id == 0x80862883)
@@ -83,6 +85,7 @@ struct hdmi_spec_per_pin {
83 struct mutex lock; 85 struct mutex lock;
84 struct delayed_work work; 86 struct delayed_work work;
85 struct snd_kcontrol *eld_ctl; 87 struct snd_kcontrol *eld_ctl;
88 struct snd_jack *acomp_jack; /* jack via audio component */
86 int repoll_count; 89 int repoll_count;
87 bool setup; /* the stream has been set up by prepare callback */ 90 bool setup; /* the stream has been set up by prepare callback */
88 int channels; /* current number of channels */ 91 int channels; /* current number of channels */
@@ -150,8 +153,15 @@ struct hdmi_spec {
150 153
151 /* i915/powerwell (Haswell+/Valleyview+) specific */ 154 /* i915/powerwell (Haswell+/Valleyview+) specific */
152 struct i915_audio_component_audio_ops i915_audio_ops; 155 struct i915_audio_component_audio_ops i915_audio_ops;
156 bool i915_bound; /* was i915 bound in this driver? */
153}; 157};
154 158
159#ifdef CONFIG_SND_HDA_I915
160#define codec_has_acomp(codec) \
161 ((codec)->bus->core.audio_component != NULL)
162#else
163#define codec_has_acomp(codec) false
164#endif
155 165
156struct hdmi_audio_infoframe { 166struct hdmi_audio_infoframe {
157 u8 type; /* 0x84 */ 167 u8 type; /* 0x84 */
@@ -1530,7 +1540,59 @@ static int hdmi_read_pin_conn(struct hda_codec *codec, int pin_idx)
1530 return 0; 1540 return 0;
1531} 1541}
1532 1542
1533static bool hdmi_present_sense(struct hdmi_spec_per_pin *per_pin, int repoll) 1543/* update per_pin ELD from the given new ELD;
1544 * setup info frame and notification accordingly
1545 */
1546static void update_eld(struct hda_codec *codec,
1547 struct hdmi_spec_per_pin *per_pin,
1548 struct hdmi_eld *eld)
1549{
1550 struct hdmi_eld *pin_eld = &per_pin->sink_eld;
1551 bool old_eld_valid = pin_eld->eld_valid;
1552 bool eld_changed;
1553
1554 if (eld->eld_valid)
1555 snd_hdmi_show_eld(codec, &eld->info);
1556
1557 eld_changed = (pin_eld->eld_valid != eld->eld_valid);
1558 if (eld->eld_valid && pin_eld->eld_valid)
1559 if (pin_eld->eld_size != eld->eld_size ||
1560 memcmp(pin_eld->eld_buffer, eld->eld_buffer,
1561 eld->eld_size) != 0)
1562 eld_changed = true;
1563
1564 pin_eld->eld_valid = eld->eld_valid;
1565 pin_eld->eld_size = eld->eld_size;
1566 if (eld->eld_valid)
1567 memcpy(pin_eld->eld_buffer, eld->eld_buffer, eld->eld_size);
1568 pin_eld->info = eld->info;
1569
1570 /*
1571 * Re-setup pin and infoframe. This is needed e.g. when
1572 * - sink is first plugged-in
1573 * - transcoder can change during stream playback on Haswell
1574 * and this can make HW reset converter selection on a pin.
1575 */
1576 if (eld->eld_valid && !old_eld_valid && per_pin->setup) {
1577 if (is_haswell_plus(codec) || is_valleyview_plus(codec)) {
1578 intel_verify_pin_cvt_connect(codec, per_pin);
1579 intel_not_share_assigned_cvt(codec, per_pin->pin_nid,
1580 per_pin->mux_idx);
1581 }
1582
1583 hdmi_setup_audio_infoframe(codec, per_pin, per_pin->non_pcm);
1584 }
1585
1586 if (eld_changed)
1587 snd_ctl_notify(codec->card,
1588 SNDRV_CTL_EVENT_MASK_VALUE |
1589 SNDRV_CTL_EVENT_MASK_INFO,
1590 &per_pin->eld_ctl->id);
1591}
1592
1593/* update ELD and jack state via HD-audio verbs */
1594static bool hdmi_present_sense_via_verbs(struct hdmi_spec_per_pin *per_pin,
1595 int repoll)
1534{ 1596{
1535 struct hda_jack_tbl *jack; 1597 struct hda_jack_tbl *jack;
1536 struct hda_codec *codec = per_pin->codec; 1598 struct hda_codec *codec = per_pin->codec;
@@ -1547,9 +1609,8 @@ static bool hdmi_present_sense(struct hdmi_spec_per_pin *per_pin, int repoll)
1547 * the unsolicited response to avoid custom WARs. 1609 * the unsolicited response to avoid custom WARs.
1548 */ 1610 */
1549 int present; 1611 int present;
1550 bool update_eld = false;
1551 bool eld_changed = false;
1552 bool ret; 1612 bool ret;
1613 bool do_repoll = false;
1553 1614
1554 snd_hda_power_up_pm(codec); 1615 snd_hda_power_up_pm(codec);
1555 present = snd_hda_pin_sense(codec, pin_nid); 1616 present = snd_hda_pin_sense(codec, pin_nid);
@@ -1570,66 +1631,19 @@ static bool hdmi_present_sense(struct hdmi_spec_per_pin *per_pin, int repoll)
1570 &eld->eld_size) < 0) 1631 &eld->eld_size) < 0)
1571 eld->eld_valid = false; 1632 eld->eld_valid = false;
1572 else { 1633 else {
1573 memset(&eld->info, 0, sizeof(struct parsed_hdmi_eld));
1574 if (snd_hdmi_parse_eld(codec, &eld->info, eld->eld_buffer, 1634 if (snd_hdmi_parse_eld(codec, &eld->info, eld->eld_buffer,
1575 eld->eld_size) < 0) 1635 eld->eld_size) < 0)
1576 eld->eld_valid = false; 1636 eld->eld_valid = false;
1577 } 1637 }
1578 1638 if (!eld->eld_valid && repoll)
1579 if (eld->eld_valid) { 1639 do_repoll = true;
1580 snd_hdmi_show_eld(codec, &eld->info);
1581 update_eld = true;
1582 }
1583 else if (repoll) {
1584 schedule_delayed_work(&per_pin->work,
1585 msecs_to_jiffies(300));
1586 goto unlock;
1587 }
1588 } 1640 }
1589 1641
1590 if (pin_eld->eld_valid != eld->eld_valid) 1642 if (do_repoll)
1591 eld_changed = true; 1643 schedule_delayed_work(&per_pin->work, msecs_to_jiffies(300));
1592 1644 else
1593 if (pin_eld->eld_valid && !eld->eld_valid) 1645 update_eld(codec, per_pin, eld);
1594 update_eld = true;
1595
1596 if (update_eld) {
1597 bool old_eld_valid = pin_eld->eld_valid;
1598 pin_eld->eld_valid = eld->eld_valid;
1599 if (pin_eld->eld_size != eld->eld_size ||
1600 memcmp(pin_eld->eld_buffer, eld->eld_buffer,
1601 eld->eld_size) != 0) {
1602 memcpy(pin_eld->eld_buffer, eld->eld_buffer,
1603 eld->eld_size);
1604 eld_changed = true;
1605 }
1606 pin_eld->eld_size = eld->eld_size;
1607 pin_eld->info = eld->info;
1608
1609 /*
1610 * Re-setup pin and infoframe. This is needed e.g. when
1611 * - sink is first plugged-in (infoframe is not set up if !monitor_present)
1612 * - transcoder can change during stream playback on Haswell
1613 * and this can make HW reset converter selection on a pin.
1614 */
1615 if (eld->eld_valid && !old_eld_valid && per_pin->setup) {
1616 if (is_haswell_plus(codec) ||
1617 is_valleyview_plus(codec)) {
1618 intel_verify_pin_cvt_connect(codec, per_pin);
1619 intel_not_share_assigned_cvt(codec, pin_nid,
1620 per_pin->mux_idx);
1621 }
1622
1623 hdmi_setup_audio_infoframe(codec, per_pin,
1624 per_pin->non_pcm);
1625 }
1626 }
1627 1646
1628 if (eld_changed)
1629 snd_ctl_notify(codec->card,
1630 SNDRV_CTL_EVENT_MASK_VALUE | SNDRV_CTL_EVENT_MASK_INFO,
1631 &per_pin->eld_ctl->id);
1632 unlock:
1633 ret = !repoll || !pin_eld->monitor_present || pin_eld->eld_valid; 1647 ret = !repoll || !pin_eld->monitor_present || pin_eld->eld_valid;
1634 1648
1635 jack = snd_hda_jack_tbl_get(codec, pin_nid); 1649 jack = snd_hda_jack_tbl_get(codec, pin_nid);
@@ -1641,6 +1655,54 @@ static bool hdmi_present_sense(struct hdmi_spec_per_pin *per_pin, int repoll)
1641 return ret; 1655 return ret;
1642} 1656}
1643 1657
1658/* update ELD and jack state via audio component */
1659static void sync_eld_via_acomp(struct hda_codec *codec,
1660 struct hdmi_spec_per_pin *per_pin)
1661{
1662 struct hdmi_spec *spec = codec->spec;
1663 struct hdmi_eld *eld = &spec->temp_eld;
1664 int size;
1665
1666 mutex_lock(&per_pin->lock);
1667 size = snd_hdac_acomp_get_eld(&codec->bus->core, per_pin->pin_nid,
1668 &eld->monitor_present, eld->eld_buffer,
1669 ELD_MAX_SIZE);
1670 if (size < 0)
1671 goto unlock;
1672 if (size > 0) {
1673 size = min(size, ELD_MAX_SIZE);
1674 if (snd_hdmi_parse_eld(codec, &eld->info,
1675 eld->eld_buffer, size) < 0)
1676 size = -EINVAL;
1677 }
1678
1679 if (size > 0) {
1680 eld->eld_valid = true;
1681 eld->eld_size = size;
1682 } else {
1683 eld->eld_valid = false;
1684 eld->eld_size = 0;
1685 }
1686
1687 update_eld(codec, per_pin, eld);
1688 snd_jack_report(per_pin->acomp_jack,
1689 eld->monitor_present ? SND_JACK_AVOUT : 0);
1690 unlock:
1691 mutex_unlock(&per_pin->lock);
1692}
1693
1694static bool hdmi_present_sense(struct hdmi_spec_per_pin *per_pin, int repoll)
1695{
1696 struct hda_codec *codec = per_pin->codec;
1697
1698 if (codec_has_acomp(codec)) {
1699 sync_eld_via_acomp(codec, per_pin);
1700 return false; /* don't call snd_hda_jack_report_sync() */
1701 } else {
1702 return hdmi_present_sense_via_verbs(per_pin, repoll);
1703 }
1704}
1705
1644static void hdmi_repoll_eld(struct work_struct *work) 1706static void hdmi_repoll_eld(struct work_struct *work)
1645{ 1707{
1646 struct hdmi_spec_per_pin *per_pin = 1708 struct hdmi_spec_per_pin *per_pin =
@@ -1776,17 +1838,6 @@ static bool check_non_pcm_per_cvt(struct hda_codec *codec, hda_nid_t cvt_nid)
1776 return non_pcm; 1838 return non_pcm;
1777} 1839}
1778 1840
1779/* There is a fixed mapping between audio pin node and display port
1780 * on current Intel platforms:
1781 * Pin Widget 5 - PORT B (port = 1 in i915 driver)
1782 * Pin Widget 6 - PORT C (port = 2 in i915 driver)
1783 * Pin Widget 7 - PORT D (port = 3 in i915 driver)
1784 */
1785static int intel_pin2port(hda_nid_t pin_nid)
1786{
1787 return pin_nid - 4;
1788}
1789
1790/* 1841/*
1791 * HDMI callbacks 1842 * HDMI callbacks
1792 */ 1843 */
@@ -1803,7 +1854,6 @@ static int generic_hdmi_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
1803 struct hdmi_spec_per_pin *per_pin = get_pin(spec, pin_idx); 1854 struct hdmi_spec_per_pin *per_pin = get_pin(spec, pin_idx);
1804 hda_nid_t pin_nid = per_pin->pin_nid; 1855 hda_nid_t pin_nid = per_pin->pin_nid;
1805 struct snd_pcm_runtime *runtime = substream->runtime; 1856 struct snd_pcm_runtime *runtime = substream->runtime;
1806 struct i915_audio_component *acomp = codec->bus->core.audio_component;
1807 bool non_pcm; 1857 bool non_pcm;
1808 int pinctl; 1858 int pinctl;
1809 1859
@@ -1822,10 +1872,7 @@ static int generic_hdmi_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
1822 1872
1823 /* Call sync_audio_rate to set the N/CTS/M manually if necessary */ 1873 /* Call sync_audio_rate to set the N/CTS/M manually if necessary */
1824 /* Todo: add DP1.2 MST audio support later */ 1874 /* Todo: add DP1.2 MST audio support later */
1825 if (acomp && acomp->ops && acomp->ops->sync_audio_rate) 1875 snd_hdac_sync_audio_rate(&codec->bus->core, pin_nid, runtime->rate);
1826 acomp->ops->sync_audio_rate(acomp->dev,
1827 intel_pin2port(pin_nid),
1828 runtime->rate);
1829 1876
1830 non_pcm = check_non_pcm_per_cvt(codec, cvt_nid); 1877 non_pcm = check_non_pcm_per_cvt(codec, cvt_nid);
1831 mutex_lock(&per_pin->lock); 1878 mutex_lock(&per_pin->lock);
@@ -2091,6 +2138,30 @@ static int generic_hdmi_build_pcms(struct hda_codec *codec)
2091 return 0; 2138 return 0;
2092} 2139}
2093 2140
2141static void free_acomp_jack_priv(struct snd_jack *jack)
2142{
2143 struct hdmi_spec_per_pin *per_pin = jack->private_data;
2144
2145 per_pin->acomp_jack = NULL;
2146}
2147
2148static int add_acomp_jack_kctl(struct hda_codec *codec,
2149 struct hdmi_spec_per_pin *per_pin,
2150 const char *name)
2151{
2152 struct snd_jack *jack;
2153 int err;
2154
2155 err = snd_jack_new(codec->card, name, SND_JACK_AVOUT, &jack,
2156 true, false);
2157 if (err < 0)
2158 return err;
2159 per_pin->acomp_jack = jack;
2160 jack->private_data = per_pin;
2161 jack->private_free = free_acomp_jack_priv;
2162 return 0;
2163}
2164
2094static int generic_hdmi_build_jack(struct hda_codec *codec, int pin_idx) 2165static int generic_hdmi_build_jack(struct hda_codec *codec, int pin_idx)
2095{ 2166{
2096 char hdmi_str[32] = "HDMI/DP"; 2167 char hdmi_str[32] = "HDMI/DP";
@@ -2101,6 +2172,8 @@ static int generic_hdmi_build_jack(struct hda_codec *codec, int pin_idx)
2101 2172
2102 if (pcmdev > 0) 2173 if (pcmdev > 0)
2103 sprintf(hdmi_str + strlen(hdmi_str), ",pcm=%d", pcmdev); 2174 sprintf(hdmi_str + strlen(hdmi_str), ",pcm=%d", pcmdev);
2175 if (codec_has_acomp(codec))
2176 return add_acomp_jack_kctl(codec, per_pin, hdmi_str);
2104 phantom_jack = !is_jack_detectable(codec, per_pin->pin_nid); 2177 phantom_jack = !is_jack_detectable(codec, per_pin->pin_nid);
2105 if (phantom_jack) 2178 if (phantom_jack)
2106 strncat(hdmi_str, " Phantom", 2179 strncat(hdmi_str, " Phantom",
@@ -2196,8 +2269,10 @@ static int generic_hdmi_init(struct hda_codec *codec)
2196 hda_nid_t pin_nid = per_pin->pin_nid; 2269 hda_nid_t pin_nid = per_pin->pin_nid;
2197 2270
2198 hdmi_init_pin(codec, pin_nid); 2271 hdmi_init_pin(codec, pin_nid);
2199 snd_hda_jack_detect_enable_callback(codec, pin_nid, 2272 if (!codec_has_acomp(codec))
2200 codec->jackpoll_interval > 0 ? jack_callback : NULL); 2273 snd_hda_jack_detect_enable_callback(codec, pin_nid,
2274 codec->jackpoll_interval > 0 ?
2275 jack_callback : NULL);
2201 } 2276 }
2202 return 0; 2277 return 0;
2203} 2278}
@@ -2219,7 +2294,7 @@ static void generic_hdmi_free(struct hda_codec *codec)
2219 struct hdmi_spec *spec = codec->spec; 2294 struct hdmi_spec *spec = codec->spec;
2220 int pin_idx; 2295 int pin_idx;
2221 2296
2222 if (is_haswell_plus(codec) || is_valleyview_plus(codec)) 2297 if (codec_has_acomp(codec))
2223 snd_hdac_i915_register_notifier(NULL); 2298 snd_hdac_i915_register_notifier(NULL);
2224 2299
2225 for (pin_idx = 0; pin_idx < spec->num_pins; pin_idx++) { 2300 for (pin_idx = 0; pin_idx < spec->num_pins; pin_idx++) {
@@ -2227,8 +2302,12 @@ static void generic_hdmi_free(struct hda_codec *codec)
2227 2302
2228 cancel_delayed_work_sync(&per_pin->work); 2303 cancel_delayed_work_sync(&per_pin->work);
2229 eld_proc_free(per_pin); 2304 eld_proc_free(per_pin);
2305 if (per_pin->acomp_jack)
2306 snd_device_free(codec->card, per_pin->acomp_jack);
2230 } 2307 }
2231 2308
2309 if (spec->i915_bound)
2310 snd_hdac_i915_exit(&codec->bus->core);
2232 hdmi_array_free(spec); 2311 hdmi_array_free(spec);
2233 kfree(spec); 2312 kfree(spec);
2234} 2313}
@@ -2357,6 +2436,9 @@ static void intel_pin_eld_notify(void *audio_ptr, int port)
2357 */ 2436 */
2358 if (snd_power_get_state(codec->card) != SNDRV_CTL_POWER_D0) 2437 if (snd_power_get_state(codec->card) != SNDRV_CTL_POWER_D0)
2359 return; 2438 return;
2439 /* ditto during suspend/resume process itself */
2440 if (atomic_read(&(codec)->core.in_pm))
2441 return;
2360 2442
2361 check_presence_and_report(codec, pin_nid); 2443 check_presence_and_report(codec, pin_nid);
2362} 2444}
@@ -2373,6 +2455,12 @@ static int patch_generic_hdmi(struct hda_codec *codec)
2373 codec->spec = spec; 2455 codec->spec = spec;
2374 hdmi_array_init(spec, 4); 2456 hdmi_array_init(spec, 4);
2375 2457
2458 /* Try to bind with i915 for any Intel codecs (if not done yet) */
2459 if (!codec_has_acomp(codec) &&
2460 (codec->core.vendor_id >> 16) == 0x8086)
2461 if (!snd_hdac_i915_init(&codec->bus->core))
2462 spec->i915_bound = true;
2463
2376 if (is_haswell_plus(codec)) { 2464 if (is_haswell_plus(codec)) {
2377 intel_haswell_enable_all_pins(codec, true); 2465 intel_haswell_enable_all_pins(codec, true);
2378 intel_haswell_fixup_enable_dp12(codec); 2466 intel_haswell_fixup_enable_dp12(codec);
@@ -2388,7 +2476,7 @@ static int patch_generic_hdmi(struct hda_codec *codec)
2388 is_broxton(codec)) 2476 is_broxton(codec))
2389 codec->core.link_power_control = 1; 2477 codec->core.link_power_control = 1;
2390 2478
2391 if (is_haswell_plus(codec) || is_valleyview_plus(codec)) { 2479 if (codec_has_acomp(codec)) {
2392 codec->depop_delay = 0; 2480 codec->depop_delay = 0;
2393 spec->i915_audio_ops.audio_ptr = codec; 2481 spec->i915_audio_ops.audio_ptr = codec;
2394 spec->i915_audio_ops.pin_eld_notify = intel_pin_eld_notify; 2482 spec->i915_audio_ops.pin_eld_notify = intel_pin_eld_notify;
@@ -2396,6 +2484,8 @@ static int patch_generic_hdmi(struct hda_codec *codec)
2396 } 2484 }
2397 2485
2398 if (hdmi_parse_codec(codec) < 0) { 2486 if (hdmi_parse_codec(codec) < 0) {
2487 if (spec->i915_bound)
2488 snd_hdac_i915_exit(&codec->bus->core);
2399 codec->spec = NULL; 2489 codec->spec = NULL;
2400 kfree(spec); 2490 kfree(spec);
2401 return -EINVAL; 2491 return -EINVAL;
@@ -3579,6 +3669,7 @@ HDA_CODEC_ENTRY(0x80862807, "Haswell HDMI", patch_generic_hdmi),
3579HDA_CODEC_ENTRY(0x80862808, "Broadwell HDMI", patch_generic_hdmi), 3669HDA_CODEC_ENTRY(0x80862808, "Broadwell HDMI", patch_generic_hdmi),
3580HDA_CODEC_ENTRY(0x80862809, "Skylake HDMI", patch_generic_hdmi), 3670HDA_CODEC_ENTRY(0x80862809, "Skylake HDMI", patch_generic_hdmi),
3581HDA_CODEC_ENTRY(0x8086280a, "Broxton HDMI", patch_generic_hdmi), 3671HDA_CODEC_ENTRY(0x8086280a, "Broxton HDMI", patch_generic_hdmi),
3672HDA_CODEC_ENTRY(0x8086280b, "Kabylake HDMI", patch_generic_hdmi),
3582HDA_CODEC_ENTRY(0x80862880, "CedarTrail HDMI", patch_generic_hdmi), 3673HDA_CODEC_ENTRY(0x80862880, "CedarTrail HDMI", patch_generic_hdmi),
3583HDA_CODEC_ENTRY(0x80862882, "Valleyview2 HDMI", patch_generic_hdmi), 3674HDA_CODEC_ENTRY(0x80862882, "Valleyview2 HDMI", patch_generic_hdmi),
3584HDA_CODEC_ENTRY(0x80862883, "Braswell HDMI", patch_generic_hdmi), 3675HDA_CODEC_ENTRY(0x80862883, "Braswell HDMI", patch_generic_hdmi),
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index 3a89d82f8057..8143c0e24a27 100644
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -4666,6 +4666,7 @@ enum {
4666 ALC290_FIXUP_SUBWOOFER, 4666 ALC290_FIXUP_SUBWOOFER,
4667 ALC290_FIXUP_SUBWOOFER_HSJACK, 4667 ALC290_FIXUP_SUBWOOFER_HSJACK,
4668 ALC269_FIXUP_THINKPAD_ACPI, 4668 ALC269_FIXUP_THINKPAD_ACPI,
4669 ALC269_FIXUP_DMIC_THINKPAD_ACPI,
4669 ALC255_FIXUP_DELL1_MIC_NO_PRESENCE, 4670 ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
4670 ALC255_FIXUP_DELL2_MIC_NO_PRESENCE, 4671 ALC255_FIXUP_DELL2_MIC_NO_PRESENCE,
4671 ALC255_FIXUP_HEADSET_MODE, 4672 ALC255_FIXUP_HEADSET_MODE,
@@ -5103,6 +5104,12 @@ static const struct hda_fixup alc269_fixups[] = {
5103 .type = HDA_FIXUP_FUNC, 5104 .type = HDA_FIXUP_FUNC,
5104 .v.func = hda_fixup_thinkpad_acpi, 5105 .v.func = hda_fixup_thinkpad_acpi,
5105 }, 5106 },
5107 [ALC269_FIXUP_DMIC_THINKPAD_ACPI] = {
5108 .type = HDA_FIXUP_FUNC,
5109 .v.func = alc_fixup_inv_dmic,
5110 .chained = true,
5111 .chain_id = ALC269_FIXUP_THINKPAD_ACPI,
5112 },
5106 [ALC255_FIXUP_DELL1_MIC_NO_PRESENCE] = { 5113 [ALC255_FIXUP_DELL1_MIC_NO_PRESENCE] = {
5107 .type = HDA_FIXUP_PINS, 5114 .type = HDA_FIXUP_PINS,
5108 .v.pins = (const struct hda_pintbl[]) { 5115 .v.pins = (const struct hda_pintbl[]) {
@@ -5324,6 +5331,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
5324 SND_PCI_QUIRK(0x1028, 0x0470, "Dell M101z", ALC269_FIXUP_DELL_M101Z), 5331 SND_PCI_QUIRK(0x1028, 0x0470, "Dell M101z", ALC269_FIXUP_DELL_M101Z),
5325 SND_PCI_QUIRK(0x1028, 0x054b, "Dell XPS one 2710", ALC275_FIXUP_DELL_XPS), 5332 SND_PCI_QUIRK(0x1028, 0x054b, "Dell XPS one 2710", ALC275_FIXUP_DELL_XPS),
5326 SND_PCI_QUIRK(0x1028, 0x05bd, "Dell Latitude E6440", ALC292_FIXUP_DELL_E7X), 5333 SND_PCI_QUIRK(0x1028, 0x05bd, "Dell Latitude E6440", ALC292_FIXUP_DELL_E7X),
5334 SND_PCI_QUIRK(0x1028, 0x05be, "Dell Latitude E6540", ALC292_FIXUP_DELL_E7X),
5327 SND_PCI_QUIRK(0x1028, 0x05ca, "Dell Latitude E7240", ALC292_FIXUP_DELL_E7X), 5335 SND_PCI_QUIRK(0x1028, 0x05ca, "Dell Latitude E7240", ALC292_FIXUP_DELL_E7X),
5328 SND_PCI_QUIRK(0x1028, 0x05cb, "Dell Latitude E7440", ALC292_FIXUP_DELL_E7X), 5336 SND_PCI_QUIRK(0x1028, 0x05cb, "Dell Latitude E7440", ALC292_FIXUP_DELL_E7X),
5329 SND_PCI_QUIRK(0x1028, 0x05da, "Dell Vostro 5460", ALC290_FIXUP_SUBWOOFER), 5337 SND_PCI_QUIRK(0x1028, 0x05da, "Dell Vostro 5460", ALC290_FIXUP_SUBWOOFER),
@@ -5332,6 +5340,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
5332 SND_PCI_QUIRK(0x1028, 0x05f6, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), 5340 SND_PCI_QUIRK(0x1028, 0x05f6, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE),
5333 SND_PCI_QUIRK(0x1028, 0x0615, "Dell Vostro 5470", ALC290_FIXUP_SUBWOOFER_HSJACK), 5341 SND_PCI_QUIRK(0x1028, 0x0615, "Dell Vostro 5470", ALC290_FIXUP_SUBWOOFER_HSJACK),
5334 SND_PCI_QUIRK(0x1028, 0x0616, "Dell Vostro 5470", ALC290_FIXUP_SUBWOOFER_HSJACK), 5342 SND_PCI_QUIRK(0x1028, 0x0616, "Dell Vostro 5470", ALC290_FIXUP_SUBWOOFER_HSJACK),
5343 SND_PCI_QUIRK(0x1028, 0x062c, "Dell Latitude E5550", ALC292_FIXUP_DELL_E7X),
5335 SND_PCI_QUIRK(0x1028, 0x062e, "Dell Latitude E7450", ALC292_FIXUP_DELL_E7X), 5344 SND_PCI_QUIRK(0x1028, 0x062e, "Dell Latitude E7450", ALC292_FIXUP_DELL_E7X),
5336 SND_PCI_QUIRK(0x1028, 0x0638, "Dell Inspiron 5439", ALC290_FIXUP_MONO_SPEAKERS_HSJACK), 5345 SND_PCI_QUIRK(0x1028, 0x0638, "Dell Inspiron 5439", ALC290_FIXUP_MONO_SPEAKERS_HSJACK),
5337 SND_PCI_QUIRK(0x1028, 0x064a, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE), 5346 SND_PCI_QUIRK(0x1028, 0x064a, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE),
@@ -5457,6 +5466,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
5457 SND_PCI_QUIRK(0x17aa, 0x2226, "ThinkPad X250", ALC292_FIXUP_TPT440_DOCK), 5466 SND_PCI_QUIRK(0x17aa, 0x2226, "ThinkPad X250", ALC292_FIXUP_TPT440_DOCK),
5458 SND_PCI_QUIRK(0x17aa, 0x2233, "Thinkpad", ALC293_FIXUP_LENOVO_SPK_NOISE), 5467 SND_PCI_QUIRK(0x17aa, 0x2233, "Thinkpad", ALC293_FIXUP_LENOVO_SPK_NOISE),
5459 SND_PCI_QUIRK(0x17aa, 0x30bb, "ThinkCentre AIO", ALC233_FIXUP_LENOVO_LINE2_MIC_HOTKEY), 5468 SND_PCI_QUIRK(0x17aa, 0x30bb, "ThinkCentre AIO", ALC233_FIXUP_LENOVO_LINE2_MIC_HOTKEY),
5469 SND_PCI_QUIRK(0x17aa, 0x3902, "Lenovo E50-80", ALC269_FIXUP_DMIC_THINKPAD_ACPI),
5460 SND_PCI_QUIRK(0x17aa, 0x3977, "IdeaPad S210", ALC283_FIXUP_INT_MIC), 5470 SND_PCI_QUIRK(0x17aa, 0x3977, "IdeaPad S210", ALC283_FIXUP_INT_MIC),
5461 SND_PCI_QUIRK(0x17aa, 0x3978, "IdeaPad Y410P", ALC269_FIXUP_NO_SHUTUP), 5471 SND_PCI_QUIRK(0x17aa, 0x3978, "IdeaPad Y410P", ALC269_FIXUP_NO_SHUTUP),
5462 SND_PCI_QUIRK(0x17aa, 0x5013, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST), 5472 SND_PCI_QUIRK(0x17aa, 0x5013, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
@@ -5617,6 +5627,10 @@ static const struct snd_hda_pin_quirk alc269_pin_fixup_tbl[] = {
5617 {0x21, 0x02211040}), 5627 {0x21, 0x02211040}),
5618 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE, 5628 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
5619 {0x12, 0x90a60170}, 5629 {0x12, 0x90a60170},
5630 {0x14, 0x90171130},
5631 {0x21, 0x02211040}),
5632 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
5633 {0x12, 0x90a60170},
5620 {0x14, 0x90170140}, 5634 {0x14, 0x90170140},
5621 {0x21, 0x02211050}), 5635 {0x21, 0x02211050}),
5622 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell Inspiron 5548", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE, 5636 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell Inspiron 5548", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
diff --git a/sound/pci/ice1712/delta.c b/sound/pci/ice1712/delta.c
index 496dbd0ad5db..3bfdc78cbc5f 100644
--- a/sound/pci/ice1712/delta.c
+++ b/sound/pci/ice1712/delta.c
@@ -174,7 +174,7 @@ static int ap_cs8427_probeaddr(struct snd_i2c_bus *bus, unsigned short addr)
174 return -ENOENT; 174 return -ENOENT;
175} 175}
176 176
177static struct snd_i2c_ops ap_cs8427_i2c_ops = { 177static const struct snd_i2c_ops ap_cs8427_i2c_ops = {
178 .sendbytes = ap_cs8427_sendbytes, 178 .sendbytes = ap_cs8427_sendbytes,
179 .readbytes = ap_cs8427_readbytes, 179 .readbytes = ap_cs8427_readbytes,
180 .probeaddr = ap_cs8427_probeaddr, 180 .probeaddr = ap_cs8427_probeaddr,
diff --git a/sound/soc/Kconfig b/sound/soc/Kconfig
index 7ff7d88e46dd..7ea66ee3653f 100644
--- a/sound/soc/Kconfig
+++ b/sound/soc/Kconfig
@@ -38,6 +38,7 @@ config SND_SOC_TOPOLOGY
38 38
39# All the supported SoCs 39# All the supported SoCs
40source "sound/soc/adi/Kconfig" 40source "sound/soc/adi/Kconfig"
41source "sound/soc/amd/Kconfig"
41source "sound/soc/atmel/Kconfig" 42source "sound/soc/atmel/Kconfig"
42source "sound/soc/au1x/Kconfig" 43source "sound/soc/au1x/Kconfig"
43source "sound/soc/bcm/Kconfig" 44source "sound/soc/bcm/Kconfig"
@@ -50,6 +51,7 @@ source "sound/soc/jz4740/Kconfig"
50source "sound/soc/nuc900/Kconfig" 51source "sound/soc/nuc900/Kconfig"
51source "sound/soc/omap/Kconfig" 52source "sound/soc/omap/Kconfig"
52source "sound/soc/kirkwood/Kconfig" 53source "sound/soc/kirkwood/Kconfig"
54source "sound/soc/img/Kconfig"
53source "sound/soc/intel/Kconfig" 55source "sound/soc/intel/Kconfig"
54source "sound/soc/mediatek/Kconfig" 56source "sound/soc/mediatek/Kconfig"
55source "sound/soc/mxs/Kconfig" 57source "sound/soc/mxs/Kconfig"
diff --git a/sound/soc/Makefile b/sound/soc/Makefile
index 8eb06db32fa0..9a30f21d16ee 100644
--- a/sound/soc/Makefile
+++ b/sound/soc/Makefile
@@ -18,6 +18,7 @@ obj-$(CONFIG_SND_SOC) += snd-soc-core.o
18obj-$(CONFIG_SND_SOC) += codecs/ 18obj-$(CONFIG_SND_SOC) += codecs/
19obj-$(CONFIG_SND_SOC) += generic/ 19obj-$(CONFIG_SND_SOC) += generic/
20obj-$(CONFIG_SND_SOC) += adi/ 20obj-$(CONFIG_SND_SOC) += adi/
21obj-$(CONFIG_SND_SOC) += amd/
21obj-$(CONFIG_SND_SOC) += atmel/ 22obj-$(CONFIG_SND_SOC) += atmel/
22obj-$(CONFIG_SND_SOC) += au1x/ 23obj-$(CONFIG_SND_SOC) += au1x/
23obj-$(CONFIG_SND_SOC) += bcm/ 24obj-$(CONFIG_SND_SOC) += bcm/
@@ -27,6 +28,7 @@ obj-$(CONFIG_SND_SOC) += davinci/
27obj-$(CONFIG_SND_SOC) += dwc/ 28obj-$(CONFIG_SND_SOC) += dwc/
28obj-$(CONFIG_SND_SOC) += fsl/ 29obj-$(CONFIG_SND_SOC) += fsl/
29obj-$(CONFIG_SND_SOC) += jz4740/ 30obj-$(CONFIG_SND_SOC) += jz4740/
31obj-$(CONFIG_SND_SOC) += img/
30obj-$(CONFIG_SND_SOC) += intel/ 32obj-$(CONFIG_SND_SOC) += intel/
31obj-$(CONFIG_SND_SOC) += mediatek/ 33obj-$(CONFIG_SND_SOC) += mediatek/
32obj-$(CONFIG_SND_SOC) += mxs/ 34obj-$(CONFIG_SND_SOC) += mxs/
diff --git a/sound/soc/amd/Kconfig b/sound/soc/amd/Kconfig
new file mode 100644
index 000000000000..78187eb24f56
--- /dev/null
+++ b/sound/soc/amd/Kconfig
@@ -0,0 +1,4 @@
1config SND_SOC_AMD_ACP
2 tristate "AMD Audio Coprocessor support"
3 help
4 This option enables ACP DMA support on AMD platform.
diff --git a/sound/soc/amd/Makefile b/sound/soc/amd/Makefile
new file mode 100644
index 000000000000..1a66ec0366b2
--- /dev/null
+++ b/sound/soc/amd/Makefile
@@ -0,0 +1,3 @@
1snd-soc-acp-pcm-objs := acp-pcm-dma.o
2
3obj-$(CONFIG_SND_SOC_AMD_ACP) += snd-soc-acp-pcm.o
diff --git a/sound/soc/amd/acp-pcm-dma.c b/sound/soc/amd/acp-pcm-dma.c
new file mode 100644
index 000000000000..3191e0a7d273
--- /dev/null
+++ b/sound/soc/amd/acp-pcm-dma.c
@@ -0,0 +1,1043 @@
1/*
2 * AMD ALSA SoC PCM Driver for ACP 2.x
3 *
4 * Copyright 2014-2015 Advanced Micro Devices, Inc.
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
16#include <linux/module.h>
17#include <linux/delay.h>
18#include <linux/io.h>
19#include <linux/sizes.h>
20#include <linux/pm_runtime.h>
21
22#include <sound/soc.h>
23
24#include "acp.h"
25
26#define PLAYBACK_MIN_NUM_PERIODS 2
27#define PLAYBACK_MAX_NUM_PERIODS 2
28#define PLAYBACK_MAX_PERIOD_SIZE 16384
29#define PLAYBACK_MIN_PERIOD_SIZE 1024
30#define CAPTURE_MIN_NUM_PERIODS 2
31#define CAPTURE_MAX_NUM_PERIODS 2
32#define CAPTURE_MAX_PERIOD_SIZE 16384
33#define CAPTURE_MIN_PERIOD_SIZE 1024
34
35#define MAX_BUFFER (PLAYBACK_MAX_PERIOD_SIZE * PLAYBACK_MAX_NUM_PERIODS)
36#define MIN_BUFFER MAX_BUFFER
37
38static const struct snd_pcm_hardware acp_pcm_hardware_playback = {
39 .info = SNDRV_PCM_INFO_INTERLEAVED |
40 SNDRV_PCM_INFO_BLOCK_TRANSFER | SNDRV_PCM_INFO_MMAP |
41 SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_BATCH |
42 SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME,
43 .formats = SNDRV_PCM_FMTBIT_S16_LE |
44 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE,
45 .channels_min = 1,
46 .channels_max = 8,
47 .rates = SNDRV_PCM_RATE_8000_96000,
48 .rate_min = 8000,
49 .rate_max = 96000,
50 .buffer_bytes_max = PLAYBACK_MAX_NUM_PERIODS * PLAYBACK_MAX_PERIOD_SIZE,
51 .period_bytes_min = PLAYBACK_MIN_PERIOD_SIZE,
52 .period_bytes_max = PLAYBACK_MAX_PERIOD_SIZE,
53 .periods_min = PLAYBACK_MIN_NUM_PERIODS,
54 .periods_max = PLAYBACK_MAX_NUM_PERIODS,
55};
56
57static const struct snd_pcm_hardware acp_pcm_hardware_capture = {
58 .info = SNDRV_PCM_INFO_INTERLEAVED |
59 SNDRV_PCM_INFO_BLOCK_TRANSFER | SNDRV_PCM_INFO_MMAP |
60 SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_BATCH |
61 SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME,
62 .formats = SNDRV_PCM_FMTBIT_S16_LE |
63 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE,
64 .channels_min = 1,
65 .channels_max = 2,
66 .rates = SNDRV_PCM_RATE_8000_48000,
67 .rate_min = 8000,
68 .rate_max = 48000,
69 .buffer_bytes_max = CAPTURE_MAX_NUM_PERIODS * CAPTURE_MAX_PERIOD_SIZE,
70 .period_bytes_min = CAPTURE_MIN_PERIOD_SIZE,
71 .period_bytes_max = CAPTURE_MAX_PERIOD_SIZE,
72 .periods_min = CAPTURE_MIN_NUM_PERIODS,
73 .periods_max = CAPTURE_MAX_NUM_PERIODS,
74};
75
76struct audio_drv_data {
77 struct snd_pcm_substream *play_stream;
78 struct snd_pcm_substream *capture_stream;
79 void __iomem *acp_mmio;
80};
81
82static u32 acp_reg_read(void __iomem *acp_mmio, u32 reg)
83{
84 return readl(acp_mmio + (reg * 4));
85}
86
87static void acp_reg_write(u32 val, void __iomem *acp_mmio, u32 reg)
88{
89 writel(val, acp_mmio + (reg * 4));
90}
91
92/* Configure a given dma channel parameters - enable/disble,
93 * number of descriptors, priority
94 */
95static void config_acp_dma_channel(void __iomem *acp_mmio, u8 ch_num,
96 u16 dscr_strt_idx, u16 num_dscrs,
97 enum acp_dma_priority_level priority_level)
98{
99 u32 dma_ctrl;
100
101 /* disable the channel run field */
102 dma_ctrl = acp_reg_read(acp_mmio, mmACP_DMA_CNTL_0 + ch_num);
103 dma_ctrl &= ~ACP_DMA_CNTL_0__DMAChRun_MASK;
104 acp_reg_write(dma_ctrl, acp_mmio, mmACP_DMA_CNTL_0 + ch_num);
105
106 /* program a DMA channel with first descriptor to be processed. */
107 acp_reg_write((ACP_DMA_DSCR_STRT_IDX_0__DMAChDscrStrtIdx_MASK
108 & dscr_strt_idx),
109 acp_mmio, mmACP_DMA_DSCR_STRT_IDX_0 + ch_num);
110
111 /* program a DMA channel with the number of descriptors to be
112 * processed in the transfer
113 */
114 acp_reg_write(ACP_DMA_DSCR_CNT_0__DMAChDscrCnt_MASK & num_dscrs,
115 acp_mmio, mmACP_DMA_DSCR_CNT_0 + ch_num);
116
117 /* set DMA channel priority */
118 acp_reg_write(priority_level, acp_mmio, mmACP_DMA_PRIO_0 + ch_num);
119}
120
121/* Initialize a dma descriptor in SRAM based on descritor information passed */
122static void config_dma_descriptor_in_sram(void __iomem *acp_mmio,
123 u16 descr_idx,
124 acp_dma_dscr_transfer_t *descr_info)
125{
126 u32 sram_offset;
127
128 sram_offset = (descr_idx * sizeof(acp_dma_dscr_transfer_t));
129
130 /* program the source base address. */
131 acp_reg_write(sram_offset, acp_mmio, mmACP_SRBM_Targ_Idx_Addr);
132 acp_reg_write(descr_info->src, acp_mmio, mmACP_SRBM_Targ_Idx_Data);
133 /* program the destination base address. */
134 acp_reg_write(sram_offset + 4, acp_mmio, mmACP_SRBM_Targ_Idx_Addr);
135 acp_reg_write(descr_info->dest, acp_mmio, mmACP_SRBM_Targ_Idx_Data);
136
137 /* program the number of bytes to be transferred for this descriptor. */
138 acp_reg_write(sram_offset + 8, acp_mmio, mmACP_SRBM_Targ_Idx_Addr);
139 acp_reg_write(descr_info->xfer_val, acp_mmio, mmACP_SRBM_Targ_Idx_Data);
140}
141
142/* Initialize the DMA descriptor information for transfer between
143 * system memory <-> ACP SRAM
144 */
145static void set_acp_sysmem_dma_descriptors(void __iomem *acp_mmio,
146 u32 size, int direction,
147 u32 pte_offset)
148{
149 u16 i;
150 u16 dma_dscr_idx = PLAYBACK_START_DMA_DESCR_CH12;
151 acp_dma_dscr_transfer_t dmadscr[NUM_DSCRS_PER_CHANNEL];
152
153 for (i = 0; i < NUM_DSCRS_PER_CHANNEL; i++) {
154 dmadscr[i].xfer_val = 0;
155 if (direction == SNDRV_PCM_STREAM_PLAYBACK) {
156 dma_dscr_idx = PLAYBACK_START_DMA_DESCR_CH12 + i;
157 dmadscr[i].dest = ACP_SHARED_RAM_BANK_1_ADDRESS +
158 (size / 2) - (i * (size/2));
159 dmadscr[i].src = ACP_INTERNAL_APERTURE_WINDOW_0_ADDRESS
160 + (pte_offset * SZ_4K) + (i * (size/2));
161 dmadscr[i].xfer_val |=
162 (ACP_DMA_ATTRIBUTES_DAGB_ONION_TO_SHAREDMEM << 16) |
163 (size / 2);
164 } else {
165 dma_dscr_idx = CAPTURE_START_DMA_DESCR_CH14 + i;
166 dmadscr[i].src = ACP_SHARED_RAM_BANK_5_ADDRESS +
167 (i * (size/2));
168 dmadscr[i].dest = ACP_INTERNAL_APERTURE_WINDOW_0_ADDRESS
169 + (pte_offset * SZ_4K) +
170 (i * (size/2));
171 dmadscr[i].xfer_val |=
172 BIT(22) |
173 (ACP_DMA_ATTRIBUTES_SHAREDMEM_TO_DAGB_ONION << 16) |
174 (size / 2);
175 }
176 config_dma_descriptor_in_sram(acp_mmio, dma_dscr_idx,
177 &dmadscr[i]);
178 }
179 if (direction == SNDRV_PCM_STREAM_PLAYBACK)
180 config_acp_dma_channel(acp_mmio, SYSRAM_TO_ACP_CH_NUM,
181 PLAYBACK_START_DMA_DESCR_CH12,
182 NUM_DSCRS_PER_CHANNEL,
183 ACP_DMA_PRIORITY_LEVEL_NORMAL);
184 else
185 config_acp_dma_channel(acp_mmio, ACP_TO_SYSRAM_CH_NUM,
186 CAPTURE_START_DMA_DESCR_CH14,
187 NUM_DSCRS_PER_CHANNEL,
188 ACP_DMA_PRIORITY_LEVEL_NORMAL);
189}
190
191/* Initialize the DMA descriptor information for transfer between
192 * ACP SRAM <-> I2S
193 */
194static void set_acp_to_i2s_dma_descriptors(void __iomem *acp_mmio,
195 u32 size, int direction)
196{
197
198 u16 i;
199 u16 dma_dscr_idx = PLAYBACK_START_DMA_DESCR_CH13;
200 acp_dma_dscr_transfer_t dmadscr[NUM_DSCRS_PER_CHANNEL];
201
202 for (i = 0; i < NUM_DSCRS_PER_CHANNEL; i++) {
203 dmadscr[i].xfer_val = 0;
204 if (direction == SNDRV_PCM_STREAM_PLAYBACK) {
205 dma_dscr_idx = PLAYBACK_START_DMA_DESCR_CH13 + i;
206 dmadscr[i].src = ACP_SHARED_RAM_BANK_1_ADDRESS +
207 (i * (size/2));
208 /* dmadscr[i].dest is unused by hardware. */
209 dmadscr[i].dest = 0;
210 dmadscr[i].xfer_val |= BIT(22) | (TO_ACP_I2S_1 << 16) |
211 (size / 2);
212 } else {
213 dma_dscr_idx = CAPTURE_START_DMA_DESCR_CH15 + i;
214 /* dmadscr[i].src is unused by hardware. */
215 dmadscr[i].src = 0;
216 dmadscr[i].dest = ACP_SHARED_RAM_BANK_5_ADDRESS +
217 (i * (size / 2));
218 dmadscr[i].xfer_val |= BIT(22) |
219 (FROM_ACP_I2S_1 << 16) | (size / 2);
220 }
221 config_dma_descriptor_in_sram(acp_mmio, dma_dscr_idx,
222 &dmadscr[i]);
223 }
224 /* Configure the DMA channel with the above descriptore */
225 if (direction == SNDRV_PCM_STREAM_PLAYBACK)
226 config_acp_dma_channel(acp_mmio, ACP_TO_I2S_DMA_CH_NUM,
227 PLAYBACK_START_DMA_DESCR_CH13,
228 NUM_DSCRS_PER_CHANNEL,
229 ACP_DMA_PRIORITY_LEVEL_NORMAL);
230 else
231 config_acp_dma_channel(acp_mmio, I2S_TO_ACP_DMA_CH_NUM,
232 CAPTURE_START_DMA_DESCR_CH15,
233 NUM_DSCRS_PER_CHANNEL,
234 ACP_DMA_PRIORITY_LEVEL_NORMAL);
235}
236
237/* Create page table entries in ACP SRAM for the allocated memory */
238static void acp_pte_config(void __iomem *acp_mmio, struct page *pg,
239 u16 num_of_pages, u32 pte_offset)
240{
241 u16 page_idx;
242 u64 addr;
243 u32 low;
244 u32 high;
245 u32 offset;
246
247 offset = ACP_DAGB_GRP_SRBM_SRAM_BASE_OFFSET + (pte_offset * 8);
248 for (page_idx = 0; page_idx < (num_of_pages); page_idx++) {
249 /* Load the low address of page int ACP SRAM through SRBM */
250 acp_reg_write((offset + (page_idx * 8)),
251 acp_mmio, mmACP_SRBM_Targ_Idx_Addr);
252 addr = page_to_phys(pg);
253
254 low = lower_32_bits(addr);
255 high = upper_32_bits(addr);
256
257 acp_reg_write(low, acp_mmio, mmACP_SRBM_Targ_Idx_Data);
258
259 /* Load the High address of page int ACP SRAM through SRBM */
260 acp_reg_write((offset + (page_idx * 8) + 4),
261 acp_mmio, mmACP_SRBM_Targ_Idx_Addr);
262
263 /* page enable in ACP */
264 high |= BIT(31);
265 acp_reg_write(high, acp_mmio, mmACP_SRBM_Targ_Idx_Data);
266
267 /* Move to next physically contiguos page */
268 pg++;
269 }
270}
271
272static void config_acp_dma(void __iomem *acp_mmio,
273 struct audio_substream_data *audio_config)
274{
275 u32 pte_offset;
276
277 if (audio_config->direction == SNDRV_PCM_STREAM_PLAYBACK)
278 pte_offset = ACP_PLAYBACK_PTE_OFFSET;
279 else
280 pte_offset = ACP_CAPTURE_PTE_OFFSET;
281
282 acp_pte_config(acp_mmio, audio_config->pg, audio_config->num_of_pages,
283 pte_offset);
284
285 /* Configure System memory <-> ACP SRAM DMA descriptors */
286 set_acp_sysmem_dma_descriptors(acp_mmio, audio_config->size,
287 audio_config->direction, pte_offset);
288
289 /* Configure ACP SRAM <-> I2S DMA descriptors */
290 set_acp_to_i2s_dma_descriptors(acp_mmio, audio_config->size,
291 audio_config->direction);
292}
293
294/* Start a given DMA channel transfer */
295static void acp_dma_start(void __iomem *acp_mmio,
296 u16 ch_num, bool is_circular)
297{
298 u32 dma_ctrl;
299
300 /* read the dma control register and disable the channel run field */
301 dma_ctrl = acp_reg_read(acp_mmio, mmACP_DMA_CNTL_0 + ch_num);
302
303 /* Invalidating the DAGB cache */
304 acp_reg_write(1, acp_mmio, mmACP_DAGB_ATU_CTRL);
305
306 /* configure the DMA channel and start the DMA transfer
307 * set dmachrun bit to start the transfer and enable the
308 * interrupt on completion of the dma transfer
309 */
310 dma_ctrl |= ACP_DMA_CNTL_0__DMAChRun_MASK;
311
312 switch (ch_num) {
313 case ACP_TO_I2S_DMA_CH_NUM:
314 case ACP_TO_SYSRAM_CH_NUM:
315 case I2S_TO_ACP_DMA_CH_NUM:
316 dma_ctrl |= ACP_DMA_CNTL_0__DMAChIOCEn_MASK;
317 break;
318 default:
319 dma_ctrl &= ~ACP_DMA_CNTL_0__DMAChIOCEn_MASK;
320 break;
321 }
322
323 /* enable for ACP SRAM to/from I2S DMA channel */
324 if (is_circular == true)
325 dma_ctrl |= ACP_DMA_CNTL_0__Circular_DMA_En_MASK;
326 else
327 dma_ctrl &= ~ACP_DMA_CNTL_0__Circular_DMA_En_MASK;
328
329 acp_reg_write(dma_ctrl, acp_mmio, mmACP_DMA_CNTL_0 + ch_num);
330}
331
332/* Stop a given DMA channel transfer */
333static int acp_dma_stop(void __iomem *acp_mmio, u8 ch_num)
334{
335 u32 dma_ctrl;
336 u32 dma_ch_sts;
337 u32 count = ACP_DMA_RESET_TIME;
338
339 dma_ctrl = acp_reg_read(acp_mmio, mmACP_DMA_CNTL_0 + ch_num);
340
341 /* clear the dma control register fields before writing zero
342 * in reset bit
343 */
344 dma_ctrl &= ~ACP_DMA_CNTL_0__DMAChRun_MASK;
345 dma_ctrl &= ~ACP_DMA_CNTL_0__DMAChIOCEn_MASK;
346
347 acp_reg_write(dma_ctrl, acp_mmio, mmACP_DMA_CNTL_0 + ch_num);
348 dma_ch_sts = acp_reg_read(acp_mmio, mmACP_DMA_CH_STS);
349
350 if (dma_ch_sts & BIT(ch_num)) {
351 /* set the reset bit for this channel to stop the dma
352 * transfer
353 */
354 dma_ctrl |= ACP_DMA_CNTL_0__DMAChRst_MASK;
355 acp_reg_write(dma_ctrl, acp_mmio, mmACP_DMA_CNTL_0 + ch_num);
356 }
357
358 /* check the channel status bit for some time and return the status */
359 while (true) {
360 dma_ch_sts = acp_reg_read(acp_mmio, mmACP_DMA_CH_STS);
361 if (!(dma_ch_sts & BIT(ch_num))) {
362 /* clear the reset flag after successfully stopping
363 * the dma transfer and break from the loop
364 */
365 dma_ctrl &= ~ACP_DMA_CNTL_0__DMAChRst_MASK;
366
367 acp_reg_write(dma_ctrl, acp_mmio, mmACP_DMA_CNTL_0
368 + ch_num);
369 break;
370 }
371 if (--count == 0) {
372 pr_err("Failed to stop ACP DMA channel : %d\n", ch_num);
373 return -ETIMEDOUT;
374 }
375 udelay(100);
376 }
377 return 0;
378}
379
380static void acp_set_sram_bank_state(void __iomem *acp_mmio, u16 bank,
381 bool power_on)
382{
383 u32 val, req_reg, sts_reg, sts_reg_mask;
384 u32 loops = 1000;
385
386 if (bank < 32) {
387 req_reg = mmACP_MEM_SHUT_DOWN_REQ_LO;
388 sts_reg = mmACP_MEM_SHUT_DOWN_STS_LO;
389 sts_reg_mask = 0xFFFFFFFF;
390
391 } else {
392 bank -= 32;
393 req_reg = mmACP_MEM_SHUT_DOWN_REQ_HI;
394 sts_reg = mmACP_MEM_SHUT_DOWN_STS_HI;
395 sts_reg_mask = 0x0000FFFF;
396 }
397
398 val = acp_reg_read(acp_mmio, req_reg);
399 if (val & (1 << bank)) {
400 /* bank is in off state */
401 if (power_on == true)
402 /* request to on */
403 val &= ~(1 << bank);
404 else
405 /* request to off */
406 return;
407 } else {
408 /* bank is in on state */
409 if (power_on == false)
410 /* request to off */
411 val |= 1 << bank;
412 else
413 /* request to on */
414 return;
415 }
416 acp_reg_write(val, acp_mmio, req_reg);
417
418 while (acp_reg_read(acp_mmio, sts_reg) != sts_reg_mask) {
419 if (!loops--) {
420 pr_err("ACP SRAM bank %d state change failed\n", bank);
421 break;
422 }
423 cpu_relax();
424 }
425}
426
427/* Initialize and bring ACP hardware to default state. */
428static int acp_init(void __iomem *acp_mmio)
429{
430 u16 bank;
431 u32 val, count, sram_pte_offset;
432
433 /* Assert Soft reset of ACP */
434 val = acp_reg_read(acp_mmio, mmACP_SOFT_RESET);
435
436 val |= ACP_SOFT_RESET__SoftResetAud_MASK;
437 acp_reg_write(val, acp_mmio, mmACP_SOFT_RESET);
438
439 count = ACP_SOFT_RESET_DONE_TIME_OUT_VALUE;
440 while (true) {
441 val = acp_reg_read(acp_mmio, mmACP_SOFT_RESET);
442 if (ACP_SOFT_RESET__SoftResetAudDone_MASK ==
443 (val & ACP_SOFT_RESET__SoftResetAudDone_MASK))
444 break;
445 if (--count == 0) {
446 pr_err("Failed to reset ACP\n");
447 return -ETIMEDOUT;
448 }
449 udelay(100);
450 }
451
452 /* Enable clock to ACP and wait until the clock is enabled */
453 val = acp_reg_read(acp_mmio, mmACP_CONTROL);
454 val = val | ACP_CONTROL__ClkEn_MASK;
455 acp_reg_write(val, acp_mmio, mmACP_CONTROL);
456
457 count = ACP_CLOCK_EN_TIME_OUT_VALUE;
458
459 while (true) {
460 val = acp_reg_read(acp_mmio, mmACP_STATUS);
461 if (val & (u32) 0x1)
462 break;
463 if (--count == 0) {
464 pr_err("Failed to reset ACP\n");
465 return -ETIMEDOUT;
466 }
467 udelay(100);
468 }
469
470 /* Deassert the SOFT RESET flags */
471 val = acp_reg_read(acp_mmio, mmACP_SOFT_RESET);
472 val &= ~ACP_SOFT_RESET__SoftResetAud_MASK;
473 acp_reg_write(val, acp_mmio, mmACP_SOFT_RESET);
474
475 /* initiailize Onion control DAGB register */
476 acp_reg_write(ACP_ONION_CNTL_DEFAULT, acp_mmio,
477 mmACP_AXI2DAGB_ONION_CNTL);
478
479 /* initiailize Garlic control DAGB registers */
480 acp_reg_write(ACP_GARLIC_CNTL_DEFAULT, acp_mmio,
481 mmACP_AXI2DAGB_GARLIC_CNTL);
482
483 sram_pte_offset = ACP_DAGB_GRP_SRAM_BASE_ADDRESS |
484 ACP_DAGB_BASE_ADDR_GRP_1__AXI2DAGBSnoopSel_MASK |
485 ACP_DAGB_BASE_ADDR_GRP_1__AXI2DAGBTargetMemSel_MASK |
486 ACP_DAGB_BASE_ADDR_GRP_1__AXI2DAGBGrpEnable_MASK;
487 acp_reg_write(sram_pte_offset, acp_mmio, mmACP_DAGB_BASE_ADDR_GRP_1);
488 acp_reg_write(ACP_PAGE_SIZE_4K_ENABLE, acp_mmio,
489 mmACP_DAGB_PAGE_SIZE_GRP_1);
490
491 acp_reg_write(ACP_SRAM_BASE_ADDRESS, acp_mmio,
492 mmACP_DMA_DESC_BASE_ADDR);
493
494 /* Num of descriptiors in SRAM 0x4, means 256 descriptors;(64 * 4) */
495 acp_reg_write(0x4, acp_mmio, mmACP_DMA_DESC_MAX_NUM_DSCR);
496 acp_reg_write(ACP_EXTERNAL_INTR_CNTL__DMAIOCMask_MASK,
497 acp_mmio, mmACP_EXTERNAL_INTR_CNTL);
498
499 /* When ACP_TILE_P1 is turned on, all SRAM banks get turned on.
500 * Now, turn off all of them. This can't be done in 'poweron' of
501 * ACP pm domain, as this requires ACP to be initialized.
502 */
503 for (bank = 1; bank < 48; bank++)
504 acp_set_sram_bank_state(acp_mmio, bank, false);
505
506 return 0;
507}
508
509/* Deintialize ACP */
510static int acp_deinit(void __iomem *acp_mmio)
511{
512 u32 val;
513 u32 count;
514
515 /* Assert Soft reset of ACP */
516 val = acp_reg_read(acp_mmio, mmACP_SOFT_RESET);
517
518 val |= ACP_SOFT_RESET__SoftResetAud_MASK;
519 acp_reg_write(val, acp_mmio, mmACP_SOFT_RESET);
520
521 count = ACP_SOFT_RESET_DONE_TIME_OUT_VALUE;
522 while (true) {
523 val = acp_reg_read(acp_mmio, mmACP_SOFT_RESET);
524 if (ACP_SOFT_RESET__SoftResetAudDone_MASK ==
525 (val & ACP_SOFT_RESET__SoftResetAudDone_MASK))
526 break;
527 if (--count == 0) {
528 pr_err("Failed to reset ACP\n");
529 return -ETIMEDOUT;
530 }
531 udelay(100);
532 }
533 /** Disable ACP clock */
534 val = acp_reg_read(acp_mmio, mmACP_CONTROL);
535 val &= ~ACP_CONTROL__ClkEn_MASK;
536 acp_reg_write(val, acp_mmio, mmACP_CONTROL);
537
538 count = ACP_CLOCK_EN_TIME_OUT_VALUE;
539
540 while (true) {
541 val = acp_reg_read(acp_mmio, mmACP_STATUS);
542 if (!(val & (u32) 0x1))
543 break;
544 if (--count == 0) {
545 pr_err("Failed to reset ACP\n");
546 return -ETIMEDOUT;
547 }
548 udelay(100);
549 }
550 return 0;
551}
552
553/* ACP DMA irq handler routine for playback, capture usecases */
554static irqreturn_t dma_irq_handler(int irq, void *arg)
555{
556 u16 dscr_idx;
557 u32 intr_flag, ext_intr_status;
558 struct audio_drv_data *irq_data;
559 void __iomem *acp_mmio;
560 struct device *dev = arg;
561 bool valid_irq = false;
562
563 irq_data = dev_get_drvdata(dev);
564 acp_mmio = irq_data->acp_mmio;
565
566 ext_intr_status = acp_reg_read(acp_mmio, mmACP_EXTERNAL_INTR_STAT);
567 intr_flag = (((ext_intr_status &
568 ACP_EXTERNAL_INTR_STAT__DMAIOCStat_MASK) >>
569 ACP_EXTERNAL_INTR_STAT__DMAIOCStat__SHIFT));
570
571 if ((intr_flag & BIT(ACP_TO_I2S_DMA_CH_NUM)) != 0) {
572 valid_irq = true;
573 if (acp_reg_read(acp_mmio, mmACP_DMA_CUR_DSCR_13) ==
574 PLAYBACK_START_DMA_DESCR_CH13)
575 dscr_idx = PLAYBACK_START_DMA_DESCR_CH12;
576 else
577 dscr_idx = PLAYBACK_END_DMA_DESCR_CH12;
578 config_acp_dma_channel(acp_mmio, SYSRAM_TO_ACP_CH_NUM, dscr_idx,
579 1, 0);
580 acp_dma_start(acp_mmio, SYSRAM_TO_ACP_CH_NUM, false);
581
582 snd_pcm_period_elapsed(irq_data->play_stream);
583
584 acp_reg_write((intr_flag & BIT(ACP_TO_I2S_DMA_CH_NUM)) << 16,
585 acp_mmio, mmACP_EXTERNAL_INTR_STAT);
586 }
587
588 if ((intr_flag & BIT(I2S_TO_ACP_DMA_CH_NUM)) != 0) {
589 valid_irq = true;
590 if (acp_reg_read(acp_mmio, mmACP_DMA_CUR_DSCR_15) ==
591 CAPTURE_START_DMA_DESCR_CH15)
592 dscr_idx = CAPTURE_END_DMA_DESCR_CH14;
593 else
594 dscr_idx = CAPTURE_START_DMA_DESCR_CH14;
595 config_acp_dma_channel(acp_mmio, ACP_TO_SYSRAM_CH_NUM, dscr_idx,
596 1, 0);
597 acp_dma_start(acp_mmio, ACP_TO_SYSRAM_CH_NUM, false);
598
599 acp_reg_write((intr_flag & BIT(I2S_TO_ACP_DMA_CH_NUM)) << 16,
600 acp_mmio, mmACP_EXTERNAL_INTR_STAT);
601 }
602
603 if ((intr_flag & BIT(ACP_TO_SYSRAM_CH_NUM)) != 0) {
604 valid_irq = true;
605 snd_pcm_period_elapsed(irq_data->capture_stream);
606 acp_reg_write((intr_flag & BIT(ACP_TO_SYSRAM_CH_NUM)) << 16,
607 acp_mmio, mmACP_EXTERNAL_INTR_STAT);
608 }
609
610 if (valid_irq)
611 return IRQ_HANDLED;
612 else
613 return IRQ_NONE;
614}
615
616static int acp_dma_open(struct snd_pcm_substream *substream)
617{
618 u16 bank;
619 int ret = 0;
620 struct snd_pcm_runtime *runtime = substream->runtime;
621 struct snd_soc_pcm_runtime *prtd = substream->private_data;
622 struct audio_drv_data *intr_data = dev_get_drvdata(prtd->platform->dev);
623
624 struct audio_substream_data *adata =
625 kzalloc(sizeof(struct audio_substream_data), GFP_KERNEL);
626 if (adata == NULL)
627 return -ENOMEM;
628
629 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
630 runtime->hw = acp_pcm_hardware_playback;
631 else
632 runtime->hw = acp_pcm_hardware_capture;
633
634 ret = snd_pcm_hw_constraint_integer(runtime,
635 SNDRV_PCM_HW_PARAM_PERIODS);
636 if (ret < 0) {
637 dev_err(prtd->platform->dev, "set integer constraint failed\n");
638 return ret;
639 }
640
641 adata->acp_mmio = intr_data->acp_mmio;
642 runtime->private_data = adata;
643
644 /* Enable ACP irq, when neither playback or capture streams are
645 * active by the time when a new stream is being opened.
646 * This enablement is not required for another stream, if current
647 * stream is not closed
648 */
649 if (!intr_data->play_stream && !intr_data->capture_stream)
650 acp_reg_write(1, adata->acp_mmio, mmACP_EXTERNAL_INTR_ENB);
651
652 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
653 intr_data->play_stream = substream;
654 for (bank = 1; bank <= 4; bank++)
655 acp_set_sram_bank_state(intr_data->acp_mmio, bank,
656 true);
657 } else {
658 intr_data->capture_stream = substream;
659 for (bank = 5; bank <= 8; bank++)
660 acp_set_sram_bank_state(intr_data->acp_mmio, bank,
661 true);
662 }
663
664 return 0;
665}
666
667static int acp_dma_hw_params(struct snd_pcm_substream *substream,
668 struct snd_pcm_hw_params *params)
669{
670 int status;
671 uint64_t size;
672 struct snd_dma_buffer *dma_buffer;
673 struct page *pg;
674 struct snd_pcm_runtime *runtime;
675 struct audio_substream_data *rtd;
676
677 dma_buffer = &substream->dma_buffer;
678
679 runtime = substream->runtime;
680 rtd = runtime->private_data;
681
682 if (WARN_ON(!rtd))
683 return -EINVAL;
684
685 size = params_buffer_bytes(params);
686 status = snd_pcm_lib_malloc_pages(substream, size);
687 if (status < 0)
688 return status;
689
690 memset(substream->runtime->dma_area, 0, params_buffer_bytes(params));
691 pg = virt_to_page(substream->dma_buffer.area);
692
693 if (pg != NULL) {
694 acp_set_sram_bank_state(rtd->acp_mmio, 0, true);
695 /* Save for runtime private data */
696 rtd->pg = pg;
697 rtd->order = get_order(size);
698
699 /* Fill the page table entries in ACP SRAM */
700 rtd->pg = pg;
701 rtd->size = size;
702 rtd->num_of_pages = PAGE_ALIGN(size) >> PAGE_SHIFT;
703 rtd->direction = substream->stream;
704
705 config_acp_dma(rtd->acp_mmio, rtd);
706 status = 0;
707 } else {
708 status = -ENOMEM;
709 }
710 return status;
711}
712
713static int acp_dma_hw_free(struct snd_pcm_substream *substream)
714{
715 return snd_pcm_lib_free_pages(substream);
716}
717
718static snd_pcm_uframes_t acp_dma_pointer(struct snd_pcm_substream *substream)
719{
720 u16 dscr;
721 u32 mul, dma_config, period_bytes;
722 u32 pos = 0;
723
724 struct snd_pcm_runtime *runtime = substream->runtime;
725 struct audio_substream_data *rtd = runtime->private_data;
726
727 period_bytes = frames_to_bytes(runtime, runtime->period_size);
728 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
729 dscr = acp_reg_read(rtd->acp_mmio, mmACP_DMA_CUR_DSCR_13);
730
731 if (dscr == PLAYBACK_START_DMA_DESCR_CH13)
732 mul = 0;
733 else
734 mul = 1;
735 pos = (mul * period_bytes);
736 } else {
737 dma_config = acp_reg_read(rtd->acp_mmio, mmACP_DMA_CNTL_14);
738 if (dma_config != 0) {
739 dscr = acp_reg_read(rtd->acp_mmio,
740 mmACP_DMA_CUR_DSCR_14);
741 if (dscr == CAPTURE_START_DMA_DESCR_CH14)
742 mul = 1;
743 else
744 mul = 2;
745 pos = (mul * period_bytes);
746 }
747
748 if (pos >= (2 * period_bytes))
749 pos = 0;
750
751 }
752 return bytes_to_frames(runtime, pos);
753}
754
755static int acp_dma_mmap(struct snd_pcm_substream *substream,
756 struct vm_area_struct *vma)
757{
758 return snd_pcm_lib_default_mmap(substream, vma);
759}
760
761static int acp_dma_prepare(struct snd_pcm_substream *substream)
762{
763 struct snd_pcm_runtime *runtime = substream->runtime;
764 struct audio_substream_data *rtd = runtime->private_data;
765
766 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
767 config_acp_dma_channel(rtd->acp_mmio, SYSRAM_TO_ACP_CH_NUM,
768 PLAYBACK_START_DMA_DESCR_CH12,
769 NUM_DSCRS_PER_CHANNEL, 0);
770 config_acp_dma_channel(rtd->acp_mmio, ACP_TO_I2S_DMA_CH_NUM,
771 PLAYBACK_START_DMA_DESCR_CH13,
772 NUM_DSCRS_PER_CHANNEL, 0);
773 /* Fill ACP SRAM (2 periods) with zeros from System RAM
774 * which is zero-ed in hw_params
775 */
776 acp_dma_start(rtd->acp_mmio, SYSRAM_TO_ACP_CH_NUM, false);
777
778 /* ACP SRAM (2 periods of buffer size) is intially filled with
779 * zeros. Before rendering starts, 2nd half of SRAM will be
780 * filled with valid audio data DMA'ed from first half of system
781 * RAM and 1st half of SRAM will be filled with Zeros. This is
782 * the initial scenario when redering starts from SRAM. Later
783 * on, 2nd half of system memory will be DMA'ed to 1st half of
784 * SRAM, 1st half of system memory will be DMA'ed to 2nd half of
785 * SRAM in ping-pong way till rendering stops.
786 */
787 config_acp_dma_channel(rtd->acp_mmio, SYSRAM_TO_ACP_CH_NUM,
788 PLAYBACK_START_DMA_DESCR_CH12,
789 1, 0);
790 } else {
791 config_acp_dma_channel(rtd->acp_mmio, ACP_TO_SYSRAM_CH_NUM,
792 CAPTURE_START_DMA_DESCR_CH14,
793 NUM_DSCRS_PER_CHANNEL, 0);
794 config_acp_dma_channel(rtd->acp_mmio, I2S_TO_ACP_DMA_CH_NUM,
795 CAPTURE_START_DMA_DESCR_CH15,
796 NUM_DSCRS_PER_CHANNEL, 0);
797 }
798 return 0;
799}
800
801static int acp_dma_trigger(struct snd_pcm_substream *substream, int cmd)
802{
803 int ret;
804 u32 loops = 1000;
805
806 struct snd_pcm_runtime *runtime = substream->runtime;
807 struct snd_soc_pcm_runtime *prtd = substream->private_data;
808 struct audio_substream_data *rtd = runtime->private_data;
809
810 if (!rtd)
811 return -EINVAL;
812 switch (cmd) {
813 case SNDRV_PCM_TRIGGER_START:
814 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
815 case SNDRV_PCM_TRIGGER_RESUME:
816 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
817 acp_dma_start(rtd->acp_mmio,
818 SYSRAM_TO_ACP_CH_NUM, false);
819 while (acp_reg_read(rtd->acp_mmio, mmACP_DMA_CH_STS) &
820 BIT(SYSRAM_TO_ACP_CH_NUM)) {
821 if (!loops--) {
822 dev_err(prtd->platform->dev,
823 "acp dma start timeout\n");
824 return -ETIMEDOUT;
825 }
826 cpu_relax();
827 }
828
829 acp_dma_start(rtd->acp_mmio,
830 ACP_TO_I2S_DMA_CH_NUM, true);
831
832 } else {
833 acp_dma_start(rtd->acp_mmio,
834 I2S_TO_ACP_DMA_CH_NUM, true);
835 }
836 ret = 0;
837 break;
838 case SNDRV_PCM_TRIGGER_STOP:
839 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
840 case SNDRV_PCM_TRIGGER_SUSPEND:
841 /* Need to stop only circular DMA channels :
842 * ACP_TO_I2S_DMA_CH_NUM / I2S_TO_ACP_DMA_CH_NUM. Non-circular
843 * channels will stopped automatically after its transfer
844 * completes : SYSRAM_TO_ACP_CH_NUM / ACP_TO_SYSRAM_CH_NUM
845 */
846 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
847 ret = acp_dma_stop(rtd->acp_mmio,
848 ACP_TO_I2S_DMA_CH_NUM);
849 else
850 ret = acp_dma_stop(rtd->acp_mmio,
851 I2S_TO_ACP_DMA_CH_NUM);
852 break;
853 default:
854 ret = -EINVAL;
855
856 }
857 return ret;
858}
859
860static int acp_dma_new(struct snd_soc_pcm_runtime *rtd)
861{
862 return snd_pcm_lib_preallocate_pages_for_all(rtd->pcm,
863 SNDRV_DMA_TYPE_DEV,
864 NULL, MIN_BUFFER,
865 MAX_BUFFER);
866}
867
868static int acp_dma_close(struct snd_pcm_substream *substream)
869{
870 u16 bank;
871 struct snd_pcm_runtime *runtime = substream->runtime;
872 struct audio_substream_data *rtd = runtime->private_data;
873 struct snd_soc_pcm_runtime *prtd = substream->private_data;
874 struct audio_drv_data *adata = dev_get_drvdata(prtd->platform->dev);
875
876 kfree(rtd);
877
878 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
879 adata->play_stream = NULL;
880 for (bank = 1; bank <= 4; bank++)
881 acp_set_sram_bank_state(adata->acp_mmio, bank,
882 false);
883 } else {
884 adata->capture_stream = NULL;
885 for (bank = 5; bank <= 8; bank++)
886 acp_set_sram_bank_state(adata->acp_mmio, bank,
887 false);
888 }
889
890 /* Disable ACP irq, when the current stream is being closed and
891 * another stream is also not active.
892 */
893 if (!adata->play_stream && !adata->capture_stream)
894 acp_reg_write(0, adata->acp_mmio, mmACP_EXTERNAL_INTR_ENB);
895
896 return 0;
897}
898
899static struct snd_pcm_ops acp_dma_ops = {
900 .open = acp_dma_open,
901 .close = acp_dma_close,
902 .ioctl = snd_pcm_lib_ioctl,
903 .hw_params = acp_dma_hw_params,
904 .hw_free = acp_dma_hw_free,
905 .trigger = acp_dma_trigger,
906 .pointer = acp_dma_pointer,
907 .mmap = acp_dma_mmap,
908 .prepare = acp_dma_prepare,
909};
910
911static struct snd_soc_platform_driver acp_asoc_platform = {
912 .ops = &acp_dma_ops,
913 .pcm_new = acp_dma_new,
914};
915
916static int acp_audio_probe(struct platform_device *pdev)
917{
918 int status;
919 struct audio_drv_data *audio_drv_data;
920 struct resource *res;
921
922 audio_drv_data = devm_kzalloc(&pdev->dev, sizeof(struct audio_drv_data),
923 GFP_KERNEL);
924 if (audio_drv_data == NULL)
925 return -ENOMEM;
926
927 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
928 audio_drv_data->acp_mmio = devm_ioremap_resource(&pdev->dev, res);
929
930 /* The following members gets populated in device 'open'
931 * function. Till then interrupts are disabled in 'acp_init'
932 * and device doesn't generate any interrupts.
933 */
934
935 audio_drv_data->play_stream = NULL;
936 audio_drv_data->capture_stream = NULL;
937
938 res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
939 if (!res) {
940 dev_err(&pdev->dev, "IORESOURCE_IRQ FAILED\n");
941 return -ENODEV;
942 }
943
944 status = devm_request_irq(&pdev->dev, res->start, dma_irq_handler,
945 0, "ACP_IRQ", &pdev->dev);
946 if (status) {
947 dev_err(&pdev->dev, "ACP IRQ request failed\n");
948 return status;
949 }
950
951 dev_set_drvdata(&pdev->dev, audio_drv_data);
952
953 /* Initialize the ACP */
954 acp_init(audio_drv_data->acp_mmio);
955
956 status = snd_soc_register_platform(&pdev->dev, &acp_asoc_platform);
957 if (status != 0) {
958 dev_err(&pdev->dev, "Fail to register ALSA platform device\n");
959 return status;
960 }
961
962 pm_runtime_set_autosuspend_delay(&pdev->dev, 10000);
963 pm_runtime_use_autosuspend(&pdev->dev);
964 pm_runtime_enable(&pdev->dev);
965
966 return status;
967}
968
969static int acp_audio_remove(struct platform_device *pdev)
970{
971 struct audio_drv_data *adata = dev_get_drvdata(&pdev->dev);
972
973 acp_deinit(adata->acp_mmio);
974 snd_soc_unregister_platform(&pdev->dev);
975 pm_runtime_disable(&pdev->dev);
976
977 return 0;
978}
979
980static int acp_pcm_resume(struct device *dev)
981{
982 u16 bank;
983 struct audio_drv_data *adata = dev_get_drvdata(dev);
984
985 acp_init(adata->acp_mmio);
986
987 if (adata->play_stream && adata->play_stream->runtime) {
988 for (bank = 1; bank <= 4; bank++)
989 acp_set_sram_bank_state(adata->acp_mmio, bank,
990 true);
991 config_acp_dma(adata->acp_mmio,
992 adata->play_stream->runtime->private_data);
993 }
994 if (adata->capture_stream && adata->capture_stream->runtime) {
995 for (bank = 5; bank <= 8; bank++)
996 acp_set_sram_bank_state(adata->acp_mmio, bank,
997 true);
998 config_acp_dma(adata->acp_mmio,
999 adata->capture_stream->runtime->private_data);
1000 }
1001 acp_reg_write(1, adata->acp_mmio, mmACP_EXTERNAL_INTR_ENB);
1002 return 0;
1003}
1004
1005static int acp_pcm_runtime_suspend(struct device *dev)
1006{
1007 struct audio_drv_data *adata = dev_get_drvdata(dev);
1008
1009 acp_deinit(adata->acp_mmio);
1010 acp_reg_write(0, adata->acp_mmio, mmACP_EXTERNAL_INTR_ENB);
1011 return 0;
1012}
1013
1014static int acp_pcm_runtime_resume(struct device *dev)
1015{
1016 struct audio_drv_data *adata = dev_get_drvdata(dev);
1017
1018 acp_init(adata->acp_mmio);
1019 acp_reg_write(1, adata->acp_mmio, mmACP_EXTERNAL_INTR_ENB);
1020 return 0;
1021}
1022
1023static const struct dev_pm_ops acp_pm_ops = {
1024 .resume = acp_pcm_resume,
1025 .runtime_suspend = acp_pcm_runtime_suspend,
1026 .runtime_resume = acp_pcm_runtime_resume,
1027};
1028
1029static struct platform_driver acp_dma_driver = {
1030 .probe = acp_audio_probe,
1031 .remove = acp_audio_remove,
1032 .driver = {
1033 .name = "acp_audio_dma",
1034 .pm = &acp_pm_ops,
1035 },
1036};
1037
1038module_platform_driver(acp_dma_driver);
1039
1040MODULE_AUTHOR("Maruthi.Bayyavarapu@amd.com");
1041MODULE_DESCRIPTION("AMD ACP PCM Driver");
1042MODULE_LICENSE("GPL v2");
1043MODULE_ALIAS("platform:acp-dma-audio");
diff --git a/sound/soc/amd/acp.h b/sound/soc/amd/acp.h
new file mode 100644
index 000000000000..330832ef4e5e
--- /dev/null
+++ b/sound/soc/amd/acp.h
@@ -0,0 +1,118 @@
1#ifndef __ACP_HW_H
2#define __ACP_HW_H
3
4#include "include/acp_2_2_d.h"
5#include "include/acp_2_2_sh_mask.h"
6
7#define ACP_PAGE_SIZE_4K_ENABLE 0x02
8
9#define ACP_PLAYBACK_PTE_OFFSET 10
10#define ACP_CAPTURE_PTE_OFFSET 0
11
12#define ACP_GARLIC_CNTL_DEFAULT 0x00000FB4
13#define ACP_ONION_CNTL_DEFAULT 0x00000FB4
14
15#define ACP_PHYSICAL_BASE 0x14000
16
17/* Playback SRAM address (as a destination in dma descriptor) */
18#define ACP_SHARED_RAM_BANK_1_ADDRESS 0x4002000
19
20/* Capture SRAM address (as a source in dma descriptor) */
21#define ACP_SHARED_RAM_BANK_5_ADDRESS 0x400A000
22
23#define ACP_DMA_RESET_TIME 10000
24#define ACP_CLOCK_EN_TIME_OUT_VALUE 0x000000FF
25#define ACP_SOFT_RESET_DONE_TIME_OUT_VALUE 0x000000FF
26#define ACP_DMA_COMPLETE_TIME_OUT_VALUE 0x000000FF
27
28#define ACP_SRAM_BASE_ADDRESS 0x4000000
29#define ACP_DAGB_GRP_SRAM_BASE_ADDRESS 0x4001000
30#define ACP_DAGB_GRP_SRBM_SRAM_BASE_OFFSET 0x1000
31#define ACP_INTERNAL_APERTURE_WINDOW_0_ADDRESS 0x00000000
32#define ACP_INTERNAL_APERTURE_WINDOW_4_ADDRESS 0x01800000
33
34#define TO_ACP_I2S_1 0x2
35#define TO_ACP_I2S_2 0x4
36#define FROM_ACP_I2S_1 0xa
37#define FROM_ACP_I2S_2 0xb
38
39#define ACP_TILE_ON_MASK 0x03
40#define ACP_TILE_OFF_MASK 0x02
41#define ACP_TILE_ON_RETAIN_REG_MASK 0x1f
42#define ACP_TILE_OFF_RETAIN_REG_MASK 0x20
43
44#define ACP_TILE_P1_MASK 0x3e
45#define ACP_TILE_P2_MASK 0x3d
46#define ACP_TILE_DSP0_MASK 0x3b
47#define ACP_TILE_DSP1_MASK 0x37
48
49#define ACP_TILE_DSP2_MASK 0x2f
50/* Playback DMA channels */
51#define SYSRAM_TO_ACP_CH_NUM 12
52#define ACP_TO_I2S_DMA_CH_NUM 13
53
54/* Capture DMA channels */
55#define ACP_TO_SYSRAM_CH_NUM 14
56#define I2S_TO_ACP_DMA_CH_NUM 15
57
58#define NUM_DSCRS_PER_CHANNEL 2
59
60#define PLAYBACK_START_DMA_DESCR_CH12 0
61#define PLAYBACK_END_DMA_DESCR_CH12 1
62#define PLAYBACK_START_DMA_DESCR_CH13 2
63#define PLAYBACK_END_DMA_DESCR_CH13 3
64
65#define CAPTURE_START_DMA_DESCR_CH14 4
66#define CAPTURE_END_DMA_DESCR_CH14 5
67#define CAPTURE_START_DMA_DESCR_CH15 6
68#define CAPTURE_END_DMA_DESCR_CH15 7
69
70enum acp_dma_priority_level {
71 /* 0x0 Specifies the DMA channel is given normal priority */
72 ACP_DMA_PRIORITY_LEVEL_NORMAL = 0x0,
73 /* 0x1 Specifies the DMA channel is given high priority */
74 ACP_DMA_PRIORITY_LEVEL_HIGH = 0x1,
75 ACP_DMA_PRIORITY_LEVEL_FORCESIZE = 0xFF
76};
77
78struct audio_substream_data {
79 struct page *pg;
80 unsigned int order;
81 u16 num_of_pages;
82 u16 direction;
83 uint64_t size;
84 void __iomem *acp_mmio;
85};
86
87enum {
88 ACP_TILE_P1 = 0,
89 ACP_TILE_P2,
90 ACP_TILE_DSP0,
91 ACP_TILE_DSP1,
92 ACP_TILE_DSP2,
93};
94
95enum {
96 ACP_DMA_ATTRIBUTES_SHAREDMEM_TO_DAGB_ONION = 0x0,
97 ACP_DMA_ATTRIBUTES_SHARED_MEM_TO_DAGB_GARLIC = 0x1,
98 ACP_DMA_ATTRIBUTES_DAGB_ONION_TO_SHAREDMEM = 0x8,
99 ACP_DMA_ATTRIBUTES_DAGB_GARLIC_TO_SHAREDMEM = 0x9,
100 ACP_DMA_ATTRIBUTES_FORCE_SIZE = 0xF
101};
102
103typedef struct acp_dma_dscr_transfer {
104 /* Specifies the source memory location for the DMA data transfer. */
105 u32 src;
106 /* Specifies the destination memory location to where the data will
107 * be transferred.
108 */
109 u32 dest;
110 /* Specifies the number of bytes need to be transferred
111 * from source to destination memory.Transfer direction & IOC enable
112 */
113 u32 xfer_val;
114 /* Reserved for future use */
115 u32 reserved;
116} acp_dma_dscr_transfer_t;
117
118#endif /*__ACP_HW_H */
diff --git a/sound/soc/amd/include/acp_2_2_d.h b/sound/soc/amd/include/acp_2_2_d.h
new file mode 100644
index 000000000000..0118fe9e6a87
--- /dev/null
+++ b/sound/soc/amd/include/acp_2_2_d.h
@@ -0,0 +1,609 @@
1/*
2 * ACP_2_2 Register documentation
3 *
4 * Copyright (C) 2014 Advanced Micro Devices, Inc.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the "Software"),
8 * to deal in the Software without restriction, including without limitation
9 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 * and/or sell copies of the Software, and to permit persons to whom the
11 * Software is furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included
14 * in all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
17 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE COPYRIGHT HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
20 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 */
23
24#ifndef ACP_2_2_D_H
25#define ACP_2_2_D_H
26
27#define mmACP_DMA_CNTL_0 0x5000
28#define mmACP_DMA_CNTL_1 0x5001
29#define mmACP_DMA_CNTL_2 0x5002
30#define mmACP_DMA_CNTL_3 0x5003
31#define mmACP_DMA_CNTL_4 0x5004
32#define mmACP_DMA_CNTL_5 0x5005
33#define mmACP_DMA_CNTL_6 0x5006
34#define mmACP_DMA_CNTL_7 0x5007
35#define mmACP_DMA_CNTL_8 0x5008
36#define mmACP_DMA_CNTL_9 0x5009
37#define mmACP_DMA_CNTL_10 0x500a
38#define mmACP_DMA_CNTL_11 0x500b
39#define mmACP_DMA_CNTL_12 0x500c
40#define mmACP_DMA_CNTL_13 0x500d
41#define mmACP_DMA_CNTL_14 0x500e
42#define mmACP_DMA_CNTL_15 0x500f
43#define mmACP_DMA_DSCR_STRT_IDX_0 0x5010
44#define mmACP_DMA_DSCR_STRT_IDX_1 0x5011
45#define mmACP_DMA_DSCR_STRT_IDX_2 0x5012
46#define mmACP_DMA_DSCR_STRT_IDX_3 0x5013
47#define mmACP_DMA_DSCR_STRT_IDX_4 0x5014
48#define mmACP_DMA_DSCR_STRT_IDX_5 0x5015
49#define mmACP_DMA_DSCR_STRT_IDX_6 0x5016
50#define mmACP_DMA_DSCR_STRT_IDX_7 0x5017
51#define mmACP_DMA_DSCR_STRT_IDX_8 0x5018
52#define mmACP_DMA_DSCR_STRT_IDX_9 0x5019
53#define mmACP_DMA_DSCR_STRT_IDX_10 0x501a
54#define mmACP_DMA_DSCR_STRT_IDX_11 0x501b
55#define mmACP_DMA_DSCR_STRT_IDX_12 0x501c
56#define mmACP_DMA_DSCR_STRT_IDX_13 0x501d
57#define mmACP_DMA_DSCR_STRT_IDX_14 0x501e
58#define mmACP_DMA_DSCR_STRT_IDX_15 0x501f
59#define mmACP_DMA_DSCR_CNT_0 0x5020
60#define mmACP_DMA_DSCR_CNT_1 0x5021
61#define mmACP_DMA_DSCR_CNT_2 0x5022
62#define mmACP_DMA_DSCR_CNT_3 0x5023
63#define mmACP_DMA_DSCR_CNT_4 0x5024
64#define mmACP_DMA_DSCR_CNT_5 0x5025
65#define mmACP_DMA_DSCR_CNT_6 0x5026
66#define mmACP_DMA_DSCR_CNT_7 0x5027
67#define mmACP_DMA_DSCR_CNT_8 0x5028
68#define mmACP_DMA_DSCR_CNT_9 0x5029
69#define mmACP_DMA_DSCR_CNT_10 0x502a
70#define mmACP_DMA_DSCR_CNT_11 0x502b
71#define mmACP_DMA_DSCR_CNT_12 0x502c
72#define mmACP_DMA_DSCR_CNT_13 0x502d
73#define mmACP_DMA_DSCR_CNT_14 0x502e
74#define mmACP_DMA_DSCR_CNT_15 0x502f
75#define mmACP_DMA_PRIO_0 0x5030
76#define mmACP_DMA_PRIO_1 0x5031
77#define mmACP_DMA_PRIO_2 0x5032
78#define mmACP_DMA_PRIO_3 0x5033
79#define mmACP_DMA_PRIO_4 0x5034
80#define mmACP_DMA_PRIO_5 0x5035
81#define mmACP_DMA_PRIO_6 0x5036
82#define mmACP_DMA_PRIO_7 0x5037
83#define mmACP_DMA_PRIO_8 0x5038
84#define mmACP_DMA_PRIO_9 0x5039
85#define mmACP_DMA_PRIO_10 0x503a
86#define mmACP_DMA_PRIO_11 0x503b
87#define mmACP_DMA_PRIO_12 0x503c
88#define mmACP_DMA_PRIO_13 0x503d
89#define mmACP_DMA_PRIO_14 0x503e
90#define mmACP_DMA_PRIO_15 0x503f
91#define mmACP_DMA_CUR_DSCR_0 0x5040
92#define mmACP_DMA_CUR_DSCR_1 0x5041
93#define mmACP_DMA_CUR_DSCR_2 0x5042
94#define mmACP_DMA_CUR_DSCR_3 0x5043
95#define mmACP_DMA_CUR_DSCR_4 0x5044
96#define mmACP_DMA_CUR_DSCR_5 0x5045
97#define mmACP_DMA_CUR_DSCR_6 0x5046
98#define mmACP_DMA_CUR_DSCR_7 0x5047
99#define mmACP_DMA_CUR_DSCR_8 0x5048
100#define mmACP_DMA_CUR_DSCR_9 0x5049
101#define mmACP_DMA_CUR_DSCR_10 0x504a
102#define mmACP_DMA_CUR_DSCR_11 0x504b
103#define mmACP_DMA_CUR_DSCR_12 0x504c
104#define mmACP_DMA_CUR_DSCR_13 0x504d
105#define mmACP_DMA_CUR_DSCR_14 0x504e
106#define mmACP_DMA_CUR_DSCR_15 0x504f
107#define mmACP_DMA_CUR_TRANS_CNT_0 0x5050
108#define mmACP_DMA_CUR_TRANS_CNT_1 0x5051
109#define mmACP_DMA_CUR_TRANS_CNT_2 0x5052
110#define mmACP_DMA_CUR_TRANS_CNT_3 0x5053
111#define mmACP_DMA_CUR_TRANS_CNT_4 0x5054
112#define mmACP_DMA_CUR_TRANS_CNT_5 0x5055
113#define mmACP_DMA_CUR_TRANS_CNT_6 0x5056
114#define mmACP_DMA_CUR_TRANS_CNT_7 0x5057
115#define mmACP_DMA_CUR_TRANS_CNT_8 0x5058
116#define mmACP_DMA_CUR_TRANS_CNT_9 0x5059
117#define mmACP_DMA_CUR_TRANS_CNT_10 0x505a
118#define mmACP_DMA_CUR_TRANS_CNT_11 0x505b
119#define mmACP_DMA_CUR_TRANS_CNT_12 0x505c
120#define mmACP_DMA_CUR_TRANS_CNT_13 0x505d
121#define mmACP_DMA_CUR_TRANS_CNT_14 0x505e
122#define mmACP_DMA_CUR_TRANS_CNT_15 0x505f
123#define mmACP_DMA_ERR_STS_0 0x5060
124#define mmACP_DMA_ERR_STS_1 0x5061
125#define mmACP_DMA_ERR_STS_2 0x5062
126#define mmACP_DMA_ERR_STS_3 0x5063
127#define mmACP_DMA_ERR_STS_4 0x5064
128#define mmACP_DMA_ERR_STS_5 0x5065
129#define mmACP_DMA_ERR_STS_6 0x5066
130#define mmACP_DMA_ERR_STS_7 0x5067
131#define mmACP_DMA_ERR_STS_8 0x5068
132#define mmACP_DMA_ERR_STS_9 0x5069
133#define mmACP_DMA_ERR_STS_10 0x506a
134#define mmACP_DMA_ERR_STS_11 0x506b
135#define mmACP_DMA_ERR_STS_12 0x506c
136#define mmACP_DMA_ERR_STS_13 0x506d
137#define mmACP_DMA_ERR_STS_14 0x506e
138#define mmACP_DMA_ERR_STS_15 0x506f
139#define mmACP_DMA_DESC_BASE_ADDR 0x5070
140#define mmACP_DMA_DESC_MAX_NUM_DSCR 0x5071
141#define mmACP_DMA_CH_STS 0x5072
142#define mmACP_DMA_CH_GROUP 0x5073
143#define mmACP_DSP0_CACHE_OFFSET0 0x5078
144#define mmACP_DSP0_CACHE_SIZE0 0x5079
145#define mmACP_DSP0_CACHE_OFFSET1 0x507a
146#define mmACP_DSP0_CACHE_SIZE1 0x507b
147#define mmACP_DSP0_CACHE_OFFSET2 0x507c
148#define mmACP_DSP0_CACHE_SIZE2 0x507d
149#define mmACP_DSP0_CACHE_OFFSET3 0x507e
150#define mmACP_DSP0_CACHE_SIZE3 0x507f
151#define mmACP_DSP0_CACHE_OFFSET4 0x5080
152#define mmACP_DSP0_CACHE_SIZE4 0x5081
153#define mmACP_DSP0_CACHE_OFFSET5 0x5082
154#define mmACP_DSP0_CACHE_SIZE5 0x5083
155#define mmACP_DSP0_CACHE_OFFSET6 0x5084
156#define mmACP_DSP0_CACHE_SIZE6 0x5085
157#define mmACP_DSP0_CACHE_OFFSET7 0x5086
158#define mmACP_DSP0_CACHE_SIZE7 0x5087
159#define mmACP_DSP0_CACHE_OFFSET8 0x5088
160#define mmACP_DSP0_CACHE_SIZE8 0x5089
161#define mmACP_DSP0_NONCACHE_OFFSET0 0x508a
162#define mmACP_DSP0_NONCACHE_SIZE0 0x508b
163#define mmACP_DSP0_NONCACHE_OFFSET1 0x508c
164#define mmACP_DSP0_NONCACHE_SIZE1 0x508d
165#define mmACP_DSP0_DEBUG_PC 0x508e
166#define mmACP_DSP0_NMI_SEL 0x508f
167#define mmACP_DSP0_CLKRST_CNTL 0x5090
168#define mmACP_DSP0_RUNSTALL 0x5091
169#define mmACP_DSP0_OCD_HALT_ON_RST 0x5092
170#define mmACP_DSP0_WAIT_MODE 0x5093
171#define mmACP_DSP0_VECT_SEL 0x5094
172#define mmACP_DSP0_DEBUG_REG1 0x5095
173#define mmACP_DSP0_DEBUG_REG2 0x5096
174#define mmACP_DSP0_DEBUG_REG3 0x5097
175#define mmACP_DSP1_CACHE_OFFSET0 0x509d
176#define mmACP_DSP1_CACHE_SIZE0 0x509e
177#define mmACP_DSP1_CACHE_OFFSET1 0x509f
178#define mmACP_DSP1_CACHE_SIZE1 0x50a0
179#define mmACP_DSP1_CACHE_OFFSET2 0x50a1
180#define mmACP_DSP1_CACHE_SIZE2 0x50a2
181#define mmACP_DSP1_CACHE_OFFSET3 0x50a3
182#define mmACP_DSP1_CACHE_SIZE3 0x50a4
183#define mmACP_DSP1_CACHE_OFFSET4 0x50a5
184#define mmACP_DSP1_CACHE_SIZE4 0x50a6
185#define mmACP_DSP1_CACHE_OFFSET5 0x50a7
186#define mmACP_DSP1_CACHE_SIZE5 0x50a8
187#define mmACP_DSP1_CACHE_OFFSET6 0x50a9
188#define mmACP_DSP1_CACHE_SIZE6 0x50aa
189#define mmACP_DSP1_CACHE_OFFSET7 0x50ab
190#define mmACP_DSP1_CACHE_SIZE7 0x50ac
191#define mmACP_DSP1_CACHE_OFFSET8 0x50ad
192#define mmACP_DSP1_CACHE_SIZE8 0x50ae
193#define mmACP_DSP1_NONCACHE_OFFSET0 0x50af
194#define mmACP_DSP1_NONCACHE_SIZE0 0x50b0
195#define mmACP_DSP1_NONCACHE_OFFSET1 0x50b1
196#define mmACP_DSP1_NONCACHE_SIZE1 0x50b2
197#define mmACP_DSP1_DEBUG_PC 0x50b3
198#define mmACP_DSP1_NMI_SEL 0x50b4
199#define mmACP_DSP1_CLKRST_CNTL 0x50b5
200#define mmACP_DSP1_RUNSTALL 0x50b6
201#define mmACP_DSP1_OCD_HALT_ON_RST 0x50b7
202#define mmACP_DSP1_WAIT_MODE 0x50b8
203#define mmACP_DSP1_VECT_SEL 0x50b9
204#define mmACP_DSP1_DEBUG_REG1 0x50ba
205#define mmACP_DSP1_DEBUG_REG2 0x50bb
206#define mmACP_DSP1_DEBUG_REG3 0x50bc
207#define mmACP_DSP2_CACHE_OFFSET0 0x50c2
208#define mmACP_DSP2_CACHE_SIZE0 0x50c3
209#define mmACP_DSP2_CACHE_OFFSET1 0x50c4
210#define mmACP_DSP2_CACHE_SIZE1 0x50c5
211#define mmACP_DSP2_CACHE_OFFSET2 0x50c6
212#define mmACP_DSP2_CACHE_SIZE2 0x50c7
213#define mmACP_DSP2_CACHE_OFFSET3 0x50c8
214#define mmACP_DSP2_CACHE_SIZE3 0x50c9
215#define mmACP_DSP2_CACHE_OFFSET4 0x50ca
216#define mmACP_DSP2_CACHE_SIZE4 0x50cb
217#define mmACP_DSP2_CACHE_OFFSET5 0x50cc
218#define mmACP_DSP2_CACHE_SIZE5 0x50cd
219#define mmACP_DSP2_CACHE_OFFSET6 0x50ce
220#define mmACP_DSP2_CACHE_SIZE6 0x50cf
221#define mmACP_DSP2_CACHE_OFFSET7 0x50d0
222#define mmACP_DSP2_CACHE_SIZE7 0x50d1
223#define mmACP_DSP2_CACHE_OFFSET8 0x50d2
224#define mmACP_DSP2_CACHE_SIZE8 0x50d3
225#define mmACP_DSP2_NONCACHE_OFFSET0 0x50d4
226#define mmACP_DSP2_NONCACHE_SIZE0 0x50d5
227#define mmACP_DSP2_NONCACHE_OFFSET1 0x50d6
228#define mmACP_DSP2_NONCACHE_SIZE1 0x50d7
229#define mmACP_DSP2_DEBUG_PC 0x50d8
230#define mmACP_DSP2_NMI_SEL 0x50d9
231#define mmACP_DSP2_CLKRST_CNTL 0x50da
232#define mmACP_DSP2_RUNSTALL 0x50db
233#define mmACP_DSP2_OCD_HALT_ON_RST 0x50dc
234#define mmACP_DSP2_WAIT_MODE 0x50dd
235#define mmACP_DSP2_VECT_SEL 0x50de
236#define mmACP_DSP2_DEBUG_REG1 0x50df
237#define mmACP_DSP2_DEBUG_REG2 0x50e0
238#define mmACP_DSP2_DEBUG_REG3 0x50e1
239#define mmACP_AXI2DAGB_ONION_CNTL 0x50e7
240#define mmACP_AXI2DAGB_ONION_ERR_STATUS_WR 0x50e8
241#define mmACP_AXI2DAGB_ONION_ERR_STATUS_RD 0x50e9
242#define mmACP_DAGB_Onion_TransPerf_Counter_Control 0x50ea
243#define mmACP_DAGB_Onion_Wr_TransPerf_Counter_Current 0x50eb
244#define mmACP_DAGB_Onion_Wr_TransPerf_Counter_Peak 0x50ec
245#define mmACP_DAGB_Onion_Rd_TransPerf_Counter_Current 0x50ed
246#define mmACP_DAGB_Onion_Rd_TransPerf_Counter_Peak 0x50ee
247#define mmACP_AXI2DAGB_GARLIC_CNTL 0x50f3
248#define mmACP_AXI2DAGB_GARLIC_ERR_STATUS_WR 0x50f4
249#define mmACP_AXI2DAGB_GARLIC_ERR_STATUS_RD 0x50f5
250#define mmACP_DAGB_Garlic_TransPerf_Counter_Control 0x50f6
251#define mmACP_DAGB_Garlic_Wr_TransPerf_Counter_Current 0x50f7
252#define mmACP_DAGB_Garlic_Wr_TransPerf_Counter_Peak 0x50f8
253#define mmACP_DAGB_Garlic_Rd_TransPerf_Counter_Current 0x50f9
254#define mmACP_DAGB_Garlic_Rd_TransPerf_Counter_Peak 0x50fa
255#define mmACP_DAGB_PAGE_SIZE_GRP_1 0x50ff
256#define mmACP_DAGB_BASE_ADDR_GRP_1 0x5100
257#define mmACP_DAGB_PAGE_SIZE_GRP_2 0x5101
258#define mmACP_DAGB_BASE_ADDR_GRP_2 0x5102
259#define mmACP_DAGB_PAGE_SIZE_GRP_3 0x5103
260#define mmACP_DAGB_BASE_ADDR_GRP_3 0x5104
261#define mmACP_DAGB_PAGE_SIZE_GRP_4 0x5105
262#define mmACP_DAGB_BASE_ADDR_GRP_4 0x5106
263#define mmACP_DAGB_PAGE_SIZE_GRP_5 0x5107
264#define mmACP_DAGB_BASE_ADDR_GRP_5 0x5108
265#define mmACP_DAGB_PAGE_SIZE_GRP_6 0x5109
266#define mmACP_DAGB_BASE_ADDR_GRP_6 0x510a
267#define mmACP_DAGB_PAGE_SIZE_GRP_7 0x510b
268#define mmACP_DAGB_BASE_ADDR_GRP_7 0x510c
269#define mmACP_DAGB_PAGE_SIZE_GRP_8 0x510d
270#define mmACP_DAGB_BASE_ADDR_GRP_8 0x510e
271#define mmACP_DAGB_ATU_CTRL 0x510f
272#define mmACP_CONTROL 0x5131
273#define mmACP_STATUS 0x5133
274#define mmACP_SOFT_RESET 0x5134
275#define mmACP_PwrMgmt_CNTL 0x5135
276#define mmACP_CAC_INDICATOR_CONTROL 0x5136
277#define mmACP_SMU_MAILBOX 0x5137
278#define mmACP_FUTURE_REG_SCLK_0 0x5138
279#define mmACP_FUTURE_REG_SCLK_1 0x5139
280#define mmACP_FUTURE_REG_SCLK_2 0x513a
281#define mmACP_FUTURE_REG_SCLK_3 0x513b
282#define mmACP_FUTURE_REG_SCLK_4 0x513c
283#define mmACP_DAGB_DEBUG_CNT_ENABLE 0x513d
284#define mmACP_DAGBG_WR_ASK_CNT 0x513e
285#define mmACP_DAGBG_WR_GO_CNT 0x513f
286#define mmACP_DAGBG_WR_EXP_RESP_CNT 0x5140
287#define mmACP_DAGBG_WR_ACTUAL_RESP_CNT 0x5141
288#define mmACP_DAGBG_RD_ASK_CNT 0x5142
289#define mmACP_DAGBG_RD_GO_CNT 0x5143
290#define mmACP_DAGBG_RD_EXP_RESP_CNT 0x5144
291#define mmACP_DAGBG_RD_ACTUAL_RESP_CNT 0x5145
292#define mmACP_DAGBO_WR_ASK_CNT 0x5146
293#define mmACP_DAGBO_WR_GO_CNT 0x5147
294#define mmACP_DAGBO_WR_EXP_RESP_CNT 0x5148
295#define mmACP_DAGBO_WR_ACTUAL_RESP_CNT 0x5149
296#define mmACP_DAGBO_RD_ASK_CNT 0x514a
297#define mmACP_DAGBO_RD_GO_CNT 0x514b
298#define mmACP_DAGBO_RD_EXP_RESP_CNT 0x514c
299#define mmACP_DAGBO_RD_ACTUAL_RESP_CNT 0x514d
300#define mmACP_BRB_CONTROL 0x5156
301#define mmACP_EXTERNAL_INTR_ENB 0x5157
302#define mmACP_EXTERNAL_INTR_CNTL 0x5158
303#define mmACP_ERROR_SOURCE_STS 0x5159
304#define mmACP_DSP_SW_INTR_TRIG 0x515a
305#define mmACP_DSP_SW_INTR_CNTL 0x515b
306#define mmACP_DAGBG_TIMEOUT_CNTL 0x515c
307#define mmACP_DAGBO_TIMEOUT_CNTL 0x515d
308#define mmACP_EXTERNAL_INTR_STAT 0x515e
309#define mmACP_DSP_SW_INTR_STAT 0x515f
310#define mmACP_DSP0_INTR_CNTL 0x5160
311#define mmACP_DSP0_INTR_STAT 0x5161
312#define mmACP_DSP0_TIMEOUT_CNTL 0x5162
313#define mmACP_DSP1_INTR_CNTL 0x5163
314#define mmACP_DSP1_INTR_STAT 0x5164
315#define mmACP_DSP1_TIMEOUT_CNTL 0x5165
316#define mmACP_DSP2_INTR_CNTL 0x5166
317#define mmACP_DSP2_INTR_STAT 0x5167
318#define mmACP_DSP2_TIMEOUT_CNTL 0x5168
319#define mmACP_DSP0_EXT_TIMER_CNTL 0x5169
320#define mmACP_DSP1_EXT_TIMER_CNTL 0x516a
321#define mmACP_DSP2_EXT_TIMER_CNTL 0x516b
322#define mmACP_AXI2DAGB_SEM_0 0x516c
323#define mmACP_AXI2DAGB_SEM_1 0x516d
324#define mmACP_AXI2DAGB_SEM_2 0x516e
325#define mmACP_AXI2DAGB_SEM_3 0x516f
326#define mmACP_AXI2DAGB_SEM_4 0x5170
327#define mmACP_AXI2DAGB_SEM_5 0x5171
328#define mmACP_AXI2DAGB_SEM_6 0x5172
329#define mmACP_AXI2DAGB_SEM_7 0x5173
330#define mmACP_AXI2DAGB_SEM_8 0x5174
331#define mmACP_AXI2DAGB_SEM_9 0x5175
332#define mmACP_AXI2DAGB_SEM_10 0x5176
333#define mmACP_AXI2DAGB_SEM_11 0x5177
334#define mmACP_AXI2DAGB_SEM_12 0x5178
335#define mmACP_AXI2DAGB_SEM_13 0x5179
336#define mmACP_AXI2DAGB_SEM_14 0x517a
337#define mmACP_AXI2DAGB_SEM_15 0x517b
338#define mmACP_AXI2DAGB_SEM_16 0x517c
339#define mmACP_AXI2DAGB_SEM_17 0x517d
340#define mmACP_AXI2DAGB_SEM_18 0x517e
341#define mmACP_AXI2DAGB_SEM_19 0x517f
342#define mmACP_AXI2DAGB_SEM_20 0x5180
343#define mmACP_AXI2DAGB_SEM_21 0x5181
344#define mmACP_AXI2DAGB_SEM_22 0x5182
345#define mmACP_AXI2DAGB_SEM_23 0x5183
346#define mmACP_AXI2DAGB_SEM_24 0x5184
347#define mmACP_AXI2DAGB_SEM_25 0x5185
348#define mmACP_AXI2DAGB_SEM_26 0x5186
349#define mmACP_AXI2DAGB_SEM_27 0x5187
350#define mmACP_AXI2DAGB_SEM_28 0x5188
351#define mmACP_AXI2DAGB_SEM_29 0x5189
352#define mmACP_AXI2DAGB_SEM_30 0x518a
353#define mmACP_AXI2DAGB_SEM_31 0x518b
354#define mmACP_AXI2DAGB_SEM_32 0x518c
355#define mmACP_AXI2DAGB_SEM_33 0x518d
356#define mmACP_AXI2DAGB_SEM_34 0x518e
357#define mmACP_AXI2DAGB_SEM_35 0x518f
358#define mmACP_AXI2DAGB_SEM_36 0x5190
359#define mmACP_AXI2DAGB_SEM_37 0x5191
360#define mmACP_AXI2DAGB_SEM_38 0x5192
361#define mmACP_AXI2DAGB_SEM_39 0x5193
362#define mmACP_AXI2DAGB_SEM_40 0x5194
363#define mmACP_AXI2DAGB_SEM_41 0x5195
364#define mmACP_AXI2DAGB_SEM_42 0x5196
365#define mmACP_AXI2DAGB_SEM_43 0x5197
366#define mmACP_AXI2DAGB_SEM_44 0x5198
367#define mmACP_AXI2DAGB_SEM_45 0x5199
368#define mmACP_AXI2DAGB_SEM_46 0x519a
369#define mmACP_AXI2DAGB_SEM_47 0x519b
370#define mmACP_SRBM_Client_Base_Addr 0x519c
371#define mmACP_SRBM_Client_RDDATA 0x519d
372#define mmACP_SRBM_Cycle_Sts 0x519e
373#define mmACP_SRBM_Targ_Idx_Addr 0x519f
374#define mmACP_SRBM_Targ_Idx_Data 0x51a0
375#define mmACP_SEMA_ADDR_LOW 0x51a1
376#define mmACP_SEMA_ADDR_HIGH 0x51a2
377#define mmACP_SEMA_CMD 0x51a3
378#define mmACP_SEMA_STS 0x51a4
379#define mmACP_SEMA_REQ 0x51a5
380#define mmACP_FW_STATUS 0x51a6
381#define mmACP_FUTURE_REG_ACLK_0 0x51a7
382#define mmACP_FUTURE_REG_ACLK_1 0x51a8
383#define mmACP_FUTURE_REG_ACLK_2 0x51a9
384#define mmACP_FUTURE_REG_ACLK_3 0x51aa
385#define mmACP_FUTURE_REG_ACLK_4 0x51ab
386#define mmACP_TIMER 0x51ac
387#define mmACP_TIMER_CNTL 0x51ad
388#define mmACP_DSP0_TIMER 0x51ae
389#define mmACP_DSP1_TIMER 0x51af
390#define mmACP_DSP2_TIMER 0x51b0
391#define mmACP_I2S_TRANSMIT_BYTE_CNT_HIGH 0x51b1
392#define mmACP_I2S_TRANSMIT_BYTE_CNT_LOW 0x51b2
393#define mmACP_I2S_BT_TRANSMIT_BYTE_CNT_HIGH 0x51b3
394#define mmACP_I2S_BT_TRANSMIT_BYTE_CNT_LOW 0x51b4
395#define mmACP_I2S_BT_RECEIVE_BYTE_CNT_HIGH 0x51b5
396#define mmACP_I2S_BT_RECEIVE_BYTE_CNT_LOW 0x51b6
397#define mmACP_DSP0_CS_STATE 0x51b7
398#define mmACP_DSP1_CS_STATE 0x51b8
399#define mmACP_DSP2_CS_STATE 0x51b9
400#define mmACP_SCRATCH_REG_BASE_ADDR 0x51ba
401#define mmCC_ACP_EFUSE 0x51c8
402#define mmACP_PGFSM_RETAIN_REG 0x51c9
403#define mmACP_PGFSM_CONFIG_REG 0x51ca
404#define mmACP_PGFSM_WRITE_REG 0x51cb
405#define mmACP_PGFSM_READ_REG_0 0x51cc
406#define mmACP_PGFSM_READ_REG_1 0x51cd
407#define mmACP_PGFSM_READ_REG_2 0x51ce
408#define mmACP_PGFSM_READ_REG_3 0x51cf
409#define mmACP_PGFSM_READ_REG_4 0x51d0
410#define mmACP_PGFSM_READ_REG_5 0x51d1
411#define mmACP_IP_PGFSM_ENABLE 0x51d2
412#define mmACP_I2S_PIN_CONFIG 0x51d3
413#define mmACP_AZALIA_I2S_SELECT 0x51d4
414#define mmACP_CHIP_PKG_FOR_PAD_ISOLATION 0x51d5
415#define mmACP_AUDIO_PAD_PULLUP_PULLDOWN_CTRL 0x51d6
416#define mmACP_BT_UART_PAD_SEL 0x51d7
417#define mmACP_SCRATCH_REG_0 0x52c0
418#define mmACP_SCRATCH_REG_1 0x52c1
419#define mmACP_SCRATCH_REG_2 0x52c2
420#define mmACP_SCRATCH_REG_3 0x52c3
421#define mmACP_SCRATCH_REG_4 0x52c4
422#define mmACP_SCRATCH_REG_5 0x52c5
423#define mmACP_SCRATCH_REG_6 0x52c6
424#define mmACP_SCRATCH_REG_7 0x52c7
425#define mmACP_SCRATCH_REG_8 0x52c8
426#define mmACP_SCRATCH_REG_9 0x52c9
427#define mmACP_SCRATCH_REG_10 0x52ca
428#define mmACP_SCRATCH_REG_11 0x52cb
429#define mmACP_SCRATCH_REG_12 0x52cc
430#define mmACP_SCRATCH_REG_13 0x52cd
431#define mmACP_SCRATCH_REG_14 0x52ce
432#define mmACP_SCRATCH_REG_15 0x52cf
433#define mmACP_SCRATCH_REG_16 0x52d0
434#define mmACP_SCRATCH_REG_17 0x52d1
435#define mmACP_SCRATCH_REG_18 0x52d2
436#define mmACP_SCRATCH_REG_19 0x52d3
437#define mmACP_SCRATCH_REG_20 0x52d4
438#define mmACP_SCRATCH_REG_21 0x52d5
439#define mmACP_SCRATCH_REG_22 0x52d6
440#define mmACP_SCRATCH_REG_23 0x52d7
441#define mmACP_SCRATCH_REG_24 0x52d8
442#define mmACP_SCRATCH_REG_25 0x52d9
443#define mmACP_SCRATCH_REG_26 0x52da
444#define mmACP_SCRATCH_REG_27 0x52db
445#define mmACP_SCRATCH_REG_28 0x52dc
446#define mmACP_SCRATCH_REG_29 0x52dd
447#define mmACP_SCRATCH_REG_30 0x52de
448#define mmACP_SCRATCH_REG_31 0x52df
449#define mmACP_SCRATCH_REG_32 0x52e0
450#define mmACP_SCRATCH_REG_33 0x52e1
451#define mmACP_SCRATCH_REG_34 0x52e2
452#define mmACP_SCRATCH_REG_35 0x52e3
453#define mmACP_SCRATCH_REG_36 0x52e4
454#define mmACP_SCRATCH_REG_37 0x52e5
455#define mmACP_SCRATCH_REG_38 0x52e6
456#define mmACP_SCRATCH_REG_39 0x52e7
457#define mmACP_SCRATCH_REG_40 0x52e8
458#define mmACP_SCRATCH_REG_41 0x52e9
459#define mmACP_SCRATCH_REG_42 0x52ea
460#define mmACP_SCRATCH_REG_43 0x52eb
461#define mmACP_SCRATCH_REG_44 0x52ec
462#define mmACP_SCRATCH_REG_45 0x52ed
463#define mmACP_SCRATCH_REG_46 0x52ee
464#define mmACP_SCRATCH_REG_47 0x52ef
465#define mmACP_VOICE_WAKEUP_ENABLE 0x51e8
466#define mmACP_VOICE_WAKEUP_STATUS 0x51e9
467#define mmI2S_VOICE_WAKEUP_LOWER_THRESHOLD 0x51ea
468#define mmI2S_VOICE_WAKEUP_HIGHER_THRESHOLD 0x51eb
469#define mmI2S_VOICE_WAKEUP_NO_OF_SAMPLES 0x51ec
470#define mmI2S_VOICE_WAKEUP_NO_OF_PEAKS 0x51ed
471#define mmI2S_VOICE_WAKEUP_DURATION_OF_N_PEAKS 0x51ee
472#define mmI2S_VOICE_WAKEUP_BITCLK_TOGGLE_DETECTION 0x51ef
473#define mmI2S_VOICE_WAKEUP_DATA_PATH_SWITCH 0x51f0
474#define mmI2S_VOICE_WAKEUP_DATA_POINTER 0x51f1
475#define mmI2S_VOICE_WAKEUP_AUTH_MATCH 0x51f2
476#define mmI2S_VOICE_WAKEUP_8KB_WRAP 0x51f3
477#define mmACP_I2S_RECEIVED_BYTE_CNT_HIGH 0x51f4
478#define mmACP_I2S_RECEIVED_BYTE_CNT_LOW 0x51f5
479#define mmACP_I2S_MICSP_TRANSMIT_BYTE_CNT_HIGH 0x51f6
480#define mmACP_I2S_MICSP_TRANSMIT_BYTE_CNT_LOW 0x51f7
481#define mmACP_MEM_SHUT_DOWN_REQ_LO 0x51f8
482#define mmACP_MEM_SHUT_DOWN_REQ_HI 0x51f9
483#define mmACP_MEM_SHUT_DOWN_STS_LO 0x51fa
484#define mmACP_MEM_SHUT_DOWN_STS_HI 0x51fb
485#define mmACP_MEM_DEEP_SLEEP_REQ_LO 0x51fc
486#define mmACP_MEM_DEEP_SLEEP_REQ_HI 0x51fd
487#define mmACP_MEM_DEEP_SLEEP_STS_LO 0x51fe
488#define mmACP_MEM_DEEP_SLEEP_STS_HI 0x51ff
489#define mmACP_MEM_WAKEUP_FROM_SHUT_DOWN_LO 0x5200
490#define mmACP_MEM_WAKEUP_FROM_SHUT_DOWN_HI 0x5201
491#define mmACP_MEM_WAKEUP_FROM_SLEEP_LO 0x5202
492#define mmACP_MEM_WAKEUP_FROM_SLEEP_HI 0x5203
493#define mmACP_I2SSP_IER 0x5210
494#define mmACP_I2SSP_IRER 0x5211
495#define mmACP_I2SSP_ITER 0x5212
496#define mmACP_I2SSP_CER 0x5213
497#define mmACP_I2SSP_CCR 0x5214
498#define mmACP_I2SSP_RXFFR 0x5215
499#define mmACP_I2SSP_TXFFR 0x5216
500#define mmACP_I2SSP_LRBR0 0x5218
501#define mmACP_I2SSP_RRBR0 0x5219
502#define mmACP_I2SSP_RER0 0x521a
503#define mmACP_I2SSP_TER0 0x521b
504#define mmACP_I2SSP_RCR0 0x521c
505#define mmACP_I2SSP_TCR0 0x521d
506#define mmACP_I2SSP_ISR0 0x521e
507#define mmACP_I2SSP_IMR0 0x521f
508#define mmACP_I2SSP_ROR0 0x5220
509#define mmACP_I2SSP_TOR0 0x5221
510#define mmACP_I2SSP_RFCR0 0x5222
511#define mmACP_I2SSP_TFCR0 0x5223
512#define mmACP_I2SSP_RFF0 0x5224
513#define mmACP_I2SSP_TFF0 0x5225
514#define mmACP_I2SSP_RXDMA 0x5226
515#define mmACP_I2SSP_RRXDMA 0x5227
516#define mmACP_I2SSP_TXDMA 0x5228
517#define mmACP_I2SSP_RTXDMA 0x5229
518#define mmACP_I2SSP_COMP_PARAM_2 0x522a
519#define mmACP_I2SSP_COMP_PARAM_1 0x522b
520#define mmACP_I2SSP_COMP_VERSION 0x522c
521#define mmACP_I2SSP_COMP_TYPE 0x522d
522#define mmACP_I2SMICSP_IER 0x522e
523#define mmACP_I2SMICSP_IRER 0x522f
524#define mmACP_I2SMICSP_ITER 0x5230
525#define mmACP_I2SMICSP_CER 0x5231
526#define mmACP_I2SMICSP_CCR 0x5232
527#define mmACP_I2SMICSP_RXFFR 0x5233
528#define mmACP_I2SMICSP_TXFFR 0x5234
529#define mmACP_I2SMICSP_LRBR0 0x5236
530#define mmACP_I2SMICSP_RRBR0 0x5237
531#define mmACP_I2SMICSP_RER0 0x5238
532#define mmACP_I2SMICSP_TER0 0x5239
533#define mmACP_I2SMICSP_RCR0 0x523a
534#define mmACP_I2SMICSP_TCR0 0x523b
535#define mmACP_I2SMICSP_ISR0 0x523c
536#define mmACP_I2SMICSP_IMR0 0x523d
537#define mmACP_I2SMICSP_ROR0 0x523e
538#define mmACP_I2SMICSP_TOR0 0x523f
539#define mmACP_I2SMICSP_RFCR0 0x5240
540#define mmACP_I2SMICSP_TFCR0 0x5241
541#define mmACP_I2SMICSP_RFF0 0x5242
542#define mmACP_I2SMICSP_TFF0 0x5243
543#define mmACP_I2SMICSP_LRBR1 0x5246
544#define mmACP_I2SMICSP_RRBR1 0x5247
545#define mmACP_I2SMICSP_RER1 0x5248
546#define mmACP_I2SMICSP_TER1 0x5249
547#define mmACP_I2SMICSP_RCR1 0x524a
548#define mmACP_I2SMICSP_TCR1 0x524b
549#define mmACP_I2SMICSP_ISR1 0x524c
550#define mmACP_I2SMICSP_IMR1 0x524d
551#define mmACP_I2SMICSP_ROR1 0x524e
552#define mmACP_I2SMICSP_TOR1 0x524f
553#define mmACP_I2SMICSP_RFCR1 0x5250
554#define mmACP_I2SMICSP_TFCR1 0x5251
555#define mmACP_I2SMICSP_RFF1 0x5252
556#define mmACP_I2SMICSP_TFF1 0x5253
557#define mmACP_I2SMICSP_RXDMA 0x5254
558#define mmACP_I2SMICSP_RRXDMA 0x5255
559#define mmACP_I2SMICSP_TXDMA 0x5256
560#define mmACP_I2SMICSP_RTXDMA 0x5257
561#define mmACP_I2SMICSP_COMP_PARAM_2 0x5258
562#define mmACP_I2SMICSP_COMP_PARAM_1 0x5259
563#define mmACP_I2SMICSP_COMP_VERSION 0x525a
564#define mmACP_I2SMICSP_COMP_TYPE 0x525b
565#define mmACP_I2SBT_IER 0x525c
566#define mmACP_I2SBT_IRER 0x525d
567#define mmACP_I2SBT_ITER 0x525e
568#define mmACP_I2SBT_CER 0x525f
569#define mmACP_I2SBT_CCR 0x5260
570#define mmACP_I2SBT_RXFFR 0x5261
571#define mmACP_I2SBT_TXFFR 0x5262
572#define mmACP_I2SBT_LRBR0 0x5264
573#define mmACP_I2SBT_RRBR0 0x5265
574#define mmACP_I2SBT_RER0 0x5266
575#define mmACP_I2SBT_TER0 0x5267
576#define mmACP_I2SBT_RCR0 0x5268
577#define mmACP_I2SBT_TCR0 0x5269
578#define mmACP_I2SBT_ISR0 0x526a
579#define mmACP_I2SBT_IMR0 0x526b
580#define mmACP_I2SBT_ROR0 0x526c
581#define mmACP_I2SBT_TOR0 0x526d
582#define mmACP_I2SBT_RFCR0 0x526e
583#define mmACP_I2SBT_TFCR0 0x526f
584#define mmACP_I2SBT_RFF0 0x5270
585#define mmACP_I2SBT_TFF0 0x5271
586#define mmACP_I2SBT_LRBR1 0x5274
587#define mmACP_I2SBT_RRBR1 0x5275
588#define mmACP_I2SBT_RER1 0x5276
589#define mmACP_I2SBT_TER1 0x5277
590#define mmACP_I2SBT_RCR1 0x5278
591#define mmACP_I2SBT_TCR1 0x5279
592#define mmACP_I2SBT_ISR1 0x527a
593#define mmACP_I2SBT_IMR1 0x527b
594#define mmACP_I2SBT_ROR1 0x527c
595#define mmACP_I2SBT_TOR1 0x527d
596#define mmACP_I2SBT_RFCR1 0x527e
597#define mmACP_I2SBT_TFCR1 0x527f
598#define mmACP_I2SBT_RFF1 0x5280
599#define mmACP_I2SBT_TFF1 0x5281
600#define mmACP_I2SBT_RXDMA 0x5282
601#define mmACP_I2SBT_RRXDMA 0x5283
602#define mmACP_I2SBT_TXDMA 0x5284
603#define mmACP_I2SBT_RTXDMA 0x5285
604#define mmACP_I2SBT_COMP_PARAM_2 0x5286
605#define mmACP_I2SBT_COMP_PARAM_1 0x5287
606#define mmACP_I2SBT_COMP_VERSION 0x5288
607#define mmACP_I2SBT_COMP_TYPE 0x5289
608
609#endif /* ACP_2_2_D_H */
diff --git a/sound/soc/amd/include/acp_2_2_enum.h b/sound/soc/amd/include/acp_2_2_enum.h
new file mode 100644
index 000000000000..f3577c851086
--- /dev/null
+++ b/sound/soc/amd/include/acp_2_2_enum.h
@@ -0,0 +1,1068 @@
1/*
2 * ACP_2_2 Register documentation
3 *
4 * Copyright (C) 2014 Advanced Micro Devices, Inc.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the "Software"),
8 * to deal in the Software without restriction, including without limitation
9 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 * and/or sell copies of the Software, and to permit persons to whom the
11 * Software is furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included
14 * in all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
17 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE COPYRIGHT HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
20 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 */
23
24#ifndef ACP_2_2_ENUM_H
25#define ACP_2_2_ENUM_H
26
27typedef enum DebugBlockId {
28 DBG_BLOCK_ID_RESERVED = 0x0,
29 DBG_BLOCK_ID_DBG = 0x1,
30 DBG_BLOCK_ID_VMC = 0x2,
31 DBG_BLOCK_ID_PDMA = 0x3,
32 DBG_BLOCK_ID_CG = 0x4,
33 DBG_BLOCK_ID_SRBM = 0x5,
34 DBG_BLOCK_ID_GRBM = 0x6,
35 DBG_BLOCK_ID_RLC = 0x7,
36 DBG_BLOCK_ID_CSC = 0x8,
37 DBG_BLOCK_ID_SEM = 0x9,
38 DBG_BLOCK_ID_IH = 0xa,
39 DBG_BLOCK_ID_SC = 0xb,
40 DBG_BLOCK_ID_SQ = 0xc,
41 DBG_BLOCK_ID_UVDU = 0xd,
42 DBG_BLOCK_ID_SQA = 0xe,
43 DBG_BLOCK_ID_SDMA0 = 0xf,
44 DBG_BLOCK_ID_SDMA1 = 0x10,
45 DBG_BLOCK_ID_SPIM = 0x11,
46 DBG_BLOCK_ID_GDS = 0x12,
47 DBG_BLOCK_ID_VC0 = 0x13,
48 DBG_BLOCK_ID_VC1 = 0x14,
49 DBG_BLOCK_ID_PA0 = 0x15,
50 DBG_BLOCK_ID_PA1 = 0x16,
51 DBG_BLOCK_ID_CP0 = 0x17,
52 DBG_BLOCK_ID_CP1 = 0x18,
53 DBG_BLOCK_ID_CP2 = 0x19,
54 DBG_BLOCK_ID_XBR = 0x1a,
55 DBG_BLOCK_ID_UVDM = 0x1b,
56 DBG_BLOCK_ID_VGT0 = 0x1c,
57 DBG_BLOCK_ID_VGT1 = 0x1d,
58 DBG_BLOCK_ID_IA = 0x1e,
59 DBG_BLOCK_ID_SXM0 = 0x1f,
60 DBG_BLOCK_ID_SXM1 = 0x20,
61 DBG_BLOCK_ID_SCT0 = 0x21,
62 DBG_BLOCK_ID_SCT1 = 0x22,
63 DBG_BLOCK_ID_SPM0 = 0x23,
64 DBG_BLOCK_ID_SPM1 = 0x24,
65 DBG_BLOCK_ID_UNUSED0 = 0x25,
66 DBG_BLOCK_ID_UNUSED1 = 0x26,
67 DBG_BLOCK_ID_TCAA = 0x27,
68 DBG_BLOCK_ID_TCAB = 0x28,
69 DBG_BLOCK_ID_TCCA = 0x29,
70 DBG_BLOCK_ID_TCCB = 0x2a,
71 DBG_BLOCK_ID_MCC0 = 0x2b,
72 DBG_BLOCK_ID_MCC1 = 0x2c,
73 DBG_BLOCK_ID_MCC2 = 0x2d,
74 DBG_BLOCK_ID_MCC3 = 0x2e,
75 DBG_BLOCK_ID_SXS0 = 0x2f,
76 DBG_BLOCK_ID_SXS1 = 0x30,
77 DBG_BLOCK_ID_SXS2 = 0x31,
78 DBG_BLOCK_ID_SXS3 = 0x32,
79 DBG_BLOCK_ID_SXS4 = 0x33,
80 DBG_BLOCK_ID_SXS5 = 0x34,
81 DBG_BLOCK_ID_SXS6 = 0x35,
82 DBG_BLOCK_ID_SXS7 = 0x36,
83 DBG_BLOCK_ID_SXS8 = 0x37,
84 DBG_BLOCK_ID_SXS9 = 0x38,
85 DBG_BLOCK_ID_BCI0 = 0x39,
86 DBG_BLOCK_ID_BCI1 = 0x3a,
87 DBG_BLOCK_ID_BCI2 = 0x3b,
88 DBG_BLOCK_ID_BCI3 = 0x3c,
89 DBG_BLOCK_ID_MCB = 0x3d,
90 DBG_BLOCK_ID_UNUSED6 = 0x3e,
91 DBG_BLOCK_ID_SQA00 = 0x3f,
92 DBG_BLOCK_ID_SQA01 = 0x40,
93 DBG_BLOCK_ID_SQA02 = 0x41,
94 DBG_BLOCK_ID_SQA10 = 0x42,
95 DBG_BLOCK_ID_SQA11 = 0x43,
96 DBG_BLOCK_ID_SQA12 = 0x44,
97 DBG_BLOCK_ID_UNUSED7 = 0x45,
98 DBG_BLOCK_ID_UNUSED8 = 0x46,
99 DBG_BLOCK_ID_SQB00 = 0x47,
100 DBG_BLOCK_ID_SQB01 = 0x48,
101 DBG_BLOCK_ID_SQB10 = 0x49,
102 DBG_BLOCK_ID_SQB11 = 0x4a,
103 DBG_BLOCK_ID_SQ00 = 0x4b,
104 DBG_BLOCK_ID_SQ01 = 0x4c,
105 DBG_BLOCK_ID_SQ10 = 0x4d,
106 DBG_BLOCK_ID_SQ11 = 0x4e,
107 DBG_BLOCK_ID_CB00 = 0x4f,
108 DBG_BLOCK_ID_CB01 = 0x50,
109 DBG_BLOCK_ID_CB02 = 0x51,
110 DBG_BLOCK_ID_CB03 = 0x52,
111 DBG_BLOCK_ID_CB04 = 0x53,
112 DBG_BLOCK_ID_UNUSED9 = 0x54,
113 DBG_BLOCK_ID_UNUSED10 = 0x55,
114 DBG_BLOCK_ID_UNUSED11 = 0x56,
115 DBG_BLOCK_ID_CB10 = 0x57,
116 DBG_BLOCK_ID_CB11 = 0x58,
117 DBG_BLOCK_ID_CB12 = 0x59,
118 DBG_BLOCK_ID_CB13 = 0x5a,
119 DBG_BLOCK_ID_CB14 = 0x5b,
120 DBG_BLOCK_ID_UNUSED12 = 0x5c,
121 DBG_BLOCK_ID_UNUSED13 = 0x5d,
122 DBG_BLOCK_ID_UNUSED14 = 0x5e,
123 DBG_BLOCK_ID_TCP0 = 0x5f,
124 DBG_BLOCK_ID_TCP1 = 0x60,
125 DBG_BLOCK_ID_TCP2 = 0x61,
126 DBG_BLOCK_ID_TCP3 = 0x62,
127 DBG_BLOCK_ID_TCP4 = 0x63,
128 DBG_BLOCK_ID_TCP5 = 0x64,
129 DBG_BLOCK_ID_TCP6 = 0x65,
130 DBG_BLOCK_ID_TCP7 = 0x66,
131 DBG_BLOCK_ID_TCP8 = 0x67,
132 DBG_BLOCK_ID_TCP9 = 0x68,
133 DBG_BLOCK_ID_TCP10 = 0x69,
134 DBG_BLOCK_ID_TCP11 = 0x6a,
135 DBG_BLOCK_ID_TCP12 = 0x6b,
136 DBG_BLOCK_ID_TCP13 = 0x6c,
137 DBG_BLOCK_ID_TCP14 = 0x6d,
138 DBG_BLOCK_ID_TCP15 = 0x6e,
139 DBG_BLOCK_ID_TCP16 = 0x6f,
140 DBG_BLOCK_ID_TCP17 = 0x70,
141 DBG_BLOCK_ID_TCP18 = 0x71,
142 DBG_BLOCK_ID_TCP19 = 0x72,
143 DBG_BLOCK_ID_TCP20 = 0x73,
144 DBG_BLOCK_ID_TCP21 = 0x74,
145 DBG_BLOCK_ID_TCP22 = 0x75,
146 DBG_BLOCK_ID_TCP23 = 0x76,
147 DBG_BLOCK_ID_TCP_RESERVED0 = 0x77,
148 DBG_BLOCK_ID_TCP_RESERVED1 = 0x78,
149 DBG_BLOCK_ID_TCP_RESERVED2 = 0x79,
150 DBG_BLOCK_ID_TCP_RESERVED3 = 0x7a,
151 DBG_BLOCK_ID_TCP_RESERVED4 = 0x7b,
152 DBG_BLOCK_ID_TCP_RESERVED5 = 0x7c,
153 DBG_BLOCK_ID_TCP_RESERVED6 = 0x7d,
154 DBG_BLOCK_ID_TCP_RESERVED7 = 0x7e,
155 DBG_BLOCK_ID_DB00 = 0x7f,
156 DBG_BLOCK_ID_DB01 = 0x80,
157 DBG_BLOCK_ID_DB02 = 0x81,
158 DBG_BLOCK_ID_DB03 = 0x82,
159 DBG_BLOCK_ID_DB04 = 0x83,
160 DBG_BLOCK_ID_UNUSED15 = 0x84,
161 DBG_BLOCK_ID_UNUSED16 = 0x85,
162 DBG_BLOCK_ID_UNUSED17 = 0x86,
163 DBG_BLOCK_ID_DB10 = 0x87,
164 DBG_BLOCK_ID_DB11 = 0x88,
165 DBG_BLOCK_ID_DB12 = 0x89,
166 DBG_BLOCK_ID_DB13 = 0x8a,
167 DBG_BLOCK_ID_DB14 = 0x8b,
168 DBG_BLOCK_ID_UNUSED18 = 0x8c,
169 DBG_BLOCK_ID_UNUSED19 = 0x8d,
170 DBG_BLOCK_ID_UNUSED20 = 0x8e,
171 DBG_BLOCK_ID_TCC0 = 0x8f,
172 DBG_BLOCK_ID_TCC1 = 0x90,
173 DBG_BLOCK_ID_TCC2 = 0x91,
174 DBG_BLOCK_ID_TCC3 = 0x92,
175 DBG_BLOCK_ID_TCC4 = 0x93,
176 DBG_BLOCK_ID_TCC5 = 0x94,
177 DBG_BLOCK_ID_TCC6 = 0x95,
178 DBG_BLOCK_ID_TCC7 = 0x96,
179 DBG_BLOCK_ID_SPS00 = 0x97,
180 DBG_BLOCK_ID_SPS01 = 0x98,
181 DBG_BLOCK_ID_SPS02 = 0x99,
182 DBG_BLOCK_ID_SPS10 = 0x9a,
183 DBG_BLOCK_ID_SPS11 = 0x9b,
184 DBG_BLOCK_ID_SPS12 = 0x9c,
185 DBG_BLOCK_ID_UNUSED21 = 0x9d,
186 DBG_BLOCK_ID_UNUSED22 = 0x9e,
187 DBG_BLOCK_ID_TA00 = 0x9f,
188 DBG_BLOCK_ID_TA01 = 0xa0,
189 DBG_BLOCK_ID_TA02 = 0xa1,
190 DBG_BLOCK_ID_TA03 = 0xa2,
191 DBG_BLOCK_ID_TA04 = 0xa3,
192 DBG_BLOCK_ID_TA05 = 0xa4,
193 DBG_BLOCK_ID_TA06 = 0xa5,
194 DBG_BLOCK_ID_TA07 = 0xa6,
195 DBG_BLOCK_ID_TA08 = 0xa7,
196 DBG_BLOCK_ID_TA09 = 0xa8,
197 DBG_BLOCK_ID_TA0A = 0xa9,
198 DBG_BLOCK_ID_TA0B = 0xaa,
199 DBG_BLOCK_ID_UNUSED23 = 0xab,
200 DBG_BLOCK_ID_UNUSED24 = 0xac,
201 DBG_BLOCK_ID_UNUSED25 = 0xad,
202 DBG_BLOCK_ID_UNUSED26 = 0xae,
203 DBG_BLOCK_ID_TA10 = 0xaf,
204 DBG_BLOCK_ID_TA11 = 0xb0,
205 DBG_BLOCK_ID_TA12 = 0xb1,
206 DBG_BLOCK_ID_TA13 = 0xb2,
207 DBG_BLOCK_ID_TA14 = 0xb3,
208 DBG_BLOCK_ID_TA15 = 0xb4,
209 DBG_BLOCK_ID_TA16 = 0xb5,
210 DBG_BLOCK_ID_TA17 = 0xb6,
211 DBG_BLOCK_ID_TA18 = 0xb7,
212 DBG_BLOCK_ID_TA19 = 0xb8,
213 DBG_BLOCK_ID_TA1A = 0xb9,
214 DBG_BLOCK_ID_TA1B = 0xba,
215 DBG_BLOCK_ID_UNUSED27 = 0xbb,
216 DBG_BLOCK_ID_UNUSED28 = 0xbc,
217 DBG_BLOCK_ID_UNUSED29 = 0xbd,
218 DBG_BLOCK_ID_UNUSED30 = 0xbe,
219 DBG_BLOCK_ID_TD00 = 0xbf,
220 DBG_BLOCK_ID_TD01 = 0xc0,
221 DBG_BLOCK_ID_TD02 = 0xc1,
222 DBG_BLOCK_ID_TD03 = 0xc2,
223 DBG_BLOCK_ID_TD04 = 0xc3,
224 DBG_BLOCK_ID_TD05 = 0xc4,
225 DBG_BLOCK_ID_TD06 = 0xc5,
226 DBG_BLOCK_ID_TD07 = 0xc6,
227 DBG_BLOCK_ID_TD08 = 0xc7,
228 DBG_BLOCK_ID_TD09 = 0xc8,
229 DBG_BLOCK_ID_TD0A = 0xc9,
230 DBG_BLOCK_ID_TD0B = 0xca,
231 DBG_BLOCK_ID_UNUSED31 = 0xcb,
232 DBG_BLOCK_ID_UNUSED32 = 0xcc,
233 DBG_BLOCK_ID_UNUSED33 = 0xcd,
234 DBG_BLOCK_ID_UNUSED34 = 0xce,
235 DBG_BLOCK_ID_TD10 = 0xcf,
236 DBG_BLOCK_ID_TD11 = 0xd0,
237 DBG_BLOCK_ID_TD12 = 0xd1,
238 DBG_BLOCK_ID_TD13 = 0xd2,
239 DBG_BLOCK_ID_TD14 = 0xd3,
240 DBG_BLOCK_ID_TD15 = 0xd4,
241 DBG_BLOCK_ID_TD16 = 0xd5,
242 DBG_BLOCK_ID_TD17 = 0xd6,
243 DBG_BLOCK_ID_TD18 = 0xd7,
244 DBG_BLOCK_ID_TD19 = 0xd8,
245 DBG_BLOCK_ID_TD1A = 0xd9,
246 DBG_BLOCK_ID_TD1B = 0xda,
247 DBG_BLOCK_ID_UNUSED35 = 0xdb,
248 DBG_BLOCK_ID_UNUSED36 = 0xdc,
249 DBG_BLOCK_ID_UNUSED37 = 0xdd,
250 DBG_BLOCK_ID_UNUSED38 = 0xde,
251 DBG_BLOCK_ID_LDS00 = 0xdf,
252 DBG_BLOCK_ID_LDS01 = 0xe0,
253 DBG_BLOCK_ID_LDS02 = 0xe1,
254 DBG_BLOCK_ID_LDS03 = 0xe2,
255 DBG_BLOCK_ID_LDS04 = 0xe3,
256 DBG_BLOCK_ID_LDS05 = 0xe4,
257 DBG_BLOCK_ID_LDS06 = 0xe5,
258 DBG_BLOCK_ID_LDS07 = 0xe6,
259 DBG_BLOCK_ID_LDS08 = 0xe7,
260 DBG_BLOCK_ID_LDS09 = 0xe8,
261 DBG_BLOCK_ID_LDS0A = 0xe9,
262 DBG_BLOCK_ID_LDS0B = 0xea,
263 DBG_BLOCK_ID_UNUSED39 = 0xeb,
264 DBG_BLOCK_ID_UNUSED40 = 0xec,
265 DBG_BLOCK_ID_UNUSED41 = 0xed,
266 DBG_BLOCK_ID_UNUSED42 = 0xee,
267 DBG_BLOCK_ID_LDS10 = 0xef,
268 DBG_BLOCK_ID_LDS11 = 0xf0,
269 DBG_BLOCK_ID_LDS12 = 0xf1,
270 DBG_BLOCK_ID_LDS13 = 0xf2,
271 DBG_BLOCK_ID_LDS14 = 0xf3,
272 DBG_BLOCK_ID_LDS15 = 0xf4,
273 DBG_BLOCK_ID_LDS16 = 0xf5,
274 DBG_BLOCK_ID_LDS17 = 0xf6,
275 DBG_BLOCK_ID_LDS18 = 0xf7,
276 DBG_BLOCK_ID_LDS19 = 0xf8,
277 DBG_BLOCK_ID_LDS1A = 0xf9,
278 DBG_BLOCK_ID_LDS1B = 0xfa,
279 DBG_BLOCK_ID_UNUSED43 = 0xfb,
280 DBG_BLOCK_ID_UNUSED44 = 0xfc,
281 DBG_BLOCK_ID_UNUSED45 = 0xfd,
282 DBG_BLOCK_ID_UNUSED46 = 0xfe,
283} DebugBlockId;
284typedef enum DebugBlockId_BY2 {
285 DBG_BLOCK_ID_RESERVED_BY2 = 0x0,
286 DBG_BLOCK_ID_VMC_BY2 = 0x1,
287 DBG_BLOCK_ID_UNUSED0_BY2 = 0x2,
288 DBG_BLOCK_ID_GRBM_BY2 = 0x3,
289 DBG_BLOCK_ID_CSC_BY2 = 0x4,
290 DBG_BLOCK_ID_IH_BY2 = 0x5,
291 DBG_BLOCK_ID_SQ_BY2 = 0x6,
292 DBG_BLOCK_ID_UVD_BY2 = 0x7,
293 DBG_BLOCK_ID_SDMA0_BY2 = 0x8,
294 DBG_BLOCK_ID_SPIM_BY2 = 0x9,
295 DBG_BLOCK_ID_VC0_BY2 = 0xa,
296 DBG_BLOCK_ID_PA_BY2 = 0xb,
297 DBG_BLOCK_ID_CP0_BY2 = 0xc,
298 DBG_BLOCK_ID_CP2_BY2 = 0xd,
299 DBG_BLOCK_ID_PC0_BY2 = 0xe,
300 DBG_BLOCK_ID_BCI0_BY2 = 0xf,
301 DBG_BLOCK_ID_SXM0_BY2 = 0x10,
302 DBG_BLOCK_ID_SCT0_BY2 = 0x11,
303 DBG_BLOCK_ID_SPM0_BY2 = 0x12,
304 DBG_BLOCK_ID_BCI2_BY2 = 0x13,
305 DBG_BLOCK_ID_TCA_BY2 = 0x14,
306 DBG_BLOCK_ID_TCCA_BY2 = 0x15,
307 DBG_BLOCK_ID_MCC_BY2 = 0x16,
308 DBG_BLOCK_ID_MCC2_BY2 = 0x17,
309 DBG_BLOCK_ID_MCD_BY2 = 0x18,
310 DBG_BLOCK_ID_MCD2_BY2 = 0x19,
311 DBG_BLOCK_ID_MCD4_BY2 = 0x1a,
312 DBG_BLOCK_ID_MCB_BY2 = 0x1b,
313 DBG_BLOCK_ID_SQA_BY2 = 0x1c,
314 DBG_BLOCK_ID_SQA02_BY2 = 0x1d,
315 DBG_BLOCK_ID_SQA11_BY2 = 0x1e,
316 DBG_BLOCK_ID_UNUSED8_BY2 = 0x1f,
317 DBG_BLOCK_ID_SQB_BY2 = 0x20,
318 DBG_BLOCK_ID_SQB10_BY2 = 0x21,
319 DBG_BLOCK_ID_UNUSED10_BY2 = 0x22,
320 DBG_BLOCK_ID_UNUSED12_BY2 = 0x23,
321 DBG_BLOCK_ID_CB_BY2 = 0x24,
322 DBG_BLOCK_ID_CB02_BY2 = 0x25,
323 DBG_BLOCK_ID_CB10_BY2 = 0x26,
324 DBG_BLOCK_ID_CB12_BY2 = 0x27,
325 DBG_BLOCK_ID_SXS_BY2 = 0x28,
326 DBG_BLOCK_ID_SXS2_BY2 = 0x29,
327 DBG_BLOCK_ID_SXS4_BY2 = 0x2a,
328 DBG_BLOCK_ID_SXS6_BY2 = 0x2b,
329 DBG_BLOCK_ID_DB_BY2 = 0x2c,
330 DBG_BLOCK_ID_DB02_BY2 = 0x2d,
331 DBG_BLOCK_ID_DB10_BY2 = 0x2e,
332 DBG_BLOCK_ID_DB12_BY2 = 0x2f,
333 DBG_BLOCK_ID_TCP_BY2 = 0x30,
334 DBG_BLOCK_ID_TCP2_BY2 = 0x31,
335 DBG_BLOCK_ID_TCP4_BY2 = 0x32,
336 DBG_BLOCK_ID_TCP6_BY2 = 0x33,
337 DBG_BLOCK_ID_TCP8_BY2 = 0x34,
338 DBG_BLOCK_ID_TCP10_BY2 = 0x35,
339 DBG_BLOCK_ID_TCP12_BY2 = 0x36,
340 DBG_BLOCK_ID_TCP14_BY2 = 0x37,
341 DBG_BLOCK_ID_TCP16_BY2 = 0x38,
342 DBG_BLOCK_ID_TCP18_BY2 = 0x39,
343 DBG_BLOCK_ID_TCP20_BY2 = 0x3a,
344 DBG_BLOCK_ID_TCP22_BY2 = 0x3b,
345 DBG_BLOCK_ID_TCP_RESERVED0_BY2 = 0x3c,
346 DBG_BLOCK_ID_TCP_RESERVED2_BY2 = 0x3d,
347 DBG_BLOCK_ID_TCP_RESERVED4_BY2 = 0x3e,
348 DBG_BLOCK_ID_TCP_RESERVED6_BY2 = 0x3f,
349 DBG_BLOCK_ID_TCC_BY2 = 0x40,
350 DBG_BLOCK_ID_TCC2_BY2 = 0x41,
351 DBG_BLOCK_ID_TCC4_BY2 = 0x42,
352 DBG_BLOCK_ID_TCC6_BY2 = 0x43,
353 DBG_BLOCK_ID_SPS_BY2 = 0x44,
354 DBG_BLOCK_ID_SPS02_BY2 = 0x45,
355 DBG_BLOCK_ID_SPS11_BY2 = 0x46,
356 DBG_BLOCK_ID_UNUSED14_BY2 = 0x47,
357 DBG_BLOCK_ID_TA_BY2 = 0x48,
358 DBG_BLOCK_ID_TA02_BY2 = 0x49,
359 DBG_BLOCK_ID_TA04_BY2 = 0x4a,
360 DBG_BLOCK_ID_TA06_BY2 = 0x4b,
361 DBG_BLOCK_ID_TA08_BY2 = 0x4c,
362 DBG_BLOCK_ID_TA0A_BY2 = 0x4d,
363 DBG_BLOCK_ID_UNUSED20_BY2 = 0x4e,
364 DBG_BLOCK_ID_UNUSED22_BY2 = 0x4f,
365 DBG_BLOCK_ID_TA10_BY2 = 0x50,
366 DBG_BLOCK_ID_TA12_BY2 = 0x51,
367 DBG_BLOCK_ID_TA14_BY2 = 0x52,
368 DBG_BLOCK_ID_TA16_BY2 = 0x53,
369 DBG_BLOCK_ID_TA18_BY2 = 0x54,
370 DBG_BLOCK_ID_TA1A_BY2 = 0x55,
371 DBG_BLOCK_ID_UNUSED24_BY2 = 0x56,
372 DBG_BLOCK_ID_UNUSED26_BY2 = 0x57,
373 DBG_BLOCK_ID_TD_BY2 = 0x58,
374 DBG_BLOCK_ID_TD02_BY2 = 0x59,
375 DBG_BLOCK_ID_TD04_BY2 = 0x5a,
376 DBG_BLOCK_ID_TD06_BY2 = 0x5b,
377 DBG_BLOCK_ID_TD08_BY2 = 0x5c,
378 DBG_BLOCK_ID_TD0A_BY2 = 0x5d,
379 DBG_BLOCK_ID_UNUSED28_BY2 = 0x5e,
380 DBG_BLOCK_ID_UNUSED30_BY2 = 0x5f,
381 DBG_BLOCK_ID_TD10_BY2 = 0x60,
382 DBG_BLOCK_ID_TD12_BY2 = 0x61,
383 DBG_BLOCK_ID_TD14_BY2 = 0x62,
384 DBG_BLOCK_ID_TD16_BY2 = 0x63,
385 DBG_BLOCK_ID_TD18_BY2 = 0x64,
386 DBG_BLOCK_ID_TD1A_BY2 = 0x65,
387 DBG_BLOCK_ID_UNUSED32_BY2 = 0x66,
388 DBG_BLOCK_ID_UNUSED34_BY2 = 0x67,
389 DBG_BLOCK_ID_LDS_BY2 = 0x68,
390 DBG_BLOCK_ID_LDS02_BY2 = 0x69,
391 DBG_BLOCK_ID_LDS04_BY2 = 0x6a,
392 DBG_BLOCK_ID_LDS06_BY2 = 0x6b,
393 DBG_BLOCK_ID_LDS08_BY2 = 0x6c,
394 DBG_BLOCK_ID_LDS0A_BY2 = 0x6d,
395 DBG_BLOCK_ID_UNUSED36_BY2 = 0x6e,
396 DBG_BLOCK_ID_UNUSED38_BY2 = 0x6f,
397 DBG_BLOCK_ID_LDS10_BY2 = 0x70,
398 DBG_BLOCK_ID_LDS12_BY2 = 0x71,
399 DBG_BLOCK_ID_LDS14_BY2 = 0x72,
400 DBG_BLOCK_ID_LDS16_BY2 = 0x73,
401 DBG_BLOCK_ID_LDS18_BY2 = 0x74,
402 DBG_BLOCK_ID_LDS1A_BY2 = 0x75,
403 DBG_BLOCK_ID_UNUSED40_BY2 = 0x76,
404 DBG_BLOCK_ID_UNUSED42_BY2 = 0x77,
405} DebugBlockId_BY2;
406typedef enum DebugBlockId_BY4 {
407 DBG_BLOCK_ID_RESERVED_BY4 = 0x0,
408 DBG_BLOCK_ID_UNUSED0_BY4 = 0x1,
409 DBG_BLOCK_ID_CSC_BY4 = 0x2,
410 DBG_BLOCK_ID_SQ_BY4 = 0x3,
411 DBG_BLOCK_ID_SDMA0_BY4 = 0x4,
412 DBG_BLOCK_ID_VC0_BY4 = 0x5,
413 DBG_BLOCK_ID_CP0_BY4 = 0x6,
414 DBG_BLOCK_ID_UNUSED1_BY4 = 0x7,
415 DBG_BLOCK_ID_SXM0_BY4 = 0x8,
416 DBG_BLOCK_ID_SPM0_BY4 = 0x9,
417 DBG_BLOCK_ID_TCAA_BY4 = 0xa,
418 DBG_BLOCK_ID_MCC_BY4 = 0xb,
419 DBG_BLOCK_ID_MCD_BY4 = 0xc,
420 DBG_BLOCK_ID_MCD4_BY4 = 0xd,
421 DBG_BLOCK_ID_SQA_BY4 = 0xe,
422 DBG_BLOCK_ID_SQA11_BY4 = 0xf,
423 DBG_BLOCK_ID_SQB_BY4 = 0x10,
424 DBG_BLOCK_ID_UNUSED10_BY4 = 0x11,
425 DBG_BLOCK_ID_CB_BY4 = 0x12,
426 DBG_BLOCK_ID_CB10_BY4 = 0x13,
427 DBG_BLOCK_ID_SXS_BY4 = 0x14,
428 DBG_BLOCK_ID_SXS4_BY4 = 0x15,
429 DBG_BLOCK_ID_DB_BY4 = 0x16,
430 DBG_BLOCK_ID_DB10_BY4 = 0x17,
431 DBG_BLOCK_ID_TCP_BY4 = 0x18,
432 DBG_BLOCK_ID_TCP4_BY4 = 0x19,
433 DBG_BLOCK_ID_TCP8_BY4 = 0x1a,
434 DBG_BLOCK_ID_TCP12_BY4 = 0x1b,
435 DBG_BLOCK_ID_TCP16_BY4 = 0x1c,
436 DBG_BLOCK_ID_TCP20_BY4 = 0x1d,
437 DBG_BLOCK_ID_TCP_RESERVED0_BY4 = 0x1e,
438 DBG_BLOCK_ID_TCP_RESERVED4_BY4 = 0x1f,
439 DBG_BLOCK_ID_TCC_BY4 = 0x20,
440 DBG_BLOCK_ID_TCC4_BY4 = 0x21,
441 DBG_BLOCK_ID_SPS_BY4 = 0x22,
442 DBG_BLOCK_ID_SPS11_BY4 = 0x23,
443 DBG_BLOCK_ID_TA_BY4 = 0x24,
444 DBG_BLOCK_ID_TA04_BY4 = 0x25,
445 DBG_BLOCK_ID_TA08_BY4 = 0x26,
446 DBG_BLOCK_ID_UNUSED20_BY4 = 0x27,
447 DBG_BLOCK_ID_TA10_BY4 = 0x28,
448 DBG_BLOCK_ID_TA14_BY4 = 0x29,
449 DBG_BLOCK_ID_TA18_BY4 = 0x2a,
450 DBG_BLOCK_ID_UNUSED24_BY4 = 0x2b,
451 DBG_BLOCK_ID_TD_BY4 = 0x2c,
452 DBG_BLOCK_ID_TD04_BY4 = 0x2d,
453 DBG_BLOCK_ID_TD08_BY4 = 0x2e,
454 DBG_BLOCK_ID_UNUSED28_BY4 = 0x2f,
455 DBG_BLOCK_ID_TD10_BY4 = 0x30,
456 DBG_BLOCK_ID_TD14_BY4 = 0x31,
457 DBG_BLOCK_ID_TD18_BY4 = 0x32,
458 DBG_BLOCK_ID_UNUSED32_BY4 = 0x33,
459 DBG_BLOCK_ID_LDS_BY4 = 0x34,
460 DBG_BLOCK_ID_LDS04_BY4 = 0x35,
461 DBG_BLOCK_ID_LDS08_BY4 = 0x36,
462 DBG_BLOCK_ID_UNUSED36_BY4 = 0x37,
463 DBG_BLOCK_ID_LDS10_BY4 = 0x38,
464 DBG_BLOCK_ID_LDS14_BY4 = 0x39,
465 DBG_BLOCK_ID_LDS18_BY4 = 0x3a,
466 DBG_BLOCK_ID_UNUSED40_BY4 = 0x3b,
467} DebugBlockId_BY4;
468typedef enum DebugBlockId_BY8 {
469 DBG_BLOCK_ID_RESERVED_BY8 = 0x0,
470 DBG_BLOCK_ID_CSC_BY8 = 0x1,
471 DBG_BLOCK_ID_SDMA0_BY8 = 0x2,
472 DBG_BLOCK_ID_CP0_BY8 = 0x3,
473 DBG_BLOCK_ID_SXM0_BY8 = 0x4,
474 DBG_BLOCK_ID_TCA_BY8 = 0x5,
475 DBG_BLOCK_ID_MCD_BY8 = 0x6,
476 DBG_BLOCK_ID_SQA_BY8 = 0x7,
477 DBG_BLOCK_ID_SQB_BY8 = 0x8,
478 DBG_BLOCK_ID_CB_BY8 = 0x9,
479 DBG_BLOCK_ID_SXS_BY8 = 0xa,
480 DBG_BLOCK_ID_DB_BY8 = 0xb,
481 DBG_BLOCK_ID_TCP_BY8 = 0xc,
482 DBG_BLOCK_ID_TCP8_BY8 = 0xd,
483 DBG_BLOCK_ID_TCP16_BY8 = 0xe,
484 DBG_BLOCK_ID_TCP_RESERVED0_BY8 = 0xf,
485 DBG_BLOCK_ID_TCC_BY8 = 0x10,
486 DBG_BLOCK_ID_SPS_BY8 = 0x11,
487 DBG_BLOCK_ID_TA_BY8 = 0x12,
488 DBG_BLOCK_ID_TA08_BY8 = 0x13,
489 DBG_BLOCK_ID_TA10_BY8 = 0x14,
490 DBG_BLOCK_ID_TA18_BY8 = 0x15,
491 DBG_BLOCK_ID_TD_BY8 = 0x16,
492 DBG_BLOCK_ID_TD08_BY8 = 0x17,
493 DBG_BLOCK_ID_TD10_BY8 = 0x18,
494 DBG_BLOCK_ID_TD18_BY8 = 0x19,
495 DBG_BLOCK_ID_LDS_BY8 = 0x1a,
496 DBG_BLOCK_ID_LDS08_BY8 = 0x1b,
497 DBG_BLOCK_ID_LDS10_BY8 = 0x1c,
498 DBG_BLOCK_ID_LDS18_BY8 = 0x1d,
499} DebugBlockId_BY8;
500typedef enum DebugBlockId_BY16 {
501 DBG_BLOCK_ID_RESERVED_BY16 = 0x0,
502 DBG_BLOCK_ID_SDMA0_BY16 = 0x1,
503 DBG_BLOCK_ID_SXM_BY16 = 0x2,
504 DBG_BLOCK_ID_MCD_BY16 = 0x3,
505 DBG_BLOCK_ID_SQB_BY16 = 0x4,
506 DBG_BLOCK_ID_SXS_BY16 = 0x5,
507 DBG_BLOCK_ID_TCP_BY16 = 0x6,
508 DBG_BLOCK_ID_TCP16_BY16 = 0x7,
509 DBG_BLOCK_ID_TCC_BY16 = 0x8,
510 DBG_BLOCK_ID_TA_BY16 = 0x9,
511 DBG_BLOCK_ID_TA10_BY16 = 0xa,
512 DBG_BLOCK_ID_TD_BY16 = 0xb,
513 DBG_BLOCK_ID_TD10_BY16 = 0xc,
514 DBG_BLOCK_ID_LDS_BY16 = 0xd,
515 DBG_BLOCK_ID_LDS10_BY16 = 0xe,
516} DebugBlockId_BY16;
517typedef enum SurfaceEndian {
518 ENDIAN_NONE = 0x0,
519 ENDIAN_8IN16 = 0x1,
520 ENDIAN_8IN32 = 0x2,
521 ENDIAN_8IN64 = 0x3,
522} SurfaceEndian;
523typedef enum ArrayMode {
524 ARRAY_LINEAR_GENERAL = 0x0,
525 ARRAY_LINEAR_ALIGNED = 0x1,
526 ARRAY_1D_TILED_THIN1 = 0x2,
527 ARRAY_1D_TILED_THICK = 0x3,
528 ARRAY_2D_TILED_THIN1 = 0x4,
529 ARRAY_PRT_TILED_THIN1 = 0x5,
530 ARRAY_PRT_2D_TILED_THIN1 = 0x6,
531 ARRAY_2D_TILED_THICK = 0x7,
532 ARRAY_2D_TILED_XTHICK = 0x8,
533 ARRAY_PRT_TILED_THICK = 0x9,
534 ARRAY_PRT_2D_TILED_THICK = 0xa,
535 ARRAY_PRT_3D_TILED_THIN1 = 0xb,
536 ARRAY_3D_TILED_THIN1 = 0xc,
537 ARRAY_3D_TILED_THICK = 0xd,
538 ARRAY_3D_TILED_XTHICK = 0xe,
539 ARRAY_PRT_3D_TILED_THICK = 0xf,
540} ArrayMode;
541typedef enum PipeTiling {
542 CONFIG_1_PIPE = 0x0,
543 CONFIG_2_PIPE = 0x1,
544 CONFIG_4_PIPE = 0x2,
545 CONFIG_8_PIPE = 0x3,
546} PipeTiling;
547typedef enum BankTiling {
548 CONFIG_4_BANK = 0x0,
549 CONFIG_8_BANK = 0x1,
550} BankTiling;
551typedef enum GroupInterleave {
552 CONFIG_256B_GROUP = 0x0,
553 CONFIG_512B_GROUP = 0x1,
554} GroupInterleave;
555typedef enum RowTiling {
556 CONFIG_1KB_ROW = 0x0,
557 CONFIG_2KB_ROW = 0x1,
558 CONFIG_4KB_ROW = 0x2,
559 CONFIG_8KB_ROW = 0x3,
560 CONFIG_1KB_ROW_OPT = 0x4,
561 CONFIG_2KB_ROW_OPT = 0x5,
562 CONFIG_4KB_ROW_OPT = 0x6,
563 CONFIG_8KB_ROW_OPT = 0x7,
564} RowTiling;
565typedef enum BankSwapBytes {
566 CONFIG_128B_SWAPS = 0x0,
567 CONFIG_256B_SWAPS = 0x1,
568 CONFIG_512B_SWAPS = 0x2,
569 CONFIG_1KB_SWAPS = 0x3,
570} BankSwapBytes;
571typedef enum SampleSplitBytes {
572 CONFIG_1KB_SPLIT = 0x0,
573 CONFIG_2KB_SPLIT = 0x1,
574 CONFIG_4KB_SPLIT = 0x2,
575 CONFIG_8KB_SPLIT = 0x3,
576} SampleSplitBytes;
577typedef enum NumPipes {
578 ADDR_CONFIG_1_PIPE = 0x0,
579 ADDR_CONFIG_2_PIPE = 0x1,
580 ADDR_CONFIG_4_PIPE = 0x2,
581 ADDR_CONFIG_8_PIPE = 0x3,
582} NumPipes;
583typedef enum PipeInterleaveSize {
584 ADDR_CONFIG_PIPE_INTERLEAVE_256B = 0x0,
585 ADDR_CONFIG_PIPE_INTERLEAVE_512B = 0x1,
586} PipeInterleaveSize;
587typedef enum BankInterleaveSize {
588 ADDR_CONFIG_BANK_INTERLEAVE_1 = 0x0,
589 ADDR_CONFIG_BANK_INTERLEAVE_2 = 0x1,
590 ADDR_CONFIG_BANK_INTERLEAVE_4 = 0x2,
591 ADDR_CONFIG_BANK_INTERLEAVE_8 = 0x3,
592} BankInterleaveSize;
593typedef enum NumShaderEngines {
594 ADDR_CONFIG_1_SHADER_ENGINE = 0x0,
595 ADDR_CONFIG_2_SHADER_ENGINE = 0x1,
596} NumShaderEngines;
597typedef enum ShaderEngineTileSize {
598 ADDR_CONFIG_SE_TILE_16 = 0x0,
599 ADDR_CONFIG_SE_TILE_32 = 0x1,
600} ShaderEngineTileSize;
601typedef enum NumGPUs {
602 ADDR_CONFIG_1_GPU = 0x0,
603 ADDR_CONFIG_2_GPU = 0x1,
604 ADDR_CONFIG_4_GPU = 0x2,
605} NumGPUs;
606typedef enum MultiGPUTileSize {
607 ADDR_CONFIG_GPU_TILE_16 = 0x0,
608 ADDR_CONFIG_GPU_TILE_32 = 0x1,
609 ADDR_CONFIG_GPU_TILE_64 = 0x2,
610 ADDR_CONFIG_GPU_TILE_128 = 0x3,
611} MultiGPUTileSize;
612typedef enum RowSize {
613 ADDR_CONFIG_1KB_ROW = 0x0,
614 ADDR_CONFIG_2KB_ROW = 0x1,
615 ADDR_CONFIG_4KB_ROW = 0x2,
616} RowSize;
617typedef enum NumLowerPipes {
618 ADDR_CONFIG_1_LOWER_PIPES = 0x0,
619 ADDR_CONFIG_2_LOWER_PIPES = 0x1,
620} NumLowerPipes;
621typedef enum ColorTransform {
622 DCC_CT_AUTO = 0x0,
623 DCC_CT_NONE = 0x1,
624 ABGR_TO_A_BG_G_RB = 0x2,
625 BGRA_TO_BG_G_RB_A = 0x3,
626} ColorTransform;
627typedef enum CompareRef {
628 REF_NEVER = 0x0,
629 REF_LESS = 0x1,
630 REF_EQUAL = 0x2,
631 REF_LEQUAL = 0x3,
632 REF_GREATER = 0x4,
633 REF_NOTEQUAL = 0x5,
634 REF_GEQUAL = 0x6,
635 REF_ALWAYS = 0x7,
636} CompareRef;
637typedef enum ReadSize {
638 READ_256_BITS = 0x0,
639 READ_512_BITS = 0x1,
640} ReadSize;
641typedef enum DepthFormat {
642 DEPTH_INVALID = 0x0,
643 DEPTH_16 = 0x1,
644 DEPTH_X8_24 = 0x2,
645 DEPTH_8_24 = 0x3,
646 DEPTH_X8_24_FLOAT = 0x4,
647 DEPTH_8_24_FLOAT = 0x5,
648 DEPTH_32_FLOAT = 0x6,
649 DEPTH_X24_8_32_FLOAT = 0x7,
650} DepthFormat;
651typedef enum ZFormat {
652 Z_INVALID = 0x0,
653 Z_16 = 0x1,
654 Z_24 = 0x2,
655 Z_32_FLOAT = 0x3,
656} ZFormat;
657typedef enum StencilFormat {
658 STENCIL_INVALID = 0x0,
659 STENCIL_8 = 0x1,
660} StencilFormat;
661typedef enum CmaskMode {
662 CMASK_CLEAR_NONE = 0x0,
663 CMASK_CLEAR_ONE = 0x1,
664 CMASK_CLEAR_ALL = 0x2,
665 CMASK_ANY_EXPANDED = 0x3,
666 CMASK_ALPHA0_FRAG1 = 0x4,
667 CMASK_ALPHA0_FRAG2 = 0x5,
668 CMASK_ALPHA0_FRAG4 = 0x6,
669 CMASK_ALPHA0_FRAGS = 0x7,
670 CMASK_ALPHA1_FRAG1 = 0x8,
671 CMASK_ALPHA1_FRAG2 = 0x9,
672 CMASK_ALPHA1_FRAG4 = 0xa,
673 CMASK_ALPHA1_FRAGS = 0xb,
674 CMASK_ALPHAX_FRAG1 = 0xc,
675 CMASK_ALPHAX_FRAG2 = 0xd,
676 CMASK_ALPHAX_FRAG4 = 0xe,
677 CMASK_ALPHAX_FRAGS = 0xf,
678} CmaskMode;
679typedef enum QuadExportFormat {
680 EXPORT_UNUSED = 0x0,
681 EXPORT_32_R = 0x1,
682 EXPORT_32_GR = 0x2,
683 EXPORT_32_AR = 0x3,
684 EXPORT_FP16_ABGR = 0x4,
685 EXPORT_UNSIGNED16_ABGR = 0x5,
686 EXPORT_SIGNED16_ABGR = 0x6,
687 EXPORT_32_ABGR = 0x7,
688} QuadExportFormat;
689typedef enum QuadExportFormatOld {
690 EXPORT_4P_32BPC_ABGR = 0x0,
691 EXPORT_4P_16BPC_ABGR = 0x1,
692 EXPORT_4P_32BPC_GR = 0x2,
693 EXPORT_4P_32BPC_AR = 0x3,
694 EXPORT_2P_32BPC_ABGR = 0x4,
695 EXPORT_8P_32BPC_R = 0x5,
696} QuadExportFormatOld;
697typedef enum ColorFormat {
698 COLOR_INVALID = 0x0,
699 COLOR_8 = 0x1,
700 COLOR_16 = 0x2,
701 COLOR_8_8 = 0x3,
702 COLOR_32 = 0x4,
703 COLOR_16_16 = 0x5,
704 COLOR_10_11_11 = 0x6,
705 COLOR_11_11_10 = 0x7,
706 COLOR_10_10_10_2 = 0x8,
707 COLOR_2_10_10_10 = 0x9,
708 COLOR_8_8_8_8 = 0xa,
709 COLOR_32_32 = 0xb,
710 COLOR_16_16_16_16 = 0xc,
711 COLOR_RESERVED_13 = 0xd,
712 COLOR_32_32_32_32 = 0xe,
713 COLOR_RESERVED_15 = 0xf,
714 COLOR_5_6_5 = 0x10,
715 COLOR_1_5_5_5 = 0x11,
716 COLOR_5_5_5_1 = 0x12,
717 COLOR_4_4_4_4 = 0x13,
718 COLOR_8_24 = 0x14,
719 COLOR_24_8 = 0x15,
720 COLOR_X24_8_32_FLOAT = 0x16,
721 COLOR_RESERVED_23 = 0x17,
722} ColorFormat;
723typedef enum SurfaceFormat {
724 FMT_INVALID = 0x0,
725 FMT_8 = 0x1,
726 FMT_16 = 0x2,
727 FMT_8_8 = 0x3,
728 FMT_32 = 0x4,
729 FMT_16_16 = 0x5,
730 FMT_10_11_11 = 0x6,
731 FMT_11_11_10 = 0x7,
732 FMT_10_10_10_2 = 0x8,
733 FMT_2_10_10_10 = 0x9,
734 FMT_8_8_8_8 = 0xa,
735 FMT_32_32 = 0xb,
736 FMT_16_16_16_16 = 0xc,
737 FMT_32_32_32 = 0xd,
738 FMT_32_32_32_32 = 0xe,
739 FMT_RESERVED_4 = 0xf,
740 FMT_5_6_5 = 0x10,
741 FMT_1_5_5_5 = 0x11,
742 FMT_5_5_5_1 = 0x12,
743 FMT_4_4_4_4 = 0x13,
744 FMT_8_24 = 0x14,
745 FMT_24_8 = 0x15,
746 FMT_X24_8_32_FLOAT = 0x16,
747 FMT_RESERVED_33 = 0x17,
748 FMT_11_11_10_FLOAT = 0x18,
749 FMT_16_FLOAT = 0x19,
750 FMT_32_FLOAT = 0x1a,
751 FMT_16_16_FLOAT = 0x1b,
752 FMT_8_24_FLOAT = 0x1c,
753 FMT_24_8_FLOAT = 0x1d,
754 FMT_32_32_FLOAT = 0x1e,
755 FMT_10_11_11_FLOAT = 0x1f,
756 FMT_16_16_16_16_FLOAT = 0x20,
757 FMT_3_3_2 = 0x21,
758 FMT_6_5_5 = 0x22,
759 FMT_32_32_32_32_FLOAT = 0x23,
760 FMT_RESERVED_36 = 0x24,
761 FMT_1 = 0x25,
762 FMT_1_REVERSED = 0x26,
763 FMT_GB_GR = 0x27,
764 FMT_BG_RG = 0x28,
765 FMT_32_AS_8 = 0x29,
766 FMT_32_AS_8_8 = 0x2a,
767 FMT_5_9_9_9_SHAREDEXP = 0x2b,
768 FMT_8_8_8 = 0x2c,
769 FMT_16_16_16 = 0x2d,
770 FMT_16_16_16_FLOAT = 0x2e,
771 FMT_4_4 = 0x2f,
772 FMT_32_32_32_FLOAT = 0x30,
773 FMT_BC1 = 0x31,
774 FMT_BC2 = 0x32,
775 FMT_BC3 = 0x33,
776 FMT_BC4 = 0x34,
777 FMT_BC5 = 0x35,
778 FMT_BC6 = 0x36,
779 FMT_BC7 = 0x37,
780 FMT_32_AS_32_32_32_32 = 0x38,
781 FMT_APC3 = 0x39,
782 FMT_APC4 = 0x3a,
783 FMT_APC5 = 0x3b,
784 FMT_APC6 = 0x3c,
785 FMT_APC7 = 0x3d,
786 FMT_CTX1 = 0x3e,
787 FMT_RESERVED_63 = 0x3f,
788} SurfaceFormat;
789typedef enum BUF_DATA_FORMAT {
790 BUF_DATA_FORMAT_INVALID = 0x0,
791 BUF_DATA_FORMAT_8 = 0x1,
792 BUF_DATA_FORMAT_16 = 0x2,
793 BUF_DATA_FORMAT_8_8 = 0x3,
794 BUF_DATA_FORMAT_32 = 0x4,
795 BUF_DATA_FORMAT_16_16 = 0x5,
796 BUF_DATA_FORMAT_10_11_11 = 0x6,
797 BUF_DATA_FORMAT_11_11_10 = 0x7,
798 BUF_DATA_FORMAT_10_10_10_2 = 0x8,
799 BUF_DATA_FORMAT_2_10_10_10 = 0x9,
800 BUF_DATA_FORMAT_8_8_8_8 = 0xa,
801 BUF_DATA_FORMAT_32_32 = 0xb,
802 BUF_DATA_FORMAT_16_16_16_16 = 0xc,
803 BUF_DATA_FORMAT_32_32_32 = 0xd,
804 BUF_DATA_FORMAT_32_32_32_32 = 0xe,
805 BUF_DATA_FORMAT_RESERVED_15 = 0xf,
806} BUF_DATA_FORMAT;
807typedef enum IMG_DATA_FORMAT {
808 IMG_DATA_FORMAT_INVALID = 0x0,
809 IMG_DATA_FORMAT_8 = 0x1,
810 IMG_DATA_FORMAT_16 = 0x2,
811 IMG_DATA_FORMAT_8_8 = 0x3,
812 IMG_DATA_FORMAT_32 = 0x4,
813 IMG_DATA_FORMAT_16_16 = 0x5,
814 IMG_DATA_FORMAT_10_11_11 = 0x6,
815 IMG_DATA_FORMAT_11_11_10 = 0x7,
816 IMG_DATA_FORMAT_10_10_10_2 = 0x8,
817 IMG_DATA_FORMAT_2_10_10_10 = 0x9,
818 IMG_DATA_FORMAT_8_8_8_8 = 0xa,
819 IMG_DATA_FORMAT_32_32 = 0xb,
820 IMG_DATA_FORMAT_16_16_16_16 = 0xc,
821 IMG_DATA_FORMAT_32_32_32 = 0xd,
822 IMG_DATA_FORMAT_32_32_32_32 = 0xe,
823 IMG_DATA_FORMAT_RESERVED_15 = 0xf,
824 IMG_DATA_FORMAT_5_6_5 = 0x10,
825 IMG_DATA_FORMAT_1_5_5_5 = 0x11,
826 IMG_DATA_FORMAT_5_5_5_1 = 0x12,
827 IMG_DATA_FORMAT_4_4_4_4 = 0x13,
828 IMG_DATA_FORMAT_8_24 = 0x14,
829 IMG_DATA_FORMAT_24_8 = 0x15,
830 IMG_DATA_FORMAT_X24_8_32 = 0x16,
831 IMG_DATA_FORMAT_RESERVED_23 = 0x17,
832 IMG_DATA_FORMAT_RESERVED_24 = 0x18,
833 IMG_DATA_FORMAT_RESERVED_25 = 0x19,
834 IMG_DATA_FORMAT_RESERVED_26 = 0x1a,
835 IMG_DATA_FORMAT_RESERVED_27 = 0x1b,
836 IMG_DATA_FORMAT_RESERVED_28 = 0x1c,
837 IMG_DATA_FORMAT_RESERVED_29 = 0x1d,
838 IMG_DATA_FORMAT_RESERVED_30 = 0x1e,
839 IMG_DATA_FORMAT_RESERVED_31 = 0x1f,
840 IMG_DATA_FORMAT_GB_GR = 0x20,
841 IMG_DATA_FORMAT_BG_RG = 0x21,
842 IMG_DATA_FORMAT_5_9_9_9 = 0x22,
843 IMG_DATA_FORMAT_BC1 = 0x23,
844 IMG_DATA_FORMAT_BC2 = 0x24,
845 IMG_DATA_FORMAT_BC3 = 0x25,
846 IMG_DATA_FORMAT_BC4 = 0x26,
847 IMG_DATA_FORMAT_BC5 = 0x27,
848 IMG_DATA_FORMAT_BC6 = 0x28,
849 IMG_DATA_FORMAT_BC7 = 0x29,
850 IMG_DATA_FORMAT_RESERVED_42 = 0x2a,
851 IMG_DATA_FORMAT_RESERVED_43 = 0x2b,
852 IMG_DATA_FORMAT_FMASK8_S2_F1 = 0x2c,
853 IMG_DATA_FORMAT_FMASK8_S4_F1 = 0x2d,
854 IMG_DATA_FORMAT_FMASK8_S8_F1 = 0x2e,
855 IMG_DATA_FORMAT_FMASK8_S2_F2 = 0x2f,
856 IMG_DATA_FORMAT_FMASK8_S4_F2 = 0x30,
857 IMG_DATA_FORMAT_FMASK8_S4_F4 = 0x31,
858 IMG_DATA_FORMAT_FMASK16_S16_F1 = 0x32,
859 IMG_DATA_FORMAT_FMASK16_S8_F2 = 0x33,
860 IMG_DATA_FORMAT_FMASK32_S16_F2 = 0x34,
861 IMG_DATA_FORMAT_FMASK32_S8_F4 = 0x35,
862 IMG_DATA_FORMAT_FMASK32_S8_F8 = 0x36,
863 IMG_DATA_FORMAT_FMASK64_S16_F4 = 0x37,
864 IMG_DATA_FORMAT_FMASK64_S16_F8 = 0x38,
865 IMG_DATA_FORMAT_4_4 = 0x39,
866 IMG_DATA_FORMAT_6_5_5 = 0x3a,
867 IMG_DATA_FORMAT_1 = 0x3b,
868 IMG_DATA_FORMAT_1_REVERSED = 0x3c,
869 IMG_DATA_FORMAT_32_AS_8 = 0x3d,
870 IMG_DATA_FORMAT_32_AS_8_8 = 0x3e,
871 IMG_DATA_FORMAT_32_AS_32_32_32_32 = 0x3f,
872} IMG_DATA_FORMAT;
873typedef enum BUF_NUM_FORMAT {
874 BUF_NUM_FORMAT_UNORM = 0x0,
875 BUF_NUM_FORMAT_SNORM = 0x1,
876 BUF_NUM_FORMAT_USCALED = 0x2,
877 BUF_NUM_FORMAT_SSCALED = 0x3,
878 BUF_NUM_FORMAT_UINT = 0x4,
879 BUF_NUM_FORMAT_SINT = 0x5,
880 BUF_NUM_FORMAT_RESERVED_6 = 0x6,
881 BUF_NUM_FORMAT_FLOAT = 0x7,
882} BUF_NUM_FORMAT;
883typedef enum IMG_NUM_FORMAT {
884 IMG_NUM_FORMAT_UNORM = 0x0,
885 IMG_NUM_FORMAT_SNORM = 0x1,
886 IMG_NUM_FORMAT_USCALED = 0x2,
887 IMG_NUM_FORMAT_SSCALED = 0x3,
888 IMG_NUM_FORMAT_UINT = 0x4,
889 IMG_NUM_FORMAT_SINT = 0x5,
890 IMG_NUM_FORMAT_RESERVED_6 = 0x6,
891 IMG_NUM_FORMAT_FLOAT = 0x7,
892 IMG_NUM_FORMAT_RESERVED_8 = 0x8,
893 IMG_NUM_FORMAT_SRGB = 0x9,
894 IMG_NUM_FORMAT_RESERVED_10 = 0xa,
895 IMG_NUM_FORMAT_RESERVED_11 = 0xb,
896 IMG_NUM_FORMAT_RESERVED_12 = 0xc,
897 IMG_NUM_FORMAT_RESERVED_13 = 0xd,
898 IMG_NUM_FORMAT_RESERVED_14 = 0xe,
899 IMG_NUM_FORMAT_RESERVED_15 = 0xf,
900} IMG_NUM_FORMAT;
901typedef enum TileType {
902 ARRAY_COLOR_TILE = 0x0,
903 ARRAY_DEPTH_TILE = 0x1,
904} TileType;
905typedef enum NonDispTilingOrder {
906 ADDR_SURF_MICRO_TILING_DISPLAY = 0x0,
907 ADDR_SURF_MICRO_TILING_NON_DISPLAY = 0x1,
908} NonDispTilingOrder;
909typedef enum MicroTileMode {
910 ADDR_SURF_DISPLAY_MICRO_TILING = 0x0,
911 ADDR_SURF_THIN_MICRO_TILING = 0x1,
912 ADDR_SURF_DEPTH_MICRO_TILING = 0x2,
913 ADDR_SURF_ROTATED_MICRO_TILING = 0x3,
914 ADDR_SURF_THICK_MICRO_TILING = 0x4,
915} MicroTileMode;
916typedef enum TileSplit {
917 ADDR_SURF_TILE_SPLIT_64B = 0x0,
918 ADDR_SURF_TILE_SPLIT_128B = 0x1,
919 ADDR_SURF_TILE_SPLIT_256B = 0x2,
920 ADDR_SURF_TILE_SPLIT_512B = 0x3,
921 ADDR_SURF_TILE_SPLIT_1KB = 0x4,
922 ADDR_SURF_TILE_SPLIT_2KB = 0x5,
923 ADDR_SURF_TILE_SPLIT_4KB = 0x6,
924} TileSplit;
925typedef enum SampleSplit {
926 ADDR_SURF_SAMPLE_SPLIT_1 = 0x0,
927 ADDR_SURF_SAMPLE_SPLIT_2 = 0x1,
928 ADDR_SURF_SAMPLE_SPLIT_4 = 0x2,
929 ADDR_SURF_SAMPLE_SPLIT_8 = 0x3,
930} SampleSplit;
931typedef enum PipeConfig {
932 ADDR_SURF_P2 = 0x0,
933 ADDR_SURF_P2_RESERVED0 = 0x1,
934 ADDR_SURF_P2_RESERVED1 = 0x2,
935 ADDR_SURF_P2_RESERVED2 = 0x3,
936 ADDR_SURF_P4_8x16 = 0x4,
937 ADDR_SURF_P4_16x16 = 0x5,
938 ADDR_SURF_P4_16x32 = 0x6,
939 ADDR_SURF_P4_32x32 = 0x7,
940 ADDR_SURF_P8_16x16_8x16 = 0x8,
941 ADDR_SURF_P8_16x32_8x16 = 0x9,
942 ADDR_SURF_P8_32x32_8x16 = 0xa,
943 ADDR_SURF_P8_16x32_16x16 = 0xb,
944 ADDR_SURF_P8_32x32_16x16 = 0xc,
945 ADDR_SURF_P8_32x32_16x32 = 0xd,
946 ADDR_SURF_P8_32x64_32x32 = 0xe,
947 ADDR_SURF_P8_RESERVED0 = 0xf,
948 ADDR_SURF_P16_32x32_8x16 = 0x10,
949 ADDR_SURF_P16_32x32_16x16 = 0x11,
950} PipeConfig;
951typedef enum NumBanks {
952 ADDR_SURF_2_BANK = 0x0,
953 ADDR_SURF_4_BANK = 0x1,
954 ADDR_SURF_8_BANK = 0x2,
955 ADDR_SURF_16_BANK = 0x3,
956} NumBanks;
957typedef enum BankWidth {
958 ADDR_SURF_BANK_WIDTH_1 = 0x0,
959 ADDR_SURF_BANK_WIDTH_2 = 0x1,
960 ADDR_SURF_BANK_WIDTH_4 = 0x2,
961 ADDR_SURF_BANK_WIDTH_8 = 0x3,
962} BankWidth;
963typedef enum BankHeight {
964 ADDR_SURF_BANK_HEIGHT_1 = 0x0,
965 ADDR_SURF_BANK_HEIGHT_2 = 0x1,
966 ADDR_SURF_BANK_HEIGHT_4 = 0x2,
967 ADDR_SURF_BANK_HEIGHT_8 = 0x3,
968} BankHeight;
969typedef enum BankWidthHeight {
970 ADDR_SURF_BANK_WH_1 = 0x0,
971 ADDR_SURF_BANK_WH_2 = 0x1,
972 ADDR_SURF_BANK_WH_4 = 0x2,
973 ADDR_SURF_BANK_WH_8 = 0x3,
974} BankWidthHeight;
975typedef enum MacroTileAspect {
976 ADDR_SURF_MACRO_ASPECT_1 = 0x0,
977 ADDR_SURF_MACRO_ASPECT_2 = 0x1,
978 ADDR_SURF_MACRO_ASPECT_4 = 0x2,
979 ADDR_SURF_MACRO_ASPECT_8 = 0x3,
980} MacroTileAspect;
981typedef enum GATCL1RequestType {
982 GATCL1_TYPE_NORMAL = 0x0,
983 GATCL1_TYPE_SHOOTDOWN = 0x1,
984 GATCL1_TYPE_BYPASS = 0x2,
985} GATCL1RequestType;
986typedef enum TCC_CACHE_POLICIES {
987 TCC_CACHE_POLICY_LRU = 0x0,
988 TCC_CACHE_POLICY_STREAM = 0x1,
989} TCC_CACHE_POLICIES;
990typedef enum MTYPE {
991 MTYPE_NC_NV = 0x0,
992 MTYPE_NC = 0x1,
993 MTYPE_CC = 0x2,
994 MTYPE_UC = 0x3,
995} MTYPE;
996typedef enum PERFMON_COUNTER_MODE {
997 PERFMON_COUNTER_MODE_ACCUM = 0x0,
998 PERFMON_COUNTER_MODE_ACTIVE_CYCLES = 0x1,
999 PERFMON_COUNTER_MODE_MAX = 0x2,
1000 PERFMON_COUNTER_MODE_DIRTY = 0x3,
1001 PERFMON_COUNTER_MODE_SAMPLE = 0x4,
1002 PERFMON_COUNTER_MODE_CYCLES_SINCE_FIRST_EVENT = 0x5,
1003 PERFMON_COUNTER_MODE_CYCLES_SINCE_LAST_EVENT = 0x6,
1004 PERFMON_COUNTER_MODE_CYCLES_GE_HI = 0x7,
1005 PERFMON_COUNTER_MODE_CYCLES_EQ_HI = 0x8,
1006 PERFMON_COUNTER_MODE_INACTIVE_CYCLES = 0x9,
1007 PERFMON_COUNTER_MODE_RESERVED = 0xf,
1008} PERFMON_COUNTER_MODE;
1009typedef enum PERFMON_SPM_MODE {
1010 PERFMON_SPM_MODE_OFF = 0x0,
1011 PERFMON_SPM_MODE_16BIT_CLAMP = 0x1,
1012 PERFMON_SPM_MODE_16BIT_NO_CLAMP = 0x2,
1013 PERFMON_SPM_MODE_32BIT_CLAMP = 0x3,
1014 PERFMON_SPM_MODE_32BIT_NO_CLAMP = 0x4,
1015 PERFMON_SPM_MODE_RESERVED_5 = 0x5,
1016 PERFMON_SPM_MODE_RESERVED_6 = 0x6,
1017 PERFMON_SPM_MODE_RESERVED_7 = 0x7,
1018 PERFMON_SPM_MODE_TEST_MODE_0 = 0x8,
1019 PERFMON_SPM_MODE_TEST_MODE_1 = 0x9,
1020 PERFMON_SPM_MODE_TEST_MODE_2 = 0xa,
1021} PERFMON_SPM_MODE;
1022typedef enum SurfaceTiling {
1023 ARRAY_LINEAR = 0x0,
1024 ARRAY_TILED = 0x1,
1025} SurfaceTiling;
1026typedef enum SurfaceArray {
1027 ARRAY_1D = 0x0,
1028 ARRAY_2D = 0x1,
1029 ARRAY_3D = 0x2,
1030 ARRAY_3D_SLICE = 0x3,
1031} SurfaceArray;
1032typedef enum ColorArray {
1033 ARRAY_2D_ALT_COLOR = 0x0,
1034 ARRAY_2D_COLOR = 0x1,
1035 ARRAY_3D_SLICE_COLOR = 0x3,
1036} ColorArray;
1037typedef enum DepthArray {
1038 ARRAY_2D_ALT_DEPTH = 0x0,
1039 ARRAY_2D_DEPTH = 0x1,
1040} DepthArray;
1041typedef enum ENUM_NUM_SIMD_PER_CU {
1042 NUM_SIMD_PER_CU = 0x4,
1043} ENUM_NUM_SIMD_PER_CU;
1044typedef enum MEM_PWR_FORCE_CTRL {
1045 NO_FORCE_REQUEST = 0x0,
1046 FORCE_LIGHT_SLEEP_REQUEST = 0x1,
1047 FORCE_DEEP_SLEEP_REQUEST = 0x2,
1048 FORCE_SHUT_DOWN_REQUEST = 0x3,
1049} MEM_PWR_FORCE_CTRL;
1050typedef enum MEM_PWR_FORCE_CTRL2 {
1051 NO_FORCE_REQ = 0x0,
1052 FORCE_LIGHT_SLEEP_REQ = 0x1,
1053} MEM_PWR_FORCE_CTRL2;
1054typedef enum MEM_PWR_DIS_CTRL {
1055 ENABLE_MEM_PWR_CTRL = 0x0,
1056 DISABLE_MEM_PWR_CTRL = 0x1,
1057} MEM_PWR_DIS_CTRL;
1058typedef enum MEM_PWR_SEL_CTRL {
1059 DYNAMIC_SHUT_DOWN_ENABLE = 0x0,
1060 DYNAMIC_DEEP_SLEEP_ENABLE = 0x1,
1061 DYNAMIC_LIGHT_SLEEP_ENABLE = 0x2,
1062} MEM_PWR_SEL_CTRL;
1063typedef enum MEM_PWR_SEL_CTRL2 {
1064 DYNAMIC_DEEP_SLEEP_EN = 0x0,
1065 DYNAMIC_LIGHT_SLEEP_EN = 0x1,
1066} MEM_PWR_SEL_CTRL2;
1067
1068#endif /* ACP_2_2_ENUM_H */
diff --git a/sound/soc/amd/include/acp_2_2_sh_mask.h b/sound/soc/amd/include/acp_2_2_sh_mask.h
new file mode 100644
index 000000000000..32d2d4104309
--- /dev/null
+++ b/sound/soc/amd/include/acp_2_2_sh_mask.h
@@ -0,0 +1,2292 @@
1/*
2 * ACP_2_2 Register documentation
3 *
4 * Copyright (C) 2014 Advanced Micro Devices, Inc.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the "Software"),
8 * to deal in the Software without restriction, including without limitation
9 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 * and/or sell copies of the Software, and to permit persons to whom the
11 * Software is furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included
14 * in all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
17 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE COPYRIGHT HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
20 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 */
23
24#ifndef ACP_2_2_SH_MASK_H
25#define ACP_2_2_SH_MASK_H
26
27#define ACP_DMA_CNTL_0__DMAChRst_MASK 0x1
28#define ACP_DMA_CNTL_0__DMAChRst__SHIFT 0x0
29#define ACP_DMA_CNTL_0__DMAChRun_MASK 0x2
30#define ACP_DMA_CNTL_0__DMAChRun__SHIFT 0x1
31#define ACP_DMA_CNTL_0__DMAChIOCEn_MASK 0x4
32#define ACP_DMA_CNTL_0__DMAChIOCEn__SHIFT 0x2
33#define ACP_DMA_CNTL_0__Circular_DMA_En_MASK 0x8
34#define ACP_DMA_CNTL_0__Circular_DMA_En__SHIFT 0x3
35#define ACP_DMA_CNTL_0__DMAChGracefulRstEn_MASK 0x10
36#define ACP_DMA_CNTL_0__DMAChGracefulRstEn__SHIFT 0x4
37#define ACP_DMA_CNTL_1__DMAChRst_MASK 0x1
38#define ACP_DMA_CNTL_1__DMAChRst__SHIFT 0x0
39#define ACP_DMA_CNTL_1__DMAChRun_MASK 0x2
40#define ACP_DMA_CNTL_1__DMAChRun__SHIFT 0x1
41#define ACP_DMA_CNTL_1__DMAChIOCEn_MASK 0x4
42#define ACP_DMA_CNTL_1__DMAChIOCEn__SHIFT 0x2
43#define ACP_DMA_CNTL_1__Circular_DMA_En_MASK 0x8
44#define ACP_DMA_CNTL_1__Circular_DMA_En__SHIFT 0x3
45#define ACP_DMA_CNTL_1__DMAChGracefulRstEn_MASK 0x10
46#define ACP_DMA_CNTL_1__DMAChGracefulRstEn__SHIFT 0x4
47#define ACP_DMA_CNTL_2__DMAChRst_MASK 0x1
48#define ACP_DMA_CNTL_2__DMAChRst__SHIFT 0x0
49#define ACP_DMA_CNTL_2__DMAChRun_MASK 0x2
50#define ACP_DMA_CNTL_2__DMAChRun__SHIFT 0x1
51#define ACP_DMA_CNTL_2__DMAChIOCEn_MASK 0x4
52#define ACP_DMA_CNTL_2__DMAChIOCEn__SHIFT 0x2
53#define ACP_DMA_CNTL_2__Circular_DMA_En_MASK 0x8
54#define ACP_DMA_CNTL_2__Circular_DMA_En__SHIFT 0x3
55#define ACP_DMA_CNTL_2__DMAChGracefulRstEn_MASK 0x10
56#define ACP_DMA_CNTL_2__DMAChGracefulRstEn__SHIFT 0x4
57#define ACP_DMA_CNTL_3__DMAChRst_MASK 0x1
58#define ACP_DMA_CNTL_3__DMAChRst__SHIFT 0x0
59#define ACP_DMA_CNTL_3__DMAChRun_MASK 0x2
60#define ACP_DMA_CNTL_3__DMAChRun__SHIFT 0x1
61#define ACP_DMA_CNTL_3__DMAChIOCEn_MASK 0x4
62#define ACP_DMA_CNTL_3__DMAChIOCEn__SHIFT 0x2
63#define ACP_DMA_CNTL_3__Circular_DMA_En_MASK 0x8
64#define ACP_DMA_CNTL_3__Circular_DMA_En__SHIFT 0x3
65#define ACP_DMA_CNTL_3__DMAChGracefulRstEn_MASK 0x10
66#define ACP_DMA_CNTL_3__DMAChGracefulRstEn__SHIFT 0x4
67#define ACP_DMA_CNTL_4__DMAChRst_MASK 0x1
68#define ACP_DMA_CNTL_4__DMAChRst__SHIFT 0x0
69#define ACP_DMA_CNTL_4__DMAChRun_MASK 0x2
70#define ACP_DMA_CNTL_4__DMAChRun__SHIFT 0x1
71#define ACP_DMA_CNTL_4__DMAChIOCEn_MASK 0x4
72#define ACP_DMA_CNTL_4__DMAChIOCEn__SHIFT 0x2
73#define ACP_DMA_CNTL_4__Circular_DMA_En_MASK 0x8
74#define ACP_DMA_CNTL_4__Circular_DMA_En__SHIFT 0x3
75#define ACP_DMA_CNTL_4__DMAChGracefulRstEn_MASK 0x10
76#define ACP_DMA_CNTL_4__DMAChGracefulRstEn__SHIFT 0x4
77#define ACP_DMA_CNTL_5__DMAChRst_MASK 0x1
78#define ACP_DMA_CNTL_5__DMAChRst__SHIFT 0x0
79#define ACP_DMA_CNTL_5__DMAChRun_MASK 0x2
80#define ACP_DMA_CNTL_5__DMAChRun__SHIFT 0x1
81#define ACP_DMA_CNTL_5__DMAChIOCEn_MASK 0x4
82#define ACP_DMA_CNTL_5__DMAChIOCEn__SHIFT 0x2
83#define ACP_DMA_CNTL_5__Circular_DMA_En_MASK 0x8
84#define ACP_DMA_CNTL_5__Circular_DMA_En__SHIFT 0x3
85#define ACP_DMA_CNTL_5__DMAChGracefulRstEn_MASK 0x10
86#define ACP_DMA_CNTL_5__DMAChGracefulRstEn__SHIFT 0x4
87#define ACP_DMA_CNTL_6__DMAChRst_MASK 0x1
88#define ACP_DMA_CNTL_6__DMAChRst__SHIFT 0x0
89#define ACP_DMA_CNTL_6__DMAChRun_MASK 0x2
90#define ACP_DMA_CNTL_6__DMAChRun__SHIFT 0x1
91#define ACP_DMA_CNTL_6__DMAChIOCEn_MASK 0x4
92#define ACP_DMA_CNTL_6__DMAChIOCEn__SHIFT 0x2
93#define ACP_DMA_CNTL_6__Circular_DMA_En_MASK 0x8
94#define ACP_DMA_CNTL_6__Circular_DMA_En__SHIFT 0x3
95#define ACP_DMA_CNTL_6__DMAChGracefulRstEn_MASK 0x10
96#define ACP_DMA_CNTL_6__DMAChGracefulRstEn__SHIFT 0x4
97#define ACP_DMA_CNTL_7__DMAChRst_MASK 0x1
98#define ACP_DMA_CNTL_7__DMAChRst__SHIFT 0x0
99#define ACP_DMA_CNTL_7__DMAChRun_MASK 0x2
100#define ACP_DMA_CNTL_7__DMAChRun__SHIFT 0x1
101#define ACP_DMA_CNTL_7__DMAChIOCEn_MASK 0x4
102#define ACP_DMA_CNTL_7__DMAChIOCEn__SHIFT 0x2
103#define ACP_DMA_CNTL_7__Circular_DMA_En_MASK 0x8
104#define ACP_DMA_CNTL_7__Circular_DMA_En__SHIFT 0x3
105#define ACP_DMA_CNTL_7__DMAChGracefulRstEn_MASK 0x10
106#define ACP_DMA_CNTL_7__DMAChGracefulRstEn__SHIFT 0x4
107#define ACP_DMA_CNTL_8__DMAChRst_MASK 0x1
108#define ACP_DMA_CNTL_8__DMAChRst__SHIFT 0x0
109#define ACP_DMA_CNTL_8__DMAChRun_MASK 0x2
110#define ACP_DMA_CNTL_8__DMAChRun__SHIFT 0x1
111#define ACP_DMA_CNTL_8__DMAChIOCEn_MASK 0x4
112#define ACP_DMA_CNTL_8__DMAChIOCEn__SHIFT 0x2
113#define ACP_DMA_CNTL_8__Circular_DMA_En_MASK 0x8
114#define ACP_DMA_CNTL_8__Circular_DMA_En__SHIFT 0x3
115#define ACP_DMA_CNTL_8__DMAChGracefulRstEn_MASK 0x10
116#define ACP_DMA_CNTL_8__DMAChGracefulRstEn__SHIFT 0x4
117#define ACP_DMA_CNTL_9__DMAChRst_MASK 0x1
118#define ACP_DMA_CNTL_9__DMAChRst__SHIFT 0x0
119#define ACP_DMA_CNTL_9__DMAChRun_MASK 0x2
120#define ACP_DMA_CNTL_9__DMAChRun__SHIFT 0x1
121#define ACP_DMA_CNTL_9__DMAChIOCEn_MASK 0x4
122#define ACP_DMA_CNTL_9__DMAChIOCEn__SHIFT 0x2
123#define ACP_DMA_CNTL_9__Circular_DMA_En_MASK 0x8
124#define ACP_DMA_CNTL_9__Circular_DMA_En__SHIFT 0x3
125#define ACP_DMA_CNTL_9__DMAChGracefulRstEn_MASK 0x10
126#define ACP_DMA_CNTL_9__DMAChGracefulRstEn__SHIFT 0x4
127#define ACP_DMA_CNTL_10__DMAChRst_MASK 0x1
128#define ACP_DMA_CNTL_10__DMAChRst__SHIFT 0x0
129#define ACP_DMA_CNTL_10__DMAChRun_MASK 0x2
130#define ACP_DMA_CNTL_10__DMAChRun__SHIFT 0x1
131#define ACP_DMA_CNTL_10__DMAChIOCEn_MASK 0x4
132#define ACP_DMA_CNTL_10__DMAChIOCEn__SHIFT 0x2
133#define ACP_DMA_CNTL_10__Circular_DMA_En_MASK 0x8
134#define ACP_DMA_CNTL_10__Circular_DMA_En__SHIFT 0x3
135#define ACP_DMA_CNTL_10__DMAChGracefulRstEn_MASK 0x10
136#define ACP_DMA_CNTL_10__DMAChGracefulRstEn__SHIFT 0x4
137#define ACP_DMA_CNTL_11__DMAChRst_MASK 0x1
138#define ACP_DMA_CNTL_11__DMAChRst__SHIFT 0x0
139#define ACP_DMA_CNTL_11__DMAChRun_MASK 0x2
140#define ACP_DMA_CNTL_11__DMAChRun__SHIFT 0x1
141#define ACP_DMA_CNTL_11__DMAChIOCEn_MASK 0x4
142#define ACP_DMA_CNTL_11__DMAChIOCEn__SHIFT 0x2
143#define ACP_DMA_CNTL_11__Circular_DMA_En_MASK 0x8
144#define ACP_DMA_CNTL_11__Circular_DMA_En__SHIFT 0x3
145#define ACP_DMA_CNTL_11__DMAChGracefulRstEn_MASK 0x10
146#define ACP_DMA_CNTL_11__DMAChGracefulRstEn__SHIFT 0x4
147#define ACP_DMA_CNTL_12__DMAChRst_MASK 0x1
148#define ACP_DMA_CNTL_12__DMAChRst__SHIFT 0x0
149#define ACP_DMA_CNTL_12__DMAChRun_MASK 0x2
150#define ACP_DMA_CNTL_12__DMAChRun__SHIFT 0x1
151#define ACP_DMA_CNTL_12__DMAChIOCEn_MASK 0x4
152#define ACP_DMA_CNTL_12__DMAChIOCEn__SHIFT 0x2
153#define ACP_DMA_CNTL_12__Circular_DMA_En_MASK 0x8
154#define ACP_DMA_CNTL_12__Circular_DMA_En__SHIFT 0x3
155#define ACP_DMA_CNTL_12__DMAChGracefulRstEn_MASK 0x10
156#define ACP_DMA_CNTL_12__DMAChGracefulRstEn__SHIFT 0x4
157#define ACP_DMA_CNTL_13__DMAChRst_MASK 0x1
158#define ACP_DMA_CNTL_13__DMAChRst__SHIFT 0x0
159#define ACP_DMA_CNTL_13__DMAChRun_MASK 0x2
160#define ACP_DMA_CNTL_13__DMAChRun__SHIFT 0x1
161#define ACP_DMA_CNTL_13__DMAChIOCEn_MASK 0x4
162#define ACP_DMA_CNTL_13__DMAChIOCEn__SHIFT 0x2
163#define ACP_DMA_CNTL_13__Circular_DMA_En_MASK 0x8
164#define ACP_DMA_CNTL_13__Circular_DMA_En__SHIFT 0x3
165#define ACP_DMA_CNTL_13__DMAChGracefulRstEn_MASK 0x10
166#define ACP_DMA_CNTL_13__DMAChGracefulRstEn__SHIFT 0x4
167#define ACP_DMA_CNTL_14__DMAChRst_MASK 0x1
168#define ACP_DMA_CNTL_14__DMAChRst__SHIFT 0x0
169#define ACP_DMA_CNTL_14__DMAChRun_MASK 0x2
170#define ACP_DMA_CNTL_14__DMAChRun__SHIFT 0x1
171#define ACP_DMA_CNTL_14__DMAChIOCEn_MASK 0x4
172#define ACP_DMA_CNTL_14__DMAChIOCEn__SHIFT 0x2
173#define ACP_DMA_CNTL_14__Circular_DMA_En_MASK 0x8
174#define ACP_DMA_CNTL_14__Circular_DMA_En__SHIFT 0x3
175#define ACP_DMA_CNTL_14__DMAChGracefulRstEn_MASK 0x10
176#define ACP_DMA_CNTL_14__DMAChGracefulRstEn__SHIFT 0x4
177#define ACP_DMA_CNTL_15__DMAChRst_MASK 0x1
178#define ACP_DMA_CNTL_15__DMAChRst__SHIFT 0x0
179#define ACP_DMA_CNTL_15__DMAChRun_MASK 0x2
180#define ACP_DMA_CNTL_15__DMAChRun__SHIFT 0x1
181#define ACP_DMA_CNTL_15__DMAChIOCEn_MASK 0x4
182#define ACP_DMA_CNTL_15__DMAChIOCEn__SHIFT 0x2
183#define ACP_DMA_CNTL_15__Circular_DMA_En_MASK 0x8
184#define ACP_DMA_CNTL_15__Circular_DMA_En__SHIFT 0x3
185#define ACP_DMA_CNTL_15__DMAChGracefulRstEn_MASK 0x10
186#define ACP_DMA_CNTL_15__DMAChGracefulRstEn__SHIFT 0x4
187#define ACP_DMA_DSCR_STRT_IDX_0__DMAChDscrStrtIdx_MASK 0x3ff
188#define ACP_DMA_DSCR_STRT_IDX_0__DMAChDscrStrtIdx__SHIFT 0x0
189#define ACP_DMA_DSCR_STRT_IDX_1__DMAChDscrStrtIdx_MASK 0x3ff
190#define ACP_DMA_DSCR_STRT_IDX_1__DMAChDscrStrtIdx__SHIFT 0x0
191#define ACP_DMA_DSCR_STRT_IDX_2__DMAChDscrStrtIdx_MASK 0x3ff
192#define ACP_DMA_DSCR_STRT_IDX_2__DMAChDscrStrtIdx__SHIFT 0x0
193#define ACP_DMA_DSCR_STRT_IDX_3__DMAChDscrStrtIdx_MASK 0x3ff
194#define ACP_DMA_DSCR_STRT_IDX_3__DMAChDscrStrtIdx__SHIFT 0x0
195#define ACP_DMA_DSCR_STRT_IDX_4__DMAChDscrStrtIdx_MASK 0x3ff
196#define ACP_DMA_DSCR_STRT_IDX_4__DMAChDscrStrtIdx__SHIFT 0x0
197#define ACP_DMA_DSCR_STRT_IDX_5__DMAChDscrStrtIdx_MASK 0x3ff
198#define ACP_DMA_DSCR_STRT_IDX_5__DMAChDscrStrtIdx__SHIFT 0x0
199#define ACP_DMA_DSCR_STRT_IDX_6__DMAChDscrStrtIdx_MASK 0x3ff
200#define ACP_DMA_DSCR_STRT_IDX_6__DMAChDscrStrtIdx__SHIFT 0x0
201#define ACP_DMA_DSCR_STRT_IDX_7__DMAChDscrStrtIdx_MASK 0x3ff
202#define ACP_DMA_DSCR_STRT_IDX_7__DMAChDscrStrtIdx__SHIFT 0x0
203#define ACP_DMA_DSCR_STRT_IDX_8__DMAChDscrStrtIdx_MASK 0x3ff
204#define ACP_DMA_DSCR_STRT_IDX_8__DMAChDscrStrtIdx__SHIFT 0x0
205#define ACP_DMA_DSCR_STRT_IDX_9__DMAChDscrStrtIdx_MASK 0x3ff
206#define ACP_DMA_DSCR_STRT_IDX_9__DMAChDscrStrtIdx__SHIFT 0x0
207#define ACP_DMA_DSCR_STRT_IDX_10__DMAChDscrStrtIdx_MASK 0x3ff
208#define ACP_DMA_DSCR_STRT_IDX_10__DMAChDscrStrtIdx__SHIFT 0x0
209#define ACP_DMA_DSCR_STRT_IDX_11__DMAChDscrStrtIdx_MASK 0x3ff
210#define ACP_DMA_DSCR_STRT_IDX_11__DMAChDscrStrtIdx__SHIFT 0x0
211#define ACP_DMA_DSCR_STRT_IDX_12__DMAChDscrStrtIdx_MASK 0x3ff
212#define ACP_DMA_DSCR_STRT_IDX_12__DMAChDscrStrtIdx__SHIFT 0x0
213#define ACP_DMA_DSCR_STRT_IDX_13__DMAChDscrStrtIdx_MASK 0x3ff
214#define ACP_DMA_DSCR_STRT_IDX_13__DMAChDscrStrtIdx__SHIFT 0x0
215#define ACP_DMA_DSCR_STRT_IDX_14__DMAChDscrStrtIdx_MASK 0x3ff
216#define ACP_DMA_DSCR_STRT_IDX_14__DMAChDscrStrtIdx__SHIFT 0x0
217#define ACP_DMA_DSCR_STRT_IDX_15__DMAChDscrStrtIdx_MASK 0x3ff
218#define ACP_DMA_DSCR_STRT_IDX_15__DMAChDscrStrtIdx__SHIFT 0x0
219#define ACP_DMA_DSCR_CNT_0__DMAChDscrCnt_MASK 0x3ff
220#define ACP_DMA_DSCR_CNT_0__DMAChDscrCnt__SHIFT 0x0
221#define ACP_DMA_DSCR_CNT_1__DMAChDscrCnt_MASK 0x3ff
222#define ACP_DMA_DSCR_CNT_1__DMAChDscrCnt__SHIFT 0x0
223#define ACP_DMA_DSCR_CNT_2__DMAChDscrCnt_MASK 0x3ff
224#define ACP_DMA_DSCR_CNT_2__DMAChDscrCnt__SHIFT 0x0
225#define ACP_DMA_DSCR_CNT_3__DMAChDscrCnt_MASK 0x3ff
226#define ACP_DMA_DSCR_CNT_3__DMAChDscrCnt__SHIFT 0x0
227#define ACP_DMA_DSCR_CNT_4__DMAChDscrCnt_MASK 0x3ff
228#define ACP_DMA_DSCR_CNT_4__DMAChDscrCnt__SHIFT 0x0
229#define ACP_DMA_DSCR_CNT_5__DMAChDscrCnt_MASK 0x3ff
230#define ACP_DMA_DSCR_CNT_5__DMAChDscrCnt__SHIFT 0x0
231#define ACP_DMA_DSCR_CNT_6__DMAChDscrCnt_MASK 0x3ff
232#define ACP_DMA_DSCR_CNT_6__DMAChDscrCnt__SHIFT 0x0
233#define ACP_DMA_DSCR_CNT_7__DMAChDscrCnt_MASK 0x3ff
234#define ACP_DMA_DSCR_CNT_7__DMAChDscrCnt__SHIFT 0x0
235#define ACP_DMA_DSCR_CNT_8__DMAChDscrCnt_MASK 0x3ff
236#define ACP_DMA_DSCR_CNT_8__DMAChDscrCnt__SHIFT 0x0
237#define ACP_DMA_DSCR_CNT_9__DMAChDscrCnt_MASK 0x3ff
238#define ACP_DMA_DSCR_CNT_9__DMAChDscrCnt__SHIFT 0x0
239#define ACP_DMA_DSCR_CNT_10__DMAChDscrCnt_MASK 0x3ff
240#define ACP_DMA_DSCR_CNT_10__DMAChDscrCnt__SHIFT 0x0
241#define ACP_DMA_DSCR_CNT_11__DMAChDscrCnt_MASK 0x3ff
242#define ACP_DMA_DSCR_CNT_11__DMAChDscrCnt__SHIFT 0x0
243#define ACP_DMA_DSCR_CNT_12__DMAChDscrCnt_MASK 0x3ff
244#define ACP_DMA_DSCR_CNT_12__DMAChDscrCnt__SHIFT 0x0
245#define ACP_DMA_DSCR_CNT_13__DMAChDscrCnt_MASK 0x3ff
246#define ACP_DMA_DSCR_CNT_13__DMAChDscrCnt__SHIFT 0x0
247#define ACP_DMA_DSCR_CNT_14__DMAChDscrCnt_MASK 0x3ff
248#define ACP_DMA_DSCR_CNT_14__DMAChDscrCnt__SHIFT 0x0
249#define ACP_DMA_DSCR_CNT_15__DMAChDscrCnt_MASK 0x3ff
250#define ACP_DMA_DSCR_CNT_15__DMAChDscrCnt__SHIFT 0x0
251#define ACP_DMA_PRIO_0__DMAChPrioLvl_MASK 0x1
252#define ACP_DMA_PRIO_0__DMAChPrioLvl__SHIFT 0x0
253#define ACP_DMA_PRIO_1__DMAChPrioLvl_MASK 0x1
254#define ACP_DMA_PRIO_1__DMAChPrioLvl__SHIFT 0x0
255#define ACP_DMA_PRIO_2__DMAChPrioLvl_MASK 0x1
256#define ACP_DMA_PRIO_2__DMAChPrioLvl__SHIFT 0x0
257#define ACP_DMA_PRIO_3__DMAChPrioLvl_MASK 0x1
258#define ACP_DMA_PRIO_3__DMAChPrioLvl__SHIFT 0x0
259#define ACP_DMA_PRIO_4__DMAChPrioLvl_MASK 0x1
260#define ACP_DMA_PRIO_4__DMAChPrioLvl__SHIFT 0x0
261#define ACP_DMA_PRIO_5__DMAChPrioLvl_MASK 0x1
262#define ACP_DMA_PRIO_5__DMAChPrioLvl__SHIFT 0x0
263#define ACP_DMA_PRIO_6__DMAChPrioLvl_MASK 0x1
264#define ACP_DMA_PRIO_6__DMAChPrioLvl__SHIFT 0x0
265#define ACP_DMA_PRIO_7__DMAChPrioLvl_MASK 0x1
266#define ACP_DMA_PRIO_7__DMAChPrioLvl__SHIFT 0x0
267#define ACP_DMA_PRIO_8__DMAChPrioLvl_MASK 0x1
268#define ACP_DMA_PRIO_8__DMAChPrioLvl__SHIFT 0x0
269#define ACP_DMA_PRIO_9__DMAChPrioLvl_MASK 0x1
270#define ACP_DMA_PRIO_9__DMAChPrioLvl__SHIFT 0x0
271#define ACP_DMA_PRIO_10__DMAChPrioLvl_MASK 0x1
272#define ACP_DMA_PRIO_10__DMAChPrioLvl__SHIFT 0x0
273#define ACP_DMA_PRIO_11__DMAChPrioLvl_MASK 0x1
274#define ACP_DMA_PRIO_11__DMAChPrioLvl__SHIFT 0x0
275#define ACP_DMA_PRIO_12__DMAChPrioLvl_MASK 0x1
276#define ACP_DMA_PRIO_12__DMAChPrioLvl__SHIFT 0x0
277#define ACP_DMA_PRIO_13__DMAChPrioLvl_MASK 0x1
278#define ACP_DMA_PRIO_13__DMAChPrioLvl__SHIFT 0x0
279#define ACP_DMA_PRIO_14__DMAChPrioLvl_MASK 0x1
280#define ACP_DMA_PRIO_14__DMAChPrioLvl__SHIFT 0x0
281#define ACP_DMA_PRIO_15__DMAChPrioLvl_MASK 0x1
282#define ACP_DMA_PRIO_15__DMAChPrioLvl__SHIFT 0x0
283#define ACP_DMA_CUR_DSCR_0__DMAChCurDscrIdx_MASK 0x3ff
284#define ACP_DMA_CUR_DSCR_0__DMAChCurDscrIdx__SHIFT 0x0
285#define ACP_DMA_CUR_DSCR_1__DMAChCurDscrIdx_MASK 0x3ff
286#define ACP_DMA_CUR_DSCR_1__DMAChCurDscrIdx__SHIFT 0x0
287#define ACP_DMA_CUR_DSCR_2__DMAChCurDscrIdx_MASK 0x3ff
288#define ACP_DMA_CUR_DSCR_2__DMAChCurDscrIdx__SHIFT 0x0
289#define ACP_DMA_CUR_DSCR_3__DMAChCurDscrIdx_MASK 0x3ff
290#define ACP_DMA_CUR_DSCR_3__DMAChCurDscrIdx__SHIFT 0x0
291#define ACP_DMA_CUR_DSCR_4__DMAChCurDscrIdx_MASK 0x3ff
292#define ACP_DMA_CUR_DSCR_4__DMAChCurDscrIdx__SHIFT 0x0
293#define ACP_DMA_CUR_DSCR_5__DMAChCurDscrIdx_MASK 0x3ff
294#define ACP_DMA_CUR_DSCR_5__DMAChCurDscrIdx__SHIFT 0x0
295#define ACP_DMA_CUR_DSCR_6__DMAChCurDscrIdx_MASK 0x3ff
296#define ACP_DMA_CUR_DSCR_6__DMAChCurDscrIdx__SHIFT 0x0
297#define ACP_DMA_CUR_DSCR_7__DMAChCurDscrIdx_MASK 0x3ff
298#define ACP_DMA_CUR_DSCR_7__DMAChCurDscrIdx__SHIFT 0x0
299#define ACP_DMA_CUR_DSCR_8__DMAChCurDscrIdx_MASK 0x3ff
300#define ACP_DMA_CUR_DSCR_8__DMAChCurDscrIdx__SHIFT 0x0
301#define ACP_DMA_CUR_DSCR_9__DMAChCurDscrIdx_MASK 0x3ff
302#define ACP_DMA_CUR_DSCR_9__DMAChCurDscrIdx__SHIFT 0x0
303#define ACP_DMA_CUR_DSCR_10__DMAChCurDscrIdx_MASK 0x3ff
304#define ACP_DMA_CUR_DSCR_10__DMAChCurDscrIdx__SHIFT 0x0
305#define ACP_DMA_CUR_DSCR_11__DMAChCurDscrIdx_MASK 0x3ff
306#define ACP_DMA_CUR_DSCR_11__DMAChCurDscrIdx__SHIFT 0x0
307#define ACP_DMA_CUR_DSCR_12__DMAChCurDscrIdx_MASK 0x3ff
308#define ACP_DMA_CUR_DSCR_12__DMAChCurDscrIdx__SHIFT 0x0
309#define ACP_DMA_CUR_DSCR_13__DMAChCurDscrIdx_MASK 0x3ff
310#define ACP_DMA_CUR_DSCR_13__DMAChCurDscrIdx__SHIFT 0x0
311#define ACP_DMA_CUR_DSCR_14__DMAChCurDscrIdx_MASK 0x3ff
312#define ACP_DMA_CUR_DSCR_14__DMAChCurDscrIdx__SHIFT 0x0
313#define ACP_DMA_CUR_DSCR_15__DMAChCurDscrIdx_MASK 0x3ff
314#define ACP_DMA_CUR_DSCR_15__DMAChCurDscrIdx__SHIFT 0x0
315#define ACP_DMA_CUR_TRANS_CNT_0__DMAChCurTransCnt_MASK 0x1ffff
316#define ACP_DMA_CUR_TRANS_CNT_0__DMAChCurTransCnt__SHIFT 0x0
317#define ACP_DMA_CUR_TRANS_CNT_1__DMAChCurTransCnt_MASK 0x1ffff
318#define ACP_DMA_CUR_TRANS_CNT_1__DMAChCurTransCnt__SHIFT 0x0
319#define ACP_DMA_CUR_TRANS_CNT_2__DMAChCurTransCnt_MASK 0x1ffff
320#define ACP_DMA_CUR_TRANS_CNT_2__DMAChCurTransCnt__SHIFT 0x0
321#define ACP_DMA_CUR_TRANS_CNT_3__DMAChCurTransCnt_MASK 0x1ffff
322#define ACP_DMA_CUR_TRANS_CNT_3__DMAChCurTransCnt__SHIFT 0x0
323#define ACP_DMA_CUR_TRANS_CNT_4__DMAChCurTransCnt_MASK 0x1ffff
324#define ACP_DMA_CUR_TRANS_CNT_4__DMAChCurTransCnt__SHIFT 0x0
325#define ACP_DMA_CUR_TRANS_CNT_5__DMAChCurTransCnt_MASK 0x1ffff
326#define ACP_DMA_CUR_TRANS_CNT_5__DMAChCurTransCnt__SHIFT 0x0
327#define ACP_DMA_CUR_TRANS_CNT_6__DMAChCurTransCnt_MASK 0x1ffff
328#define ACP_DMA_CUR_TRANS_CNT_6__DMAChCurTransCnt__SHIFT 0x0
329#define ACP_DMA_CUR_TRANS_CNT_7__DMAChCurTransCnt_MASK 0x1ffff
330#define ACP_DMA_CUR_TRANS_CNT_7__DMAChCurTransCnt__SHIFT 0x0
331#define ACP_DMA_CUR_TRANS_CNT_8__DMAChCurTransCnt_MASK 0x1ffff
332#define ACP_DMA_CUR_TRANS_CNT_8__DMAChCurTransCnt__SHIFT 0x0
333#define ACP_DMA_CUR_TRANS_CNT_9__DMAChCurTransCnt_MASK 0x1ffff
334#define ACP_DMA_CUR_TRANS_CNT_9__DMAChCurTransCnt__SHIFT 0x0
335#define ACP_DMA_CUR_TRANS_CNT_10__DMAChCurTransCnt_MASK 0x1ffff
336#define ACP_DMA_CUR_TRANS_CNT_10__DMAChCurTransCnt__SHIFT 0x0
337#define ACP_DMA_CUR_TRANS_CNT_11__DMAChCurTransCnt_MASK 0x1ffff
338#define ACP_DMA_CUR_TRANS_CNT_11__DMAChCurTransCnt__SHIFT 0x0
339#define ACP_DMA_CUR_TRANS_CNT_12__DMAChCurTransCnt_MASK 0x1ffff
340#define ACP_DMA_CUR_TRANS_CNT_12__DMAChCurTransCnt__SHIFT 0x0
341#define ACP_DMA_CUR_TRANS_CNT_13__DMAChCurTransCnt_MASK 0x1ffff
342#define ACP_DMA_CUR_TRANS_CNT_13__DMAChCurTransCnt__SHIFT 0x0
343#define ACP_DMA_CUR_TRANS_CNT_14__DMAChCurTransCnt_MASK 0x1ffff
344#define ACP_DMA_CUR_TRANS_CNT_14__DMAChCurTransCnt__SHIFT 0x0
345#define ACP_DMA_CUR_TRANS_CNT_15__DMAChCurTransCnt_MASK 0x1ffff
346#define ACP_DMA_CUR_TRANS_CNT_15__DMAChCurTransCnt__SHIFT 0x0
347#define ACP_DMA_ERR_STS_0__DMAChTermErr_MASK 0x1
348#define ACP_DMA_ERR_STS_0__DMAChTermErr__SHIFT 0x0
349#define ACP_DMA_ERR_STS_0__DMAChErrCode_MASK 0x1e
350#define ACP_DMA_ERR_STS_0__DMAChErrCode__SHIFT 0x1
351#define ACP_DMA_ERR_STS_1__DMAChTermErr_MASK 0x1
352#define ACP_DMA_ERR_STS_1__DMAChTermErr__SHIFT 0x0
353#define ACP_DMA_ERR_STS_1__DMAChErrCode_MASK 0x1e
354#define ACP_DMA_ERR_STS_1__DMAChErrCode__SHIFT 0x1
355#define ACP_DMA_ERR_STS_2__DMAChTermErr_MASK 0x1
356#define ACP_DMA_ERR_STS_2__DMAChTermErr__SHIFT 0x0
357#define ACP_DMA_ERR_STS_2__DMAChErrCode_MASK 0x1e
358#define ACP_DMA_ERR_STS_2__DMAChErrCode__SHIFT 0x1
359#define ACP_DMA_ERR_STS_3__DMAChTermErr_MASK 0x1
360#define ACP_DMA_ERR_STS_3__DMAChTermErr__SHIFT 0x0
361#define ACP_DMA_ERR_STS_3__DMAChErrCode_MASK 0x1e
362#define ACP_DMA_ERR_STS_3__DMAChErrCode__SHIFT 0x1
363#define ACP_DMA_ERR_STS_4__DMAChTermErr_MASK 0x1
364#define ACP_DMA_ERR_STS_4__DMAChTermErr__SHIFT 0x0
365#define ACP_DMA_ERR_STS_4__DMAChErrCode_MASK 0x1e
366#define ACP_DMA_ERR_STS_4__DMAChErrCode__SHIFT 0x1
367#define ACP_DMA_ERR_STS_5__DMAChTermErr_MASK 0x1
368#define ACP_DMA_ERR_STS_5__DMAChTermErr__SHIFT 0x0
369#define ACP_DMA_ERR_STS_5__DMAChErrCode_MASK 0x1e
370#define ACP_DMA_ERR_STS_5__DMAChErrCode__SHIFT 0x1
371#define ACP_DMA_ERR_STS_6__DMAChTermErr_MASK 0x1
372#define ACP_DMA_ERR_STS_6__DMAChTermErr__SHIFT 0x0
373#define ACP_DMA_ERR_STS_6__DMAChErrCode_MASK 0x1e
374#define ACP_DMA_ERR_STS_6__DMAChErrCode__SHIFT 0x1
375#define ACP_DMA_ERR_STS_7__DMAChTermErr_MASK 0x1
376#define ACP_DMA_ERR_STS_7__DMAChTermErr__SHIFT 0x0
377#define ACP_DMA_ERR_STS_7__DMAChErrCode_MASK 0x1e
378#define ACP_DMA_ERR_STS_7__DMAChErrCode__SHIFT 0x1
379#define ACP_DMA_ERR_STS_8__DMAChTermErr_MASK 0x1
380#define ACP_DMA_ERR_STS_8__DMAChTermErr__SHIFT 0x0
381#define ACP_DMA_ERR_STS_8__DMAChErrCode_MASK 0x1e
382#define ACP_DMA_ERR_STS_8__DMAChErrCode__SHIFT 0x1
383#define ACP_DMA_ERR_STS_9__DMAChTermErr_MASK 0x1
384#define ACP_DMA_ERR_STS_9__DMAChTermErr__SHIFT 0x0
385#define ACP_DMA_ERR_STS_9__DMAChErrCode_MASK 0x1e
386#define ACP_DMA_ERR_STS_9__DMAChErrCode__SHIFT 0x1
387#define ACP_DMA_ERR_STS_10__DMAChTermErr_MASK 0x1
388#define ACP_DMA_ERR_STS_10__DMAChTermErr__SHIFT 0x0
389#define ACP_DMA_ERR_STS_10__DMAChErrCode_MASK 0x1e
390#define ACP_DMA_ERR_STS_10__DMAChErrCode__SHIFT 0x1
391#define ACP_DMA_ERR_STS_11__DMAChTermErr_MASK 0x1
392#define ACP_DMA_ERR_STS_11__DMAChTermErr__SHIFT 0x0
393#define ACP_DMA_ERR_STS_11__DMAChErrCode_MASK 0x1e
394#define ACP_DMA_ERR_STS_11__DMAChErrCode__SHIFT 0x1
395#define ACP_DMA_ERR_STS_12__DMAChTermErr_MASK 0x1
396#define ACP_DMA_ERR_STS_12__DMAChTermErr__SHIFT 0x0
397#define ACP_DMA_ERR_STS_12__DMAChErrCode_MASK 0x1e
398#define ACP_DMA_ERR_STS_12__DMAChErrCode__SHIFT 0x1
399#define ACP_DMA_ERR_STS_13__DMAChTermErr_MASK 0x1
400#define ACP_DMA_ERR_STS_13__DMAChTermErr__SHIFT 0x0
401#define ACP_DMA_ERR_STS_13__DMAChErrCode_MASK 0x1e
402#define ACP_DMA_ERR_STS_13__DMAChErrCode__SHIFT 0x1
403#define ACP_DMA_ERR_STS_14__DMAChTermErr_MASK 0x1
404#define ACP_DMA_ERR_STS_14__DMAChTermErr__SHIFT 0x0
405#define ACP_DMA_ERR_STS_14__DMAChErrCode_MASK 0x1e
406#define ACP_DMA_ERR_STS_14__DMAChErrCode__SHIFT 0x1
407#define ACP_DMA_ERR_STS_15__DMAChTermErr_MASK 0x1
408#define ACP_DMA_ERR_STS_15__DMAChTermErr__SHIFT 0x0
409#define ACP_DMA_ERR_STS_15__DMAChErrCode_MASK 0x1e
410#define ACP_DMA_ERR_STS_15__DMAChErrCode__SHIFT 0x1
411#define ACP_DMA_DESC_BASE_ADDR__DescriptorBaseAddr_MASK 0xffffffff
412#define ACP_DMA_DESC_BASE_ADDR__DescriptorBaseAddr__SHIFT 0x0
413#define ACP_DMA_DESC_MAX_NUM_DSCR__MaximumNumberDescr_MASK 0xf
414#define ACP_DMA_DESC_MAX_NUM_DSCR__MaximumNumberDescr__SHIFT 0x0
415#define ACP_DMA_CH_STS__DMAChSts_MASK 0xffff
416#define ACP_DMA_CH_STS__DMAChSts__SHIFT 0x0
417#define ACP_DMA_CH_GROUP__DMAChanelGrouping_MASK 0x1
418#define ACP_DMA_CH_GROUP__DMAChanelGrouping__SHIFT 0x0
419#define ACP_DSP0_CACHE_OFFSET0__Offset_MASK 0xfffffff
420#define ACP_DSP0_CACHE_OFFSET0__Offset__SHIFT 0x0
421#define ACP_DSP0_CACHE_OFFSET0__OnionGarlicSel_MASK 0x80000000
422#define ACP_DSP0_CACHE_OFFSET0__OnionGarlicSel__SHIFT 0x1f
423#define ACP_DSP0_CACHE_SIZE0__Size_MASK 0xffffff
424#define ACP_DSP0_CACHE_SIZE0__Size__SHIFT 0x0
425#define ACP_DSP0_CACHE_SIZE0__PageEnable_MASK 0x80000000
426#define ACP_DSP0_CACHE_SIZE0__PageEnable__SHIFT 0x1f
427#define ACP_DSP0_CACHE_OFFSET1__Offset_MASK 0xfffffff
428#define ACP_DSP0_CACHE_OFFSET1__Offset__SHIFT 0x0
429#define ACP_DSP0_CACHE_OFFSET1__OnionGarlicSel_MASK 0x80000000
430#define ACP_DSP0_CACHE_OFFSET1__OnionGarlicSel__SHIFT 0x1f
431#define ACP_DSP0_CACHE_SIZE1__Size_MASK 0xffffff
432#define ACP_DSP0_CACHE_SIZE1__Size__SHIFT 0x0
433#define ACP_DSP0_CACHE_SIZE1__PageEnable_MASK 0x80000000
434#define ACP_DSP0_CACHE_SIZE1__PageEnable__SHIFT 0x1f
435#define ACP_DSP0_CACHE_OFFSET2__Offset_MASK 0xfffffff
436#define ACP_DSP0_CACHE_OFFSET2__Offset__SHIFT 0x0
437#define ACP_DSP0_CACHE_OFFSET2__OnionGarlicSel_MASK 0x80000000
438#define ACP_DSP0_CACHE_OFFSET2__OnionGarlicSel__SHIFT 0x1f
439#define ACP_DSP0_CACHE_SIZE2__Size_MASK 0xffffff
440#define ACP_DSP0_CACHE_SIZE2__Size__SHIFT 0x0
441#define ACP_DSP0_CACHE_SIZE2__PageEnable_MASK 0x80000000
442#define ACP_DSP0_CACHE_SIZE2__PageEnable__SHIFT 0x1f
443#define ACP_DSP0_CACHE_OFFSET3__Offset_MASK 0xfffffff
444#define ACP_DSP0_CACHE_OFFSET3__Offset__SHIFT 0x0
445#define ACP_DSP0_CACHE_OFFSET3__OnionGarlicSel_MASK 0x80000000
446#define ACP_DSP0_CACHE_OFFSET3__OnionGarlicSel__SHIFT 0x1f
447#define ACP_DSP0_CACHE_SIZE3__Size_MASK 0xffffff
448#define ACP_DSP0_CACHE_SIZE3__Size__SHIFT 0x0
449#define ACP_DSP0_CACHE_SIZE3__PageEnable_MASK 0x80000000
450#define ACP_DSP0_CACHE_SIZE3__PageEnable__SHIFT 0x1f
451#define ACP_DSP0_CACHE_OFFSET4__Offset_MASK 0xfffffff
452#define ACP_DSP0_CACHE_OFFSET4__Offset__SHIFT 0x0
453#define ACP_DSP0_CACHE_OFFSET4__OnionGarlicSel_MASK 0x80000000
454#define ACP_DSP0_CACHE_OFFSET4__OnionGarlicSel__SHIFT 0x1f
455#define ACP_DSP0_CACHE_SIZE4__Size_MASK 0xffffff
456#define ACP_DSP0_CACHE_SIZE4__Size__SHIFT 0x0
457#define ACP_DSP0_CACHE_SIZE4__PageEnable_MASK 0x80000000
458#define ACP_DSP0_CACHE_SIZE4__PageEnable__SHIFT 0x1f
459#define ACP_DSP0_CACHE_OFFSET5__Offset_MASK 0xfffffff
460#define ACP_DSP0_CACHE_OFFSET5__Offset__SHIFT 0x0
461#define ACP_DSP0_CACHE_OFFSET5__OnionGarlicSel_MASK 0x80000000
462#define ACP_DSP0_CACHE_OFFSET5__OnionGarlicSel__SHIFT 0x1f
463#define ACP_DSP0_CACHE_SIZE5__Size_MASK 0xffffff
464#define ACP_DSP0_CACHE_SIZE5__Size__SHIFT 0x0
465#define ACP_DSP0_CACHE_SIZE5__PageEnable_MASK 0x80000000
466#define ACP_DSP0_CACHE_SIZE5__PageEnable__SHIFT 0x1f
467#define ACP_DSP0_CACHE_OFFSET6__Offset_MASK 0xfffffff
468#define ACP_DSP0_CACHE_OFFSET6__Offset__SHIFT 0x0
469#define ACP_DSP0_CACHE_OFFSET6__OnionGarlicSel_MASK 0x80000000
470#define ACP_DSP0_CACHE_OFFSET6__OnionGarlicSel__SHIFT 0x1f
471#define ACP_DSP0_CACHE_SIZE6__Size_MASK 0xffffff
472#define ACP_DSP0_CACHE_SIZE6__Size__SHIFT 0x0
473#define ACP_DSP0_CACHE_SIZE6__PageEnable_MASK 0x80000000
474#define ACP_DSP0_CACHE_SIZE6__PageEnable__SHIFT 0x1f
475#define ACP_DSP0_CACHE_OFFSET7__Offset_MASK 0xfffffff
476#define ACP_DSP0_CACHE_OFFSET7__Offset__SHIFT 0x0
477#define ACP_DSP0_CACHE_OFFSET7__OnionGarlicSel_MASK 0x80000000
478#define ACP_DSP0_CACHE_OFFSET7__OnionGarlicSel__SHIFT 0x1f
479#define ACP_DSP0_CACHE_SIZE7__Size_MASK 0xffffff
480#define ACP_DSP0_CACHE_SIZE7__Size__SHIFT 0x0
481#define ACP_DSP0_CACHE_SIZE7__PageEnable_MASK 0x80000000
482#define ACP_DSP0_CACHE_SIZE7__PageEnable__SHIFT 0x1f
483#define ACP_DSP0_CACHE_OFFSET8__Offset_MASK 0xfffffff
484#define ACP_DSP0_CACHE_OFFSET8__Offset__SHIFT 0x0
485#define ACP_DSP0_CACHE_OFFSET8__OnionGarlicSel_MASK 0x80000000
486#define ACP_DSP0_CACHE_OFFSET8__OnionGarlicSel__SHIFT 0x1f
487#define ACP_DSP0_CACHE_SIZE8__Size_MASK 0xffffff
488#define ACP_DSP0_CACHE_SIZE8__Size__SHIFT 0x0
489#define ACP_DSP0_CACHE_SIZE8__PageEnable_MASK 0x80000000
490#define ACP_DSP0_CACHE_SIZE8__PageEnable__SHIFT 0x1f
491#define ACP_DSP0_NONCACHE_OFFSET0__Offset_MASK 0xfffffff
492#define ACP_DSP0_NONCACHE_OFFSET0__Offset__SHIFT 0x0
493#define ACP_DSP0_NONCACHE_OFFSET0__OnionGarlicSel_MASK 0x80000000
494#define ACP_DSP0_NONCACHE_OFFSET0__OnionGarlicSel__SHIFT 0x1f
495#define ACP_DSP0_NONCACHE_SIZE0__Size_MASK 0xffffff
496#define ACP_DSP0_NONCACHE_SIZE0__Size__SHIFT 0x0
497#define ACP_DSP0_NONCACHE_SIZE0__PageEnable_MASK 0x80000000
498#define ACP_DSP0_NONCACHE_SIZE0__PageEnable__SHIFT 0x1f
499#define ACP_DSP0_NONCACHE_OFFSET1__Offset_MASK 0xfffffff
500#define ACP_DSP0_NONCACHE_OFFSET1__Offset__SHIFT 0x0
501#define ACP_DSP0_NONCACHE_OFFSET1__OnionGarlicSel_MASK 0x80000000
502#define ACP_DSP0_NONCACHE_OFFSET1__OnionGarlicSel__SHIFT 0x1f
503#define ACP_DSP0_NONCACHE_SIZE1__Size_MASK 0xffffff
504#define ACP_DSP0_NONCACHE_SIZE1__Size__SHIFT 0x0
505#define ACP_DSP0_NONCACHE_SIZE1__PageEnable_MASK 0x80000000
506#define ACP_DSP0_NONCACHE_SIZE1__PageEnable__SHIFT 0x1f
507#define ACP_DSP0_DEBUG_PC__DebugPC_MASK 0xffffffff
508#define ACP_DSP0_DEBUG_PC__DebugPC__SHIFT 0x0
509#define ACP_DSP0_NMI_SEL__NMISel_MASK 0x1
510#define ACP_DSP0_NMI_SEL__NMISel__SHIFT 0x0
511#define ACP_DSP0_CLKRST_CNTL__ClkEn_MASK 0x1
512#define ACP_DSP0_CLKRST_CNTL__ClkEn__SHIFT 0x0
513#define ACP_DSP0_CLKRST_CNTL__SoftResetDSP_MASK 0x2
514#define ACP_DSP0_CLKRST_CNTL__SoftResetDSP__SHIFT 0x1
515#define ACP_DSP0_CLKRST_CNTL__InternalSoftResetMode_MASK 0x4
516#define ACP_DSP0_CLKRST_CNTL__InternalSoftResetMode__SHIFT 0x2
517#define ACP_DSP0_CLKRST_CNTL__ExternalSoftResetMode_MASK 0x8
518#define ACP_DSP0_CLKRST_CNTL__ExternalSoftResetMode__SHIFT 0x3
519#define ACP_DSP0_CLKRST_CNTL__SoftResetDSPDone_MASK 0x10
520#define ACP_DSP0_CLKRST_CNTL__SoftResetDSPDone__SHIFT 0x4
521#define ACP_DSP0_CLKRST_CNTL__Clk_ON_Status_MASK 0x20
522#define ACP_DSP0_CLKRST_CNTL__Clk_ON_Status__SHIFT 0x5
523#define ACP_DSP0_RUNSTALL__RunStallCntl_MASK 0x1
524#define ACP_DSP0_RUNSTALL__RunStallCntl__SHIFT 0x0
525#define ACP_DSP0_OCD_HALT_ON_RST__OCD_HALT_ON_RST_MASK 0x1
526#define ACP_DSP0_OCD_HALT_ON_RST__OCD_HALT_ON_RST__SHIFT 0x0
527#define ACP_DSP0_WAIT_MODE__WaitMode_MASK 0x1
528#define ACP_DSP0_WAIT_MODE__WaitMode__SHIFT 0x0
529#define ACP_DSP0_VECT_SEL__StaticVectorSel_MASK 0x1
530#define ACP_DSP0_VECT_SEL__StaticVectorSel__SHIFT 0x0
531#define ACP_DSP0_DEBUG_REG1__ACP_DSP_DEBUG_REG1_MASK 0xffffffff
532#define ACP_DSP0_DEBUG_REG1__ACP_DSP_DEBUG_REG1__SHIFT 0x0
533#define ACP_DSP0_DEBUG_REG2__ACP_DSP_DEBUG_REG2_MASK 0xffffffff
534#define ACP_DSP0_DEBUG_REG2__ACP_DSP_DEBUG_REG2__SHIFT 0x0
535#define ACP_DSP0_DEBUG_REG3__ACP_DSP_DEBUG_REG3_MASK 0xffffffff
536#define ACP_DSP0_DEBUG_REG3__ACP_DSP_DEBUG_REG3__SHIFT 0x0
537#define ACP_DSP1_CACHE_OFFSET0__Offset_MASK 0xfffffff
538#define ACP_DSP1_CACHE_OFFSET0__Offset__SHIFT 0x0
539#define ACP_DSP1_CACHE_OFFSET0__OnionGarlicSel_MASK 0x80000000
540#define ACP_DSP1_CACHE_OFFSET0__OnionGarlicSel__SHIFT 0x1f
541#define ACP_DSP1_CACHE_SIZE0__Size_MASK 0xffffff
542#define ACP_DSP1_CACHE_SIZE0__Size__SHIFT 0x0
543#define ACP_DSP1_CACHE_SIZE0__PageEnable_MASK 0x80000000
544#define ACP_DSP1_CACHE_SIZE0__PageEnable__SHIFT 0x1f
545#define ACP_DSP1_CACHE_OFFSET1__Offset_MASK 0xfffffff
546#define ACP_DSP1_CACHE_OFFSET1__Offset__SHIFT 0x0
547#define ACP_DSP1_CACHE_OFFSET1__OnionGarlicSel_MASK 0x80000000
548#define ACP_DSP1_CACHE_OFFSET1__OnionGarlicSel__SHIFT 0x1f
549#define ACP_DSP1_CACHE_SIZE1__Size_MASK 0xffffff
550#define ACP_DSP1_CACHE_SIZE1__Size__SHIFT 0x0
551#define ACP_DSP1_CACHE_SIZE1__PageEnable_MASK 0x80000000
552#define ACP_DSP1_CACHE_SIZE1__PageEnable__SHIFT 0x1f
553#define ACP_DSP1_CACHE_OFFSET2__Offset_MASK 0xfffffff
554#define ACP_DSP1_CACHE_OFFSET2__Offset__SHIFT 0x0
555#define ACP_DSP1_CACHE_OFFSET2__OnionGarlicSel_MASK 0x80000000
556#define ACP_DSP1_CACHE_OFFSET2__OnionGarlicSel__SHIFT 0x1f
557#define ACP_DSP1_CACHE_SIZE2__Size_MASK 0xffffff
558#define ACP_DSP1_CACHE_SIZE2__Size__SHIFT 0x0
559#define ACP_DSP1_CACHE_SIZE2__PageEnable_MASK 0x80000000
560#define ACP_DSP1_CACHE_SIZE2__PageEnable__SHIFT 0x1f
561#define ACP_DSP1_CACHE_OFFSET3__Offset_MASK 0xfffffff
562#define ACP_DSP1_CACHE_OFFSET3__Offset__SHIFT 0x0
563#define ACP_DSP1_CACHE_OFFSET3__OnionGarlicSel_MASK 0x80000000
564#define ACP_DSP1_CACHE_OFFSET3__OnionGarlicSel__SHIFT 0x1f
565#define ACP_DSP1_CACHE_SIZE3__Size_MASK 0xffffff
566#define ACP_DSP1_CACHE_SIZE3__Size__SHIFT 0x0
567#define ACP_DSP1_CACHE_SIZE3__PageEnable_MASK 0x80000000
568#define ACP_DSP1_CACHE_SIZE3__PageEnable__SHIFT 0x1f
569#define ACP_DSP1_CACHE_OFFSET4__Offset_MASK 0xfffffff
570#define ACP_DSP1_CACHE_OFFSET4__Offset__SHIFT 0x0
571#define ACP_DSP1_CACHE_OFFSET4__OnionGarlicSel_MASK 0x80000000
572#define ACP_DSP1_CACHE_OFFSET4__OnionGarlicSel__SHIFT 0x1f
573#define ACP_DSP1_CACHE_SIZE4__Size_MASK 0xffffff
574#define ACP_DSP1_CACHE_SIZE4__Size__SHIFT 0x0
575#define ACP_DSP1_CACHE_SIZE4__PageEnable_MASK 0x80000000
576#define ACP_DSP1_CACHE_SIZE4__PageEnable__SHIFT 0x1f
577#define ACP_DSP1_CACHE_OFFSET5__Offset_MASK 0xfffffff
578#define ACP_DSP1_CACHE_OFFSET5__Offset__SHIFT 0x0
579#define ACP_DSP1_CACHE_OFFSET5__OnionGarlicSel_MASK 0x80000000
580#define ACP_DSP1_CACHE_OFFSET5__OnionGarlicSel__SHIFT 0x1f
581#define ACP_DSP1_CACHE_SIZE5__Size_MASK 0xffffff
582#define ACP_DSP1_CACHE_SIZE5__Size__SHIFT 0x0
583#define ACP_DSP1_CACHE_SIZE5__PageEnable_MASK 0x80000000
584#define ACP_DSP1_CACHE_SIZE5__PageEnable__SHIFT 0x1f
585#define ACP_DSP1_CACHE_OFFSET6__Offset_MASK 0xfffffff
586#define ACP_DSP1_CACHE_OFFSET6__Offset__SHIFT 0x0
587#define ACP_DSP1_CACHE_OFFSET6__OnionGarlicSel_MASK 0x80000000
588#define ACP_DSP1_CACHE_OFFSET6__OnionGarlicSel__SHIFT 0x1f
589#define ACP_DSP1_CACHE_SIZE6__Size_MASK 0xffffff
590#define ACP_DSP1_CACHE_SIZE6__Size__SHIFT 0x0
591#define ACP_DSP1_CACHE_SIZE6__PageEnable_MASK 0x80000000
592#define ACP_DSP1_CACHE_SIZE6__PageEnable__SHIFT 0x1f
593#define ACP_DSP1_CACHE_OFFSET7__Offset_MASK 0xfffffff
594#define ACP_DSP1_CACHE_OFFSET7__Offset__SHIFT 0x0
595#define ACP_DSP1_CACHE_OFFSET7__OnionGarlicSel_MASK 0x80000000
596#define ACP_DSP1_CACHE_OFFSET7__OnionGarlicSel__SHIFT 0x1f
597#define ACP_DSP1_CACHE_SIZE7__Size_MASK 0xffffff
598#define ACP_DSP1_CACHE_SIZE7__Size__SHIFT 0x0
599#define ACP_DSP1_CACHE_SIZE7__PageEnable_MASK 0x80000000
600#define ACP_DSP1_CACHE_SIZE7__PageEnable__SHIFT 0x1f
601#define ACP_DSP1_CACHE_OFFSET8__Offset_MASK 0xfffffff
602#define ACP_DSP1_CACHE_OFFSET8__Offset__SHIFT 0x0
603#define ACP_DSP1_CACHE_OFFSET8__OnionGarlicSel_MASK 0x80000000
604#define ACP_DSP1_CACHE_OFFSET8__OnionGarlicSel__SHIFT 0x1f
605#define ACP_DSP1_CACHE_SIZE8__Size_MASK 0xffffff
606#define ACP_DSP1_CACHE_SIZE8__Size__SHIFT 0x0
607#define ACP_DSP1_CACHE_SIZE8__PageEnable_MASK 0x80000000
608#define ACP_DSP1_CACHE_SIZE8__PageEnable__SHIFT 0x1f
609#define ACP_DSP1_NONCACHE_OFFSET0__Offset_MASK 0xfffffff
610#define ACP_DSP1_NONCACHE_OFFSET0__Offset__SHIFT 0x0
611#define ACP_DSP1_NONCACHE_OFFSET0__OnionGarlicSel_MASK 0x80000000
612#define ACP_DSP1_NONCACHE_OFFSET0__OnionGarlicSel__SHIFT 0x1f
613#define ACP_DSP1_NONCACHE_SIZE0__Size_MASK 0xffffff
614#define ACP_DSP1_NONCACHE_SIZE0__Size__SHIFT 0x0
615#define ACP_DSP1_NONCACHE_SIZE0__PageEnable_MASK 0x80000000
616#define ACP_DSP1_NONCACHE_SIZE0__PageEnable__SHIFT 0x1f
617#define ACP_DSP1_NONCACHE_OFFSET1__Offset_MASK 0xfffffff
618#define ACP_DSP1_NONCACHE_OFFSET1__Offset__SHIFT 0x0
619#define ACP_DSP1_NONCACHE_OFFSET1__OnionGarlicSel_MASK 0x80000000
620#define ACP_DSP1_NONCACHE_OFFSET1__OnionGarlicSel__SHIFT 0x1f
621#define ACP_DSP1_NONCACHE_SIZE1__Size_MASK 0xffffff
622#define ACP_DSP1_NONCACHE_SIZE1__Size__SHIFT 0x0
623#define ACP_DSP1_NONCACHE_SIZE1__PageEnable_MASK 0x80000000
624#define ACP_DSP1_NONCACHE_SIZE1__PageEnable__SHIFT 0x1f
625#define ACP_DSP1_DEBUG_PC__DebugPC_MASK 0xffffffff
626#define ACP_DSP1_DEBUG_PC__DebugPC__SHIFT 0x0
627#define ACP_DSP1_NMI_SEL__NMISel_MASK 0x1
628#define ACP_DSP1_NMI_SEL__NMISel__SHIFT 0x0
629#define ACP_DSP1_CLKRST_CNTL__ClkEn_MASK 0x1
630#define ACP_DSP1_CLKRST_CNTL__ClkEn__SHIFT 0x0
631#define ACP_DSP1_CLKRST_CNTL__SoftResetDSP_MASK 0x2
632#define ACP_DSP1_CLKRST_CNTL__SoftResetDSP__SHIFT 0x1
633#define ACP_DSP1_CLKRST_CNTL__InternalSoftResetMode_MASK 0x4
634#define ACP_DSP1_CLKRST_CNTL__InternalSoftResetMode__SHIFT 0x2
635#define ACP_DSP1_CLKRST_CNTL__ExternalSoftResetMode_MASK 0x8
636#define ACP_DSP1_CLKRST_CNTL__ExternalSoftResetMode__SHIFT 0x3
637#define ACP_DSP1_CLKRST_CNTL__SoftResetDSPDone_MASK 0x10
638#define ACP_DSP1_CLKRST_CNTL__SoftResetDSPDone__SHIFT 0x4
639#define ACP_DSP1_CLKRST_CNTL__Clk_ON_Status_MASK 0x20
640#define ACP_DSP1_CLKRST_CNTL__Clk_ON_Status__SHIFT 0x5
641#define ACP_DSP1_RUNSTALL__RunStallCntl_MASK 0x1
642#define ACP_DSP1_RUNSTALL__RunStallCntl__SHIFT 0x0
643#define ACP_DSP1_OCD_HALT_ON_RST__OCD_HALT_ON_RST_MASK 0x1
644#define ACP_DSP1_OCD_HALT_ON_RST__OCD_HALT_ON_RST__SHIFT 0x0
645#define ACP_DSP1_WAIT_MODE__WaitMode_MASK 0x1
646#define ACP_DSP1_WAIT_MODE__WaitMode__SHIFT 0x0
647#define ACP_DSP1_VECT_SEL__StaticVectorSel_MASK 0x1
648#define ACP_DSP1_VECT_SEL__StaticVectorSel__SHIFT 0x0
649#define ACP_DSP1_DEBUG_REG1__ACP_DSP_DEBUG_REG1_MASK 0xffffffff
650#define ACP_DSP1_DEBUG_REG1__ACP_DSP_DEBUG_REG1__SHIFT 0x0
651#define ACP_DSP1_DEBUG_REG2__ACP_DSP_DEBUG_REG2_MASK 0xffffffff
652#define ACP_DSP1_DEBUG_REG2__ACP_DSP_DEBUG_REG2__SHIFT 0x0
653#define ACP_DSP1_DEBUG_REG3__ACP_DSP_DEBUG_REG3_MASK 0xffffffff
654#define ACP_DSP1_DEBUG_REG3__ACP_DSP_DEBUG_REG3__SHIFT 0x0
655#define ACP_DSP2_CACHE_OFFSET0__Offset_MASK 0xfffffff
656#define ACP_DSP2_CACHE_OFFSET0__Offset__SHIFT 0x0
657#define ACP_DSP2_CACHE_OFFSET0__OnionGarlicSel_MASK 0x80000000
658#define ACP_DSP2_CACHE_OFFSET0__OnionGarlicSel__SHIFT 0x1f
659#define ACP_DSP2_CACHE_SIZE0__Size_MASK 0xffffff
660#define ACP_DSP2_CACHE_SIZE0__Size__SHIFT 0x0
661#define ACP_DSP2_CACHE_SIZE0__PageEnable_MASK 0x80000000
662#define ACP_DSP2_CACHE_SIZE0__PageEnable__SHIFT 0x1f
663#define ACP_DSP2_CACHE_OFFSET1__Offset_MASK 0xfffffff
664#define ACP_DSP2_CACHE_OFFSET1__Offset__SHIFT 0x0
665#define ACP_DSP2_CACHE_OFFSET1__OnionGarlicSel_MASK 0x80000000
666#define ACP_DSP2_CACHE_OFFSET1__OnionGarlicSel__SHIFT 0x1f
667#define ACP_DSP2_CACHE_SIZE1__Size_MASK 0xffffff
668#define ACP_DSP2_CACHE_SIZE1__Size__SHIFT 0x0
669#define ACP_DSP2_CACHE_SIZE1__PageEnable_MASK 0x80000000
670#define ACP_DSP2_CACHE_SIZE1__PageEnable__SHIFT 0x1f
671#define ACP_DSP2_CACHE_OFFSET2__Offset_MASK 0xfffffff
672#define ACP_DSP2_CACHE_OFFSET2__Offset__SHIFT 0x0
673#define ACP_DSP2_CACHE_OFFSET2__OnionGarlicSel_MASK 0x80000000
674#define ACP_DSP2_CACHE_OFFSET2__OnionGarlicSel__SHIFT 0x1f
675#define ACP_DSP2_CACHE_SIZE2__Size_MASK 0xffffff
676#define ACP_DSP2_CACHE_SIZE2__Size__SHIFT 0x0
677#define ACP_DSP2_CACHE_SIZE2__PageEnable_MASK 0x80000000
678#define ACP_DSP2_CACHE_SIZE2__PageEnable__SHIFT 0x1f
679#define ACP_DSP2_CACHE_OFFSET3__Offset_MASK 0xfffffff
680#define ACP_DSP2_CACHE_OFFSET3__Offset__SHIFT 0x0
681#define ACP_DSP2_CACHE_OFFSET3__OnionGarlicSel_MASK 0x80000000
682#define ACP_DSP2_CACHE_OFFSET3__OnionGarlicSel__SHIFT 0x1f
683#define ACP_DSP2_CACHE_SIZE3__Size_MASK 0xffffff
684#define ACP_DSP2_CACHE_SIZE3__Size__SHIFT 0x0
685#define ACP_DSP2_CACHE_SIZE3__PageEnable_MASK 0x80000000
686#define ACP_DSP2_CACHE_SIZE3__PageEnable__SHIFT 0x1f
687#define ACP_DSP2_CACHE_OFFSET4__Offset_MASK 0xfffffff
688#define ACP_DSP2_CACHE_OFFSET4__Offset__SHIFT 0x0
689#define ACP_DSP2_CACHE_OFFSET4__OnionGarlicSel_MASK 0x80000000
690#define ACP_DSP2_CACHE_OFFSET4__OnionGarlicSel__SHIFT 0x1f
691#define ACP_DSP2_CACHE_SIZE4__Size_MASK 0xffffff
692#define ACP_DSP2_CACHE_SIZE4__Size__SHIFT 0x0
693#define ACP_DSP2_CACHE_SIZE4__PageEnable_MASK 0x80000000
694#define ACP_DSP2_CACHE_SIZE4__PageEnable__SHIFT 0x1f
695#define ACP_DSP2_CACHE_OFFSET5__Offset_MASK 0xfffffff
696#define ACP_DSP2_CACHE_OFFSET5__Offset__SHIFT 0x0
697#define ACP_DSP2_CACHE_OFFSET5__OnionGarlicSel_MASK 0x80000000
698#define ACP_DSP2_CACHE_OFFSET5__OnionGarlicSel__SHIFT 0x1f
699#define ACP_DSP2_CACHE_SIZE5__Size_MASK 0xffffff
700#define ACP_DSP2_CACHE_SIZE5__Size__SHIFT 0x0
701#define ACP_DSP2_CACHE_SIZE5__PageEnable_MASK 0x80000000
702#define ACP_DSP2_CACHE_SIZE5__PageEnable__SHIFT 0x1f
703#define ACP_DSP2_CACHE_OFFSET6__Offset_MASK 0xfffffff
704#define ACP_DSP2_CACHE_OFFSET6__Offset__SHIFT 0x0
705#define ACP_DSP2_CACHE_OFFSET6__OnionGarlicSel_MASK 0x80000000
706#define ACP_DSP2_CACHE_OFFSET6__OnionGarlicSel__SHIFT 0x1f
707#define ACP_DSP2_CACHE_SIZE6__Size_MASK 0xffffff
708#define ACP_DSP2_CACHE_SIZE6__Size__SHIFT 0x0
709#define ACP_DSP2_CACHE_SIZE6__PageEnable_MASK 0x80000000
710#define ACP_DSP2_CACHE_SIZE6__PageEnable__SHIFT 0x1f
711#define ACP_DSP2_CACHE_OFFSET7__Offset_MASK 0xfffffff
712#define ACP_DSP2_CACHE_OFFSET7__Offset__SHIFT 0x0
713#define ACP_DSP2_CACHE_OFFSET7__OnionGarlicSel_MASK 0x80000000
714#define ACP_DSP2_CACHE_OFFSET7__OnionGarlicSel__SHIFT 0x1f
715#define ACP_DSP2_CACHE_SIZE7__Size_MASK 0xffffff
716#define ACP_DSP2_CACHE_SIZE7__Size__SHIFT 0x0
717#define ACP_DSP2_CACHE_SIZE7__PageEnable_MASK 0x80000000
718#define ACP_DSP2_CACHE_SIZE7__PageEnable__SHIFT 0x1f
719#define ACP_DSP2_CACHE_OFFSET8__Offset_MASK 0xfffffff
720#define ACP_DSP2_CACHE_OFFSET8__Offset__SHIFT 0x0
721#define ACP_DSP2_CACHE_OFFSET8__OnionGarlicSel_MASK 0x80000000
722#define ACP_DSP2_CACHE_OFFSET8__OnionGarlicSel__SHIFT 0x1f
723#define ACP_DSP2_CACHE_SIZE8__Size_MASK 0xffffff
724#define ACP_DSP2_CACHE_SIZE8__Size__SHIFT 0x0
725#define ACP_DSP2_CACHE_SIZE8__PageEnable_MASK 0x80000000
726#define ACP_DSP2_CACHE_SIZE8__PageEnable__SHIFT 0x1f
727#define ACP_DSP2_NONCACHE_OFFSET0__Offset_MASK 0xfffffff
728#define ACP_DSP2_NONCACHE_OFFSET0__Offset__SHIFT 0x0
729#define ACP_DSP2_NONCACHE_OFFSET0__OnionGarlicSel_MASK 0x80000000
730#define ACP_DSP2_NONCACHE_OFFSET0__OnionGarlicSel__SHIFT 0x1f
731#define ACP_DSP2_NONCACHE_SIZE0__Size_MASK 0xffffff
732#define ACP_DSP2_NONCACHE_SIZE0__Size__SHIFT 0x0
733#define ACP_DSP2_NONCACHE_SIZE0__PageEnable_MASK 0x80000000
734#define ACP_DSP2_NONCACHE_SIZE0__PageEnable__SHIFT 0x1f
735#define ACP_DSP2_NONCACHE_OFFSET1__Offset_MASK 0xfffffff
736#define ACP_DSP2_NONCACHE_OFFSET1__Offset__SHIFT 0x0
737#define ACP_DSP2_NONCACHE_OFFSET1__OnionGarlicSel_MASK 0x80000000
738#define ACP_DSP2_NONCACHE_OFFSET1__OnionGarlicSel__SHIFT 0x1f
739#define ACP_DSP2_NONCACHE_SIZE1__Size_MASK 0xffffff
740#define ACP_DSP2_NONCACHE_SIZE1__Size__SHIFT 0x0
741#define ACP_DSP2_NONCACHE_SIZE1__PageEnable_MASK 0x80000000
742#define ACP_DSP2_NONCACHE_SIZE1__PageEnable__SHIFT 0x1f
743#define ACP_DSP2_DEBUG_PC__DebugPC_MASK 0xffffffff
744#define ACP_DSP2_DEBUG_PC__DebugPC__SHIFT 0x0
745#define ACP_DSP2_NMI_SEL__NMISel_MASK 0x1
746#define ACP_DSP2_NMI_SEL__NMISel__SHIFT 0x0
747#define ACP_DSP2_CLKRST_CNTL__ClkEn_MASK 0x1
748#define ACP_DSP2_CLKRST_CNTL__ClkEn__SHIFT 0x0
749#define ACP_DSP2_CLKRST_CNTL__SoftResetDSP_MASK 0x2
750#define ACP_DSP2_CLKRST_CNTL__SoftResetDSP__SHIFT 0x1
751#define ACP_DSP2_CLKRST_CNTL__InternalSoftResetMode_MASK 0x4
752#define ACP_DSP2_CLKRST_CNTL__InternalSoftResetMode__SHIFT 0x2
753#define ACP_DSP2_CLKRST_CNTL__ExternalSoftResetMode_MASK 0x8
754#define ACP_DSP2_CLKRST_CNTL__ExternalSoftResetMode__SHIFT 0x3
755#define ACP_DSP2_CLKRST_CNTL__SoftResetDSPDone_MASK 0x10
756#define ACP_DSP2_CLKRST_CNTL__SoftResetDSPDone__SHIFT 0x4
757#define ACP_DSP2_CLKRST_CNTL__Clk_ON_Status_MASK 0x20
758#define ACP_DSP2_CLKRST_CNTL__Clk_ON_Status__SHIFT 0x5
759#define ACP_DSP2_RUNSTALL__RunStallCntl_MASK 0x1
760#define ACP_DSP2_RUNSTALL__RunStallCntl__SHIFT 0x0
761#define ACP_DSP2_OCD_HALT_ON_RST__OCD_HALT_ON_RST_MASK 0x1
762#define ACP_DSP2_OCD_HALT_ON_RST__OCD_HALT_ON_RST__SHIFT 0x0
763#define ACP_DSP2_WAIT_MODE__WaitMode_MASK 0x1
764#define ACP_DSP2_WAIT_MODE__WaitMode__SHIFT 0x0
765#define ACP_DSP2_VECT_SEL__StaticVectorSel_MASK 0x1
766#define ACP_DSP2_VECT_SEL__StaticVectorSel__SHIFT 0x0
767#define ACP_DSP2_DEBUG_REG1__ACP_DSP_DEBUG_REG1_MASK 0xffffffff
768#define ACP_DSP2_DEBUG_REG1__ACP_DSP_DEBUG_REG1__SHIFT 0x0
769#define ACP_DSP2_DEBUG_REG2__ACP_DSP_DEBUG_REG2_MASK 0xffffffff
770#define ACP_DSP2_DEBUG_REG2__ACP_DSP_DEBUG_REG2__SHIFT 0x0
771#define ACP_DSP2_DEBUG_REG3__ACP_DSP_DEBUG_REG3_MASK 0xffffffff
772#define ACP_DSP2_DEBUG_REG3__ACP_DSP_DEBUG_REG3__SHIFT 0x0
773#define ACP_AXI2DAGB_ONION_CNTL__AXI2DAGBDataSwap_MASK 0x3
774#define ACP_AXI2DAGB_ONION_CNTL__AXI2DAGBDataSwap__SHIFT 0x0
775#define ACP_AXI2DAGB_ONION_CNTL__AXI2DAGBEnbMultRdReq_MASK 0x4
776#define ACP_AXI2DAGB_ONION_CNTL__AXI2DAGBEnbMultRdReq__SHIFT 0x2
777#define ACP_AXI2DAGB_ONION_CNTL__AXI2DAGBEnbMultWrReq_MASK 0x18
778#define ACP_AXI2DAGB_ONION_CNTL__AXI2DAGBEnbMultWrReq__SHIFT 0x3
779#define ACP_AXI2DAGB_ONION_CNTL__AXI2DAGBMaxReadBurst_MASK 0x60
780#define ACP_AXI2DAGB_ONION_CNTL__AXI2DAGBMaxReadBurst__SHIFT 0x5
781#define ACP_AXI2DAGB_ONION_CNTL__AXI2DAGBStallEnb_MASK 0x80
782#define ACP_AXI2DAGB_ONION_CNTL__AXI2DAGBStallEnb__SHIFT 0x7
783#define ACP_AXI2DAGB_ONION_CNTL__AXI2DAGBNackChkEnb_MASK 0x100
784#define ACP_AXI2DAGB_ONION_CNTL__AXI2DAGBNackChkEnb__SHIFT 0x8
785#define ACP_AXI2DAGB_ONION_CNTL__AXI2DAGBAdrWinViolChkEnb_MASK 0x200
786#define ACP_AXI2DAGB_ONION_CNTL__AXI2DAGBAdrWinViolChkEnb__SHIFT 0x9
787#define ACP_AXI2DAGB_ONION_CNTL__AXI2DAGBUrgEnb_MASK 0x400
788#define ACP_AXI2DAGB_ONION_CNTL__AXI2DAGBUrgEnb__SHIFT 0xa
789#define ACP_AXI2DAGB_ONION_CNTL__AXI2DAGBUrgCntMult_MASK 0x1800
790#define ACP_AXI2DAGB_ONION_CNTL__AXI2DAGBUrgCntMult__SHIFT 0xb
791#define ACP_AXI2DAGB_ONION_CNTL__AXI2DAGBStallMode_MASK 0x2000
792#define ACP_AXI2DAGB_ONION_CNTL__AXI2DAGBStallMode__SHIFT 0xd
793#define ACP_AXI2DAGB_ONION_ERR_STATUS_WR__AXI2DAGBAdrWinViolOver_MASK 0x2000000
794#define ACP_AXI2DAGB_ONION_ERR_STATUS_WR__AXI2DAGBAdrWinViolOver__SHIFT 0x19
795#define ACP_AXI2DAGB_ONION_ERR_STATUS_WR__AXI2DAGBAdrWinViolSource_MASK 0x1c000000
796#define ACP_AXI2DAGB_ONION_ERR_STATUS_WR__AXI2DAGBAdrWinViolSource__SHIFT 0x1a
797#define ACP_AXI2DAGB_ONION_ERR_STATUS_WR__AXI2DAGBAdrWinViol_MASK 0x20000000
798#define ACP_AXI2DAGB_ONION_ERR_STATUS_WR__AXI2DAGBAdrWinViol__SHIFT 0x1d
799#define ACP_AXI2DAGB_ONION_ERR_STATUS_WR__AXI2DAGBNackOver_MASK 0x40000000
800#define ACP_AXI2DAGB_ONION_ERR_STATUS_WR__AXI2DAGBNackOver__SHIFT 0x1e
801#define ACP_AXI2DAGB_ONION_ERR_STATUS_WR__AXI2DAGBNackVal_MASK 0x80000000
802#define ACP_AXI2DAGB_ONION_ERR_STATUS_WR__AXI2DAGBNackVal__SHIFT 0x1f
803#define ACP_AXI2DAGB_ONION_ERR_STATUS_RD__AXI2DAGBAdrWinViolOver_MASK 0x2000000
804#define ACP_AXI2DAGB_ONION_ERR_STATUS_RD__AXI2DAGBAdrWinViolOver__SHIFT 0x19
805#define ACP_AXI2DAGB_ONION_ERR_STATUS_RD__AXI2DAGBAdrWinViolSource_MASK 0x1c000000
806#define ACP_AXI2DAGB_ONION_ERR_STATUS_RD__AXI2DAGBAdrWinViolSource__SHIFT 0x1a
807#define ACP_AXI2DAGB_ONION_ERR_STATUS_RD__AXI2DAGBAdrWinViol_MASK 0x20000000
808#define ACP_AXI2DAGB_ONION_ERR_STATUS_RD__AXI2DAGBAdrWinViol__SHIFT 0x1d
809#define ACP_AXI2DAGB_ONION_ERR_STATUS_RD__AXI2DAGBNackOver_MASK 0x40000000
810#define ACP_AXI2DAGB_ONION_ERR_STATUS_RD__AXI2DAGBNackOver__SHIFT 0x1e
811#define ACP_AXI2DAGB_ONION_ERR_STATUS_RD__AXI2DAGBNackVal_MASK 0x80000000
812#define ACP_AXI2DAGB_ONION_ERR_STATUS_RD__AXI2DAGBNackVal__SHIFT 0x1f
813#define ACP_DAGB_Onion_TransPerf_Counter_Control__EnbDAGBTransPerfCntr_MASK 0x1
814#define ACP_DAGB_Onion_TransPerf_Counter_Control__EnbDAGBTransPerfCntr__SHIFT 0x0
815#define ACP_DAGB_Onion_Wr_TransPerf_Counter_Current__CurDAGBTransPerfCntrTime_MASK 0x1ffff
816#define ACP_DAGB_Onion_Wr_TransPerf_Counter_Current__CurDAGBTransPerfCntrTime__SHIFT 0x0
817#define ACP_DAGB_Onion_Wr_TransPerf_Counter_Current__ClrCurDAGBTransPerfCntr_MASK 0x80000000
818#define ACP_DAGB_Onion_Wr_TransPerf_Counter_Current__ClrCurDAGBTransPerfCntr__SHIFT 0x1f
819#define ACP_DAGB_Onion_Wr_TransPerf_Counter_Peak__PeakDAGBTransPerfCntrTime_MASK 0x1ffff
820#define ACP_DAGB_Onion_Wr_TransPerf_Counter_Peak__PeakDAGBTransPerfCntrTime__SHIFT 0x0
821#define ACP_DAGB_Onion_Wr_TransPerf_Counter_Peak__ClrPeakDAGBTransPerfCntr_MASK 0x80000000
822#define ACP_DAGB_Onion_Wr_TransPerf_Counter_Peak__ClrPeakDAGBTransPerfCntr__SHIFT 0x1f
823#define ACP_DAGB_Onion_Rd_TransPerf_Counter_Current__CurDAGBTransPerfCntrTime_MASK 0x1ffff
824#define ACP_DAGB_Onion_Rd_TransPerf_Counter_Current__CurDAGBTransPerfCntrTime__SHIFT 0x0
825#define ACP_DAGB_Onion_Rd_TransPerf_Counter_Current__ClrCurDAGBTransPerfCntr_MASK 0x80000000
826#define ACP_DAGB_Onion_Rd_TransPerf_Counter_Current__ClrCurDAGBTransPerfCntr__SHIFT 0x1f
827#define ACP_DAGB_Onion_Rd_TransPerf_Counter_Peak__PeakDAGBTransPerfCntrTime_MASK 0x1ffff
828#define ACP_DAGB_Onion_Rd_TransPerf_Counter_Peak__PeakDAGBTransPerfCntrTime__SHIFT 0x0
829#define ACP_DAGB_Onion_Rd_TransPerf_Counter_Peak__ClrPeakDAGBTransPerfCntr_MASK 0x80000000
830#define ACP_DAGB_Onion_Rd_TransPerf_Counter_Peak__ClrPeakDAGBTransPerfCntr__SHIFT 0x1f
831#define ACP_AXI2DAGB_GARLIC_CNTL__AXI2DAGBDataSwap_MASK 0x3
832#define ACP_AXI2DAGB_GARLIC_CNTL__AXI2DAGBDataSwap__SHIFT 0x0
833#define ACP_AXI2DAGB_GARLIC_CNTL__AXI2DAGBEnbMultRdReq_MASK 0x4
834#define ACP_AXI2DAGB_GARLIC_CNTL__AXI2DAGBEnbMultRdReq__SHIFT 0x2
835#define ACP_AXI2DAGB_GARLIC_CNTL__AXI2DAGBEnbMultWrReq_MASK 0x18
836#define ACP_AXI2DAGB_GARLIC_CNTL__AXI2DAGBEnbMultWrReq__SHIFT 0x3
837#define ACP_AXI2DAGB_GARLIC_CNTL__AXI2DAGBMaxReadBurst_MASK 0x60
838#define ACP_AXI2DAGB_GARLIC_CNTL__AXI2DAGBMaxReadBurst__SHIFT 0x5
839#define ACP_AXI2DAGB_GARLIC_CNTL__AXI2DAGBStallEnb_MASK 0x80
840#define ACP_AXI2DAGB_GARLIC_CNTL__AXI2DAGBStallEnb__SHIFT 0x7
841#define ACP_AXI2DAGB_GARLIC_CNTL__AXI2DAGBNackChkEnb_MASK 0x100
842#define ACP_AXI2DAGB_GARLIC_CNTL__AXI2DAGBNackChkEnb__SHIFT 0x8
843#define ACP_AXI2DAGB_GARLIC_CNTL__AXI2DAGBAdrWinViolChkEnb_MASK 0x200
844#define ACP_AXI2DAGB_GARLIC_CNTL__AXI2DAGBAdrWinViolChkEnb__SHIFT 0x9
845#define ACP_AXI2DAGB_GARLIC_CNTL__AXI2DAGBUrgEnb_MASK 0x400
846#define ACP_AXI2DAGB_GARLIC_CNTL__AXI2DAGBUrgEnb__SHIFT 0xa
847#define ACP_AXI2DAGB_GARLIC_CNTL__AXI2DAGBUrgCntMult_MASK 0x1800
848#define ACP_AXI2DAGB_GARLIC_CNTL__AXI2DAGBUrgCntMult__SHIFT 0xb
849#define ACP_AXI2DAGB_GARLIC_CNTL__AXI2DAGBStallMode_MASK 0x2000
850#define ACP_AXI2DAGB_GARLIC_CNTL__AXI2DAGBStallMode__SHIFT 0xd
851#define ACP_AXI2DAGB_GARLIC_ERR_STATUS_WR__AXI2DAGBAdrWinViolOver_MASK 0x2000000
852#define ACP_AXI2DAGB_GARLIC_ERR_STATUS_WR__AXI2DAGBAdrWinViolOver__SHIFT 0x19
853#define ACP_AXI2DAGB_GARLIC_ERR_STATUS_WR__AXI2DAGBAdrWinViolSource_MASK 0x1c000000
854#define ACP_AXI2DAGB_GARLIC_ERR_STATUS_WR__AXI2DAGBAdrWinViolSource__SHIFT 0x1a
855#define ACP_AXI2DAGB_GARLIC_ERR_STATUS_WR__AXI2DAGBAdrWinViol_MASK 0x20000000
856#define ACP_AXI2DAGB_GARLIC_ERR_STATUS_WR__AXI2DAGBAdrWinViol__SHIFT 0x1d
857#define ACP_AXI2DAGB_GARLIC_ERR_STATUS_WR__AXI2DAGBNackOver_MASK 0x40000000
858#define ACP_AXI2DAGB_GARLIC_ERR_STATUS_WR__AXI2DAGBNackOver__SHIFT 0x1e
859#define ACP_AXI2DAGB_GARLIC_ERR_STATUS_WR__AXI2DAGBNackVal_MASK 0x80000000
860#define ACP_AXI2DAGB_GARLIC_ERR_STATUS_WR__AXI2DAGBNackVal__SHIFT 0x1f
861#define ACP_AXI2DAGB_GARLIC_ERR_STATUS_RD__AXI2DAGBAdrWinViolOver_MASK 0x2000000
862#define ACP_AXI2DAGB_GARLIC_ERR_STATUS_RD__AXI2DAGBAdrWinViolOver__SHIFT 0x19
863#define ACP_AXI2DAGB_GARLIC_ERR_STATUS_RD__AXI2DAGBAdrWinViolSource_MASK 0x1c000000
864#define ACP_AXI2DAGB_GARLIC_ERR_STATUS_RD__AXI2DAGBAdrWinViolSource__SHIFT 0x1a
865#define ACP_AXI2DAGB_GARLIC_ERR_STATUS_RD__AXI2DAGBAdrWinViol_MASK 0x20000000
866#define ACP_AXI2DAGB_GARLIC_ERR_STATUS_RD__AXI2DAGBAdrWinViol__SHIFT 0x1d
867#define ACP_AXI2DAGB_GARLIC_ERR_STATUS_RD__AXI2DAGBNackOver_MASK 0x40000000
868#define ACP_AXI2DAGB_GARLIC_ERR_STATUS_RD__AXI2DAGBNackOver__SHIFT 0x1e
869#define ACP_AXI2DAGB_GARLIC_ERR_STATUS_RD__AXI2DAGBNackVal_MASK 0x80000000
870#define ACP_AXI2DAGB_GARLIC_ERR_STATUS_RD__AXI2DAGBNackVal__SHIFT 0x1f
871#define ACP_DAGB_Garlic_TransPerf_Counter_Control__EnbDAGBTransPerfCntr_MASK 0x1
872#define ACP_DAGB_Garlic_TransPerf_Counter_Control__EnbDAGBTransPerfCntr__SHIFT 0x0
873#define ACP_DAGB_Garlic_Wr_TransPerf_Counter_Current__CurDAGBTransPerfCntrTime_MASK 0x1ffff
874#define ACP_DAGB_Garlic_Wr_TransPerf_Counter_Current__CurDAGBTransPerfCntrTime__SHIFT 0x0
875#define ACP_DAGB_Garlic_Wr_TransPerf_Counter_Current__ClrCurDAGBTransPerfCntr_MASK 0x80000000
876#define ACP_DAGB_Garlic_Wr_TransPerf_Counter_Current__ClrCurDAGBTransPerfCntr__SHIFT 0x1f
877#define ACP_DAGB_Garlic_Wr_TransPerf_Counter_Peak__PeakDAGBTransPerfCntrTime_MASK 0x1ffff
878#define ACP_DAGB_Garlic_Wr_TransPerf_Counter_Peak__PeakDAGBTransPerfCntrTime__SHIFT 0x0
879#define ACP_DAGB_Garlic_Wr_TransPerf_Counter_Peak__ClrPeakDAGBTransPerfCntr_MASK 0x80000000
880#define ACP_DAGB_Garlic_Wr_TransPerf_Counter_Peak__ClrPeakDAGBTransPerfCntr__SHIFT 0x1f
881#define ACP_DAGB_Garlic_Rd_TransPerf_Counter_Current__CurDAGBTransPerfCntrTime_MASK 0x1ffff
882#define ACP_DAGB_Garlic_Rd_TransPerf_Counter_Current__CurDAGBTransPerfCntrTime__SHIFT 0x0
883#define ACP_DAGB_Garlic_Rd_TransPerf_Counter_Current__ClrCurDAGBTransPerfCntr_MASK 0x80000000
884#define ACP_DAGB_Garlic_Rd_TransPerf_Counter_Current__ClrCurDAGBTransPerfCntr__SHIFT 0x1f
885#define ACP_DAGB_Garlic_Rd_TransPerf_Counter_Peak__PeakDAGBTransPerfCntrTime_MASK 0x1ffff
886#define ACP_DAGB_Garlic_Rd_TransPerf_Counter_Peak__PeakDAGBTransPerfCntrTime__SHIFT 0x0
887#define ACP_DAGB_Garlic_Rd_TransPerf_Counter_Peak__ClrPeakDAGBTransPerfCntr_MASK 0x80000000
888#define ACP_DAGB_Garlic_Rd_TransPerf_Counter_Peak__ClrPeakDAGBTransPerfCntr__SHIFT 0x1f
889#define ACP_DAGB_PAGE_SIZE_GRP_1__AXI2DAGBPageSize_MASK 0x3
890#define ACP_DAGB_PAGE_SIZE_GRP_1__AXI2DAGBPageSize__SHIFT 0x0
891#define ACP_DAGB_BASE_ADDR_GRP_1__AXI2DAGBBaseAddr_MASK 0xfffffff
892#define ACP_DAGB_BASE_ADDR_GRP_1__AXI2DAGBBaseAddr__SHIFT 0x0
893#define ACP_DAGB_BASE_ADDR_GRP_1__AXI2DAGBSnoopSel_MASK 0x20000000
894#define ACP_DAGB_BASE_ADDR_GRP_1__AXI2DAGBSnoopSel__SHIFT 0x1d
895#define ACP_DAGB_BASE_ADDR_GRP_1__AXI2DAGBTargetMemSel_MASK 0x40000000
896#define ACP_DAGB_BASE_ADDR_GRP_1__AXI2DAGBTargetMemSel__SHIFT 0x1e
897#define ACP_DAGB_BASE_ADDR_GRP_1__AXI2DAGBGrpEnable_MASK 0x80000000
898#define ACP_DAGB_BASE_ADDR_GRP_1__AXI2DAGBGrpEnable__SHIFT 0x1f
899#define ACP_DAGB_PAGE_SIZE_GRP_2__AXI2DAGBPageSize_MASK 0x3
900#define ACP_DAGB_PAGE_SIZE_GRP_2__AXI2DAGBPageSize__SHIFT 0x0
901#define ACP_DAGB_BASE_ADDR_GRP_2__AXI2DAGBBaseAddr_MASK 0xfffffff
902#define ACP_DAGB_BASE_ADDR_GRP_2__AXI2DAGBBaseAddr__SHIFT 0x0
903#define ACP_DAGB_BASE_ADDR_GRP_2__AXI2DAGBSnoopSel_MASK 0x20000000
904#define ACP_DAGB_BASE_ADDR_GRP_2__AXI2DAGBSnoopSel__SHIFT 0x1d
905#define ACP_DAGB_BASE_ADDR_GRP_2__AXI2DAGBTargetMemSel_MASK 0x40000000
906#define ACP_DAGB_BASE_ADDR_GRP_2__AXI2DAGBTargetMemSel__SHIFT 0x1e
907#define ACP_DAGB_BASE_ADDR_GRP_2__AXI2DAGBGrpEnable_MASK 0x80000000
908#define ACP_DAGB_BASE_ADDR_GRP_2__AXI2DAGBGrpEnable__SHIFT 0x1f
909#define ACP_DAGB_PAGE_SIZE_GRP_3__AXI2DAGBPageSize_MASK 0x3
910#define ACP_DAGB_PAGE_SIZE_GRP_3__AXI2DAGBPageSize__SHIFT 0x0
911#define ACP_DAGB_BASE_ADDR_GRP_3__AXI2DAGBBaseAddr_MASK 0xfffffff
912#define ACP_DAGB_BASE_ADDR_GRP_3__AXI2DAGBBaseAddr__SHIFT 0x0
913#define ACP_DAGB_BASE_ADDR_GRP_3__AXI2DAGBSnoopSel_MASK 0x20000000
914#define ACP_DAGB_BASE_ADDR_GRP_3__AXI2DAGBSnoopSel__SHIFT 0x1d
915#define ACP_DAGB_BASE_ADDR_GRP_3__AXI2DAGBTargetMemSel_MASK 0x40000000
916#define ACP_DAGB_BASE_ADDR_GRP_3__AXI2DAGBTargetMemSel__SHIFT 0x1e
917#define ACP_DAGB_BASE_ADDR_GRP_3__AXI2DAGBGrpEnable_MASK 0x80000000
918#define ACP_DAGB_BASE_ADDR_GRP_3__AXI2DAGBGrpEnable__SHIFT 0x1f
919#define ACP_DAGB_PAGE_SIZE_GRP_4__AXI2DAGBPageSize_MASK 0x3
920#define ACP_DAGB_PAGE_SIZE_GRP_4__AXI2DAGBPageSize__SHIFT 0x0
921#define ACP_DAGB_BASE_ADDR_GRP_4__AXI2DAGBBaseAddr_MASK 0xfffffff
922#define ACP_DAGB_BASE_ADDR_GRP_4__AXI2DAGBBaseAddr__SHIFT 0x0
923#define ACP_DAGB_BASE_ADDR_GRP_4__AXI2DAGBSnoopSel_MASK 0x20000000
924#define ACP_DAGB_BASE_ADDR_GRP_4__AXI2DAGBSnoopSel__SHIFT 0x1d
925#define ACP_DAGB_BASE_ADDR_GRP_4__AXI2DAGBTargetMemSel_MASK 0x40000000
926#define ACP_DAGB_BASE_ADDR_GRP_4__AXI2DAGBTargetMemSel__SHIFT 0x1e
927#define ACP_DAGB_BASE_ADDR_GRP_4__AXI2DAGBGrpEnable_MASK 0x80000000
928#define ACP_DAGB_BASE_ADDR_GRP_4__AXI2DAGBGrpEnable__SHIFT 0x1f
929#define ACP_DAGB_PAGE_SIZE_GRP_5__AXI2DAGBPageSize_MASK 0x3
930#define ACP_DAGB_PAGE_SIZE_GRP_5__AXI2DAGBPageSize__SHIFT 0x0
931#define ACP_DAGB_BASE_ADDR_GRP_5__AXI2DAGBBaseAddr_MASK 0xfffffff
932#define ACP_DAGB_BASE_ADDR_GRP_5__AXI2DAGBBaseAddr__SHIFT 0x0
933#define ACP_DAGB_BASE_ADDR_GRP_5__AXI2DAGBSnoopSel_MASK 0x20000000
934#define ACP_DAGB_BASE_ADDR_GRP_5__AXI2DAGBSnoopSel__SHIFT 0x1d
935#define ACP_DAGB_BASE_ADDR_GRP_5__AXI2DAGBTargetMemSel_MASK 0x40000000
936#define ACP_DAGB_BASE_ADDR_GRP_5__AXI2DAGBTargetMemSel__SHIFT 0x1e
937#define ACP_DAGB_BASE_ADDR_GRP_5__AXI2DAGBGrpEnable_MASK 0x80000000
938#define ACP_DAGB_BASE_ADDR_GRP_5__AXI2DAGBGrpEnable__SHIFT 0x1f
939#define ACP_DAGB_PAGE_SIZE_GRP_6__AXI2DAGBPageSize_MASK 0x3
940#define ACP_DAGB_PAGE_SIZE_GRP_6__AXI2DAGBPageSize__SHIFT 0x0
941#define ACP_DAGB_BASE_ADDR_GRP_6__AXI2DAGBBaseAddr_MASK 0xfffffff
942#define ACP_DAGB_BASE_ADDR_GRP_6__AXI2DAGBBaseAddr__SHIFT 0x0
943#define ACP_DAGB_BASE_ADDR_GRP_6__AXI2DAGBSnoopSel_MASK 0x20000000
944#define ACP_DAGB_BASE_ADDR_GRP_6__AXI2DAGBSnoopSel__SHIFT 0x1d
945#define ACP_DAGB_BASE_ADDR_GRP_6__AXI2DAGBTargetMemSel_MASK 0x40000000
946#define ACP_DAGB_BASE_ADDR_GRP_6__AXI2DAGBTargetMemSel__SHIFT 0x1e
947#define ACP_DAGB_BASE_ADDR_GRP_6__AXI2DAGBGrpEnable_MASK 0x80000000
948#define ACP_DAGB_BASE_ADDR_GRP_6__AXI2DAGBGrpEnable__SHIFT 0x1f
949#define ACP_DAGB_PAGE_SIZE_GRP_7__AXI2DAGBPageSize_MASK 0x3
950#define ACP_DAGB_PAGE_SIZE_GRP_7__AXI2DAGBPageSize__SHIFT 0x0
951#define ACP_DAGB_BASE_ADDR_GRP_7__AXI2DAGBBaseAddr_MASK 0xfffffff
952#define ACP_DAGB_BASE_ADDR_GRP_7__AXI2DAGBBaseAddr__SHIFT 0x0
953#define ACP_DAGB_BASE_ADDR_GRP_7__AXI2DAGBSnoopSel_MASK 0x20000000
954#define ACP_DAGB_BASE_ADDR_GRP_7__AXI2DAGBSnoopSel__SHIFT 0x1d
955#define ACP_DAGB_BASE_ADDR_GRP_7__AXI2DAGBTargetMemSel_MASK 0x40000000
956#define ACP_DAGB_BASE_ADDR_GRP_7__AXI2DAGBTargetMemSel__SHIFT 0x1e
957#define ACP_DAGB_BASE_ADDR_GRP_7__AXI2DAGBGrpEnable_MASK 0x80000000
958#define ACP_DAGB_BASE_ADDR_GRP_7__AXI2DAGBGrpEnable__SHIFT 0x1f
959#define ACP_DAGB_PAGE_SIZE_GRP_8__AXI2DAGBPageSize_MASK 0x3
960#define ACP_DAGB_PAGE_SIZE_GRP_8__AXI2DAGBPageSize__SHIFT 0x0
961#define ACP_DAGB_BASE_ADDR_GRP_8__AXI2DAGBBaseAddr_MASK 0xfffffff
962#define ACP_DAGB_BASE_ADDR_GRP_8__AXI2DAGBBaseAddr__SHIFT 0x0
963#define ACP_DAGB_BASE_ADDR_GRP_8__AXI2DAGBSnoopSel_MASK 0x20000000
964#define ACP_DAGB_BASE_ADDR_GRP_8__AXI2DAGBSnoopSel__SHIFT 0x1d
965#define ACP_DAGB_BASE_ADDR_GRP_8__AXI2DAGBTargetMemSel_MASK 0x40000000
966#define ACP_DAGB_BASE_ADDR_GRP_8__AXI2DAGBTargetMemSel__SHIFT 0x1e
967#define ACP_DAGB_BASE_ADDR_GRP_8__AXI2DAGBGrpEnable_MASK 0x80000000
968#define ACP_DAGB_BASE_ADDR_GRP_8__AXI2DAGBGrpEnable__SHIFT 0x1f
969#define ACP_DAGB_ATU_CTRL__AXI2DAGBCacheInvalidate_MASK 0x1
970#define ACP_DAGB_ATU_CTRL__AXI2DAGBCacheInvalidate__SHIFT 0x0
971#define ACP_CONTROL__ClkEn_MASK 0x1
972#define ACP_CONTROL__ClkEn__SHIFT 0x0
973#define ACP_CONTROL__JtagEn_MASK 0x400
974#define ACP_CONTROL__JtagEn__SHIFT 0xa
975#define ACP_STATUS__ClkOn_MASK 0x1
976#define ACP_STATUS__ClkOn__SHIFT 0x0
977#define ACP_STATUS__ACPRefClkSpd_MASK 0x2
978#define ACP_STATUS__ACPRefClkSpd__SHIFT 0x1
979#define ACP_STATUS__SMUStutterLastEdge_MASK 0x4
980#define ACP_STATUS__SMUStutterLastEdge__SHIFT 0x2
981#define ACP_STATUS__MCStutterLastEdge_MASK 0x8
982#define ACP_STATUS__MCStutterLastEdge__SHIFT 0x3
983#define ACP_SOFT_RESET__SoftResetAud_MASK 0x100
984#define ACP_SOFT_RESET__SoftResetAud__SHIFT 0x8
985#define ACP_SOFT_RESET__SoftResetDMA_MASK 0x200
986#define ACP_SOFT_RESET__SoftResetDMA__SHIFT 0x9
987#define ACP_SOFT_RESET__InternalSoftResetMode_MASK 0x4000
988#define ACP_SOFT_RESET__InternalSoftResetMode__SHIFT 0xe
989#define ACP_SOFT_RESET__ExternalSoftResetMode_MASK 0x8000
990#define ACP_SOFT_RESET__ExternalSoftResetMode__SHIFT 0xf
991#define ACP_SOFT_RESET__SoftResetAudDone_MASK 0x1000000
992#define ACP_SOFT_RESET__SoftResetAudDone__SHIFT 0x18
993#define ACP_SOFT_RESET__SoftResetDMADone_MASK 0x2000000
994#define ACP_SOFT_RESET__SoftResetDMADone__SHIFT 0x19
995#define ACP_PwrMgmt_CNTL__SCLKSleepCntl_MASK 0x3
996#define ACP_PwrMgmt_CNTL__SCLKSleepCntl__SHIFT 0x0
997#define ACP_CAC_INDICATOR_CONTROL__ACP_Cac_Indicator_Counter_MASK 0xffff
998#define ACP_CAC_INDICATOR_CONTROL__ACP_Cac_Indicator_Counter__SHIFT 0x0
999#define ACP_SMU_MAILBOX__ACP_SMU_Mailbox_MASK 0xffffffff
1000#define ACP_SMU_MAILBOX__ACP_SMU_Mailbox__SHIFT 0x0
1001#define ACP_FUTURE_REG_SCLK_0__ACPFutureReg_MASK 0xffffffff
1002#define ACP_FUTURE_REG_SCLK_0__ACPFutureReg__SHIFT 0x0
1003#define ACP_FUTURE_REG_SCLK_1__ACPFutureReg_MASK 0xffffffff
1004#define ACP_FUTURE_REG_SCLK_1__ACPFutureReg__SHIFT 0x0
1005#define ACP_FUTURE_REG_SCLK_2__ACPFutureReg_MASK 0xffffffff
1006#define ACP_FUTURE_REG_SCLK_2__ACPFutureReg__SHIFT 0x0
1007#define ACP_FUTURE_REG_SCLK_3__ACPFutureReg_MASK 0xffffffff
1008#define ACP_FUTURE_REG_SCLK_3__ACPFutureReg__SHIFT 0x0
1009#define ACP_FUTURE_REG_SCLK_4__ACPFutureReg_MASK 0xffffffff
1010#define ACP_FUTURE_REG_SCLK_4__ACPFutureReg__SHIFT 0x0
1011#define ACP_DAGB_DEBUG_CNT_ENABLE__garlic_wr_ask_cnt_enable_MASK 0x1
1012#define ACP_DAGB_DEBUG_CNT_ENABLE__garlic_wr_ask_cnt_enable__SHIFT 0x0
1013#define ACP_DAGB_DEBUG_CNT_ENABLE__garlic_wr_go_cnt_enable_MASK 0x2
1014#define ACP_DAGB_DEBUG_CNT_ENABLE__garlic_wr_go_cnt_enable__SHIFT 0x1
1015#define ACP_DAGB_DEBUG_CNT_ENABLE__garlic_wr_exp_respcnt_enable_MASK 0x4
1016#define ACP_DAGB_DEBUG_CNT_ENABLE__garlic_wr_exp_respcnt_enable__SHIFT 0x2
1017#define ACP_DAGB_DEBUG_CNT_ENABLE__garlic_wr_actual_respcnt_enable_MASK 0x8
1018#define ACP_DAGB_DEBUG_CNT_ENABLE__garlic_wr_actual_respcnt_enable__SHIFT 0x3
1019#define ACP_DAGB_DEBUG_CNT_ENABLE__garlic_rd_ask_cnt_enable_MASK 0x10
1020#define ACP_DAGB_DEBUG_CNT_ENABLE__garlic_rd_ask_cnt_enable__SHIFT 0x4
1021#define ACP_DAGB_DEBUG_CNT_ENABLE__garlic_rd_go_cnt_enable_MASK 0x20
1022#define ACP_DAGB_DEBUG_CNT_ENABLE__garlic_rd_go_cnt_enable__SHIFT 0x5
1023#define ACP_DAGB_DEBUG_CNT_ENABLE__garlic_rd_exp_respcnt_enable_MASK 0x40
1024#define ACP_DAGB_DEBUG_CNT_ENABLE__garlic_rd_exp_respcnt_enable__SHIFT 0x6
1025#define ACP_DAGB_DEBUG_CNT_ENABLE__garlic_rd_actual_respcnt_enable_MASK 0x80
1026#define ACP_DAGB_DEBUG_CNT_ENABLE__garlic_rd_actual_respcnt_enable__SHIFT 0x7
1027#define ACP_DAGB_DEBUG_CNT_ENABLE__onion_wr_ask_cnt_enable_MASK 0x100
1028#define ACP_DAGB_DEBUG_CNT_ENABLE__onion_wr_ask_cnt_enable__SHIFT 0x8
1029#define ACP_DAGB_DEBUG_CNT_ENABLE__onion_wr_go_cnt_enable_MASK 0x200
1030#define ACP_DAGB_DEBUG_CNT_ENABLE__onion_wr_go_cnt_enable__SHIFT 0x9
1031#define ACP_DAGB_DEBUG_CNT_ENABLE__onion_wr_exp_respcnt_enable_MASK 0x400
1032#define ACP_DAGB_DEBUG_CNT_ENABLE__onion_wr_exp_respcnt_enable__SHIFT 0xa
1033#define ACP_DAGB_DEBUG_CNT_ENABLE__onion_wr_actual_respcnt_enable_MASK 0x800
1034#define ACP_DAGB_DEBUG_CNT_ENABLE__onion_wr_actual_respcnt_enable__SHIFT 0xb
1035#define ACP_DAGB_DEBUG_CNT_ENABLE__onion_rd_ask_cnt_enable_MASK 0x1000
1036#define ACP_DAGB_DEBUG_CNT_ENABLE__onion_rd_ask_cnt_enable__SHIFT 0xc
1037#define ACP_DAGB_DEBUG_CNT_ENABLE__onion_rd_go_cnt_enable_MASK 0x2000
1038#define ACP_DAGB_DEBUG_CNT_ENABLE__onion_rd_go_cnt_enable__SHIFT 0xd
1039#define ACP_DAGB_DEBUG_CNT_ENABLE__onion_rd_exp_respcnt_enable_MASK 0x4000
1040#define ACP_DAGB_DEBUG_CNT_ENABLE__onion_rd_exp_respcnt_enable__SHIFT 0xe
1041#define ACP_DAGB_DEBUG_CNT_ENABLE__onion_rd_actual_respcnt_enable_MASK 0x8000
1042#define ACP_DAGB_DEBUG_CNT_ENABLE__onion_rd_actual_respcnt_enable__SHIFT 0xf
1043#define ACP_DAGBG_WR_ASK_CNT__garlic_wr_only_ask_cnt_MASK 0xffff
1044#define ACP_DAGBG_WR_ASK_CNT__garlic_wr_only_ask_cnt__SHIFT 0x0
1045#define ACP_DAGBG_WR_GO_CNT__garlic_wr_only_go_cnt_MASK 0xffff
1046#define ACP_DAGBG_WR_GO_CNT__garlic_wr_only_go_cnt__SHIFT 0x0
1047#define ACP_DAGBG_WR_EXP_RESP_CNT__garlic_wr_exp_resp_cnt_MASK 0xffff
1048#define ACP_DAGBG_WR_EXP_RESP_CNT__garlic_wr_exp_resp_cnt__SHIFT 0x0
1049#define ACP_DAGBG_WR_ACTUAL_RESP_CNT__garlic_wr_actual_resp_cnt_MASK 0xffff
1050#define ACP_DAGBG_WR_ACTUAL_RESP_CNT__garlic_wr_actual_resp_cnt__SHIFT 0x0
1051#define ACP_DAGBG_RD_ASK_CNT__garlic_rd_only_ask_cnt_MASK 0xffff
1052#define ACP_DAGBG_RD_ASK_CNT__garlic_rd_only_ask_cnt__SHIFT 0x0
1053#define ACP_DAGBG_RD_GO_CNT__garlic_rd_only_go_cnt_MASK 0xffff
1054#define ACP_DAGBG_RD_GO_CNT__garlic_rd_only_go_cnt__SHIFT 0x0
1055#define ACP_DAGBG_RD_EXP_RESP_CNT__garlic_rd_exp_resp_cnt_MASK 0xffff
1056#define ACP_DAGBG_RD_EXP_RESP_CNT__garlic_rd_exp_resp_cnt__SHIFT 0x0
1057#define ACP_DAGBG_RD_ACTUAL_RESP_CNT__garlic_rd_actual_resp_cnt_MASK 0xffff
1058#define ACP_DAGBG_RD_ACTUAL_RESP_CNT__garlic_rd_actual_resp_cnt__SHIFT 0x0
1059#define ACP_DAGBO_WR_ASK_CNT__onion_wr_only_ask_cnt_MASK 0xffff
1060#define ACP_DAGBO_WR_ASK_CNT__onion_wr_only_ask_cnt__SHIFT 0x0
1061#define ACP_DAGBO_WR_GO_CNT__onion_wr_only_go_cnt_MASK 0xffff
1062#define ACP_DAGBO_WR_GO_CNT__onion_wr_only_go_cnt__SHIFT 0x0
1063#define ACP_DAGBO_WR_EXP_RESP_CNT__onion_wr_exp_resp_cnt_MASK 0xffff
1064#define ACP_DAGBO_WR_EXP_RESP_CNT__onion_wr_exp_resp_cnt__SHIFT 0x0
1065#define ACP_DAGBO_WR_ACTUAL_RESP_CNT__onion_wr_actual_resp_cnt_MASK 0xffff
1066#define ACP_DAGBO_WR_ACTUAL_RESP_CNT__onion_wr_actual_resp_cnt__SHIFT 0x0
1067#define ACP_DAGBO_RD_ASK_CNT__onion_rd_only_ask_cnt_MASK 0xffff
1068#define ACP_DAGBO_RD_ASK_CNT__onion_rd_only_ask_cnt__SHIFT 0x0
1069#define ACP_DAGBO_RD_GO_CNT__onion_rd_only_go_cnt_MASK 0xffff
1070#define ACP_DAGBO_RD_GO_CNT__onion_rd_only_go_cnt__SHIFT 0x0
1071#define ACP_DAGBO_RD_EXP_RESP_CNT__onion_rd_exp_resp_cnt_MASK 0xffff
1072#define ACP_DAGBO_RD_EXP_RESP_CNT__onion_rd_exp_resp_cnt__SHIFT 0x0
1073#define ACP_DAGBO_RD_ACTUAL_RESP_CNT__onion_rd_actual_resp_cnt_MASK 0xffff
1074#define ACP_DAGBO_RD_ACTUAL_RESP_CNT__onion_rd_actual_resp_cnt__SHIFT 0x0
1075#define ACP_BRB_CONTROL__BRB_BlockSharedRAMArbCntrl_MASK 0xf
1076#define ACP_BRB_CONTROL__BRB_BlockSharedRAMArbCntrl__SHIFT 0x0
1077#define ACP_EXTERNAL_INTR_ENB__ACPExtIntrEnb_MASK 0x1
1078#define ACP_EXTERNAL_INTR_ENB__ACPExtIntrEnb__SHIFT 0x0
1079#define ACP_EXTERNAL_INTR_CNTL__ACPErrMask_MASK 0x1
1080#define ACP_EXTERNAL_INTR_CNTL__ACPErrMask__SHIFT 0x0
1081#define ACP_EXTERNAL_INTR_CNTL__I2SMicDataAvMask_MASK 0x2
1082#define ACP_EXTERNAL_INTR_CNTL__I2SMicDataAvMask__SHIFT 0x1
1083#define ACP_EXTERNAL_INTR_CNTL__I2SSpkr0DataEmptyMask_MASK 0x4
1084#define ACP_EXTERNAL_INTR_CNTL__I2SSpkr0DataEmptyMask__SHIFT 0x2
1085#define ACP_EXTERNAL_INTR_CNTL__I2SSpkr1DataEmptyMask_MASK 0x8
1086#define ACP_EXTERNAL_INTR_CNTL__I2SSpkr1DataEmptyMask__SHIFT 0x3
1087#define ACP_EXTERNAL_INTR_CNTL__I2SBTDataAvMask_MASK 0x10
1088#define ACP_EXTERNAL_INTR_CNTL__I2SBTDataAvMask__SHIFT 0x4
1089#define ACP_EXTERNAL_INTR_CNTL__AzaliaIntrMask_MASK 0x40
1090#define ACP_EXTERNAL_INTR_CNTL__AzaliaIntrMask__SHIFT 0x6
1091#define ACP_EXTERNAL_INTR_CNTL__DSP0TimeoutMask_MASK 0x100
1092#define ACP_EXTERNAL_INTR_CNTL__DSP0TimeoutMask__SHIFT 0x8
1093#define ACP_EXTERNAL_INTR_CNTL__DSP1TimeoutMask_MASK 0x200
1094#define ACP_EXTERNAL_INTR_CNTL__DSP1TimeoutMask__SHIFT 0x9
1095#define ACP_EXTERNAL_INTR_CNTL__DSP2TimeoutMask_MASK 0x400
1096#define ACP_EXTERNAL_INTR_CNTL__DSP2TimeoutMask__SHIFT 0xa
1097#define ACP_EXTERNAL_INTR_CNTL__I2SBTDataEmptyMask_MASK 0x800
1098#define ACP_EXTERNAL_INTR_CNTL__I2SBTDataEmptyMask__SHIFT 0xb
1099#define ACP_EXTERNAL_INTR_CNTL__DMAIOCMask_MASK 0xffff0000
1100#define ACP_EXTERNAL_INTR_CNTL__DMAIOCMask__SHIFT 0x10
1101#define ACP_ERROR_SOURCE_STS__ACPRegUdefADDRErr_MASK 0x1
1102#define ACP_ERROR_SOURCE_STS__ACPRegUdefADDRErr__SHIFT 0x0
1103#define ACP_ERROR_SOURCE_STS__ACPRegUdefADDRErrSource_MASK 0xe
1104#define ACP_ERROR_SOURCE_STS__ACPRegUdefADDRErrSource__SHIFT 0x1
1105#define ACP_ERROR_SOURCE_STS__ACPRegUdefADDRErrSourceOver_MASK 0x10
1106#define ACP_ERROR_SOURCE_STS__ACPRegUdefADDRErrSourceOver__SHIFT 0x4
1107#define ACP_ERROR_SOURCE_STS__BRBAddrErr_MASK 0x20
1108#define ACP_ERROR_SOURCE_STS__BRBAddrErr__SHIFT 0x5
1109#define ACP_ERROR_SOURCE_STS__BRBAddrErrSource_MASK 0x3c0
1110#define ACP_ERROR_SOURCE_STS__BRBAddrErrSource__SHIFT 0x6
1111#define ACP_ERROR_SOURCE_STS__BRBAddrErrSourceOver_MASK 0x400
1112#define ACP_ERROR_SOURCE_STS__BRBAddrErrSourceOver__SHIFT 0xa
1113#define ACP_ERROR_SOURCE_STS__I2SMicOverFlowErr_MASK 0x800
1114#define ACP_ERROR_SOURCE_STS__I2SMicOverFlowErr__SHIFT 0xb
1115#define ACP_ERROR_SOURCE_STS__I2SSpeaker0OverFlowErr_MASK 0x1000
1116#define ACP_ERROR_SOURCE_STS__I2SSpeaker0OverFlowErr__SHIFT 0xc
1117#define ACP_ERROR_SOURCE_STS__I2SSpeaker1OverFlowErr_MASK 0x2000
1118#define ACP_ERROR_SOURCE_STS__I2SSpeaker1OverFlowErr__SHIFT 0xd
1119#define ACP_ERROR_SOURCE_STS__I2SBTRxFifoOverFlowErr_MASK 0x4000
1120#define ACP_ERROR_SOURCE_STS__I2SBTRxFifoOverFlowErr__SHIFT 0xe
1121#define ACP_ERROR_SOURCE_STS__DSPAdrTransRangeErr_MASK 0x8000
1122#define ACP_ERROR_SOURCE_STS__DSPAdrTransRangeErr__SHIFT 0xf
1123#define ACP_ERROR_SOURCE_STS__DSPAdrTransRangeErrSource_MASK 0x70000
1124#define ACP_ERROR_SOURCE_STS__DSPAdrTransRangeErrSource__SHIFT 0x10
1125#define ACP_ERROR_SOURCE_STS__DSPAdrTransRangeErrSourceOver_MASK 0x80000
1126#define ACP_ERROR_SOURCE_STS__DSPAdrTransRangeErrSourceOver__SHIFT 0x13
1127#define ACP_ERROR_SOURCE_STS__DAGBErr_MASK 0x100000
1128#define ACP_ERROR_SOURCE_STS__DAGBErr__SHIFT 0x14
1129#define ACP_ERROR_SOURCE_STS__DAGBErrSource_MASK 0x1e00000
1130#define ACP_ERROR_SOURCE_STS__DAGBErrSource__SHIFT 0x15
1131#define ACP_ERROR_SOURCE_STS__DAGBErrSourceOver_MASK 0x2000000
1132#define ACP_ERROR_SOURCE_STS__DAGBErrSourceOver__SHIFT 0x19
1133#define ACP_ERROR_SOURCE_STS__DMATermOnErr_MASK 0x4000000
1134#define ACP_ERROR_SOURCE_STS__DMATermOnErr__SHIFT 0x1a
1135#define ACP_ERROR_SOURCE_STS__I2SBTTxFifoOverFlowErr_MASK 0x10000000
1136#define ACP_ERROR_SOURCE_STS__I2SBTTxFifoOverFlowErr__SHIFT 0x1c
1137#define ACP_DSP_SW_INTR_TRIG__TrigSWIntHostDSP0_MASK 0x1
1138#define ACP_DSP_SW_INTR_TRIG__TrigSWIntHostDSP0__SHIFT 0x0
1139#define ACP_DSP_SW_INTR_TRIG__TrigSWIntHostDSP1_MASK 0x2
1140#define ACP_DSP_SW_INTR_TRIG__TrigSWIntHostDSP1__SHIFT 0x1
1141#define ACP_DSP_SW_INTR_TRIG__TrigSWIntHostDSP2_MASK 0x4
1142#define ACP_DSP_SW_INTR_TRIG__TrigSWIntHostDSP2__SHIFT 0x2
1143#define ACP_DSP_SW_INTR_TRIG__TrigSWIntDSPnDSP0_MASK 0x100
1144#define ACP_DSP_SW_INTR_TRIG__TrigSWIntDSPnDSP0__SHIFT 0x8
1145#define ACP_DSP_SW_INTR_TRIG__TrigSWIntDSPnDSP1_MASK 0x200
1146#define ACP_DSP_SW_INTR_TRIG__TrigSWIntDSPnDSP1__SHIFT 0x9
1147#define ACP_DSP_SW_INTR_TRIG__TrigSWIntDSPnDSP2_MASK 0x400
1148#define ACP_DSP_SW_INTR_TRIG__TrigSWIntDSPnDSP2__SHIFT 0xa
1149#define ACP_DSP_SW_INTR_TRIG__TrigSWIntDSP0Host_MASK 0x10000
1150#define ACP_DSP_SW_INTR_TRIG__TrigSWIntDSP0Host__SHIFT 0x10
1151#define ACP_DSP_SW_INTR_TRIG__TrigSWIntDSP1Host_MASK 0x20000
1152#define ACP_DSP_SW_INTR_TRIG__TrigSWIntDSP1Host__SHIFT 0x11
1153#define ACP_DSP_SW_INTR_TRIG__TrigSWIntDSP2Host_MASK 0x40000
1154#define ACP_DSP_SW_INTR_TRIG__TrigSWIntDSP2Host__SHIFT 0x12
1155#define ACP_DSP_SW_INTR_CNTL__EnbSWIntHostDSP0_MASK 0x1
1156#define ACP_DSP_SW_INTR_CNTL__EnbSWIntHostDSP0__SHIFT 0x0
1157#define ACP_DSP_SW_INTR_CNTL__EnbSWIntHostDSP1_MASK 0x2
1158#define ACP_DSP_SW_INTR_CNTL__EnbSWIntHostDSP1__SHIFT 0x1
1159#define ACP_DSP_SW_INTR_CNTL__EnbSWIntHostDSP2_MASK 0x4
1160#define ACP_DSP_SW_INTR_CNTL__EnbSWIntHostDSP2__SHIFT 0x2
1161#define ACP_DSP_SW_INTR_CNTL__EnbSWIntDSPnDSP0_MASK 0x100
1162#define ACP_DSP_SW_INTR_CNTL__EnbSWIntDSPnDSP0__SHIFT 0x8
1163#define ACP_DSP_SW_INTR_CNTL__EnbSWIntDSPnDSP1_MASK 0x200
1164#define ACP_DSP_SW_INTR_CNTL__EnbSWIntDSPnDSP1__SHIFT 0x9
1165#define ACP_DSP_SW_INTR_CNTL__EnbSWIntDSPnDSP2_MASK 0x400
1166#define ACP_DSP_SW_INTR_CNTL__EnbSWIntDSPnDSP2__SHIFT 0xa
1167#define ACP_DSP_SW_INTR_CNTL__EnbKernelIntrDSP0Mask_MASK 0x10000
1168#define ACP_DSP_SW_INTR_CNTL__EnbKernelIntrDSP0Mask__SHIFT 0x10
1169#define ACP_DSP_SW_INTR_CNTL__EmbKernelIntrDSP1Mask_MASK 0x20000
1170#define ACP_DSP_SW_INTR_CNTL__EmbKernelIntrDSP1Mask__SHIFT 0x11
1171#define ACP_DSP_SW_INTR_CNTL__EmbKernelIntrDSP2Mask_MASK 0x40000
1172#define ACP_DSP_SW_INTR_CNTL__EmbKernelIntrDSP2Mask__SHIFT 0x12
1173#define ACP_DAGBG_TIMEOUT_CNTL__DAGBGTimeoutValue_MASK 0x3ffff
1174#define ACP_DAGBG_TIMEOUT_CNTL__DAGBGTimeoutValue__SHIFT 0x0
1175#define ACP_DAGBG_TIMEOUT_CNTL__CntEn_MASK 0x80000000
1176#define ACP_DAGBG_TIMEOUT_CNTL__CntEn__SHIFT 0x1f
1177#define ACP_DAGBO_TIMEOUT_CNTL__DAGBOTimeoutValue_MASK 0x3ffff
1178#define ACP_DAGBO_TIMEOUT_CNTL__DAGBOTimeoutValue__SHIFT 0x0
1179#define ACP_DAGBO_TIMEOUT_CNTL__CntEn_MASK 0x80000000
1180#define ACP_DAGBO_TIMEOUT_CNTL__CntEn__SHIFT 0x1f
1181#define ACP_EXTERNAL_INTR_STAT__ACPErrStat_MASK 0x1
1182#define ACP_EXTERNAL_INTR_STAT__ACPErrStat__SHIFT 0x0
1183#define ACP_EXTERNAL_INTR_STAT__ACPErrAck_MASK 0x1
1184#define ACP_EXTERNAL_INTR_STAT__ACPErrAck__SHIFT 0x0
1185#define ACP_EXTERNAL_INTR_STAT__I2SMicDataAvStat_MASK 0x2
1186#define ACP_EXTERNAL_INTR_STAT__I2SMicDataAvStat__SHIFT 0x1
1187#define ACP_EXTERNAL_INTR_STAT__I2SMicDataAvAck_MASK 0x2
1188#define ACP_EXTERNAL_INTR_STAT__I2SMicDataAvAck__SHIFT 0x1
1189#define ACP_EXTERNAL_INTR_STAT__I2SSpkr0DataEmptyStat_MASK 0x4
1190#define ACP_EXTERNAL_INTR_STAT__I2SSpkr0DataEmptyStat__SHIFT 0x2
1191#define ACP_EXTERNAL_INTR_STAT__I2SSpkr0DataEmptyAck_MASK 0x4
1192#define ACP_EXTERNAL_INTR_STAT__I2SSpkr0DataEmptyAck__SHIFT 0x2
1193#define ACP_EXTERNAL_INTR_STAT__I2SSpkr1DataEmptyStat_MASK 0x8
1194#define ACP_EXTERNAL_INTR_STAT__I2SSpkr1DataEmptyStat__SHIFT 0x3
1195#define ACP_EXTERNAL_INTR_STAT__I2SSpkr1DataEmptyAck_MASK 0x8
1196#define ACP_EXTERNAL_INTR_STAT__I2SSpkr1DataEmptyAck__SHIFT 0x3
1197#define ACP_EXTERNAL_INTR_STAT__I2SBTDataAvStat_MASK 0x10
1198#define ACP_EXTERNAL_INTR_STAT__I2SBTDataAvStat__SHIFT 0x4
1199#define ACP_EXTERNAL_INTR_STAT__I2SBTDataAvAck_MASK 0x10
1200#define ACP_EXTERNAL_INTR_STAT__I2SBTDataAvAck__SHIFT 0x4
1201#define ACP_EXTERNAL_INTR_STAT__AzaliaIntrStat_MASK 0x40
1202#define ACP_EXTERNAL_INTR_STAT__AzaliaIntrStat__SHIFT 0x6
1203#define ACP_EXTERNAL_INTR_STAT__AzaliaIntrAck_MASK 0x40
1204#define ACP_EXTERNAL_INTR_STAT__AzaliaIntrAck__SHIFT 0x6
1205#define ACP_EXTERNAL_INTR_STAT__DSP0TimeoutStat_MASK 0x100
1206#define ACP_EXTERNAL_INTR_STAT__DSP0TimeoutStat__SHIFT 0x8
1207#define ACP_EXTERNAL_INTR_STAT__DSP0TimeoutAck_MASK 0x100
1208#define ACP_EXTERNAL_INTR_STAT__DSP0TimeoutAck__SHIFT 0x8
1209#define ACP_EXTERNAL_INTR_STAT__DSP1TimeoutStat_MASK 0x200
1210#define ACP_EXTERNAL_INTR_STAT__DSP1TimeoutStat__SHIFT 0x9
1211#define ACP_EXTERNAL_INTR_STAT__DSP1TimeoutAck_MASK 0x200
1212#define ACP_EXTERNAL_INTR_STAT__DSP1TimeoutAck__SHIFT 0x9
1213#define ACP_EXTERNAL_INTR_STAT__DSP2TimeoutStat_MASK 0x400
1214#define ACP_EXTERNAL_INTR_STAT__DSP2TimeoutStat__SHIFT 0xa
1215#define ACP_EXTERNAL_INTR_STAT__DSP2TimeoutAck_MASK 0x400
1216#define ACP_EXTERNAL_INTR_STAT__DSP2TimeoutAck__SHIFT 0xa
1217#define ACP_EXTERNAL_INTR_STAT__I2SBTDataEmptyStat_MASK 0x800
1218#define ACP_EXTERNAL_INTR_STAT__I2SBTDataEmptyStat__SHIFT 0xb
1219#define ACP_EXTERNAL_INTR_STAT__I2SBTDataEmptyAck_MASK 0x800
1220#define ACP_EXTERNAL_INTR_STAT__I2SBTDataEmptyAck__SHIFT 0xb
1221#define ACP_EXTERNAL_INTR_STAT__DMAIOCStat_MASK 0xffff0000
1222#define ACP_EXTERNAL_INTR_STAT__DMAIOCStat__SHIFT 0x10
1223#define ACP_EXTERNAL_INTR_STAT__DMAIOCAck_MASK 0xffff0000
1224#define ACP_EXTERNAL_INTR_STAT__DMAIOCAck__SHIFT 0x10
1225#define ACP_DSP_SW_INTR_STAT__SWIntHostDSP0Stat_MASK 0x1
1226#define ACP_DSP_SW_INTR_STAT__SWIntHostDSP0Stat__SHIFT 0x0
1227#define ACP_DSP_SW_INTR_STAT__SWIntHostDSP0Ack_MASK 0x1
1228#define ACP_DSP_SW_INTR_STAT__SWIntHostDSP0Ack__SHIFT 0x0
1229#define ACP_DSP_SW_INTR_STAT__SWIntHostDSP1Stat_MASK 0x2
1230#define ACP_DSP_SW_INTR_STAT__SWIntHostDSP1Stat__SHIFT 0x1
1231#define ACP_DSP_SW_INTR_STAT__SWIntHostDSP1Ack_MASK 0x2
1232#define ACP_DSP_SW_INTR_STAT__SWIntHostDSP1Ack__SHIFT 0x1
1233#define ACP_DSP_SW_INTR_STAT__SWIntHostDSP2Stat_MASK 0x4
1234#define ACP_DSP_SW_INTR_STAT__SWIntHostDSP2Stat__SHIFT 0x2
1235#define ACP_DSP_SW_INTR_STAT__SWIntHostDSP2Ack_MASK 0x4
1236#define ACP_DSP_SW_INTR_STAT__SWIntHostDSP2Ack__SHIFT 0x2
1237#define ACP_DSP_SW_INTR_STAT__SWIntDSPnDSP0Stat_MASK 0x100
1238#define ACP_DSP_SW_INTR_STAT__SWIntDSPnDSP0Stat__SHIFT 0x8
1239#define ACP_DSP_SW_INTR_STAT__SWIntDSPnDSP0Ack_MASK 0x100
1240#define ACP_DSP_SW_INTR_STAT__SWIntDSPnDSP0Ack__SHIFT 0x8
1241#define ACP_DSP_SW_INTR_STAT__SWIntDSPnDSP1Stat_MASK 0x200
1242#define ACP_DSP_SW_INTR_STAT__SWIntDSPnDSP1Stat__SHIFT 0x9
1243#define ACP_DSP_SW_INTR_STAT__SWIntDSPnDSP1Ack_MASK 0x200
1244#define ACP_DSP_SW_INTR_STAT__SWIntDSPnDSP1Ack__SHIFT 0x9
1245#define ACP_DSP_SW_INTR_STAT__SWIntDSPnDSP2Stat_MASK 0x400
1246#define ACP_DSP_SW_INTR_STAT__SWIntDSPnDSP2Stat__SHIFT 0xa
1247#define ACP_DSP_SW_INTR_STAT__SWIntDSPnDSP2Ack_MASK 0x400
1248#define ACP_DSP_SW_INTR_STAT__SWIntDSPnDSP2Ack__SHIFT 0xa
1249#define ACP_DSP_SW_INTR_STAT__SWKernelIntrDSP0Stat_MASK 0x10000
1250#define ACP_DSP_SW_INTR_STAT__SWKernelIntrDSP0Stat__SHIFT 0x10
1251#define ACP_DSP_SW_INTR_STAT__SWKernelIntrDSP0Ack_MASK 0x10000
1252#define ACP_DSP_SW_INTR_STAT__SWKernelIntrDSP0Ack__SHIFT 0x10
1253#define ACP_DSP_SW_INTR_STAT__SWKernelIntrDSP1Stat_MASK 0x20000
1254#define ACP_DSP_SW_INTR_STAT__SWKernelIntrDSP1Stat__SHIFT 0x11
1255#define ACP_DSP_SW_INTR_STAT__SWKernelIntrDSP1Ack_MASK 0x20000
1256#define ACP_DSP_SW_INTR_STAT__SWKernelIntrDSP1Ack__SHIFT 0x11
1257#define ACP_DSP_SW_INTR_STAT__SWKernelIntrDSP2Stat_MASK 0x40000
1258#define ACP_DSP_SW_INTR_STAT__SWKernelIntrDSP2Stat__SHIFT 0x12
1259#define ACP_DSP_SW_INTR_STAT__SWKernelIntrDSP2Ack_MASK 0x40000
1260#define ACP_DSP_SW_INTR_STAT__SWKernelIntrDSP2Ack__SHIFT 0x12
1261#define ACP_DSP0_INTR_CNTL__ACPErrMask_MASK 0x1
1262#define ACP_DSP0_INTR_CNTL__ACPErrMask__SHIFT 0x0
1263#define ACP_DSP0_INTR_CNTL__I2SMicDataAvMask_MASK 0x2
1264#define ACP_DSP0_INTR_CNTL__I2SMicDataAvMask__SHIFT 0x1
1265#define ACP_DSP0_INTR_CNTL__I2SSpkr0DataEmptyMask_MASK 0x4
1266#define ACP_DSP0_INTR_CNTL__I2SSpkr0DataEmptyMask__SHIFT 0x2
1267#define ACP_DSP0_INTR_CNTL__I2SSpkr1DataEmptyMask_MASK 0x8
1268#define ACP_DSP0_INTR_CNTL__I2SSpkr1DataEmptyMask__SHIFT 0x3
1269#define ACP_DSP0_INTR_CNTL__I2SBTDataAvMask_MASK 0x10
1270#define ACP_DSP0_INTR_CNTL__I2SBTDataAvMask__SHIFT 0x4
1271#define ACP_DSP0_INTR_CNTL__AzaliaIntrMask_MASK 0x40
1272#define ACP_DSP0_INTR_CNTL__AzaliaIntrMask__SHIFT 0x6
1273#define ACP_DSP0_INTR_CNTL__SMUMailboxWriteMask_MASK 0x100
1274#define ACP_DSP0_INTR_CNTL__SMUMailboxWriteMask__SHIFT 0x8
1275#define ACP_DSP0_INTR_CNTL__SMUStutterStatusMask_MASK 0x200
1276#define ACP_DSP0_INTR_CNTL__SMUStutterStatusMask__SHIFT 0x9
1277#define ACP_DSP0_INTR_CNTL__MCStutterStatusMask_MASK 0x400
1278#define ACP_DSP0_INTR_CNTL__MCStutterStatusMask__SHIFT 0xa
1279#define ACP_DSP0_INTR_CNTL__DSPExtTimerMask_MASK 0x800
1280#define ACP_DSP0_INTR_CNTL__DSPExtTimerMask__SHIFT 0xb
1281#define ACP_DSP0_INTR_CNTL__DSPSemRespMask_MASK 0x1000
1282#define ACP_DSP0_INTR_CNTL__DSPSemRespMask__SHIFT 0xc
1283#define ACP_DSP0_INTR_CNTL__I2SBTDataEmptyMask_MASK 0x2000
1284#define ACP_DSP0_INTR_CNTL__I2SBTDataEmptyMask__SHIFT 0xd
1285#define ACP_DSP0_INTR_CNTL__DMAIOCMask_MASK 0xffff0000
1286#define ACP_DSP0_INTR_CNTL__DMAIOCMask__SHIFT 0x10
1287#define ACP_DSP0_INTR_STAT__ACPErrStat_MASK 0x1
1288#define ACP_DSP0_INTR_STAT__ACPErrStat__SHIFT 0x0
1289#define ACP_DSP0_INTR_STAT__ACPErrAck_MASK 0x1
1290#define ACP_DSP0_INTR_STAT__ACPErrAck__SHIFT 0x0
1291#define ACP_DSP0_INTR_STAT__I2SMicDataAvStat_MASK 0x2
1292#define ACP_DSP0_INTR_STAT__I2SMicDataAvStat__SHIFT 0x1
1293#define ACP_DSP0_INTR_STAT__I2SMicDataAvAck_MASK 0x2
1294#define ACP_DSP0_INTR_STAT__I2SMicDataAvAck__SHIFT 0x1
1295#define ACP_DSP0_INTR_STAT__I2SSpkr0DataEmptyStat_MASK 0x4
1296#define ACP_DSP0_INTR_STAT__I2SSpkr0DataEmptyStat__SHIFT 0x2
1297#define ACP_DSP0_INTR_STAT__I2SSpkr0DataEmptyAck_MASK 0x4
1298#define ACP_DSP0_INTR_STAT__I2SSpkr0DataEmptyAck__SHIFT 0x2
1299#define ACP_DSP0_INTR_STAT__I2SSpkr1DataEmptyStat_MASK 0x8
1300#define ACP_DSP0_INTR_STAT__I2SSpkr1DataEmptyStat__SHIFT 0x3
1301#define ACP_DSP0_INTR_STAT__I2SSpkr1DataEmptyAck_MASK 0x8
1302#define ACP_DSP0_INTR_STAT__I2SSpkr1DataEmptyAck__SHIFT 0x3
1303#define ACP_DSP0_INTR_STAT__I2SBTDataAvStat_MASK 0x10
1304#define ACP_DSP0_INTR_STAT__I2SBTDataAvStat__SHIFT 0x4
1305#define ACP_DSP0_INTR_STAT__I2SBTDataAvAck_MASK 0x10
1306#define ACP_DSP0_INTR_STAT__I2SBTDataAvAck__SHIFT 0x4
1307#define ACP_DSP0_INTR_STAT__AzaliaIntrStat_MASK 0x40
1308#define ACP_DSP0_INTR_STAT__AzaliaIntrStat__SHIFT 0x6
1309#define ACP_DSP0_INTR_STAT__AzaliaIntrAck_MASK 0x40
1310#define ACP_DSP0_INTR_STAT__AzaliaIntrAck__SHIFT 0x6
1311#define ACP_DSP0_INTR_STAT__SMUMailboxWriteStat_MASK 0x100
1312#define ACP_DSP0_INTR_STAT__SMUMailboxWriteStat__SHIFT 0x8
1313#define ACP_DSP0_INTR_STAT__SMUMailboxWriteAck_MASK 0x100
1314#define ACP_DSP0_INTR_STAT__SMUMailboxWriteAck__SHIFT 0x8
1315#define ACP_DSP0_INTR_STAT__SMUStutterStatusStat_MASK 0x200
1316#define ACP_DSP0_INTR_STAT__SMUStutterStatusStat__SHIFT 0x9
1317#define ACP_DSP0_INTR_STAT__SMUStutterStatusAck_MASK 0x200
1318#define ACP_DSP0_INTR_STAT__SMUStutterStatusAck__SHIFT 0x9
1319#define ACP_DSP0_INTR_STAT__MCStutterStatusStat_MASK 0x400
1320#define ACP_DSP0_INTR_STAT__MCStutterStatusStat__SHIFT 0xa
1321#define ACP_DSP0_INTR_STAT__MCStutterStatusAck_MASK 0x400
1322#define ACP_DSP0_INTR_STAT__MCStutterStatusAck__SHIFT 0xa
1323#define ACP_DSP0_INTR_STAT__DSPExtTimerStat_MASK 0x800
1324#define ACP_DSP0_INTR_STAT__DSPExtTimerStat__SHIFT 0xb
1325#define ACP_DSP0_INTR_STAT__DSPExtTimerAck_MASK 0x800
1326#define ACP_DSP0_INTR_STAT__DSPExtTimerAck__SHIFT 0xb
1327#define ACP_DSP0_INTR_STAT__DSPSemRespStat_MASK 0x1000
1328#define ACP_DSP0_INTR_STAT__DSPSemRespStat__SHIFT 0xc
1329#define ACP_DSP0_INTR_STAT__DSPSemRespAck_MASK 0x1000
1330#define ACP_DSP0_INTR_STAT__DSPSemRespAck__SHIFT 0xc
1331#define ACP_DSP0_INTR_STAT__I2SBTDataEmptyStat_MASK 0x2000
1332#define ACP_DSP0_INTR_STAT__I2SBTDataEmptyStat__SHIFT 0xd
1333#define ACP_DSP0_INTR_STAT__I2SBTDataEmptyAck_MASK 0x2000
1334#define ACP_DSP0_INTR_STAT__I2SBTDataEmptyAck__SHIFT 0xd
1335#define ACP_DSP0_INTR_STAT__DMAIOCStat_MASK 0xffff0000
1336#define ACP_DSP0_INTR_STAT__DMAIOCStat__SHIFT 0x10
1337#define ACP_DSP0_INTR_STAT__DMAIOCAck_MASK 0xffff0000
1338#define ACP_DSP0_INTR_STAT__DMAIOCAck__SHIFT 0x10
1339#define ACP_DSP0_TIMEOUT_CNTL__DSP0TimeoutValue_MASK 0x3ffff
1340#define ACP_DSP0_TIMEOUT_CNTL__DSP0TimeoutValue__SHIFT 0x0
1341#define ACP_DSP0_TIMEOUT_CNTL__CntEn_MASK 0x80000000
1342#define ACP_DSP0_TIMEOUT_CNTL__CntEn__SHIFT 0x1f
1343#define ACP_DSP1_INTR_CNTL__ACPErrMask_MASK 0x1
1344#define ACP_DSP1_INTR_CNTL__ACPErrMask__SHIFT 0x0
1345#define ACP_DSP1_INTR_CNTL__I2SMicDataAvMask_MASK 0x2
1346#define ACP_DSP1_INTR_CNTL__I2SMicDataAvMask__SHIFT 0x1
1347#define ACP_DSP1_INTR_CNTL__I2SSpkr0DataEmptyMask_MASK 0x4
1348#define ACP_DSP1_INTR_CNTL__I2SSpkr0DataEmptyMask__SHIFT 0x2
1349#define ACP_DSP1_INTR_CNTL__I2SSpkr1DataEmptyMask_MASK 0x8
1350#define ACP_DSP1_INTR_CNTL__I2SSpkr1DataEmptyMask__SHIFT 0x3
1351#define ACP_DSP1_INTR_CNTL__I2SBTDataAvMask_MASK 0x10
1352#define ACP_DSP1_INTR_CNTL__I2SBTDataAvMask__SHIFT 0x4
1353#define ACP_DSP1_INTR_CNTL__AzaliaIntrMask_MASK 0x40
1354#define ACP_DSP1_INTR_CNTL__AzaliaIntrMask__SHIFT 0x6
1355#define ACP_DSP1_INTR_CNTL__SMUMailboxWriteMask_MASK 0x100
1356#define ACP_DSP1_INTR_CNTL__SMUMailboxWriteMask__SHIFT 0x8
1357#define ACP_DSP1_INTR_CNTL__SMUStutterStatusMask_MASK 0x200
1358#define ACP_DSP1_INTR_CNTL__SMUStutterStatusMask__SHIFT 0x9
1359#define ACP_DSP1_INTR_CNTL__MCStutterStatusMask_MASK 0x400
1360#define ACP_DSP1_INTR_CNTL__MCStutterStatusMask__SHIFT 0xa
1361#define ACP_DSP1_INTR_CNTL__DSPExtTimerMask_MASK 0x800
1362#define ACP_DSP1_INTR_CNTL__DSPExtTimerMask__SHIFT 0xb
1363#define ACP_DSP1_INTR_CNTL__DSPSemRespMask_MASK 0x1000
1364#define ACP_DSP1_INTR_CNTL__DSPSemRespMask__SHIFT 0xc
1365#define ACP_DSP1_INTR_CNTL__I2SBTDataEmptyMask_MASK 0x2000
1366#define ACP_DSP1_INTR_CNTL__I2SBTDataEmptyMask__SHIFT 0xd
1367#define ACP_DSP1_INTR_CNTL__DMAIOCMask_MASK 0xffff0000
1368#define ACP_DSP1_INTR_CNTL__DMAIOCMask__SHIFT 0x10
1369#define ACP_DSP1_INTR_STAT__ACPErrStat_MASK 0x1
1370#define ACP_DSP1_INTR_STAT__ACPErrStat__SHIFT 0x0
1371#define ACP_DSP1_INTR_STAT__ACPErrAck_MASK 0x1
1372#define ACP_DSP1_INTR_STAT__ACPErrAck__SHIFT 0x0
1373#define ACP_DSP1_INTR_STAT__I2SMicDataAvStat_MASK 0x2
1374#define ACP_DSP1_INTR_STAT__I2SMicDataAvStat__SHIFT 0x1
1375#define ACP_DSP1_INTR_STAT__I2SMicDataAvAck_MASK 0x2
1376#define ACP_DSP1_INTR_STAT__I2SMicDataAvAck__SHIFT 0x1
1377#define ACP_DSP1_INTR_STAT__I2SSpkr0DataEmptyStat_MASK 0x4
1378#define ACP_DSP1_INTR_STAT__I2SSpkr0DataEmptyStat__SHIFT 0x2
1379#define ACP_DSP1_INTR_STAT__I2SSpkr0DataEmptyAck_MASK 0x4
1380#define ACP_DSP1_INTR_STAT__I2SSpkr0DataEmptyAck__SHIFT 0x2
1381#define ACP_DSP1_INTR_STAT__I2SSpkr1DataEmptyStat_MASK 0x8
1382#define ACP_DSP1_INTR_STAT__I2SSpkr1DataEmptyStat__SHIFT 0x3
1383#define ACP_DSP1_INTR_STAT__I2SSpkr1DataEmptyAck_MASK 0x8
1384#define ACP_DSP1_INTR_STAT__I2SSpkr1DataEmptyAck__SHIFT 0x3
1385#define ACP_DSP1_INTR_STAT__I2SBTDataAvStat_MASK 0x10
1386#define ACP_DSP1_INTR_STAT__I2SBTDataAvStat__SHIFT 0x4
1387#define ACP_DSP1_INTR_STAT__I2SBTDataAvAck_MASK 0x10
1388#define ACP_DSP1_INTR_STAT__I2SBTDataAvAck__SHIFT 0x4
1389#define ACP_DSP1_INTR_STAT__AzaliaIntrStat_MASK 0x40
1390#define ACP_DSP1_INTR_STAT__AzaliaIntrStat__SHIFT 0x6
1391#define ACP_DSP1_INTR_STAT__AzaliaIntrAck_MASK 0x40
1392#define ACP_DSP1_INTR_STAT__AzaliaIntrAck__SHIFT 0x6
1393#define ACP_DSP1_INTR_STAT__SMUMailboxWriteStat_MASK 0x100
1394#define ACP_DSP1_INTR_STAT__SMUMailboxWriteStat__SHIFT 0x8
1395#define ACP_DSP1_INTR_STAT__SMUMailboxWriteAck_MASK 0x100
1396#define ACP_DSP1_INTR_STAT__SMUMailboxWriteAck__SHIFT 0x8
1397#define ACP_DSP1_INTR_STAT__SMUStutterStatusStat_MASK 0x200
1398#define ACP_DSP1_INTR_STAT__SMUStutterStatusStat__SHIFT 0x9
1399#define ACP_DSP1_INTR_STAT__SMUStutterStatusAck_MASK 0x200
1400#define ACP_DSP1_INTR_STAT__SMUStutterStatusAck__SHIFT 0x9
1401#define ACP_DSP1_INTR_STAT__MCStutterStatusStat_MASK 0x400
1402#define ACP_DSP1_INTR_STAT__MCStutterStatusStat__SHIFT 0xa
1403#define ACP_DSP1_INTR_STAT__MCStutterStatusAck_MASK 0x400
1404#define ACP_DSP1_INTR_STAT__MCStutterStatusAck__SHIFT 0xa
1405#define ACP_DSP1_INTR_STAT__DSPExtTimerStat_MASK 0x800
1406#define ACP_DSP1_INTR_STAT__DSPExtTimerStat__SHIFT 0xb
1407#define ACP_DSP1_INTR_STAT__DSPExtTimerAck_MASK 0x800
1408#define ACP_DSP1_INTR_STAT__DSPExtTimerAck__SHIFT 0xb
1409#define ACP_DSP1_INTR_STAT__DSPSemRespStat_MASK 0x1000
1410#define ACP_DSP1_INTR_STAT__DSPSemRespStat__SHIFT 0xc
1411#define ACP_DSP1_INTR_STAT__DSPSemRespAck_MASK 0x1000
1412#define ACP_DSP1_INTR_STAT__DSPSemRespAck__SHIFT 0xc
1413#define ACP_DSP1_INTR_STAT__I2SBTDataEmptyStat_MASK 0x2000
1414#define ACP_DSP1_INTR_STAT__I2SBTDataEmptyStat__SHIFT 0xd
1415#define ACP_DSP1_INTR_STAT__I2SBTDataEmptyAck_MASK 0x2000
1416#define ACP_DSP1_INTR_STAT__I2SBTDataEmptyAck__SHIFT 0xd
1417#define ACP_DSP1_INTR_STAT__DMAIOCStat_MASK 0xffff0000
1418#define ACP_DSP1_INTR_STAT__DMAIOCStat__SHIFT 0x10
1419#define ACP_DSP1_INTR_STAT__DMAIOCAck_MASK 0xffff0000
1420#define ACP_DSP1_INTR_STAT__DMAIOCAck__SHIFT 0x10
1421#define ACP_DSP1_TIMEOUT_CNTL__DSP1TimeoutValue_MASK 0x3ffff
1422#define ACP_DSP1_TIMEOUT_CNTL__DSP1TimeoutValue__SHIFT 0x0
1423#define ACP_DSP1_TIMEOUT_CNTL__CntEn_MASK 0x80000000
1424#define ACP_DSP1_TIMEOUT_CNTL__CntEn__SHIFT 0x1f
1425#define ACP_DSP2_INTR_CNTL__ACPErrMask_MASK 0x1
1426#define ACP_DSP2_INTR_CNTL__ACPErrMask__SHIFT 0x0
1427#define ACP_DSP2_INTR_CNTL__I2SMicDataAvMask_MASK 0x2
1428#define ACP_DSP2_INTR_CNTL__I2SMicDataAvMask__SHIFT 0x1
1429#define ACP_DSP2_INTR_CNTL__I2SSpkr0DataEmptyMask_MASK 0x4
1430#define ACP_DSP2_INTR_CNTL__I2SSpkr0DataEmptyMask__SHIFT 0x2
1431#define ACP_DSP2_INTR_CNTL__I2SSpkr1DataEmptyMask_MASK 0x8
1432#define ACP_DSP2_INTR_CNTL__I2SSpkr1DataEmptyMask__SHIFT 0x3
1433#define ACP_DSP2_INTR_CNTL__I2SBTDataAvMask_MASK 0x10
1434#define ACP_DSP2_INTR_CNTL__I2SBTDataAvMask__SHIFT 0x4
1435#define ACP_DSP2_INTR_CNTL__AzaliaIntrMask_MASK 0x40
1436#define ACP_DSP2_INTR_CNTL__AzaliaIntrMask__SHIFT 0x6
1437#define ACP_DSP2_INTR_CNTL__SMUMailboxWriteMask_MASK 0x100
1438#define ACP_DSP2_INTR_CNTL__SMUMailboxWriteMask__SHIFT 0x8
1439#define ACP_DSP2_INTR_CNTL__SMUStutterStatusMask_MASK 0x200
1440#define ACP_DSP2_INTR_CNTL__SMUStutterStatusMask__SHIFT 0x9
1441#define ACP_DSP2_INTR_CNTL__MCStutterStatusMask_MASK 0x400
1442#define ACP_DSP2_INTR_CNTL__MCStutterStatusMask__SHIFT 0xa
1443#define ACP_DSP2_INTR_CNTL__DSPExtTimerMask_MASK 0x800
1444#define ACP_DSP2_INTR_CNTL__DSPExtTimerMask__SHIFT 0xb
1445#define ACP_DSP2_INTR_CNTL__DSPSemRespMask_MASK 0x1000
1446#define ACP_DSP2_INTR_CNTL__DSPSemRespMask__SHIFT 0xc
1447#define ACP_DSP2_INTR_CNTL__I2SBTDataEmptyMask_MASK 0x2000
1448#define ACP_DSP2_INTR_CNTL__I2SBTDataEmptyMask__SHIFT 0xd
1449#define ACP_DSP2_INTR_CNTL__DMAIOCMask_MASK 0xffff0000
1450#define ACP_DSP2_INTR_CNTL__DMAIOCMask__SHIFT 0x10
1451#define ACP_DSP2_INTR_STAT__ACPErrStat_MASK 0x1
1452#define ACP_DSP2_INTR_STAT__ACPErrStat__SHIFT 0x0
1453#define ACP_DSP2_INTR_STAT__ACPErrAck_MASK 0x1
1454#define ACP_DSP2_INTR_STAT__ACPErrAck__SHIFT 0x0
1455#define ACP_DSP2_INTR_STAT__I2SMicDataAvStat_MASK 0x2
1456#define ACP_DSP2_INTR_STAT__I2SMicDataAvStat__SHIFT 0x1
1457#define ACP_DSP2_INTR_STAT__I2SMicDataAvAck_MASK 0x2
1458#define ACP_DSP2_INTR_STAT__I2SMicDataAvAck__SHIFT 0x1
1459#define ACP_DSP2_INTR_STAT__I2SSpkr0DataEmptyStat_MASK 0x4
1460#define ACP_DSP2_INTR_STAT__I2SSpkr0DataEmptyStat__SHIFT 0x2
1461#define ACP_DSP2_INTR_STAT__I2SSpkr0DataEmptyAck_MASK 0x4
1462#define ACP_DSP2_INTR_STAT__I2SSpkr0DataEmptyAck__SHIFT 0x2
1463#define ACP_DSP2_INTR_STAT__I2SSpkr1DataEmptyStat_MASK 0x8
1464#define ACP_DSP2_INTR_STAT__I2SSpkr1DataEmptyStat__SHIFT 0x3
1465#define ACP_DSP2_INTR_STAT__I2SSpkr1DataEmptyAck_MASK 0x8
1466#define ACP_DSP2_INTR_STAT__I2SSpkr1DataEmptyAck__SHIFT 0x3
1467#define ACP_DSP2_INTR_STAT__I2SBTDataAvStat_MASK 0x10
1468#define ACP_DSP2_INTR_STAT__I2SBTDataAvStat__SHIFT 0x4
1469#define ACP_DSP2_INTR_STAT__I2SBTDataAvAck_MASK 0x10
1470#define ACP_DSP2_INTR_STAT__I2SBTDataAvAck__SHIFT 0x4
1471#define ACP_DSP2_INTR_STAT__AzaliaIntrStat_MASK 0x40
1472#define ACP_DSP2_INTR_STAT__AzaliaIntrStat__SHIFT 0x6
1473#define ACP_DSP2_INTR_STAT__AzaliaIntrAck_MASK 0x40
1474#define ACP_DSP2_INTR_STAT__AzaliaIntrAck__SHIFT 0x6
1475#define ACP_DSP2_INTR_STAT__SMUMailboxWriteStat_MASK 0x100
1476#define ACP_DSP2_INTR_STAT__SMUMailboxWriteStat__SHIFT 0x8
1477#define ACP_DSP2_INTR_STAT__SMUMailboxWriteAck_MASK 0x100
1478#define ACP_DSP2_INTR_STAT__SMUMailboxWriteAck__SHIFT 0x8
1479#define ACP_DSP2_INTR_STAT__SMUStutterStatusStat_MASK 0x200
1480#define ACP_DSP2_INTR_STAT__SMUStutterStatusStat__SHIFT 0x9
1481#define ACP_DSP2_INTR_STAT__SMUStutterStatusAck_MASK 0x200
1482#define ACP_DSP2_INTR_STAT__SMUStutterStatusAck__SHIFT 0x9
1483#define ACP_DSP2_INTR_STAT__MCStutterStatusStat_MASK 0x400
1484#define ACP_DSP2_INTR_STAT__MCStutterStatusStat__SHIFT 0xa
1485#define ACP_DSP2_INTR_STAT__MCStutterStatusAck_MASK 0x400
1486#define ACP_DSP2_INTR_STAT__MCStutterStatusAck__SHIFT 0xa
1487#define ACP_DSP2_INTR_STAT__DSPExtTimerStat_MASK 0x800
1488#define ACP_DSP2_INTR_STAT__DSPExtTimerStat__SHIFT 0xb
1489#define ACP_DSP2_INTR_STAT__DSPExtTimerAck_MASK 0x800
1490#define ACP_DSP2_INTR_STAT__DSPExtTimerAck__SHIFT 0xb
1491#define ACP_DSP2_INTR_STAT__DSPSemRespStat_MASK 0x1000
1492#define ACP_DSP2_INTR_STAT__DSPSemRespStat__SHIFT 0xc
1493#define ACP_DSP2_INTR_STAT__DSPSemRespAck_MASK 0x1000
1494#define ACP_DSP2_INTR_STAT__DSPSemRespAck__SHIFT 0xc
1495#define ACP_DSP2_INTR_STAT__I2SBTDataEmptyStat_MASK 0x2000
1496#define ACP_DSP2_INTR_STAT__I2SBTDataEmptyStat__SHIFT 0xd
1497#define ACP_DSP2_INTR_STAT__I2SBTDataEmptyAck_MASK 0x2000
1498#define ACP_DSP2_INTR_STAT__I2SBTDataEmptyAck__SHIFT 0xd
1499#define ACP_DSP2_INTR_STAT__DMAIOCStat_MASK 0xffff0000
1500#define ACP_DSP2_INTR_STAT__DMAIOCStat__SHIFT 0x10
1501#define ACP_DSP2_INTR_STAT__DMAIOCAck_MASK 0xffff0000
1502#define ACP_DSP2_INTR_STAT__DMAIOCAck__SHIFT 0x10
1503#define ACP_DSP2_TIMEOUT_CNTL__DSP2TimeoutValue_MASK 0x3ffff
1504#define ACP_DSP2_TIMEOUT_CNTL__DSP2TimeoutValue__SHIFT 0x0
1505#define ACP_DSP2_TIMEOUT_CNTL__CntEn_MASK 0x80000000
1506#define ACP_DSP2_TIMEOUT_CNTL__CntEn__SHIFT 0x1f
1507#define ACP_DSP0_EXT_TIMER_CNTL__TimerCount_MASK 0xffffff
1508#define ACP_DSP0_EXT_TIMER_CNTL__TimerCount__SHIFT 0x0
1509#define ACP_DSP0_EXT_TIMER_CNTL__TimerCntl_MASK 0xc0000000
1510#define ACP_DSP0_EXT_TIMER_CNTL__TimerCntl__SHIFT 0x1e
1511#define ACP_DSP1_EXT_TIMER_CNTL__TimerCount_MASK 0xffffff
1512#define ACP_DSP1_EXT_TIMER_CNTL__TimerCount__SHIFT 0x0
1513#define ACP_DSP1_EXT_TIMER_CNTL__TimerCntl_MASK 0xc0000000
1514#define ACP_DSP1_EXT_TIMER_CNTL__TimerCntl__SHIFT 0x1e
1515#define ACP_DSP2_EXT_TIMER_CNTL__TimerCount_MASK 0xffffff
1516#define ACP_DSP2_EXT_TIMER_CNTL__TimerCount__SHIFT 0x0
1517#define ACP_DSP2_EXT_TIMER_CNTL__TimerCntl_MASK 0xc0000000
1518#define ACP_DSP2_EXT_TIMER_CNTL__TimerCntl__SHIFT 0x1e
1519#define ACP_AXI2DAGB_SEM_0__AXI2DAGBGblSemReg_MASK 0x1
1520#define ACP_AXI2DAGB_SEM_0__AXI2DAGBGblSemReg__SHIFT 0x0
1521#define ACP_AXI2DAGB_SEM_1__AXI2DAGBGblSemReg_MASK 0x1
1522#define ACP_AXI2DAGB_SEM_1__AXI2DAGBGblSemReg__SHIFT 0x0
1523#define ACP_AXI2DAGB_SEM_2__AXI2DAGBGblSemReg_MASK 0x1
1524#define ACP_AXI2DAGB_SEM_2__AXI2DAGBGblSemReg__SHIFT 0x0
1525#define ACP_AXI2DAGB_SEM_3__AXI2DAGBGblSemReg_MASK 0x1
1526#define ACP_AXI2DAGB_SEM_3__AXI2DAGBGblSemReg__SHIFT 0x0
1527#define ACP_AXI2DAGB_SEM_4__AXI2DAGBGblSemReg_MASK 0x1
1528#define ACP_AXI2DAGB_SEM_4__AXI2DAGBGblSemReg__SHIFT 0x0
1529#define ACP_AXI2DAGB_SEM_5__AXI2DAGBGblSemReg_MASK 0x1
1530#define ACP_AXI2DAGB_SEM_5__AXI2DAGBGblSemReg__SHIFT 0x0
1531#define ACP_AXI2DAGB_SEM_6__AXI2DAGBGblSemReg_MASK 0x1
1532#define ACP_AXI2DAGB_SEM_6__AXI2DAGBGblSemReg__SHIFT 0x0
1533#define ACP_AXI2DAGB_SEM_7__AXI2DAGBGblSemReg_MASK 0x1
1534#define ACP_AXI2DAGB_SEM_7__AXI2DAGBGblSemReg__SHIFT 0x0
1535#define ACP_AXI2DAGB_SEM_8__AXI2DAGBGblSemReg_MASK 0x1
1536#define ACP_AXI2DAGB_SEM_8__AXI2DAGBGblSemReg__SHIFT 0x0
1537#define ACP_AXI2DAGB_SEM_9__AXI2DAGBGblSemReg_MASK 0x1
1538#define ACP_AXI2DAGB_SEM_9__AXI2DAGBGblSemReg__SHIFT 0x0
1539#define ACP_AXI2DAGB_SEM_10__AXI2DAGBGblSemReg_MASK 0x1
1540#define ACP_AXI2DAGB_SEM_10__AXI2DAGBGblSemReg__SHIFT 0x0
1541#define ACP_AXI2DAGB_SEM_11__AXI2DAGBGblSemReg_MASK 0x1
1542#define ACP_AXI2DAGB_SEM_11__AXI2DAGBGblSemReg__SHIFT 0x0
1543#define ACP_AXI2DAGB_SEM_12__AXI2DAGBGblSemReg_MASK 0x1
1544#define ACP_AXI2DAGB_SEM_12__AXI2DAGBGblSemReg__SHIFT 0x0
1545#define ACP_AXI2DAGB_SEM_13__AXI2DAGBGblSemReg_MASK 0x1
1546#define ACP_AXI2DAGB_SEM_13__AXI2DAGBGblSemReg__SHIFT 0x0
1547#define ACP_AXI2DAGB_SEM_14__AXI2DAGBGblSemReg_MASK 0x1
1548#define ACP_AXI2DAGB_SEM_14__AXI2DAGBGblSemReg__SHIFT 0x0
1549#define ACP_AXI2DAGB_SEM_15__AXI2DAGBGblSemReg_MASK 0x1
1550#define ACP_AXI2DAGB_SEM_15__AXI2DAGBGblSemReg__SHIFT 0x0
1551#define ACP_AXI2DAGB_SEM_16__AXI2DAGBGblSemReg_MASK 0x1
1552#define ACP_AXI2DAGB_SEM_16__AXI2DAGBGblSemReg__SHIFT 0x0
1553#define ACP_AXI2DAGB_SEM_17__AXI2DAGBGblSemReg_MASK 0x1
1554#define ACP_AXI2DAGB_SEM_17__AXI2DAGBGblSemReg__SHIFT 0x0
1555#define ACP_AXI2DAGB_SEM_18__AXI2DAGBGblSemReg_MASK 0x1
1556#define ACP_AXI2DAGB_SEM_18__AXI2DAGBGblSemReg__SHIFT 0x0
1557#define ACP_AXI2DAGB_SEM_19__AXI2DAGBGblSemReg_MASK 0x1
1558#define ACP_AXI2DAGB_SEM_19__AXI2DAGBGblSemReg__SHIFT 0x0
1559#define ACP_AXI2DAGB_SEM_20__AXI2DAGBGblSemReg_MASK 0x1
1560#define ACP_AXI2DAGB_SEM_20__AXI2DAGBGblSemReg__SHIFT 0x0
1561#define ACP_AXI2DAGB_SEM_21__AXI2DAGBGblSemReg_MASK 0x1
1562#define ACP_AXI2DAGB_SEM_21__AXI2DAGBGblSemReg__SHIFT 0x0
1563#define ACP_AXI2DAGB_SEM_22__AXI2DAGBGblSemReg_MASK 0x1
1564#define ACP_AXI2DAGB_SEM_22__AXI2DAGBGblSemReg__SHIFT 0x0
1565#define ACP_AXI2DAGB_SEM_23__AXI2DAGBGblSemReg_MASK 0x1
1566#define ACP_AXI2DAGB_SEM_23__AXI2DAGBGblSemReg__SHIFT 0x0
1567#define ACP_AXI2DAGB_SEM_24__AXI2DAGBGblSemReg_MASK 0x1
1568#define ACP_AXI2DAGB_SEM_24__AXI2DAGBGblSemReg__SHIFT 0x0
1569#define ACP_AXI2DAGB_SEM_25__AXI2DAGBGblSemReg_MASK 0x1
1570#define ACP_AXI2DAGB_SEM_25__AXI2DAGBGblSemReg__SHIFT 0x0
1571#define ACP_AXI2DAGB_SEM_26__AXI2DAGBGblSemReg_MASK 0x1
1572#define ACP_AXI2DAGB_SEM_26__AXI2DAGBGblSemReg__SHIFT 0x0
1573#define ACP_AXI2DAGB_SEM_27__AXI2DAGBGblSemReg_MASK 0x1
1574#define ACP_AXI2DAGB_SEM_27__AXI2DAGBGblSemReg__SHIFT 0x0
1575#define ACP_AXI2DAGB_SEM_28__AXI2DAGBGblSemReg_MASK 0x1
1576#define ACP_AXI2DAGB_SEM_28__AXI2DAGBGblSemReg__SHIFT 0x0
1577#define ACP_AXI2DAGB_SEM_29__AXI2DAGBGblSemReg_MASK 0x1
1578#define ACP_AXI2DAGB_SEM_29__AXI2DAGBGblSemReg__SHIFT 0x0
1579#define ACP_AXI2DAGB_SEM_30__AXI2DAGBGblSemReg_MASK 0x1
1580#define ACP_AXI2DAGB_SEM_30__AXI2DAGBGblSemReg__SHIFT 0x0
1581#define ACP_AXI2DAGB_SEM_31__AXI2DAGBGblSemReg_MASK 0x1
1582#define ACP_AXI2DAGB_SEM_31__AXI2DAGBGblSemReg__SHIFT 0x0
1583#define ACP_AXI2DAGB_SEM_32__AXI2DAGBGblSemReg_MASK 0x1
1584#define ACP_AXI2DAGB_SEM_32__AXI2DAGBGblSemReg__SHIFT 0x0
1585#define ACP_AXI2DAGB_SEM_33__AXI2DAGBGblSemReg_MASK 0x1
1586#define ACP_AXI2DAGB_SEM_33__AXI2DAGBGblSemReg__SHIFT 0x0
1587#define ACP_AXI2DAGB_SEM_34__AXI2DAGBGblSemReg_MASK 0x1
1588#define ACP_AXI2DAGB_SEM_34__AXI2DAGBGblSemReg__SHIFT 0x0
1589#define ACP_AXI2DAGB_SEM_35__AXI2DAGBGblSemReg_MASK 0x1
1590#define ACP_AXI2DAGB_SEM_35__AXI2DAGBGblSemReg__SHIFT 0x0
1591#define ACP_AXI2DAGB_SEM_36__AXI2DAGBGblSemReg_MASK 0x1
1592#define ACP_AXI2DAGB_SEM_36__AXI2DAGBGblSemReg__SHIFT 0x0
1593#define ACP_AXI2DAGB_SEM_37__AXI2DAGBGblSemReg_MASK 0x1
1594#define ACP_AXI2DAGB_SEM_37__AXI2DAGBGblSemReg__SHIFT 0x0
1595#define ACP_AXI2DAGB_SEM_38__AXI2DAGBGblSemReg_MASK 0x1
1596#define ACP_AXI2DAGB_SEM_38__AXI2DAGBGblSemReg__SHIFT 0x0
1597#define ACP_AXI2DAGB_SEM_39__AXI2DAGBGblSemReg_MASK 0x1
1598#define ACP_AXI2DAGB_SEM_39__AXI2DAGBGblSemReg__SHIFT 0x0
1599#define ACP_AXI2DAGB_SEM_40__AXI2DAGBGblSemReg_MASK 0x1
1600#define ACP_AXI2DAGB_SEM_40__AXI2DAGBGblSemReg__SHIFT 0x0
1601#define ACP_AXI2DAGB_SEM_41__AXI2DAGBGblSemReg_MASK 0x1
1602#define ACP_AXI2DAGB_SEM_41__AXI2DAGBGblSemReg__SHIFT 0x0
1603#define ACP_AXI2DAGB_SEM_42__AXI2DAGBGblSemReg_MASK 0x1
1604#define ACP_AXI2DAGB_SEM_42__AXI2DAGBGblSemReg__SHIFT 0x0
1605#define ACP_AXI2DAGB_SEM_43__AXI2DAGBGblSemReg_MASK 0x1
1606#define ACP_AXI2DAGB_SEM_43__AXI2DAGBGblSemReg__SHIFT 0x0
1607#define ACP_AXI2DAGB_SEM_44__AXI2DAGBGblSemReg_MASK 0x1
1608#define ACP_AXI2DAGB_SEM_44__AXI2DAGBGblSemReg__SHIFT 0x0
1609#define ACP_AXI2DAGB_SEM_45__AXI2DAGBGblSemReg_MASK 0x1
1610#define ACP_AXI2DAGB_SEM_45__AXI2DAGBGblSemReg__SHIFT 0x0
1611#define ACP_AXI2DAGB_SEM_46__AXI2DAGBGblSemReg_MASK 0x1
1612#define ACP_AXI2DAGB_SEM_46__AXI2DAGBGblSemReg__SHIFT 0x0
1613#define ACP_AXI2DAGB_SEM_47__AXI2DAGBGblSemReg_MASK 0x1
1614#define ACP_AXI2DAGB_SEM_47__AXI2DAGBGblSemReg__SHIFT 0x0
1615#define ACP_SRBM_Client_Base_Addr__SRBM_Client_base_addr_MASK 0xff
1616#define ACP_SRBM_Client_Base_Addr__SRBM_Client_base_addr__SHIFT 0x0
1617#define ACP_SRBM_Client_RDDATA__ReadData_MASK 0xffffffff
1618#define ACP_SRBM_Client_RDDATA__ReadData__SHIFT 0x0
1619#define ACP_SRBM_Cycle_Sts__SRBM_Client_Sts_MASK 0x1
1620#define ACP_SRBM_Cycle_Sts__SRBM_Client_Sts__SHIFT 0x0
1621#define ACP_SRBM_Targ_Idx_Addr__SRBM_Targ_Idx_addr_MASK 0x7ffffff
1622#define ACP_SRBM_Targ_Idx_Addr__SRBM_Targ_Idx_addr__SHIFT 0x0
1623#define ACP_SRBM_Targ_Idx_Data__SRBM_Targ_Idx_Data_MASK 0xffffffff
1624#define ACP_SRBM_Targ_Idx_Data__SRBM_Targ_Idx_Data__SHIFT 0x0
1625#define ACP_SEMA_ADDR_LOW__ADDR_9_3_MASK 0x7f
1626#define ACP_SEMA_ADDR_LOW__ADDR_9_3__SHIFT 0x0
1627#define ACP_SEMA_ADDR_HIGH__ADDR_39_10_MASK 0x3fffffff
1628#define ACP_SEMA_ADDR_HIGH__ADDR_39_10__SHIFT 0x0
1629#define ACP_SEMA_CMD__REQ_CMD_MASK 0xf
1630#define ACP_SEMA_CMD__REQ_CMD__SHIFT 0x0
1631#define ACP_SEMA_CMD__WR_PHASE_MASK 0x30
1632#define ACP_SEMA_CMD__WR_PHASE__SHIFT 0x4
1633#define ACP_SEMA_CMD__VMID_EN_MASK 0x80
1634#define ACP_SEMA_CMD__VMID_EN__SHIFT 0x7
1635#define ACP_SEMA_CMD__VMID_MASK 0xf00
1636#define ACP_SEMA_CMD__VMID__SHIFT 0x8
1637#define ACP_SEMA_CMD__ATC_MASK 0x1000
1638#define ACP_SEMA_CMD__ATC__SHIFT 0xc
1639#define ACP_SEMA_STS__REQ_STS_MASK 0x3
1640#define ACP_SEMA_STS__REQ_STS__SHIFT 0x0
1641#define ACP_SEMA_STS__REQ_RESP_AVAIL_MASK 0x100
1642#define ACP_SEMA_STS__REQ_RESP_AVAIL__SHIFT 0x8
1643#define ACP_SEMA_REQ__ISSUE_POLL_REQ_MASK 0x1
1644#define ACP_SEMA_REQ__ISSUE_POLL_REQ__SHIFT 0x0
1645#define ACP_FW_STATUS__RUN_MASK 0x1
1646#define ACP_FW_STATUS__RUN__SHIFT 0x0
1647#define ACP_FUTURE_REG_ACLK_0__ACPFutureReg_MASK 0xffffffff
1648#define ACP_FUTURE_REG_ACLK_0__ACPFutureReg__SHIFT 0x0
1649#define ACP_FUTURE_REG_ACLK_1__ACPFutureReg_MASK 0xffffffff
1650#define ACP_FUTURE_REG_ACLK_1__ACPFutureReg__SHIFT 0x0
1651#define ACP_FUTURE_REG_ACLK_2__ACPFutureReg_MASK 0xffffffff
1652#define ACP_FUTURE_REG_ACLK_2__ACPFutureReg__SHIFT 0x0
1653#define ACP_FUTURE_REG_ACLK_3__ACPFutureReg_MASK 0xffffffff
1654#define ACP_FUTURE_REG_ACLK_3__ACPFutureReg__SHIFT 0x0
1655#define ACP_FUTURE_REG_ACLK_4__ACPFutureReg_MASK 0xffffffff
1656#define ACP_FUTURE_REG_ACLK_4__ACPFutureReg__SHIFT 0x0
1657#define ACP_TIMER__ACP_Timer_count_MASK 0xffffffff
1658#define ACP_TIMER__ACP_Timer_count__SHIFT 0x0
1659#define ACP_TIMER_CNTL__ACP_Timer_control_MASK 0x1
1660#define ACP_TIMER_CNTL__ACP_Timer_control__SHIFT 0x0
1661#define ACP_DSP0_TIMER__ACP_DSP0_timer_MASK 0xffffff
1662#define ACP_DSP0_TIMER__ACP_DSP0_timer__SHIFT 0x0
1663#define ACP_DSP1_TIMER__ACP_DSP1_timer_MASK 0xffffff
1664#define ACP_DSP1_TIMER__ACP_DSP1_timer__SHIFT 0x0
1665#define ACP_DSP2_TIMER__ACP_DSP2_timer_MASK 0xffffff
1666#define ACP_DSP2_TIMER__ACP_DSP2_timer__SHIFT 0x0
1667#define ACP_I2S_TRANSMIT_BYTE_CNT_HIGH__i2s_sp_tx_byte_cnt_high_MASK 0xffffffff
1668#define ACP_I2S_TRANSMIT_BYTE_CNT_HIGH__i2s_sp_tx_byte_cnt_high__SHIFT 0x0
1669#define ACP_I2S_TRANSMIT_BYTE_CNT_LOW__i2s_sp_tx_byte_cnt_low_MASK 0xffffffff
1670#define ACP_I2S_TRANSMIT_BYTE_CNT_LOW__i2s_sp_tx_byte_cnt_low__SHIFT 0x0
1671#define ACP_I2S_BT_TRANSMIT_BYTE_CNT_HIGH__i2s_bt_tx_byte_cnt_high_MASK 0xffffffff
1672#define ACP_I2S_BT_TRANSMIT_BYTE_CNT_HIGH__i2s_bt_tx_byte_cnt_high__SHIFT 0x0
1673#define ACP_I2S_BT_TRANSMIT_BYTE_CNT_LOW__i2s_bt_tx_byte_cnt_low_MASK 0xffffffff
1674#define ACP_I2S_BT_TRANSMIT_BYTE_CNT_LOW__i2s_bt_tx_byte_cnt_low__SHIFT 0x0
1675#define ACP_I2S_BT_RECEIVE_BYTE_CNT_HIGH__i2s_bt_rx_byte_cnt_high_MASK 0xffffffff
1676#define ACP_I2S_BT_RECEIVE_BYTE_CNT_HIGH__i2s_bt_rx_byte_cnt_high__SHIFT 0x0
1677#define ACP_I2S_BT_RECEIVE_BYTE_CNT_LOW__i2s_bt_rx_byte_cnt_low_MASK 0xffffffff
1678#define ACP_I2S_BT_RECEIVE_BYTE_CNT_LOW__i2s_bt_rx_byte_cnt_low__SHIFT 0x0
1679#define ACP_DSP0_CS_STATE__DSP0_CS_state_MASK 0x1
1680#define ACP_DSP0_CS_STATE__DSP0_CS_state__SHIFT 0x0
1681#define ACP_DSP1_CS_STATE__DSP1_CS_state_MASK 0x1
1682#define ACP_DSP1_CS_STATE__DSP1_CS_state__SHIFT 0x0
1683#define ACP_DSP2_CS_STATE__DSP2_CS_state_MASK 0x1
1684#define ACP_DSP2_CS_STATE__DSP2_CS_state__SHIFT 0x0
1685#define ACP_SCRATCH_REG_BASE_ADDR__SCRATCH_REG_BASE_ADDR_MASK 0x7ffff
1686#define ACP_SCRATCH_REG_BASE_ADDR__SCRATCH_REG_BASE_ADDR__SHIFT 0x0
1687#define CC_ACP_EFUSE__DSP0_DISABLE_MASK 0x2
1688#define CC_ACP_EFUSE__DSP0_DISABLE__SHIFT 0x1
1689#define CC_ACP_EFUSE__DSP1_DISABLE_MASK 0x4
1690#define CC_ACP_EFUSE__DSP1_DISABLE__SHIFT 0x2
1691#define CC_ACP_EFUSE__DSP2_DISABLE_MASK 0x8
1692#define CC_ACP_EFUSE__DSP2_DISABLE__SHIFT 0x3
1693#define CC_ACP_EFUSE__ACP_DISABLE_MASK 0x10
1694#define CC_ACP_EFUSE__ACP_DISABLE__SHIFT 0x4
1695#define ACP_PGFSM_RETAIN_REG__ACP_P1_ON_OFF_MASK 0x1
1696#define ACP_PGFSM_RETAIN_REG__ACP_P1_ON_OFF__SHIFT 0x0
1697#define ACP_PGFSM_RETAIN_REG__ACP_P2_ON_OFF_MASK 0x2
1698#define ACP_PGFSM_RETAIN_REG__ACP_P2_ON_OFF__SHIFT 0x1
1699#define ACP_PGFSM_RETAIN_REG__ACP_DSP0_ON_OFF_MASK 0x4
1700#define ACP_PGFSM_RETAIN_REG__ACP_DSP0_ON_OFF__SHIFT 0x2
1701#define ACP_PGFSM_RETAIN_REG__ACP_DSP1_ON_OFF_MASK 0x8
1702#define ACP_PGFSM_RETAIN_REG__ACP_DSP1_ON_OFF__SHIFT 0x3
1703#define ACP_PGFSM_RETAIN_REG__ACP_DSP2_ON_OFF_MASK 0x10
1704#define ACP_PGFSM_RETAIN_REG__ACP_DSP2_ON_OFF__SHIFT 0x4
1705#define ACP_PGFSM_RETAIN_REG__ACP_AZ_ON_OFF_MASK 0x20
1706#define ACP_PGFSM_RETAIN_REG__ACP_AZ_ON_OFF__SHIFT 0x5
1707#define ACP_PGFSM_CONFIG_REG__FSM_ADDR_MASK 0xff
1708#define ACP_PGFSM_CONFIG_REG__FSM_ADDR__SHIFT 0x0
1709#define ACP_PGFSM_CONFIG_REG__Power_Down_MASK 0x100
1710#define ACP_PGFSM_CONFIG_REG__Power_Down__SHIFT 0x8
1711#define ACP_PGFSM_CONFIG_REG__Power_Up_MASK 0x200
1712#define ACP_PGFSM_CONFIG_REG__Power_Up__SHIFT 0x9
1713#define ACP_PGFSM_CONFIG_REG__P1_Select_MASK 0x400
1714#define ACP_PGFSM_CONFIG_REG__P1_Select__SHIFT 0xa
1715#define ACP_PGFSM_CONFIG_REG__P2_Select_MASK 0x800
1716#define ACP_PGFSM_CONFIG_REG__P2_Select__SHIFT 0xb
1717#define ACP_PGFSM_CONFIG_REG__Wr_MASK 0x1000
1718#define ACP_PGFSM_CONFIG_REG__Wr__SHIFT 0xc
1719#define ACP_PGFSM_CONFIG_REG__Rd_MASK 0x2000
1720#define ACP_PGFSM_CONFIG_REG__Rd__SHIFT 0xd
1721#define ACP_PGFSM_CONFIG_REG__RdData_Reset_MASK 0x4000
1722#define ACP_PGFSM_CONFIG_REG__RdData_Reset__SHIFT 0xe
1723#define ACP_PGFSM_CONFIG_REG__Short_Format_MASK 0x8000
1724#define ACP_PGFSM_CONFIG_REG__Short_Format__SHIFT 0xf
1725#define ACP_PGFSM_CONFIG_REG__BPM_CG_MG_FGCG_MASK 0x3ff0000
1726#define ACP_PGFSM_CONFIG_REG__BPM_CG_MG_FGCG__SHIFT 0x10
1727#define ACP_PGFSM_CONFIG_REG__SRBM_override_MASK 0x4000000
1728#define ACP_PGFSM_CONFIG_REG__SRBM_override__SHIFT 0x1a
1729#define ACP_PGFSM_CONFIG_REG__Rsvd_BPM_Addr_MASK 0x8000000
1730#define ACP_PGFSM_CONFIG_REG__Rsvd_BPM_Addr__SHIFT 0x1b
1731#define ACP_PGFSM_CONFIG_REG__REG_ADDR_MASK 0xf0000000
1732#define ACP_PGFSM_CONFIG_REG__REG_ADDR__SHIFT 0x1c
1733#define ACP_PGFSM_WRITE_REG__Write_value_MASK 0xffffffff
1734#define ACP_PGFSM_WRITE_REG__Write_value__SHIFT 0x0
1735#define ACP_PGFSM_READ_REG_0__Read_value_MASK 0xffffff
1736#define ACP_PGFSM_READ_REG_0__Read_value__SHIFT 0x0
1737#define ACP_PGFSM_READ_REG_1__Read_value_MASK 0xffffff
1738#define ACP_PGFSM_READ_REG_1__Read_value__SHIFT 0x0
1739#define ACP_PGFSM_READ_REG_2__Read_value_MASK 0xffffff
1740#define ACP_PGFSM_READ_REG_2__Read_value__SHIFT 0x0
1741#define ACP_PGFSM_READ_REG_3__Read_value_MASK 0xffffff
1742#define ACP_PGFSM_READ_REG_3__Read_value__SHIFT 0x0
1743#define ACP_PGFSM_READ_REG_4__Read_value_MASK 0xffffff
1744#define ACP_PGFSM_READ_REG_4__Read_value__SHIFT 0x0
1745#define ACP_PGFSM_READ_REG_5__Read_value_MASK 0xffffff
1746#define ACP_PGFSM_READ_REG_5__Read_value__SHIFT 0x0
1747#define ACP_IP_PGFSM_ENABLE__ACP_IP_ACCESS_MASK 0x1
1748#define ACP_IP_PGFSM_ENABLE__ACP_IP_ACCESS__SHIFT 0x0
1749#define ACP_I2S_PIN_CONFIG__ACP_I2S_PIN_CONFIG_MASK 0x3
1750#define ACP_I2S_PIN_CONFIG__ACP_I2S_PIN_CONFIG__SHIFT 0x0
1751#define ACP_AZALIA_I2S_SELECT__AZ_I2S_SELECT_MASK 0x1
1752#define ACP_AZALIA_I2S_SELECT__AZ_I2S_SELECT__SHIFT 0x0
1753#define ACP_CHIP_PKG_FOR_PAD_ISOLATION__external_fch_package_MASK 0x1
1754#define ACP_CHIP_PKG_FOR_PAD_ISOLATION__external_fch_package__SHIFT 0x0
1755#define ACP_AUDIO_PAD_PULLUP_PULLDOWN_CTRL__ACP_AUDIO_PAD_pullup_disable_MASK 0x7ff
1756#define ACP_AUDIO_PAD_PULLUP_PULLDOWN_CTRL__ACP_AUDIO_PAD_pullup_disable__SHIFT 0x0
1757#define ACP_AUDIO_PAD_PULLUP_PULLDOWN_CTRL__ACP_AUDIO_PAD_pulldown_enable_MASK 0x7ff0000
1758#define ACP_AUDIO_PAD_PULLUP_PULLDOWN_CTRL__ACP_AUDIO_PAD_pulldown_enable__SHIFT 0x10
1759#define ACP_BT_UART_PAD_SEL__ACP_BT_UART_PAD_SEL_MASK 0x1
1760#define ACP_BT_UART_PAD_SEL__ACP_BT_UART_PAD_SEL__SHIFT 0x0
1761#define ACP_SCRATCH_REG_0__ACP_SCRATCH_REG_MASK 0xffffffff
1762#define ACP_SCRATCH_REG_0__ACP_SCRATCH_REG__SHIFT 0x0
1763#define ACP_SCRATCH_REG_1__ACP_SCRATCH_REG_MASK 0xffffffff
1764#define ACP_SCRATCH_REG_1__ACP_SCRATCH_REG__SHIFT 0x0
1765#define ACP_SCRATCH_REG_2__ACP_SCRATCH_REG_MASK 0xffffffff
1766#define ACP_SCRATCH_REG_2__ACP_SCRATCH_REG__SHIFT 0x0
1767#define ACP_SCRATCH_REG_3__ACP_SCRATCH_REG_MASK 0xffffffff
1768#define ACP_SCRATCH_REG_3__ACP_SCRATCH_REG__SHIFT 0x0
1769#define ACP_SCRATCH_REG_4__ACP_SCRATCH_REG_MASK 0xffffffff
1770#define ACP_SCRATCH_REG_4__ACP_SCRATCH_REG__SHIFT 0x0
1771#define ACP_SCRATCH_REG_5__ACP_SCRATCH_REG_MASK 0xffffffff
1772#define ACP_SCRATCH_REG_5__ACP_SCRATCH_REG__SHIFT 0x0
1773#define ACP_SCRATCH_REG_6__ACP_SCRATCH_REG_MASK 0xffffffff
1774#define ACP_SCRATCH_REG_6__ACP_SCRATCH_REG__SHIFT 0x0
1775#define ACP_SCRATCH_REG_7__ACP_SCRATCH_REG_MASK 0xffffffff
1776#define ACP_SCRATCH_REG_7__ACP_SCRATCH_REG__SHIFT 0x0
1777#define ACP_SCRATCH_REG_8__ACP_SCRATCH_REG_MASK 0xffffffff
1778#define ACP_SCRATCH_REG_8__ACP_SCRATCH_REG__SHIFT 0x0
1779#define ACP_SCRATCH_REG_9__ACP_SCRATCH_REG_MASK 0xffffffff
1780#define ACP_SCRATCH_REG_9__ACP_SCRATCH_REG__SHIFT 0x0
1781#define ACP_SCRATCH_REG_10__ACP_SCRATCH_REG_MASK 0xffffffff
1782#define ACP_SCRATCH_REG_10__ACP_SCRATCH_REG__SHIFT 0x0
1783#define ACP_SCRATCH_REG_11__ACP_SCRATCH_REG_MASK 0xffffffff
1784#define ACP_SCRATCH_REG_11__ACP_SCRATCH_REG__SHIFT 0x0
1785#define ACP_SCRATCH_REG_12__ACP_SCRATCH_REG_MASK 0xffffffff
1786#define ACP_SCRATCH_REG_12__ACP_SCRATCH_REG__SHIFT 0x0
1787#define ACP_SCRATCH_REG_13__ACP_SCRATCH_REG_MASK 0xffffffff
1788#define ACP_SCRATCH_REG_13__ACP_SCRATCH_REG__SHIFT 0x0
1789#define ACP_SCRATCH_REG_14__ACP_SCRATCH_REG_MASK 0xffffffff
1790#define ACP_SCRATCH_REG_14__ACP_SCRATCH_REG__SHIFT 0x0
1791#define ACP_SCRATCH_REG_15__ACP_SCRATCH_REG_MASK 0xffffffff
1792#define ACP_SCRATCH_REG_15__ACP_SCRATCH_REG__SHIFT 0x0
1793#define ACP_SCRATCH_REG_16__ACP_SCRATCH_REG_MASK 0xffffffff
1794#define ACP_SCRATCH_REG_16__ACP_SCRATCH_REG__SHIFT 0x0
1795#define ACP_SCRATCH_REG_17__ACP_SCRATCH_REG_MASK 0xffffffff
1796#define ACP_SCRATCH_REG_17__ACP_SCRATCH_REG__SHIFT 0x0
1797#define ACP_SCRATCH_REG_18__ACP_SCRATCH_REG_MASK 0xffffffff
1798#define ACP_SCRATCH_REG_18__ACP_SCRATCH_REG__SHIFT 0x0
1799#define ACP_SCRATCH_REG_19__ACP_SCRATCH_REG_MASK 0xffffffff
1800#define ACP_SCRATCH_REG_19__ACP_SCRATCH_REG__SHIFT 0x0
1801#define ACP_SCRATCH_REG_20__ACP_SCRATCH_REG_MASK 0xffffffff
1802#define ACP_SCRATCH_REG_20__ACP_SCRATCH_REG__SHIFT 0x0
1803#define ACP_SCRATCH_REG_21__ACP_SCRATCH_REG_MASK 0xffffffff
1804#define ACP_SCRATCH_REG_21__ACP_SCRATCH_REG__SHIFT 0x0
1805#define ACP_SCRATCH_REG_22__ACP_SCRATCH_REG_MASK 0xffffffff
1806#define ACP_SCRATCH_REG_22__ACP_SCRATCH_REG__SHIFT 0x0
1807#define ACP_SCRATCH_REG_23__ACP_SCRATCH_REG_MASK 0xffffffff
1808#define ACP_SCRATCH_REG_23__ACP_SCRATCH_REG__SHIFT 0x0
1809#define ACP_SCRATCH_REG_24__ACP_SCRATCH_REG_MASK 0xffffffff
1810#define ACP_SCRATCH_REG_24__ACP_SCRATCH_REG__SHIFT 0x0
1811#define ACP_SCRATCH_REG_25__ACP_SCRATCH_REG_MASK 0xffffffff
1812#define ACP_SCRATCH_REG_25__ACP_SCRATCH_REG__SHIFT 0x0
1813#define ACP_SCRATCH_REG_26__ACP_SCRATCH_REG_MASK 0xffffffff
1814#define ACP_SCRATCH_REG_26__ACP_SCRATCH_REG__SHIFT 0x0
1815#define ACP_SCRATCH_REG_27__ACP_SCRATCH_REG_MASK 0xffffffff
1816#define ACP_SCRATCH_REG_27__ACP_SCRATCH_REG__SHIFT 0x0
1817#define ACP_SCRATCH_REG_28__ACP_SCRATCH_REG_MASK 0xffffffff
1818#define ACP_SCRATCH_REG_28__ACP_SCRATCH_REG__SHIFT 0x0
1819#define ACP_SCRATCH_REG_29__ACP_SCRATCH_REG_MASK 0xffffffff
1820#define ACP_SCRATCH_REG_29__ACP_SCRATCH_REG__SHIFT 0x0
1821#define ACP_SCRATCH_REG_30__ACP_SCRATCH_REG_MASK 0xffffffff
1822#define ACP_SCRATCH_REG_30__ACP_SCRATCH_REG__SHIFT 0x0
1823#define ACP_SCRATCH_REG_31__ACP_SCRATCH_REG_MASK 0xffffffff
1824#define ACP_SCRATCH_REG_31__ACP_SCRATCH_REG__SHIFT 0x0
1825#define ACP_SCRATCH_REG_32__ACP_SCRATCH_REG_MASK 0xffffffff
1826#define ACP_SCRATCH_REG_32__ACP_SCRATCH_REG__SHIFT 0x0
1827#define ACP_SCRATCH_REG_33__ACP_SCRATCH_REG_MASK 0xffffffff
1828#define ACP_SCRATCH_REG_33__ACP_SCRATCH_REG__SHIFT 0x0
1829#define ACP_SCRATCH_REG_34__ACP_SCRATCH_REG_MASK 0xffffffff
1830#define ACP_SCRATCH_REG_34__ACP_SCRATCH_REG__SHIFT 0x0
1831#define ACP_SCRATCH_REG_35__ACP_SCRATCH_REG_MASK 0xffffffff
1832#define ACP_SCRATCH_REG_35__ACP_SCRATCH_REG__SHIFT 0x0
1833#define ACP_SCRATCH_REG_36__ACP_SCRATCH_REG_MASK 0xffffffff
1834#define ACP_SCRATCH_REG_36__ACP_SCRATCH_REG__SHIFT 0x0
1835#define ACP_SCRATCH_REG_37__ACP_SCRATCH_REG_MASK 0xffffffff
1836#define ACP_SCRATCH_REG_37__ACP_SCRATCH_REG__SHIFT 0x0
1837#define ACP_SCRATCH_REG_38__ACP_SCRATCH_REG_MASK 0xffffffff
1838#define ACP_SCRATCH_REG_38__ACP_SCRATCH_REG__SHIFT 0x0
1839#define ACP_SCRATCH_REG_39__ACP_SCRATCH_REG_MASK 0xffffffff
1840#define ACP_SCRATCH_REG_39__ACP_SCRATCH_REG__SHIFT 0x0
1841#define ACP_SCRATCH_REG_40__ACP_SCRATCH_REG_MASK 0xffffffff
1842#define ACP_SCRATCH_REG_40__ACP_SCRATCH_REG__SHIFT 0x0
1843#define ACP_SCRATCH_REG_41__ACP_SCRATCH_REG_MASK 0xffffffff
1844#define ACP_SCRATCH_REG_41__ACP_SCRATCH_REG__SHIFT 0x0
1845#define ACP_SCRATCH_REG_42__ACP_SCRATCH_REG_MASK 0xffffffff
1846#define ACP_SCRATCH_REG_42__ACP_SCRATCH_REG__SHIFT 0x0
1847#define ACP_SCRATCH_REG_43__ACP_SCRATCH_REG_MASK 0xffffffff
1848#define ACP_SCRATCH_REG_43__ACP_SCRATCH_REG__SHIFT 0x0
1849#define ACP_SCRATCH_REG_44__ACP_SCRATCH_REG_MASK 0xffffffff
1850#define ACP_SCRATCH_REG_44__ACP_SCRATCH_REG__SHIFT 0x0
1851#define ACP_SCRATCH_REG_45__ACP_SCRATCH_REG_MASK 0xffffffff
1852#define ACP_SCRATCH_REG_45__ACP_SCRATCH_REG__SHIFT 0x0
1853#define ACP_SCRATCH_REG_46__ACP_SCRATCH_REG_MASK 0xffffffff
1854#define ACP_SCRATCH_REG_46__ACP_SCRATCH_REG__SHIFT 0x0
1855#define ACP_SCRATCH_REG_47__ACP_SCRATCH_REG_MASK 0xffffffff
1856#define ACP_SCRATCH_REG_47__ACP_SCRATCH_REG__SHIFT 0x0
1857#define ACP_VOICE_WAKEUP_ENABLE__voice_wakeup_enable_MASK 0x1
1858#define ACP_VOICE_WAKEUP_ENABLE__voice_wakeup_enable__SHIFT 0x0
1859#define ACP_VOICE_WAKEUP_STATUS__voice_wakeup_status_MASK 0x1
1860#define ACP_VOICE_WAKEUP_STATUS__voice_wakeup_status__SHIFT 0x0
1861#define I2S_VOICE_WAKEUP_LOWER_THRESHOLD__i2s_voice_wakeup_lower_threshold_MASK 0xffffffff
1862#define I2S_VOICE_WAKEUP_LOWER_THRESHOLD__i2s_voice_wakeup_lower_threshold__SHIFT 0x0
1863#define I2S_VOICE_WAKEUP_HIGHER_THRESHOLD__i2s_voice_wakeup_higher_threshold_MASK 0xffffffff
1864#define I2S_VOICE_WAKEUP_HIGHER_THRESHOLD__i2s_voice_wakeup_higher_threshold__SHIFT 0x0
1865#define I2S_VOICE_WAKEUP_NO_OF_SAMPLES__i2s_voice_wakeup_no_of_samples_MASK 0xffff
1866#define I2S_VOICE_WAKEUP_NO_OF_SAMPLES__i2s_voice_wakeup_no_of_samples__SHIFT 0x0
1867#define I2S_VOICE_WAKEUP_NO_OF_PEAKS__i2s_voice_wakeup_no_of_peaks_MASK 0xffff
1868#define I2S_VOICE_WAKEUP_NO_OF_PEAKS__i2s_voice_wakeup_no_of_peaks__SHIFT 0x0
1869#define I2S_VOICE_WAKEUP_DURATION_OF_N_PEAKS__i2s_voice_wakeup_duration_of_n_peaks_MASK 0xffffffff
1870#define I2S_VOICE_WAKEUP_DURATION_OF_N_PEAKS__i2s_voice_wakeup_duration_of_n_peaks__SHIFT 0x0
1871#define I2S_VOICE_WAKEUP_BITCLK_TOGGLE_DETECTION__i2s_voice_wakeup_bitclk_toggle_wakeup_en_MASK 0x1
1872#define I2S_VOICE_WAKEUP_BITCLK_TOGGLE_DETECTION__i2s_voice_wakeup_bitclk_toggle_wakeup_en__SHIFT 0x0
1873#define I2S_VOICE_WAKEUP_DATA_PATH_SWITCH__i2s_voice_wakeup_data_path_switch_req_MASK 0x1
1874#define I2S_VOICE_WAKEUP_DATA_PATH_SWITCH__i2s_voice_wakeup_data_path_switch_req__SHIFT 0x0
1875#define I2S_VOICE_WAKEUP_DATA_PATH_SWITCH__i2s_voice_wakeup_data_path_switch_ack_MASK 0x2
1876#define I2S_VOICE_WAKEUP_DATA_PATH_SWITCH__i2s_voice_wakeup_data_path_switch_ack__SHIFT 0x1
1877#define I2S_VOICE_WAKEUP_DATA_POINTER__i2s_voice_wakeup_data_pointer_MASK 0xffffffff
1878#define I2S_VOICE_WAKEUP_DATA_POINTER__i2s_voice_wakeup_data_pointer__SHIFT 0x0
1879#define I2S_VOICE_WAKEUP_AUTH_MATCH__i2s_voice_wakeup_authentication_valid_MASK 0x1
1880#define I2S_VOICE_WAKEUP_AUTH_MATCH__i2s_voice_wakeup_authentication_valid__SHIFT 0x0
1881#define I2S_VOICE_WAKEUP_AUTH_MATCH__i2s_voice_wakeup_authentication_match_MASK 0x2
1882#define I2S_VOICE_WAKEUP_AUTH_MATCH__i2s_voice_wakeup_authentication_match__SHIFT 0x1
1883#define I2S_VOICE_WAKEUP_8KB_WRAP__i2s_voice_wakeup_8kb_wrap_MASK 0x1
1884#define I2S_VOICE_WAKEUP_8KB_WRAP__i2s_voice_wakeup_8kb_wrap__SHIFT 0x0
1885#define ACP_I2S_RECEIVED_BYTE_CNT_HIGH__i2s_mic_rx_byte_cnt_high_MASK 0xffffffff
1886#define ACP_I2S_RECEIVED_BYTE_CNT_HIGH__i2s_mic_rx_byte_cnt_high__SHIFT 0x0
1887#define ACP_I2S_RECEIVED_BYTE_CNT_LOW__i2s_mic_rx_byte_cnt_low_MASK 0xffffffff
1888#define ACP_I2S_RECEIVED_BYTE_CNT_LOW__i2s_mic_rx_byte_cnt_low__SHIFT 0x0
1889#define ACP_I2S_MICSP_TRANSMIT_BYTE_CNT_HIGH__i2s_micsp_tx_byte_cnt_high_MASK 0xffffffff
1890#define ACP_I2S_MICSP_TRANSMIT_BYTE_CNT_HIGH__i2s_micsp_tx_byte_cnt_high__SHIFT 0x0
1891#define ACP_I2S_MICSP_TRANSMIT_BYTE_CNT_LOW__i2s_micsp_tx_byte_cnt_low_MASK 0xffffffff
1892#define ACP_I2S_MICSP_TRANSMIT_BYTE_CNT_LOW__i2s_micsp_tx_byte_cnt_low__SHIFT 0x0
1893#define ACP_MEM_SHUT_DOWN_REQ_LO__ACP_ShutDownReq_RAML_MASK 0xffffffff
1894#define ACP_MEM_SHUT_DOWN_REQ_LO__ACP_ShutDownReq_RAML__SHIFT 0x0
1895#define ACP_MEM_SHUT_DOWN_REQ_HI__ACP_ShutDownReq_RAMH_MASK 0xffff
1896#define ACP_MEM_SHUT_DOWN_REQ_HI__ACP_ShutDownReq_RAMH__SHIFT 0x0
1897#define ACP_MEM_SHUT_DOWN_STS_LO__ACP_ShutDownSts_RAML_MASK 0xffffffff
1898#define ACP_MEM_SHUT_DOWN_STS_LO__ACP_ShutDownSts_RAML__SHIFT 0x0
1899#define ACP_MEM_SHUT_DOWN_STS_HI__ACP_ShutDownSts_RAMH_MASK 0xffff
1900#define ACP_MEM_SHUT_DOWN_STS_HI__ACP_ShutDownSts_RAMH__SHIFT 0x0
1901#define ACP_MEM_DEEP_SLEEP_REQ_LO__ACP_DeepSleepReq_RAML_MASK 0xffffffff
1902#define ACP_MEM_DEEP_SLEEP_REQ_LO__ACP_DeepSleepReq_RAML__SHIFT 0x0
1903#define ACP_MEM_DEEP_SLEEP_REQ_HI__ACP_DeepSleepReq_RAMH_MASK 0xffff
1904#define ACP_MEM_DEEP_SLEEP_REQ_HI__ACP_DeepSleepReq_RAMH__SHIFT 0x0
1905#define ACP_MEM_DEEP_SLEEP_STS_LO__ACP_DeepSleepSts_RAML_MASK 0xffffffff
1906#define ACP_MEM_DEEP_SLEEP_STS_LO__ACP_DeepSleepSts_RAML__SHIFT 0x0
1907#define ACP_MEM_DEEP_SLEEP_STS_HI__ACP_DeepSleepSts_RAMH_MASK 0xffff
1908#define ACP_MEM_DEEP_SLEEP_STS_HI__ACP_DeepSleepSts_RAMH__SHIFT 0x0
1909#define ACP_MEM_WAKEUP_FROM_SHUT_DOWN_LO__acp_mem_wakeup_from_shut_down_lo_MASK 0xffffffff
1910#define ACP_MEM_WAKEUP_FROM_SHUT_DOWN_LO__acp_mem_wakeup_from_shut_down_lo__SHIFT 0x0
1911#define ACP_MEM_WAKEUP_FROM_SHUT_DOWN_HI__acp_mem_wakeup_from_shut_down_hi_MASK 0xffff
1912#define ACP_MEM_WAKEUP_FROM_SHUT_DOWN_HI__acp_mem_wakeup_from_shut_down_hi__SHIFT 0x0
1913#define ACP_MEM_WAKEUP_FROM_SLEEP_LO__acp_mem_wakeup_from_sleep_lo_MASK 0xffffffff
1914#define ACP_MEM_WAKEUP_FROM_SLEEP_LO__acp_mem_wakeup_from_sleep_lo__SHIFT 0x0
1915#define ACP_MEM_WAKEUP_FROM_SLEEP_HI__acp_mem_wakeup_from_sleep_hi_MASK 0xffff
1916#define ACP_MEM_WAKEUP_FROM_SLEEP_HI__acp_mem_wakeup_from_sleep_hi__SHIFT 0x0
1917#define ACP_I2SSP_IER__I2SSP_IEN_MASK 0x1
1918#define ACP_I2SSP_IER__I2SSP_IEN__SHIFT 0x0
1919#define ACP_I2SSP_IRER__I2SSP_RXEN_MASK 0x1
1920#define ACP_I2SSP_IRER__I2SSP_RXEN__SHIFT 0x0
1921#define ACP_I2SSP_ITER__I2SSP_TXEN_MASK 0x1
1922#define ACP_I2SSP_ITER__I2SSP_TXEN__SHIFT 0x0
1923#define ACP_I2SSP_CER__I2SSP_CLKEN_MASK 0x1
1924#define ACP_I2SSP_CER__I2SSP_CLKEN__SHIFT 0x0
1925#define ACP_I2SSP_CCR__I2SSP_SCLKG_MASK 0x7
1926#define ACP_I2SSP_CCR__I2SSP_SCLKG__SHIFT 0x0
1927#define ACP_I2SSP_CCR__I2SSP_WSS_MASK 0x18
1928#define ACP_I2SSP_CCR__I2SSP_WSS__SHIFT 0x3
1929#define ACP_I2SSP_RXFFR__I2SSP_RXFFR_MASK 0x1
1930#define ACP_I2SSP_RXFFR__I2SSP_RXFFR__SHIFT 0x0
1931#define ACP_I2SSP_TXFFR__I2SSP_TXFFR_MASK 0x1
1932#define ACP_I2SSP_TXFFR__I2SSP_TXFFR__SHIFT 0x0
1933#define ACP_I2SSP_LRBR0__I2SSP_LRBR0_MASK 0xffffffff
1934#define ACP_I2SSP_LRBR0__I2SSP_LRBR0__SHIFT 0x0
1935#define ACP_I2SSP_RRBR0__I2SSP_RRBR0_MASK 0xffffffff
1936#define ACP_I2SSP_RRBR0__I2SSP_RRBR0__SHIFT 0x0
1937#define ACP_I2SSP_RER0__I2SSP_RXCHEN0_MASK 0x1
1938#define ACP_I2SSP_RER0__I2SSP_RXCHEN0__SHIFT 0x0
1939#define ACP_I2SSP_TER0__I2SSP_TXCHEN0_MASK 0x1
1940#define ACP_I2SSP_TER0__I2SSP_TXCHEN0__SHIFT 0x0
1941#define ACP_I2SSP_RCR0__I2SSP_WLEN_MASK 0x7
1942#define ACP_I2SSP_RCR0__I2SSP_WLEN__SHIFT 0x0
1943#define ACP_I2SSP_TCR0__I2SSP_WLEN_MASK 0x7
1944#define ACP_I2SSP_TCR0__I2SSP_WLEN__SHIFT 0x0
1945#define ACP_I2SSP_ISR0__I2SSP_RXDA_MASK 0x1
1946#define ACP_I2SSP_ISR0__I2SSP_RXDA__SHIFT 0x0
1947#define ACP_I2SSP_ISR0__I2SSP_RXFO_MASK 0x2
1948#define ACP_I2SSP_ISR0__I2SSP_RXFO__SHIFT 0x1
1949#define ACP_I2SSP_ISR0__I2SSP_TXFE_MASK 0x10
1950#define ACP_I2SSP_ISR0__I2SSP_TXFE__SHIFT 0x4
1951#define ACP_I2SSP_ISR0__I2SSP_TXFO_MASK 0x20
1952#define ACP_I2SSP_ISR0__I2SSP_TXFO__SHIFT 0x5
1953#define ACP_I2SSP_IMR0__I2SSP_RXDAM_MASK 0x1
1954#define ACP_I2SSP_IMR0__I2SSP_RXDAM__SHIFT 0x0
1955#define ACP_I2SSP_IMR0__I2SSP_RXFOM_MASK 0x2
1956#define ACP_I2SSP_IMR0__I2SSP_RXFOM__SHIFT 0x1
1957#define ACP_I2SSP_IMR0__I2SSP_TXFEM_MASK 0x10
1958#define ACP_I2SSP_IMR0__I2SSP_TXFEM__SHIFT 0x4
1959#define ACP_I2SSP_IMR0__I2SSP_TXFOM_MASK 0x20
1960#define ACP_I2SSP_IMR0__I2SSP_TXFOM__SHIFT 0x5
1961#define ACP_I2SSP_ROR0__I2SSP_RXCHO_MASK 0x1
1962#define ACP_I2SSP_ROR0__I2SSP_RXCHO__SHIFT 0x0
1963#define ACP_I2SSP_TOR0__I2SSP_TXCHO_MASK 0x1
1964#define ACP_I2SSP_TOR0__I2SSP_TXCHO__SHIFT 0x0
1965#define ACP_I2SSP_RFCR0__I2SSP_RXCHDT_MASK 0xf
1966#define ACP_I2SSP_RFCR0__I2SSP_RXCHDT__SHIFT 0x0
1967#define ACP_I2SSP_TFCR0__I2SSP_TXCHET_MASK 0xf
1968#define ACP_I2SSP_TFCR0__I2SSP_TXCHET__SHIFT 0x0
1969#define ACP_I2SSP_RFF0__I2SSP_RXCHFR_MASK 0x1
1970#define ACP_I2SSP_RFF0__I2SSP_RXCHFR__SHIFT 0x0
1971#define ACP_I2SSP_TFF0__I2SSP_TXCHFR_MASK 0x1
1972#define ACP_I2SSP_TFF0__I2SSP_TXCHFR__SHIFT 0x0
1973#define ACP_I2SSP_RXDMA__I2SSP_RXDMA_MASK 0xffffffff
1974#define ACP_I2SSP_RXDMA__I2SSP_RXDMA__SHIFT 0x0
1975#define ACP_I2SSP_RRXDMA__I2SSP_RRXDMA_MASK 0x1
1976#define ACP_I2SSP_RRXDMA__I2SSP_RRXDMA__SHIFT 0x0
1977#define ACP_I2SSP_TXDMA__I2SSP_TXDMA_MASK 0xffffffff
1978#define ACP_I2SSP_TXDMA__I2SSP_TXDMA__SHIFT 0x0
1979#define ACP_I2SSP_RTXDMA__I2SSP_RTXDMA_MASK 0x1
1980#define ACP_I2SSP_RTXDMA__I2SSP_RTXDMA__SHIFT 0x0
1981#define ACP_I2SSP_COMP_PARAM_2__I2SSP_RX_WPRDSIZE_0_MASK 0x7
1982#define ACP_I2SSP_COMP_PARAM_2__I2SSP_RX_WPRDSIZE_0__SHIFT 0x0
1983#define ACP_I2SSP_COMP_PARAM_2__I2SSP_RX_WPRDSIZE_1_MASK 0x38
1984#define ACP_I2SSP_COMP_PARAM_2__I2SSP_RX_WPRDSIZE_1__SHIFT 0x3
1985#define ACP_I2SSP_COMP_PARAM_2__I2SSP_RX_WPRDSIZE_2_MASK 0x380
1986#define ACP_I2SSP_COMP_PARAM_2__I2SSP_RX_WPRDSIZE_2__SHIFT 0x7
1987#define ACP_I2SSP_COMP_PARAM_2__I2SSP_RX_WPRDSIZE_3_MASK 0x1c00
1988#define ACP_I2SSP_COMP_PARAM_2__I2SSP_RX_WPRDSIZE_3__SHIFT 0xa
1989#define ACP_I2SSP_COMP_PARAM_1__I2SSP_APB_DATA_WIDTH_MASK 0x3
1990#define ACP_I2SSP_COMP_PARAM_1__I2SSP_APB_DATA_WIDTH__SHIFT 0x0
1991#define ACP_I2SSP_COMP_PARAM_1__I2SSP_FIFO_DEPTH_GLOBAL_MASK 0xc
1992#define ACP_I2SSP_COMP_PARAM_1__I2SSP_FIFO_DEPTH_GLOBAL__SHIFT 0x2
1993#define ACP_I2SSP_COMP_PARAM_1__I2SSP_MODE_EN_MASK 0x10
1994#define ACP_I2SSP_COMP_PARAM_1__I2SSP_MODE_EN__SHIFT 0x4
1995#define ACP_I2SSP_COMP_PARAM_1__I2SSP_TRANSMITTER_BLOCK_MASK 0x20
1996#define ACP_I2SSP_COMP_PARAM_1__I2SSP_TRANSMITTER_BLOCK__SHIFT 0x5
1997#define ACP_I2SSP_COMP_PARAM_1__I2SSP_RECEIVER_BLOCK_MASK 0x40
1998#define ACP_I2SSP_COMP_PARAM_1__I2SSP_RECEIVER_BLOCK__SHIFT 0x6
1999#define ACP_I2SSP_COMP_PARAM_1__I2SSP_RX_CHANNLES_MASK 0x180
2000#define ACP_I2SSP_COMP_PARAM_1__I2SSP_RX_CHANNLES__SHIFT 0x7
2001#define ACP_I2SSP_COMP_PARAM_1__I2SSP_TX_CHANNLES_MASK 0x600
2002#define ACP_I2SSP_COMP_PARAM_1__I2SSP_TX_CHANNLES__SHIFT 0x9
2003#define ACP_I2SSP_COMP_PARAM_1__I2SSP_TX_WORDSIZE_0_MASK 0x70000
2004#define ACP_I2SSP_COMP_PARAM_1__I2SSP_TX_WORDSIZE_0__SHIFT 0x10
2005#define ACP_I2SSP_COMP_PARAM_1__I2SSP_TX_WORDSIZE_1_MASK 0x380000
2006#define ACP_I2SSP_COMP_PARAM_1__I2SSP_TX_WORDSIZE_1__SHIFT 0x13
2007#define ACP_I2SSP_COMP_PARAM_1__I2SSP_TX_WORDSIZE_2_MASK 0x1c00000
2008#define ACP_I2SSP_COMP_PARAM_1__I2SSP_TX_WORDSIZE_2__SHIFT 0x16
2009#define ACP_I2SSP_COMP_PARAM_1__I2SSP_TX_WORDSIZE_3_MASK 0xe000000
2010#define ACP_I2SSP_COMP_PARAM_1__I2SSP_TX_WORDSIZE_3__SHIFT 0x19
2011#define ACP_I2SSP_COMP_VERSION__I2SSP_APB_DATA_WIDTH_MASK 0xffffffff
2012#define ACP_I2SSP_COMP_VERSION__I2SSP_APB_DATA_WIDTH__SHIFT 0x0
2013#define ACP_I2SSP_COMP_TYPE__I2SSP_COMP_TYPE_MASK 0xffffffff
2014#define ACP_I2SSP_COMP_TYPE__I2SSP_COMP_TYPE__SHIFT 0x0
2015#define ACP_I2SMICSP_IER__I2SMICSP_IEN_MASK 0x1
2016#define ACP_I2SMICSP_IER__I2SMICSP_IEN__SHIFT 0x0
2017#define ACP_I2SMICSP_IRER__I2SMICSP_RXEN_MASK 0x1
2018#define ACP_I2SMICSP_IRER__I2SMICSP_RXEN__SHIFT 0x0
2019#define ACP_I2SMICSP_ITER__I2SMICSP_TXEN_MASK 0x1
2020#define ACP_I2SMICSP_ITER__I2SMICSP_TXEN__SHIFT 0x0
2021#define ACP_I2SMICSP_CER__I2SMICSP_CLKEN_MASK 0x1
2022#define ACP_I2SMICSP_CER__I2SMICSP_CLKEN__SHIFT 0x0
2023#define ACP_I2SMICSP_CCR__I2SMICSP_SCLKG_MASK 0x7
2024#define ACP_I2SMICSP_CCR__I2SMICSP_SCLKG__SHIFT 0x0
2025#define ACP_I2SMICSP_CCR__I2SMICSP_WSS_MASK 0x18
2026#define ACP_I2SMICSP_CCR__I2SMICSP_WSS__SHIFT 0x3
2027#define ACP_I2SMICSP_RXFFR__I2SMICSP_RXFFR_MASK 0x1
2028#define ACP_I2SMICSP_RXFFR__I2SMICSP_RXFFR__SHIFT 0x0
2029#define ACP_I2SMICSP_TXFFR__I2SMICSP_TXFFR_MASK 0x1
2030#define ACP_I2SMICSP_TXFFR__I2SMICSP_TXFFR__SHIFT 0x0
2031#define ACP_I2SMICSP_LRBR0__I2SMICSP_LRBR0_MASK 0xffffffff
2032#define ACP_I2SMICSP_LRBR0__I2SMICSP_LRBR0__SHIFT 0x0
2033#define ACP_I2SMICSP_RRBR0__I2SMICSP_RRBR0_MASK 0xffffffff
2034#define ACP_I2SMICSP_RRBR0__I2SMICSP_RRBR0__SHIFT 0x0
2035#define ACP_I2SMICSP_RER0__I2SMICSP_RXCHEN0_MASK 0x1
2036#define ACP_I2SMICSP_RER0__I2SMICSP_RXCHEN0__SHIFT 0x0
2037#define ACP_I2SMICSP_TER0__I2SMICSP_TXCHEN0_MASK 0x1
2038#define ACP_I2SMICSP_TER0__I2SMICSP_TXCHEN0__SHIFT 0x0
2039#define ACP_I2SMICSP_RCR0__I2SMICSP_WLEN_MASK 0x7
2040#define ACP_I2SMICSP_RCR0__I2SMICSP_WLEN__SHIFT 0x0
2041#define ACP_I2SMICSP_TCR0__I2SMICSP_WLEN_MASK 0x7
2042#define ACP_I2SMICSP_TCR0__I2SMICSP_WLEN__SHIFT 0x0
2043#define ACP_I2SMICSP_ISR0__I2SMICSP_RXDA_MASK 0x1
2044#define ACP_I2SMICSP_ISR0__I2SMICSP_RXDA__SHIFT 0x0
2045#define ACP_I2SMICSP_ISR0__I2SMICSP_RXFO_MASK 0x2
2046#define ACP_I2SMICSP_ISR0__I2SMICSP_RXFO__SHIFT 0x1
2047#define ACP_I2SMICSP_ISR0__I2SMICSP_TXFE_MASK 0x10
2048#define ACP_I2SMICSP_ISR0__I2SMICSP_TXFE__SHIFT 0x4
2049#define ACP_I2SMICSP_ISR0__I2SMICSP_TXFO_MASK 0x20
2050#define ACP_I2SMICSP_ISR0__I2SMICSP_TXFO__SHIFT 0x5
2051#define ACP_I2SMICSP_IMR0__I2SMICSP_RXDAM_MASK 0x1
2052#define ACP_I2SMICSP_IMR0__I2SMICSP_RXDAM__SHIFT 0x0
2053#define ACP_I2SMICSP_IMR0__I2SMICSP_RXFOM_MASK 0x2
2054#define ACP_I2SMICSP_IMR0__I2SMICSP_RXFOM__SHIFT 0x1
2055#define ACP_I2SMICSP_IMR0__I2SMICSP_TXFEM_MASK 0x10
2056#define ACP_I2SMICSP_IMR0__I2SMICSP_TXFEM__SHIFT 0x4
2057#define ACP_I2SMICSP_IMR0__I2SMICSP_TXFOM_MASK 0x20
2058#define ACP_I2SMICSP_IMR0__I2SMICSP_TXFOM__SHIFT 0x5
2059#define ACP_I2SMICSP_ROR0__I2SMICSP_RXCHO_MASK 0x1
2060#define ACP_I2SMICSP_ROR0__I2SMICSP_RXCHO__SHIFT 0x0
2061#define ACP_I2SMICSP_TOR0__I2SMICSP_TXCHO_MASK 0x1
2062#define ACP_I2SMICSP_TOR0__I2SMICSP_TXCHO__SHIFT 0x0
2063#define ACP_I2SMICSP_RFCR0__I2SMICSP_RXCHDT_MASK 0xf
2064#define ACP_I2SMICSP_RFCR0__I2SMICSP_RXCHDT__SHIFT 0x0
2065#define ACP_I2SMICSP_TFCR0__I2SMICSP_TXCHET_MASK 0xf
2066#define ACP_I2SMICSP_TFCR0__I2SMICSP_TXCHET__SHIFT 0x0
2067#define ACP_I2SMICSP_RFF0__I2SMICSP_RXCHFR_MASK 0x1
2068#define ACP_I2SMICSP_RFF0__I2SMICSP_RXCHFR__SHIFT 0x0
2069#define ACP_I2SMICSP_TFF0__I2SMICSP_TXCHFR_MASK 0x1
2070#define ACP_I2SMICSP_TFF0__I2SMICSP_TXCHFR__SHIFT 0x0
2071#define ACP_I2SMICSP_LRBR1__I2SMICSP_LRBR1_MASK 0xffffffff
2072#define ACP_I2SMICSP_LRBR1__I2SMICSP_LRBR1__SHIFT 0x0
2073#define ACP_I2SMICSP_RRBR1__I2SMICSP_RRBR1_MASK 0xffffffff
2074#define ACP_I2SMICSP_RRBR1__I2SMICSP_RRBR1__SHIFT 0x0
2075#define ACP_I2SMICSP_RER1__I2SMICSP_RXCHEN1_MASK 0x1
2076#define ACP_I2SMICSP_RER1__I2SMICSP_RXCHEN1__SHIFT 0x0
2077#define ACP_I2SMICSP_TER1__I2SMICSP_TXCHEN1_MASK 0x1
2078#define ACP_I2SMICSP_TER1__I2SMICSP_TXCHEN1__SHIFT 0x0
2079#define ACP_I2SMICSP_RCR1__I2SMICSP_WLEN_MASK 0x7
2080#define ACP_I2SMICSP_RCR1__I2SMICSP_WLEN__SHIFT 0x0
2081#define ACP_I2SMICSP_TCR1__I2SMICSP_WLEN_MASK 0x7
2082#define ACP_I2SMICSP_TCR1__I2SMICSP_WLEN__SHIFT 0x0
2083#define ACP_I2SMICSP_ISR1__I2SMICSP_RXDA_MASK 0x1
2084#define ACP_I2SMICSP_ISR1__I2SMICSP_RXDA__SHIFT 0x0
2085#define ACP_I2SMICSP_ISR1__I2SMICSP_RXFO_MASK 0x2
2086#define ACP_I2SMICSP_ISR1__I2SMICSP_RXFO__SHIFT 0x1
2087#define ACP_I2SMICSP_ISR1__I2SMICSP_TXFE_MASK 0x10
2088#define ACP_I2SMICSP_ISR1__I2SMICSP_TXFE__SHIFT 0x4
2089#define ACP_I2SMICSP_ISR1__I2SMICSP_TXFO_MASK 0x20
2090#define ACP_I2SMICSP_ISR1__I2SMICSP_TXFO__SHIFT 0x5
2091#define ACP_I2SMICSP_IMR1__I2SMICSP_RXDAM_MASK 0x1
2092#define ACP_I2SMICSP_IMR1__I2SMICSP_RXDAM__SHIFT 0x0
2093#define ACP_I2SMICSP_IMR1__I2SMICSP_RXFOM_MASK 0x2
2094#define ACP_I2SMICSP_IMR1__I2SMICSP_RXFOM__SHIFT 0x1
2095#define ACP_I2SMICSP_IMR1__I2SMICSP_TXFEM_MASK 0x10
2096#define ACP_I2SMICSP_IMR1__I2SMICSP_TXFEM__SHIFT 0x4
2097#define ACP_I2SMICSP_IMR1__I2SMICSP_TXFOM_MASK 0x20
2098#define ACP_I2SMICSP_IMR1__I2SMICSP_TXFOM__SHIFT 0x5
2099#define ACP_I2SMICSP_ROR1__I2SMICSP_RXCHO_MASK 0x1
2100#define ACP_I2SMICSP_ROR1__I2SMICSP_RXCHO__SHIFT 0x0
2101#define ACP_I2SMICSP_TOR1__I2SMICSP_TXCHO_MASK 0x1
2102#define ACP_I2SMICSP_TOR1__I2SMICSP_TXCHO__SHIFT 0x0
2103#define ACP_I2SMICSP_RFCR1__I2SMICSP_RXCHDT_MASK 0xf
2104#define ACP_I2SMICSP_RFCR1__I2SMICSP_RXCHDT__SHIFT 0x0
2105#define ACP_I2SMICSP_TFCR1__I2SMICSP_TXCHET_MASK 0xf
2106#define ACP_I2SMICSP_TFCR1__I2SMICSP_TXCHET__SHIFT 0x0
2107#define ACP_I2SMICSP_RFF1__I2SMICSP_RXCHFR_MASK 0x1
2108#define ACP_I2SMICSP_RFF1__I2SMICSP_RXCHFR__SHIFT 0x0
2109#define ACP_I2SMICSP_TFF1__I2SMICSP_TXCHFR_MASK 0x1
2110#define ACP_I2SMICSP_TFF1__I2SMICSP_TXCHFR__SHIFT 0x0
2111#define ACP_I2SMICSP_RXDMA__I2SMICSP_RXDMA_MASK 0xffffffff
2112#define ACP_I2SMICSP_RXDMA__I2SMICSP_RXDMA__SHIFT 0x0
2113#define ACP_I2SMICSP_RRXDMA__I2SMICSP_RRXDMA_MASK 0x1
2114#define ACP_I2SMICSP_RRXDMA__I2SMICSP_RRXDMA__SHIFT 0x0
2115#define ACP_I2SMICSP_TXDMA__I2SMICSP_TXDMA_MASK 0xffffffff
2116#define ACP_I2SMICSP_TXDMA__I2SMICSP_TXDMA__SHIFT 0x0
2117#define ACP_I2SMICSP_RTXDMA__I2SMICSP_RTXDMA_MASK 0x1
2118#define ACP_I2SMICSP_RTXDMA__I2SMICSP_RTXDMA__SHIFT 0x0
2119#define ACP_I2SMICSP_COMP_PARAM_2__I2SMICSP_RX_WPRDSIZE_0_MASK 0x7
2120#define ACP_I2SMICSP_COMP_PARAM_2__I2SMICSP_RX_WPRDSIZE_0__SHIFT 0x0
2121#define ACP_I2SMICSP_COMP_PARAM_2__I2SMICSP_RX_WPRDSIZE_1_MASK 0x38
2122#define ACP_I2SMICSP_COMP_PARAM_2__I2SMICSP_RX_WPRDSIZE_1__SHIFT 0x3
2123#define ACP_I2SMICSP_COMP_PARAM_2__I2SMICSP_RX_WPRDSIZE_2_MASK 0x380
2124#define ACP_I2SMICSP_COMP_PARAM_2__I2SMICSP_RX_WPRDSIZE_2__SHIFT 0x7
2125#define ACP_I2SMICSP_COMP_PARAM_2__I2SMICSP_RX_WPRDSIZE_3_MASK 0x1c00
2126#define ACP_I2SMICSP_COMP_PARAM_2__I2SMICSP_RX_WPRDSIZE_3__SHIFT 0xa
2127#define ACP_I2SMICSP_COMP_PARAM_1__I2SMICSP_APB_DATA_WIDTH_MASK 0x3
2128#define ACP_I2SMICSP_COMP_PARAM_1__I2SMICSP_APB_DATA_WIDTH__SHIFT 0x0
2129#define ACP_I2SMICSP_COMP_PARAM_1__I2SMICSP_FIFO_DEPTH_GLOBAL_MASK 0xc
2130#define ACP_I2SMICSP_COMP_PARAM_1__I2SMICSP_FIFO_DEPTH_GLOBAL__SHIFT 0x2
2131#define ACP_I2SMICSP_COMP_PARAM_1__I2SMICSP_MODE_EN_MASK 0x10
2132#define ACP_I2SMICSP_COMP_PARAM_1__I2SMICSP_MODE_EN__SHIFT 0x4
2133#define ACP_I2SMICSP_COMP_PARAM_1__I2SMICSP_TRANSMITTER_BLOCK_MASK 0x20
2134#define ACP_I2SMICSP_COMP_PARAM_1__I2SMICSP_TRANSMITTER_BLOCK__SHIFT 0x5
2135#define ACP_I2SMICSP_COMP_PARAM_1__I2SMICSP_RECEIVER_BLOCK_MASK 0x40
2136#define ACP_I2SMICSP_COMP_PARAM_1__I2SMICSP_RECEIVER_BLOCK__SHIFT 0x6
2137#define ACP_I2SMICSP_COMP_PARAM_1__I2SMICSP_RX_CHANNLES_MASK 0x180
2138#define ACP_I2SMICSP_COMP_PARAM_1__I2SMICSP_RX_CHANNLES__SHIFT 0x7
2139#define ACP_I2SMICSP_COMP_PARAM_1__I2SMICSP_TX_CHANNLES_MASK 0x600
2140#define ACP_I2SMICSP_COMP_PARAM_1__I2SMICSP_TX_CHANNLES__SHIFT 0x9
2141#define ACP_I2SMICSP_COMP_PARAM_1__I2SMICSP_TX_WORDSIZE_0_MASK 0x70000
2142#define ACP_I2SMICSP_COMP_PARAM_1__I2SMICSP_TX_WORDSIZE_0__SHIFT 0x10
2143#define ACP_I2SMICSP_COMP_PARAM_1__I2SMICSP_TX_WORDSIZE_1_MASK 0x380000
2144#define ACP_I2SMICSP_COMP_PARAM_1__I2SMICSP_TX_WORDSIZE_1__SHIFT 0x13
2145#define ACP_I2SMICSP_COMP_PARAM_1__I2SMICSP_TX_WORDSIZE_2_MASK 0x1c00000
2146#define ACP_I2SMICSP_COMP_PARAM_1__I2SMICSP_TX_WORDSIZE_2__SHIFT 0x16
2147#define ACP_I2SMICSP_COMP_PARAM_1__I2SMICSP_TX_WORDSIZE_3_MASK 0xe000000
2148#define ACP_I2SMICSP_COMP_PARAM_1__I2SMICSP_TX_WORDSIZE_3__SHIFT 0x19
2149#define ACP_I2SMICSP_COMP_VERSION__I2SMICSP_APB_DATA_WIDTH_MASK 0xffffffff
2150#define ACP_I2SMICSP_COMP_VERSION__I2SMICSP_APB_DATA_WIDTH__SHIFT 0x0
2151#define ACP_I2SMICSP_COMP_TYPE__I2SMICSP_COMP_TYPE_MASK 0xffffffff
2152#define ACP_I2SMICSP_COMP_TYPE__I2SMICSP_COMP_TYPE__SHIFT 0x0
2153#define ACP_I2SBT_IER__I2SBT_IEN_MASK 0x1
2154#define ACP_I2SBT_IER__I2SBT_IEN__SHIFT 0x0
2155#define ACP_I2SBT_IRER__I2SBT_RXEN_MASK 0x1
2156#define ACP_I2SBT_IRER__I2SBT_RXEN__SHIFT 0x0
2157#define ACP_I2SBT_ITER__I2SBT_TXEN_MASK 0x1
2158#define ACP_I2SBT_ITER__I2SBT_TXEN__SHIFT 0x0
2159#define ACP_I2SBT_CER__I2SBT_CLKEN_MASK 0x1
2160#define ACP_I2SBT_CER__I2SBT_CLKEN__SHIFT 0x0
2161#define ACP_I2SBT_CCR__I2SBT_SCLKG_MASK 0x7
2162#define ACP_I2SBT_CCR__I2SBT_SCLKG__SHIFT 0x0
2163#define ACP_I2SBT_CCR__I2SBT_WSS_MASK 0x18
2164#define ACP_I2SBT_CCR__I2SBT_WSS__SHIFT 0x3
2165#define ACP_I2SBT_RXFFR__I2SBT_RXFFR_MASK 0x1
2166#define ACP_I2SBT_RXFFR__I2SBT_RXFFR__SHIFT 0x0
2167#define ACP_I2SBT_TXFFR__I2SBT_TXFFR_MASK 0x1
2168#define ACP_I2SBT_TXFFR__I2SBT_TXFFR__SHIFT 0x0
2169#define ACP_I2SBT_LRBR0__I2SBT_LRBR0_MASK 0xffffffff
2170#define ACP_I2SBT_LRBR0__I2SBT_LRBR0__SHIFT 0x0
2171#define ACP_I2SBT_RRBR0__I2SBT_RRBR0_MASK 0xffffffff
2172#define ACP_I2SBT_RRBR0__I2SBT_RRBR0__SHIFT 0x0
2173#define ACP_I2SBT_RER0__I2SBT_RXCHEN0_MASK 0x1
2174#define ACP_I2SBT_RER0__I2SBT_RXCHEN0__SHIFT 0x0
2175#define ACP_I2SBT_TER0__I2SBT_TXCHEN0_MASK 0x1
2176#define ACP_I2SBT_TER0__I2SBT_TXCHEN0__SHIFT 0x0
2177#define ACP_I2SBT_RCR0__I2SBT_WLEN_MASK 0x7
2178#define ACP_I2SBT_RCR0__I2SBT_WLEN__SHIFT 0x0
2179#define ACP_I2SBT_TCR0__I2SBT_WLEN_MASK 0x7
2180#define ACP_I2SBT_TCR0__I2SBT_WLEN__SHIFT 0x0
2181#define ACP_I2SBT_ISR0__I2SBT_RXDA_MASK 0x1
2182#define ACP_I2SBT_ISR0__I2SBT_RXDA__SHIFT 0x0
2183#define ACP_I2SBT_ISR0__I2SBT_RXFO_MASK 0x2
2184#define ACP_I2SBT_ISR0__I2SBT_RXFO__SHIFT 0x1
2185#define ACP_I2SBT_ISR0__I2SBT_TXFE_MASK 0x10
2186#define ACP_I2SBT_ISR0__I2SBT_TXFE__SHIFT 0x4
2187#define ACP_I2SBT_ISR0__I2SBT_TXFO_MASK 0x20
2188#define ACP_I2SBT_ISR0__I2SBT_TXFO__SHIFT 0x5
2189#define ACP_I2SBT_IMR0__I2SBT_RXDAM_MASK 0x1
2190#define ACP_I2SBT_IMR0__I2SBT_RXDAM__SHIFT 0x0
2191#define ACP_I2SBT_IMR0__I2SBT_RXFOM_MASK 0x2
2192#define ACP_I2SBT_IMR0__I2SBT_RXFOM__SHIFT 0x1
2193#define ACP_I2SBT_IMR0__I2SBT_TXFEM_MASK 0x10
2194#define ACP_I2SBT_IMR0__I2SBT_TXFEM__SHIFT 0x4
2195#define ACP_I2SBT_IMR0__I2SBT_TXFOM_MASK 0x20
2196#define ACP_I2SBT_IMR0__I2SBT_TXFOM__SHIFT 0x5
2197#define ACP_I2SBT_ROR0__I2SBT_RXCHO_MASK 0x1
2198#define ACP_I2SBT_ROR0__I2SBT_RXCHO__SHIFT 0x0
2199#define ACP_I2SBT_TOR0__I2SBT_TXCHO_MASK 0x1
2200#define ACP_I2SBT_TOR0__I2SBT_TXCHO__SHIFT 0x0
2201#define ACP_I2SBT_RFCR0__I2SBT_RXCHDT_MASK 0xf
2202#define ACP_I2SBT_RFCR0__I2SBT_RXCHDT__SHIFT 0x0
2203#define ACP_I2SBT_TFCR0__I2SBT_TXCHET_MASK 0xf
2204#define ACP_I2SBT_TFCR0__I2SBT_TXCHET__SHIFT 0x0
2205#define ACP_I2SBT_RFF0__I2SBT_RXCHFR_MASK 0x1
2206#define ACP_I2SBT_RFF0__I2SBT_RXCHFR__SHIFT 0x0
2207#define ACP_I2SBT_TFF0__I2SBT_TXCHFR_MASK 0x1
2208#define ACP_I2SBT_TFF0__I2SBT_TXCHFR__SHIFT 0x0
2209#define ACP_I2SBT_LRBR1__I2SBT_LRBR1_MASK 0xffffffff
2210#define ACP_I2SBT_LRBR1__I2SBT_LRBR1__SHIFT 0x0
2211#define ACP_I2SBT_RRBR1__I2SBT_RRBR1_MASK 0xffffffff
2212#define ACP_I2SBT_RRBR1__I2SBT_RRBR1__SHIFT 0x0
2213#define ACP_I2SBT_RER1__I2SBT_RXCHEN1_MASK 0x1
2214#define ACP_I2SBT_RER1__I2SBT_RXCHEN1__SHIFT 0x0
2215#define ACP_I2SBT_TER1__I2SBT_TXCHEN1_MASK 0x1
2216#define ACP_I2SBT_TER1__I2SBT_TXCHEN1__SHIFT 0x0
2217#define ACP_I2SBT_RCR1__I2SBT_WLEN_MASK 0x7
2218#define ACP_I2SBT_RCR1__I2SBT_WLEN__SHIFT 0x0
2219#define ACP_I2SBT_TCR1__I2SBT_WLEN_MASK 0x7
2220#define ACP_I2SBT_TCR1__I2SBT_WLEN__SHIFT 0x0
2221#define ACP_I2SBT_ISR1__I2SBT_RXDA_MASK 0x1
2222#define ACP_I2SBT_ISR1__I2SBT_RXDA__SHIFT 0x0
2223#define ACP_I2SBT_ISR1__I2SBT_RXFO_MASK 0x2
2224#define ACP_I2SBT_ISR1__I2SBT_RXFO__SHIFT 0x1
2225#define ACP_I2SBT_ISR1__I2SBT_TXFE_MASK 0x10
2226#define ACP_I2SBT_ISR1__I2SBT_TXFE__SHIFT 0x4
2227#define ACP_I2SBT_ISR1__I2SBT_TXFO_MASK 0x20
2228#define ACP_I2SBT_ISR1__I2SBT_TXFO__SHIFT 0x5
2229#define ACP_I2SBT_IMR1__I2SBT_RXDAM_MASK 0x1
2230#define ACP_I2SBT_IMR1__I2SBT_RXDAM__SHIFT 0x0
2231#define ACP_I2SBT_IMR1__I2SBT_RXFOM_MASK 0x2
2232#define ACP_I2SBT_IMR1__I2SBT_RXFOM__SHIFT 0x1
2233#define ACP_I2SBT_IMR1__I2SBT_TXFEM_MASK 0x10
2234#define ACP_I2SBT_IMR1__I2SBT_TXFEM__SHIFT 0x4
2235#define ACP_I2SBT_IMR1__I2SBT_TXFOM_MASK 0x20
2236#define ACP_I2SBT_IMR1__I2SBT_TXFOM__SHIFT 0x5
2237#define ACP_I2SBT_ROR1__I2SBT_RXCHO_MASK 0x1
2238#define ACP_I2SBT_ROR1__I2SBT_RXCHO__SHIFT 0x0
2239#define ACP_I2SBT_TOR1__I2SBT_TXCHO_MASK 0x1
2240#define ACP_I2SBT_TOR1__I2SBT_TXCHO__SHIFT 0x0
2241#define ACP_I2SBT_RFCR1__I2SBT_RXCHDT_MASK 0xf
2242#define ACP_I2SBT_RFCR1__I2SBT_RXCHDT__SHIFT 0x0
2243#define ACP_I2SBT_TFCR1__I2SBT_TXCHET_MASK 0xf
2244#define ACP_I2SBT_TFCR1__I2SBT_TXCHET__SHIFT 0x0
2245#define ACP_I2SBT_RFF1__I2SBT_RXCHFR_MASK 0x1
2246#define ACP_I2SBT_RFF1__I2SBT_RXCHFR__SHIFT 0x0
2247#define ACP_I2SBT_TFF1__I2SBT_TXCHFR_MASK 0x1
2248#define ACP_I2SBT_TFF1__I2SBT_TXCHFR__SHIFT 0x0
2249#define ACP_I2SBT_RXDMA__I2SBT_RXDMA_MASK 0xffffffff
2250#define ACP_I2SBT_RXDMA__I2SBT_RXDMA__SHIFT 0x0
2251#define ACP_I2SBT_RRXDMA__I2SBT_RRXDMA_MASK 0x1
2252#define ACP_I2SBT_RRXDMA__I2SBT_RRXDMA__SHIFT 0x0
2253#define ACP_I2SBT_TXDMA__I2SBT_TXDMA_MASK 0xffffffff
2254#define ACP_I2SBT_TXDMA__I2SBT_TXDMA__SHIFT 0x0
2255#define ACP_I2SBT_RTXDMA__I2SBT_RTXDMA_MASK 0x1
2256#define ACP_I2SBT_RTXDMA__I2SBT_RTXDMA__SHIFT 0x0
2257#define ACP_I2SBT_COMP_PARAM_2__I2SBT_RX_WPRDSIZE_0_MASK 0x7
2258#define ACP_I2SBT_COMP_PARAM_2__I2SBT_RX_WPRDSIZE_0__SHIFT 0x0
2259#define ACP_I2SBT_COMP_PARAM_2__I2SBT_RX_WPRDSIZE_1_MASK 0x38
2260#define ACP_I2SBT_COMP_PARAM_2__I2SBT_RX_WPRDSIZE_1__SHIFT 0x3
2261#define ACP_I2SBT_COMP_PARAM_2__I2SBT_RX_WPRDSIZE_2_MASK 0x380
2262#define ACP_I2SBT_COMP_PARAM_2__I2SBT_RX_WPRDSIZE_2__SHIFT 0x7
2263#define ACP_I2SBT_COMP_PARAM_2__I2SBT_RX_WPRDSIZE_3_MASK 0x1c00
2264#define ACP_I2SBT_COMP_PARAM_2__I2SBT_RX_WPRDSIZE_3__SHIFT 0xa
2265#define ACP_I2SBT_COMP_PARAM_1__I2SBT_APB_DATA_WIDTH_MASK 0x3
2266#define ACP_I2SBT_COMP_PARAM_1__I2SBT_APB_DATA_WIDTH__SHIFT 0x0
2267#define ACP_I2SBT_COMP_PARAM_1__I2SBT_FIFO_DEPTH_GLOBAL_MASK 0xc
2268#define ACP_I2SBT_COMP_PARAM_1__I2SBT_FIFO_DEPTH_GLOBAL__SHIFT 0x2
2269#define ACP_I2SBT_COMP_PARAM_1__I2SBT_MODE_EN_MASK 0x10
2270#define ACP_I2SBT_COMP_PARAM_1__I2SBT_MODE_EN__SHIFT 0x4
2271#define ACP_I2SBT_COMP_PARAM_1__I2SBT_TRANSMITTER_BLOCK_MASK 0x20
2272#define ACP_I2SBT_COMP_PARAM_1__I2SBT_TRANSMITTER_BLOCK__SHIFT 0x5
2273#define ACP_I2SBT_COMP_PARAM_1__I2SBT_RECEIVER_BLOCK_MASK 0x40
2274#define ACP_I2SBT_COMP_PARAM_1__I2SBT_RECEIVER_BLOCK__SHIFT 0x6
2275#define ACP_I2SBT_COMP_PARAM_1__I2SBT_RX_CHANNLES_MASK 0x180
2276#define ACP_I2SBT_COMP_PARAM_1__I2SBT_RX_CHANNLES__SHIFT 0x7
2277#define ACP_I2SBT_COMP_PARAM_1__I2SBT_TX_CHANNLES_MASK 0x600
2278#define ACP_I2SBT_COMP_PARAM_1__I2SBT_TX_CHANNLES__SHIFT 0x9
2279#define ACP_I2SBT_COMP_PARAM_1__I2SBT_TX_WORDSIZE_0_MASK 0x70000
2280#define ACP_I2SBT_COMP_PARAM_1__I2SBT_TX_WORDSIZE_0__SHIFT 0x10
2281#define ACP_I2SBT_COMP_PARAM_1__I2SBT_TX_WORDSIZE_1_MASK 0x380000
2282#define ACP_I2SBT_COMP_PARAM_1__I2SBT_TX_WORDSIZE_1__SHIFT 0x13
2283#define ACP_I2SBT_COMP_PARAM_1__I2SBT_TX_WORDSIZE_2_MASK 0x1c00000
2284#define ACP_I2SBT_COMP_PARAM_1__I2SBT_TX_WORDSIZE_2__SHIFT 0x16
2285#define ACP_I2SBT_COMP_PARAM_1__I2SBT_TX_WORDSIZE_3_MASK 0xe000000
2286#define ACP_I2SBT_COMP_PARAM_1__I2SBT_TX_WORDSIZE_3__SHIFT 0x19
2287#define ACP_I2SBT_COMP_VERSION__I2SBT_APB_DATA_WIDTH_MASK 0xffffffff
2288#define ACP_I2SBT_COMP_VERSION__I2SBT_APB_DATA_WIDTH__SHIFT 0x0
2289#define ACP_I2SBT_COMP_TYPE__I2SBT_COMP_TYPE_MASK 0xffffffff
2290#define ACP_I2SBT_COMP_TYPE__I2SBT_COMP_TYPE__SHIFT 0x0
2291
2292#endif /* ACP_2_2_SH_MASK_H */
diff --git a/sound/soc/atmel/Kconfig b/sound/soc/atmel/Kconfig
index 2d30464b81ce..06e099e802df 100644
--- a/sound/soc/atmel/Kconfig
+++ b/sound/soc/atmel/Kconfig
@@ -68,4 +68,13 @@ config SND_ATMEL_SOC_CLASSD
68 help 68 help
69 Say Y if you want to add support for Atmel ASoC driver for boards using 69 Say Y if you want to add support for Atmel ASoC driver for boards using
70 CLASSD. 70 CLASSD.
71
72config SND_ATMEL_SOC_PDMIC
73 tristate "Atmel ASoC driver for boards using PDMIC"
74 depends on OF && (ARCH_AT91 || COMPILE_TEST)
75 select SND_SOC_GENERIC_DMAENGINE_PCM
76 select REGMAP_MMIO
77 help
78 Say Y if you want to add support for Atmel ASoC driver for boards using
79 PDMIC.
71endif 80endif
diff --git a/sound/soc/atmel/Makefile b/sound/soc/atmel/Makefile
index f6f7db428216..a2b127bd9c87 100644
--- a/sound/soc/atmel/Makefile
+++ b/sound/soc/atmel/Makefile
@@ -12,8 +12,10 @@ snd-soc-sam9g20-wm8731-objs := sam9g20_wm8731.o
12snd-atmel-soc-wm8904-objs := atmel_wm8904.o 12snd-atmel-soc-wm8904-objs := atmel_wm8904.o
13snd-soc-sam9x5-wm8731-objs := sam9x5_wm8731.o 13snd-soc-sam9x5-wm8731-objs := sam9x5_wm8731.o
14snd-atmel-soc-classd-objs := atmel-classd.o 14snd-atmel-soc-classd-objs := atmel-classd.o
15snd-atmel-soc-pdmic-objs := atmel-pdmic.o
15 16
16obj-$(CONFIG_SND_AT91_SOC_SAM9G20_WM8731) += snd-soc-sam9g20-wm8731.o 17obj-$(CONFIG_SND_AT91_SOC_SAM9G20_WM8731) += snd-soc-sam9g20-wm8731.o
17obj-$(CONFIG_SND_ATMEL_SOC_WM8904) += snd-atmel-soc-wm8904.o 18obj-$(CONFIG_SND_ATMEL_SOC_WM8904) += snd-atmel-soc-wm8904.o
18obj-$(CONFIG_SND_AT91_SOC_SAM9X5_WM8731) += snd-soc-sam9x5-wm8731.o 19obj-$(CONFIG_SND_AT91_SOC_SAM9X5_WM8731) += snd-soc-sam9x5-wm8731.o
19obj-$(CONFIG_SND_ATMEL_SOC_CLASSD) += snd-atmel-soc-classd.o 20obj-$(CONFIG_SND_ATMEL_SOC_CLASSD) += snd-atmel-soc-classd.o
21obj-$(CONFIG_SND_ATMEL_SOC_PDMIC) += snd-atmel-soc-pdmic.o
diff --git a/sound/soc/atmel/atmel-classd.c b/sound/soc/atmel/atmel-classd.c
index 8276675730ef..6107de9c538b 100644
--- a/sound/soc/atmel/atmel-classd.c
+++ b/sound/soc/atmel/atmel-classd.c
@@ -106,7 +106,7 @@ static const struct snd_pcm_hardware atmel_classd_hw = {
106 .rates = ATMEL_CLASSD_RATES, 106 .rates = ATMEL_CLASSD_RATES,
107 .rate_min = 8000, 107 .rate_min = 8000,
108 .rate_max = 96000, 108 .rate_max = 96000,
109 .channels_min = 2, 109 .channels_min = 1,
110 .channels_max = 2, 110 .channels_max = 2,
111 .buffer_bytes_max = 64 * 1024, 111 .buffer_bytes_max = 64 * 1024,
112 .period_bytes_min = 256, 112 .period_bytes_min = 256,
@@ -145,7 +145,7 @@ static const struct snd_soc_dai_ops atmel_classd_cpu_dai_ops = {
145 145
146static struct snd_soc_dai_driver atmel_classd_cpu_dai = { 146static struct snd_soc_dai_driver atmel_classd_cpu_dai = {
147 .playback = { 147 .playback = {
148 .channels_min = 2, 148 .channels_min = 1,
149 .channels_max = 2, 149 .channels_max = 2,
150 .rates = ATMEL_CLASSD_RATES, 150 .rates = ATMEL_CLASSD_RATES,
151 .formats = SNDRV_PCM_FMTBIT_S16_LE,}, 151 .formats = SNDRV_PCM_FMTBIT_S16_LE,},
@@ -171,9 +171,13 @@ atmel_classd_platform_configure_dma(struct snd_pcm_substream *substream,
171 return -EINVAL; 171 return -EINVAL;
172 } 172 }
173 173
174 if (params_channels(params) == 1)
175 slave_config->dst_addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES;
176 else
177 slave_config->dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
178
174 slave_config->direction = DMA_MEM_TO_DEV; 179 slave_config->direction = DMA_MEM_TO_DEV;
175 slave_config->dst_addr = dd->phy_base + CLASSD_THR; 180 slave_config->dst_addr = dd->phy_base + CLASSD_THR;
176 slave_config->dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
177 slave_config->dst_maxburst = 1; 181 slave_config->dst_maxburst = 1;
178 slave_config->src_maxburst = 1; 182 slave_config->src_maxburst = 1;
179 slave_config->device_fc = false; 183 slave_config->device_fc = false;
@@ -486,7 +490,7 @@ static struct snd_soc_dai_driver atmel_classd_codec_dai = {
486 .name = ATMEL_CLASSD_CODEC_DAI_NAME, 490 .name = ATMEL_CLASSD_CODEC_DAI_NAME,
487 .playback = { 491 .playback = {
488 .stream_name = "Playback", 492 .stream_name = "Playback",
489 .channels_min = 2, 493 .channels_min = 1,
490 .channels_max = 2, 494 .channels_max = 2,
491 .rates = ATMEL_CLASSD_RATES, 495 .rates = ATMEL_CLASSD_RATES,
492 .formats = SNDRV_PCM_FMTBIT_S16_LE, 496 .formats = SNDRV_PCM_FMTBIT_S16_LE,
@@ -636,8 +640,10 @@ static int atmel_classd_probe(struct platform_device *pdev)
636 640
637 /* register sound card */ 641 /* register sound card */
638 card = devm_kzalloc(dev, sizeof(*card), GFP_KERNEL); 642 card = devm_kzalloc(dev, sizeof(*card), GFP_KERNEL);
639 if (!card) 643 if (!card) {
640 return -ENOMEM; 644 ret = -ENOMEM;
645 goto unregister_codec;
646 }
641 647
642 snd_soc_card_set_drvdata(card, dd); 648 snd_soc_card_set_drvdata(card, dd);
643 platform_set_drvdata(pdev, card); 649 platform_set_drvdata(pdev, card);
@@ -645,16 +651,20 @@ static int atmel_classd_probe(struct platform_device *pdev)
645 ret = atmel_classd_asoc_card_init(dev, card); 651 ret = atmel_classd_asoc_card_init(dev, card);
646 if (ret) { 652 if (ret) {
647 dev_err(dev, "failed to init sound card\n"); 653 dev_err(dev, "failed to init sound card\n");
648 return ret; 654 goto unregister_codec;
649 } 655 }
650 656
651 ret = devm_snd_soc_register_card(dev, card); 657 ret = devm_snd_soc_register_card(dev, card);
652 if (ret) { 658 if (ret) {
653 dev_err(dev, "failed to register sound card: %d\n", ret); 659 dev_err(dev, "failed to register sound card: %d\n", ret);
654 return ret; 660 goto unregister_codec;
655 } 661 }
656 662
657 return 0; 663 return 0;
664
665unregister_codec:
666 snd_soc_unregister_codec(dev);
667 return ret;
658} 668}
659 669
660static int atmel_classd_remove(struct platform_device *pdev) 670static int atmel_classd_remove(struct platform_device *pdev)
diff --git a/sound/soc/atmel/atmel-pdmic.c b/sound/soc/atmel/atmel-pdmic.c
new file mode 100644
index 000000000000..aee4787a0b89
--- /dev/null
+++ b/sound/soc/atmel/atmel-pdmic.c
@@ -0,0 +1,738 @@
1/* Atmel PDMIC driver
2 *
3 * Copyright (C) 2015 Atmel
4 *
5 * Author: Songjun Wu <songjun.wu@atmel.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 or later
9 * as published by the Free Software Foundation.
10 */
11
12#include <linux/of.h>
13#include <linux/clk.h>
14#include <linux/module.h>
15#include <linux/platform_device.h>
16#include <linux/regmap.h>
17#include <sound/core.h>
18#include <sound/dmaengine_pcm.h>
19#include <sound/pcm_params.h>
20#include <sound/tlv.h>
21#include "atmel-pdmic.h"
22
23struct atmel_pdmic_pdata {
24 u32 mic_min_freq;
25 u32 mic_max_freq;
26 s32 mic_offset;
27 const char *card_name;
28};
29
30struct atmel_pdmic {
31 dma_addr_t phy_base;
32 struct regmap *regmap;
33 struct clk *pclk;
34 struct clk *gclk;
35 int irq;
36 struct snd_pcm_substream *substream;
37 const struct atmel_pdmic_pdata *pdata;
38};
39
40static const struct of_device_id atmel_pdmic_of_match[] = {
41 {
42 .compatible = "atmel,sama5d2-pdmic",
43 }, {
44 /* sentinel */
45 }
46};
47MODULE_DEVICE_TABLE(of, atmel_pdmic_of_match);
48
49#define PDMIC_OFFSET_MAX_VAL S16_MAX
50#define PDMIC_OFFSET_MIN_VAL S16_MIN
51
52static struct atmel_pdmic_pdata *atmel_pdmic_dt_init(struct device *dev)
53{
54 struct device_node *np = dev->of_node;
55 struct atmel_pdmic_pdata *pdata;
56
57 if (!np) {
58 dev_err(dev, "device node not found\n");
59 return ERR_PTR(-EINVAL);
60 }
61
62 pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL);
63 if (!pdata)
64 return ERR_PTR(-ENOMEM);
65
66 if (of_property_read_string(np, "atmel,model", &pdata->card_name))
67 pdata->card_name = "PDMIC";
68
69 if (of_property_read_u32(np, "atmel,mic-min-freq",
70 &pdata->mic_min_freq)) {
71 dev_err(dev, "failed to get mic-min-freq\n");
72 return ERR_PTR(-EINVAL);
73 }
74
75 if (of_property_read_u32(np, "atmel,mic-max-freq",
76 &pdata->mic_max_freq)) {
77 dev_err(dev, "failed to get mic-max-freq\n");
78 return ERR_PTR(-EINVAL);
79 }
80
81 if (pdata->mic_max_freq < pdata->mic_min_freq) {
82 dev_err(dev,
83 "mic-max-freq should not less than mic-min-freq\n");
84 return ERR_PTR(-EINVAL);
85 }
86
87 if (of_property_read_s32(np, "atmel,mic-offset", &pdata->mic_offset))
88 pdata->mic_offset = 0;
89
90 if (pdata->mic_offset > PDMIC_OFFSET_MAX_VAL) {
91 dev_warn(dev,
92 "mic-offset value %d is larger than the max value %d, the max value is specified\n",
93 pdata->mic_offset, PDMIC_OFFSET_MAX_VAL);
94 pdata->mic_offset = PDMIC_OFFSET_MAX_VAL;
95 } else if (pdata->mic_offset < PDMIC_OFFSET_MIN_VAL) {
96 dev_warn(dev,
97 "mic-offset value %d is less than the min value %d, the min value is specified\n",
98 pdata->mic_offset, PDMIC_OFFSET_MIN_VAL);
99 pdata->mic_offset = PDMIC_OFFSET_MIN_VAL;
100 }
101
102 return pdata;
103}
104
105/* cpu dai component */
106static int atmel_pdmic_cpu_dai_startup(struct snd_pcm_substream *substream,
107 struct snd_soc_dai *cpu_dai)
108{
109 struct snd_soc_pcm_runtime *rtd = substream->private_data;
110 struct atmel_pdmic *dd = snd_soc_card_get_drvdata(rtd->card);
111 int ret;
112
113 ret = clk_prepare_enable(dd->gclk);
114 if (ret)
115 return ret;
116
117 ret = clk_prepare_enable(dd->pclk);
118 if (ret)
119 return ret;
120
121 /* Clear all bits in the Control Register(PDMIC_CR) */
122 regmap_write(dd->regmap, PDMIC_CR, 0);
123
124 dd->substream = substream;
125
126 /* Enable the overrun error interrupt */
127 regmap_write(dd->regmap, PDMIC_IER, PDMIC_IER_OVRE);
128
129 return 0;
130}
131
132static void atmel_pdmic_cpu_dai_shutdown(struct snd_pcm_substream *substream,
133 struct snd_soc_dai *cpu_dai)
134{
135 struct snd_soc_pcm_runtime *rtd = substream->private_data;
136 struct atmel_pdmic *dd = snd_soc_card_get_drvdata(rtd->card);
137
138 /* Disable the overrun error interrupt */
139 regmap_write(dd->regmap, PDMIC_IDR, PDMIC_IDR_OVRE);
140
141 clk_disable_unprepare(dd->gclk);
142 clk_disable_unprepare(dd->pclk);
143}
144
145static int atmel_pdmic_cpu_dai_prepare(struct snd_pcm_substream *substream,
146 struct snd_soc_dai *cpu_dai)
147{
148 struct snd_soc_pcm_runtime *rtd = substream->private_data;
149 struct atmel_pdmic *dd = snd_soc_card_get_drvdata(rtd->card);
150 u32 val;
151
152 /* Clean the PDMIC Converted Data Register */
153 return regmap_read(dd->regmap, PDMIC_CDR, &val);
154}
155
156static const struct snd_soc_dai_ops atmel_pdmic_cpu_dai_ops = {
157 .startup = atmel_pdmic_cpu_dai_startup,
158 .shutdown = atmel_pdmic_cpu_dai_shutdown,
159 .prepare = atmel_pdmic_cpu_dai_prepare,
160};
161
162#define ATMEL_PDMIC_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S32_LE)
163
164static struct snd_soc_dai_driver atmel_pdmic_cpu_dai = {
165 .capture = {
166 .channels_min = 1,
167 .channels_max = 1,
168 .rates = SNDRV_PCM_RATE_KNOT,
169 .formats = ATMEL_PDMIC_FORMATS,},
170 .ops = &atmel_pdmic_cpu_dai_ops,
171};
172
173static const struct snd_soc_component_driver atmel_pdmic_cpu_dai_component = {
174 .name = "atmel-pdmic",
175};
176
177/* platform */
178#define ATMEL_PDMIC_MAX_BUF_SIZE (64 * 1024)
179#define ATMEL_PDMIC_PREALLOC_BUF_SIZE ATMEL_PDMIC_MAX_BUF_SIZE
180
181static const struct snd_pcm_hardware atmel_pdmic_hw = {
182 .info = SNDRV_PCM_INFO_MMAP
183 | SNDRV_PCM_INFO_MMAP_VALID
184 | SNDRV_PCM_INFO_INTERLEAVED
185 | SNDRV_PCM_INFO_RESUME
186 | SNDRV_PCM_INFO_PAUSE,
187 .formats = ATMEL_PDMIC_FORMATS,
188 .buffer_bytes_max = ATMEL_PDMIC_MAX_BUF_SIZE,
189 .period_bytes_min = 256,
190 .period_bytes_max = 32 * 1024,
191 .periods_min = 2,
192 .periods_max = 256,
193};
194
195static int
196atmel_pdmic_platform_configure_dma(struct snd_pcm_substream *substream,
197 struct snd_pcm_hw_params *params,
198 struct dma_slave_config *slave_config)
199{
200 struct snd_soc_pcm_runtime *rtd = substream->private_data;
201 struct atmel_pdmic *dd = snd_soc_card_get_drvdata(rtd->card);
202 int ret;
203
204 ret = snd_hwparams_to_dma_slave_config(substream, params,
205 slave_config);
206 if (ret) {
207 dev_err(rtd->platform->dev,
208 "hw params to dma slave configure failed\n");
209 return ret;
210 }
211
212 slave_config->src_addr = dd->phy_base + PDMIC_CDR;
213 slave_config->src_maxburst = 1;
214 slave_config->dst_maxburst = 1;
215
216 return 0;
217}
218
219static const struct snd_dmaengine_pcm_config
220atmel_pdmic_dmaengine_pcm_config = {
221 .prepare_slave_config = atmel_pdmic_platform_configure_dma,
222 .pcm_hardware = &atmel_pdmic_hw,
223 .prealloc_buffer_size = ATMEL_PDMIC_PREALLOC_BUF_SIZE,
224};
225
226/* codec */
227/* Mic Gain = dgain * 2^(-scale) */
228struct mic_gain {
229 unsigned int dgain;
230 unsigned int scale;
231};
232
233/* range from -90 dB to 90 dB */
234static const struct mic_gain mic_gain_table[] = {
235{ 1, 15}, { 1, 14}, /* -90, -84 dB */
236{ 3, 15}, { 1, 13}, { 3, 14}, { 1, 12}, /* -81, -78, -75, -72 dB */
237{ 5, 14}, { 13, 15}, /* -70, -68 dB */
238{ 9, 14}, { 21, 15}, { 23, 15}, { 13, 14}, /* -65 ~ -62 dB */
239{ 29, 15}, { 33, 15}, { 37, 15}, { 41, 15}, /* -61 ~ -58 dB */
240{ 23, 14}, { 13, 13}, { 58, 15}, { 65, 15}, /* -57 ~ -54 dB */
241{ 73, 15}, { 41, 14}, { 23, 13}, { 13, 12}, /* -53 ~ -50 dB */
242{ 29, 13}, { 65, 14}, { 73, 14}, { 41, 13}, /* -49 ~ -46 dB */
243{ 23, 12}, { 207, 15}, { 29, 12}, { 65, 13}, /* -45 ~ -42 dB */
244{ 73, 13}, { 41, 12}, { 23, 11}, { 413, 15}, /* -41 ~ -38 dB */
245{ 463, 15}, { 519, 15}, { 583, 15}, { 327, 14}, /* -37 ~ -34 dB */
246{ 367, 14}, { 823, 15}, { 231, 13}, { 1036, 15}, /* -33 ~ -30 dB */
247{ 1163, 15}, { 1305, 15}, { 183, 12}, { 1642, 15}, /* -29 ~ -26 dB */
248{ 1843, 15}, { 2068, 15}, { 145, 11}, { 2603, 15}, /* -25 ~ -22 dB */
249{ 365, 12}, { 3277, 15}, { 3677, 15}, { 4125, 15}, /* -21 ~ -18 dB */
250{ 4629, 15}, { 5193, 15}, { 5827, 15}, { 3269, 14}, /* -17 ~ -14 dB */
251{ 917, 12}, { 8231, 15}, { 9235, 15}, { 5181, 14}, /* -13 ~ -10 dB */
252{11627, 15}, {13045, 15}, {14637, 15}, {16423, 15}, /* -9 ~ -6 dB */
253{18427, 15}, {20675, 15}, { 5799, 13}, {26029, 15}, /* -5 ~ -2 dB */
254{ 7301, 13}, { 1, 0}, {18383, 14}, {10313, 13}, /* -1 ~ 2 dB */
255{23143, 14}, {25967, 14}, {29135, 14}, {16345, 13}, /* 3 ~ 6 dB */
256{ 4585, 11}, {20577, 13}, { 1443, 9}, {25905, 13}, /* 7 ~ 10 dB */
257{14533, 12}, { 8153, 11}, { 2287, 9}, {20529, 12}, /* 11 ~ 14 dB */
258{11517, 11}, { 6461, 10}, {28997, 12}, { 4067, 9}, /* 15 ~ 18 dB */
259{18253, 11}, { 10, 0}, {22979, 11}, {25783, 11}, /* 19 ~ 22 dB */
260{28929, 11}, {32459, 11}, { 9105, 9}, {20431, 10}, /* 23 ~ 26 dB */
261{22925, 10}, {12861, 9}, { 7215, 8}, {16191, 9}, /* 27 ~ 30 dB */
262{ 9083, 8}, {20383, 9}, {11435, 8}, { 6145, 7}, /* 31 ~ 34 dB */
263{ 3599, 6}, {32305, 9}, {18123, 8}, {20335, 8}, /* 35 ~ 38 dB */
264{ 713, 3}, { 100, 0}, { 7181, 6}, { 8057, 6}, /* 39 ~ 42 dB */
265{ 565, 2}, {20287, 7}, {11381, 6}, {25539, 7}, /* 43 ~ 46 dB */
266{ 1791, 3}, { 4019, 4}, { 9019, 5}, {20239, 6}, /* 47 ~ 50 dB */
267{ 5677, 4}, {25479, 6}, { 7147, 4}, { 8019, 4}, /* 51 ~ 54 dB */
268{17995, 5}, {20191, 5}, {11327, 4}, {12709, 4}, /* 55 ~ 58 dB */
269{ 3565, 2}, { 1000, 0}, { 1122, 0}, { 1259, 0}, /* 59 ~ 62 dB */
270{ 2825, 1}, {12679, 3}, { 7113, 2}, { 7981, 2}, /* 63 ~ 66 dB */
271{ 8955, 2}, {20095, 3}, {22547, 3}, {12649, 2}, /* 67 ~ 70 dB */
272{28385, 3}, { 3981, 0}, {17867, 2}, {20047, 2}, /* 71 ~ 74 dB */
273{11247, 1}, {12619, 1}, {14159, 1}, {31773, 2}, /* 75 ~ 78 dB */
274{17825, 1}, {10000, 0}, {11220, 0}, {12589, 0}, /* 79 ~ 82 dB */
275{28251, 1}, {15849, 0}, {17783, 0}, {19953, 0}, /* 83 ~ 86 dB */
276{22387, 0}, {25119, 0}, {28184, 0}, {31623, 0}, /* 87 ~ 90 dB */
277};
278
279static const DECLARE_TLV_DB_RANGE(mic_gain_tlv,
280 0, 1, TLV_DB_SCALE_ITEM(-9000, 600, 0),
281 2, 5, TLV_DB_SCALE_ITEM(-8100, 300, 0),
282 6, 7, TLV_DB_SCALE_ITEM(-7000, 200, 0),
283 8, ARRAY_SIZE(mic_gain_table)-1, TLV_DB_SCALE_ITEM(-6500, 100, 0),
284);
285
286int pdmic_get_mic_volsw(struct snd_kcontrol *kcontrol,
287 struct snd_ctl_elem_value *ucontrol)
288{
289 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
290 unsigned int dgain_val, scale_val;
291 int i;
292
293 dgain_val = (snd_soc_read(codec, PDMIC_DSPR1) & PDMIC_DSPR1_DGAIN_MASK)
294 >> PDMIC_DSPR1_DGAIN_SHIFT;
295
296 scale_val = (snd_soc_read(codec, PDMIC_DSPR0) & PDMIC_DSPR0_SCALE_MASK)
297 >> PDMIC_DSPR0_SCALE_SHIFT;
298
299 for (i = 0; i < ARRAY_SIZE(mic_gain_table); i++) {
300 if ((mic_gain_table[i].dgain == dgain_val) &&
301 (mic_gain_table[i].scale == scale_val))
302 ucontrol->value.integer.value[0] = i;
303 }
304
305 return 0;
306}
307
308static int pdmic_put_mic_volsw(struct snd_kcontrol *kcontrol,
309 struct snd_ctl_elem_value *ucontrol)
310{
311 struct soc_mixer_control *mc =
312 (struct soc_mixer_control *)kcontrol->private_value;
313 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
314 int max = mc->max;
315 unsigned int val;
316 int ret;
317
318 val = ucontrol->value.integer.value[0];
319
320 if (val > max)
321 return -EINVAL;
322
323 ret = snd_soc_update_bits(codec, PDMIC_DSPR1, PDMIC_DSPR1_DGAIN_MASK,
324 mic_gain_table[val].dgain << PDMIC_DSPR1_DGAIN_SHIFT);
325 if (ret < 0)
326 return ret;
327
328 ret = snd_soc_update_bits(codec, PDMIC_DSPR0, PDMIC_DSPR0_SCALE_MASK,
329 mic_gain_table[val].scale << PDMIC_DSPR0_SCALE_SHIFT);
330 if (ret < 0)
331 return ret;
332
333 return 0;
334}
335
336static const struct snd_kcontrol_new atmel_pdmic_snd_controls[] = {
337SOC_SINGLE_EXT_TLV("Mic Capture Volume", PDMIC_DSPR1, PDMIC_DSPR1_DGAIN_SHIFT,
338 ARRAY_SIZE(mic_gain_table)-1, 0,
339 pdmic_get_mic_volsw, pdmic_put_mic_volsw, mic_gain_tlv),
340
341SOC_SINGLE("High Pass Filter Switch", PDMIC_DSPR0,
342 PDMIC_DSPR0_HPFBYP_SHIFT, 1, 1),
343
344SOC_SINGLE("SINCC Filter Switch", PDMIC_DSPR0, PDMIC_DSPR0_SINBYP_SHIFT, 1, 1),
345};
346
347static int atmel_pdmic_codec_probe(struct snd_soc_codec *codec)
348{
349 struct snd_soc_card *card = snd_soc_codec_get_drvdata(codec);
350 struct atmel_pdmic *dd = snd_soc_card_get_drvdata(card);
351
352 snd_soc_update_bits(codec, PDMIC_DSPR1, PDMIC_DSPR1_OFFSET_MASK,
353 (u32)(dd->pdata->mic_offset << PDMIC_DSPR1_OFFSET_SHIFT));
354
355 return 0;
356}
357
358static struct snd_soc_codec_driver soc_codec_dev_pdmic = {
359 .probe = atmel_pdmic_codec_probe,
360 .controls = atmel_pdmic_snd_controls,
361 .num_controls = ARRAY_SIZE(atmel_pdmic_snd_controls),
362};
363
364/* codec dai component */
365#define PDMIC_MR_PRESCAL_MAX_VAL 127
366
367static int
368atmel_pdmic_codec_dai_hw_params(struct snd_pcm_substream *substream,
369 struct snd_pcm_hw_params *params,
370 struct snd_soc_dai *codec_dai)
371{
372 struct snd_soc_pcm_runtime *rtd = substream->private_data;
373 struct atmel_pdmic *dd = snd_soc_card_get_drvdata(rtd->card);
374 struct snd_soc_codec *codec = codec_dai->codec;
375 unsigned int rate_min = substream->runtime->hw.rate_min;
376 unsigned int rate_max = substream->runtime->hw.rate_max;
377 int fs = params_rate(params);
378 int bits = params_width(params);
379 unsigned long pclk_rate, gclk_rate;
380 unsigned int f_pdmic;
381 u32 mr_val, dspr0_val, pclk_prescal, gclk_prescal;
382
383 if (params_channels(params) != 1) {
384 dev_err(codec->dev,
385 "only supports one channel\n");
386 return -EINVAL;
387 }
388
389 if ((fs < rate_min) || (fs > rate_max)) {
390 dev_err(codec->dev,
391 "sample rate is %dHz, min rate is %dHz, max rate is %dHz\n",
392 fs, rate_min, rate_max);
393
394 return -EINVAL;
395 }
396
397 switch (bits) {
398 case 16:
399 dspr0_val = (PDMIC_DSPR0_SIZE_16_BITS
400 << PDMIC_DSPR0_SIZE_SHIFT);
401 break;
402 case 32:
403 dspr0_val = (PDMIC_DSPR0_SIZE_32_BITS
404 << PDMIC_DSPR0_SIZE_SHIFT);
405 break;
406 default:
407 return -EINVAL;
408 }
409
410 if ((fs << 7) > (rate_max << 6)) {
411 f_pdmic = fs << 6;
412 dspr0_val |= PDMIC_DSPR0_OSR_64 << PDMIC_DSPR0_OSR_SHIFT;
413 } else {
414 f_pdmic = fs << 7;
415 dspr0_val |= PDMIC_DSPR0_OSR_128 << PDMIC_DSPR0_OSR_SHIFT;
416 }
417
418 pclk_rate = clk_get_rate(dd->pclk);
419 gclk_rate = clk_get_rate(dd->gclk);
420
421 /* PRESCAL = SELCK/(2*f_pdmic) - 1*/
422 pclk_prescal = (u32)(pclk_rate/(f_pdmic << 1)) - 1;
423 gclk_prescal = (u32)(gclk_rate/(f_pdmic << 1)) - 1;
424
425 if ((pclk_prescal > PDMIC_MR_PRESCAL_MAX_VAL) ||
426 (gclk_rate/((gclk_prescal + 1) << 1) <
427 pclk_rate/((pclk_prescal + 1) << 1))) {
428 mr_val = gclk_prescal << PDMIC_MR_PRESCAL_SHIFT;
429 mr_val |= PDMIC_MR_CLKS_GCK << PDMIC_MR_CLKS_SHIFT;
430 } else {
431 mr_val = pclk_prescal << PDMIC_MR_PRESCAL_SHIFT;
432 mr_val |= PDMIC_MR_CLKS_PCK << PDMIC_MR_CLKS_SHIFT;
433 }
434
435 snd_soc_update_bits(codec, PDMIC_MR,
436 PDMIC_MR_PRESCAL_MASK | PDMIC_MR_CLKS_MASK, mr_val);
437
438 snd_soc_update_bits(codec, PDMIC_DSPR0,
439 PDMIC_DSPR0_OSR_MASK | PDMIC_DSPR0_SIZE_MASK, dspr0_val);
440
441 return 0;
442}
443
444static int atmel_pdmic_codec_dai_prepare(struct snd_pcm_substream *substream,
445 struct snd_soc_dai *codec_dai)
446{
447 struct snd_soc_codec *codec = codec_dai->codec;
448
449 snd_soc_update_bits(codec, PDMIC_CR, PDMIC_CR_ENPDM_MASK,
450 PDMIC_CR_ENPDM_DIS << PDMIC_CR_ENPDM_SHIFT);
451
452 return 0;
453}
454
455static int atmel_pdmic_codec_dai_trigger(struct snd_pcm_substream *substream,
456 int cmd, struct snd_soc_dai *codec_dai)
457{
458 struct snd_soc_codec *codec = codec_dai->codec;
459 u32 val;
460
461 switch (cmd) {
462 case SNDRV_PCM_TRIGGER_START:
463 case SNDRV_PCM_TRIGGER_RESUME:
464 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
465 val = PDMIC_CR_ENPDM_EN << PDMIC_CR_ENPDM_SHIFT;
466 break;
467 case SNDRV_PCM_TRIGGER_STOP:
468 case SNDRV_PCM_TRIGGER_SUSPEND:
469 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
470 val = PDMIC_CR_ENPDM_DIS << PDMIC_CR_ENPDM_SHIFT;
471 break;
472 default:
473 return -EINVAL;
474 }
475
476 snd_soc_update_bits(codec, PDMIC_CR, PDMIC_CR_ENPDM_MASK, val);
477
478 return 0;
479}
480
481static const struct snd_soc_dai_ops atmel_pdmic_codec_dai_ops = {
482 .hw_params = atmel_pdmic_codec_dai_hw_params,
483 .prepare = atmel_pdmic_codec_dai_prepare,
484 .trigger = atmel_pdmic_codec_dai_trigger,
485};
486
487#define ATMEL_PDMIC_CODEC_DAI_NAME "atmel-pdmic-hifi"
488
489static struct snd_soc_dai_driver atmel_pdmic_codec_dai = {
490 .name = ATMEL_PDMIC_CODEC_DAI_NAME,
491 .capture = {
492 .stream_name = "Capture",
493 .channels_min = 1,
494 .channels_max = 1,
495 .rates = SNDRV_PCM_RATE_KNOT,
496 .formats = ATMEL_PDMIC_FORMATS,
497 },
498 .ops = &atmel_pdmic_codec_dai_ops,
499};
500
501/* ASoC sound card */
502static int atmel_pdmic_asoc_card_init(struct device *dev,
503 struct snd_soc_card *card)
504{
505 struct snd_soc_dai_link *dai_link;
506 struct atmel_pdmic *dd = snd_soc_card_get_drvdata(card);
507
508 dai_link = devm_kzalloc(dev, sizeof(*dai_link), GFP_KERNEL);
509 if (!dai_link)
510 return -ENOMEM;
511
512 dai_link->name = "PDMIC";
513 dai_link->stream_name = "PDMIC PCM";
514 dai_link->codec_dai_name = ATMEL_PDMIC_CODEC_DAI_NAME;
515 dai_link->cpu_dai_name = dev_name(dev);
516 dai_link->codec_name = dev_name(dev);
517 dai_link->platform_name = dev_name(dev);
518
519 card->dai_link = dai_link;
520 card->num_links = 1;
521 card->name = dd->pdata->card_name;
522 card->dev = dev;
523
524 return 0;
525}
526
527static void atmel_pdmic_get_sample_rate(struct atmel_pdmic *dd,
528 unsigned int *rate_min, unsigned int *rate_max)
529{
530 u32 mic_min_freq = dd->pdata->mic_min_freq;
531 u32 mic_max_freq = dd->pdata->mic_max_freq;
532 u32 clk_max_rate = (u32)(clk_get_rate(dd->pclk) >> 1);
533 u32 clk_min_rate = (u32)(clk_get_rate(dd->gclk) >> 8);
534
535 if (mic_max_freq > clk_max_rate)
536 mic_max_freq = clk_max_rate;
537
538 if (mic_min_freq < clk_min_rate)
539 mic_min_freq = clk_min_rate;
540
541 *rate_min = DIV_ROUND_CLOSEST(mic_min_freq, 128);
542 *rate_max = mic_max_freq >> 6;
543}
544
545/* PDMIC interrupt handler */
546static irqreturn_t atmel_pdmic_interrupt(int irq, void *dev_id)
547{
548 struct atmel_pdmic *dd = (struct atmel_pdmic *)dev_id;
549 u32 pdmic_isr;
550 irqreturn_t ret = IRQ_NONE;
551
552 regmap_read(dd->regmap, PDMIC_ISR, &pdmic_isr);
553
554 if (pdmic_isr & PDMIC_ISR_OVRE) {
555 regmap_update_bits(dd->regmap, PDMIC_CR, PDMIC_CR_ENPDM_MASK,
556 PDMIC_CR_ENPDM_DIS << PDMIC_CR_ENPDM_SHIFT);
557
558 snd_pcm_stop_xrun(dd->substream);
559
560 ret = IRQ_HANDLED;
561 }
562
563 return ret;
564}
565
566/* regmap configuration */
567#define ATMEL_PDMIC_REG_MAX 0x124
568static const struct regmap_config atmel_pdmic_regmap_config = {
569 .reg_bits = 32,
570 .reg_stride = 4,
571 .val_bits = 32,
572 .max_register = ATMEL_PDMIC_REG_MAX,
573};
574
575static int atmel_pdmic_probe(struct platform_device *pdev)
576{
577 struct device *dev = &pdev->dev;
578 struct atmel_pdmic *dd;
579 struct resource *res;
580 void __iomem *io_base;
581 const struct atmel_pdmic_pdata *pdata;
582 struct snd_soc_card *card;
583 unsigned int rate_min, rate_max;
584 int ret;
585
586 pdata = atmel_pdmic_dt_init(dev);
587 if (IS_ERR(pdata))
588 return PTR_ERR(pdata);
589
590 dd = devm_kzalloc(dev, sizeof(*dd), GFP_KERNEL);
591 if (!dd)
592 return -ENOMEM;
593
594 dd->pdata = pdata;
595
596 dd->irq = platform_get_irq(pdev, 0);
597 if (dd->irq < 0) {
598 ret = dd->irq;
599 dev_err(dev, "failed to could not get irq: %d\n", ret);
600 return ret;
601 }
602
603 dd->pclk = devm_clk_get(dev, "pclk");
604 if (IS_ERR(dd->pclk)) {
605 ret = PTR_ERR(dd->pclk);
606 dev_err(dev, "failed to get peripheral clock: %d\n", ret);
607 return ret;
608 }
609
610 dd->gclk = devm_clk_get(dev, "gclk");
611 if (IS_ERR(dd->gclk)) {
612 ret = PTR_ERR(dd->gclk);
613 dev_err(dev, "failed to get GCK: %d\n", ret);
614 return ret;
615 }
616
617 /* The gclk clock frequency must always be tree times
618 * lower than the pclk clock frequency
619 */
620 ret = clk_set_rate(dd->gclk, clk_get_rate(dd->pclk)/3);
621 if (ret) {
622 dev_err(dev, "failed to set GCK clock rate: %d\n", ret);
623 return ret;
624 }
625
626 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
627 if (!res) {
628 dev_err(dev, "no memory resource\n");
629 return -ENXIO;
630 }
631
632 io_base = devm_ioremap_resource(dev, res);
633 if (IS_ERR(io_base)) {
634 ret = PTR_ERR(io_base);
635 dev_err(dev, "failed to remap register memory: %d\n", ret);
636 return ret;
637 }
638
639 dd->phy_base = res->start;
640
641 dd->regmap = devm_regmap_init_mmio(dev, io_base,
642 &atmel_pdmic_regmap_config);
643 if (IS_ERR(dd->regmap)) {
644 ret = PTR_ERR(dd->regmap);
645 dev_err(dev, "failed to init register map: %d\n", ret);
646 return ret;
647 }
648
649 ret = devm_request_irq(dev, dd->irq, atmel_pdmic_interrupt, 0,
650 "PDMIC", (void *)dd);
651 if (ret < 0) {
652 dev_err(dev, "can't register ISR for IRQ %u (ret=%i)\n",
653 dd->irq, ret);
654 return ret;
655 }
656
657 /* Get the minimal and maximal sample rate that micphone supports */
658 atmel_pdmic_get_sample_rate(dd, &rate_min, &rate_max);
659
660 /* register cpu dai */
661 atmel_pdmic_cpu_dai.capture.rate_min = rate_min;
662 atmel_pdmic_cpu_dai.capture.rate_max = rate_max;
663 ret = devm_snd_soc_register_component(dev,
664 &atmel_pdmic_cpu_dai_component,
665 &atmel_pdmic_cpu_dai, 1);
666 if (ret) {
667 dev_err(dev, "could not register CPU DAI: %d\n", ret);
668 return ret;
669 }
670
671 /* register platform */
672 ret = devm_snd_dmaengine_pcm_register(dev,
673 &atmel_pdmic_dmaengine_pcm_config,
674 0);
675 if (ret) {
676 dev_err(dev, "could not register platform: %d\n", ret);
677 return ret;
678 }
679
680 /* register codec and codec dai */
681 atmel_pdmic_codec_dai.capture.rate_min = rate_min;
682 atmel_pdmic_codec_dai.capture.rate_max = rate_max;
683 ret = snd_soc_register_codec(dev, &soc_codec_dev_pdmic,
684 &atmel_pdmic_codec_dai, 1);
685 if (ret) {
686 dev_err(dev, "could not register codec: %d\n", ret);
687 return ret;
688 }
689
690 /* register sound card */
691 card = devm_kzalloc(dev, sizeof(*card), GFP_KERNEL);
692 if (!card) {
693 ret = -ENOMEM;
694 goto unregister_codec;
695 }
696
697 snd_soc_card_set_drvdata(card, dd);
698 platform_set_drvdata(pdev, card);
699
700 ret = atmel_pdmic_asoc_card_init(dev, card);
701 if (ret) {
702 dev_err(dev, "failed to init sound card: %d\n", ret);
703 goto unregister_codec;
704 }
705
706 ret = devm_snd_soc_register_card(dev, card);
707 if (ret) {
708 dev_err(dev, "failed to register sound card: %d\n", ret);
709 goto unregister_codec;
710 }
711
712 return 0;
713
714unregister_codec:
715 snd_soc_unregister_codec(dev);
716 return ret;
717}
718
719static int atmel_pdmic_remove(struct platform_device *pdev)
720{
721 snd_soc_unregister_codec(&pdev->dev);
722 return 0;
723}
724
725static struct platform_driver atmel_pdmic_driver = {
726 .driver = {
727 .name = "atmel-pdmic",
728 .of_match_table = of_match_ptr(atmel_pdmic_of_match),
729 .pm = &snd_soc_pm_ops,
730 },
731 .probe = atmel_pdmic_probe,
732 .remove = atmel_pdmic_remove,
733};
734module_platform_driver(atmel_pdmic_driver);
735
736MODULE_DESCRIPTION("Atmel PDMIC driver under ALSA SoC architecture");
737MODULE_AUTHOR("Songjun Wu <songjun.wu@atmel.com>");
738MODULE_LICENSE("GPL v2");
diff --git a/sound/soc/atmel/atmel-pdmic.h b/sound/soc/atmel/atmel-pdmic.h
new file mode 100644
index 000000000000..4527ac741919
--- /dev/null
+++ b/sound/soc/atmel/atmel-pdmic.h
@@ -0,0 +1,80 @@
1#ifndef __ATMEL_PDMIC_H_
2#define __ATMEL_PDMIC_H_
3
4#include <linux/bitops.h>
5
6#define PDMIC_CR 0x00000000
7
8#define PDMIC_CR_SWRST 0x1
9#define PDMIC_CR_SWRST_MASK BIT(0)
10#define PDMIC_CR_SWRST_SHIFT (0)
11
12#define PDMIC_CR_ENPDM_DIS 0x0
13#define PDMIC_CR_ENPDM_EN 0x1
14#define PDMIC_CR_ENPDM_MASK BIT(4)
15#define PDMIC_CR_ENPDM_SHIFT (4)
16
17#define PDMIC_MR 0x00000004
18
19#define PDMIC_MR_CLKS_PCK 0x0
20#define PDMIC_MR_CLKS_GCK 0x1
21#define PDMIC_MR_CLKS_MASK BIT(4)
22#define PDMIC_MR_CLKS_SHIFT (4)
23
24#define PDMIC_MR_PRESCAL_MASK GENMASK(14, 8)
25#define PDMIC_MR_PRESCAL_SHIFT (8)
26
27#define PDMIC_CDR 0x00000014
28
29#define PDMIC_IER 0x00000018
30#define PDMIC_IER_OVRE BIT(25)
31
32#define PDMIC_IDR 0x0000001c
33#define PDMIC_IDR_OVRE BIT(25)
34
35#define PDMIC_IMR 0x00000020
36
37#define PDMIC_ISR 0x00000024
38#define PDMIC_ISR_OVRE BIT(25)
39
40#define PDMIC_DSPR0 0x00000058
41
42#define PDMIC_DSPR0_HPFBYP_DIS 0x1
43#define PDMIC_DSPR0_HPFBYP_EN 0x0
44#define PDMIC_DSPR0_HPFBYP_MASK BIT(1)
45#define PDMIC_DSPR0_HPFBYP_SHIFT (1)
46
47#define PDMIC_DSPR0_SINBYP_DIS 0x1
48#define PDMIC_DSPR0_SINBYP_EN 0x0
49#define PDMIC_DSPR0_SINBYP_MASK BIT(2)
50#define PDMIC_DSPR0_SINBYP_SHIFT (2)
51
52#define PDMIC_DSPR0_SIZE_16_BITS 0x0
53#define PDMIC_DSPR0_SIZE_32_BITS 0x1
54#define PDMIC_DSPR0_SIZE_MASK BIT(3)
55#define PDMIC_DSPR0_SIZE_SHIFT (3)
56
57#define PDMIC_DSPR0_OSR_128 0x0
58#define PDMIC_DSPR0_OSR_64 0x1
59#define PDMIC_DSPR0_OSR_MASK GENMASK(6, 4)
60#define PDMIC_DSPR0_OSR_SHIFT (4)
61
62#define PDMIC_DSPR0_SCALE_MASK GENMASK(11, 8)
63#define PDMIC_DSPR0_SCALE_SHIFT (8)
64
65#define PDMIC_DSPR0_SHIFT_MASK GENMASK(15, 12)
66#define PDMIC_DSPR0_SHIFT_SHIFT (12)
67
68#define PDMIC_DSPR1 0x0000005c
69
70#define PDMIC_DSPR1_DGAIN_MASK GENMASK(14, 0)
71#define PDMIC_DSPR1_DGAIN_SHIFT (0)
72
73#define PDMIC_DSPR1_OFFSET_MASK GENMASK(31, 16)
74#define PDMIC_DSPR1_OFFSET_SHIFT (16)
75
76#define PDMIC_WPMR 0x000000e4
77
78#define PDMIC_WPSR 0x000000e8
79
80#endif
diff --git a/sound/soc/atmel/atmel_wm8904.c b/sound/soc/atmel/atmel_wm8904.c
index 1933bcd46cca..fdd28ed3e0b9 100644
--- a/sound/soc/atmel/atmel_wm8904.c
+++ b/sound/soc/atmel/atmel_wm8904.c
@@ -183,6 +183,7 @@ static struct platform_driver atmel_asoc_wm8904_driver = {
183 .driver = { 183 .driver = {
184 .name = "atmel-wm8904-audio", 184 .name = "atmel-wm8904-audio",
185 .of_match_table = of_match_ptr(atmel_asoc_wm8904_dt_ids), 185 .of_match_table = of_match_ptr(atmel_asoc_wm8904_dt_ids),
186 .pm = &snd_soc_pm_ops,
186 }, 187 },
187 .probe = atmel_asoc_wm8904_probe, 188 .probe = atmel_asoc_wm8904_probe,
188 .remove = atmel_asoc_wm8904_remove, 189 .remove = atmel_asoc_wm8904_remove,
diff --git a/sound/soc/bcm/bcm2835-i2s.c b/sound/soc/bcm/bcm2835-i2s.c
index 8c435beb263d..3303d5f58082 100644
--- a/sound/soc/bcm/bcm2835-i2s.c
+++ b/sound/soc/bcm/bcm2835-i2s.c
@@ -31,20 +31,20 @@
31 * General Public License for more details. 31 * General Public License for more details.
32 */ 32 */
33 33
34#include <linux/clk.h>
35#include <linux/delay.h>
36#include <linux/device.h>
34#include <linux/init.h> 37#include <linux/init.h>
38#include <linux/io.h>
35#include <linux/module.h> 39#include <linux/module.h>
36#include <linux/device.h>
37#include <linux/slab.h> 40#include <linux/slab.h>
38#include <linux/delay.h>
39#include <linux/io.h>
40#include <linux/clk.h>
41 41
42#include <sound/core.h> 42#include <sound/core.h>
43#include <sound/dmaengine_pcm.h>
44#include <sound/initval.h>
43#include <sound/pcm.h> 45#include <sound/pcm.h>
44#include <sound/pcm_params.h> 46#include <sound/pcm_params.h>
45#include <sound/initval.h>
46#include <sound/soc.h> 47#include <sound/soc.h>
47#include <sound/dmaengine_pcm.h>
48 48
49/* Clock registers */ 49/* Clock registers */
50#define BCM2835_CLK_PCMCTL_REG 0x00 50#define BCM2835_CLK_PCMCTL_REG 0x00
diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig
index cfdafc4c11ea..50693c867e71 100644
--- a/sound/soc/codecs/Kconfig
+++ b/sound/soc/codecs/Kconfig
@@ -55,9 +55,11 @@ config SND_SOC_ALL_CODECS
55 select SND_SOC_CS4271_SPI if SPI_MASTER 55 select SND_SOC_CS4271_SPI if SPI_MASTER
56 select SND_SOC_CS42XX8_I2C if I2C 56 select SND_SOC_CS42XX8_I2C if I2C
57 select SND_SOC_CS4349 if I2C 57 select SND_SOC_CS4349 if I2C
58 select SND_SOC_CS47L24 if MFD_CS47L24
58 select SND_SOC_CX20442 if TTY 59 select SND_SOC_CX20442 if TTY
59 select SND_SOC_DA7210 if SND_SOC_I2C_AND_SPI 60 select SND_SOC_DA7210 if SND_SOC_I2C_AND_SPI
60 select SND_SOC_DA7213 if I2C 61 select SND_SOC_DA7213 if I2C
62 select SND_SOC_DA7218 if I2C
61 select SND_SOC_DA7219 if I2C 63 select SND_SOC_DA7219 if I2C
62 select SND_SOC_DA732X if I2C 64 select SND_SOC_DA732X if I2C
63 select SND_SOC_DA9055 if I2C 65 select SND_SOC_DA9055 if I2C
@@ -66,7 +68,9 @@ config SND_SOC_ALL_CODECS
66 select SND_SOC_ES8328_SPI if SPI_MASTER 68 select SND_SOC_ES8328_SPI if SPI_MASTER
67 select SND_SOC_ES8328_I2C if I2C 69 select SND_SOC_ES8328_I2C if I2C
68 select SND_SOC_GTM601 70 select SND_SOC_GTM601
71 select SND_SOC_HDAC_HDMI
69 select SND_SOC_ICS43432 72 select SND_SOC_ICS43432
73 select SND_SOC_INNO_RK3036
70 select SND_SOC_ISABELLE if I2C 74 select SND_SOC_ISABELLE if I2C
71 select SND_SOC_JZ4740_CODEC 75 select SND_SOC_JZ4740_CODEC
72 select SND_SOC_LM4857 if I2C 76 select SND_SOC_LM4857 if I2C
@@ -83,16 +87,20 @@ config SND_SOC_ALL_CODECS
83 select SND_SOC_ML26124 if I2C 87 select SND_SOC_ML26124 if I2C
84 select SND_SOC_NAU8825 if I2C 88 select SND_SOC_NAU8825 if I2C
85 select SND_SOC_PCM1681 if I2C 89 select SND_SOC_PCM1681 if I2C
86 select SND_SOC_PCM1792A if SPI_MASTER 90 select SND_SOC_PCM179X if SPI_MASTER
87 select SND_SOC_PCM3008 91 select SND_SOC_PCM3008
92 select SND_SOC_PCM3168A_I2C if I2C
93 select SND_SOC_PCM3168A_SPI if SPI_MASTER
88 select SND_SOC_PCM512x_I2C if I2C 94 select SND_SOC_PCM512x_I2C if I2C
89 select SND_SOC_PCM512x_SPI if SPI_MASTER 95 select SND_SOC_PCM512x_SPI if SPI_MASTER
90 select SND_SOC_RT286 if I2C 96 select SND_SOC_RT286 if I2C
91 select SND_SOC_RT298 if I2C 97 select SND_SOC_RT298 if I2C
98 select SND_SOC_RT5616 if I2C
92 select SND_SOC_RT5631 if I2C 99 select SND_SOC_RT5631 if I2C
93 select SND_SOC_RT5640 if I2C 100 select SND_SOC_RT5640 if I2C
94 select SND_SOC_RT5645 if I2C 101 select SND_SOC_RT5645 if I2C
95 select SND_SOC_RT5651 if I2C 102 select SND_SOC_RT5651 if I2C
103 select SND_SOC_RT5659 if I2C
96 select SND_SOC_RT5670 if I2C 104 select SND_SOC_RT5670 if I2C
97 select SND_SOC_RT5677 if I2C && SPI_MASTER 105 select SND_SOC_RT5677 if I2C && SPI_MASTER
98 select SND_SOC_SGTL5000 if I2C 106 select SND_SOC_SGTL5000 if I2C
@@ -195,10 +203,12 @@ config SND_SOC_88PM860X
195 203
196config SND_SOC_ARIZONA 204config SND_SOC_ARIZONA
197 tristate 205 tristate
206 default y if SND_SOC_CS47L24=y
198 default y if SND_SOC_WM5102=y 207 default y if SND_SOC_WM5102=y
199 default y if SND_SOC_WM5110=y 208 default y if SND_SOC_WM5110=y
200 default y if SND_SOC_WM8997=y 209 default y if SND_SOC_WM8997=y
201 default y if SND_SOC_WM8998=y 210 default y if SND_SOC_WM8998=y
211 default m if SND_SOC_CS47L24=m
202 default m if SND_SOC_WM5102=m 212 default m if SND_SOC_WM5102=m
203 default m if SND_SOC_WM5110=m 213 default m if SND_SOC_WM5110=m
204 default m if SND_SOC_WM8997=m 214 default m if SND_SOC_WM8997=m
@@ -211,9 +221,12 @@ config SND_SOC_WM_HUBS
211 221
212config SND_SOC_WM_ADSP 222config SND_SOC_WM_ADSP
213 tristate 223 tristate
224 select SND_SOC_COMPRESS
225 default y if SND_SOC_CS47L24=y
214 default y if SND_SOC_WM5102=y 226 default y if SND_SOC_WM5102=y
215 default y if SND_SOC_WM5110=y 227 default y if SND_SOC_WM5110=y
216 default y if SND_SOC_WM2200=y 228 default y if SND_SOC_WM2200=y
229 default m if SND_SOC_CS47L24=m
217 default m if SND_SOC_WM5102=m 230 default m if SND_SOC_WM5102=m
218 default m if SND_SOC_WM5110=m 231 default m if SND_SOC_WM5110=m
219 default m if SND_SOC_WM2200=m 232 default m if SND_SOC_WM2200=m
@@ -422,6 +435,9 @@ config SND_SOC_CS4349
422 tristate "Cirrus Logic CS4349 CODEC" 435 tristate "Cirrus Logic CS4349 CODEC"
423 depends on I2C 436 depends on I2C
424 437
438config SND_SOC_CS47L24
439 tristate
440
425config SND_SOC_CX20442 441config SND_SOC_CX20442
426 tristate 442 tristate
427 depends on TTY 443 depends on TTY
@@ -439,6 +455,9 @@ config SND_SOC_DA7210
439config SND_SOC_DA7213 455config SND_SOC_DA7213
440 tristate 456 tristate
441 457
458config SND_SOC_DA7218
459 tristate
460
442config SND_SOC_DA7219 461config SND_SOC_DA7219
443 tristate 462 tristate
444 463
@@ -468,9 +487,17 @@ config SND_SOC_ES8328_SPI
468config SND_SOC_GTM601 487config SND_SOC_GTM601
469 tristate 'GTM601 UMTS modem audio codec' 488 tristate 'GTM601 UMTS modem audio codec'
470 489
490config SND_SOC_HDAC_HDMI
491 tristate
492 select SND_HDA_EXT_CORE
493 select HDMI
494
471config SND_SOC_ICS43432 495config SND_SOC_ICS43432
472 tristate 496 tristate
473 497
498config SND_SOC_INNO_RK3036
499 tristate "Inno codec driver for RK3036 SoC"
500
474config SND_SOC_ISABELLE 501config SND_SOC_ISABELLE
475 tristate 502 tristate
476 503
@@ -499,13 +526,28 @@ config SND_SOC_PCM1681
499 tristate "Texas Instruments PCM1681 CODEC" 526 tristate "Texas Instruments PCM1681 CODEC"
500 depends on I2C 527 depends on I2C
501 528
502config SND_SOC_PCM1792A 529config SND_SOC_PCM179X
503 tristate "Texas Instruments PCM1792A CODEC" 530 tristate "Texas Instruments PCM179X CODEC"
504 depends on SPI_MASTER 531 depends on SPI_MASTER
505 532
506config SND_SOC_PCM3008 533config SND_SOC_PCM3008
507 tristate 534 tristate
508 535
536config SND_SOC_PCM3168A
537 tristate
538
539config SND_SOC_PCM3168A_I2C
540 tristate "Texas Instruments PCM3168A CODEC - I2C"
541 depends on I2C
542 select SND_SOC_PCM3168A
543 select REGMAP_I2C
544
545config SND_SOC_PCM3168A_SPI
546 tristate "Texas Instruments PCM3168A CODEC - SPI"
547 depends on SPI_MASTER
548 select SND_SOC_PCM3168A
549 select REGMAP_SPI
550
509config SND_SOC_PCM512x 551config SND_SOC_PCM512x
510 tristate 552 tristate
511 553
@@ -523,14 +565,18 @@ config SND_SOC_PCM512x_SPI
523 565
524config SND_SOC_RL6231 566config SND_SOC_RL6231
525 tristate 567 tristate
568 default y if SND_SOC_RT5616=y
526 default y if SND_SOC_RT5640=y 569 default y if SND_SOC_RT5640=y
527 default y if SND_SOC_RT5645=y 570 default y if SND_SOC_RT5645=y
528 default y if SND_SOC_RT5651=y 571 default y if SND_SOC_RT5651=y
572 default y if SND_SOC_RT5659=y
529 default y if SND_SOC_RT5670=y 573 default y if SND_SOC_RT5670=y
530 default y if SND_SOC_RT5677=y 574 default y if SND_SOC_RT5677=y
575 default m if SND_SOC_RT5616=m
531 default m if SND_SOC_RT5640=m 576 default m if SND_SOC_RT5640=m
532 default m if SND_SOC_RT5645=m 577 default m if SND_SOC_RT5645=m
533 default m if SND_SOC_RT5651=m 578 default m if SND_SOC_RT5651=m
579 default m if SND_SOC_RT5659=m
534 default m if SND_SOC_RT5670=m 580 default m if SND_SOC_RT5670=m
535 default m if SND_SOC_RT5677=m 581 default m if SND_SOC_RT5677=m
536 582
@@ -549,6 +595,9 @@ config SND_SOC_RT298
549 tristate 595 tristate
550 depends on I2C 596 depends on I2C
551 597
598config SND_SOC_RT5616
599 tristate
600
552config SND_SOC_RT5631 601config SND_SOC_RT5631
553 tristate "Realtek ALC5631/RT5631 CODEC" 602 tristate "Realtek ALC5631/RT5631 CODEC"
554 depends on I2C 603 depends on I2C
@@ -562,6 +611,9 @@ config SND_SOC_RT5645
562config SND_SOC_RT5651 611config SND_SOC_RT5651
563 tristate 612 tristate
564 613
614config SND_SOC_RT5659
615 tristate
616
565config SND_SOC_RT5670 617config SND_SOC_RT5670
566 tristate 618 tristate
567 619
@@ -838,7 +890,8 @@ config SND_SOC_WM8971
838 tristate 890 tristate
839 891
840config SND_SOC_WM8974 892config SND_SOC_WM8974
841 tristate 893 tristate "Wolfson Microelectronics WM8974 codec"
894 depends on I2C
842 895
843config SND_SOC_WM8978 896config SND_SOC_WM8978
844 tristate "Wolfson Microelectronics WM8978 codec" 897 tristate "Wolfson Microelectronics WM8978 codec"
@@ -891,6 +944,7 @@ config SND_SOC_WM9712
891 944
892config SND_SOC_WM9713 945config SND_SOC_WM9713
893 tristate 946 tristate
947 select REGMAP_AC97
894 948
895# Amp 949# Amp
896config SND_SOC_LM4857 950config SND_SOC_LM4857
diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile
index f632fc42f59f..d44f7d347183 100644
--- a/sound/soc/codecs/Makefile
+++ b/sound/soc/codecs/Makefile
@@ -47,9 +47,11 @@ snd-soc-cs4271-spi-objs := cs4271-spi.o
47snd-soc-cs42xx8-objs := cs42xx8.o 47snd-soc-cs42xx8-objs := cs42xx8.o
48snd-soc-cs42xx8-i2c-objs := cs42xx8-i2c.o 48snd-soc-cs42xx8-i2c-objs := cs42xx8-i2c.o
49snd-soc-cs4349-objs := cs4349.o 49snd-soc-cs4349-objs := cs4349.o
50snd-soc-cs47l24-objs := cs47l24.o
50snd-soc-cx20442-objs := cx20442.o 51snd-soc-cx20442-objs := cx20442.o
51snd-soc-da7210-objs := da7210.o 52snd-soc-da7210-objs := da7210.o
52snd-soc-da7213-objs := da7213.o 53snd-soc-da7213-objs := da7213.o
54snd-soc-da7218-objs := da7218.o
53snd-soc-da7219-objs := da7219.o da7219-aad.o 55snd-soc-da7219-objs := da7219.o da7219-aad.o
54snd-soc-da732x-objs := da732x.o 56snd-soc-da732x-objs := da732x.o
55snd-soc-da9055-objs := da9055.o 57snd-soc-da9055-objs := da9055.o
@@ -59,7 +61,9 @@ snd-soc-es8328-objs := es8328.o
59snd-soc-es8328-i2c-objs := es8328-i2c.o 61snd-soc-es8328-i2c-objs := es8328-i2c.o
60snd-soc-es8328-spi-objs := es8328-spi.o 62snd-soc-es8328-spi-objs := es8328-spi.o
61snd-soc-gtm601-objs := gtm601.o 63snd-soc-gtm601-objs := gtm601.o
64snd-soc-hdac-hdmi-objs := hdac_hdmi.o
62snd-soc-ics43432-objs := ics43432.o 65snd-soc-ics43432-objs := ics43432.o
66snd-soc-inno-rk3036-objs := inno_rk3036.o
63snd-soc-isabelle-objs := isabelle.o 67snd-soc-isabelle-objs := isabelle.o
64snd-soc-jz4740-codec-objs := jz4740.o 68snd-soc-jz4740-codec-objs := jz4740.o
65snd-soc-l3-objs := l3.o 69snd-soc-l3-objs := l3.o
@@ -76,8 +80,11 @@ snd-soc-mc13783-objs := mc13783.o
76snd-soc-ml26124-objs := ml26124.o 80snd-soc-ml26124-objs := ml26124.o
77snd-soc-nau8825-objs := nau8825.o 81snd-soc-nau8825-objs := nau8825.o
78snd-soc-pcm1681-objs := pcm1681.o 82snd-soc-pcm1681-objs := pcm1681.o
79snd-soc-pcm1792a-codec-objs := pcm1792a.o 83snd-soc-pcm179x-codec-objs := pcm179x.o
80snd-soc-pcm3008-objs := pcm3008.o 84snd-soc-pcm3008-objs := pcm3008.o
85snd-soc-pcm3168a-objs := pcm3168a.o
86snd-soc-pcm3168a-i2c-objs := pcm3168a-i2c.o
87snd-soc-pcm3168a-spi-objs := pcm3168a-spi.o
81snd-soc-pcm512x-objs := pcm512x.o 88snd-soc-pcm512x-objs := pcm512x.o
82snd-soc-pcm512x-i2c-objs := pcm512x-i2c.o 89snd-soc-pcm512x-i2c-objs := pcm512x-i2c.o
83snd-soc-pcm512x-spi-objs := pcm512x-spi.o 90snd-soc-pcm512x-spi-objs := pcm512x-spi.o
@@ -85,10 +92,12 @@ snd-soc-rl6231-objs := rl6231.o
85snd-soc-rl6347a-objs := rl6347a.o 92snd-soc-rl6347a-objs := rl6347a.o
86snd-soc-rt286-objs := rt286.o 93snd-soc-rt286-objs := rt286.o
87snd-soc-rt298-objs := rt298.o 94snd-soc-rt298-objs := rt298.o
95snd-soc-rt5616-objs := rt5616.o
88snd-soc-rt5631-objs := rt5631.o 96snd-soc-rt5631-objs := rt5631.o
89snd-soc-rt5640-objs := rt5640.o 97snd-soc-rt5640-objs := rt5640.o
90snd-soc-rt5645-objs := rt5645.o 98snd-soc-rt5645-objs := rt5645.o
91snd-soc-rt5651-objs := rt5651.o 99snd-soc-rt5651-objs := rt5651.o
100snd-soc-rt5659-objs := rt5659.o
92snd-soc-rt5670-objs := rt5670.o 101snd-soc-rt5670-objs := rt5670.o
93snd-soc-rt5677-objs := rt5677.o 102snd-soc-rt5677-objs := rt5677.o
94snd-soc-rt5677-spi-objs := rt5677-spi.o 103snd-soc-rt5677-spi-objs := rt5677-spi.o
@@ -242,9 +251,11 @@ obj-$(CONFIG_SND_SOC_CS4271_SPI) += snd-soc-cs4271-spi.o
242obj-$(CONFIG_SND_SOC_CS42XX8) += snd-soc-cs42xx8.o 251obj-$(CONFIG_SND_SOC_CS42XX8) += snd-soc-cs42xx8.o
243obj-$(CONFIG_SND_SOC_CS42XX8_I2C) += snd-soc-cs42xx8-i2c.o 252obj-$(CONFIG_SND_SOC_CS42XX8_I2C) += snd-soc-cs42xx8-i2c.o
244obj-$(CONFIG_SND_SOC_CS4349) += snd-soc-cs4349.o 253obj-$(CONFIG_SND_SOC_CS4349) += snd-soc-cs4349.o
254obj-$(CONFIG_SND_SOC_CS47L24) += snd-soc-cs47l24.o
245obj-$(CONFIG_SND_SOC_CX20442) += snd-soc-cx20442.o 255obj-$(CONFIG_SND_SOC_CX20442) += snd-soc-cx20442.o
246obj-$(CONFIG_SND_SOC_DA7210) += snd-soc-da7210.o 256obj-$(CONFIG_SND_SOC_DA7210) += snd-soc-da7210.o
247obj-$(CONFIG_SND_SOC_DA7213) += snd-soc-da7213.o 257obj-$(CONFIG_SND_SOC_DA7213) += snd-soc-da7213.o
258obj-$(CONFIG_SND_SOC_DA7218) += snd-soc-da7218.o
248obj-$(CONFIG_SND_SOC_DA7219) += snd-soc-da7219.o 259obj-$(CONFIG_SND_SOC_DA7219) += snd-soc-da7219.o
249obj-$(CONFIG_SND_SOC_DA732X) += snd-soc-da732x.o 260obj-$(CONFIG_SND_SOC_DA732X) += snd-soc-da732x.o
250obj-$(CONFIG_SND_SOC_DA9055) += snd-soc-da9055.o 261obj-$(CONFIG_SND_SOC_DA9055) += snd-soc-da9055.o
@@ -254,7 +265,9 @@ obj-$(CONFIG_SND_SOC_ES8328) += snd-soc-es8328.o
254obj-$(CONFIG_SND_SOC_ES8328_I2C)+= snd-soc-es8328-i2c.o 265obj-$(CONFIG_SND_SOC_ES8328_I2C)+= snd-soc-es8328-i2c.o
255obj-$(CONFIG_SND_SOC_ES8328_SPI)+= snd-soc-es8328-spi.o 266obj-$(CONFIG_SND_SOC_ES8328_SPI)+= snd-soc-es8328-spi.o
256obj-$(CONFIG_SND_SOC_GTM601) += snd-soc-gtm601.o 267obj-$(CONFIG_SND_SOC_GTM601) += snd-soc-gtm601.o
268obj-$(CONFIG_SND_SOC_HDAC_HDMI) += snd-soc-hdac-hdmi.o
257obj-$(CONFIG_SND_SOC_ICS43432) += snd-soc-ics43432.o 269obj-$(CONFIG_SND_SOC_ICS43432) += snd-soc-ics43432.o
270obj-$(CONFIG_SND_SOC_INNO_RK3036) += snd-soc-inno-rk3036.o
258obj-$(CONFIG_SND_SOC_ISABELLE) += snd-soc-isabelle.o 271obj-$(CONFIG_SND_SOC_ISABELLE) += snd-soc-isabelle.o
259obj-$(CONFIG_SND_SOC_JZ4740_CODEC) += snd-soc-jz4740-codec.o 272obj-$(CONFIG_SND_SOC_JZ4740_CODEC) += snd-soc-jz4740-codec.o
260obj-$(CONFIG_SND_SOC_L3) += snd-soc-l3.o 273obj-$(CONFIG_SND_SOC_L3) += snd-soc-l3.o
@@ -271,8 +284,11 @@ obj-$(CONFIG_SND_SOC_MC13783) += snd-soc-mc13783.o
271obj-$(CONFIG_SND_SOC_ML26124) += snd-soc-ml26124.o 284obj-$(CONFIG_SND_SOC_ML26124) += snd-soc-ml26124.o
272obj-$(CONFIG_SND_SOC_NAU8825) += snd-soc-nau8825.o 285obj-$(CONFIG_SND_SOC_NAU8825) += snd-soc-nau8825.o
273obj-$(CONFIG_SND_SOC_PCM1681) += snd-soc-pcm1681.o 286obj-$(CONFIG_SND_SOC_PCM1681) += snd-soc-pcm1681.o
274obj-$(CONFIG_SND_SOC_PCM1792A) += snd-soc-pcm1792a-codec.o 287obj-$(CONFIG_SND_SOC_PCM179X) += snd-soc-pcm179x-codec.o
275obj-$(CONFIG_SND_SOC_PCM3008) += snd-soc-pcm3008.o 288obj-$(CONFIG_SND_SOC_PCM3008) += snd-soc-pcm3008.o
289obj-$(CONFIG_SND_SOC_PCM3168A) += snd-soc-pcm3168a.o
290obj-$(CONFIG_SND_SOC_PCM3168A_I2C) += snd-soc-pcm3168a-i2c.o
291obj-$(CONFIG_SND_SOC_PCM3168A_SPI) += snd-soc-pcm3168a-spi.o
276obj-$(CONFIG_SND_SOC_PCM512x) += snd-soc-pcm512x.o 292obj-$(CONFIG_SND_SOC_PCM512x) += snd-soc-pcm512x.o
277obj-$(CONFIG_SND_SOC_PCM512x_I2C) += snd-soc-pcm512x-i2c.o 293obj-$(CONFIG_SND_SOC_PCM512x_I2C) += snd-soc-pcm512x-i2c.o
278obj-$(CONFIG_SND_SOC_PCM512x_SPI) += snd-soc-pcm512x-spi.o 294obj-$(CONFIG_SND_SOC_PCM512x_SPI) += snd-soc-pcm512x-spi.o
@@ -280,10 +296,12 @@ obj-$(CONFIG_SND_SOC_RL6231) += snd-soc-rl6231.o
280obj-$(CONFIG_SND_SOC_RL6347A) += snd-soc-rl6347a.o 296obj-$(CONFIG_SND_SOC_RL6347A) += snd-soc-rl6347a.o
281obj-$(CONFIG_SND_SOC_RT286) += snd-soc-rt286.o 297obj-$(CONFIG_SND_SOC_RT286) += snd-soc-rt286.o
282obj-$(CONFIG_SND_SOC_RT298) += snd-soc-rt298.o 298obj-$(CONFIG_SND_SOC_RT298) += snd-soc-rt298.o
299obj-$(CONFIG_SND_SOC_RT5616) += snd-soc-rt5616.o
283obj-$(CONFIG_SND_SOC_RT5631) += snd-soc-rt5631.o 300obj-$(CONFIG_SND_SOC_RT5631) += snd-soc-rt5631.o
284obj-$(CONFIG_SND_SOC_RT5640) += snd-soc-rt5640.o 301obj-$(CONFIG_SND_SOC_RT5640) += snd-soc-rt5640.o
285obj-$(CONFIG_SND_SOC_RT5645) += snd-soc-rt5645.o 302obj-$(CONFIG_SND_SOC_RT5645) += snd-soc-rt5645.o
286obj-$(CONFIG_SND_SOC_RT5651) += snd-soc-rt5651.o 303obj-$(CONFIG_SND_SOC_RT5651) += snd-soc-rt5651.o
304obj-$(CONFIG_SND_SOC_RT5659) += snd-soc-rt5659.o
287obj-$(CONFIG_SND_SOC_RT5670) += snd-soc-rt5670.o 305obj-$(CONFIG_SND_SOC_RT5670) += snd-soc-rt5670.o
288obj-$(CONFIG_SND_SOC_RT5677) += snd-soc-rt5677.o 306obj-$(CONFIG_SND_SOC_RT5677) += snd-soc-rt5677.o
289obj-$(CONFIG_SND_SOC_RT5677_SPI) += snd-soc-rt5677-spi.o 307obj-$(CONFIG_SND_SOC_RT5677_SPI) += snd-soc-rt5677-spi.o
diff --git a/sound/soc/codecs/ak4613.c b/sound/soc/codecs/ak4613.c
index 07a266460ec3..647f69de6baa 100644
--- a/sound/soc/codecs/ak4613.c
+++ b/sound/soc/codecs/ak4613.c
@@ -70,18 +70,11 @@
70#define FMT_MASK (0xf8) 70#define FMT_MASK (0xf8)
71 71
72/* CTRL2 */ 72/* CTRL2 */
73#define DFS_MASK (3 << 2)
73#define DFS_NORMAL_SPEED (0 << 2) 74#define DFS_NORMAL_SPEED (0 << 2)
74#define DFS_DOUBLE_SPEED (1 << 2) 75#define DFS_DOUBLE_SPEED (1 << 2)
75#define DFS_QUAD_SPEED (2 << 2) 76#define DFS_QUAD_SPEED (2 << 2)
76 77
77struct ak4613_priv {
78 struct mutex lock;
79
80 unsigned int fmt;
81 u8 fmt_ctrl;
82 int cnt;
83};
84
85struct ak4613_formats { 78struct ak4613_formats {
86 unsigned int width; 79 unsigned int width;
87 unsigned int fmt; 80 unsigned int fmt;
@@ -92,6 +85,16 @@ struct ak4613_interface {
92 struct ak4613_formats playback; 85 struct ak4613_formats playback;
93}; 86};
94 87
88struct ak4613_priv {
89 struct mutex lock;
90 const struct ak4613_interface *iface;
91
92 unsigned int fmt;
93 u8 oc;
94 u8 ic;
95 int cnt;
96};
97
95/* 98/*
96 * Playback Volume 99 * Playback Volume
97 * 100 *
@@ -126,7 +129,7 @@ static const struct reg_default ak4613_reg[] = {
126 { 0x14, 0x00 }, { 0x15, 0x00 }, { 0x16, 0x00 }, 129 { 0x14, 0x00 }, { 0x15, 0x00 }, { 0x16, 0x00 },
127}; 130};
128 131
129#define AUDIO_IFACE_IDX_TO_VAL(i) (i << 3) 132#define AUDIO_IFACE_TO_VAL(fmts) ((fmts - ak4613_iface) << 3)
130#define AUDIO_IFACE(b, fmt) { b, SND_SOC_DAIFMT_##fmt } 133#define AUDIO_IFACE(b, fmt) { b, SND_SOC_DAIFMT_##fmt }
131static const struct ak4613_interface ak4613_iface[] = { 134static const struct ak4613_interface ak4613_iface[] = {
132 /* capture */ /* playback */ 135 /* capture */ /* playback */
@@ -240,7 +243,7 @@ static void ak4613_dai_shutdown(struct snd_pcm_substream *substream,
240 priv->cnt = 0; 243 priv->cnt = 0;
241 } 244 }
242 if (!priv->cnt) 245 if (!priv->cnt)
243 priv->fmt_ctrl = NO_FMT; 246 priv->iface = NULL;
244 mutex_unlock(&priv->lock); 247 mutex_unlock(&priv->lock);
245} 248}
246 249
@@ -265,13 +268,35 @@ static int ak4613_dai_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
265 return 0; 268 return 0;
266} 269}
267 270
271static bool ak4613_dai_fmt_matching(const struct ak4613_interface *iface,
272 int is_play,
273 unsigned int fmt, unsigned int width)
274{
275 const struct ak4613_formats *fmts;
276
277 fmts = (is_play) ? &iface->playback : &iface->capture;
278
279 if (fmts->fmt != fmt)
280 return false;
281
282 if (fmt == SND_SOC_DAIFMT_RIGHT_J) {
283 if (fmts->width != width)
284 return false;
285 } else {
286 if (fmts->width < width)
287 return false;
288 }
289
290 return true;
291}
292
268static int ak4613_dai_hw_params(struct snd_pcm_substream *substream, 293static int ak4613_dai_hw_params(struct snd_pcm_substream *substream,
269 struct snd_pcm_hw_params *params, 294 struct snd_pcm_hw_params *params,
270 struct snd_soc_dai *dai) 295 struct snd_soc_dai *dai)
271{ 296{
272 struct snd_soc_codec *codec = dai->codec; 297 struct snd_soc_codec *codec = dai->codec;
273 struct ak4613_priv *priv = snd_soc_codec_get_drvdata(codec); 298 struct ak4613_priv *priv = snd_soc_codec_get_drvdata(codec);
274 const struct ak4613_formats *fmts; 299 const struct ak4613_interface *iface;
275 struct device *dev = codec->dev; 300 struct device *dev = codec->dev;
276 unsigned int width = params_width(params); 301 unsigned int width = params_width(params);
277 unsigned int fmt = priv->fmt; 302 unsigned int fmt = priv->fmt;
@@ -305,33 +330,27 @@ static int ak4613_dai_hw_params(struct snd_pcm_substream *substream,
305 * It doesn't support TDM at this point 330 * It doesn't support TDM at this point
306 */ 331 */
307 fmt_ctrl = NO_FMT; 332 fmt_ctrl = NO_FMT;
308 for (i = 0; i < ARRAY_SIZE(ak4613_iface); i++) { 333 ret = -EINVAL;
309 fmts = (is_play) ? &ak4613_iface[i].playback : 334 iface = NULL;
310 &ak4613_iface[i].capture;
311
312 if (fmts->fmt != fmt)
313 continue;
314 335
315 if (fmt == SND_SOC_DAIFMT_RIGHT_J) { 336 mutex_lock(&priv->lock);
316 if (fmts->width != width) 337 if (priv->iface) {
317 continue; 338 if (ak4613_dai_fmt_matching(priv->iface, is_play, fmt, width))
318 } else { 339 iface = priv->iface;
319 if (fmts->width < width) 340 } else {
341 for (i = ARRAY_SIZE(ak4613_iface); i >= 0; i--) {
342 if (!ak4613_dai_fmt_matching(ak4613_iface + i,
343 is_play,
344 fmt, width))
320 continue; 345 continue;
346 iface = ak4613_iface + i;
347 break;
321 } 348 }
322
323 fmt_ctrl = AUDIO_IFACE_IDX_TO_VAL(i);
324 break;
325 } 349 }
326 350
327 ret = -EINVAL; 351 if ((priv->iface == NULL) ||
328 if (fmt_ctrl == NO_FMT) 352 (priv->iface == iface)) {
329 goto hw_params_end; 353 priv->iface = iface;
330
331 mutex_lock(&priv->lock);
332 if ((priv->fmt_ctrl == NO_FMT) ||
333 (priv->fmt_ctrl == fmt_ctrl)) {
334 priv->fmt_ctrl = fmt_ctrl;
335 priv->cnt++; 354 priv->cnt++;
336 ret = 0; 355 ret = 0;
337 } 356 }
@@ -340,8 +359,13 @@ static int ak4613_dai_hw_params(struct snd_pcm_substream *substream,
340 if (ret < 0) 359 if (ret < 0)
341 goto hw_params_end; 360 goto hw_params_end;
342 361
362 fmt_ctrl = AUDIO_IFACE_TO_VAL(iface);
363
343 snd_soc_update_bits(codec, CTRL1, FMT_MASK, fmt_ctrl); 364 snd_soc_update_bits(codec, CTRL1, FMT_MASK, fmt_ctrl);
344 snd_soc_write(codec, CTRL2, ctrl2); 365 snd_soc_update_bits(codec, CTRL2, DFS_MASK, ctrl2);
366
367 snd_soc_write(codec, ICTRL, priv->ic);
368 snd_soc_write(codec, OCTRL, priv->oc);
345 369
346hw_params_end: 370hw_params_end:
347 if (ret < 0) 371 if (ret < 0)
@@ -431,6 +455,28 @@ static struct snd_soc_codec_driver soc_codec_dev_ak4613 = {
431 .num_dapm_routes = ARRAY_SIZE(ak4613_intercon), 455 .num_dapm_routes = ARRAY_SIZE(ak4613_intercon),
432}; 456};
433 457
458static void ak4613_parse_of(struct ak4613_priv *priv,
459 struct device *dev)
460{
461 struct device_node *np = dev->of_node;
462 char prop[32];
463 int i;
464
465 /* Input 1 - 2 */
466 for (i = 0; i < 2; i++) {
467 snprintf(prop, sizeof(prop), "asahi-kasei,in%d-single-end", i + 1);
468 if (!of_get_property(np, prop, NULL))
469 priv->ic |= 1 << i;
470 }
471
472 /* Output 1 - 6 */
473 for (i = 0; i < 6; i++) {
474 snprintf(prop, sizeof(prop), "asahi-kasei,out%d-single-end", i + 1);
475 if (!of_get_property(np, prop, NULL))
476 priv->oc |= 1 << i;
477 }
478}
479
434static int ak4613_i2c_probe(struct i2c_client *i2c, 480static int ak4613_i2c_probe(struct i2c_client *i2c,
435 const struct i2c_device_id *id) 481 const struct i2c_device_id *id)
436{ 482{
@@ -458,7 +504,9 @@ static int ak4613_i2c_probe(struct i2c_client *i2c,
458 if (!priv) 504 if (!priv)
459 return -ENOMEM; 505 return -ENOMEM;
460 506
461 priv->fmt_ctrl = NO_FMT; 507 ak4613_parse_of(priv, dev);
508
509 priv->iface = NULL;
462 priv->cnt = 0; 510 priv->cnt = 0;
463 511
464 mutex_init(&priv->lock); 512 mutex_init(&priv->lock);
diff --git a/sound/soc/codecs/arizona.c b/sound/soc/codecs/arizona.c
index 93b400800905..33143fe1de0b 100644
--- a/sound/soc/codecs/arizona.c
+++ b/sound/soc/codecs/arizona.c
@@ -310,7 +310,7 @@ int arizona_init_gpio(struct snd_soc_codec *codec)
310} 310}
311EXPORT_SYMBOL_GPL(arizona_init_gpio); 311EXPORT_SYMBOL_GPL(arizona_init_gpio);
312 312
313const char *arizona_mixer_texts[ARIZONA_NUM_MIXER_INPUTS] = { 313const char * const arizona_mixer_texts[ARIZONA_NUM_MIXER_INPUTS] = {
314 "None", 314 "None",
315 "Tone Generator 1", 315 "Tone Generator 1",
316 "Tone Generator 2", 316 "Tone Generator 2",
@@ -418,7 +418,7 @@ const char *arizona_mixer_texts[ARIZONA_NUM_MIXER_INPUTS] = {
418}; 418};
419EXPORT_SYMBOL_GPL(arizona_mixer_texts); 419EXPORT_SYMBOL_GPL(arizona_mixer_texts);
420 420
421int arizona_mixer_values[ARIZONA_NUM_MIXER_INPUTS] = { 421unsigned int arizona_mixer_values[ARIZONA_NUM_MIXER_INPUTS] = {
422 0x00, /* None */ 422 0x00, /* None */
423 0x04, /* Tone */ 423 0x04, /* Tone */
424 0x05, 424 0x05,
@@ -555,12 +555,12 @@ const char *arizona_sample_rate_val_to_name(unsigned int rate_val)
555} 555}
556EXPORT_SYMBOL_GPL(arizona_sample_rate_val_to_name); 556EXPORT_SYMBOL_GPL(arizona_sample_rate_val_to_name);
557 557
558const char *arizona_rate_text[ARIZONA_RATE_ENUM_SIZE] = { 558const char * const arizona_rate_text[ARIZONA_RATE_ENUM_SIZE] = {
559 "SYNCCLK rate", "8kHz", "16kHz", "ASYNCCLK rate", 559 "SYNCCLK rate", "8kHz", "16kHz", "ASYNCCLK rate",
560}; 560};
561EXPORT_SYMBOL_GPL(arizona_rate_text); 561EXPORT_SYMBOL_GPL(arizona_rate_text);
562 562
563const int arizona_rate_val[ARIZONA_RATE_ENUM_SIZE] = { 563const unsigned int arizona_rate_val[ARIZONA_RATE_ENUM_SIZE] = {
564 0, 1, 2, 8, 564 0, 1, 2, 8,
565}; 565};
566EXPORT_SYMBOL_GPL(arizona_rate_val); 566EXPORT_SYMBOL_GPL(arizona_rate_val);
@@ -702,6 +702,100 @@ const struct soc_enum arizona_in_dmic_osr[] = {
702}; 702};
703EXPORT_SYMBOL_GPL(arizona_in_dmic_osr); 703EXPORT_SYMBOL_GPL(arizona_in_dmic_osr);
704 704
705static const char * const arizona_anc_input_src_text[] = {
706 "None", "IN1", "IN2", "IN3", "IN4",
707};
708
709static const char * const arizona_anc_channel_src_text[] = {
710 "None", "Left", "Right", "Combine",
711};
712
713const struct soc_enum arizona_anc_input_src[] = {
714 SOC_ENUM_SINGLE(ARIZONA_ANC_SRC,
715 ARIZONA_IN_RXANCL_SEL_SHIFT,
716 ARRAY_SIZE(arizona_anc_input_src_text),
717 arizona_anc_input_src_text),
718 SOC_ENUM_SINGLE(ARIZONA_FCL_ADC_REFORMATTER_CONTROL,
719 ARIZONA_FCL_MIC_MODE_SEL,
720 ARRAY_SIZE(arizona_anc_channel_src_text),
721 arizona_anc_channel_src_text),
722 SOC_ENUM_SINGLE(ARIZONA_ANC_SRC,
723 ARIZONA_IN_RXANCR_SEL_SHIFT,
724 ARRAY_SIZE(arizona_anc_input_src_text),
725 arizona_anc_input_src_text),
726 SOC_ENUM_SINGLE(ARIZONA_FCR_ADC_REFORMATTER_CONTROL,
727 ARIZONA_FCR_MIC_MODE_SEL,
728 ARRAY_SIZE(arizona_anc_channel_src_text),
729 arizona_anc_channel_src_text),
730};
731EXPORT_SYMBOL_GPL(arizona_anc_input_src);
732
733static const char * const arizona_anc_ng_texts[] = {
734 "None",
735 "Internal",
736 "External",
737};
738
739SOC_ENUM_SINGLE_DECL(arizona_anc_ng_enum, SND_SOC_NOPM, 0,
740 arizona_anc_ng_texts);
741EXPORT_SYMBOL_GPL(arizona_anc_ng_enum);
742
743static const char * const arizona_output_anc_src_text[] = {
744 "None", "RXANCL", "RXANCR",
745};
746
747const struct soc_enum arizona_output_anc_src[] = {
748 SOC_ENUM_SINGLE(ARIZONA_OUTPUT_PATH_CONFIG_1L,
749 ARIZONA_OUT1L_ANC_SRC_SHIFT,
750 ARRAY_SIZE(arizona_output_anc_src_text),
751 arizona_output_anc_src_text),
752 SOC_ENUM_SINGLE(ARIZONA_OUTPUT_PATH_CONFIG_1R,
753 ARIZONA_OUT1R_ANC_SRC_SHIFT,
754 ARRAY_SIZE(arizona_output_anc_src_text),
755 arizona_output_anc_src_text),
756 SOC_ENUM_SINGLE(ARIZONA_OUTPUT_PATH_CONFIG_2L,
757 ARIZONA_OUT2L_ANC_SRC_SHIFT,
758 ARRAY_SIZE(arizona_output_anc_src_text),
759 arizona_output_anc_src_text),
760 SOC_ENUM_SINGLE(ARIZONA_OUTPUT_PATH_CONFIG_2R,
761 ARIZONA_OUT2R_ANC_SRC_SHIFT,
762 ARRAY_SIZE(arizona_output_anc_src_text),
763 arizona_output_anc_src_text),
764 SOC_ENUM_SINGLE(ARIZONA_OUTPUT_PATH_CONFIG_3L,
765 ARIZONA_OUT3L_ANC_SRC_SHIFT,
766 ARRAY_SIZE(arizona_output_anc_src_text),
767 arizona_output_anc_src_text),
768 SOC_ENUM_SINGLE(ARIZONA_DAC_VOLUME_LIMIT_3R,
769 ARIZONA_OUT3R_ANC_SRC_SHIFT,
770 ARRAY_SIZE(arizona_output_anc_src_text),
771 arizona_output_anc_src_text),
772 SOC_ENUM_SINGLE(ARIZONA_OUTPUT_PATH_CONFIG_4L,
773 ARIZONA_OUT4L_ANC_SRC_SHIFT,
774 ARRAY_SIZE(arizona_output_anc_src_text),
775 arizona_output_anc_src_text),
776 SOC_ENUM_SINGLE(ARIZONA_OUTPUT_PATH_CONFIG_4R,
777 ARIZONA_OUT4R_ANC_SRC_SHIFT,
778 ARRAY_SIZE(arizona_output_anc_src_text),
779 arizona_output_anc_src_text),
780 SOC_ENUM_SINGLE(ARIZONA_OUTPUT_PATH_CONFIG_5L,
781 ARIZONA_OUT5L_ANC_SRC_SHIFT,
782 ARRAY_SIZE(arizona_output_anc_src_text),
783 arizona_output_anc_src_text),
784 SOC_ENUM_SINGLE(ARIZONA_OUTPUT_PATH_CONFIG_5R,
785 ARIZONA_OUT5R_ANC_SRC_SHIFT,
786 ARRAY_SIZE(arizona_output_anc_src_text),
787 arizona_output_anc_src_text),
788 SOC_ENUM_SINGLE(ARIZONA_OUTPUT_PATH_CONFIG_6L,
789 ARIZONA_OUT6L_ANC_SRC_SHIFT,
790 ARRAY_SIZE(arizona_output_anc_src_text),
791 arizona_output_anc_src_text),
792 SOC_ENUM_SINGLE(ARIZONA_OUTPUT_PATH_CONFIG_6R,
793 ARIZONA_OUT6R_ANC_SRC_SHIFT,
794 ARRAY_SIZE(arizona_output_anc_src_text),
795 arizona_output_anc_src_text),
796};
797EXPORT_SYMBOL_GPL(arizona_output_anc_src);
798
705static void arizona_in_set_vu(struct snd_soc_codec *codec, int ena) 799static void arizona_in_set_vu(struct snd_soc_codec *codec, int ena)
706{ 800{
707 struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec); 801 struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
@@ -1023,6 +1117,31 @@ void arizona_init_dvfs(struct arizona_priv *priv)
1023} 1117}
1024EXPORT_SYMBOL_GPL(arizona_init_dvfs); 1118EXPORT_SYMBOL_GPL(arizona_init_dvfs);
1025 1119
1120int arizona_anc_ev(struct snd_soc_dapm_widget *w,
1121 struct snd_kcontrol *kcontrol,
1122 int event)
1123{
1124 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
1125 unsigned int mask = 0x3 << w->shift;
1126 unsigned int val;
1127
1128 switch (event) {
1129 case SND_SOC_DAPM_POST_PMU:
1130 val = 1 << w->shift;
1131 break;
1132 case SND_SOC_DAPM_PRE_PMD:
1133 val = 1 << (w->shift + 1);
1134 break;
1135 default:
1136 return 0;
1137 }
1138
1139 snd_soc_update_bits(codec, ARIZONA_CLOCK_CONTROL, mask, val);
1140
1141 return 0;
1142}
1143EXPORT_SYMBOL_GPL(arizona_anc_ev);
1144
1026static unsigned int arizona_opclk_ref_48k_rates[] = { 1145static unsigned int arizona_opclk_ref_48k_rates[] = {
1027 6144000, 1146 6144000,
1028 12288000, 1147 12288000,
@@ -1095,7 +1214,7 @@ int arizona_set_sysclk(struct snd_soc_codec *codec, int clk_id,
1095 unsigned int reg; 1214 unsigned int reg;
1096 unsigned int mask = ARIZONA_SYSCLK_FREQ_MASK | ARIZONA_SYSCLK_SRC_MASK; 1215 unsigned int mask = ARIZONA_SYSCLK_FREQ_MASK | ARIZONA_SYSCLK_SRC_MASK;
1097 unsigned int val = source << ARIZONA_SYSCLK_SRC_SHIFT; 1216 unsigned int val = source << ARIZONA_SYSCLK_SRC_SHIFT;
1098 unsigned int *clk; 1217 int *clk;
1099 1218
1100 switch (clk_id) { 1219 switch (clk_id) {
1101 case ARIZONA_CLK_SYSCLK: 1220 case ARIZONA_CLK_SYSCLK:
@@ -1375,6 +1494,9 @@ static int arizona_startup(struct snd_pcm_substream *substream,
1375 const struct snd_pcm_hw_constraint_list *constraint; 1494 const struct snd_pcm_hw_constraint_list *constraint;
1376 unsigned int base_rate; 1495 unsigned int base_rate;
1377 1496
1497 if (!substream->runtime)
1498 return 0;
1499
1378 switch (dai_priv->clk) { 1500 switch (dai_priv->clk) {
1379 case ARIZONA_CLK_SYSCLK: 1501 case ARIZONA_CLK_SYSCLK:
1380 base_rate = priv->sysclk; 1502 base_rate = priv->sysclk;
@@ -1901,18 +2023,18 @@ static int arizona_calc_fratio(struct arizona_fll *fll,
1901 } 2023 }
1902 2024
1903 switch (fll->arizona->type) { 2025 switch (fll->arizona->type) {
2026 case WM5102:
2027 case WM8997:
2028 return init_ratio;
1904 case WM5110: 2029 case WM5110:
1905 case WM8280: 2030 case WM8280:
1906 if (fll->arizona->rev < 3 || sync) 2031 if (fll->arizona->rev < 3 || sync)
1907 return init_ratio; 2032 return init_ratio;
1908 break; 2033 break;
1909 case WM8998: 2034 default:
1910 case WM1814:
1911 if (sync) 2035 if (sync)
1912 return init_ratio; 2036 return init_ratio;
1913 break; 2037 break;
1914 default:
1915 return init_ratio;
1916 } 2038 }
1917 2039
1918 cfg->fratio = init_ratio - 1; 2040 cfg->fratio = init_ratio - 1;
@@ -2093,9 +2215,9 @@ static int arizona_enable_fll(struct arizona_fll *fll)
2093 /* Facilitate smooth refclk across the transition */ 2215 /* Facilitate smooth refclk across the transition */
2094 regmap_update_bits_async(fll->arizona->regmap, fll->base + 0x9, 2216 regmap_update_bits_async(fll->arizona->regmap, fll->base + 0x9,
2095 ARIZONA_FLL1_GAIN_MASK, 0); 2217 ARIZONA_FLL1_GAIN_MASK, 0);
2096 regmap_update_bits_async(fll->arizona->regmap, fll->base + 1, 2218 regmap_update_bits(fll->arizona->regmap, fll->base + 1,
2097 ARIZONA_FLL1_FREERUN, 2219 ARIZONA_FLL1_FREERUN, ARIZONA_FLL1_FREERUN);
2098 ARIZONA_FLL1_FREERUN); 2220 udelay(32);
2099 } 2221 }
2100 2222
2101 /* 2223 /*
diff --git a/sound/soc/codecs/arizona.h b/sound/soc/codecs/arizona.h
index fea8b8ae8e1a..8b6adb5419bb 100644
--- a/sound/soc/codecs/arizona.h
+++ b/sound/soc/codecs/arizona.h
@@ -57,7 +57,7 @@
57#define ARIZONA_CLK_98MHZ 5 57#define ARIZONA_CLK_98MHZ 5
58#define ARIZONA_CLK_147MHZ 6 58#define ARIZONA_CLK_147MHZ 6
59 59
60#define ARIZONA_MAX_DAI 6 60#define ARIZONA_MAX_DAI 8
61#define ARIZONA_MAX_ADSP 4 61#define ARIZONA_MAX_ADSP 4
62 62
63#define ARIZONA_DVFS_SR1_RQ 0x001 63#define ARIZONA_DVFS_SR1_RQ 0x001
@@ -96,8 +96,8 @@ struct arizona_priv {
96#define ARIZONA_NUM_MIXER_INPUTS 104 96#define ARIZONA_NUM_MIXER_INPUTS 104
97 97
98extern const unsigned int arizona_mixer_tlv[]; 98extern const unsigned int arizona_mixer_tlv[];
99extern const char *arizona_mixer_texts[ARIZONA_NUM_MIXER_INPUTS]; 99extern const char * const arizona_mixer_texts[ARIZONA_NUM_MIXER_INPUTS];
100extern int arizona_mixer_values[ARIZONA_NUM_MIXER_INPUTS]; 100extern unsigned int arizona_mixer_values[ARIZONA_NUM_MIXER_INPUTS];
101 101
102#define ARIZONA_GAINMUX_CONTROLS(name, base) \ 102#define ARIZONA_GAINMUX_CONTROLS(name, base) \
103 SOC_SINGLE_RANGE_TLV(name " Input Volume", base + 1, \ 103 SOC_SINGLE_RANGE_TLV(name " Input Volume", base + 1, \
@@ -216,8 +216,8 @@ extern int arizona_mixer_values[ARIZONA_NUM_MIXER_INPUTS];
216#define ARIZONA_RATE_ENUM_SIZE 4 216#define ARIZONA_RATE_ENUM_SIZE 4
217#define ARIZONA_SAMPLE_RATE_ENUM_SIZE 14 217#define ARIZONA_SAMPLE_RATE_ENUM_SIZE 14
218 218
219extern const char *arizona_rate_text[ARIZONA_RATE_ENUM_SIZE]; 219extern const char * const arizona_rate_text[ARIZONA_RATE_ENUM_SIZE];
220extern const int arizona_rate_val[ARIZONA_RATE_ENUM_SIZE]; 220extern const unsigned int arizona_rate_val[ARIZONA_RATE_ENUM_SIZE];
221extern const char * const arizona_sample_rate_text[ARIZONA_SAMPLE_RATE_ENUM_SIZE]; 221extern const char * const arizona_sample_rate_text[ARIZONA_SAMPLE_RATE_ENUM_SIZE];
222extern const unsigned int arizona_sample_rate_val[ARIZONA_SAMPLE_RATE_ENUM_SIZE]; 222extern const unsigned int arizona_sample_rate_val[ARIZONA_SAMPLE_RATE_ENUM_SIZE];
223 223
@@ -242,6 +242,10 @@ extern const struct soc_enum arizona_in_dmic_osr[];
242 242
243extern const struct snd_kcontrol_new arizona_adsp2_rate_controls[]; 243extern const struct snd_kcontrol_new arizona_adsp2_rate_controls[];
244 244
245extern const struct soc_enum arizona_anc_input_src[];
246extern const struct soc_enum arizona_anc_ng_enum;
247extern const struct soc_enum arizona_output_anc_src[];
248
245extern int arizona_in_ev(struct snd_soc_dapm_widget *w, 249extern int arizona_in_ev(struct snd_soc_dapm_widget *w,
246 struct snd_kcontrol *kcontrol, 250 struct snd_kcontrol *kcontrol,
247 int event); 251 int event);
@@ -251,6 +255,9 @@ extern int arizona_out_ev(struct snd_soc_dapm_widget *w,
251extern int arizona_hp_ev(struct snd_soc_dapm_widget *w, 255extern int arizona_hp_ev(struct snd_soc_dapm_widget *w,
252 struct snd_kcontrol *kcontrol, 256 struct snd_kcontrol *kcontrol,
253 int event); 257 int event);
258extern int arizona_anc_ev(struct snd_soc_dapm_widget *w,
259 struct snd_kcontrol *kcontrol,
260 int event);
254 261
255extern int arizona_eq_coeff_put(struct snd_kcontrol *kcontrol, 262extern int arizona_eq_coeff_put(struct snd_kcontrol *kcontrol,
256 struct snd_ctl_elem_value *ucontrol); 263 struct snd_ctl_elem_value *ucontrol);
diff --git a/sound/soc/codecs/cs47l24.c b/sound/soc/codecs/cs47l24.c
new file mode 100644
index 000000000000..dc5ae7f7a1bd
--- /dev/null
+++ b/sound/soc/codecs/cs47l24.c
@@ -0,0 +1,1148 @@
1/*
2 * cs47l24.h -- ALSA SoC Audio driver for Cirrus Logic CS47L24
3 *
4 * Copyright 2015 Cirrus Logic Inc.
5 *
6 * Author: Richard Fitzgerald <rf@opensource.wolfsonmicro.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 */
12
13#include <linux/module.h>
14#include <linux/moduleparam.h>
15#include <linux/init.h>
16#include <linux/delay.h>
17#include <linux/pm.h>
18#include <linux/pm_runtime.h>
19#include <linux/regmap.h>
20#include <linux/slab.h>
21#include <sound/core.h>
22#include <sound/pcm.h>
23#include <sound/pcm_params.h>
24#include <sound/soc.h>
25#include <sound/jack.h>
26#include <sound/initval.h>
27#include <sound/tlv.h>
28
29#include <linux/mfd/arizona/core.h>
30#include <linux/mfd/arizona/registers.h>
31
32#include "arizona.h"
33#include "wm_adsp.h"
34#include "cs47l24.h"
35
36struct cs47l24_priv {
37 struct arizona_priv core;
38 struct arizona_fll fll[2];
39};
40
41static const struct wm_adsp_region cs47l24_dsp2_regions[] = {
42 { .type = WMFW_ADSP2_PM, .base = 0x200000 },
43 { .type = WMFW_ADSP2_ZM, .base = 0x280000 },
44 { .type = WMFW_ADSP2_XM, .base = 0x290000 },
45 { .type = WMFW_ADSP2_YM, .base = 0x2a8000 },
46};
47
48static const struct wm_adsp_region cs47l24_dsp3_regions[] = {
49 { .type = WMFW_ADSP2_PM, .base = 0x300000 },
50 { .type = WMFW_ADSP2_ZM, .base = 0x380000 },
51 { .type = WMFW_ADSP2_XM, .base = 0x390000 },
52 { .type = WMFW_ADSP2_YM, .base = 0x3a8000 },
53};
54
55static const struct wm_adsp_region *cs47l24_dsp_regions[] = {
56 cs47l24_dsp2_regions,
57 cs47l24_dsp3_regions,
58};
59
60static DECLARE_TLV_DB_SCALE(eq_tlv, -1200, 100, 0);
61static DECLARE_TLV_DB_SCALE(digital_tlv, -6400, 50, 0);
62static DECLARE_TLV_DB_SCALE(noise_tlv, -13200, 600, 0);
63static DECLARE_TLV_DB_SCALE(ng_tlv, -10200, 600, 0);
64
65#define CS47L24_NG_SRC(name, base) \
66 SOC_SINGLE(name " NG HPOUT1L Switch", base, 0, 1, 0), \
67 SOC_SINGLE(name " NG HPOUT1R Switch", base, 1, 1, 0), \
68 SOC_SINGLE(name " NG SPKOUT Switch", base, 6, 1, 0)
69
70static const struct snd_kcontrol_new cs47l24_snd_controls[] = {
71SOC_ENUM("IN1 OSR", arizona_in_dmic_osr[0]),
72SOC_ENUM("IN2 OSR", arizona_in_dmic_osr[1]),
73
74SOC_ENUM("IN HPF Cutoff Frequency", arizona_in_hpf_cut_enum),
75
76SOC_SINGLE("IN1L HPF Switch", ARIZONA_IN1L_CONTROL,
77 ARIZONA_IN1L_HPF_SHIFT, 1, 0),
78SOC_SINGLE("IN1R HPF Switch", ARIZONA_IN1R_CONTROL,
79 ARIZONA_IN1R_HPF_SHIFT, 1, 0),
80SOC_SINGLE("IN2L HPF Switch", ARIZONA_IN2L_CONTROL,
81 ARIZONA_IN2L_HPF_SHIFT, 1, 0),
82SOC_SINGLE("IN2R HPF Switch", ARIZONA_IN2R_CONTROL,
83 ARIZONA_IN2R_HPF_SHIFT, 1, 0),
84
85SOC_SINGLE_TLV("IN1L Digital Volume", ARIZONA_ADC_DIGITAL_VOLUME_1L,
86 ARIZONA_IN1L_DIG_VOL_SHIFT, 0xbf, 0, digital_tlv),
87SOC_SINGLE_TLV("IN1R Digital Volume", ARIZONA_ADC_DIGITAL_VOLUME_1R,
88 ARIZONA_IN1R_DIG_VOL_SHIFT, 0xbf, 0, digital_tlv),
89SOC_SINGLE_TLV("IN2L Digital Volume", ARIZONA_ADC_DIGITAL_VOLUME_2L,
90 ARIZONA_IN2L_DIG_VOL_SHIFT, 0xbf, 0, digital_tlv),
91SOC_SINGLE_TLV("IN2R Digital Volume", ARIZONA_ADC_DIGITAL_VOLUME_2R,
92 ARIZONA_IN2R_DIG_VOL_SHIFT, 0xbf, 0, digital_tlv),
93
94SOC_ENUM("Input Ramp Up", arizona_in_vi_ramp),
95SOC_ENUM("Input Ramp Down", arizona_in_vd_ramp),
96
97ARIZONA_MIXER_CONTROLS("EQ1", ARIZONA_EQ1MIX_INPUT_1_SOURCE),
98ARIZONA_MIXER_CONTROLS("EQ2", ARIZONA_EQ2MIX_INPUT_1_SOURCE),
99
100ARIZONA_EQ_CONTROL("EQ1 Coefficients", ARIZONA_EQ1_2),
101SOC_SINGLE_TLV("EQ1 B1 Volume", ARIZONA_EQ1_1, ARIZONA_EQ1_B1_GAIN_SHIFT,
102 24, 0, eq_tlv),
103SOC_SINGLE_TLV("EQ1 B2 Volume", ARIZONA_EQ1_1, ARIZONA_EQ1_B2_GAIN_SHIFT,
104 24, 0, eq_tlv),
105SOC_SINGLE_TLV("EQ1 B3 Volume", ARIZONA_EQ1_1, ARIZONA_EQ1_B3_GAIN_SHIFT,
106 24, 0, eq_tlv),
107SOC_SINGLE_TLV("EQ1 B4 Volume", ARIZONA_EQ1_2, ARIZONA_EQ1_B4_GAIN_SHIFT,
108 24, 0, eq_tlv),
109SOC_SINGLE_TLV("EQ1 B5 Volume", ARIZONA_EQ1_2, ARIZONA_EQ1_B5_GAIN_SHIFT,
110 24, 0, eq_tlv),
111
112ARIZONA_EQ_CONTROL("EQ2 Coefficients", ARIZONA_EQ2_2),
113SOC_SINGLE_TLV("EQ2 B1 Volume", ARIZONA_EQ2_1, ARIZONA_EQ2_B1_GAIN_SHIFT,
114 24, 0, eq_tlv),
115SOC_SINGLE_TLV("EQ2 B2 Volume", ARIZONA_EQ2_1, ARIZONA_EQ2_B2_GAIN_SHIFT,
116 24, 0, eq_tlv),
117SOC_SINGLE_TLV("EQ2 B3 Volume", ARIZONA_EQ2_1, ARIZONA_EQ2_B3_GAIN_SHIFT,
118 24, 0, eq_tlv),
119SOC_SINGLE_TLV("EQ2 B4 Volume", ARIZONA_EQ2_2, ARIZONA_EQ2_B4_GAIN_SHIFT,
120 24, 0, eq_tlv),
121SOC_SINGLE_TLV("EQ2 B5 Volume", ARIZONA_EQ2_2, ARIZONA_EQ2_B5_GAIN_SHIFT,
122 24, 0, eq_tlv),
123
124ARIZONA_MIXER_CONTROLS("DRC1L", ARIZONA_DRC1LMIX_INPUT_1_SOURCE),
125ARIZONA_MIXER_CONTROLS("DRC1R", ARIZONA_DRC1RMIX_INPUT_1_SOURCE),
126ARIZONA_MIXER_CONTROLS("DRC2L", ARIZONA_DRC2LMIX_INPUT_1_SOURCE),
127ARIZONA_MIXER_CONTROLS("DRC2R", ARIZONA_DRC2RMIX_INPUT_1_SOURCE),
128
129SND_SOC_BYTES_MASK("DRC1", ARIZONA_DRC1_CTRL1, 5,
130 ARIZONA_DRC1R_ENA | ARIZONA_DRC1L_ENA),
131SND_SOC_BYTES_MASK("DRC2", ARIZONA_DRC2_CTRL1, 5,
132 ARIZONA_DRC2R_ENA | ARIZONA_DRC2L_ENA),
133
134ARIZONA_MIXER_CONTROLS("LHPF1", ARIZONA_HPLP1MIX_INPUT_1_SOURCE),
135ARIZONA_MIXER_CONTROLS("LHPF2", ARIZONA_HPLP2MIX_INPUT_1_SOURCE),
136ARIZONA_MIXER_CONTROLS("LHPF3", ARIZONA_HPLP3MIX_INPUT_1_SOURCE),
137ARIZONA_MIXER_CONTROLS("LHPF4", ARIZONA_HPLP4MIX_INPUT_1_SOURCE),
138
139ARIZONA_LHPF_CONTROL("LHPF1 Coefficients", ARIZONA_HPLPF1_2),
140ARIZONA_LHPF_CONTROL("LHPF2 Coefficients", ARIZONA_HPLPF2_2),
141ARIZONA_LHPF_CONTROL("LHPF3 Coefficients", ARIZONA_HPLPF3_2),
142ARIZONA_LHPF_CONTROL("LHPF4 Coefficients", ARIZONA_HPLPF4_2),
143
144SOC_ENUM("LHPF1 Mode", arizona_lhpf1_mode),
145SOC_ENUM("LHPF2 Mode", arizona_lhpf2_mode),
146SOC_ENUM("LHPF3 Mode", arizona_lhpf3_mode),
147SOC_ENUM("LHPF4 Mode", arizona_lhpf4_mode),
148
149SOC_ENUM("ISRC1 FSL", arizona_isrc_fsl[0]),
150SOC_ENUM("ISRC2 FSL", arizona_isrc_fsl[1]),
151SOC_ENUM("ISRC3 FSL", arizona_isrc_fsl[2]),
152SOC_ENUM("ISRC1 FSH", arizona_isrc_fsh[0]),
153SOC_ENUM("ISRC2 FSH", arizona_isrc_fsh[1]),
154SOC_ENUM("ISRC3 FSH", arizona_isrc_fsh[2]),
155SOC_ENUM("ASRC RATE 1", arizona_asrc_rate1),
156
157ARIZONA_MIXER_CONTROLS("DSP2L", ARIZONA_DSP2LMIX_INPUT_1_SOURCE),
158ARIZONA_MIXER_CONTROLS("DSP2R", ARIZONA_DSP2RMIX_INPUT_1_SOURCE),
159ARIZONA_MIXER_CONTROLS("DSP3L", ARIZONA_DSP3LMIX_INPUT_1_SOURCE),
160ARIZONA_MIXER_CONTROLS("DSP3R", ARIZONA_DSP3RMIX_INPUT_1_SOURCE),
161
162SOC_SINGLE_TLV("Noise Generator Volume", ARIZONA_COMFORT_NOISE_GENERATOR,
163 ARIZONA_NOISE_GEN_GAIN_SHIFT, 0x16, 0, noise_tlv),
164
165ARIZONA_MIXER_CONTROLS("HPOUT1L", ARIZONA_OUT1LMIX_INPUT_1_SOURCE),
166ARIZONA_MIXER_CONTROLS("HPOUT1R", ARIZONA_OUT1RMIX_INPUT_1_SOURCE),
167ARIZONA_MIXER_CONTROLS("SPKOUT", ARIZONA_OUT4LMIX_INPUT_1_SOURCE),
168
169SOC_SINGLE("HPOUT1 SC Protect Switch", ARIZONA_HP1_SHORT_CIRCUIT_CTRL,
170 ARIZONA_HP1_SC_ENA_SHIFT, 1, 0),
171
172SOC_DOUBLE_R("HPOUT1 Digital Switch", ARIZONA_DAC_DIGITAL_VOLUME_1L,
173 ARIZONA_DAC_DIGITAL_VOLUME_1R, ARIZONA_OUT1L_MUTE_SHIFT, 1, 1),
174SOC_SINGLE("Speaker Digital Switch", ARIZONA_DAC_DIGITAL_VOLUME_4L,
175 ARIZONA_OUT4L_MUTE_SHIFT, 1, 1),
176
177SOC_DOUBLE_R_TLV("HPOUT1 Digital Volume", ARIZONA_DAC_DIGITAL_VOLUME_1L,
178 ARIZONA_DAC_DIGITAL_VOLUME_1R, ARIZONA_OUT1L_VOL_SHIFT,
179 0xbf, 0, digital_tlv),
180SOC_SINGLE_TLV("Speaker Digital Volume", ARIZONA_DAC_DIGITAL_VOLUME_4L,
181 ARIZONA_OUT4L_VOL_SHIFT,
182 0xbf, 0, digital_tlv),
183
184SOC_ENUM("Output Ramp Up", arizona_out_vi_ramp),
185SOC_ENUM("Output Ramp Down", arizona_out_vd_ramp),
186
187SOC_SINGLE("Noise Gate Switch", ARIZONA_NOISE_GATE_CONTROL,
188 ARIZONA_NGATE_ENA_SHIFT, 1, 0),
189SOC_SINGLE_TLV("Noise Gate Threshold Volume", ARIZONA_NOISE_GATE_CONTROL,
190 ARIZONA_NGATE_THR_SHIFT, 7, 1, ng_tlv),
191SOC_ENUM("Noise Gate Hold", arizona_ng_hold),
192
193CS47L24_NG_SRC("HPOUT1L", ARIZONA_NOISE_GATE_SELECT_1L),
194CS47L24_NG_SRC("HPOUT1R", ARIZONA_NOISE_GATE_SELECT_1R),
195CS47L24_NG_SRC("SPKOUT", ARIZONA_NOISE_GATE_SELECT_4L),
196
197ARIZONA_MIXER_CONTROLS("AIF1TX1", ARIZONA_AIF1TX1MIX_INPUT_1_SOURCE),
198ARIZONA_MIXER_CONTROLS("AIF1TX2", ARIZONA_AIF1TX2MIX_INPUT_1_SOURCE),
199ARIZONA_MIXER_CONTROLS("AIF1TX3", ARIZONA_AIF1TX3MIX_INPUT_1_SOURCE),
200ARIZONA_MIXER_CONTROLS("AIF1TX4", ARIZONA_AIF1TX4MIX_INPUT_1_SOURCE),
201ARIZONA_MIXER_CONTROLS("AIF1TX5", ARIZONA_AIF1TX5MIX_INPUT_1_SOURCE),
202ARIZONA_MIXER_CONTROLS("AIF1TX6", ARIZONA_AIF1TX6MIX_INPUT_1_SOURCE),
203ARIZONA_MIXER_CONTROLS("AIF1TX7", ARIZONA_AIF1TX7MIX_INPUT_1_SOURCE),
204ARIZONA_MIXER_CONTROLS("AIF1TX8", ARIZONA_AIF1TX8MIX_INPUT_1_SOURCE),
205
206ARIZONA_MIXER_CONTROLS("AIF2TX1", ARIZONA_AIF2TX1MIX_INPUT_1_SOURCE),
207ARIZONA_MIXER_CONTROLS("AIF2TX2", ARIZONA_AIF2TX2MIX_INPUT_1_SOURCE),
208ARIZONA_MIXER_CONTROLS("AIF2TX3", ARIZONA_AIF2TX3MIX_INPUT_1_SOURCE),
209ARIZONA_MIXER_CONTROLS("AIF2TX4", ARIZONA_AIF2TX4MIX_INPUT_1_SOURCE),
210ARIZONA_MIXER_CONTROLS("AIF2TX5", ARIZONA_AIF2TX5MIX_INPUT_1_SOURCE),
211ARIZONA_MIXER_CONTROLS("AIF2TX6", ARIZONA_AIF2TX6MIX_INPUT_1_SOURCE),
212
213ARIZONA_MIXER_CONTROLS("AIF3TX1", ARIZONA_AIF3TX1MIX_INPUT_1_SOURCE),
214ARIZONA_MIXER_CONTROLS("AIF3TX2", ARIZONA_AIF3TX2MIX_INPUT_1_SOURCE),
215};
216
217ARIZONA_MIXER_ENUMS(EQ1, ARIZONA_EQ1MIX_INPUT_1_SOURCE);
218ARIZONA_MIXER_ENUMS(EQ2, ARIZONA_EQ2MIX_INPUT_1_SOURCE);
219
220ARIZONA_MIXER_ENUMS(DRC1L, ARIZONA_DRC1LMIX_INPUT_1_SOURCE);
221ARIZONA_MIXER_ENUMS(DRC1R, ARIZONA_DRC1RMIX_INPUT_1_SOURCE);
222ARIZONA_MIXER_ENUMS(DRC2L, ARIZONA_DRC2LMIX_INPUT_1_SOURCE);
223ARIZONA_MIXER_ENUMS(DRC2R, ARIZONA_DRC2RMIX_INPUT_1_SOURCE);
224
225ARIZONA_MIXER_ENUMS(LHPF1, ARIZONA_HPLP1MIX_INPUT_1_SOURCE);
226ARIZONA_MIXER_ENUMS(LHPF2, ARIZONA_HPLP2MIX_INPUT_1_SOURCE);
227ARIZONA_MIXER_ENUMS(LHPF3, ARIZONA_HPLP3MIX_INPUT_1_SOURCE);
228ARIZONA_MIXER_ENUMS(LHPF4, ARIZONA_HPLP4MIX_INPUT_1_SOURCE);
229
230ARIZONA_MIXER_ENUMS(DSP2L, ARIZONA_DSP2LMIX_INPUT_1_SOURCE);
231ARIZONA_MIXER_ENUMS(DSP2R, ARIZONA_DSP2RMIX_INPUT_1_SOURCE);
232ARIZONA_DSP_AUX_ENUMS(DSP2, ARIZONA_DSP2AUX1MIX_INPUT_1_SOURCE);
233
234ARIZONA_MIXER_ENUMS(DSP3L, ARIZONA_DSP3LMIX_INPUT_1_SOURCE);
235ARIZONA_MIXER_ENUMS(DSP3R, ARIZONA_DSP3RMIX_INPUT_1_SOURCE);
236ARIZONA_DSP_AUX_ENUMS(DSP3, ARIZONA_DSP3AUX1MIX_INPUT_1_SOURCE);
237
238ARIZONA_MIXER_ENUMS(PWM1, ARIZONA_PWM1MIX_INPUT_1_SOURCE);
239ARIZONA_MIXER_ENUMS(PWM2, ARIZONA_PWM2MIX_INPUT_1_SOURCE);
240
241ARIZONA_MIXER_ENUMS(OUT1L, ARIZONA_OUT1LMIX_INPUT_1_SOURCE);
242ARIZONA_MIXER_ENUMS(OUT1R, ARIZONA_OUT1RMIX_INPUT_1_SOURCE);
243ARIZONA_MIXER_ENUMS(SPKOUT, ARIZONA_OUT4LMIX_INPUT_1_SOURCE);
244
245ARIZONA_MIXER_ENUMS(AIF1TX1, ARIZONA_AIF1TX1MIX_INPUT_1_SOURCE);
246ARIZONA_MIXER_ENUMS(AIF1TX2, ARIZONA_AIF1TX2MIX_INPUT_1_SOURCE);
247ARIZONA_MIXER_ENUMS(AIF1TX3, ARIZONA_AIF1TX3MIX_INPUT_1_SOURCE);
248ARIZONA_MIXER_ENUMS(AIF1TX4, ARIZONA_AIF1TX4MIX_INPUT_1_SOURCE);
249ARIZONA_MIXER_ENUMS(AIF1TX5, ARIZONA_AIF1TX5MIX_INPUT_1_SOURCE);
250ARIZONA_MIXER_ENUMS(AIF1TX6, ARIZONA_AIF1TX6MIX_INPUT_1_SOURCE);
251ARIZONA_MIXER_ENUMS(AIF1TX7, ARIZONA_AIF1TX7MIX_INPUT_1_SOURCE);
252ARIZONA_MIXER_ENUMS(AIF1TX8, ARIZONA_AIF1TX8MIX_INPUT_1_SOURCE);
253
254ARIZONA_MIXER_ENUMS(AIF2TX1, ARIZONA_AIF2TX1MIX_INPUT_1_SOURCE);
255ARIZONA_MIXER_ENUMS(AIF2TX2, ARIZONA_AIF2TX2MIX_INPUT_1_SOURCE);
256ARIZONA_MIXER_ENUMS(AIF2TX3, ARIZONA_AIF2TX3MIX_INPUT_1_SOURCE);
257ARIZONA_MIXER_ENUMS(AIF2TX4, ARIZONA_AIF2TX4MIX_INPUT_1_SOURCE);
258ARIZONA_MIXER_ENUMS(AIF2TX5, ARIZONA_AIF2TX5MIX_INPUT_1_SOURCE);
259ARIZONA_MIXER_ENUMS(AIF2TX6, ARIZONA_AIF2TX6MIX_INPUT_1_SOURCE);
260
261ARIZONA_MIXER_ENUMS(AIF3TX1, ARIZONA_AIF3TX1MIX_INPUT_1_SOURCE);
262ARIZONA_MIXER_ENUMS(AIF3TX2, ARIZONA_AIF3TX2MIX_INPUT_1_SOURCE);
263
264ARIZONA_MUX_ENUMS(ASRC1L, ARIZONA_ASRC1LMIX_INPUT_1_SOURCE);
265ARIZONA_MUX_ENUMS(ASRC1R, ARIZONA_ASRC1RMIX_INPUT_1_SOURCE);
266ARIZONA_MUX_ENUMS(ASRC2L, ARIZONA_ASRC2LMIX_INPUT_1_SOURCE);
267ARIZONA_MUX_ENUMS(ASRC2R, ARIZONA_ASRC2RMIX_INPUT_1_SOURCE);
268
269ARIZONA_MUX_ENUMS(ISRC1INT1, ARIZONA_ISRC1INT1MIX_INPUT_1_SOURCE);
270ARIZONA_MUX_ENUMS(ISRC1INT2, ARIZONA_ISRC1INT2MIX_INPUT_1_SOURCE);
271ARIZONA_MUX_ENUMS(ISRC1INT3, ARIZONA_ISRC1INT3MIX_INPUT_1_SOURCE);
272ARIZONA_MUX_ENUMS(ISRC1INT4, ARIZONA_ISRC1INT4MIX_INPUT_1_SOURCE);
273
274ARIZONA_MUX_ENUMS(ISRC1DEC1, ARIZONA_ISRC1DEC1MIX_INPUT_1_SOURCE);
275ARIZONA_MUX_ENUMS(ISRC1DEC2, ARIZONA_ISRC1DEC2MIX_INPUT_1_SOURCE);
276ARIZONA_MUX_ENUMS(ISRC1DEC3, ARIZONA_ISRC1DEC3MIX_INPUT_1_SOURCE);
277ARIZONA_MUX_ENUMS(ISRC1DEC4, ARIZONA_ISRC1DEC4MIX_INPUT_1_SOURCE);
278
279ARIZONA_MUX_ENUMS(ISRC2INT1, ARIZONA_ISRC2INT1MIX_INPUT_1_SOURCE);
280ARIZONA_MUX_ENUMS(ISRC2INT2, ARIZONA_ISRC2INT2MIX_INPUT_1_SOURCE);
281ARIZONA_MUX_ENUMS(ISRC2INT3, ARIZONA_ISRC2INT3MIX_INPUT_1_SOURCE);
282ARIZONA_MUX_ENUMS(ISRC2INT4, ARIZONA_ISRC2INT4MIX_INPUT_1_SOURCE);
283
284ARIZONA_MUX_ENUMS(ISRC2DEC1, ARIZONA_ISRC2DEC1MIX_INPUT_1_SOURCE);
285ARIZONA_MUX_ENUMS(ISRC2DEC2, ARIZONA_ISRC2DEC2MIX_INPUT_1_SOURCE);
286ARIZONA_MUX_ENUMS(ISRC2DEC3, ARIZONA_ISRC2DEC3MIX_INPUT_1_SOURCE);
287ARIZONA_MUX_ENUMS(ISRC2DEC4, ARIZONA_ISRC2DEC4MIX_INPUT_1_SOURCE);
288
289ARIZONA_MUX_ENUMS(ISRC3INT1, ARIZONA_ISRC3INT1MIX_INPUT_1_SOURCE);
290ARIZONA_MUX_ENUMS(ISRC3INT2, ARIZONA_ISRC3INT2MIX_INPUT_1_SOURCE);
291ARIZONA_MUX_ENUMS(ISRC3INT3, ARIZONA_ISRC3INT3MIX_INPUT_1_SOURCE);
292ARIZONA_MUX_ENUMS(ISRC3INT4, ARIZONA_ISRC3INT4MIX_INPUT_1_SOURCE);
293
294ARIZONA_MUX_ENUMS(ISRC3DEC1, ARIZONA_ISRC3DEC1MIX_INPUT_1_SOURCE);
295ARIZONA_MUX_ENUMS(ISRC3DEC2, ARIZONA_ISRC3DEC2MIX_INPUT_1_SOURCE);
296ARIZONA_MUX_ENUMS(ISRC3DEC3, ARIZONA_ISRC3DEC3MIX_INPUT_1_SOURCE);
297ARIZONA_MUX_ENUMS(ISRC3DEC4, ARIZONA_ISRC3DEC4MIX_INPUT_1_SOURCE);
298
299static const char * const cs47l24_aec_loopback_texts[] = {
300 "HPOUT1L", "HPOUT1R", "SPKOUT",
301};
302
303static const unsigned int cs47l24_aec_loopback_values[] = {
304 0, 1, 6,
305};
306
307static const struct soc_enum cs47l24_aec_loopback =
308 SOC_VALUE_ENUM_SINGLE(ARIZONA_DAC_AEC_CONTROL_1,
309 ARIZONA_AEC_LOOPBACK_SRC_SHIFT, 0xf,
310 ARRAY_SIZE(cs47l24_aec_loopback_texts),
311 cs47l24_aec_loopback_texts,
312 cs47l24_aec_loopback_values);
313
314static const struct snd_kcontrol_new cs47l24_aec_loopback_mux =
315 SOC_DAPM_ENUM("AEC Loopback", cs47l24_aec_loopback);
316
317static const struct snd_soc_dapm_widget cs47l24_dapm_widgets[] = {
318SND_SOC_DAPM_SUPPLY("SYSCLK", ARIZONA_SYSTEM_CLOCK_1,
319 ARIZONA_SYSCLK_ENA_SHIFT, 0, NULL, 0),
320SND_SOC_DAPM_SUPPLY("ASYNCCLK", ARIZONA_ASYNC_CLOCK_1,
321 ARIZONA_ASYNC_CLK_ENA_SHIFT, 0, NULL, 0),
322SND_SOC_DAPM_SUPPLY("OPCLK", ARIZONA_OUTPUT_SYSTEM_CLOCK,
323 ARIZONA_OPCLK_ENA_SHIFT, 0, NULL, 0),
324SND_SOC_DAPM_SUPPLY("ASYNCOPCLK", ARIZONA_OUTPUT_ASYNC_CLOCK,
325 ARIZONA_OPCLK_ASYNC_ENA_SHIFT, 0, NULL, 0),
326
327SND_SOC_DAPM_REGULATOR_SUPPLY("CPVDD", 20, 0),
328SND_SOC_DAPM_REGULATOR_SUPPLY("MICVDD", 0, SND_SOC_DAPM_REGULATOR_BYPASS),
329SND_SOC_DAPM_REGULATOR_SUPPLY("SPKVDD", 0, 0),
330
331SND_SOC_DAPM_SIGGEN("TONE"),
332SND_SOC_DAPM_SIGGEN("NOISE"),
333SND_SOC_DAPM_SIGGEN("HAPTICS"),
334
335SND_SOC_DAPM_INPUT("IN1L"),
336SND_SOC_DAPM_INPUT("IN1R"),
337SND_SOC_DAPM_INPUT("IN2L"),
338SND_SOC_DAPM_INPUT("IN2R"),
339
340SND_SOC_DAPM_OUTPUT("DRC1 Signal Activity"),
341SND_SOC_DAPM_OUTPUT("DRC2 Signal Activity"),
342
343SND_SOC_DAPM_PGA_E("IN1L PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN1L_ENA_SHIFT,
344 0, NULL, 0, arizona_in_ev,
345 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD |
346 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU),
347SND_SOC_DAPM_PGA_E("IN1R PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN1R_ENA_SHIFT,
348 0, NULL, 0, arizona_in_ev,
349 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD |
350 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU),
351SND_SOC_DAPM_PGA_E("IN2L PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN2L_ENA_SHIFT,
352 0, NULL, 0, arizona_in_ev,
353 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD |
354 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU),
355SND_SOC_DAPM_PGA_E("IN2R PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN2R_ENA_SHIFT,
356 0, NULL, 0, arizona_in_ev,
357 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD |
358 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU),
359
360SND_SOC_DAPM_SUPPLY("MICBIAS1", ARIZONA_MIC_BIAS_CTRL_1,
361 ARIZONA_MICB1_ENA_SHIFT, 0, NULL, 0),
362SND_SOC_DAPM_SUPPLY("MICBIAS2", ARIZONA_MIC_BIAS_CTRL_2,
363 ARIZONA_MICB1_ENA_SHIFT, 0, NULL, 0),
364
365SND_SOC_DAPM_PGA("Noise Generator", ARIZONA_COMFORT_NOISE_GENERATOR,
366 ARIZONA_NOISE_GEN_ENA_SHIFT, 0, NULL, 0),
367
368SND_SOC_DAPM_PGA("Tone Generator 1", ARIZONA_TONE_GENERATOR_1,
369 ARIZONA_TONE1_ENA_SHIFT, 0, NULL, 0),
370SND_SOC_DAPM_PGA("Tone Generator 2", ARIZONA_TONE_GENERATOR_1,
371 ARIZONA_TONE2_ENA_SHIFT, 0, NULL, 0),
372
373SND_SOC_DAPM_PGA("EQ1", ARIZONA_EQ1_1, ARIZONA_EQ1_ENA_SHIFT, 0, NULL, 0),
374SND_SOC_DAPM_PGA("EQ2", ARIZONA_EQ2_1, ARIZONA_EQ2_ENA_SHIFT, 0, NULL, 0),
375
376SND_SOC_DAPM_PGA("DRC1L", ARIZONA_DRC1_CTRL1, ARIZONA_DRC1L_ENA_SHIFT, 0,
377 NULL, 0),
378SND_SOC_DAPM_PGA("DRC1R", ARIZONA_DRC1_CTRL1, ARIZONA_DRC1R_ENA_SHIFT, 0,
379 NULL, 0),
380SND_SOC_DAPM_PGA("DRC2L", ARIZONA_DRC2_CTRL1, ARIZONA_DRC2L_ENA_SHIFT, 0,
381 NULL, 0),
382SND_SOC_DAPM_PGA("DRC2R", ARIZONA_DRC2_CTRL1, ARIZONA_DRC2R_ENA_SHIFT, 0,
383 NULL, 0),
384
385SND_SOC_DAPM_PGA("LHPF1", ARIZONA_HPLPF1_1, ARIZONA_LHPF1_ENA_SHIFT, 0,
386 NULL, 0),
387SND_SOC_DAPM_PGA("LHPF2", ARIZONA_HPLPF2_1, ARIZONA_LHPF2_ENA_SHIFT, 0,
388 NULL, 0),
389SND_SOC_DAPM_PGA("LHPF3", ARIZONA_HPLPF3_1, ARIZONA_LHPF3_ENA_SHIFT, 0,
390 NULL, 0),
391SND_SOC_DAPM_PGA("LHPF4", ARIZONA_HPLPF4_1, ARIZONA_LHPF4_ENA_SHIFT, 0,
392 NULL, 0),
393
394SND_SOC_DAPM_PGA("PWM1 Driver", ARIZONA_PWM_DRIVE_1, ARIZONA_PWM1_ENA_SHIFT,
395 0, NULL, 0),
396SND_SOC_DAPM_PGA("PWM2 Driver", ARIZONA_PWM_DRIVE_1, ARIZONA_PWM2_ENA_SHIFT,
397 0, NULL, 0),
398
399SND_SOC_DAPM_PGA("ASRC1L", ARIZONA_ASRC_ENABLE, ARIZONA_ASRC1L_ENA_SHIFT, 0,
400 NULL, 0),
401SND_SOC_DAPM_PGA("ASRC1R", ARIZONA_ASRC_ENABLE, ARIZONA_ASRC1R_ENA_SHIFT, 0,
402 NULL, 0),
403SND_SOC_DAPM_PGA("ASRC2L", ARIZONA_ASRC_ENABLE, ARIZONA_ASRC2L_ENA_SHIFT, 0,
404 NULL, 0),
405SND_SOC_DAPM_PGA("ASRC2R", ARIZONA_ASRC_ENABLE, ARIZONA_ASRC2R_ENA_SHIFT, 0,
406 NULL, 0),
407
408WM_ADSP2("DSP2", 1),
409WM_ADSP2("DSP3", 2),
410
411SND_SOC_DAPM_PGA("ISRC1INT1", ARIZONA_ISRC_1_CTRL_3,
412 ARIZONA_ISRC1_INT0_ENA_SHIFT, 0, NULL, 0),
413SND_SOC_DAPM_PGA("ISRC1INT2", ARIZONA_ISRC_1_CTRL_3,
414 ARIZONA_ISRC1_INT1_ENA_SHIFT, 0, NULL, 0),
415SND_SOC_DAPM_PGA("ISRC1INT3", ARIZONA_ISRC_1_CTRL_3,
416 ARIZONA_ISRC1_INT2_ENA_SHIFT, 0, NULL, 0),
417SND_SOC_DAPM_PGA("ISRC1INT4", ARIZONA_ISRC_1_CTRL_3,
418 ARIZONA_ISRC1_INT3_ENA_SHIFT, 0, NULL, 0),
419
420SND_SOC_DAPM_PGA("ISRC1DEC1", ARIZONA_ISRC_1_CTRL_3,
421 ARIZONA_ISRC1_DEC0_ENA_SHIFT, 0, NULL, 0),
422SND_SOC_DAPM_PGA("ISRC1DEC2", ARIZONA_ISRC_1_CTRL_3,
423 ARIZONA_ISRC1_DEC1_ENA_SHIFT, 0, NULL, 0),
424SND_SOC_DAPM_PGA("ISRC1DEC3", ARIZONA_ISRC_1_CTRL_3,
425 ARIZONA_ISRC1_DEC2_ENA_SHIFT, 0, NULL, 0),
426SND_SOC_DAPM_PGA("ISRC1DEC4", ARIZONA_ISRC_1_CTRL_3,
427 ARIZONA_ISRC1_DEC3_ENA_SHIFT, 0, NULL, 0),
428
429SND_SOC_DAPM_PGA("ISRC2INT1", ARIZONA_ISRC_2_CTRL_3,
430 ARIZONA_ISRC2_INT0_ENA_SHIFT, 0, NULL, 0),
431SND_SOC_DAPM_PGA("ISRC2INT2", ARIZONA_ISRC_2_CTRL_3,
432 ARIZONA_ISRC2_INT1_ENA_SHIFT, 0, NULL, 0),
433SND_SOC_DAPM_PGA("ISRC2INT3", ARIZONA_ISRC_2_CTRL_3,
434 ARIZONA_ISRC2_INT2_ENA_SHIFT, 0, NULL, 0),
435SND_SOC_DAPM_PGA("ISRC2INT4", ARIZONA_ISRC_2_CTRL_3,
436 ARIZONA_ISRC2_INT3_ENA_SHIFT, 0, NULL, 0),
437
438SND_SOC_DAPM_PGA("ISRC2DEC1", ARIZONA_ISRC_2_CTRL_3,
439 ARIZONA_ISRC2_DEC0_ENA_SHIFT, 0, NULL, 0),
440SND_SOC_DAPM_PGA("ISRC2DEC2", ARIZONA_ISRC_2_CTRL_3,
441 ARIZONA_ISRC2_DEC1_ENA_SHIFT, 0, NULL, 0),
442SND_SOC_DAPM_PGA("ISRC2DEC3", ARIZONA_ISRC_2_CTRL_3,
443 ARIZONA_ISRC2_DEC2_ENA_SHIFT, 0, NULL, 0),
444SND_SOC_DAPM_PGA("ISRC2DEC4", ARIZONA_ISRC_2_CTRL_3,
445 ARIZONA_ISRC2_DEC3_ENA_SHIFT, 0, NULL, 0),
446
447SND_SOC_DAPM_PGA("ISRC3INT1", ARIZONA_ISRC_3_CTRL_3,
448 ARIZONA_ISRC3_INT0_ENA_SHIFT, 0, NULL, 0),
449SND_SOC_DAPM_PGA("ISRC3INT2", ARIZONA_ISRC_3_CTRL_3,
450 ARIZONA_ISRC3_INT1_ENA_SHIFT, 0, NULL, 0),
451SND_SOC_DAPM_PGA("ISRC3INT3", ARIZONA_ISRC_3_CTRL_3,
452 ARIZONA_ISRC3_INT2_ENA_SHIFT, 0, NULL, 0),
453SND_SOC_DAPM_PGA("ISRC3INT4", ARIZONA_ISRC_3_CTRL_3,
454 ARIZONA_ISRC3_INT3_ENA_SHIFT, 0, NULL, 0),
455
456SND_SOC_DAPM_PGA("ISRC3DEC1", ARIZONA_ISRC_3_CTRL_3,
457 ARIZONA_ISRC3_DEC0_ENA_SHIFT, 0, NULL, 0),
458SND_SOC_DAPM_PGA("ISRC3DEC2", ARIZONA_ISRC_3_CTRL_3,
459 ARIZONA_ISRC3_DEC1_ENA_SHIFT, 0, NULL, 0),
460SND_SOC_DAPM_PGA("ISRC3DEC3", ARIZONA_ISRC_3_CTRL_3,
461 ARIZONA_ISRC3_DEC2_ENA_SHIFT, 0, NULL, 0),
462SND_SOC_DAPM_PGA("ISRC3DEC4", ARIZONA_ISRC_3_CTRL_3,
463 ARIZONA_ISRC3_DEC3_ENA_SHIFT, 0, NULL, 0),
464
465SND_SOC_DAPM_MUX("AEC Loopback", ARIZONA_DAC_AEC_CONTROL_1,
466 ARIZONA_AEC_LOOPBACK_ENA_SHIFT, 0,
467 &cs47l24_aec_loopback_mux),
468
469SND_SOC_DAPM_AIF_OUT("AIF1TX1", NULL, 0,
470 ARIZONA_AIF1_TX_ENABLES, ARIZONA_AIF1TX1_ENA_SHIFT, 0),
471SND_SOC_DAPM_AIF_OUT("AIF1TX2", NULL, 0,
472 ARIZONA_AIF1_TX_ENABLES, ARIZONA_AIF1TX2_ENA_SHIFT, 0),
473SND_SOC_DAPM_AIF_OUT("AIF1TX3", NULL, 0,
474 ARIZONA_AIF1_TX_ENABLES, ARIZONA_AIF1TX3_ENA_SHIFT, 0),
475SND_SOC_DAPM_AIF_OUT("AIF1TX4", NULL, 0,
476 ARIZONA_AIF1_TX_ENABLES, ARIZONA_AIF1TX4_ENA_SHIFT, 0),
477SND_SOC_DAPM_AIF_OUT("AIF1TX5", NULL, 0,
478 ARIZONA_AIF1_TX_ENABLES, ARIZONA_AIF1TX5_ENA_SHIFT, 0),
479SND_SOC_DAPM_AIF_OUT("AIF1TX6", NULL, 0,
480 ARIZONA_AIF1_TX_ENABLES, ARIZONA_AIF1TX6_ENA_SHIFT, 0),
481SND_SOC_DAPM_AIF_OUT("AIF1TX7", NULL, 0,
482 ARIZONA_AIF1_TX_ENABLES, ARIZONA_AIF1TX7_ENA_SHIFT, 0),
483SND_SOC_DAPM_AIF_OUT("AIF1TX8", NULL, 0,
484 ARIZONA_AIF1_TX_ENABLES, ARIZONA_AIF1TX8_ENA_SHIFT, 0),
485
486SND_SOC_DAPM_AIF_IN("AIF1RX1", NULL, 0,
487 ARIZONA_AIF1_RX_ENABLES, ARIZONA_AIF1RX1_ENA_SHIFT, 0),
488SND_SOC_DAPM_AIF_IN("AIF1RX2", NULL, 0,
489 ARIZONA_AIF1_RX_ENABLES, ARIZONA_AIF1RX2_ENA_SHIFT, 0),
490SND_SOC_DAPM_AIF_IN("AIF1RX3", NULL, 0,
491 ARIZONA_AIF1_RX_ENABLES, ARIZONA_AIF1RX3_ENA_SHIFT, 0),
492SND_SOC_DAPM_AIF_IN("AIF1RX4", NULL, 0,
493 ARIZONA_AIF1_RX_ENABLES, ARIZONA_AIF1RX4_ENA_SHIFT, 0),
494SND_SOC_DAPM_AIF_IN("AIF1RX5", NULL, 0,
495 ARIZONA_AIF1_RX_ENABLES, ARIZONA_AIF1RX5_ENA_SHIFT, 0),
496SND_SOC_DAPM_AIF_IN("AIF1RX6", NULL, 0,
497 ARIZONA_AIF1_RX_ENABLES, ARIZONA_AIF1RX6_ENA_SHIFT, 0),
498SND_SOC_DAPM_AIF_IN("AIF1RX7", NULL, 0,
499 ARIZONA_AIF1_RX_ENABLES, ARIZONA_AIF1RX7_ENA_SHIFT, 0),
500SND_SOC_DAPM_AIF_IN("AIF1RX8", NULL, 0,
501 ARIZONA_AIF1_RX_ENABLES, ARIZONA_AIF1RX8_ENA_SHIFT, 0),
502
503SND_SOC_DAPM_AIF_OUT("AIF2TX1", NULL, 0,
504 ARIZONA_AIF2_TX_ENABLES, ARIZONA_AIF2TX1_ENA_SHIFT, 0),
505SND_SOC_DAPM_AIF_OUT("AIF2TX2", NULL, 0,
506 ARIZONA_AIF2_TX_ENABLES, ARIZONA_AIF2TX2_ENA_SHIFT, 0),
507SND_SOC_DAPM_AIF_OUT("AIF2TX3", NULL, 0,
508 ARIZONA_AIF2_TX_ENABLES, ARIZONA_AIF2TX3_ENA_SHIFT, 0),
509SND_SOC_DAPM_AIF_OUT("AIF2TX4", NULL, 0,
510 ARIZONA_AIF2_TX_ENABLES, ARIZONA_AIF2TX4_ENA_SHIFT, 0),
511SND_SOC_DAPM_AIF_OUT("AIF2TX5", NULL, 0,
512 ARIZONA_AIF2_TX_ENABLES, ARIZONA_AIF2TX5_ENA_SHIFT, 0),
513SND_SOC_DAPM_AIF_OUT("AIF2TX6", NULL, 0,
514 ARIZONA_AIF2_TX_ENABLES, ARIZONA_AIF2TX6_ENA_SHIFT, 0),
515
516SND_SOC_DAPM_AIF_IN("AIF2RX1", NULL, 0,
517 ARIZONA_AIF2_RX_ENABLES, ARIZONA_AIF2RX1_ENA_SHIFT, 0),
518SND_SOC_DAPM_AIF_IN("AIF2RX2", NULL, 0,
519 ARIZONA_AIF2_RX_ENABLES, ARIZONA_AIF2RX2_ENA_SHIFT, 0),
520SND_SOC_DAPM_AIF_IN("AIF2RX3", NULL, 0,
521 ARIZONA_AIF2_RX_ENABLES, ARIZONA_AIF2RX3_ENA_SHIFT, 0),
522SND_SOC_DAPM_AIF_IN("AIF2RX4", NULL, 0,
523 ARIZONA_AIF2_RX_ENABLES, ARIZONA_AIF2RX4_ENA_SHIFT, 0),
524SND_SOC_DAPM_AIF_IN("AIF2RX5", NULL, 0,
525 ARIZONA_AIF2_RX_ENABLES, ARIZONA_AIF2RX5_ENA_SHIFT, 0),
526SND_SOC_DAPM_AIF_IN("AIF2RX6", NULL, 0,
527 ARIZONA_AIF2_RX_ENABLES, ARIZONA_AIF2RX6_ENA_SHIFT, 0),
528
529SND_SOC_DAPM_AIF_OUT("AIF3TX1", NULL, 0,
530 ARIZONA_AIF3_TX_ENABLES, ARIZONA_AIF3TX1_ENA_SHIFT, 0),
531SND_SOC_DAPM_AIF_OUT("AIF3TX2", NULL, 0,
532 ARIZONA_AIF3_TX_ENABLES, ARIZONA_AIF3TX2_ENA_SHIFT, 0),
533
534SND_SOC_DAPM_AIF_IN("AIF3RX1", NULL, 0,
535 ARIZONA_AIF3_RX_ENABLES, ARIZONA_AIF3RX1_ENA_SHIFT, 0),
536SND_SOC_DAPM_AIF_IN("AIF3RX2", NULL, 0,
537 ARIZONA_AIF3_RX_ENABLES, ARIZONA_AIF3RX2_ENA_SHIFT, 0),
538
539SND_SOC_DAPM_PGA_E("OUT1L", SND_SOC_NOPM,
540 ARIZONA_OUT1L_ENA_SHIFT, 0, NULL, 0, arizona_hp_ev,
541 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD |
542 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU),
543SND_SOC_DAPM_PGA_E("OUT1R", SND_SOC_NOPM,
544 ARIZONA_OUT1R_ENA_SHIFT, 0, NULL, 0, arizona_hp_ev,
545 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD |
546 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU),
547
548ARIZONA_MIXER_WIDGETS(EQ1, "EQ1"),
549ARIZONA_MIXER_WIDGETS(EQ2, "EQ2"),
550
551ARIZONA_MIXER_WIDGETS(DRC1L, "DRC1L"),
552ARIZONA_MIXER_WIDGETS(DRC1R, "DRC1R"),
553ARIZONA_MIXER_WIDGETS(DRC2L, "DRC2L"),
554ARIZONA_MIXER_WIDGETS(DRC2R, "DRC2R"),
555
556ARIZONA_MIXER_WIDGETS(LHPF1, "LHPF1"),
557ARIZONA_MIXER_WIDGETS(LHPF2, "LHPF2"),
558ARIZONA_MIXER_WIDGETS(LHPF3, "LHPF3"),
559ARIZONA_MIXER_WIDGETS(LHPF4, "LHPF4"),
560
561ARIZONA_MIXER_WIDGETS(PWM1, "PWM1"),
562ARIZONA_MIXER_WIDGETS(PWM2, "PWM2"),
563
564ARIZONA_MIXER_WIDGETS(OUT1L, "HPOUT1L"),
565ARIZONA_MIXER_WIDGETS(OUT1R, "HPOUT1R"),
566ARIZONA_MIXER_WIDGETS(SPKOUT, "SPKOUT"),
567
568ARIZONA_MIXER_WIDGETS(AIF1TX1, "AIF1TX1"),
569ARIZONA_MIXER_WIDGETS(AIF1TX2, "AIF1TX2"),
570ARIZONA_MIXER_WIDGETS(AIF1TX3, "AIF1TX3"),
571ARIZONA_MIXER_WIDGETS(AIF1TX4, "AIF1TX4"),
572ARIZONA_MIXER_WIDGETS(AIF1TX5, "AIF1TX5"),
573ARIZONA_MIXER_WIDGETS(AIF1TX6, "AIF1TX6"),
574ARIZONA_MIXER_WIDGETS(AIF1TX7, "AIF1TX7"),
575ARIZONA_MIXER_WIDGETS(AIF1TX8, "AIF1TX8"),
576
577ARIZONA_MIXER_WIDGETS(AIF2TX1, "AIF2TX1"),
578ARIZONA_MIXER_WIDGETS(AIF2TX2, "AIF2TX2"),
579ARIZONA_MIXER_WIDGETS(AIF2TX3, "AIF2TX3"),
580ARIZONA_MIXER_WIDGETS(AIF2TX4, "AIF2TX4"),
581ARIZONA_MIXER_WIDGETS(AIF2TX5, "AIF2TX5"),
582ARIZONA_MIXER_WIDGETS(AIF2TX6, "AIF2TX6"),
583
584ARIZONA_MIXER_WIDGETS(AIF3TX1, "AIF3TX1"),
585ARIZONA_MIXER_WIDGETS(AIF3TX2, "AIF3TX2"),
586
587ARIZONA_MUX_WIDGETS(ASRC1L, "ASRC1L"),
588ARIZONA_MUX_WIDGETS(ASRC1R, "ASRC1R"),
589ARIZONA_MUX_WIDGETS(ASRC2L, "ASRC2L"),
590ARIZONA_MUX_WIDGETS(ASRC2R, "ASRC2R"),
591
592ARIZONA_DSP_WIDGETS(DSP2, "DSP2"),
593ARIZONA_DSP_WIDGETS(DSP3, "DSP3"),
594
595ARIZONA_MUX_WIDGETS(ISRC1DEC1, "ISRC1DEC1"),
596ARIZONA_MUX_WIDGETS(ISRC1DEC2, "ISRC1DEC2"),
597ARIZONA_MUX_WIDGETS(ISRC1DEC3, "ISRC1DEC3"),
598ARIZONA_MUX_WIDGETS(ISRC1DEC4, "ISRC1DEC4"),
599
600ARIZONA_MUX_WIDGETS(ISRC1INT1, "ISRC1INT1"),
601ARIZONA_MUX_WIDGETS(ISRC1INT2, "ISRC1INT2"),
602ARIZONA_MUX_WIDGETS(ISRC1INT3, "ISRC1INT3"),
603ARIZONA_MUX_WIDGETS(ISRC1INT4, "ISRC1INT4"),
604
605ARIZONA_MUX_WIDGETS(ISRC2DEC1, "ISRC2DEC1"),
606ARIZONA_MUX_WIDGETS(ISRC2DEC2, "ISRC2DEC2"),
607ARIZONA_MUX_WIDGETS(ISRC2DEC3, "ISRC2DEC3"),
608ARIZONA_MUX_WIDGETS(ISRC2DEC4, "ISRC2DEC4"),
609
610ARIZONA_MUX_WIDGETS(ISRC2INT1, "ISRC2INT1"),
611ARIZONA_MUX_WIDGETS(ISRC2INT2, "ISRC2INT2"),
612ARIZONA_MUX_WIDGETS(ISRC2INT3, "ISRC2INT3"),
613ARIZONA_MUX_WIDGETS(ISRC2INT4, "ISRC2INT4"),
614
615ARIZONA_MUX_WIDGETS(ISRC3DEC1, "ISRC3DEC1"),
616ARIZONA_MUX_WIDGETS(ISRC3DEC2, "ISRC3DEC2"),
617ARIZONA_MUX_WIDGETS(ISRC3DEC3, "ISRC3DEC3"),
618ARIZONA_MUX_WIDGETS(ISRC3DEC4, "ISRC3DEC4"),
619
620ARIZONA_MUX_WIDGETS(ISRC3INT1, "ISRC3INT1"),
621ARIZONA_MUX_WIDGETS(ISRC3INT2, "ISRC3INT2"),
622ARIZONA_MUX_WIDGETS(ISRC3INT3, "ISRC3INT3"),
623ARIZONA_MUX_WIDGETS(ISRC3INT4, "ISRC3INT4"),
624
625SND_SOC_DAPM_OUTPUT("HPOUT1L"),
626SND_SOC_DAPM_OUTPUT("HPOUT1R"),
627SND_SOC_DAPM_OUTPUT("SPKOUTN"),
628SND_SOC_DAPM_OUTPUT("SPKOUTP"),
629
630SND_SOC_DAPM_OUTPUT("MICSUPP"),
631};
632
633#define ARIZONA_MIXER_INPUT_ROUTES(name) \
634 { name, "Noise Generator", "Noise Generator" }, \
635 { name, "Tone Generator 1", "Tone Generator 1" }, \
636 { name, "Tone Generator 2", "Tone Generator 2" }, \
637 { name, "Haptics", "HAPTICS" }, \
638 { name, "AEC", "AEC Loopback" }, \
639 { name, "IN1L", "IN1L PGA" }, \
640 { name, "IN1R", "IN1R PGA" }, \
641 { name, "IN2L", "IN2L PGA" }, \
642 { name, "IN2R", "IN2R PGA" }, \
643 { name, "AIF1RX1", "AIF1RX1" }, \
644 { name, "AIF1RX2", "AIF1RX2" }, \
645 { name, "AIF1RX3", "AIF1RX3" }, \
646 { name, "AIF1RX4", "AIF1RX4" }, \
647 { name, "AIF1RX5", "AIF1RX5" }, \
648 { name, "AIF1RX6", "AIF1RX6" }, \
649 { name, "AIF1RX7", "AIF1RX7" }, \
650 { name, "AIF1RX8", "AIF1RX8" }, \
651 { name, "AIF2RX1", "AIF2RX1" }, \
652 { name, "AIF2RX2", "AIF2RX2" }, \
653 { name, "AIF2RX3", "AIF2RX3" }, \
654 { name, "AIF2RX4", "AIF2RX4" }, \
655 { name, "AIF2RX5", "AIF2RX5" }, \
656 { name, "AIF2RX6", "AIF2RX6" }, \
657 { name, "AIF3RX1", "AIF3RX1" }, \
658 { name, "AIF3RX2", "AIF3RX2" }, \
659 { name, "EQ1", "EQ1" }, \
660 { name, "EQ2", "EQ2" }, \
661 { name, "DRC1L", "DRC1L" }, \
662 { name, "DRC1R", "DRC1R" }, \
663 { name, "DRC2L", "DRC2L" }, \
664 { name, "DRC2R", "DRC2R" }, \
665 { name, "LHPF1", "LHPF1" }, \
666 { name, "LHPF2", "LHPF2" }, \
667 { name, "LHPF3", "LHPF3" }, \
668 { name, "LHPF4", "LHPF4" }, \
669 { name, "ASRC1L", "ASRC1L" }, \
670 { name, "ASRC1R", "ASRC1R" }, \
671 { name, "ASRC2L", "ASRC2L" }, \
672 { name, "ASRC2R", "ASRC2R" }, \
673 { name, "ISRC1DEC1", "ISRC1DEC1" }, \
674 { name, "ISRC1DEC2", "ISRC1DEC2" }, \
675 { name, "ISRC1DEC3", "ISRC1DEC3" }, \
676 { name, "ISRC1DEC4", "ISRC1DEC4" }, \
677 { name, "ISRC1INT1", "ISRC1INT1" }, \
678 { name, "ISRC1INT2", "ISRC1INT2" }, \
679 { name, "ISRC1INT3", "ISRC1INT3" }, \
680 { name, "ISRC1INT4", "ISRC1INT4" }, \
681 { name, "ISRC2DEC1", "ISRC2DEC1" }, \
682 { name, "ISRC2DEC2", "ISRC2DEC2" }, \
683 { name, "ISRC2DEC3", "ISRC2DEC3" }, \
684 { name, "ISRC2DEC4", "ISRC2DEC4" }, \
685 { name, "ISRC2INT1", "ISRC2INT1" }, \
686 { name, "ISRC2INT2", "ISRC2INT2" }, \
687 { name, "ISRC2INT3", "ISRC2INT3" }, \
688 { name, "ISRC2INT4", "ISRC2INT4" }, \
689 { name, "ISRC3DEC1", "ISRC3DEC1" }, \
690 { name, "ISRC3DEC2", "ISRC3DEC2" }, \
691 { name, "ISRC3DEC3", "ISRC3DEC3" }, \
692 { name, "ISRC3DEC4", "ISRC3DEC4" }, \
693 { name, "ISRC3INT1", "ISRC3INT1" }, \
694 { name, "ISRC3INT2", "ISRC3INT2" }, \
695 { name, "ISRC3INT3", "ISRC3INT3" }, \
696 { name, "ISRC3INT4", "ISRC3INT4" }, \
697 { name, "DSP2.1", "DSP2" }, \
698 { name, "DSP2.2", "DSP2" }, \
699 { name, "DSP2.3", "DSP2" }, \
700 { name, "DSP2.4", "DSP2" }, \
701 { name, "DSP2.5", "DSP2" }, \
702 { name, "DSP2.6", "DSP2" }, \
703 { name, "DSP3.1", "DSP3" }, \
704 { name, "DSP3.2", "DSP3" }, \
705 { name, "DSP3.3", "DSP3" }, \
706 { name, "DSP3.4", "DSP3" }, \
707 { name, "DSP3.5", "DSP3" }, \
708 { name, "DSP3.6", "DSP3" }
709
710static const struct snd_soc_dapm_route cs47l24_dapm_routes[] = {
711 { "OUT1L", NULL, "CPVDD" },
712 { "OUT1R", NULL, "CPVDD" },
713
714 { "OUT4L", NULL, "SPKVDD" },
715
716 { "OUT1L", NULL, "SYSCLK" },
717 { "OUT1R", NULL, "SYSCLK" },
718 { "OUT4L", NULL, "SYSCLK" },
719
720 { "IN1L", NULL, "SYSCLK" },
721 { "IN1R", NULL, "SYSCLK" },
722 { "IN2L", NULL, "SYSCLK" },
723 { "IN2R", NULL, "SYSCLK" },
724
725 { "MICBIAS1", NULL, "MICVDD" },
726 { "MICBIAS2", NULL, "MICVDD" },
727
728 { "Noise Generator", NULL, "SYSCLK" },
729 { "Tone Generator 1", NULL, "SYSCLK" },
730 { "Tone Generator 2", NULL, "SYSCLK" },
731
732 { "Noise Generator", NULL, "NOISE" },
733 { "Tone Generator 1", NULL, "TONE" },
734 { "Tone Generator 2", NULL, "TONE" },
735
736 { "AIF1 Capture", NULL, "AIF1TX1" },
737 { "AIF1 Capture", NULL, "AIF1TX2" },
738 { "AIF1 Capture", NULL, "AIF1TX3" },
739 { "AIF1 Capture", NULL, "AIF1TX4" },
740 { "AIF1 Capture", NULL, "AIF1TX5" },
741 { "AIF1 Capture", NULL, "AIF1TX6" },
742 { "AIF1 Capture", NULL, "AIF1TX7" },
743 { "AIF1 Capture", NULL, "AIF1TX8" },
744
745 { "AIF1RX1", NULL, "AIF1 Playback" },
746 { "AIF1RX2", NULL, "AIF1 Playback" },
747 { "AIF1RX3", NULL, "AIF1 Playback" },
748 { "AIF1RX4", NULL, "AIF1 Playback" },
749 { "AIF1RX5", NULL, "AIF1 Playback" },
750 { "AIF1RX6", NULL, "AIF1 Playback" },
751 { "AIF1RX7", NULL, "AIF1 Playback" },
752 { "AIF1RX8", NULL, "AIF1 Playback" },
753
754 { "AIF2 Capture", NULL, "AIF2TX1" },
755 { "AIF2 Capture", NULL, "AIF2TX2" },
756 { "AIF2 Capture", NULL, "AIF2TX3" },
757 { "AIF2 Capture", NULL, "AIF2TX4" },
758 { "AIF2 Capture", NULL, "AIF2TX5" },
759 { "AIF2 Capture", NULL, "AIF2TX6" },
760
761 { "AIF2RX1", NULL, "AIF2 Playback" },
762 { "AIF2RX2", NULL, "AIF2 Playback" },
763 { "AIF2RX3", NULL, "AIF2 Playback" },
764 { "AIF2RX4", NULL, "AIF2 Playback" },
765 { "AIF2RX5", NULL, "AIF2 Playback" },
766 { "AIF2RX6", NULL, "AIF2 Playback" },
767
768 { "AIF3 Capture", NULL, "AIF3TX1" },
769 { "AIF3 Capture", NULL, "AIF3TX2" },
770
771 { "AIF3RX1", NULL, "AIF3 Playback" },
772 { "AIF3RX2", NULL, "AIF3 Playback" },
773
774 { "AIF1 Playback", NULL, "SYSCLK" },
775 { "AIF2 Playback", NULL, "SYSCLK" },
776 { "AIF3 Playback", NULL, "SYSCLK" },
777
778 { "AIF1 Capture", NULL, "SYSCLK" },
779 { "AIF2 Capture", NULL, "SYSCLK" },
780 { "AIF3 Capture", NULL, "SYSCLK" },
781
782 { "IN1L PGA", NULL, "IN1L" },
783 { "IN1R PGA", NULL, "IN1R" },
784
785 { "IN2L PGA", NULL, "IN2L" },
786 { "IN2R PGA", NULL, "IN2R" },
787
788 ARIZONA_MIXER_ROUTES("OUT1L", "HPOUT1L"),
789 ARIZONA_MIXER_ROUTES("OUT1R", "HPOUT1R"),
790
791 ARIZONA_MIXER_ROUTES("OUT4L", "SPKOUT"),
792
793 ARIZONA_MIXER_ROUTES("PWM1 Driver", "PWM1"),
794 ARIZONA_MIXER_ROUTES("PWM2 Driver", "PWM2"),
795
796 ARIZONA_MIXER_ROUTES("AIF1TX1", "AIF1TX1"),
797 ARIZONA_MIXER_ROUTES("AIF1TX2", "AIF1TX2"),
798 ARIZONA_MIXER_ROUTES("AIF1TX3", "AIF1TX3"),
799 ARIZONA_MIXER_ROUTES("AIF1TX4", "AIF1TX4"),
800 ARIZONA_MIXER_ROUTES("AIF1TX5", "AIF1TX5"),
801 ARIZONA_MIXER_ROUTES("AIF1TX6", "AIF1TX6"),
802 ARIZONA_MIXER_ROUTES("AIF1TX7", "AIF1TX7"),
803 ARIZONA_MIXER_ROUTES("AIF1TX8", "AIF1TX8"),
804
805 ARIZONA_MIXER_ROUTES("AIF2TX1", "AIF2TX1"),
806 ARIZONA_MIXER_ROUTES("AIF2TX2", "AIF2TX2"),
807 ARIZONA_MIXER_ROUTES("AIF2TX3", "AIF2TX3"),
808 ARIZONA_MIXER_ROUTES("AIF2TX4", "AIF2TX4"),
809 ARIZONA_MIXER_ROUTES("AIF2TX5", "AIF2TX5"),
810 ARIZONA_MIXER_ROUTES("AIF2TX6", "AIF2TX6"),
811
812 ARIZONA_MIXER_ROUTES("AIF3TX1", "AIF3TX1"),
813 ARIZONA_MIXER_ROUTES("AIF3TX2", "AIF3TX2"),
814
815 ARIZONA_MIXER_ROUTES("EQ1", "EQ1"),
816 ARIZONA_MIXER_ROUTES("EQ2", "EQ2"),
817
818 ARIZONA_MIXER_ROUTES("DRC1L", "DRC1L"),
819 ARIZONA_MIXER_ROUTES("DRC1R", "DRC1R"),
820 ARIZONA_MIXER_ROUTES("DRC2L", "DRC2L"),
821 ARIZONA_MIXER_ROUTES("DRC2R", "DRC2R"),
822
823 ARIZONA_MIXER_ROUTES("LHPF1", "LHPF1"),
824 ARIZONA_MIXER_ROUTES("LHPF2", "LHPF2"),
825 ARIZONA_MIXER_ROUTES("LHPF3", "LHPF3"),
826 ARIZONA_MIXER_ROUTES("LHPF4", "LHPF4"),
827
828 ARIZONA_MUX_ROUTES("ASRC1L", "ASRC1L"),
829 ARIZONA_MUX_ROUTES("ASRC1R", "ASRC1R"),
830 ARIZONA_MUX_ROUTES("ASRC2L", "ASRC2L"),
831 ARIZONA_MUX_ROUTES("ASRC2R", "ASRC2R"),
832
833 ARIZONA_DSP_ROUTES("DSP2"),
834 ARIZONA_DSP_ROUTES("DSP3"),
835
836 ARIZONA_MUX_ROUTES("ISRC1INT1", "ISRC1INT1"),
837 ARIZONA_MUX_ROUTES("ISRC1INT2", "ISRC1INT2"),
838 ARIZONA_MUX_ROUTES("ISRC1INT3", "ISRC1INT3"),
839 ARIZONA_MUX_ROUTES("ISRC1INT4", "ISRC1INT4"),
840
841 ARIZONA_MUX_ROUTES("ISRC1DEC1", "ISRC1DEC1"),
842 ARIZONA_MUX_ROUTES("ISRC1DEC2", "ISRC1DEC2"),
843 ARIZONA_MUX_ROUTES("ISRC1DEC3", "ISRC1DEC3"),
844 ARIZONA_MUX_ROUTES("ISRC1DEC4", "ISRC1DEC4"),
845
846 ARIZONA_MUX_ROUTES("ISRC2INT1", "ISRC2INT1"),
847 ARIZONA_MUX_ROUTES("ISRC2INT2", "ISRC2INT2"),
848 ARIZONA_MUX_ROUTES("ISRC2INT3", "ISRC2INT3"),
849 ARIZONA_MUX_ROUTES("ISRC2INT4", "ISRC2INT4"),
850
851 ARIZONA_MUX_ROUTES("ISRC2DEC1", "ISRC2DEC1"),
852 ARIZONA_MUX_ROUTES("ISRC2DEC2", "ISRC2DEC2"),
853 ARIZONA_MUX_ROUTES("ISRC2DEC3", "ISRC2DEC3"),
854 ARIZONA_MUX_ROUTES("ISRC2DEC4", "ISRC2DEC4"),
855
856 ARIZONA_MUX_ROUTES("ISRC3INT1", "ISRC3INT1"),
857 ARIZONA_MUX_ROUTES("ISRC3INT2", "ISRC3INT2"),
858 ARIZONA_MUX_ROUTES("ISRC3INT3", "ISRC3INT3"),
859 ARIZONA_MUX_ROUTES("ISRC3INT4", "ISRC3INT4"),
860
861 ARIZONA_MUX_ROUTES("ISRC3DEC1", "ISRC3DEC1"),
862 ARIZONA_MUX_ROUTES("ISRC3DEC2", "ISRC3DEC2"),
863 ARIZONA_MUX_ROUTES("ISRC3DEC3", "ISRC3DEC3"),
864 ARIZONA_MUX_ROUTES("ISRC3DEC4", "ISRC3DEC4"),
865
866 { "AEC Loopback", "HPOUT1L", "OUT1L" },
867 { "AEC Loopback", "HPOUT1R", "OUT1R" },
868 { "HPOUT1L", NULL, "OUT1L" },
869 { "HPOUT1R", NULL, "OUT1R" },
870
871 { "AEC Loopback", "SPKOUT", "OUT4L" },
872 { "SPKOUTN", NULL, "OUT4L" },
873 { "SPKOUTP", NULL, "OUT4L" },
874
875 { "MICSUPP", NULL, "SYSCLK" },
876
877 { "DRC1 Signal Activity", NULL, "DRC1L" },
878 { "DRC1 Signal Activity", NULL, "DRC1R" },
879 { "DRC2 Signal Activity", NULL, "DRC2L" },
880 { "DRC2 Signal Activity", NULL, "DRC2R" },
881};
882
883static int cs47l24_set_fll(struct snd_soc_codec *codec, int fll_id, int source,
884 unsigned int Fref, unsigned int Fout)
885{
886 struct cs47l24_priv *cs47l24 = snd_soc_codec_get_drvdata(codec);
887
888 switch (fll_id) {
889 case CS47L24_FLL1:
890 return arizona_set_fll(&cs47l24->fll[0], source, Fref, Fout);
891 case CS47L24_FLL2:
892 return arizona_set_fll(&cs47l24->fll[1], source, Fref, Fout);
893 case CS47L24_FLL1_REFCLK:
894 return arizona_set_fll_refclk(&cs47l24->fll[0], source, Fref,
895 Fout);
896 case CS47L24_FLL2_REFCLK:
897 return arizona_set_fll_refclk(&cs47l24->fll[1], source, Fref,
898 Fout);
899 default:
900 return -EINVAL;
901 }
902}
903
904#define CS47L24_RATES SNDRV_PCM_RATE_8000_192000
905
906#define CS47L24_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
907 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
908
909static struct snd_soc_dai_driver cs47l24_dai[] = {
910 {
911 .name = "cs47l24-aif1",
912 .id = 1,
913 .base = ARIZONA_AIF1_BCLK_CTRL,
914 .playback = {
915 .stream_name = "AIF1 Playback",
916 .channels_min = 1,
917 .channels_max = 8,
918 .rates = CS47L24_RATES,
919 .formats = CS47L24_FORMATS,
920 },
921 .capture = {
922 .stream_name = "AIF1 Capture",
923 .channels_min = 1,
924 .channels_max = 8,
925 .rates = CS47L24_RATES,
926 .formats = CS47L24_FORMATS,
927 },
928 .ops = &arizona_dai_ops,
929 .symmetric_rates = 1,
930 .symmetric_samplebits = 1,
931 },
932 {
933 .name = "cs47l24-aif2",
934 .id = 2,
935 .base = ARIZONA_AIF2_BCLK_CTRL,
936 .playback = {
937 .stream_name = "AIF2 Playback",
938 .channels_min = 1,
939 .channels_max = 6,
940 .rates = CS47L24_RATES,
941 .formats = CS47L24_FORMATS,
942 },
943 .capture = {
944 .stream_name = "AIF2 Capture",
945 .channels_min = 1,
946 .channels_max = 6,
947 .rates = CS47L24_RATES,
948 .formats = CS47L24_FORMATS,
949 },
950 .ops = &arizona_dai_ops,
951 .symmetric_rates = 1,
952 .symmetric_samplebits = 1,
953 },
954 {
955 .name = "cs47l24-aif3",
956 .id = 3,
957 .base = ARIZONA_AIF3_BCLK_CTRL,
958 .playback = {
959 .stream_name = "AIF3 Playback",
960 .channels_min = 1,
961 .channels_max = 2,
962 .rates = CS47L24_RATES,
963 .formats = CS47L24_FORMATS,
964 },
965 .capture = {
966 .stream_name = "AIF3 Capture",
967 .channels_min = 1,
968 .channels_max = 2,
969 .rates = CS47L24_RATES,
970 .formats = CS47L24_FORMATS,
971 },
972 .ops = &arizona_dai_ops,
973 .symmetric_rates = 1,
974 .symmetric_samplebits = 1,
975 },
976};
977
978static int cs47l24_codec_probe(struct snd_soc_codec *codec)
979{
980 struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
981 struct cs47l24_priv *priv = snd_soc_codec_get_drvdata(codec);
982 int ret;
983
984 priv->core.arizona->dapm = dapm;
985
986 arizona_init_spk(codec);
987 arizona_init_gpio(codec);
988 arizona_init_mono(codec);
989
990 ret = wm_adsp2_codec_probe(&priv->core.adsp[1], codec);
991 if (ret)
992 goto err_adsp2_codec_probe;
993
994 ret = wm_adsp2_codec_probe(&priv->core.adsp[2], codec);
995 if (ret)
996 goto err_adsp2_codec_probe;
997
998 ret = snd_soc_add_codec_controls(codec,
999 &arizona_adsp2_rate_controls[1], 2);
1000 if (ret)
1001 goto err_adsp2_codec_probe;
1002
1003 snd_soc_dapm_disable_pin(dapm, "HAPTICS");
1004
1005 return 0;
1006
1007err_adsp2_codec_probe:
1008 wm_adsp2_codec_remove(&priv->core.adsp[1], codec);
1009 wm_adsp2_codec_remove(&priv->core.adsp[2], codec);
1010
1011 return ret;
1012}
1013
1014static int cs47l24_codec_remove(struct snd_soc_codec *codec)
1015{
1016 struct cs47l24_priv *priv = snd_soc_codec_get_drvdata(codec);
1017
1018
1019 wm_adsp2_codec_remove(&priv->core.adsp[1], codec);
1020 wm_adsp2_codec_remove(&priv->core.adsp[2], codec);
1021
1022 priv->core.arizona->dapm = NULL;
1023
1024 return 0;
1025}
1026
1027#define CS47L24_DIG_VU 0x0200
1028
1029static unsigned int cs47l24_digital_vu[] = {
1030 ARIZONA_DAC_DIGITAL_VOLUME_1L,
1031 ARIZONA_DAC_DIGITAL_VOLUME_1R,
1032 ARIZONA_DAC_DIGITAL_VOLUME_4L,
1033};
1034
1035static struct regmap *cs47l24_get_regmap(struct device *dev)
1036{
1037 struct cs47l24_priv *priv = dev_get_drvdata(dev);
1038
1039 return priv->core.arizona->regmap;
1040}
1041
1042static struct snd_soc_codec_driver soc_codec_dev_cs47l24 = {
1043 .probe = cs47l24_codec_probe,
1044 .remove = cs47l24_codec_remove,
1045 .get_regmap = cs47l24_get_regmap,
1046
1047 .idle_bias_off = true,
1048
1049 .set_sysclk = arizona_set_sysclk,
1050 .set_pll = cs47l24_set_fll,
1051
1052 .controls = cs47l24_snd_controls,
1053 .num_controls = ARRAY_SIZE(cs47l24_snd_controls),
1054 .dapm_widgets = cs47l24_dapm_widgets,
1055 .num_dapm_widgets = ARRAY_SIZE(cs47l24_dapm_widgets),
1056 .dapm_routes = cs47l24_dapm_routes,
1057 .num_dapm_routes = ARRAY_SIZE(cs47l24_dapm_routes),
1058};
1059
1060static int cs47l24_probe(struct platform_device *pdev)
1061{
1062 struct arizona *arizona = dev_get_drvdata(pdev->dev.parent);
1063 struct cs47l24_priv *cs47l24;
1064 int i, ret;
1065
1066 BUILD_BUG_ON(ARRAY_SIZE(cs47l24_dai) > ARIZONA_MAX_DAI);
1067
1068 cs47l24 = devm_kzalloc(&pdev->dev, sizeof(struct cs47l24_priv),
1069 GFP_KERNEL);
1070 if (!cs47l24)
1071 return -ENOMEM;
1072
1073 platform_set_drvdata(pdev, cs47l24);
1074
1075 cs47l24->core.arizona = arizona;
1076 cs47l24->core.num_inputs = 4;
1077
1078 for (i = 1; i <= 2; i++) {
1079 cs47l24->core.adsp[i].part = "cs47l24";
1080 cs47l24->core.adsp[i].num = i + 1;
1081 cs47l24->core.adsp[i].type = WMFW_ADSP2;
1082 cs47l24->core.adsp[i].dev = arizona->dev;
1083 cs47l24->core.adsp[i].regmap = arizona->regmap;
1084
1085 cs47l24->core.adsp[i].base = ARIZONA_DSP1_CONTROL_1 +
1086 (0x100 * i);
1087 cs47l24->core.adsp[i].mem = cs47l24_dsp_regions[i - 1];
1088 cs47l24->core.adsp[i].num_mems =
1089 ARRAY_SIZE(cs47l24_dsp2_regions);
1090
1091 ret = wm_adsp2_init(&cs47l24->core.adsp[i]);
1092 if (ret != 0)
1093 return ret;
1094 }
1095
1096 for (i = 0; i < ARRAY_SIZE(cs47l24->fll); i++)
1097 cs47l24->fll[i].vco_mult = 3;
1098
1099 arizona_init_fll(arizona, 1, ARIZONA_FLL1_CONTROL_1 - 1,
1100 ARIZONA_IRQ_FLL1_LOCK, ARIZONA_IRQ_FLL1_CLOCK_OK,
1101 &cs47l24->fll[0]);
1102 arizona_init_fll(arizona, 2, ARIZONA_FLL2_CONTROL_1 - 1,
1103 ARIZONA_IRQ_FLL2_LOCK, ARIZONA_IRQ_FLL2_CLOCK_OK,
1104 &cs47l24->fll[1]);
1105
1106 /* SR2 fixed at 8kHz, SR3 fixed at 16kHz */
1107 regmap_update_bits(arizona->regmap, ARIZONA_SAMPLE_RATE_2,
1108 ARIZONA_SAMPLE_RATE_2_MASK, 0x11);
1109 regmap_update_bits(arizona->regmap, ARIZONA_SAMPLE_RATE_3,
1110 ARIZONA_SAMPLE_RATE_3_MASK, 0x12);
1111
1112 for (i = 0; i < ARRAY_SIZE(cs47l24_dai); i++)
1113 arizona_init_dai(&cs47l24->core, i);
1114
1115 /* Latch volume update bits */
1116 for (i = 0; i < ARRAY_SIZE(cs47l24_digital_vu); i++)
1117 regmap_update_bits(arizona->regmap, cs47l24_digital_vu[i],
1118 CS47L24_DIG_VU, CS47L24_DIG_VU);
1119
1120 pm_runtime_enable(&pdev->dev);
1121 pm_runtime_idle(&pdev->dev);
1122
1123 return snd_soc_register_codec(&pdev->dev, &soc_codec_dev_cs47l24,
1124 cs47l24_dai, ARRAY_SIZE(cs47l24_dai));
1125}
1126
1127static int cs47l24_remove(struct platform_device *pdev)
1128{
1129 snd_soc_unregister_codec(&pdev->dev);
1130 pm_runtime_disable(&pdev->dev);
1131
1132 return 0;
1133}
1134
1135static struct platform_driver cs47l24_codec_driver = {
1136 .driver = {
1137 .name = "cs47l24-codec",
1138 },
1139 .probe = cs47l24_probe,
1140 .remove = cs47l24_remove,
1141};
1142
1143module_platform_driver(cs47l24_codec_driver);
1144
1145MODULE_DESCRIPTION("ASoC CS47L24 driver");
1146MODULE_AUTHOR("Richard Fitzgerald <rf@opensource.wolfsonmicro.com>");
1147MODULE_LICENSE("GPL v2");
1148MODULE_ALIAS("platform:cs47l24-codec");
diff --git a/sound/soc/codecs/cs47l24.h b/sound/soc/codecs/cs47l24.h
new file mode 100644
index 000000000000..77ab2b77b2e6
--- /dev/null
+++ b/sound/soc/codecs/cs47l24.h
@@ -0,0 +1,23 @@
1/*
2 * cs47l24.h -- ALSA SoC Audio driver for Cirrus Logic CS47L24
3 *
4 * Copyright 2015 Cirrus Logic Inc.
5 *
6 * Author: Richard Fitzgerald <rf@opensource.wolfsonmicro.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 */
12
13#ifndef _CS47L24_H
14#define _CS47L24_H
15
16#include "arizona.h"
17
18#define CS47L24_FLL1 1
19#define CS47L24_FLL2 2
20#define CS47L24_FLL1_REFCLK 3
21#define CS47L24_FLL2_REFCLK 4
22
23#endif
diff --git a/sound/soc/codecs/da7218.c b/sound/soc/codecs/da7218.c
new file mode 100644
index 000000000000..93575f251866
--- /dev/null
+++ b/sound/soc/codecs/da7218.c
@@ -0,0 +1,3341 @@
1/*
2 * da7218.c - DA7218 ALSA SoC Codec Driver
3 *
4 * Copyright (c) 2015 Dialog Semiconductor
5 *
6 * Author: Adam Thomson <Adam.Thomson.Opensource@diasemi.com>
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the
10 * Free Software Foundation; either version 2 of the License, or (at your
11 * option) any later version.
12 */
13
14#include <linux/clk.h>
15#include <linux/i2c.h>
16#include <linux/of_device.h>
17#include <linux/regmap.h>
18#include <linux/slab.h>
19#include <linux/pm.h>
20#include <linux/module.h>
21#include <linux/delay.h>
22#include <linux/regulator/consumer.h>
23#include <sound/pcm.h>
24#include <sound/pcm_params.h>
25#include <sound/soc.h>
26#include <sound/soc-dapm.h>
27#include <sound/jack.h>
28#include <sound/initval.h>
29#include <sound/tlv.h>
30#include <asm/div64.h>
31
32#include <sound/da7218.h>
33#include "da7218.h"
34
35
36/*
37 * TLVs and Enums
38 */
39
40/* Input TLVs */
41static const DECLARE_TLV_DB_SCALE(da7218_mic_gain_tlv, -600, 600, 0);
42static const DECLARE_TLV_DB_SCALE(da7218_mixin_gain_tlv, -450, 150, 0);
43static const DECLARE_TLV_DB_SCALE(da7218_in_dig_gain_tlv, -8325, 75, 0);
44static const DECLARE_TLV_DB_SCALE(da7218_ags_trigger_tlv, -9000, 600, 0);
45static const DECLARE_TLV_DB_SCALE(da7218_ags_att_max_tlv, 0, 600, 0);
46static const DECLARE_TLV_DB_SCALE(da7218_alc_threshold_tlv, -9450, 150, 0);
47static const DECLARE_TLV_DB_SCALE(da7218_alc_gain_tlv, 0, 600, 0);
48static const DECLARE_TLV_DB_SCALE(da7218_alc_ana_gain_tlv, 0, 600, 0);
49
50/* Input/Output TLVs */
51static const DECLARE_TLV_DB_SCALE(da7218_dmix_gain_tlv, -4200, 150, 0);
52
53/* Output TLVs */
54static const DECLARE_TLV_DB_SCALE(da7218_dgs_trigger_tlv, -9450, 150, 0);
55static const DECLARE_TLV_DB_SCALE(da7218_dgs_anticlip_tlv, -4200, 600, 0);
56static const DECLARE_TLV_DB_SCALE(da7218_dgs_signal_tlv, -9000, 600, 0);
57static const DECLARE_TLV_DB_SCALE(da7218_out_eq_band_tlv, -1050, 150, 0);
58static const DECLARE_TLV_DB_SCALE(da7218_out_dig_gain_tlv, -8325, 75, 0);
59static const DECLARE_TLV_DB_SCALE(da7218_dac_ng_threshold_tlv, -10200, 600, 0);
60static const DECLARE_TLV_DB_SCALE(da7218_mixout_gain_tlv, -100, 50, 0);
61static const DECLARE_TLV_DB_SCALE(da7218_hp_gain_tlv, -5700, 150, 0);
62
63/* Input Enums */
64static const char * const da7218_alc_attack_rate_txt[] = {
65 "7.33/fs", "14.66/fs", "29.32/fs", "58.64/fs", "117.3/fs", "234.6/fs",
66 "469.1/fs", "938.2/fs", "1876/fs", "3753/fs", "7506/fs", "15012/fs",
67 "30024/fs",
68};
69
70static const struct soc_enum da7218_alc_attack_rate =
71 SOC_ENUM_SINGLE(DA7218_ALC_CTRL2, DA7218_ALC_ATTACK_SHIFT,
72 DA7218_ALC_ATTACK_MAX, da7218_alc_attack_rate_txt);
73
74static const char * const da7218_alc_release_rate_txt[] = {
75 "28.66/fs", "57.33/fs", "114.6/fs", "229.3/fs", "458.6/fs", "917.1/fs",
76 "1834/fs", "3668/fs", "7337/fs", "14674/fs", "29348/fs",
77};
78
79static const struct soc_enum da7218_alc_release_rate =
80 SOC_ENUM_SINGLE(DA7218_ALC_CTRL2, DA7218_ALC_RELEASE_SHIFT,
81 DA7218_ALC_RELEASE_MAX, da7218_alc_release_rate_txt);
82
83static const char * const da7218_alc_hold_time_txt[] = {
84 "62/fs", "124/fs", "248/fs", "496/fs", "992/fs", "1984/fs", "3968/fs",
85 "7936/fs", "15872/fs", "31744/fs", "63488/fs", "126976/fs",
86 "253952/fs", "507904/fs", "1015808/fs", "2031616/fs"
87};
88
89static const struct soc_enum da7218_alc_hold_time =
90 SOC_ENUM_SINGLE(DA7218_ALC_CTRL3, DA7218_ALC_HOLD_SHIFT,
91 DA7218_ALC_HOLD_MAX, da7218_alc_hold_time_txt);
92
93static const char * const da7218_alc_anticlip_step_txt[] = {
94 "0.034dB/fs", "0.068dB/fs", "0.136dB/fs", "0.272dB/fs",
95};
96
97static const struct soc_enum da7218_alc_anticlip_step =
98 SOC_ENUM_SINGLE(DA7218_ALC_ANTICLIP_CTRL,
99 DA7218_ALC_ANTICLIP_STEP_SHIFT,
100 DA7218_ALC_ANTICLIP_STEP_MAX,
101 da7218_alc_anticlip_step_txt);
102
103static const char * const da7218_integ_rate_txt[] = {
104 "1/4", "1/16", "1/256", "1/65536"
105};
106
107static const struct soc_enum da7218_integ_attack_rate =
108 SOC_ENUM_SINGLE(DA7218_ENV_TRACK_CTRL, DA7218_INTEG_ATTACK_SHIFT,
109 DA7218_INTEG_MAX, da7218_integ_rate_txt);
110
111static const struct soc_enum da7218_integ_release_rate =
112 SOC_ENUM_SINGLE(DA7218_ENV_TRACK_CTRL, DA7218_INTEG_RELEASE_SHIFT,
113 DA7218_INTEG_MAX, da7218_integ_rate_txt);
114
115/* Input/Output Enums */
116static const char * const da7218_gain_ramp_rate_txt[] = {
117 "Nominal Rate * 8", "Nominal Rate", "Nominal Rate / 8",
118 "Nominal Rate / 16",
119};
120
121static const struct soc_enum da7218_gain_ramp_rate =
122 SOC_ENUM_SINGLE(DA7218_GAIN_RAMP_CTRL, DA7218_GAIN_RAMP_RATE_SHIFT,
123 DA7218_GAIN_RAMP_RATE_MAX, da7218_gain_ramp_rate_txt);
124
125static const char * const da7218_hpf_mode_txt[] = {
126 "Disabled", "Audio", "Voice",
127};
128
129static const unsigned int da7218_hpf_mode_val[] = {
130 DA7218_HPF_DISABLED, DA7218_HPF_AUDIO_EN, DA7218_HPF_VOICE_EN,
131};
132
133static const struct soc_enum da7218_in1_hpf_mode =
134 SOC_VALUE_ENUM_SINGLE(DA7218_IN_1_HPF_FILTER_CTRL,
135 DA7218_HPF_MODE_SHIFT, DA7218_HPF_MODE_MASK,
136 DA7218_HPF_MODE_MAX, da7218_hpf_mode_txt,
137 da7218_hpf_mode_val);
138
139static const struct soc_enum da7218_in2_hpf_mode =
140 SOC_VALUE_ENUM_SINGLE(DA7218_IN_2_HPF_FILTER_CTRL,
141 DA7218_HPF_MODE_SHIFT, DA7218_HPF_MODE_MASK,
142 DA7218_HPF_MODE_MAX, da7218_hpf_mode_txt,
143 da7218_hpf_mode_val);
144
145static const struct soc_enum da7218_out1_hpf_mode =
146 SOC_VALUE_ENUM_SINGLE(DA7218_OUT_1_HPF_FILTER_CTRL,
147 DA7218_HPF_MODE_SHIFT, DA7218_HPF_MODE_MASK,
148 DA7218_HPF_MODE_MAX, da7218_hpf_mode_txt,
149 da7218_hpf_mode_val);
150
151static const char * const da7218_audio_hpf_corner_txt[] = {
152 "2Hz", "4Hz", "8Hz", "16Hz",
153};
154
155static const struct soc_enum da7218_in1_audio_hpf_corner =
156 SOC_ENUM_SINGLE(DA7218_IN_1_HPF_FILTER_CTRL,
157 DA7218_IN_1_AUDIO_HPF_CORNER_SHIFT,
158 DA7218_AUDIO_HPF_CORNER_MAX,
159 da7218_audio_hpf_corner_txt);
160
161static const struct soc_enum da7218_in2_audio_hpf_corner =
162 SOC_ENUM_SINGLE(DA7218_IN_2_HPF_FILTER_CTRL,
163 DA7218_IN_2_AUDIO_HPF_CORNER_SHIFT,
164 DA7218_AUDIO_HPF_CORNER_MAX,
165 da7218_audio_hpf_corner_txt);
166
167static const struct soc_enum da7218_out1_audio_hpf_corner =
168 SOC_ENUM_SINGLE(DA7218_OUT_1_HPF_FILTER_CTRL,
169 DA7218_OUT_1_AUDIO_HPF_CORNER_SHIFT,
170 DA7218_AUDIO_HPF_CORNER_MAX,
171 da7218_audio_hpf_corner_txt);
172
173static const char * const da7218_voice_hpf_corner_txt[] = {
174 "2.5Hz", "25Hz", "50Hz", "100Hz", "150Hz", "200Hz", "300Hz", "400Hz",
175};
176
177static const struct soc_enum da7218_in1_voice_hpf_corner =
178 SOC_ENUM_SINGLE(DA7218_IN_1_HPF_FILTER_CTRL,
179 DA7218_IN_1_VOICE_HPF_CORNER_SHIFT,
180 DA7218_VOICE_HPF_CORNER_MAX,
181 da7218_voice_hpf_corner_txt);
182
183static const struct soc_enum da7218_in2_voice_hpf_corner =
184 SOC_ENUM_SINGLE(DA7218_IN_2_HPF_FILTER_CTRL,
185 DA7218_IN_2_VOICE_HPF_CORNER_SHIFT,
186 DA7218_VOICE_HPF_CORNER_MAX,
187 da7218_voice_hpf_corner_txt);
188
189static const struct soc_enum da7218_out1_voice_hpf_corner =
190 SOC_ENUM_SINGLE(DA7218_OUT_1_HPF_FILTER_CTRL,
191 DA7218_OUT_1_VOICE_HPF_CORNER_SHIFT,
192 DA7218_VOICE_HPF_CORNER_MAX,
193 da7218_voice_hpf_corner_txt);
194
195static const char * const da7218_tonegen_dtmf_key_txt[] = {
196 "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D",
197 "*", "#"
198};
199
200static const struct soc_enum da7218_tonegen_dtmf_key =
201 SOC_ENUM_SINGLE(DA7218_TONE_GEN_CFG1, DA7218_DTMF_REG_SHIFT,
202 DA7218_DTMF_REG_MAX, da7218_tonegen_dtmf_key_txt);
203
204static const char * const da7218_tonegen_swg_sel_txt[] = {
205 "Sum", "SWG1", "SWG2", "SWG1_1-Cos"
206};
207
208static const struct soc_enum da7218_tonegen_swg_sel =
209 SOC_ENUM_SINGLE(DA7218_TONE_GEN_CFG2, DA7218_SWG_SEL_SHIFT,
210 DA7218_SWG_SEL_MAX, da7218_tonegen_swg_sel_txt);
211
212/* Output Enums */
213static const char * const da7218_dgs_rise_coeff_txt[] = {
214 "1/1", "1/16", "1/64", "1/256", "1/1024", "1/4096", "1/16384",
215};
216
217static const struct soc_enum da7218_dgs_rise_coeff =
218 SOC_ENUM_SINGLE(DA7218_DGS_RISE_FALL, DA7218_DGS_RISE_COEFF_SHIFT,
219 DA7218_DGS_RISE_COEFF_MAX, da7218_dgs_rise_coeff_txt);
220
221static const char * const da7218_dgs_fall_coeff_txt[] = {
222 "1/4", "1/16", "1/64", "1/256", "1/1024", "1/4096", "1/16384", "1/65536",
223};
224
225static const struct soc_enum da7218_dgs_fall_coeff =
226 SOC_ENUM_SINGLE(DA7218_DGS_RISE_FALL, DA7218_DGS_FALL_COEFF_SHIFT,
227 DA7218_DGS_FALL_COEFF_MAX, da7218_dgs_fall_coeff_txt);
228
229static const char * const da7218_dac_ng_setup_time_txt[] = {
230 "256 Samples", "512 Samples", "1024 Samples", "2048 Samples"
231};
232
233static const struct soc_enum da7218_dac_ng_setup_time =
234 SOC_ENUM_SINGLE(DA7218_DAC_NG_SETUP_TIME,
235 DA7218_DAC_NG_SETUP_TIME_SHIFT,
236 DA7218_DAC_NG_SETUP_TIME_MAX,
237 da7218_dac_ng_setup_time_txt);
238
239static const char * const da7218_dac_ng_rampup_txt[] = {
240 "0.22ms/dB", "0.0138ms/dB"
241};
242
243static const struct soc_enum da7218_dac_ng_rampup_rate =
244 SOC_ENUM_SINGLE(DA7218_DAC_NG_SETUP_TIME,
245 DA7218_DAC_NG_RAMPUP_RATE_SHIFT,
246 DA7218_DAC_NG_RAMPUP_RATE_MAX,
247 da7218_dac_ng_rampup_txt);
248
249static const char * const da7218_dac_ng_rampdown_txt[] = {
250 "0.88ms/dB", "14.08ms/dB"
251};
252
253static const struct soc_enum da7218_dac_ng_rampdown_rate =
254 SOC_ENUM_SINGLE(DA7218_DAC_NG_SETUP_TIME,
255 DA7218_DAC_NG_RAMPDN_RATE_SHIFT,
256 DA7218_DAC_NG_RAMPDN_RATE_MAX,
257 da7218_dac_ng_rampdown_txt);
258
259static const char * const da7218_cp_mchange_txt[] = {
260 "Largest Volume", "DAC Volume", "Signal Magnitude"
261};
262
263static const unsigned int da7218_cp_mchange_val[] = {
264 DA7218_CP_MCHANGE_LARGEST_VOL, DA7218_CP_MCHANGE_DAC_VOL,
265 DA7218_CP_MCHANGE_SIG_MAG
266};
267
268static const struct soc_enum da7218_cp_mchange =
269 SOC_VALUE_ENUM_SINGLE(DA7218_CP_CTRL, DA7218_CP_MCHANGE_SHIFT,
270 DA7218_CP_MCHANGE_REL_MASK, DA7218_CP_MCHANGE_MAX,
271 da7218_cp_mchange_txt, da7218_cp_mchange_val);
272
273static const char * const da7218_cp_fcontrol_txt[] = {
274 "1MHz", "500KHz", "250KHz", "125KHz", "63KHz", "0KHz"
275};
276
277static const struct soc_enum da7218_cp_fcontrol =
278 SOC_ENUM_SINGLE(DA7218_CP_DELAY, DA7218_CP_FCONTROL_SHIFT,
279 DA7218_CP_FCONTROL_MAX, da7218_cp_fcontrol_txt);
280
281static const char * const da7218_cp_tau_delay_txt[] = {
282 "0ms", "2ms", "4ms", "16ms", "64ms", "128ms", "256ms", "512ms"
283};
284
285static const struct soc_enum da7218_cp_tau_delay =
286 SOC_ENUM_SINGLE(DA7218_CP_DELAY, DA7218_CP_TAU_DELAY_SHIFT,
287 DA7218_CP_TAU_DELAY_MAX, da7218_cp_tau_delay_txt);
288
289/*
290 * Control Functions
291 */
292
293/* ALC */
294static void da7218_alc_calib(struct snd_soc_codec *codec)
295{
296 u8 mic_1_ctrl, mic_2_ctrl;
297 u8 mixin_1_ctrl, mixin_2_ctrl;
298 u8 in_1l_filt_ctrl, in_1r_filt_ctrl, in_2l_filt_ctrl, in_2r_filt_ctrl;
299 u8 in_1_hpf_ctrl, in_2_hpf_ctrl;
300 u8 calib_ctrl;
301 int i = 0;
302 bool calibrated = false;
303
304 /* Save current state of MIC control registers */
305 mic_1_ctrl = snd_soc_read(codec, DA7218_MIC_1_CTRL);
306 mic_2_ctrl = snd_soc_read(codec, DA7218_MIC_2_CTRL);
307
308 /* Save current state of input mixer control registers */
309 mixin_1_ctrl = snd_soc_read(codec, DA7218_MIXIN_1_CTRL);
310 mixin_2_ctrl = snd_soc_read(codec, DA7218_MIXIN_2_CTRL);
311
312 /* Save current state of input filter control registers */
313 in_1l_filt_ctrl = snd_soc_read(codec, DA7218_IN_1L_FILTER_CTRL);
314 in_1r_filt_ctrl = snd_soc_read(codec, DA7218_IN_1R_FILTER_CTRL);
315 in_2l_filt_ctrl = snd_soc_read(codec, DA7218_IN_2L_FILTER_CTRL);
316 in_2r_filt_ctrl = snd_soc_read(codec, DA7218_IN_2R_FILTER_CTRL);
317
318 /* Save current state of input HPF control registers */
319 in_1_hpf_ctrl = snd_soc_read(codec, DA7218_IN_1_HPF_FILTER_CTRL);
320 in_2_hpf_ctrl = snd_soc_read(codec, DA7218_IN_2_HPF_FILTER_CTRL);
321
322 /* Enable then Mute MIC PGAs */
323 snd_soc_update_bits(codec, DA7218_MIC_1_CTRL, DA7218_MIC_1_AMP_EN_MASK,
324 DA7218_MIC_1_AMP_EN_MASK);
325 snd_soc_update_bits(codec, DA7218_MIC_2_CTRL, DA7218_MIC_2_AMP_EN_MASK,
326 DA7218_MIC_2_AMP_EN_MASK);
327 snd_soc_update_bits(codec, DA7218_MIC_1_CTRL,
328 DA7218_MIC_1_AMP_MUTE_EN_MASK,
329 DA7218_MIC_1_AMP_MUTE_EN_MASK);
330 snd_soc_update_bits(codec, DA7218_MIC_2_CTRL,
331 DA7218_MIC_2_AMP_MUTE_EN_MASK,
332 DA7218_MIC_2_AMP_MUTE_EN_MASK);
333
334 /* Enable input mixers unmuted */
335 snd_soc_update_bits(codec, DA7218_MIXIN_1_CTRL,
336 DA7218_MIXIN_1_AMP_EN_MASK |
337 DA7218_MIXIN_1_AMP_MUTE_EN_MASK,
338 DA7218_MIXIN_1_AMP_EN_MASK);
339 snd_soc_update_bits(codec, DA7218_MIXIN_2_CTRL,
340 DA7218_MIXIN_2_AMP_EN_MASK |
341 DA7218_MIXIN_2_AMP_MUTE_EN_MASK,
342 DA7218_MIXIN_2_AMP_EN_MASK);
343
344 /* Enable input filters unmuted */
345 snd_soc_update_bits(codec, DA7218_IN_1L_FILTER_CTRL,
346 DA7218_IN_1L_FILTER_EN_MASK |
347 DA7218_IN_1L_MUTE_EN_MASK,
348 DA7218_IN_1L_FILTER_EN_MASK);
349 snd_soc_update_bits(codec, DA7218_IN_1R_FILTER_CTRL,
350 DA7218_IN_1R_FILTER_EN_MASK |
351 DA7218_IN_1R_MUTE_EN_MASK,
352 DA7218_IN_1R_FILTER_EN_MASK);
353 snd_soc_update_bits(codec, DA7218_IN_2L_FILTER_CTRL,
354 DA7218_IN_2L_FILTER_EN_MASK |
355 DA7218_IN_2L_MUTE_EN_MASK,
356 DA7218_IN_2L_FILTER_EN_MASK);
357 snd_soc_update_bits(codec, DA7218_IN_2R_FILTER_CTRL,
358 DA7218_IN_2R_FILTER_EN_MASK |
359 DA7218_IN_2R_MUTE_EN_MASK,
360 DA7218_IN_2R_FILTER_EN_MASK);
361
362 /*
363 * Make sure input HPFs voice mode is disabled, otherwise for sampling
364 * rates above 32KHz the ADC signals will be stopped and will cause
365 * calibration to lock up.
366 */
367 snd_soc_update_bits(codec, DA7218_IN_1_HPF_FILTER_CTRL,
368 DA7218_IN_1_VOICE_EN_MASK, 0);
369 snd_soc_update_bits(codec, DA7218_IN_2_HPF_FILTER_CTRL,
370 DA7218_IN_2_VOICE_EN_MASK, 0);
371
372 /* Perform auto calibration */
373 snd_soc_update_bits(codec, DA7218_CALIB_CTRL, DA7218_CALIB_AUTO_EN_MASK,
374 DA7218_CALIB_AUTO_EN_MASK);
375 do {
376 calib_ctrl = snd_soc_read(codec, DA7218_CALIB_CTRL);
377 if (calib_ctrl & DA7218_CALIB_AUTO_EN_MASK) {
378 ++i;
379 usleep_range(DA7218_ALC_CALIB_DELAY_MIN,
380 DA7218_ALC_CALIB_DELAY_MAX);
381 } else {
382 calibrated = true;
383 }
384
385 } while ((i < DA7218_ALC_CALIB_MAX_TRIES) && (!calibrated));
386
387 /* If auto calibration fails, disable DC offset, hybrid ALC */
388 if ((!calibrated) || (calib_ctrl & DA7218_CALIB_OVERFLOW_MASK)) {
389 dev_warn(codec->dev,
390 "ALC auto calibration failed - %s\n",
391 (calibrated) ? "overflow" : "timeout");
392 snd_soc_update_bits(codec, DA7218_CALIB_CTRL,
393 DA7218_CALIB_OFFSET_EN_MASK, 0);
394 snd_soc_update_bits(codec, DA7218_ALC_CTRL1,
395 DA7218_ALC_SYNC_MODE_MASK, 0);
396
397 } else {
398 /* Enable DC offset cancellation */
399 snd_soc_update_bits(codec, DA7218_CALIB_CTRL,
400 DA7218_CALIB_OFFSET_EN_MASK,
401 DA7218_CALIB_OFFSET_EN_MASK);
402
403 /* Enable ALC hybrid mode */
404 snd_soc_update_bits(codec, DA7218_ALC_CTRL1,
405 DA7218_ALC_SYNC_MODE_MASK,
406 DA7218_ALC_SYNC_MODE_CH1 |
407 DA7218_ALC_SYNC_MODE_CH2);
408 }
409
410 /* Restore input HPF control registers to original states */
411 snd_soc_write(codec, DA7218_IN_1_HPF_FILTER_CTRL, in_1_hpf_ctrl);
412 snd_soc_write(codec, DA7218_IN_2_HPF_FILTER_CTRL, in_2_hpf_ctrl);
413
414 /* Restore input filter control registers to original states */
415 snd_soc_write(codec, DA7218_IN_1L_FILTER_CTRL, in_1l_filt_ctrl);
416 snd_soc_write(codec, DA7218_IN_1R_FILTER_CTRL, in_1r_filt_ctrl);
417 snd_soc_write(codec, DA7218_IN_2L_FILTER_CTRL, in_2l_filt_ctrl);
418 snd_soc_write(codec, DA7218_IN_2R_FILTER_CTRL, in_2r_filt_ctrl);
419
420 /* Restore input mixer control registers to original state */
421 snd_soc_write(codec, DA7218_MIXIN_1_CTRL, mixin_1_ctrl);
422 snd_soc_write(codec, DA7218_MIXIN_2_CTRL, mixin_2_ctrl);
423
424 /* Restore MIC control registers to original states */
425 snd_soc_write(codec, DA7218_MIC_1_CTRL, mic_1_ctrl);
426 snd_soc_write(codec, DA7218_MIC_2_CTRL, mic_2_ctrl);
427}
428
429static int da7218_mixin_gain_put(struct snd_kcontrol *kcontrol,
430 struct snd_ctl_elem_value *ucontrol)
431{
432 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
433 struct da7218_priv *da7218 = snd_soc_codec_get_drvdata(codec);
434 int ret;
435
436 ret = snd_soc_put_volsw(kcontrol, ucontrol);
437
438 /*
439 * If ALC in operation and value of control has been updated,
440 * make sure calibrated offsets are updated.
441 */
442 if ((ret == 1) && (da7218->alc_en))
443 da7218_alc_calib(codec);
444
445 return ret;
446}
447
448static int da7218_alc_sw_put(struct snd_kcontrol *kcontrol,
449 struct snd_ctl_elem_value *ucontrol)
450{
451 struct soc_mixer_control *mc =
452 (struct soc_mixer_control *) kcontrol->private_value;
453 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
454 struct da7218_priv *da7218 = snd_soc_codec_get_drvdata(codec);
455 unsigned int lvalue = ucontrol->value.integer.value[0];
456 unsigned int rvalue = ucontrol->value.integer.value[1];
457 unsigned int lshift = mc->shift;
458 unsigned int rshift = mc->rshift;
459 unsigned int mask = (mc->max << lshift) | (mc->max << rshift);
460
461 /* Force ALC offset calibration if enabling ALC */
462 if ((lvalue || rvalue) && (!da7218->alc_en))
463 da7218_alc_calib(codec);
464
465 /* Update bits to detail which channels are enabled/disabled */
466 da7218->alc_en &= ~mask;
467 da7218->alc_en |= (lvalue << lshift) | (rvalue << rshift);
468
469 return snd_soc_put_volsw(kcontrol, ucontrol);
470}
471
472/* ToneGen */
473static int da7218_tonegen_freq_get(struct snd_kcontrol *kcontrol,
474 struct snd_ctl_elem_value *ucontrol)
475{
476 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
477 struct da7218_priv *da7218 = snd_soc_codec_get_drvdata(codec);
478 struct soc_mixer_control *mixer_ctrl =
479 (struct soc_mixer_control *) kcontrol->private_value;
480 unsigned int reg = mixer_ctrl->reg;
481 u16 val;
482 int ret;
483
484 /*
485 * Frequency value spans two 8-bit registers, lower then upper byte.
486 * Therefore we need to convert to host endianness here.
487 */
488 ret = regmap_raw_read(da7218->regmap, reg, &val, 2);
489 if (ret)
490 return ret;
491
492 ucontrol->value.integer.value[0] = le16_to_cpu(val);
493
494 return 0;
495}
496
497static int da7218_tonegen_freq_put(struct snd_kcontrol *kcontrol,
498 struct snd_ctl_elem_value *ucontrol)
499{
500 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
501 struct da7218_priv *da7218 = snd_soc_codec_get_drvdata(codec);
502 struct soc_mixer_control *mixer_ctrl =
503 (struct soc_mixer_control *) kcontrol->private_value;
504 unsigned int reg = mixer_ctrl->reg;
505 u16 val;
506
507 /*
508 * Frequency value spans two 8-bit registers, lower then upper byte.
509 * Therefore we need to convert to little endian here to align with
510 * HW registers.
511 */
512 val = cpu_to_le16(ucontrol->value.integer.value[0]);
513
514 return regmap_raw_write(da7218->regmap, reg, &val, 2);
515}
516
517static int da7218_mic_lvl_det_sw_put(struct snd_kcontrol *kcontrol,
518 struct snd_ctl_elem_value *ucontrol)
519{
520 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
521 struct da7218_priv *da7218 = snd_soc_codec_get_drvdata(codec);
522 struct soc_mixer_control *mixer_ctrl =
523 (struct soc_mixer_control *) kcontrol->private_value;
524 unsigned int lvalue = ucontrol->value.integer.value[0];
525 unsigned int rvalue = ucontrol->value.integer.value[1];
526 unsigned int lshift = mixer_ctrl->shift;
527 unsigned int rshift = mixer_ctrl->rshift;
528 unsigned int mask = (mixer_ctrl->max << lshift) |
529 (mixer_ctrl->max << rshift);
530 da7218->mic_lvl_det_en &= ~mask;
531 da7218->mic_lvl_det_en |= (lvalue << lshift) | (rvalue << rshift);
532
533 /*
534 * Here we only enable the feature on paths which are already
535 * powered. If a channel is enabled here for level detect, but that path
536 * isn't powered, then the channel will actually be enabled when we do
537 * power the path (IN_FILTER widget events). This handling avoids
538 * unwanted level detect events.
539 */
540 return snd_soc_write(codec, mixer_ctrl->reg,
541 (da7218->in_filt_en & da7218->mic_lvl_det_en));
542}
543
544static int da7218_mic_lvl_det_sw_get(struct snd_kcontrol *kcontrol,
545 struct snd_ctl_elem_value *ucontrol)
546{
547 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
548 struct da7218_priv *da7218 = snd_soc_codec_get_drvdata(codec);
549 struct soc_mixer_control *mixer_ctrl =
550 (struct soc_mixer_control *) kcontrol->private_value;
551 unsigned int lshift = mixer_ctrl->shift;
552 unsigned int rshift = mixer_ctrl->rshift;
553 unsigned int lmask = (mixer_ctrl->max << lshift);
554 unsigned int rmask = (mixer_ctrl->max << rshift);
555
556 ucontrol->value.integer.value[0] =
557 (da7218->mic_lvl_det_en & lmask) >> lshift;
558 ucontrol->value.integer.value[1] =
559 (da7218->mic_lvl_det_en & rmask) >> rshift;
560
561 return 0;
562}
563
564static int da7218_biquad_coeff_get(struct snd_kcontrol *kcontrol,
565 struct snd_ctl_elem_value *ucontrol)
566{
567 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
568 struct da7218_priv *da7218 = snd_soc_codec_get_drvdata(codec);
569 struct soc_bytes_ext *bytes_ext =
570 (struct soc_bytes_ext *) kcontrol->private_value;
571
572 /* Determine which BiQuads we're setting based on size of config data */
573 switch (bytes_ext->max) {
574 case DA7218_OUT_1_BIQ_5STAGE_CFG_SIZE:
575 memcpy(ucontrol->value.bytes.data, da7218->biq_5stage_coeff,
576 bytes_ext->max);
577 break;
578 case DA7218_SIDETONE_BIQ_3STAGE_CFG_SIZE:
579 memcpy(ucontrol->value.bytes.data, da7218->stbiq_3stage_coeff,
580 bytes_ext->max);
581 break;
582 default:
583 return -EINVAL;
584 }
585
586 return 0;
587}
588
589static int da7218_biquad_coeff_put(struct snd_kcontrol *kcontrol,
590 struct snd_ctl_elem_value *ucontrol)
591{
592 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
593 struct da7218_priv *da7218 = snd_soc_codec_get_drvdata(codec);
594 struct soc_bytes_ext *bytes_ext =
595 (struct soc_bytes_ext *) kcontrol->private_value;
596 u8 reg, out_filt1l;
597 u8 cfg[DA7218_BIQ_CFG_SIZE];
598 int i;
599
600 /*
601 * Determine which BiQuads we're setting based on size of config data,
602 * and stored the data for use by get function.
603 */
604 switch (bytes_ext->max) {
605 case DA7218_OUT_1_BIQ_5STAGE_CFG_SIZE:
606 reg = DA7218_OUT_1_BIQ_5STAGE_DATA;
607 memcpy(da7218->biq_5stage_coeff, ucontrol->value.bytes.data,
608 bytes_ext->max);
609 break;
610 case DA7218_SIDETONE_BIQ_3STAGE_CFG_SIZE:
611 reg = DA7218_SIDETONE_BIQ_3STAGE_DATA;
612 memcpy(da7218->stbiq_3stage_coeff, ucontrol->value.bytes.data,
613 bytes_ext->max);
614 break;
615 default:
616 return -EINVAL;
617 }
618
619 /* Make sure at least out filter1 enabled to allow programming */
620 out_filt1l = snd_soc_read(codec, DA7218_OUT_1L_FILTER_CTRL);
621 snd_soc_write(codec, DA7218_OUT_1L_FILTER_CTRL,
622 out_filt1l | DA7218_OUT_1L_FILTER_EN_MASK);
623
624 for (i = 0; i < bytes_ext->max; ++i) {
625 cfg[DA7218_BIQ_CFG_DATA] = ucontrol->value.bytes.data[i];
626 cfg[DA7218_BIQ_CFG_ADDR] = i;
627 regmap_raw_write(da7218->regmap, reg, cfg, DA7218_BIQ_CFG_SIZE);
628 }
629
630 /* Restore filter to previous setting */
631 snd_soc_write(codec, DA7218_OUT_1L_FILTER_CTRL, out_filt1l);
632
633 return 0;
634}
635
636
637/*
638 * KControls
639 */
640
641static const struct snd_kcontrol_new da7218_snd_controls[] = {
642 /* Mics */
643 SOC_SINGLE_TLV("Mic1 Volume", DA7218_MIC_1_GAIN,
644 DA7218_MIC_1_AMP_GAIN_SHIFT, DA7218_MIC_AMP_GAIN_MAX,
645 DA7218_NO_INVERT, da7218_mic_gain_tlv),
646 SOC_SINGLE("Mic1 Switch", DA7218_MIC_1_CTRL,
647 DA7218_MIC_1_AMP_MUTE_EN_SHIFT, DA7218_SWITCH_EN_MAX,
648 DA7218_INVERT),
649 SOC_SINGLE_TLV("Mic2 Volume", DA7218_MIC_2_GAIN,
650 DA7218_MIC_2_AMP_GAIN_SHIFT, DA7218_MIC_AMP_GAIN_MAX,
651 DA7218_NO_INVERT, da7218_mic_gain_tlv),
652 SOC_SINGLE("Mic2 Switch", DA7218_MIC_2_CTRL,
653 DA7218_MIC_2_AMP_MUTE_EN_SHIFT, DA7218_SWITCH_EN_MAX,
654 DA7218_INVERT),
655
656 /* Mixer Input */
657 SOC_SINGLE_EXT_TLV("Mixin1 Volume", DA7218_MIXIN_1_GAIN,
658 DA7218_MIXIN_1_AMP_GAIN_SHIFT,
659 DA7218_MIXIN_AMP_GAIN_MAX, DA7218_NO_INVERT,
660 snd_soc_get_volsw, da7218_mixin_gain_put,
661 da7218_mixin_gain_tlv),
662 SOC_SINGLE("Mixin1 Switch", DA7218_MIXIN_1_CTRL,
663 DA7218_MIXIN_1_AMP_MUTE_EN_SHIFT, DA7218_SWITCH_EN_MAX,
664 DA7218_INVERT),
665 SOC_SINGLE("Mixin1 Gain Ramp Switch", DA7218_MIXIN_1_CTRL,
666 DA7218_MIXIN_1_AMP_RAMP_EN_SHIFT, DA7218_SWITCH_EN_MAX,
667 DA7218_NO_INVERT),
668 SOC_SINGLE("Mixin1 ZC Gain Switch", DA7218_MIXIN_1_CTRL,
669 DA7218_MIXIN_1_AMP_ZC_EN_SHIFT, DA7218_SWITCH_EN_MAX,
670 DA7218_NO_INVERT),
671 SOC_SINGLE_EXT_TLV("Mixin2 Volume", DA7218_MIXIN_2_GAIN,
672 DA7218_MIXIN_2_AMP_GAIN_SHIFT,
673 DA7218_MIXIN_AMP_GAIN_MAX, DA7218_NO_INVERT,
674 snd_soc_get_volsw, da7218_mixin_gain_put,
675 da7218_mixin_gain_tlv),
676 SOC_SINGLE("Mixin2 Switch", DA7218_MIXIN_2_CTRL,
677 DA7218_MIXIN_2_AMP_MUTE_EN_SHIFT, DA7218_SWITCH_EN_MAX,
678 DA7218_INVERT),
679 SOC_SINGLE("Mixin2 Gain Ramp Switch", DA7218_MIXIN_2_CTRL,
680 DA7218_MIXIN_2_AMP_RAMP_EN_SHIFT, DA7218_SWITCH_EN_MAX,
681 DA7218_NO_INVERT),
682 SOC_SINGLE("Mixin2 ZC Gain Switch", DA7218_MIXIN_2_CTRL,
683 DA7218_MIXIN_2_AMP_ZC_EN_SHIFT, DA7218_SWITCH_EN_MAX,
684 DA7218_NO_INVERT),
685
686 /* ADCs */
687 SOC_SINGLE("ADC1 AAF Switch", DA7218_ADC_1_CTRL,
688 DA7218_ADC_1_AAF_EN_SHIFT, DA7218_SWITCH_EN_MAX,
689 DA7218_NO_INVERT),
690 SOC_SINGLE("ADC2 AAF Switch", DA7218_ADC_2_CTRL,
691 DA7218_ADC_2_AAF_EN_SHIFT, DA7218_SWITCH_EN_MAX,
692 DA7218_NO_INVERT),
693 SOC_SINGLE("ADC LP Mode Switch", DA7218_ADC_MODE,
694 DA7218_ADC_LP_MODE_SHIFT, DA7218_SWITCH_EN_MAX,
695 DA7218_NO_INVERT),
696
697 /* Input Filters */
698 SOC_SINGLE_TLV("In Filter1L Volume", DA7218_IN_1L_GAIN,
699 DA7218_IN_1L_DIGITAL_GAIN_SHIFT,
700 DA7218_IN_DIGITAL_GAIN_MAX, DA7218_NO_INVERT,
701 da7218_in_dig_gain_tlv),
702 SOC_SINGLE("In Filter1L Switch", DA7218_IN_1L_FILTER_CTRL,
703 DA7218_IN_1L_MUTE_EN_SHIFT, DA7218_SWITCH_EN_MAX,
704 DA7218_INVERT),
705 SOC_SINGLE("In Filter1L Gain Ramp Switch", DA7218_IN_1L_FILTER_CTRL,
706 DA7218_IN_1L_RAMP_EN_SHIFT, DA7218_SWITCH_EN_MAX,
707 DA7218_NO_INVERT),
708 SOC_SINGLE_TLV("In Filter1R Volume", DA7218_IN_1R_GAIN,
709 DA7218_IN_1R_DIGITAL_GAIN_SHIFT,
710 DA7218_IN_DIGITAL_GAIN_MAX, DA7218_NO_INVERT,
711 da7218_in_dig_gain_tlv),
712 SOC_SINGLE("In Filter1R Switch", DA7218_IN_1R_FILTER_CTRL,
713 DA7218_IN_1R_MUTE_EN_SHIFT, DA7218_SWITCH_EN_MAX,
714 DA7218_INVERT),
715 SOC_SINGLE("In Filter1R Gain Ramp Switch",
716 DA7218_IN_1R_FILTER_CTRL, DA7218_IN_1R_RAMP_EN_SHIFT,
717 DA7218_SWITCH_EN_MAX, DA7218_NO_INVERT),
718 SOC_SINGLE_TLV("In Filter2L Volume", DA7218_IN_2L_GAIN,
719 DA7218_IN_2L_DIGITAL_GAIN_SHIFT,
720 DA7218_IN_DIGITAL_GAIN_MAX, DA7218_NO_INVERT,
721 da7218_in_dig_gain_tlv),
722 SOC_SINGLE("In Filter2L Switch", DA7218_IN_2L_FILTER_CTRL,
723 DA7218_IN_2L_MUTE_EN_SHIFT, DA7218_SWITCH_EN_MAX,
724 DA7218_INVERT),
725 SOC_SINGLE("In Filter2L Gain Ramp Switch", DA7218_IN_2L_FILTER_CTRL,
726 DA7218_IN_2L_RAMP_EN_SHIFT, DA7218_SWITCH_EN_MAX,
727 DA7218_NO_INVERT),
728 SOC_SINGLE_TLV("In Filter2R Volume", DA7218_IN_2R_GAIN,
729 DA7218_IN_2R_DIGITAL_GAIN_SHIFT,
730 DA7218_IN_DIGITAL_GAIN_MAX, DA7218_NO_INVERT,
731 da7218_in_dig_gain_tlv),
732 SOC_SINGLE("In Filter2R Switch", DA7218_IN_2R_FILTER_CTRL,
733 DA7218_IN_2R_MUTE_EN_SHIFT, DA7218_SWITCH_EN_MAX,
734 DA7218_INVERT),
735 SOC_SINGLE("In Filter2R Gain Ramp Switch",
736 DA7218_IN_2R_FILTER_CTRL, DA7218_IN_2R_RAMP_EN_SHIFT,
737 DA7218_SWITCH_EN_MAX, DA7218_NO_INVERT),
738
739 /* AGS */
740 SOC_SINGLE_TLV("AGS Trigger", DA7218_AGS_TRIGGER,
741 DA7218_AGS_TRIGGER_SHIFT, DA7218_AGS_TRIGGER_MAX,
742 DA7218_INVERT, da7218_ags_trigger_tlv),
743 SOC_SINGLE_TLV("AGS Max Attenuation", DA7218_AGS_ATT_MAX,
744 DA7218_AGS_ATT_MAX_SHIFT, DA7218_AGS_ATT_MAX_MAX,
745 DA7218_NO_INVERT, da7218_ags_att_max_tlv),
746 SOC_SINGLE("AGS Anticlip Switch", DA7218_AGS_ANTICLIP_CTRL,
747 DA7218_AGS_ANTICLIP_EN_SHIFT, DA7218_SWITCH_EN_MAX,
748 DA7218_NO_INVERT),
749 SOC_SINGLE("AGS Channel1 Switch", DA7218_AGS_ENABLE,
750 DA7218_AGS_ENABLE_CHAN1_SHIFT, DA7218_SWITCH_EN_MAX,
751 DA7218_NO_INVERT),
752 SOC_SINGLE("AGS Channel2 Switch", DA7218_AGS_ENABLE,
753 DA7218_AGS_ENABLE_CHAN2_SHIFT, DA7218_SWITCH_EN_MAX,
754 DA7218_NO_INVERT),
755
756 /* ALC */
757 SOC_ENUM("ALC Attack Rate", da7218_alc_attack_rate),
758 SOC_ENUM("ALC Release Rate", da7218_alc_release_rate),
759 SOC_ENUM("ALC Hold Time", da7218_alc_hold_time),
760 SOC_SINGLE_TLV("ALC Noise Threshold", DA7218_ALC_NOISE,
761 DA7218_ALC_NOISE_SHIFT, DA7218_ALC_THRESHOLD_MAX,
762 DA7218_INVERT, da7218_alc_threshold_tlv),
763 SOC_SINGLE_TLV("ALC Min Threshold", DA7218_ALC_TARGET_MIN,
764 DA7218_ALC_THRESHOLD_MIN_SHIFT, DA7218_ALC_THRESHOLD_MAX,
765 DA7218_INVERT, da7218_alc_threshold_tlv),
766 SOC_SINGLE_TLV("ALC Max Threshold", DA7218_ALC_TARGET_MAX,
767 DA7218_ALC_THRESHOLD_MAX_SHIFT, DA7218_ALC_THRESHOLD_MAX,
768 DA7218_INVERT, da7218_alc_threshold_tlv),
769 SOC_SINGLE_TLV("ALC Max Attenuation", DA7218_ALC_GAIN_LIMITS,
770 DA7218_ALC_ATTEN_MAX_SHIFT, DA7218_ALC_ATTEN_GAIN_MAX,
771 DA7218_NO_INVERT, da7218_alc_gain_tlv),
772 SOC_SINGLE_TLV("ALC Max Gain", DA7218_ALC_GAIN_LIMITS,
773 DA7218_ALC_GAIN_MAX_SHIFT, DA7218_ALC_ATTEN_GAIN_MAX,
774 DA7218_NO_INVERT, da7218_alc_gain_tlv),
775 SOC_SINGLE_RANGE_TLV("ALC Min Analog Gain", DA7218_ALC_ANA_GAIN_LIMITS,
776 DA7218_ALC_ANA_GAIN_MIN_SHIFT,
777 DA7218_ALC_ANA_GAIN_MIN, DA7218_ALC_ANA_GAIN_MAX,
778 DA7218_NO_INVERT, da7218_alc_ana_gain_tlv),
779 SOC_SINGLE_RANGE_TLV("ALC Max Analog Gain", DA7218_ALC_ANA_GAIN_LIMITS,
780 DA7218_ALC_ANA_GAIN_MAX_SHIFT,
781 DA7218_ALC_ANA_GAIN_MIN, DA7218_ALC_ANA_GAIN_MAX,
782 DA7218_NO_INVERT, da7218_alc_ana_gain_tlv),
783 SOC_ENUM("ALC Anticlip Step", da7218_alc_anticlip_step),
784 SOC_SINGLE("ALC Anticlip Switch", DA7218_ALC_ANTICLIP_CTRL,
785 DA7218_ALC_ANTICLIP_EN_SHIFT, DA7218_SWITCH_EN_MAX,
786 DA7218_NO_INVERT),
787 SOC_DOUBLE_EXT("ALC Channel1 Switch", DA7218_ALC_CTRL1,
788 DA7218_ALC_CHAN1_L_EN_SHIFT, DA7218_ALC_CHAN1_R_EN_SHIFT,
789 DA7218_SWITCH_EN_MAX, DA7218_NO_INVERT,
790 snd_soc_get_volsw, da7218_alc_sw_put),
791 SOC_DOUBLE_EXT("ALC Channel2 Switch", DA7218_ALC_CTRL1,
792 DA7218_ALC_CHAN2_L_EN_SHIFT, DA7218_ALC_CHAN2_R_EN_SHIFT,
793 DA7218_SWITCH_EN_MAX, DA7218_NO_INVERT,
794 snd_soc_get_volsw, da7218_alc_sw_put),
795
796 /* Envelope Tracking */
797 SOC_ENUM("Envelope Tracking Attack Rate", da7218_integ_attack_rate),
798 SOC_ENUM("Envelope Tracking Release Rate", da7218_integ_release_rate),
799
800 /* Input High-Pass Filters */
801 SOC_ENUM("In Filter1 HPF Mode", da7218_in1_hpf_mode),
802 SOC_ENUM("In Filter1 HPF Corner Audio", da7218_in1_audio_hpf_corner),
803 SOC_ENUM("In Filter1 HPF Corner Voice", da7218_in1_voice_hpf_corner),
804 SOC_ENUM("In Filter2 HPF Mode", da7218_in2_hpf_mode),
805 SOC_ENUM("In Filter2 HPF Corner Audio", da7218_in2_audio_hpf_corner),
806 SOC_ENUM("In Filter2 HPF Corner Voice", da7218_in2_voice_hpf_corner),
807
808 /* Mic Level Detect */
809 SOC_DOUBLE_EXT("Mic Level Detect Channel1 Switch", DA7218_LVL_DET_CTRL,
810 DA7218_LVL_DET_EN_CHAN1L_SHIFT,
811 DA7218_LVL_DET_EN_CHAN1R_SHIFT, DA7218_SWITCH_EN_MAX,
812 DA7218_NO_INVERT, da7218_mic_lvl_det_sw_get,
813 da7218_mic_lvl_det_sw_put),
814 SOC_DOUBLE_EXT("Mic Level Detect Channel2 Switch", DA7218_LVL_DET_CTRL,
815 DA7218_LVL_DET_EN_CHAN2L_SHIFT,
816 DA7218_LVL_DET_EN_CHAN2R_SHIFT, DA7218_SWITCH_EN_MAX,
817 DA7218_NO_INVERT, da7218_mic_lvl_det_sw_get,
818 da7218_mic_lvl_det_sw_put),
819 SOC_SINGLE("Mic Level Detect Level", DA7218_LVL_DET_LEVEL,
820 DA7218_LVL_DET_LEVEL_SHIFT, DA7218_LVL_DET_LEVEL_MAX,
821 DA7218_NO_INVERT),
822
823 /* Digital Mixer (Input) */
824 SOC_SINGLE_TLV("DMix In Filter1L Out1 DAIL Volume",
825 DA7218_DMIX_OUTDAI_1L_INFILT_1L_GAIN,
826 DA7218_OUTDAI_1L_INFILT_1L_GAIN_SHIFT,
827 DA7218_DMIX_GAIN_MAX, DA7218_NO_INVERT,
828 da7218_dmix_gain_tlv),
829 SOC_SINGLE_TLV("DMix In Filter1L Out1 DAIR Volume",
830 DA7218_DMIX_OUTDAI_1R_INFILT_1L_GAIN,
831 DA7218_OUTDAI_1R_INFILT_1L_GAIN_SHIFT,
832 DA7218_DMIX_GAIN_MAX, DA7218_NO_INVERT,
833 da7218_dmix_gain_tlv),
834 SOC_SINGLE_TLV("DMix In Filter1L Out2 DAIL Volume",
835 DA7218_DMIX_OUTDAI_2L_INFILT_1L_GAIN,
836 DA7218_OUTDAI_2L_INFILT_1L_GAIN_SHIFT,
837 DA7218_DMIX_GAIN_MAX, DA7218_NO_INVERT,
838 da7218_dmix_gain_tlv),
839 SOC_SINGLE_TLV("DMix In Filter1L Out2 DAIR Volume",
840 DA7218_DMIX_OUTDAI_2R_INFILT_1L_GAIN,
841 DA7218_OUTDAI_2R_INFILT_1L_GAIN_SHIFT,
842 DA7218_DMIX_GAIN_MAX, DA7218_NO_INVERT,
843 da7218_dmix_gain_tlv),
844
845 SOC_SINGLE_TLV("DMix In Filter1R Out1 DAIL Volume",
846 DA7218_DMIX_OUTDAI_1L_INFILT_1R_GAIN,
847 DA7218_OUTDAI_1L_INFILT_1R_GAIN_SHIFT,
848 DA7218_DMIX_GAIN_MAX, DA7218_NO_INVERT,
849 da7218_dmix_gain_tlv),
850 SOC_SINGLE_TLV("DMix In Filter1R Out1 DAIR Volume",
851 DA7218_DMIX_OUTDAI_1R_INFILT_1R_GAIN,
852 DA7218_OUTDAI_1R_INFILT_1R_GAIN_SHIFT,
853 DA7218_DMIX_GAIN_MAX, DA7218_NO_INVERT,
854 da7218_dmix_gain_tlv),
855 SOC_SINGLE_TLV("DMix In Filter1R Out2 DAIL Volume",
856 DA7218_DMIX_OUTDAI_2L_INFILT_1R_GAIN,
857 DA7218_OUTDAI_2L_INFILT_1R_GAIN_SHIFT,
858 DA7218_DMIX_GAIN_MAX, DA7218_NO_INVERT,
859 da7218_dmix_gain_tlv),
860 SOC_SINGLE_TLV("DMix In Filter1R Out2 DAIR Volume",
861 DA7218_DMIX_OUTDAI_2R_INFILT_1R_GAIN,
862 DA7218_OUTDAI_2R_INFILT_1R_GAIN_SHIFT,
863 DA7218_DMIX_GAIN_MAX, DA7218_NO_INVERT,
864 da7218_dmix_gain_tlv),
865
866 SOC_SINGLE_TLV("DMix In Filter2L Out1 DAIL Volume",
867 DA7218_DMIX_OUTDAI_1L_INFILT_2L_GAIN,
868 DA7218_OUTDAI_1L_INFILT_2L_GAIN_SHIFT,
869 DA7218_DMIX_GAIN_MAX, DA7218_NO_INVERT,
870 da7218_dmix_gain_tlv),
871 SOC_SINGLE_TLV("DMix In Filter2L Out1 DAIR Volume",
872 DA7218_DMIX_OUTDAI_1R_INFILT_2L_GAIN,
873 DA7218_OUTDAI_1R_INFILT_2L_GAIN_SHIFT,
874 DA7218_DMIX_GAIN_MAX, DA7218_NO_INVERT,
875 da7218_dmix_gain_tlv),
876 SOC_SINGLE_TLV("DMix In Filter2L Out2 DAIL Volume",
877 DA7218_DMIX_OUTDAI_2L_INFILT_2L_GAIN,
878 DA7218_OUTDAI_2L_INFILT_2L_GAIN_SHIFT,
879 DA7218_DMIX_GAIN_MAX, DA7218_NO_INVERT,
880 da7218_dmix_gain_tlv),
881 SOC_SINGLE_TLV("DMix In Filter2L Out2 DAIR Volume",
882 DA7218_DMIX_OUTDAI_2R_INFILT_2L_GAIN,
883 DA7218_OUTDAI_2R_INFILT_2L_GAIN_SHIFT,
884 DA7218_DMIX_GAIN_MAX, DA7218_NO_INVERT,
885 da7218_dmix_gain_tlv),
886
887 SOC_SINGLE_TLV("DMix In Filter2R Out1 DAIL Volume",
888 DA7218_DMIX_OUTDAI_1L_INFILT_2R_GAIN,
889 DA7218_OUTDAI_1L_INFILT_2R_GAIN_SHIFT,
890 DA7218_DMIX_GAIN_MAX, DA7218_NO_INVERT,
891 da7218_dmix_gain_tlv),
892 SOC_SINGLE_TLV("DMix In Filter2R Out1 DAIR Volume",
893 DA7218_DMIX_OUTDAI_1R_INFILT_2R_GAIN,
894 DA7218_OUTDAI_1R_INFILT_2R_GAIN_SHIFT,
895 DA7218_DMIX_GAIN_MAX, DA7218_NO_INVERT,
896 da7218_dmix_gain_tlv),
897 SOC_SINGLE_TLV("DMix In Filter2R Out2 DAIL Volume",
898 DA7218_DMIX_OUTDAI_2L_INFILT_2R_GAIN,
899 DA7218_OUTDAI_2L_INFILT_2R_GAIN_SHIFT,
900 DA7218_DMIX_GAIN_MAX, DA7218_NO_INVERT,
901 da7218_dmix_gain_tlv),
902 SOC_SINGLE_TLV("DMix In Filter2R Out2 DAIR Volume",
903 DA7218_DMIX_OUTDAI_2R_INFILT_2R_GAIN,
904 DA7218_OUTDAI_2R_INFILT_2R_GAIN_SHIFT,
905 DA7218_DMIX_GAIN_MAX, DA7218_NO_INVERT,
906 da7218_dmix_gain_tlv),
907
908 SOC_SINGLE_TLV("DMix ToneGen Out1 DAIL Volume",
909 DA7218_DMIX_OUTDAI_1L_TONEGEN_GAIN,
910 DA7218_OUTDAI_1L_TONEGEN_GAIN_SHIFT,
911 DA7218_DMIX_GAIN_MAX, DA7218_NO_INVERT,
912 da7218_dmix_gain_tlv),
913 SOC_SINGLE_TLV("DMix ToneGen Out1 DAIR Volume",
914 DA7218_DMIX_OUTDAI_1R_TONEGEN_GAIN,
915 DA7218_OUTDAI_1R_TONEGEN_GAIN_SHIFT,
916 DA7218_DMIX_GAIN_MAX, DA7218_NO_INVERT,
917 da7218_dmix_gain_tlv),
918 SOC_SINGLE_TLV("DMix ToneGen Out2 DAIL Volume",
919 DA7218_DMIX_OUTDAI_2L_TONEGEN_GAIN,
920 DA7218_OUTDAI_2L_TONEGEN_GAIN_SHIFT,
921 DA7218_DMIX_GAIN_MAX, DA7218_NO_INVERT,
922 da7218_dmix_gain_tlv),
923 SOC_SINGLE_TLV("DMix ToneGen Out2 DAIR Volume",
924 DA7218_DMIX_OUTDAI_2R_TONEGEN_GAIN,
925 DA7218_OUTDAI_2R_TONEGEN_GAIN_SHIFT,
926 DA7218_DMIX_GAIN_MAX, DA7218_NO_INVERT,
927 da7218_dmix_gain_tlv),
928
929 SOC_SINGLE_TLV("DMix In DAIL Out1 DAIL Volume",
930 DA7218_DMIX_OUTDAI_1L_INDAI_1L_GAIN,
931 DA7218_OUTDAI_1L_INDAI_1L_GAIN_SHIFT,
932 DA7218_DMIX_GAIN_MAX, DA7218_NO_INVERT,
933 da7218_dmix_gain_tlv),
934 SOC_SINGLE_TLV("DMix In DAIL Out1 DAIR Volume",
935 DA7218_DMIX_OUTDAI_1R_INDAI_1L_GAIN,
936 DA7218_OUTDAI_1R_INDAI_1L_GAIN_SHIFT,
937 DA7218_DMIX_GAIN_MAX, DA7218_NO_INVERT,
938 da7218_dmix_gain_tlv),
939 SOC_SINGLE_TLV("DMix In DAIL Out2 DAIL Volume",
940 DA7218_DMIX_OUTDAI_2L_INDAI_1L_GAIN,
941 DA7218_OUTDAI_2L_INDAI_1L_GAIN_SHIFT,
942 DA7218_DMIX_GAIN_MAX, DA7218_NO_INVERT,
943 da7218_dmix_gain_tlv),
944 SOC_SINGLE_TLV("DMix In DAIL Out2 DAIR Volume",
945 DA7218_DMIX_OUTDAI_2R_INDAI_1L_GAIN,
946 DA7218_OUTDAI_2R_INDAI_1L_GAIN_SHIFT,
947 DA7218_DMIX_GAIN_MAX, DA7218_NO_INVERT,
948 da7218_dmix_gain_tlv),
949
950 SOC_SINGLE_TLV("DMix In DAIR Out1 DAIL Volume",
951 DA7218_DMIX_OUTDAI_1L_INDAI_1R_GAIN,
952 DA7218_OUTDAI_1L_INDAI_1R_GAIN_SHIFT,
953 DA7218_DMIX_GAIN_MAX, DA7218_NO_INVERT,
954 da7218_dmix_gain_tlv),
955 SOC_SINGLE_TLV("DMix In DAIR Out1 DAIR Volume",
956 DA7218_DMIX_OUTDAI_1R_INDAI_1R_GAIN,
957 DA7218_OUTDAI_1R_INDAI_1R_GAIN_SHIFT,
958 DA7218_DMIX_GAIN_MAX, DA7218_NO_INVERT,
959 da7218_dmix_gain_tlv),
960 SOC_SINGLE_TLV("DMix In DAIR Out2 DAIL Volume",
961 DA7218_DMIX_OUTDAI_2L_INDAI_1R_GAIN,
962 DA7218_OUTDAI_2L_INDAI_1R_GAIN_SHIFT,
963 DA7218_DMIX_GAIN_MAX, DA7218_NO_INVERT,
964 da7218_dmix_gain_tlv),
965 SOC_SINGLE_TLV("DMix In DAIR Out2 DAIR Volume",
966 DA7218_DMIX_OUTDAI_2R_INDAI_1R_GAIN,
967 DA7218_OUTDAI_2R_INDAI_1R_GAIN_SHIFT,
968 DA7218_DMIX_GAIN_MAX, DA7218_NO_INVERT,
969 da7218_dmix_gain_tlv),
970
971 /* Digital Mixer (Output) */
972 SOC_SINGLE_TLV("DMix In Filter1L Out FilterL Volume",
973 DA7218_DMIX_OUTFILT_1L_INFILT_1L_GAIN,
974 DA7218_OUTFILT_1L_INFILT_1L_GAIN_SHIFT,
975 DA7218_DMIX_GAIN_MAX, DA7218_NO_INVERT,
976 da7218_dmix_gain_tlv),
977 SOC_SINGLE_TLV("DMix In Filter1L Out FilterR Volume",
978 DA7218_DMIX_OUTFILT_1R_INFILT_1L_GAIN,
979 DA7218_OUTFILT_1R_INFILT_1L_GAIN_SHIFT,
980 DA7218_DMIX_GAIN_MAX, DA7218_NO_INVERT,
981 da7218_dmix_gain_tlv),
982
983 SOC_SINGLE_TLV("DMix In Filter1R Out FilterL Volume",
984 DA7218_DMIX_OUTFILT_1L_INFILT_1R_GAIN,
985 DA7218_OUTFILT_1L_INFILT_1R_GAIN_SHIFT,
986 DA7218_DMIX_GAIN_MAX, DA7218_NO_INVERT,
987 da7218_dmix_gain_tlv),
988 SOC_SINGLE_TLV("DMix In Filter1R Out FilterR Volume",
989 DA7218_DMIX_OUTFILT_1R_INFILT_1R_GAIN,
990 DA7218_OUTFILT_1R_INFILT_1R_GAIN_SHIFT,
991 DA7218_DMIX_GAIN_MAX, DA7218_NO_INVERT,
992 da7218_dmix_gain_tlv),
993
994 SOC_SINGLE_TLV("DMix In Filter2L Out FilterL Volume",
995 DA7218_DMIX_OUTFILT_1L_INFILT_2L_GAIN,
996 DA7218_OUTFILT_1L_INFILT_2L_GAIN_SHIFT,
997 DA7218_DMIX_GAIN_MAX, DA7218_NO_INVERT,
998 da7218_dmix_gain_tlv),
999 SOC_SINGLE_TLV("DMix In Filter2L Out FilterR Volume",
1000 DA7218_DMIX_OUTFILT_1R_INFILT_2L_GAIN,
1001 DA7218_OUTFILT_1R_INFILT_2L_GAIN_SHIFT,
1002 DA7218_DMIX_GAIN_MAX, DA7218_NO_INVERT,
1003 da7218_dmix_gain_tlv),
1004
1005 SOC_SINGLE_TLV("DMix In Filter2R Out FilterL Volume",
1006 DA7218_DMIX_OUTFILT_1L_INFILT_2R_GAIN,
1007 DA7218_OUTFILT_1L_INFILT_2R_GAIN_SHIFT,
1008 DA7218_DMIX_GAIN_MAX, DA7218_NO_INVERT,
1009 da7218_dmix_gain_tlv),
1010 SOC_SINGLE_TLV("DMix In Filter2R Out FilterR Volume",
1011 DA7218_DMIX_OUTFILT_1R_INFILT_2R_GAIN,
1012 DA7218_OUTFILT_1R_INFILT_2R_GAIN_SHIFT,
1013 DA7218_DMIX_GAIN_MAX, DA7218_NO_INVERT,
1014 da7218_dmix_gain_tlv),
1015
1016 SOC_SINGLE_TLV("DMix ToneGen Out FilterL Volume",
1017 DA7218_DMIX_OUTFILT_1L_TONEGEN_GAIN,
1018 DA7218_OUTFILT_1L_TONEGEN_GAIN_SHIFT,
1019 DA7218_DMIX_GAIN_MAX, DA7218_NO_INVERT,
1020 da7218_dmix_gain_tlv),
1021 SOC_SINGLE_TLV("DMix ToneGen Out FilterR Volume",
1022 DA7218_DMIX_OUTFILT_1R_TONEGEN_GAIN,
1023 DA7218_OUTFILT_1R_TONEGEN_GAIN_SHIFT,
1024 DA7218_DMIX_GAIN_MAX, DA7218_NO_INVERT,
1025 da7218_dmix_gain_tlv),
1026
1027 SOC_SINGLE_TLV("DMix In DAIL Out FilterL Volume",
1028 DA7218_DMIX_OUTFILT_1L_INDAI_1L_GAIN,
1029 DA7218_OUTFILT_1L_INDAI_1L_GAIN_SHIFT,
1030 DA7218_DMIX_GAIN_MAX, DA7218_NO_INVERT,
1031 da7218_dmix_gain_tlv),
1032 SOC_SINGLE_TLV("DMix In DAIL Out FilterR Volume",
1033 DA7218_DMIX_OUTFILT_1R_INDAI_1L_GAIN,
1034 DA7218_OUTFILT_1R_INDAI_1L_GAIN_SHIFT,
1035 DA7218_DMIX_GAIN_MAX, DA7218_NO_INVERT,
1036 da7218_dmix_gain_tlv),
1037
1038 SOC_SINGLE_TLV("DMix In DAIR Out FilterL Volume",
1039 DA7218_DMIX_OUTFILT_1L_INDAI_1R_GAIN,
1040 DA7218_OUTFILT_1L_INDAI_1R_GAIN_SHIFT,
1041 DA7218_DMIX_GAIN_MAX, DA7218_NO_INVERT,
1042 da7218_dmix_gain_tlv),
1043 SOC_SINGLE_TLV("DMix In DAIR Out FilterR Volume",
1044 DA7218_DMIX_OUTFILT_1R_INDAI_1R_GAIN,
1045 DA7218_OUTFILT_1R_INDAI_1R_GAIN_SHIFT,
1046 DA7218_DMIX_GAIN_MAX, DA7218_NO_INVERT,
1047 da7218_dmix_gain_tlv),
1048
1049 /* Sidetone Filter */
1050 SND_SOC_BYTES_EXT("Sidetone BiQuad Coefficients",
1051 DA7218_SIDETONE_BIQ_3STAGE_CFG_SIZE,
1052 da7218_biquad_coeff_get, da7218_biquad_coeff_put),
1053 SOC_SINGLE_TLV("Sidetone Volume", DA7218_SIDETONE_GAIN,
1054 DA7218_SIDETONE_GAIN_SHIFT, DA7218_DMIX_GAIN_MAX,
1055 DA7218_NO_INVERT, da7218_dmix_gain_tlv),
1056 SOC_SINGLE("Sidetone Switch", DA7218_SIDETONE_CTRL,
1057 DA7218_SIDETONE_MUTE_EN_SHIFT, DA7218_SWITCH_EN_MAX,
1058 DA7218_INVERT),
1059
1060 /* Tone Generator */
1061 SOC_ENUM("ToneGen DTMF Key", da7218_tonegen_dtmf_key),
1062 SOC_SINGLE("ToneGen DTMF Switch", DA7218_TONE_GEN_CFG1,
1063 DA7218_DTMF_EN_SHIFT, DA7218_SWITCH_EN_MAX,
1064 DA7218_NO_INVERT),
1065 SOC_ENUM("ToneGen Sinewave Gen Type", da7218_tonegen_swg_sel),
1066 SOC_SINGLE_EXT("ToneGen Sinewave1 Freq", DA7218_TONE_GEN_FREQ1_L,
1067 DA7218_FREQ1_L_SHIFT, DA7218_FREQ_MAX, DA7218_NO_INVERT,
1068 da7218_tonegen_freq_get, da7218_tonegen_freq_put),
1069 SOC_SINGLE_EXT("ToneGen Sinewave2 Freq", DA7218_TONE_GEN_FREQ2_L,
1070 DA7218_FREQ2_L_SHIFT, DA7218_FREQ_MAX, DA7218_NO_INVERT,
1071 da7218_tonegen_freq_get, da7218_tonegen_freq_put),
1072 SOC_SINGLE("ToneGen On Time", DA7218_TONE_GEN_ON_PER,
1073 DA7218_BEEP_ON_PER_SHIFT, DA7218_BEEP_ON_OFF_MAX,
1074 DA7218_NO_INVERT),
1075 SOC_SINGLE("ToneGen Off Time", DA7218_TONE_GEN_OFF_PER,
1076 DA7218_BEEP_OFF_PER_SHIFT, DA7218_BEEP_ON_OFF_MAX,
1077 DA7218_NO_INVERT),
1078
1079 /* Gain ramping */
1080 SOC_ENUM("Gain Ramp Rate", da7218_gain_ramp_rate),
1081
1082 /* DGS */
1083 SOC_SINGLE_TLV("DGS Trigger", DA7218_DGS_TRIGGER,
1084 DA7218_DGS_TRIGGER_LVL_SHIFT, DA7218_DGS_TRIGGER_MAX,
1085 DA7218_INVERT, da7218_dgs_trigger_tlv),
1086 SOC_ENUM("DGS Rise Coefficient", da7218_dgs_rise_coeff),
1087 SOC_ENUM("DGS Fall Coefficient", da7218_dgs_fall_coeff),
1088 SOC_SINGLE("DGS Sync Delay", DA7218_DGS_SYNC_DELAY,
1089 DA7218_DGS_SYNC_DELAY_SHIFT, DA7218_DGS_SYNC_DELAY_MAX,
1090 DA7218_NO_INVERT),
1091 SOC_SINGLE("DGS Fast SR Sync Delay", DA7218_DGS_SYNC_DELAY2,
1092 DA7218_DGS_SYNC_DELAY2_SHIFT, DA7218_DGS_SYNC_DELAY_MAX,
1093 DA7218_NO_INVERT),
1094 SOC_SINGLE("DGS Voice Filter Sync Delay", DA7218_DGS_SYNC_DELAY3,
1095 DA7218_DGS_SYNC_DELAY3_SHIFT, DA7218_DGS_SYNC_DELAY3_MAX,
1096 DA7218_NO_INVERT),
1097 SOC_SINGLE_TLV("DGS Anticlip Level", DA7218_DGS_LEVELS,
1098 DA7218_DGS_ANTICLIP_LVL_SHIFT,
1099 DA7218_DGS_ANTICLIP_LVL_MAX, DA7218_INVERT,
1100 da7218_dgs_anticlip_tlv),
1101 SOC_SINGLE_TLV("DGS Signal Level", DA7218_DGS_LEVELS,
1102 DA7218_DGS_SIGNAL_LVL_SHIFT, DA7218_DGS_SIGNAL_LVL_MAX,
1103 DA7218_INVERT, da7218_dgs_signal_tlv),
1104 SOC_SINGLE("DGS Gain Subrange Switch", DA7218_DGS_GAIN_CTRL,
1105 DA7218_DGS_SUBR_EN_SHIFT, DA7218_SWITCH_EN_MAX,
1106 DA7218_NO_INVERT),
1107 SOC_SINGLE("DGS Gain Ramp Switch", DA7218_DGS_GAIN_CTRL,
1108 DA7218_DGS_RAMP_EN_SHIFT, DA7218_SWITCH_EN_MAX,
1109 DA7218_NO_INVERT),
1110 SOC_SINGLE("DGS Gain Steps", DA7218_DGS_GAIN_CTRL,
1111 DA7218_DGS_STEPS_SHIFT, DA7218_DGS_STEPS_MAX,
1112 DA7218_NO_INVERT),
1113 SOC_DOUBLE("DGS Switch", DA7218_DGS_ENABLE, DA7218_DGS_ENABLE_L_SHIFT,
1114 DA7218_DGS_ENABLE_R_SHIFT, DA7218_SWITCH_EN_MAX,
1115 DA7218_NO_INVERT),
1116
1117 /* Output High-Pass Filter */
1118 SOC_ENUM("Out Filter HPF Mode", da7218_out1_hpf_mode),
1119 SOC_ENUM("Out Filter HPF Corner Audio", da7218_out1_audio_hpf_corner),
1120 SOC_ENUM("Out Filter HPF Corner Voice", da7218_out1_voice_hpf_corner),
1121
1122 /* 5-Band Equaliser */
1123 SOC_SINGLE_TLV("Out EQ Band1 Volume", DA7218_OUT_1_EQ_12_FILTER_CTRL,
1124 DA7218_OUT_1_EQ_BAND1_SHIFT, DA7218_OUT_EQ_BAND_MAX,
1125 DA7218_NO_INVERT, da7218_out_eq_band_tlv),
1126 SOC_SINGLE_TLV("Out EQ Band2 Volume", DA7218_OUT_1_EQ_12_FILTER_CTRL,
1127 DA7218_OUT_1_EQ_BAND2_SHIFT, DA7218_OUT_EQ_BAND_MAX,
1128 DA7218_NO_INVERT, da7218_out_eq_band_tlv),
1129 SOC_SINGLE_TLV("Out EQ Band3 Volume", DA7218_OUT_1_EQ_34_FILTER_CTRL,
1130 DA7218_OUT_1_EQ_BAND3_SHIFT, DA7218_OUT_EQ_BAND_MAX,
1131 DA7218_NO_INVERT, da7218_out_eq_band_tlv),
1132 SOC_SINGLE_TLV("Out EQ Band4 Volume", DA7218_OUT_1_EQ_34_FILTER_CTRL,
1133 DA7218_OUT_1_EQ_BAND4_SHIFT, DA7218_OUT_EQ_BAND_MAX,
1134 DA7218_NO_INVERT, da7218_out_eq_band_tlv),
1135 SOC_SINGLE_TLV("Out EQ Band5 Volume", DA7218_OUT_1_EQ_5_FILTER_CTRL,
1136 DA7218_OUT_1_EQ_BAND5_SHIFT, DA7218_OUT_EQ_BAND_MAX,
1137 DA7218_NO_INVERT, da7218_out_eq_band_tlv),
1138 SOC_SINGLE("Out EQ Switch", DA7218_OUT_1_EQ_5_FILTER_CTRL,
1139 DA7218_OUT_1_EQ_EN_SHIFT, DA7218_SWITCH_EN_MAX,
1140 DA7218_NO_INVERT),
1141
1142 /* BiQuad Filters */
1143 SND_SOC_BYTES_EXT("BiQuad Coefficients",
1144 DA7218_OUT_1_BIQ_5STAGE_CFG_SIZE,
1145 da7218_biquad_coeff_get, da7218_biquad_coeff_put),
1146 SOC_SINGLE("BiQuad Filter Switch", DA7218_OUT_1_BIQ_5STAGE_CTRL,
1147 DA7218_OUT_1_BIQ_5STAGE_MUTE_EN_SHIFT, DA7218_SWITCH_EN_MAX,
1148 DA7218_INVERT),
1149
1150 /* Output Filters */
1151 SOC_DOUBLE_R_RANGE_TLV("Out Filter Volume", DA7218_OUT_1L_GAIN,
1152 DA7218_OUT_1R_GAIN,
1153 DA7218_OUT_1L_DIGITAL_GAIN_SHIFT,
1154 DA7218_OUT_DIGITAL_GAIN_MIN,
1155 DA7218_OUT_DIGITAL_GAIN_MAX, DA7218_NO_INVERT,
1156 da7218_out_dig_gain_tlv),
1157 SOC_DOUBLE_R("Out Filter Switch", DA7218_OUT_1L_FILTER_CTRL,
1158 DA7218_OUT_1R_FILTER_CTRL, DA7218_OUT_1L_MUTE_EN_SHIFT,
1159 DA7218_SWITCH_EN_MAX, DA7218_INVERT),
1160 SOC_DOUBLE_R("Out Filter Gain Subrange Switch",
1161 DA7218_OUT_1L_FILTER_CTRL, DA7218_OUT_1R_FILTER_CTRL,
1162 DA7218_OUT_1L_SUBRANGE_EN_SHIFT, DA7218_SWITCH_EN_MAX,
1163 DA7218_NO_INVERT),
1164 SOC_DOUBLE_R("Out Filter Gain Ramp Switch", DA7218_OUT_1L_FILTER_CTRL,
1165 DA7218_OUT_1R_FILTER_CTRL, DA7218_OUT_1L_RAMP_EN_SHIFT,
1166 DA7218_SWITCH_EN_MAX, DA7218_NO_INVERT),
1167
1168 /* Mixer Output */
1169 SOC_DOUBLE_R_RANGE_TLV("Mixout Volume", DA7218_MIXOUT_L_GAIN,
1170 DA7218_MIXOUT_R_GAIN,
1171 DA7218_MIXOUT_L_AMP_GAIN_SHIFT,
1172 DA7218_MIXOUT_AMP_GAIN_MIN,
1173 DA7218_MIXOUT_AMP_GAIN_MAX, DA7218_NO_INVERT,
1174 da7218_mixout_gain_tlv),
1175
1176 /* DAC Noise Gate */
1177 SOC_ENUM("DAC NG Setup Time", da7218_dac_ng_setup_time),
1178 SOC_ENUM("DAC NG Rampup Rate", da7218_dac_ng_rampup_rate),
1179 SOC_ENUM("DAC NG Rampdown Rate", da7218_dac_ng_rampdown_rate),
1180 SOC_SINGLE_TLV("DAC NG Off Threshold", DA7218_DAC_NG_OFF_THRESH,
1181 DA7218_DAC_NG_OFF_THRESHOLD_SHIFT,
1182 DA7218_DAC_NG_THRESHOLD_MAX, DA7218_NO_INVERT,
1183 da7218_dac_ng_threshold_tlv),
1184 SOC_SINGLE_TLV("DAC NG On Threshold", DA7218_DAC_NG_ON_THRESH,
1185 DA7218_DAC_NG_ON_THRESHOLD_SHIFT,
1186 DA7218_DAC_NG_THRESHOLD_MAX, DA7218_NO_INVERT,
1187 da7218_dac_ng_threshold_tlv),
1188 SOC_SINGLE("DAC NG Switch", DA7218_DAC_NG_CTRL, DA7218_DAC_NG_EN_SHIFT,
1189 DA7218_SWITCH_EN_MAX, DA7218_NO_INVERT),
1190
1191 /* CP */
1192 SOC_ENUM("Charge Pump Track Mode", da7218_cp_mchange),
1193 SOC_ENUM("Charge Pump Frequency", da7218_cp_fcontrol),
1194 SOC_ENUM("Charge Pump Decay Rate", da7218_cp_tau_delay),
1195 SOC_SINGLE("Charge Pump Threshold", DA7218_CP_VOL_THRESHOLD1,
1196 DA7218_CP_THRESH_VDD2_SHIFT, DA7218_CP_THRESH_VDD2_MAX,
1197 DA7218_NO_INVERT),
1198
1199 /* Headphones */
1200 SOC_DOUBLE_R_RANGE_TLV("Headphone Volume", DA7218_HP_L_GAIN,
1201 DA7218_HP_R_GAIN, DA7218_HP_L_AMP_GAIN_SHIFT,
1202 DA7218_HP_AMP_GAIN_MIN, DA7218_HP_AMP_GAIN_MAX,
1203 DA7218_NO_INVERT, da7218_hp_gain_tlv),
1204 SOC_DOUBLE_R("Headphone Switch", DA7218_HP_L_CTRL, DA7218_HP_R_CTRL,
1205 DA7218_HP_L_AMP_MUTE_EN_SHIFT, DA7218_SWITCH_EN_MAX,
1206 DA7218_INVERT),
1207 SOC_DOUBLE_R("Headphone Gain Ramp Switch", DA7218_HP_L_CTRL,
1208 DA7218_HP_R_CTRL, DA7218_HP_L_AMP_RAMP_EN_SHIFT,
1209 DA7218_SWITCH_EN_MAX, DA7218_NO_INVERT),
1210 SOC_DOUBLE_R("Headphone ZC Gain Switch", DA7218_HP_L_CTRL,
1211 DA7218_HP_R_CTRL, DA7218_HP_L_AMP_ZC_EN_SHIFT,
1212 DA7218_SWITCH_EN_MAX, DA7218_NO_INVERT),
1213};
1214
1215
1216/*
1217 * DAPM Mux Controls
1218 */
1219
1220static const char * const da7218_mic_sel_text[] = { "Analog", "Digital" };
1221
1222static const struct soc_enum da7218_mic1_sel =
1223 SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(da7218_mic_sel_text),
1224 da7218_mic_sel_text);
1225
1226static const struct snd_kcontrol_new da7218_mic1_sel_mux =
1227 SOC_DAPM_ENUM("Mic1 Mux", da7218_mic1_sel);
1228
1229static const struct soc_enum da7218_mic2_sel =
1230 SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(da7218_mic_sel_text),
1231 da7218_mic_sel_text);
1232
1233static const struct snd_kcontrol_new da7218_mic2_sel_mux =
1234 SOC_DAPM_ENUM("Mic2 Mux", da7218_mic2_sel);
1235
1236static const char * const da7218_sidetone_in_sel_txt[] = {
1237 "In Filter1L", "In Filter1R", "In Filter2L", "In Filter2R"
1238};
1239
1240static const struct soc_enum da7218_sidetone_in_sel =
1241 SOC_ENUM_SINGLE(DA7218_SIDETONE_IN_SELECT,
1242 DA7218_SIDETONE_IN_SELECT_SHIFT,
1243 DA7218_SIDETONE_IN_SELECT_MAX,
1244 da7218_sidetone_in_sel_txt);
1245
1246static const struct snd_kcontrol_new da7218_sidetone_in_sel_mux =
1247 SOC_DAPM_ENUM("Sidetone Mux", da7218_sidetone_in_sel);
1248
1249static const char * const da7218_out_filt_biq_sel_txt[] = {
1250 "Bypass", "Enabled"
1251};
1252
1253static const struct soc_enum da7218_out_filtl_biq_sel =
1254 SOC_ENUM_SINGLE(DA7218_OUT_1L_FILTER_CTRL,
1255 DA7218_OUT_1L_BIQ_5STAGE_SEL_SHIFT,
1256 DA7218_OUT_BIQ_5STAGE_SEL_MAX,
1257 da7218_out_filt_biq_sel_txt);
1258
1259static const struct snd_kcontrol_new da7218_out_filtl_biq_sel_mux =
1260 SOC_DAPM_ENUM("Out FilterL BiQuad Mux", da7218_out_filtl_biq_sel);
1261
1262static const struct soc_enum da7218_out_filtr_biq_sel =
1263 SOC_ENUM_SINGLE(DA7218_OUT_1R_FILTER_CTRL,
1264 DA7218_OUT_1R_BIQ_5STAGE_SEL_SHIFT,
1265 DA7218_OUT_BIQ_5STAGE_SEL_MAX,
1266 da7218_out_filt_biq_sel_txt);
1267
1268static const struct snd_kcontrol_new da7218_out_filtr_biq_sel_mux =
1269 SOC_DAPM_ENUM("Out FilterR BiQuad Mux", da7218_out_filtr_biq_sel);
1270
1271
1272/*
1273 * DAPM Mixer Controls
1274 */
1275
1276#define DA7218_DMIX_CTRLS(reg) \
1277 SOC_DAPM_SINGLE("In Filter1L Switch", reg, \
1278 DA7218_DMIX_SRC_INFILT1L, \
1279 DA7218_SWITCH_EN_MAX, DA7218_NO_INVERT), \
1280 SOC_DAPM_SINGLE("In Filter1R Switch", reg, \
1281 DA7218_DMIX_SRC_INFILT1R, \
1282 DA7218_SWITCH_EN_MAX, DA7218_NO_INVERT), \
1283 SOC_DAPM_SINGLE("In Filter2L Switch", reg, \
1284 DA7218_DMIX_SRC_INFILT2L, \
1285 DA7218_SWITCH_EN_MAX, DA7218_NO_INVERT), \
1286 SOC_DAPM_SINGLE("In Filter2R Switch", reg, \
1287 DA7218_DMIX_SRC_INFILT2R, \
1288 DA7218_SWITCH_EN_MAX, DA7218_NO_INVERT), \
1289 SOC_DAPM_SINGLE("ToneGen Switch", reg, \
1290 DA7218_DMIX_SRC_TONEGEN, \
1291 DA7218_SWITCH_EN_MAX, DA7218_NO_INVERT), \
1292 SOC_DAPM_SINGLE("DAIL Switch", reg, DA7218_DMIX_SRC_DAIL, \
1293 DA7218_SWITCH_EN_MAX, DA7218_NO_INVERT), \
1294 SOC_DAPM_SINGLE("DAIR Switch", reg, DA7218_DMIX_SRC_DAIR, \
1295 DA7218_SWITCH_EN_MAX, DA7218_NO_INVERT)
1296
1297static const struct snd_kcontrol_new da7218_out_dai1l_mix_controls[] = {
1298 DA7218_DMIX_CTRLS(DA7218_DROUTING_OUTDAI_1L),
1299};
1300
1301static const struct snd_kcontrol_new da7218_out_dai1r_mix_controls[] = {
1302 DA7218_DMIX_CTRLS(DA7218_DROUTING_OUTDAI_1R),
1303};
1304
1305static const struct snd_kcontrol_new da7218_out_dai2l_mix_controls[] = {
1306 DA7218_DMIX_CTRLS(DA7218_DROUTING_OUTDAI_2L),
1307};
1308
1309static const struct snd_kcontrol_new da7218_out_dai2r_mix_controls[] = {
1310 DA7218_DMIX_CTRLS(DA7218_DROUTING_OUTDAI_2R),
1311};
1312
1313static const struct snd_kcontrol_new da7218_out_filtl_mix_controls[] = {
1314 DA7218_DMIX_CTRLS(DA7218_DROUTING_OUTFILT_1L),
1315};
1316
1317static const struct snd_kcontrol_new da7218_out_filtr_mix_controls[] = {
1318 DA7218_DMIX_CTRLS(DA7218_DROUTING_OUTFILT_1R),
1319};
1320
1321#define DA7218_DMIX_ST_CTRLS(reg) \
1322 SOC_DAPM_SINGLE("Out FilterL Switch", reg, \
1323 DA7218_DMIX_ST_SRC_OUTFILT1L, \
1324 DA7218_SWITCH_EN_MAX, DA7218_NO_INVERT), \
1325 SOC_DAPM_SINGLE("Out FilterR Switch", reg, \
1326 DA7218_DMIX_ST_SRC_OUTFILT1R, \
1327 DA7218_SWITCH_EN_MAX, DA7218_NO_INVERT), \
1328 SOC_DAPM_SINGLE("Sidetone Switch", reg, \
1329 DA7218_DMIX_ST_SRC_SIDETONE, \
1330 DA7218_SWITCH_EN_MAX, DA7218_NO_INVERT) \
1331
1332static const struct snd_kcontrol_new da7218_st_out_filtl_mix_controls[] = {
1333 DA7218_DMIX_ST_CTRLS(DA7218_DROUTING_ST_OUTFILT_1L),
1334};
1335
1336static const struct snd_kcontrol_new da7218_st_out_filtr_mix_controls[] = {
1337 DA7218_DMIX_ST_CTRLS(DA7218_DROUTING_ST_OUTFILT_1R),
1338};
1339
1340
1341/*
1342 * DAPM Events
1343 */
1344
1345/*
1346 * We keep track of which input filters are enabled. This is used in the logic
1347 * for controlling the mic level detect feature.
1348 */
1349static int da7218_in_filter_event(struct snd_soc_dapm_widget *w,
1350 struct snd_kcontrol *kcontrol, int event)
1351{
1352 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
1353 struct da7218_priv *da7218 = snd_soc_codec_get_drvdata(codec);
1354 u8 mask;
1355
1356 switch (w->reg) {
1357 case DA7218_IN_1L_FILTER_CTRL:
1358 mask = (1 << DA7218_LVL_DET_EN_CHAN1L_SHIFT);
1359 break;
1360 case DA7218_IN_1R_FILTER_CTRL:
1361 mask = (1 << DA7218_LVL_DET_EN_CHAN1R_SHIFT);
1362 break;
1363 case DA7218_IN_2L_FILTER_CTRL:
1364 mask = (1 << DA7218_LVL_DET_EN_CHAN2L_SHIFT);
1365 break;
1366 case DA7218_IN_2R_FILTER_CTRL:
1367 mask = (1 << DA7218_LVL_DET_EN_CHAN2R_SHIFT);
1368 break;
1369 default:
1370 return -EINVAL;
1371 }
1372
1373 switch (event) {
1374 case SND_SOC_DAPM_POST_PMU:
1375 da7218->in_filt_en |= mask;
1376 /*
1377 * If we're enabling path for mic level detect, wait for path
1378 * to settle before enabling feature to avoid incorrect and
1379 * unwanted detect events.
1380 */
1381 if (mask & da7218->mic_lvl_det_en)
1382 msleep(DA7218_MIC_LVL_DET_DELAY);
1383 break;
1384 case SND_SOC_DAPM_PRE_PMD:
1385 da7218->in_filt_en &= ~mask;
1386 break;
1387 default:
1388 return -EINVAL;
1389 }
1390
1391 /* Enable configured level detection paths */
1392 snd_soc_write(codec, DA7218_LVL_DET_CTRL,
1393 (da7218->in_filt_en & da7218->mic_lvl_det_en));
1394
1395 return 0;
1396}
1397
1398static int da7218_dai_event(struct snd_soc_dapm_widget *w,
1399 struct snd_kcontrol *kcontrol, int event)
1400{
1401 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
1402 struct da7218_priv *da7218 = snd_soc_codec_get_drvdata(codec);
1403 u8 pll_ctrl, pll_status, refosc_cal;
1404 int i;
1405 bool success;
1406
1407 switch (event) {
1408 case SND_SOC_DAPM_POST_PMU:
1409 if (da7218->master)
1410 /* Enable DAI clks for master mode */
1411 snd_soc_update_bits(codec, DA7218_DAI_CLK_MODE,
1412 DA7218_DAI_CLK_EN_MASK,
1413 DA7218_DAI_CLK_EN_MASK);
1414
1415 /* Tune reference oscillator */
1416 snd_soc_write(codec, DA7218_PLL_REFOSC_CAL,
1417 DA7218_PLL_REFOSC_CAL_START_MASK);
1418 snd_soc_write(codec, DA7218_PLL_REFOSC_CAL,
1419 DA7218_PLL_REFOSC_CAL_START_MASK |
1420 DA7218_PLL_REFOSC_CAL_EN_MASK);
1421
1422 /* Check tuning complete */
1423 i = 0;
1424 success = false;
1425 do {
1426 refosc_cal = snd_soc_read(codec, DA7218_PLL_REFOSC_CAL);
1427 if (!(refosc_cal & DA7218_PLL_REFOSC_CAL_START_MASK)) {
1428 success = true;
1429 } else {
1430 ++i;
1431 usleep_range(DA7218_REF_OSC_CHECK_DELAY_MIN,
1432 DA7218_REF_OSC_CHECK_DELAY_MAX);
1433 }
1434 } while ((i < DA7218_REF_OSC_CHECK_TRIES) && (!success));
1435
1436 if (!success)
1437 dev_warn(codec->dev,
1438 "Reference oscillator failed calibration\n");
1439
1440 /* PC synchronised to DAI */
1441 snd_soc_write(codec, DA7218_PC_COUNT,
1442 DA7218_PC_RESYNC_AUTO_MASK);
1443
1444 /* If SRM not enabled, we don't need to check status */
1445 pll_ctrl = snd_soc_read(codec, DA7218_PLL_CTRL);
1446 if ((pll_ctrl & DA7218_PLL_MODE_MASK) != DA7218_PLL_MODE_SRM)
1447 return 0;
1448
1449 /* Check SRM has locked */
1450 i = 0;
1451 success = false;
1452 do {
1453 pll_status = snd_soc_read(codec, DA7218_PLL_STATUS);
1454 if (pll_status & DA7218_PLL_SRM_STATUS_SRM_LOCK) {
1455 success = true;
1456 } else {
1457 ++i;
1458 msleep(DA7218_SRM_CHECK_DELAY);
1459 }
1460 } while ((i < DA7218_SRM_CHECK_TRIES) & (!success));
1461
1462 if (!success)
1463 dev_warn(codec->dev, "SRM failed to lock\n");
1464
1465 return 0;
1466 case SND_SOC_DAPM_POST_PMD:
1467 /* PC free-running */
1468 snd_soc_write(codec, DA7218_PC_COUNT, DA7218_PC_FREERUN_MASK);
1469
1470 if (da7218->master)
1471 /* Disable DAI clks for master mode */
1472 snd_soc_update_bits(codec, DA7218_DAI_CLK_MODE,
1473 DA7218_DAI_CLK_EN_MASK, 0);
1474
1475 return 0;
1476 default:
1477 return -EINVAL;
1478 }
1479}
1480
1481static int da7218_cp_event(struct snd_soc_dapm_widget *w,
1482 struct snd_kcontrol *kcontrol, int event)
1483{
1484 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
1485 struct da7218_priv *da7218 = snd_soc_codec_get_drvdata(codec);
1486
1487 /*
1488 * If this is DA7217 and we're using single supply for differential
1489 * output, we really don't want to touch the charge pump.
1490 */
1491 if (da7218->hp_single_supply)
1492 return 0;
1493
1494 switch (event) {
1495 case SND_SOC_DAPM_PRE_PMU:
1496 snd_soc_update_bits(codec, DA7218_CP_CTRL, DA7218_CP_EN_MASK,
1497 DA7218_CP_EN_MASK);
1498 return 0;
1499 case SND_SOC_DAPM_PRE_PMD:
1500 snd_soc_update_bits(codec, DA7218_CP_CTRL, DA7218_CP_EN_MASK,
1501 0);
1502 return 0;
1503 default:
1504 return -EINVAL;
1505 }
1506}
1507
1508static int da7218_hp_pga_event(struct snd_soc_dapm_widget *w,
1509 struct snd_kcontrol *kcontrol, int event)
1510{
1511 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
1512
1513 switch (event) {
1514 case SND_SOC_DAPM_POST_PMU:
1515 /* Enable headphone output */
1516 snd_soc_update_bits(codec, w->reg, DA7218_HP_AMP_OE_MASK,
1517 DA7218_HP_AMP_OE_MASK);
1518 return 0;
1519 case SND_SOC_DAPM_PRE_PMD:
1520 /* Headphone output high impedance */
1521 snd_soc_update_bits(codec, w->reg, DA7218_HP_AMP_OE_MASK, 0);
1522 return 0;
1523 default:
1524 return -EINVAL;
1525 }
1526}
1527
1528
1529/*
1530 * DAPM Widgets
1531 */
1532
1533static const struct snd_soc_dapm_widget da7218_dapm_widgets[] = {
1534 /* Input Supplies */
1535 SND_SOC_DAPM_SUPPLY("Mic Bias1", DA7218_MICBIAS_EN,
1536 DA7218_MICBIAS_1_EN_SHIFT, DA7218_NO_INVERT,
1537 NULL, 0),
1538 SND_SOC_DAPM_SUPPLY("Mic Bias2", DA7218_MICBIAS_EN,
1539 DA7218_MICBIAS_2_EN_SHIFT, DA7218_NO_INVERT,
1540 NULL, 0),
1541 SND_SOC_DAPM_SUPPLY("DMic1 Left", DA7218_DMIC_1_CTRL,
1542 DA7218_DMIC_1L_EN_SHIFT, DA7218_NO_INVERT,
1543 NULL, 0),
1544 SND_SOC_DAPM_SUPPLY("DMic1 Right", DA7218_DMIC_1_CTRL,
1545 DA7218_DMIC_1R_EN_SHIFT, DA7218_NO_INVERT,
1546 NULL, 0),
1547 SND_SOC_DAPM_SUPPLY("DMic2 Left", DA7218_DMIC_2_CTRL,
1548 DA7218_DMIC_2L_EN_SHIFT, DA7218_NO_INVERT,
1549 NULL, 0),
1550 SND_SOC_DAPM_SUPPLY("DMic2 Right", DA7218_DMIC_2_CTRL,
1551 DA7218_DMIC_2R_EN_SHIFT, DA7218_NO_INVERT,
1552 NULL, 0),
1553
1554 /* Inputs */
1555 SND_SOC_DAPM_INPUT("MIC1"),
1556 SND_SOC_DAPM_INPUT("MIC2"),
1557 SND_SOC_DAPM_INPUT("DMIC1L"),
1558 SND_SOC_DAPM_INPUT("DMIC1R"),
1559 SND_SOC_DAPM_INPUT("DMIC2L"),
1560 SND_SOC_DAPM_INPUT("DMIC2R"),
1561
1562 /* Input Mixer Supplies */
1563 SND_SOC_DAPM_SUPPLY("Mixin1 Supply", DA7218_MIXIN_1_CTRL,
1564 DA7218_MIXIN_1_MIX_SEL_SHIFT, DA7218_NO_INVERT,
1565 NULL, 0),
1566 SND_SOC_DAPM_SUPPLY("Mixin2 Supply", DA7218_MIXIN_2_CTRL,
1567 DA7218_MIXIN_2_MIX_SEL_SHIFT, DA7218_NO_INVERT,
1568 NULL, 0),
1569
1570 /* Input PGAs */
1571 SND_SOC_DAPM_PGA("Mic1 PGA", DA7218_MIC_1_CTRL,
1572 DA7218_MIC_1_AMP_EN_SHIFT, DA7218_NO_INVERT,
1573 NULL, 0),
1574 SND_SOC_DAPM_PGA("Mic2 PGA", DA7218_MIC_2_CTRL,
1575 DA7218_MIC_2_AMP_EN_SHIFT, DA7218_NO_INVERT,
1576 NULL, 0),
1577 SND_SOC_DAPM_PGA("Mixin1 PGA", DA7218_MIXIN_1_CTRL,
1578 DA7218_MIXIN_1_AMP_EN_SHIFT, DA7218_NO_INVERT,
1579 NULL, 0),
1580 SND_SOC_DAPM_PGA("Mixin2 PGA", DA7218_MIXIN_2_CTRL,
1581 DA7218_MIXIN_2_AMP_EN_SHIFT, DA7218_NO_INVERT,
1582 NULL, 0),
1583
1584 /* Mic/DMic Muxes */
1585 SND_SOC_DAPM_MUX("Mic1 Mux", SND_SOC_NOPM, 0, 0, &da7218_mic1_sel_mux),
1586 SND_SOC_DAPM_MUX("Mic2 Mux", SND_SOC_NOPM, 0, 0, &da7218_mic2_sel_mux),
1587
1588 /* Input Filters */
1589 SND_SOC_DAPM_ADC_E("In Filter1L", NULL, DA7218_IN_1L_FILTER_CTRL,
1590 DA7218_IN_1L_FILTER_EN_SHIFT, DA7218_NO_INVERT,
1591 da7218_in_filter_event,
1592 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
1593 SND_SOC_DAPM_ADC_E("In Filter1R", NULL, DA7218_IN_1R_FILTER_CTRL,
1594 DA7218_IN_1R_FILTER_EN_SHIFT, DA7218_NO_INVERT,
1595 da7218_in_filter_event,
1596 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
1597 SND_SOC_DAPM_ADC_E("In Filter2L", NULL, DA7218_IN_2L_FILTER_CTRL,
1598 DA7218_IN_2L_FILTER_EN_SHIFT, DA7218_NO_INVERT,
1599 da7218_in_filter_event,
1600 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
1601 SND_SOC_DAPM_ADC_E("In Filter2R", NULL, DA7218_IN_2R_FILTER_CTRL,
1602 DA7218_IN_2R_FILTER_EN_SHIFT, DA7218_NO_INVERT,
1603 da7218_in_filter_event,
1604 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
1605
1606 /* Tone Generator */
1607 SND_SOC_DAPM_SIGGEN("TONE"),
1608 SND_SOC_DAPM_PGA("Tone Generator", DA7218_TONE_GEN_CFG1,
1609 DA7218_START_STOPN_SHIFT, DA7218_NO_INVERT, NULL, 0),
1610
1611 /* Sidetone Input */
1612 SND_SOC_DAPM_MUX("Sidetone Mux", SND_SOC_NOPM, 0, 0,
1613 &da7218_sidetone_in_sel_mux),
1614 SND_SOC_DAPM_ADC("Sidetone Filter", NULL, DA7218_SIDETONE_CTRL,
1615 DA7218_SIDETONE_FILTER_EN_SHIFT, DA7218_NO_INVERT),
1616
1617 /* Input Mixers */
1618 SND_SOC_DAPM_MIXER("Mixer DAI1L", SND_SOC_NOPM, 0, 0,
1619 da7218_out_dai1l_mix_controls,
1620 ARRAY_SIZE(da7218_out_dai1l_mix_controls)),
1621 SND_SOC_DAPM_MIXER("Mixer DAI1R", SND_SOC_NOPM, 0, 0,
1622 da7218_out_dai1r_mix_controls,
1623 ARRAY_SIZE(da7218_out_dai1r_mix_controls)),
1624 SND_SOC_DAPM_MIXER("Mixer DAI2L", SND_SOC_NOPM, 0, 0,
1625 da7218_out_dai2l_mix_controls,
1626 ARRAY_SIZE(da7218_out_dai2l_mix_controls)),
1627 SND_SOC_DAPM_MIXER("Mixer DAI2R", SND_SOC_NOPM, 0, 0,
1628 da7218_out_dai2r_mix_controls,
1629 ARRAY_SIZE(da7218_out_dai2r_mix_controls)),
1630
1631 /* DAI Supply */
1632 SND_SOC_DAPM_SUPPLY("DAI", DA7218_DAI_CTRL, DA7218_DAI_EN_SHIFT,
1633 DA7218_NO_INVERT, da7218_dai_event,
1634 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
1635
1636 /* DAI */
1637 SND_SOC_DAPM_AIF_OUT("DAIOUT", "Capture", 0, SND_SOC_NOPM, 0, 0),
1638 SND_SOC_DAPM_AIF_IN("DAIIN", "Playback", 0, SND_SOC_NOPM, 0, 0),
1639
1640 /* Output Mixers */
1641 SND_SOC_DAPM_MIXER("Mixer Out FilterL", SND_SOC_NOPM, 0, 0,
1642 da7218_out_filtl_mix_controls,
1643 ARRAY_SIZE(da7218_out_filtl_mix_controls)),
1644 SND_SOC_DAPM_MIXER("Mixer Out FilterR", SND_SOC_NOPM, 0, 0,
1645 da7218_out_filtr_mix_controls,
1646 ARRAY_SIZE(da7218_out_filtr_mix_controls)),
1647
1648 /* BiQuad Filters */
1649 SND_SOC_DAPM_MUX("Out FilterL BiQuad Mux", SND_SOC_NOPM, 0, 0,
1650 &da7218_out_filtl_biq_sel_mux),
1651 SND_SOC_DAPM_MUX("Out FilterR BiQuad Mux", SND_SOC_NOPM, 0, 0,
1652 &da7218_out_filtr_biq_sel_mux),
1653 SND_SOC_DAPM_DAC("BiQuad Filter", NULL, DA7218_OUT_1_BIQ_5STAGE_CTRL,
1654 DA7218_OUT_1_BIQ_5STAGE_FILTER_EN_SHIFT,
1655 DA7218_NO_INVERT),
1656
1657 /* Sidetone Mixers */
1658 SND_SOC_DAPM_MIXER("ST Mixer Out FilterL", SND_SOC_NOPM, 0, 0,
1659 da7218_st_out_filtl_mix_controls,
1660 ARRAY_SIZE(da7218_st_out_filtl_mix_controls)),
1661 SND_SOC_DAPM_MIXER("ST Mixer Out FilterR", SND_SOC_NOPM, 0, 0,
1662 da7218_st_out_filtr_mix_controls,
1663 ARRAY_SIZE(da7218_st_out_filtr_mix_controls)),
1664
1665 /* Output Filters */
1666 SND_SOC_DAPM_DAC("Out FilterL", NULL, DA7218_OUT_1L_FILTER_CTRL,
1667 DA7218_OUT_1L_FILTER_EN_SHIFT, DA7218_NO_INVERT),
1668 SND_SOC_DAPM_DAC("Out FilterR", NULL, DA7218_OUT_1R_FILTER_CTRL,
1669 DA7218_IN_1R_FILTER_EN_SHIFT, DA7218_NO_INVERT),
1670
1671 /* Output PGAs */
1672 SND_SOC_DAPM_PGA("Mixout Left PGA", DA7218_MIXOUT_L_CTRL,
1673 DA7218_MIXOUT_L_AMP_EN_SHIFT, DA7218_NO_INVERT,
1674 NULL, 0),
1675 SND_SOC_DAPM_PGA("Mixout Right PGA", DA7218_MIXOUT_R_CTRL,
1676 DA7218_MIXOUT_R_AMP_EN_SHIFT, DA7218_NO_INVERT,
1677 NULL, 0),
1678 SND_SOC_DAPM_PGA_E("Headphone Left PGA", DA7218_HP_L_CTRL,
1679 DA7218_HP_L_AMP_EN_SHIFT, DA7218_NO_INVERT, NULL, 0,
1680 da7218_hp_pga_event,
1681 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
1682 SND_SOC_DAPM_PGA_E("Headphone Right PGA", DA7218_HP_R_CTRL,
1683 DA7218_HP_R_AMP_EN_SHIFT, DA7218_NO_INVERT, NULL, 0,
1684 da7218_hp_pga_event,
1685 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
1686
1687 /* Output Supplies */
1688 SND_SOC_DAPM_SUPPLY("Charge Pump", SND_SOC_NOPM, 0, 0, da7218_cp_event,
1689 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD),
1690
1691 /* Outputs */
1692 SND_SOC_DAPM_OUTPUT("HPL"),
1693 SND_SOC_DAPM_OUTPUT("HPR"),
1694};
1695
1696
1697/*
1698 * DAPM Mixer Routes
1699 */
1700
1701#define DA7218_DMIX_ROUTES(name) \
1702 {name, "In Filter1L Switch", "In Filter1L"}, \
1703 {name, "In Filter1R Switch", "In Filter1R"}, \
1704 {name, "In Filter2L Switch", "In Filter2L"}, \
1705 {name, "In Filter2R Switch", "In Filter2R"}, \
1706 {name, "ToneGen Switch", "Tone Generator"}, \
1707 {name, "DAIL Switch", "DAIIN"}, \
1708 {name, "DAIR Switch", "DAIIN"}
1709
1710#define DA7218_DMIX_ST_ROUTES(name) \
1711 {name, "Out FilterL Switch", "Out FilterL BiQuad Mux"}, \
1712 {name, "Out FilterR Switch", "Out FilterR BiQuad Mux"}, \
1713 {name, "Sidetone Switch", "Sidetone Filter"}
1714
1715
1716/*
1717 * DAPM audio route definition
1718 */
1719
1720static const struct snd_soc_dapm_route da7218_audio_map[] = {
1721 /* Input paths */
1722 {"MIC1", NULL, "Mic Bias1"},
1723 {"MIC2", NULL, "Mic Bias2"},
1724 {"DMIC1L", NULL, "Mic Bias1"},
1725 {"DMIC1L", NULL, "DMic1 Left"},
1726 {"DMIC1R", NULL, "Mic Bias1"},
1727 {"DMIC1R", NULL, "DMic1 Right"},
1728 {"DMIC2L", NULL, "Mic Bias2"},
1729 {"DMIC2L", NULL, "DMic2 Left"},
1730 {"DMIC2R", NULL, "Mic Bias2"},
1731 {"DMIC2R", NULL, "DMic2 Right"},
1732
1733 {"Mic1 PGA", NULL, "MIC1"},
1734 {"Mic2 PGA", NULL, "MIC2"},
1735
1736 {"Mixin1 PGA", NULL, "Mixin1 Supply"},
1737 {"Mixin2 PGA", NULL, "Mixin2 Supply"},
1738
1739 {"Mixin1 PGA", NULL, "Mic1 PGA"},
1740 {"Mixin2 PGA", NULL, "Mic2 PGA"},
1741
1742 {"Mic1 Mux", "Analog", "Mixin1 PGA"},
1743 {"Mic1 Mux", "Digital", "DMIC1L"},
1744 {"Mic1 Mux", "Digital", "DMIC1R"},
1745 {"Mic2 Mux", "Analog", "Mixin2 PGA"},
1746 {"Mic2 Mux", "Digital", "DMIC2L"},
1747 {"Mic2 Mux", "Digital", "DMIC2R"},
1748
1749 {"In Filter1L", NULL, "Mic1 Mux"},
1750 {"In Filter1R", NULL, "Mic1 Mux"},
1751 {"In Filter2L", NULL, "Mic2 Mux"},
1752 {"In Filter2R", NULL, "Mic2 Mux"},
1753
1754 {"Tone Generator", NULL, "TONE"},
1755
1756 {"Sidetone Mux", "In Filter1L", "In Filter1L"},
1757 {"Sidetone Mux", "In Filter1R", "In Filter1R"},
1758 {"Sidetone Mux", "In Filter2L", "In Filter2L"},
1759 {"Sidetone Mux", "In Filter2R", "In Filter2R"},
1760 {"Sidetone Filter", NULL, "Sidetone Mux"},
1761
1762 DA7218_DMIX_ROUTES("Mixer DAI1L"),
1763 DA7218_DMIX_ROUTES("Mixer DAI1R"),
1764 DA7218_DMIX_ROUTES("Mixer DAI2L"),
1765 DA7218_DMIX_ROUTES("Mixer DAI2R"),
1766
1767 {"DAIOUT", NULL, "Mixer DAI1L"},
1768 {"DAIOUT", NULL, "Mixer DAI1R"},
1769 {"DAIOUT", NULL, "Mixer DAI2L"},
1770 {"DAIOUT", NULL, "Mixer DAI2R"},
1771
1772 {"DAIOUT", NULL, "DAI"},
1773
1774 /* Output paths */
1775 {"DAIIN", NULL, "DAI"},
1776
1777 DA7218_DMIX_ROUTES("Mixer Out FilterL"),
1778 DA7218_DMIX_ROUTES("Mixer Out FilterR"),
1779
1780 {"BiQuad Filter", NULL, "Mixer Out FilterL"},
1781 {"BiQuad Filter", NULL, "Mixer Out FilterR"},
1782
1783 {"Out FilterL BiQuad Mux", "Bypass", "Mixer Out FilterL"},
1784 {"Out FilterL BiQuad Mux", "Enabled", "BiQuad Filter"},
1785 {"Out FilterR BiQuad Mux", "Bypass", "Mixer Out FilterR"},
1786 {"Out FilterR BiQuad Mux", "Enabled", "BiQuad Filter"},
1787
1788 DA7218_DMIX_ST_ROUTES("ST Mixer Out FilterL"),
1789 DA7218_DMIX_ST_ROUTES("ST Mixer Out FilterR"),
1790
1791 {"Out FilterL", NULL, "ST Mixer Out FilterL"},
1792 {"Out FilterR", NULL, "ST Mixer Out FilterR"},
1793
1794 {"Mixout Left PGA", NULL, "Out FilterL"},
1795 {"Mixout Right PGA", NULL, "Out FilterR"},
1796
1797 {"Headphone Left PGA", NULL, "Mixout Left PGA"},
1798 {"Headphone Right PGA", NULL, "Mixout Right PGA"},
1799
1800 {"HPL", NULL, "Headphone Left PGA"},
1801 {"HPR", NULL, "Headphone Right PGA"},
1802
1803 {"HPL", NULL, "Charge Pump"},
1804 {"HPR", NULL, "Charge Pump"},
1805};
1806
1807
1808/*
1809 * DAI operations
1810 */
1811
1812static int da7218_set_dai_sysclk(struct snd_soc_dai *codec_dai,
1813 int clk_id, unsigned int freq, int dir)
1814{
1815 struct snd_soc_codec *codec = codec_dai->codec;
1816 struct da7218_priv *da7218 = snd_soc_codec_get_drvdata(codec);
1817 int ret;
1818
1819 if (da7218->mclk_rate == freq)
1820 return 0;
1821
1822 if (((freq < 2000000) && (freq != 32768)) || (freq > 54000000)) {
1823 dev_err(codec_dai->dev, "Unsupported MCLK value %d\n",
1824 freq);
1825 return -EINVAL;
1826 }
1827
1828 switch (clk_id) {
1829 case DA7218_CLKSRC_MCLK_SQR:
1830 snd_soc_update_bits(codec, DA7218_PLL_CTRL,
1831 DA7218_PLL_MCLK_SQR_EN_MASK,
1832 DA7218_PLL_MCLK_SQR_EN_MASK);
1833 break;
1834 case DA7218_CLKSRC_MCLK:
1835 snd_soc_update_bits(codec, DA7218_PLL_CTRL,
1836 DA7218_PLL_MCLK_SQR_EN_MASK, 0);
1837 break;
1838 default:
1839 dev_err(codec_dai->dev, "Unknown clock source %d\n", clk_id);
1840 return -EINVAL;
1841 }
1842
1843 if (da7218->mclk) {
1844 freq = clk_round_rate(da7218->mclk, freq);
1845 ret = clk_set_rate(da7218->mclk, freq);
1846 if (ret) {
1847 dev_err(codec_dai->dev, "Failed to set clock rate %d\n",
1848 freq);
1849 return ret;
1850 }
1851 }
1852
1853 da7218->mclk_rate = freq;
1854
1855 return 0;
1856}
1857
1858static int da7218_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
1859 int source, unsigned int fref, unsigned int fout)
1860{
1861 struct snd_soc_codec *codec = codec_dai->codec;
1862 struct da7218_priv *da7218 = snd_soc_codec_get_drvdata(codec);
1863
1864 u8 pll_ctrl, indiv_bits, indiv;
1865 u8 pll_frac_top, pll_frac_bot, pll_integer;
1866 u32 freq_ref;
1867 u64 frac_div;
1868
1869 /* Verify 32KHz, 2MHz - 54MHz MCLK provided, and set input divider */
1870 if (da7218->mclk_rate == 32768) {
1871 indiv_bits = DA7218_PLL_INDIV_2_5_MHZ;
1872 indiv = DA7218_PLL_INDIV_2_10_MHZ_VAL;
1873 } else if (da7218->mclk_rate < 2000000) {
1874 dev_err(codec->dev, "PLL input clock %d below valid range\n",
1875 da7218->mclk_rate);
1876 return -EINVAL;
1877 } else if (da7218->mclk_rate <= 5000000) {
1878 indiv_bits = DA7218_PLL_INDIV_2_5_MHZ;
1879 indiv = DA7218_PLL_INDIV_2_10_MHZ_VAL;
1880 } else if (da7218->mclk_rate <= 10000000) {
1881 indiv_bits = DA7218_PLL_INDIV_5_10_MHZ;
1882 indiv = DA7218_PLL_INDIV_2_10_MHZ_VAL;
1883 } else if (da7218->mclk_rate <= 20000000) {
1884 indiv_bits = DA7218_PLL_INDIV_10_20_MHZ;
1885 indiv = DA7218_PLL_INDIV_10_20_MHZ_VAL;
1886 } else if (da7218->mclk_rate <= 40000000) {
1887 indiv_bits = DA7218_PLL_INDIV_20_40_MHZ;
1888 indiv = DA7218_PLL_INDIV_20_40_MHZ_VAL;
1889 } else if (da7218->mclk_rate <= 54000000) {
1890 indiv_bits = DA7218_PLL_INDIV_40_54_MHZ;
1891 indiv = DA7218_PLL_INDIV_40_54_MHZ_VAL;
1892 } else {
1893 dev_err(codec->dev, "PLL input clock %d above valid range\n",
1894 da7218->mclk_rate);
1895 return -EINVAL;
1896 }
1897 freq_ref = (da7218->mclk_rate / indiv);
1898 pll_ctrl = indiv_bits;
1899
1900 /* Configure PLL */
1901 switch (source) {
1902 case DA7218_SYSCLK_MCLK:
1903 pll_ctrl |= DA7218_PLL_MODE_BYPASS;
1904 snd_soc_update_bits(codec, DA7218_PLL_CTRL,
1905 DA7218_PLL_INDIV_MASK |
1906 DA7218_PLL_MODE_MASK, pll_ctrl);
1907 return 0;
1908 case DA7218_SYSCLK_PLL:
1909 pll_ctrl |= DA7218_PLL_MODE_NORMAL;
1910 break;
1911 case DA7218_SYSCLK_PLL_SRM:
1912 pll_ctrl |= DA7218_PLL_MODE_SRM;
1913 break;
1914 case DA7218_SYSCLK_PLL_32KHZ:
1915 pll_ctrl |= DA7218_PLL_MODE_32KHZ;
1916 break;
1917 default:
1918 dev_err(codec->dev, "Invalid PLL config\n");
1919 return -EINVAL;
1920 }
1921
1922 /* Calculate dividers for PLL */
1923 pll_integer = fout / freq_ref;
1924 frac_div = (u64)(fout % freq_ref) * 8192ULL;
1925 do_div(frac_div, freq_ref);
1926 pll_frac_top = (frac_div >> DA7218_BYTE_SHIFT) & DA7218_BYTE_MASK;
1927 pll_frac_bot = (frac_div) & DA7218_BYTE_MASK;
1928
1929 /* Write PLL config & dividers */
1930 snd_soc_write(codec, DA7218_PLL_FRAC_TOP, pll_frac_top);
1931 snd_soc_write(codec, DA7218_PLL_FRAC_BOT, pll_frac_bot);
1932 snd_soc_write(codec, DA7218_PLL_INTEGER, pll_integer);
1933 snd_soc_update_bits(codec, DA7218_PLL_CTRL,
1934 DA7218_PLL_MODE_MASK | DA7218_PLL_INDIV_MASK,
1935 pll_ctrl);
1936
1937 return 0;
1938}
1939
1940static int da7218_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
1941{
1942 struct snd_soc_codec *codec = codec_dai->codec;
1943 struct da7218_priv *da7218 = snd_soc_codec_get_drvdata(codec);
1944 u8 dai_clk_mode = 0, dai_ctrl = 0;
1945
1946 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
1947 case SND_SOC_DAIFMT_CBM_CFM:
1948 da7218->master = true;
1949 break;
1950 case SND_SOC_DAIFMT_CBS_CFS:
1951 da7218->master = false;
1952 break;
1953 default:
1954 return -EINVAL;
1955 }
1956
1957 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
1958 case SND_SOC_DAIFMT_I2S:
1959 case SND_SOC_DAIFMT_LEFT_J:
1960 case SND_SOC_DAIFMT_RIGHT_J:
1961 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
1962 case SND_SOC_DAIFMT_NB_NF:
1963 break;
1964 case SND_SOC_DAIFMT_NB_IF:
1965 dai_clk_mode |= DA7218_DAI_WCLK_POL_INV;
1966 break;
1967 case SND_SOC_DAIFMT_IB_NF:
1968 dai_clk_mode |= DA7218_DAI_CLK_POL_INV;
1969 break;
1970 case SND_SOC_DAIFMT_IB_IF:
1971 dai_clk_mode |= DA7218_DAI_WCLK_POL_INV |
1972 DA7218_DAI_CLK_POL_INV;
1973 break;
1974 default:
1975 return -EINVAL;
1976 }
1977 break;
1978 case SND_SOC_DAIFMT_DSP_B:
1979 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
1980 case SND_SOC_DAIFMT_NB_NF:
1981 dai_clk_mode |= DA7218_DAI_CLK_POL_INV;
1982 break;
1983 case SND_SOC_DAIFMT_NB_IF:
1984 dai_clk_mode |= DA7218_DAI_WCLK_POL_INV |
1985 DA7218_DAI_CLK_POL_INV;
1986 break;
1987 case SND_SOC_DAIFMT_IB_NF:
1988 break;
1989 case SND_SOC_DAIFMT_IB_IF:
1990 dai_clk_mode |= DA7218_DAI_WCLK_POL_INV;
1991 break;
1992 default:
1993 return -EINVAL;
1994 }
1995 break;
1996 default:
1997 return -EINVAL;
1998 }
1999
2000 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
2001 case SND_SOC_DAIFMT_I2S:
2002 dai_ctrl |= DA7218_DAI_FORMAT_I2S;
2003 break;
2004 case SND_SOC_DAIFMT_LEFT_J:
2005 dai_ctrl |= DA7218_DAI_FORMAT_LEFT_J;
2006 break;
2007 case SND_SOC_DAIFMT_RIGHT_J:
2008 dai_ctrl |= DA7218_DAI_FORMAT_RIGHT_J;
2009 break;
2010 case SND_SOC_DAIFMT_DSP_B:
2011 dai_ctrl |= DA7218_DAI_FORMAT_DSP;
2012 break;
2013 default:
2014 return -EINVAL;
2015 }
2016
2017 /* By default 64 BCLKs per WCLK is supported */
2018 dai_clk_mode |= DA7218_DAI_BCLKS_PER_WCLK_64;
2019
2020 snd_soc_write(codec, DA7218_DAI_CLK_MODE, dai_clk_mode);
2021 snd_soc_update_bits(codec, DA7218_DAI_CTRL, DA7218_DAI_FORMAT_MASK,
2022 dai_ctrl);
2023
2024 return 0;
2025}
2026
2027static int da7218_set_dai_tdm_slot(struct snd_soc_dai *dai,
2028 unsigned int tx_mask, unsigned int rx_mask,
2029 int slots, int slot_width)
2030{
2031 struct snd_soc_codec *codec = dai->codec;
2032 u8 dai_bclks_per_wclk;
2033 u32 frame_size;
2034
2035 /* No channels enabled so disable TDM, revert to 64-bit frames */
2036 if (!tx_mask) {
2037 snd_soc_update_bits(codec, DA7218_DAI_TDM_CTRL,
2038 DA7218_DAI_TDM_CH_EN_MASK |
2039 DA7218_DAI_TDM_MODE_EN_MASK, 0);
2040 snd_soc_update_bits(codec, DA7218_DAI_CLK_MODE,
2041 DA7218_DAI_BCLKS_PER_WCLK_MASK,
2042 DA7218_DAI_BCLKS_PER_WCLK_64);
2043 return 0;
2044 }
2045
2046 /* Check we have valid slots */
2047 if (fls(tx_mask) > DA7218_DAI_TDM_MAX_SLOTS) {
2048 dev_err(codec->dev, "Invalid number of slots, max = %d\n",
2049 DA7218_DAI_TDM_MAX_SLOTS);
2050 return -EINVAL;
2051 }
2052
2053 /* Check we have a valid offset given (first 2 bytes of rx_mask) */
2054 if (rx_mask >> DA7218_2BYTE_SHIFT) {
2055 dev_err(codec->dev, "Invalid slot offset, max = %d\n",
2056 DA7218_2BYTE_MASK);
2057 return -EINVAL;
2058 }
2059
2060 /* Calculate & validate frame size based on slot info provided. */
2061 frame_size = slots * slot_width;
2062 switch (frame_size) {
2063 case 32:
2064 dai_bclks_per_wclk = DA7218_DAI_BCLKS_PER_WCLK_32;
2065 break;
2066 case 64:
2067 dai_bclks_per_wclk = DA7218_DAI_BCLKS_PER_WCLK_64;
2068 break;
2069 case 128:
2070 dai_bclks_per_wclk = DA7218_DAI_BCLKS_PER_WCLK_128;
2071 break;
2072 case 256:
2073 dai_bclks_per_wclk = DA7218_DAI_BCLKS_PER_WCLK_256;
2074 break;
2075 default:
2076 dev_err(codec->dev, "Invalid frame size\n");
2077 return -EINVAL;
2078 }
2079
2080 snd_soc_update_bits(codec, DA7218_DAI_CLK_MODE,
2081 DA7218_DAI_BCLKS_PER_WCLK_MASK,
2082 dai_bclks_per_wclk);
2083 snd_soc_write(codec, DA7218_DAI_OFFSET_LOWER,
2084 (rx_mask & DA7218_BYTE_MASK));
2085 snd_soc_write(codec, DA7218_DAI_OFFSET_UPPER,
2086 ((rx_mask >> DA7218_BYTE_SHIFT) & DA7218_BYTE_MASK));
2087 snd_soc_update_bits(codec, DA7218_DAI_TDM_CTRL,
2088 DA7218_DAI_TDM_CH_EN_MASK |
2089 DA7218_DAI_TDM_MODE_EN_MASK,
2090 (tx_mask << DA7218_DAI_TDM_CH_EN_SHIFT) |
2091 DA7218_DAI_TDM_MODE_EN_MASK);
2092
2093 return 0;
2094}
2095
2096static int da7218_hw_params(struct snd_pcm_substream *substream,
2097 struct snd_pcm_hw_params *params,
2098 struct snd_soc_dai *dai)
2099{
2100 struct snd_soc_codec *codec = dai->codec;
2101 u8 dai_ctrl = 0, fs;
2102 unsigned int channels;
2103
2104 switch (params_width(params)) {
2105 case 16:
2106 dai_ctrl |= DA7218_DAI_WORD_LENGTH_S16_LE;
2107 break;
2108 case 20:
2109 dai_ctrl |= DA7218_DAI_WORD_LENGTH_S20_LE;
2110 break;
2111 case 24:
2112 dai_ctrl |= DA7218_DAI_WORD_LENGTH_S24_LE;
2113 break;
2114 case 32:
2115 dai_ctrl |= DA7218_DAI_WORD_LENGTH_S32_LE;
2116 break;
2117 default:
2118 return -EINVAL;
2119 }
2120
2121 channels = params_channels(params);
2122 if ((channels < 1) || (channels > DA7218_DAI_CH_NUM_MAX)) {
2123 dev_err(codec->dev,
2124 "Invalid number of channels, only 1 to %d supported\n",
2125 DA7218_DAI_CH_NUM_MAX);
2126 return -EINVAL;
2127 }
2128 dai_ctrl |= channels << DA7218_DAI_CH_NUM_SHIFT;
2129
2130 switch (params_rate(params)) {
2131 case 8000:
2132 fs = DA7218_SR_8000;
2133 break;
2134 case 11025:
2135 fs = DA7218_SR_11025;
2136 break;
2137 case 12000:
2138 fs = DA7218_SR_12000;
2139 break;
2140 case 16000:
2141 fs = DA7218_SR_16000;
2142 break;
2143 case 22050:
2144 fs = DA7218_SR_22050;
2145 break;
2146 case 24000:
2147 fs = DA7218_SR_24000;
2148 break;
2149 case 32000:
2150 fs = DA7218_SR_32000;
2151 break;
2152 case 44100:
2153 fs = DA7218_SR_44100;
2154 break;
2155 case 48000:
2156 fs = DA7218_SR_48000;
2157 break;
2158 case 88200:
2159 fs = DA7218_SR_88200;
2160 break;
2161 case 96000:
2162 fs = DA7218_SR_96000;
2163 break;
2164 default:
2165 return -EINVAL;
2166 }
2167
2168 snd_soc_update_bits(codec, DA7218_DAI_CTRL,
2169 DA7218_DAI_WORD_LENGTH_MASK | DA7218_DAI_CH_NUM_MASK,
2170 dai_ctrl);
2171 /* SRs tied for ADCs and DACs. */
2172 snd_soc_write(codec, DA7218_SR,
2173 (fs << DA7218_SR_DAC_SHIFT) | (fs << DA7218_SR_ADC_SHIFT));
2174
2175 return 0;
2176}
2177
2178static const struct snd_soc_dai_ops da7218_dai_ops = {
2179 .hw_params = da7218_hw_params,
2180 .set_sysclk = da7218_set_dai_sysclk,
2181 .set_pll = da7218_set_dai_pll,
2182 .set_fmt = da7218_set_dai_fmt,
2183 .set_tdm_slot = da7218_set_dai_tdm_slot,
2184};
2185
2186#define DA7218_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
2187 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
2188
2189static struct snd_soc_dai_driver da7218_dai = {
2190 .name = "da7218-hifi",
2191 .playback = {
2192 .stream_name = "Playback",
2193 .channels_min = 1,
2194 .channels_max = 4, /* Only 2 channels of data */
2195 .rates = SNDRV_PCM_RATE_8000_96000,
2196 .formats = DA7218_FORMATS,
2197 },
2198 .capture = {
2199 .stream_name = "Capture",
2200 .channels_min = 1,
2201 .channels_max = 4,
2202 .rates = SNDRV_PCM_RATE_8000_96000,
2203 .formats = DA7218_FORMATS,
2204 },
2205 .ops = &da7218_dai_ops,
2206 .symmetric_rates = 1,
2207 .symmetric_channels = 1,
2208 .symmetric_samplebits = 1,
2209};
2210
2211
2212/*
2213 * HP Detect
2214 */
2215
2216int da7218_hpldet(struct snd_soc_codec *codec, struct snd_soc_jack *jack)
2217{
2218 struct da7218_priv *da7218 = snd_soc_codec_get_drvdata(codec);
2219
2220 if (da7218->dev_id == DA7217_DEV_ID)
2221 return -EINVAL;
2222
2223 da7218->jack = jack;
2224 snd_soc_update_bits(codec, DA7218_HPLDET_JACK,
2225 DA7218_HPLDET_JACK_EN_MASK,
2226 jack ? DA7218_HPLDET_JACK_EN_MASK : 0);
2227
2228 return 0;
2229}
2230EXPORT_SYMBOL_GPL(da7218_hpldet);
2231
2232static void da7218_micldet_irq(struct snd_soc_codec *codec)
2233{
2234 char *envp[] = {
2235 "EVENT=MIC_LEVEL_DETECT",
2236 NULL,
2237 };
2238
2239 kobject_uevent_env(&codec->dev->kobj, KOBJ_CHANGE, envp);
2240}
2241
2242static void da7218_hpldet_irq(struct snd_soc_codec *codec)
2243{
2244 struct da7218_priv *da7218 = snd_soc_codec_get_drvdata(codec);
2245 u8 jack_status;
2246 int report;
2247
2248 jack_status = snd_soc_read(codec, DA7218_EVENT_STATUS);
2249
2250 if (jack_status & DA7218_HPLDET_JACK_STS_MASK)
2251 report = SND_JACK_HEADPHONE;
2252 else
2253 report = 0;
2254
2255 snd_soc_jack_report(da7218->jack, report, SND_JACK_HEADPHONE);
2256}
2257
2258/*
2259 * IRQ
2260 */
2261
2262static irqreturn_t da7218_irq_thread(int irq, void *data)
2263{
2264 struct snd_soc_codec *codec = data;
2265 u8 status;
2266
2267 /* Read IRQ status reg */
2268 status = snd_soc_read(codec, DA7218_EVENT);
2269 if (!status)
2270 return IRQ_NONE;
2271
2272 /* Mic level detect */
2273 if (status & DA7218_LVL_DET_EVENT_MASK)
2274 da7218_micldet_irq(codec);
2275
2276 /* HP detect */
2277 if (status & DA7218_HPLDET_JACK_EVENT_MASK)
2278 da7218_hpldet_irq(codec);
2279
2280 /* Clear interrupts */
2281 snd_soc_write(codec, DA7218_EVENT, status);
2282
2283 return IRQ_HANDLED;
2284}
2285
2286/*
2287 * DT
2288 */
2289
2290static const struct of_device_id da7218_of_match[] = {
2291 { .compatible = "dlg,da7217", .data = (void *) DA7217_DEV_ID },
2292 { .compatible = "dlg,da7218", .data = (void *) DA7218_DEV_ID },
2293 { }
2294};
2295MODULE_DEVICE_TABLE(of, da7218_of_match);
2296
2297static inline int da7218_of_get_id(struct device *dev)
2298{
2299 const struct of_device_id *id = of_match_device(da7218_of_match, dev);
2300
2301 if (id)
2302 return (uintptr_t)id->data;
2303 else
2304 return -EINVAL;
2305}
2306
2307static enum da7218_micbias_voltage
2308 da7218_of_micbias_lvl(struct snd_soc_codec *codec, u32 val)
2309{
2310 switch (val) {
2311 case 1200:
2312 return DA7218_MICBIAS_1_2V;
2313 case 1600:
2314 return DA7218_MICBIAS_1_6V;
2315 case 1800:
2316 return DA7218_MICBIAS_1_8V;
2317 case 2000:
2318 return DA7218_MICBIAS_2_0V;
2319 case 2200:
2320 return DA7218_MICBIAS_2_2V;
2321 case 2400:
2322 return DA7218_MICBIAS_2_4V;
2323 case 2600:
2324 return DA7218_MICBIAS_2_6V;
2325 case 2800:
2326 return DA7218_MICBIAS_2_8V;
2327 case 3000:
2328 return DA7218_MICBIAS_3_0V;
2329 default:
2330 dev_warn(codec->dev, "Invalid micbias level");
2331 return DA7218_MICBIAS_1_6V;
2332 }
2333}
2334
2335static enum da7218_mic_amp_in_sel
2336 da7218_of_mic_amp_in_sel(struct snd_soc_codec *codec, const char *str)
2337{
2338 if (!strcmp(str, "diff")) {
2339 return DA7218_MIC_AMP_IN_SEL_DIFF;
2340 } else if (!strcmp(str, "se_p")) {
2341 return DA7218_MIC_AMP_IN_SEL_SE_P;
2342 } else if (!strcmp(str, "se_n")) {
2343 return DA7218_MIC_AMP_IN_SEL_SE_N;
2344 } else {
2345 dev_warn(codec->dev, "Invalid mic input type selection");
2346 return DA7218_MIC_AMP_IN_SEL_DIFF;
2347 }
2348}
2349
2350static enum da7218_dmic_data_sel
2351 da7218_of_dmic_data_sel(struct snd_soc_codec *codec, const char *str)
2352{
2353 if (!strcmp(str, "lrise_rfall")) {
2354 return DA7218_DMIC_DATA_LRISE_RFALL;
2355 } else if (!strcmp(str, "lfall_rrise")) {
2356 return DA7218_DMIC_DATA_LFALL_RRISE;
2357 } else {
2358 dev_warn(codec->dev, "Invalid DMIC data type selection");
2359 return DA7218_DMIC_DATA_LRISE_RFALL;
2360 }
2361}
2362
2363static enum da7218_dmic_samplephase
2364 da7218_of_dmic_samplephase(struct snd_soc_codec *codec, const char *str)
2365{
2366 if (!strcmp(str, "on_clkedge")) {
2367 return DA7218_DMIC_SAMPLE_ON_CLKEDGE;
2368 } else if (!strcmp(str, "between_clkedge")) {
2369 return DA7218_DMIC_SAMPLE_BETWEEN_CLKEDGE;
2370 } else {
2371 dev_warn(codec->dev, "Invalid DMIC sample phase");
2372 return DA7218_DMIC_SAMPLE_ON_CLKEDGE;
2373 }
2374}
2375
2376static enum da7218_dmic_clk_rate
2377 da7218_of_dmic_clkrate(struct snd_soc_codec *codec, u32 val)
2378{
2379 switch (val) {
2380 case 1500000:
2381 return DA7218_DMIC_CLK_1_5MHZ;
2382 case 3000000:
2383 return DA7218_DMIC_CLK_3_0MHZ;
2384 default:
2385 dev_warn(codec->dev, "Invalid DMIC clock rate");
2386 return DA7218_DMIC_CLK_3_0MHZ;
2387 }
2388}
2389
2390static enum da7218_hpldet_jack_rate
2391 da7218_of_jack_rate(struct snd_soc_codec *codec, u32 val)
2392{
2393 switch (val) {
2394 case 5:
2395 return DA7218_HPLDET_JACK_RATE_5US;
2396 case 10:
2397 return DA7218_HPLDET_JACK_RATE_10US;
2398 case 20:
2399 return DA7218_HPLDET_JACK_RATE_20US;
2400 case 40:
2401 return DA7218_HPLDET_JACK_RATE_40US;
2402 case 80:
2403 return DA7218_HPLDET_JACK_RATE_80US;
2404 case 160:
2405 return DA7218_HPLDET_JACK_RATE_160US;
2406 case 320:
2407 return DA7218_HPLDET_JACK_RATE_320US;
2408 case 640:
2409 return DA7218_HPLDET_JACK_RATE_640US;
2410 default:
2411 dev_warn(codec->dev, "Invalid jack detect rate");
2412 return DA7218_HPLDET_JACK_RATE_40US;
2413 }
2414}
2415
2416static enum da7218_hpldet_jack_debounce
2417 da7218_of_jack_debounce(struct snd_soc_codec *codec, u32 val)
2418{
2419 switch (val) {
2420 case 0:
2421 return DA7218_HPLDET_JACK_DEBOUNCE_OFF;
2422 case 2:
2423 return DA7218_HPLDET_JACK_DEBOUNCE_2;
2424 case 3:
2425 return DA7218_HPLDET_JACK_DEBOUNCE_3;
2426 case 4:
2427 return DA7218_HPLDET_JACK_DEBOUNCE_4;
2428 default:
2429 dev_warn(codec->dev, "Invalid jack debounce");
2430 return DA7218_HPLDET_JACK_DEBOUNCE_2;
2431 }
2432}
2433
2434static enum da7218_hpldet_jack_thr
2435 da7218_of_jack_thr(struct snd_soc_codec *codec, u32 val)
2436{
2437 switch (val) {
2438 case 84:
2439 return DA7218_HPLDET_JACK_THR_84PCT;
2440 case 88:
2441 return DA7218_HPLDET_JACK_THR_88PCT;
2442 case 92:
2443 return DA7218_HPLDET_JACK_THR_92PCT;
2444 case 96:
2445 return DA7218_HPLDET_JACK_THR_96PCT;
2446 default:
2447 dev_warn(codec->dev, "Invalid jack threshold level");
2448 return DA7218_HPLDET_JACK_THR_84PCT;
2449 }
2450}
2451
2452static struct da7218_pdata *da7218_of_to_pdata(struct snd_soc_codec *codec)
2453{
2454 struct da7218_priv *da7218 = snd_soc_codec_get_drvdata(codec);
2455 struct device_node *np = codec->dev->of_node;
2456 struct device_node *hpldet_np;
2457 struct da7218_pdata *pdata;
2458 struct da7218_hpldet_pdata *hpldet_pdata;
2459 const char *of_str;
2460 u32 of_val32;
2461
2462 pdata = devm_kzalloc(codec->dev, sizeof(*pdata), GFP_KERNEL);
2463 if (!pdata) {
2464 dev_warn(codec->dev, "Failed to allocate memory for pdata\n");
2465 return NULL;
2466 }
2467
2468 if (of_property_read_u32(np, "dlg,micbias1-lvl-millivolt", &of_val32) >= 0)
2469 pdata->micbias1_lvl = da7218_of_micbias_lvl(codec, of_val32);
2470 else
2471 pdata->micbias1_lvl = DA7218_MICBIAS_1_6V;
2472
2473 if (of_property_read_u32(np, "dlg,micbias2-lvl-millivolt", &of_val32) >= 0)
2474 pdata->micbias2_lvl = da7218_of_micbias_lvl(codec, of_val32);
2475 else
2476 pdata->micbias2_lvl = DA7218_MICBIAS_1_6V;
2477
2478 if (!of_property_read_string(np, "dlg,mic1-amp-in-sel", &of_str))
2479 pdata->mic1_amp_in_sel =
2480 da7218_of_mic_amp_in_sel(codec, of_str);
2481 else
2482 pdata->mic1_amp_in_sel = DA7218_MIC_AMP_IN_SEL_DIFF;
2483
2484 if (!of_property_read_string(np, "dlg,mic2-amp-in-sel", &of_str))
2485 pdata->mic2_amp_in_sel =
2486 da7218_of_mic_amp_in_sel(codec, of_str);
2487 else
2488 pdata->mic2_amp_in_sel = DA7218_MIC_AMP_IN_SEL_DIFF;
2489
2490 if (!of_property_read_string(np, "dlg,dmic1-data-sel", &of_str))
2491 pdata->dmic1_data_sel = da7218_of_dmic_data_sel(codec, of_str);
2492 else
2493 pdata->dmic1_data_sel = DA7218_DMIC_DATA_LRISE_RFALL;
2494
2495 if (!of_property_read_string(np, "dlg,dmic1-samplephase", &of_str))
2496 pdata->dmic1_samplephase =
2497 da7218_of_dmic_samplephase(codec, of_str);
2498 else
2499 pdata->dmic1_samplephase = DA7218_DMIC_SAMPLE_ON_CLKEDGE;
2500
2501 if (of_property_read_u32(np, "dlg,dmic1-clkrate-hz", &of_val32) >= 0)
2502 pdata->dmic1_clk_rate = da7218_of_dmic_clkrate(codec, of_val32);
2503 else
2504 pdata->dmic1_clk_rate = DA7218_DMIC_CLK_3_0MHZ;
2505
2506 if (!of_property_read_string(np, "dlg,dmic2-data-sel", &of_str))
2507 pdata->dmic2_data_sel = da7218_of_dmic_data_sel(codec, of_str);
2508 else
2509 pdata->dmic2_data_sel = DA7218_DMIC_DATA_LRISE_RFALL;
2510
2511 if (!of_property_read_string(np, "dlg,dmic2-samplephase", &of_str))
2512 pdata->dmic2_samplephase =
2513 da7218_of_dmic_samplephase(codec, of_str);
2514 else
2515 pdata->dmic2_samplephase = DA7218_DMIC_SAMPLE_ON_CLKEDGE;
2516
2517 if (of_property_read_u32(np, "dlg,dmic2-clkrate-hz", &of_val32) >= 0)
2518 pdata->dmic2_clk_rate = da7218_of_dmic_clkrate(codec, of_val32);
2519 else
2520 pdata->dmic2_clk_rate = DA7218_DMIC_CLK_3_0MHZ;
2521
2522 if (da7218->dev_id == DA7217_DEV_ID) {
2523 if (of_property_read_bool(np, "dlg,hp-diff-single-supply"))
2524 pdata->hp_diff_single_supply = true;
2525 }
2526
2527 if (da7218->dev_id == DA7218_DEV_ID) {
2528 hpldet_np = of_find_node_by_name(np, "da7218_hpldet");
2529 if (!hpldet_np)
2530 return pdata;
2531
2532 hpldet_pdata = devm_kzalloc(codec->dev, sizeof(*hpldet_pdata),
2533 GFP_KERNEL);
2534 if (!hpldet_pdata) {
2535 dev_warn(codec->dev,
2536 "Failed to allocate memory for hpldet pdata\n");
2537 of_node_put(hpldet_np);
2538 return pdata;
2539 }
2540 pdata->hpldet_pdata = hpldet_pdata;
2541
2542 if (of_property_read_u32(hpldet_np, "dlg,jack-rate-us",
2543 &of_val32) >= 0)
2544 hpldet_pdata->jack_rate =
2545 da7218_of_jack_rate(codec, of_val32);
2546 else
2547 hpldet_pdata->jack_rate = DA7218_HPLDET_JACK_RATE_40US;
2548
2549 if (of_property_read_u32(hpldet_np, "dlg,jack-debounce",
2550 &of_val32) >= 0)
2551 hpldet_pdata->jack_debounce =
2552 da7218_of_jack_debounce(codec, of_val32);
2553 else
2554 hpldet_pdata->jack_debounce =
2555 DA7218_HPLDET_JACK_DEBOUNCE_2;
2556
2557 if (of_property_read_u32(hpldet_np, "dlg,jack-threshold-pct",
2558 &of_val32) >= 0)
2559 hpldet_pdata->jack_thr =
2560 da7218_of_jack_thr(codec, of_val32);
2561 else
2562 hpldet_pdata->jack_thr = DA7218_HPLDET_JACK_THR_84PCT;
2563
2564 if (of_property_read_bool(hpldet_np, "dlg,comp-inv"))
2565 hpldet_pdata->comp_inv = true;
2566
2567 if (of_property_read_bool(hpldet_np, "dlg,hyst"))
2568 hpldet_pdata->hyst = true;
2569
2570 if (of_property_read_bool(hpldet_np, "dlg,discharge"))
2571 hpldet_pdata->discharge = true;
2572
2573 of_node_put(hpldet_np);
2574 }
2575
2576 return pdata;
2577}
2578
2579
2580/*
2581 * Codec driver functions
2582 */
2583
2584static int da7218_set_bias_level(struct snd_soc_codec *codec,
2585 enum snd_soc_bias_level level)
2586{
2587 struct da7218_priv *da7218 = snd_soc_codec_get_drvdata(codec);
2588 int ret;
2589
2590 switch (level) {
2591 case SND_SOC_BIAS_ON:
2592 case SND_SOC_BIAS_PREPARE:
2593 break;
2594 case SND_SOC_BIAS_STANDBY:
2595 if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF) {
2596 /* MCLK */
2597 if (da7218->mclk) {
2598 ret = clk_prepare_enable(da7218->mclk);
2599 if (ret) {
2600 dev_err(codec->dev,
2601 "Failed to enable mclk\n");
2602 return ret;
2603 }
2604 }
2605
2606 /* Master bias */
2607 snd_soc_update_bits(codec, DA7218_REFERENCES,
2608 DA7218_BIAS_EN_MASK,
2609 DA7218_BIAS_EN_MASK);
2610
2611 /* Internal LDO */
2612 snd_soc_update_bits(codec, DA7218_LDO_CTRL,
2613 DA7218_LDO_EN_MASK,
2614 DA7218_LDO_EN_MASK);
2615 }
2616 break;
2617 case SND_SOC_BIAS_OFF:
2618 /* Only disable if jack detection disabled */
2619 if (!da7218->jack) {
2620 /* Internal LDO */
2621 snd_soc_update_bits(codec, DA7218_LDO_CTRL,
2622 DA7218_LDO_EN_MASK, 0);
2623
2624 /* Master bias */
2625 snd_soc_update_bits(codec, DA7218_REFERENCES,
2626 DA7218_BIAS_EN_MASK, 0);
2627 }
2628
2629 /* MCLK */
2630 if (da7218->mclk)
2631 clk_disable_unprepare(da7218->mclk);
2632 break;
2633 }
2634
2635 return 0;
2636}
2637
2638static const char *da7218_supply_names[DA7218_NUM_SUPPLIES] = {
2639 [DA7218_SUPPLY_VDD] = "VDD",
2640 [DA7218_SUPPLY_VDDMIC] = "VDDMIC",
2641 [DA7218_SUPPLY_VDDIO] = "VDDIO",
2642};
2643
2644static int da7218_handle_supplies(struct snd_soc_codec *codec)
2645{
2646 struct da7218_priv *da7218 = snd_soc_codec_get_drvdata(codec);
2647 struct regulator *vddio;
2648 u8 io_voltage_lvl = DA7218_IO_VOLTAGE_LEVEL_2_5V_3_6V;
2649 int i, ret;
2650
2651 /* Get required supplies */
2652 for (i = 0; i < DA7218_NUM_SUPPLIES; ++i)
2653 da7218->supplies[i].supply = da7218_supply_names[i];
2654
2655 ret = devm_regulator_bulk_get(codec->dev, DA7218_NUM_SUPPLIES,
2656 da7218->supplies);
2657 if (ret) {
2658 dev_err(codec->dev, "Failed to get supplies\n");
2659 return ret;
2660 }
2661
2662 /* Determine VDDIO voltage provided */
2663 vddio = da7218->supplies[DA7218_SUPPLY_VDDIO].consumer;
2664 ret = regulator_get_voltage(vddio);
2665 if (ret < 1500000)
2666 dev_warn(codec->dev, "Invalid VDDIO voltage\n");
2667 else if (ret < 2500000)
2668 io_voltage_lvl = DA7218_IO_VOLTAGE_LEVEL_1_5V_2_5V;
2669
2670 /* Enable main supplies */
2671 ret = regulator_bulk_enable(DA7218_NUM_SUPPLIES, da7218->supplies);
2672 if (ret) {
2673 dev_err(codec->dev, "Failed to enable supplies\n");
2674 return ret;
2675 }
2676
2677 /* Ensure device in active mode */
2678 snd_soc_write(codec, DA7218_SYSTEM_ACTIVE, DA7218_SYSTEM_ACTIVE_MASK);
2679
2680 /* Update IO voltage level range */
2681 snd_soc_write(codec, DA7218_IO_CTRL, io_voltage_lvl);
2682
2683 return 0;
2684}
2685
2686static void da7218_handle_pdata(struct snd_soc_codec *codec)
2687{
2688 struct da7218_priv *da7218 = snd_soc_codec_get_drvdata(codec);
2689 struct da7218_pdata *pdata = da7218->pdata;
2690
2691 if (pdata) {
2692 u8 micbias_lvl = 0, dmic_cfg = 0;
2693
2694 /* Mic Bias voltages */
2695 switch (pdata->micbias1_lvl) {
2696 case DA7218_MICBIAS_1_2V:
2697 micbias_lvl |= DA7218_MICBIAS_1_LP_MODE_MASK;
2698 break;
2699 case DA7218_MICBIAS_1_6V:
2700 case DA7218_MICBIAS_1_8V:
2701 case DA7218_MICBIAS_2_0V:
2702 case DA7218_MICBIAS_2_2V:
2703 case DA7218_MICBIAS_2_4V:
2704 case DA7218_MICBIAS_2_6V:
2705 case DA7218_MICBIAS_2_8V:
2706 case DA7218_MICBIAS_3_0V:
2707 micbias_lvl |= (pdata->micbias1_lvl <<
2708 DA7218_MICBIAS_1_LEVEL_SHIFT);
2709 break;
2710 }
2711
2712 switch (pdata->micbias2_lvl) {
2713 case DA7218_MICBIAS_1_2V:
2714 micbias_lvl |= DA7218_MICBIAS_2_LP_MODE_MASK;
2715 break;
2716 case DA7218_MICBIAS_1_6V:
2717 case DA7218_MICBIAS_1_8V:
2718 case DA7218_MICBIAS_2_0V:
2719 case DA7218_MICBIAS_2_2V:
2720 case DA7218_MICBIAS_2_4V:
2721 case DA7218_MICBIAS_2_6V:
2722 case DA7218_MICBIAS_2_8V:
2723 case DA7218_MICBIAS_3_0V:
2724 micbias_lvl |= (pdata->micbias2_lvl <<
2725 DA7218_MICBIAS_2_LEVEL_SHIFT);
2726 break;
2727 }
2728
2729 snd_soc_write(codec, DA7218_MICBIAS_CTRL, micbias_lvl);
2730
2731 /* Mic */
2732 switch (pdata->mic1_amp_in_sel) {
2733 case DA7218_MIC_AMP_IN_SEL_DIFF:
2734 case DA7218_MIC_AMP_IN_SEL_SE_P:
2735 case DA7218_MIC_AMP_IN_SEL_SE_N:
2736 snd_soc_write(codec, DA7218_MIC_1_SELECT,
2737 pdata->mic1_amp_in_sel);
2738 break;
2739 }
2740
2741 switch (pdata->mic2_amp_in_sel) {
2742 case DA7218_MIC_AMP_IN_SEL_DIFF:
2743 case DA7218_MIC_AMP_IN_SEL_SE_P:
2744 case DA7218_MIC_AMP_IN_SEL_SE_N:
2745 snd_soc_write(codec, DA7218_MIC_2_SELECT,
2746 pdata->mic2_amp_in_sel);
2747 break;
2748 }
2749
2750 /* DMic */
2751 switch (pdata->dmic1_data_sel) {
2752 case DA7218_DMIC_DATA_LFALL_RRISE:
2753 case DA7218_DMIC_DATA_LRISE_RFALL:
2754 dmic_cfg |= (pdata->dmic1_data_sel <<
2755 DA7218_DMIC_1_DATA_SEL_SHIFT);
2756 break;
2757 }
2758
2759 switch (pdata->dmic1_samplephase) {
2760 case DA7218_DMIC_SAMPLE_ON_CLKEDGE:
2761 case DA7218_DMIC_SAMPLE_BETWEEN_CLKEDGE:
2762 dmic_cfg |= (pdata->dmic1_samplephase <<
2763 DA7218_DMIC_1_SAMPLEPHASE_SHIFT);
2764 break;
2765 }
2766
2767 switch (pdata->dmic1_clk_rate) {
2768 case DA7218_DMIC_CLK_3_0MHZ:
2769 case DA7218_DMIC_CLK_1_5MHZ:
2770 dmic_cfg |= (pdata->dmic1_clk_rate <<
2771 DA7218_DMIC_1_CLK_RATE_SHIFT);
2772 break;
2773 }
2774
2775 snd_soc_update_bits(codec, DA7218_DMIC_1_CTRL,
2776 DA7218_DMIC_1_DATA_SEL_MASK |
2777 DA7218_DMIC_1_SAMPLEPHASE_MASK |
2778 DA7218_DMIC_1_CLK_RATE_MASK, dmic_cfg);
2779
2780 dmic_cfg = 0;
2781 switch (pdata->dmic2_data_sel) {
2782 case DA7218_DMIC_DATA_LFALL_RRISE:
2783 case DA7218_DMIC_DATA_LRISE_RFALL:
2784 dmic_cfg |= (pdata->dmic2_data_sel <<
2785 DA7218_DMIC_2_DATA_SEL_SHIFT);
2786 break;
2787 }
2788
2789 switch (pdata->dmic2_samplephase) {
2790 case DA7218_DMIC_SAMPLE_ON_CLKEDGE:
2791 case DA7218_DMIC_SAMPLE_BETWEEN_CLKEDGE:
2792 dmic_cfg |= (pdata->dmic2_samplephase <<
2793 DA7218_DMIC_2_SAMPLEPHASE_SHIFT);
2794 break;
2795 }
2796
2797 switch (pdata->dmic2_clk_rate) {
2798 case DA7218_DMIC_CLK_3_0MHZ:
2799 case DA7218_DMIC_CLK_1_5MHZ:
2800 dmic_cfg |= (pdata->dmic2_clk_rate <<
2801 DA7218_DMIC_2_CLK_RATE_SHIFT);
2802 break;
2803 }
2804
2805 snd_soc_update_bits(codec, DA7218_DMIC_2_CTRL,
2806 DA7218_DMIC_2_DATA_SEL_MASK |
2807 DA7218_DMIC_2_SAMPLEPHASE_MASK |
2808 DA7218_DMIC_2_CLK_RATE_MASK, dmic_cfg);
2809
2810 /* DA7217 Specific */
2811 if (da7218->dev_id == DA7217_DEV_ID) {
2812 da7218->hp_single_supply =
2813 pdata->hp_diff_single_supply;
2814
2815 if (da7218->hp_single_supply) {
2816 snd_soc_write(codec, DA7218_HP_DIFF_UNLOCK,
2817 DA7218_HP_DIFF_UNLOCK_VAL);
2818 snd_soc_update_bits(codec, DA7218_HP_DIFF_CTRL,
2819 DA7218_HP_AMP_SINGLE_SUPPLY_EN_MASK,
2820 DA7218_HP_AMP_SINGLE_SUPPLY_EN_MASK);
2821 }
2822 }
2823
2824 /* DA7218 Specific */
2825 if ((da7218->dev_id == DA7218_DEV_ID) &&
2826 (pdata->hpldet_pdata)) {
2827 struct da7218_hpldet_pdata *hpldet_pdata =
2828 pdata->hpldet_pdata;
2829 u8 hpldet_cfg = 0;
2830
2831 switch (hpldet_pdata->jack_rate) {
2832 case DA7218_HPLDET_JACK_RATE_5US:
2833 case DA7218_HPLDET_JACK_RATE_10US:
2834 case DA7218_HPLDET_JACK_RATE_20US:
2835 case DA7218_HPLDET_JACK_RATE_40US:
2836 case DA7218_HPLDET_JACK_RATE_80US:
2837 case DA7218_HPLDET_JACK_RATE_160US:
2838 case DA7218_HPLDET_JACK_RATE_320US:
2839 case DA7218_HPLDET_JACK_RATE_640US:
2840 hpldet_cfg |=
2841 (hpldet_pdata->jack_rate <<
2842 DA7218_HPLDET_JACK_RATE_SHIFT);
2843 break;
2844 }
2845
2846 switch (hpldet_pdata->jack_debounce) {
2847 case DA7218_HPLDET_JACK_DEBOUNCE_OFF:
2848 case DA7218_HPLDET_JACK_DEBOUNCE_2:
2849 case DA7218_HPLDET_JACK_DEBOUNCE_3:
2850 case DA7218_HPLDET_JACK_DEBOUNCE_4:
2851 hpldet_cfg |=
2852 (hpldet_pdata->jack_debounce <<
2853 DA7218_HPLDET_JACK_DEBOUNCE_SHIFT);
2854 break;
2855 }
2856
2857 switch (hpldet_pdata->jack_thr) {
2858 case DA7218_HPLDET_JACK_THR_84PCT:
2859 case DA7218_HPLDET_JACK_THR_88PCT:
2860 case DA7218_HPLDET_JACK_THR_92PCT:
2861 case DA7218_HPLDET_JACK_THR_96PCT:
2862 hpldet_cfg |=
2863 (hpldet_pdata->jack_thr <<
2864 DA7218_HPLDET_JACK_THR_SHIFT);
2865 break;
2866 }
2867 snd_soc_update_bits(codec, DA7218_HPLDET_JACK,
2868 DA7218_HPLDET_JACK_RATE_MASK |
2869 DA7218_HPLDET_JACK_DEBOUNCE_MASK |
2870 DA7218_HPLDET_JACK_THR_MASK,
2871 hpldet_cfg);
2872
2873 hpldet_cfg = 0;
2874 if (hpldet_pdata->comp_inv)
2875 hpldet_cfg |= DA7218_HPLDET_COMP_INV_MASK;
2876
2877 if (hpldet_pdata->hyst)
2878 hpldet_cfg |= DA7218_HPLDET_HYST_EN_MASK;
2879
2880 if (hpldet_pdata->discharge)
2881 hpldet_cfg |= DA7218_HPLDET_DISCHARGE_EN_MASK;
2882
2883 snd_soc_write(codec, DA7218_HPLDET_CTRL, hpldet_cfg);
2884 }
2885 }
2886}
2887
2888static int da7218_probe(struct snd_soc_codec *codec)
2889{
2890 struct da7218_priv *da7218 = snd_soc_codec_get_drvdata(codec);
2891 int ret;
2892
2893 /* Regulator configuration */
2894 ret = da7218_handle_supplies(codec);
2895 if (ret)
2896 return ret;
2897
2898 /* Handle DT/Platform data */
2899 if (codec->dev->of_node)
2900 da7218->pdata = da7218_of_to_pdata(codec);
2901 else
2902 da7218->pdata = dev_get_platdata(codec->dev);
2903
2904 da7218_handle_pdata(codec);
2905
2906 /* Check if MCLK provided, if not the clock is NULL */
2907 da7218->mclk = devm_clk_get(codec->dev, "mclk");
2908 if (IS_ERR(da7218->mclk)) {
2909 if (PTR_ERR(da7218->mclk) != -ENOENT) {
2910 ret = PTR_ERR(da7218->mclk);
2911 goto err_disable_reg;
2912 } else {
2913 da7218->mclk = NULL;
2914 }
2915 }
2916
2917 /* Default PC to free-running */
2918 snd_soc_write(codec, DA7218_PC_COUNT, DA7218_PC_FREERUN_MASK);
2919
2920 /*
2921 * Default Output Filter mixers to off otherwise DAPM will power
2922 * Mic to HP passthrough paths by default at startup.
2923 */
2924 snd_soc_write(codec, DA7218_DROUTING_OUTFILT_1L, 0);
2925 snd_soc_write(codec, DA7218_DROUTING_OUTFILT_1R, 0);
2926
2927 /* Default CP to normal load, power mode */
2928 snd_soc_update_bits(codec, DA7218_CP_CTRL,
2929 DA7218_CP_SMALL_SWITCH_FREQ_EN_MASK, 0);
2930
2931 /* Default gain ramping */
2932 snd_soc_update_bits(codec, DA7218_MIXIN_1_CTRL,
2933 DA7218_MIXIN_1_AMP_RAMP_EN_MASK,
2934 DA7218_MIXIN_1_AMP_RAMP_EN_MASK);
2935 snd_soc_update_bits(codec, DA7218_MIXIN_2_CTRL,
2936 DA7218_MIXIN_2_AMP_RAMP_EN_MASK,
2937 DA7218_MIXIN_2_AMP_RAMP_EN_MASK);
2938 snd_soc_update_bits(codec, DA7218_IN_1L_FILTER_CTRL,
2939 DA7218_IN_1L_RAMP_EN_MASK,
2940 DA7218_IN_1L_RAMP_EN_MASK);
2941 snd_soc_update_bits(codec, DA7218_IN_1R_FILTER_CTRL,
2942 DA7218_IN_1R_RAMP_EN_MASK,
2943 DA7218_IN_1R_RAMP_EN_MASK);
2944 snd_soc_update_bits(codec, DA7218_IN_2L_FILTER_CTRL,
2945 DA7218_IN_2L_RAMP_EN_MASK,
2946 DA7218_IN_2L_RAMP_EN_MASK);
2947 snd_soc_update_bits(codec, DA7218_IN_2R_FILTER_CTRL,
2948 DA7218_IN_2R_RAMP_EN_MASK,
2949 DA7218_IN_2R_RAMP_EN_MASK);
2950 snd_soc_update_bits(codec, DA7218_DGS_GAIN_CTRL,
2951 DA7218_DGS_RAMP_EN_MASK, DA7218_DGS_RAMP_EN_MASK);
2952 snd_soc_update_bits(codec, DA7218_OUT_1L_FILTER_CTRL,
2953 DA7218_OUT_1L_RAMP_EN_MASK,
2954 DA7218_OUT_1L_RAMP_EN_MASK);
2955 snd_soc_update_bits(codec, DA7218_OUT_1R_FILTER_CTRL,
2956 DA7218_OUT_1R_RAMP_EN_MASK,
2957 DA7218_OUT_1R_RAMP_EN_MASK);
2958 snd_soc_update_bits(codec, DA7218_HP_L_CTRL,
2959 DA7218_HP_L_AMP_RAMP_EN_MASK,
2960 DA7218_HP_L_AMP_RAMP_EN_MASK);
2961 snd_soc_update_bits(codec, DA7218_HP_R_CTRL,
2962 DA7218_HP_R_AMP_RAMP_EN_MASK,
2963 DA7218_HP_R_AMP_RAMP_EN_MASK);
2964
2965 /* Default infinite tone gen, start/stop by Kcontrol */
2966 snd_soc_write(codec, DA7218_TONE_GEN_CYCLES, DA7218_BEEP_CYCLES_MASK);
2967
2968 /* DA7217 specific config */
2969 if (da7218->dev_id == DA7217_DEV_ID) {
2970 snd_soc_update_bits(codec, DA7218_HP_DIFF_CTRL,
2971 DA7218_HP_AMP_DIFF_MODE_EN_MASK,
2972 DA7218_HP_AMP_DIFF_MODE_EN_MASK);
2973
2974 /* Only DA7218 supports HP detect, mask off for DA7217 */
2975 snd_soc_write(codec, DA7218_EVENT_MASK,
2976 DA7218_HPLDET_JACK_EVENT_IRQ_MSK_MASK);
2977 }
2978
2979 if (da7218->irq) {
2980 ret = devm_request_threaded_irq(codec->dev, da7218->irq, NULL,
2981 da7218_irq_thread,
2982 IRQF_TRIGGER_LOW | IRQF_ONESHOT,
2983 "da7218", codec);
2984 if (ret != 0) {
2985 dev_err(codec->dev, "Failed to request IRQ %d: %d\n",
2986 da7218->irq, ret);
2987 goto err_disable_reg;
2988 }
2989
2990 }
2991
2992 return 0;
2993
2994err_disable_reg:
2995 regulator_bulk_disable(DA7218_NUM_SUPPLIES, da7218->supplies);
2996
2997 return ret;
2998}
2999
3000static int da7218_remove(struct snd_soc_codec *codec)
3001{
3002 struct da7218_priv *da7218 = snd_soc_codec_get_drvdata(codec);
3003
3004 regulator_bulk_disable(DA7218_NUM_SUPPLIES, da7218->supplies);
3005
3006 return 0;
3007}
3008
3009#ifdef CONFIG_PM
3010static int da7218_suspend(struct snd_soc_codec *codec)
3011{
3012 struct da7218_priv *da7218 = snd_soc_codec_get_drvdata(codec);
3013
3014 da7218_set_bias_level(codec, SND_SOC_BIAS_OFF);
3015
3016 /* Put device into standby mode if jack detection disabled */
3017 if (!da7218->jack)
3018 snd_soc_write(codec, DA7218_SYSTEM_ACTIVE, 0);
3019
3020 return 0;
3021}
3022
3023static int da7218_resume(struct snd_soc_codec *codec)
3024{
3025 struct da7218_priv *da7218 = snd_soc_codec_get_drvdata(codec);
3026
3027 /* Put device into active mode if previously moved to standby */
3028 if (!da7218->jack)
3029 snd_soc_write(codec, DA7218_SYSTEM_ACTIVE,
3030 DA7218_SYSTEM_ACTIVE_MASK);
3031
3032 da7218_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
3033
3034 return 0;
3035}
3036#else
3037#define da7218_suspend NULL
3038#define da7218_resume NULL
3039#endif
3040
3041static struct snd_soc_codec_driver soc_codec_dev_da7218 = {
3042 .probe = da7218_probe,
3043 .remove = da7218_remove,
3044 .suspend = da7218_suspend,
3045 .resume = da7218_resume,
3046 .set_bias_level = da7218_set_bias_level,
3047
3048 .controls = da7218_snd_controls,
3049 .num_controls = ARRAY_SIZE(da7218_snd_controls),
3050
3051 .dapm_widgets = da7218_dapm_widgets,
3052 .num_dapm_widgets = ARRAY_SIZE(da7218_dapm_widgets),
3053 .dapm_routes = da7218_audio_map,
3054 .num_dapm_routes = ARRAY_SIZE(da7218_audio_map),
3055};
3056
3057
3058/*
3059 * Regmap configs
3060 */
3061
3062static struct reg_default da7218_reg_defaults[] = {
3063 { DA7218_SYSTEM_ACTIVE, 0x00 },
3064 { DA7218_CIF_CTRL, 0x00 },
3065 { DA7218_SPARE1, 0x00 },
3066 { DA7218_SR, 0xAA },
3067 { DA7218_PC_COUNT, 0x02 },
3068 { DA7218_GAIN_RAMP_CTRL, 0x00 },
3069 { DA7218_CIF_TIMEOUT_CTRL, 0x01 },
3070 { DA7218_SYSTEM_MODES_INPUT, 0x00 },
3071 { DA7218_SYSTEM_MODES_OUTPUT, 0x00 },
3072 { DA7218_IN_1L_FILTER_CTRL, 0x00 },
3073 { DA7218_IN_1R_FILTER_CTRL, 0x00 },
3074 { DA7218_IN_2L_FILTER_CTRL, 0x00 },
3075 { DA7218_IN_2R_FILTER_CTRL, 0x00 },
3076 { DA7218_OUT_1L_FILTER_CTRL, 0x40 },
3077 { DA7218_OUT_1R_FILTER_CTRL, 0x40 },
3078 { DA7218_OUT_1_HPF_FILTER_CTRL, 0x80 },
3079 { DA7218_OUT_1_EQ_12_FILTER_CTRL, 0x77 },
3080 { DA7218_OUT_1_EQ_34_FILTER_CTRL, 0x77 },
3081 { DA7218_OUT_1_EQ_5_FILTER_CTRL, 0x07 },
3082 { DA7218_OUT_1_BIQ_5STAGE_CTRL, 0x40 },
3083 { DA7218_OUT_1_BIQ_5STAGE_DATA, 0x00 },
3084 { DA7218_OUT_1_BIQ_5STAGE_ADDR, 0x00 },
3085 { DA7218_MIXIN_1_CTRL, 0x48 },
3086 { DA7218_MIXIN_1_GAIN, 0x03 },
3087 { DA7218_MIXIN_2_CTRL, 0x48 },
3088 { DA7218_MIXIN_2_GAIN, 0x03 },
3089 { DA7218_ALC_CTRL1, 0x00 },
3090 { DA7218_ALC_CTRL2, 0x00 },
3091 { DA7218_ALC_CTRL3, 0x00 },
3092 { DA7218_ALC_NOISE, 0x3F },
3093 { DA7218_ALC_TARGET_MIN, 0x3F },
3094 { DA7218_ALC_TARGET_MAX, 0x00 },
3095 { DA7218_ALC_GAIN_LIMITS, 0xFF },
3096 { DA7218_ALC_ANA_GAIN_LIMITS, 0x71 },
3097 { DA7218_ALC_ANTICLIP_CTRL, 0x00 },
3098 { DA7218_AGS_ENABLE, 0x00 },
3099 { DA7218_AGS_TRIGGER, 0x09 },
3100 { DA7218_AGS_ATT_MAX, 0x00 },
3101 { DA7218_AGS_TIMEOUT, 0x00 },
3102 { DA7218_AGS_ANTICLIP_CTRL, 0x00 },
3103 { DA7218_ENV_TRACK_CTRL, 0x00 },
3104 { DA7218_LVL_DET_CTRL, 0x00 },
3105 { DA7218_LVL_DET_LEVEL, 0x7F },
3106 { DA7218_DGS_TRIGGER, 0x24 },
3107 { DA7218_DGS_ENABLE, 0x00 },
3108 { DA7218_DGS_RISE_FALL, 0x50 },
3109 { DA7218_DGS_SYNC_DELAY, 0xA3 },
3110 { DA7218_DGS_SYNC_DELAY2, 0x31 },
3111 { DA7218_DGS_SYNC_DELAY3, 0x11 },
3112 { DA7218_DGS_LEVELS, 0x01 },
3113 { DA7218_DGS_GAIN_CTRL, 0x74 },
3114 { DA7218_DROUTING_OUTDAI_1L, 0x01 },
3115 { DA7218_DMIX_OUTDAI_1L_INFILT_1L_GAIN, 0x1C },
3116 { DA7218_DMIX_OUTDAI_1L_INFILT_1R_GAIN, 0x1C },
3117 { DA7218_DMIX_OUTDAI_1L_INFILT_2L_GAIN, 0x1C },
3118 { DA7218_DMIX_OUTDAI_1L_INFILT_2R_GAIN, 0x1C },
3119 { DA7218_DMIX_OUTDAI_1L_TONEGEN_GAIN, 0x1C },
3120 { DA7218_DMIX_OUTDAI_1L_INDAI_1L_GAIN, 0x1C },
3121 { DA7218_DMIX_OUTDAI_1L_INDAI_1R_GAIN, 0x1C },
3122 { DA7218_DROUTING_OUTDAI_1R, 0x04 },
3123 { DA7218_DMIX_OUTDAI_1R_INFILT_1L_GAIN, 0x1C },
3124 { DA7218_DMIX_OUTDAI_1R_INFILT_1R_GAIN, 0x1C },
3125 { DA7218_DMIX_OUTDAI_1R_INFILT_2L_GAIN, 0x1C },
3126 { DA7218_DMIX_OUTDAI_1R_INFILT_2R_GAIN, 0x1C },
3127 { DA7218_DMIX_OUTDAI_1R_TONEGEN_GAIN, 0x1C },
3128 { DA7218_DMIX_OUTDAI_1R_INDAI_1L_GAIN, 0x1C },
3129 { DA7218_DMIX_OUTDAI_1R_INDAI_1R_GAIN, 0x1C },
3130 { DA7218_DROUTING_OUTFILT_1L, 0x01 },
3131 { DA7218_DMIX_OUTFILT_1L_INFILT_1L_GAIN, 0x1C },
3132 { DA7218_DMIX_OUTFILT_1L_INFILT_1R_GAIN, 0x1C },
3133 { DA7218_DMIX_OUTFILT_1L_INFILT_2L_GAIN, 0x1C },
3134 { DA7218_DMIX_OUTFILT_1L_INFILT_2R_GAIN, 0x1C },
3135 { DA7218_DMIX_OUTFILT_1L_TONEGEN_GAIN, 0x1C },
3136 { DA7218_DMIX_OUTFILT_1L_INDAI_1L_GAIN, 0x1C },
3137 { DA7218_DMIX_OUTFILT_1L_INDAI_1R_GAIN, 0x1C },
3138 { DA7218_DROUTING_OUTFILT_1R, 0x04 },
3139 { DA7218_DMIX_OUTFILT_1R_INFILT_1L_GAIN, 0x1C },
3140 { DA7218_DMIX_OUTFILT_1R_INFILT_1R_GAIN, 0x1C },
3141 { DA7218_DMIX_OUTFILT_1R_INFILT_2L_GAIN, 0x1C },
3142 { DA7218_DMIX_OUTFILT_1R_INFILT_2R_GAIN, 0x1C },
3143 { DA7218_DMIX_OUTFILT_1R_TONEGEN_GAIN, 0x1C },
3144 { DA7218_DMIX_OUTFILT_1R_INDAI_1L_GAIN, 0x1C },
3145 { DA7218_DMIX_OUTFILT_1R_INDAI_1R_GAIN, 0x1C },
3146 { DA7218_DROUTING_OUTDAI_2L, 0x04 },
3147 { DA7218_DMIX_OUTDAI_2L_INFILT_1L_GAIN, 0x1C },
3148 { DA7218_DMIX_OUTDAI_2L_INFILT_1R_GAIN, 0x1C },
3149 { DA7218_DMIX_OUTDAI_2L_INFILT_2L_GAIN, 0x1C },
3150 { DA7218_DMIX_OUTDAI_2L_INFILT_2R_GAIN, 0x1C },
3151 { DA7218_DMIX_OUTDAI_2L_TONEGEN_GAIN, 0x1C },
3152 { DA7218_DMIX_OUTDAI_2L_INDAI_1L_GAIN, 0x1C },
3153 { DA7218_DMIX_OUTDAI_2L_INDAI_1R_GAIN, 0x1C },
3154 { DA7218_DROUTING_OUTDAI_2R, 0x08 },
3155 { DA7218_DMIX_OUTDAI_2R_INFILT_1L_GAIN, 0x1C },
3156 { DA7218_DMIX_OUTDAI_2R_INFILT_1R_GAIN, 0x1C },
3157 { DA7218_DMIX_OUTDAI_2R_INFILT_2L_GAIN, 0x1C },
3158 { DA7218_DMIX_OUTDAI_2R_INFILT_2R_GAIN, 0x1C },
3159 { DA7218_DMIX_OUTDAI_2R_TONEGEN_GAIN, 0x1C },
3160 { DA7218_DMIX_OUTDAI_2R_INDAI_1L_GAIN, 0x1C },
3161 { DA7218_DMIX_OUTDAI_2R_INDAI_1R_GAIN, 0x1C },
3162 { DA7218_DAI_CTRL, 0x28 },
3163 { DA7218_DAI_TDM_CTRL, 0x40 },
3164 { DA7218_DAI_OFFSET_LOWER, 0x00 },
3165 { DA7218_DAI_OFFSET_UPPER, 0x00 },
3166 { DA7218_DAI_CLK_MODE, 0x01 },
3167 { DA7218_PLL_CTRL, 0x04 },
3168 { DA7218_PLL_FRAC_TOP, 0x00 },
3169 { DA7218_PLL_FRAC_BOT, 0x00 },
3170 { DA7218_PLL_INTEGER, 0x20 },
3171 { DA7218_DAC_NG_CTRL, 0x00 },
3172 { DA7218_DAC_NG_SETUP_TIME, 0x00 },
3173 { DA7218_DAC_NG_OFF_THRESH, 0x00 },
3174 { DA7218_DAC_NG_ON_THRESH, 0x00 },
3175 { DA7218_TONE_GEN_CFG2, 0x00 },
3176 { DA7218_TONE_GEN_FREQ1_L, 0x55 },
3177 { DA7218_TONE_GEN_FREQ1_U, 0x15 },
3178 { DA7218_TONE_GEN_FREQ2_L, 0x00 },
3179 { DA7218_TONE_GEN_FREQ2_U, 0x40 },
3180 { DA7218_TONE_GEN_CYCLES, 0x00 },
3181 { DA7218_TONE_GEN_ON_PER, 0x02 },
3182 { DA7218_TONE_GEN_OFF_PER, 0x01 },
3183 { DA7218_CP_CTRL, 0x60 },
3184 { DA7218_CP_DELAY, 0x11 },
3185 { DA7218_CP_VOL_THRESHOLD1, 0x0E },
3186 { DA7218_MIC_1_CTRL, 0x40 },
3187 { DA7218_MIC_1_GAIN, 0x01 },
3188 { DA7218_MIC_1_SELECT, 0x00 },
3189 { DA7218_MIC_2_CTRL, 0x40 },
3190 { DA7218_MIC_2_GAIN, 0x01 },
3191 { DA7218_MIC_2_SELECT, 0x00 },
3192 { DA7218_IN_1_HPF_FILTER_CTRL, 0x80 },
3193 { DA7218_IN_2_HPF_FILTER_CTRL, 0x80 },
3194 { DA7218_ADC_1_CTRL, 0x07 },
3195 { DA7218_ADC_2_CTRL, 0x07 },
3196 { DA7218_MIXOUT_L_CTRL, 0x00 },
3197 { DA7218_MIXOUT_L_GAIN, 0x03 },
3198 { DA7218_MIXOUT_R_CTRL, 0x00 },
3199 { DA7218_MIXOUT_R_GAIN, 0x03 },
3200 { DA7218_HP_L_CTRL, 0x40 },
3201 { DA7218_HP_L_GAIN, 0x3B },
3202 { DA7218_HP_R_CTRL, 0x40 },
3203 { DA7218_HP_R_GAIN, 0x3B },
3204 { DA7218_HP_DIFF_CTRL, 0x00 },
3205 { DA7218_HP_DIFF_UNLOCK, 0xC3 },
3206 { DA7218_HPLDET_JACK, 0x0B },
3207 { DA7218_HPLDET_CTRL, 0x00 },
3208 { DA7218_REFERENCES, 0x08 },
3209 { DA7218_IO_CTRL, 0x00 },
3210 { DA7218_LDO_CTRL, 0x00 },
3211 { DA7218_SIDETONE_CTRL, 0x40 },
3212 { DA7218_SIDETONE_IN_SELECT, 0x00 },
3213 { DA7218_SIDETONE_GAIN, 0x1C },
3214 { DA7218_DROUTING_ST_OUTFILT_1L, 0x01 },
3215 { DA7218_DROUTING_ST_OUTFILT_1R, 0x02 },
3216 { DA7218_SIDETONE_BIQ_3STAGE_DATA, 0x00 },
3217 { DA7218_SIDETONE_BIQ_3STAGE_ADDR, 0x00 },
3218 { DA7218_EVENT_MASK, 0x00 },
3219 { DA7218_DMIC_1_CTRL, 0x00 },
3220 { DA7218_DMIC_2_CTRL, 0x00 },
3221 { DA7218_IN_1L_GAIN, 0x6F },
3222 { DA7218_IN_1R_GAIN, 0x6F },
3223 { DA7218_IN_2L_GAIN, 0x6F },
3224 { DA7218_IN_2R_GAIN, 0x6F },
3225 { DA7218_OUT_1L_GAIN, 0x6F },
3226 { DA7218_OUT_1R_GAIN, 0x6F },
3227 { DA7218_MICBIAS_CTRL, 0x00 },
3228 { DA7218_MICBIAS_EN, 0x00 },
3229};
3230
3231static bool da7218_volatile_register(struct device *dev, unsigned int reg)
3232{
3233 switch (reg) {
3234 case DA7218_STATUS1:
3235 case DA7218_SOFT_RESET:
3236 case DA7218_SYSTEM_STATUS:
3237 case DA7218_CALIB_CTRL:
3238 case DA7218_CALIB_OFFSET_AUTO_M_1:
3239 case DA7218_CALIB_OFFSET_AUTO_U_1:
3240 case DA7218_CALIB_OFFSET_AUTO_M_2:
3241 case DA7218_CALIB_OFFSET_AUTO_U_2:
3242 case DA7218_PLL_STATUS:
3243 case DA7218_PLL_REFOSC_CAL:
3244 case DA7218_TONE_GEN_CFG1:
3245 case DA7218_ADC_MODE:
3246 case DA7218_HP_SNGL_CTRL:
3247 case DA7218_HPLDET_TEST:
3248 case DA7218_EVENT_STATUS:
3249 case DA7218_EVENT:
3250 return true;
3251 default:
3252 return false;
3253 }
3254}
3255
3256static const struct regmap_config da7218_regmap_config = {
3257 .reg_bits = 8,
3258 .val_bits = 8,
3259
3260 .max_register = DA7218_MICBIAS_EN,
3261 .reg_defaults = da7218_reg_defaults,
3262 .num_reg_defaults = ARRAY_SIZE(da7218_reg_defaults),
3263 .volatile_reg = da7218_volatile_register,
3264 .cache_type = REGCACHE_RBTREE,
3265};
3266
3267
3268/*
3269 * I2C layer
3270 */
3271
3272static int da7218_i2c_probe(struct i2c_client *i2c,
3273 const struct i2c_device_id *id)
3274{
3275 struct da7218_priv *da7218;
3276 int ret;
3277
3278 da7218 = devm_kzalloc(&i2c->dev, sizeof(struct da7218_priv),
3279 GFP_KERNEL);
3280 if (!da7218)
3281 return -ENOMEM;
3282
3283 i2c_set_clientdata(i2c, da7218);
3284
3285 if (i2c->dev.of_node)
3286 da7218->dev_id = da7218_of_get_id(&i2c->dev);
3287 else
3288 da7218->dev_id = id->driver_data;
3289
3290 if ((da7218->dev_id != DA7217_DEV_ID) &&
3291 (da7218->dev_id != DA7218_DEV_ID)) {
3292 dev_err(&i2c->dev, "Invalid device Id\n");
3293 return -EINVAL;
3294 }
3295
3296 da7218->irq = i2c->irq;
3297
3298 da7218->regmap = devm_regmap_init_i2c(i2c, &da7218_regmap_config);
3299 if (IS_ERR(da7218->regmap)) {
3300 ret = PTR_ERR(da7218->regmap);
3301 dev_err(&i2c->dev, "regmap_init() failed: %d\n", ret);
3302 return ret;
3303 }
3304
3305 ret = snd_soc_register_codec(&i2c->dev,
3306 &soc_codec_dev_da7218, &da7218_dai, 1);
3307 if (ret < 0) {
3308 dev_err(&i2c->dev, "Failed to register da7218 codec: %d\n",
3309 ret);
3310 }
3311 return ret;
3312}
3313
3314static int da7218_i2c_remove(struct i2c_client *client)
3315{
3316 snd_soc_unregister_codec(&client->dev);
3317 return 0;
3318}
3319
3320static const struct i2c_device_id da7218_i2c_id[] = {
3321 { "da7217", DA7217_DEV_ID },
3322 { "da7218", DA7218_DEV_ID },
3323 { }
3324};
3325MODULE_DEVICE_TABLE(i2c, da7218_i2c_id);
3326
3327static struct i2c_driver da7218_i2c_driver = {
3328 .driver = {
3329 .name = "da7218",
3330 .of_match_table = of_match_ptr(da7218_of_match),
3331 },
3332 .probe = da7218_i2c_probe,
3333 .remove = da7218_i2c_remove,
3334 .id_table = da7218_i2c_id,
3335};
3336
3337module_i2c_driver(da7218_i2c_driver);
3338
3339MODULE_DESCRIPTION("ASoC DA7218 Codec driver");
3340MODULE_AUTHOR("Adam Thomson <Adam.Thomson.Opensource@diasemi.com>");
3341MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/da7218.h b/sound/soc/codecs/da7218.h
new file mode 100644
index 000000000000..c2c59049a2ad
--- /dev/null
+++ b/sound/soc/codecs/da7218.h
@@ -0,0 +1,1414 @@
1/*
2 * da7218.h - DA7218 ALSA SoC Codec Driver
3 *
4 * Copyright (c) 2015 Dialog Semiconductor
5 *
6 * Author: Adam Thomson <Adam.Thomson.Opensource@diasemi.com>
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the
10 * Free Software Foundation; either version 2 of the License, or (at your
11 * option) any later version.
12 */
13
14#ifndef _DA7218_H
15#define _DA7218_H
16
17#include <linux/regmap.h>
18#include <linux/regulator/consumer.h>
19#include <sound/da7218.h>
20
21
22/*
23 * Registers
24 */
25#define DA7218_SYSTEM_ACTIVE 0x0
26#define DA7218_CIF_CTRL 0x1
27#define DA7218_CHIP_ID1 0x4
28#define DA7218_CHIP_ID2 0x5
29#define DA7218_CHIP_REVISION 0x6
30#define DA7218_SPARE1 0x7
31#define DA7218_STATUS1 0x8
32#define DA7218_SOFT_RESET 0x9
33#define DA7218_SR 0xB
34#define DA7218_PC_COUNT 0xC
35#define DA7218_GAIN_RAMP_CTRL 0xD
36#define DA7218_CIF_TIMEOUT_CTRL 0x10
37#define DA7218_SYSTEM_MODES_INPUT 0x14
38#define DA7218_SYSTEM_MODES_OUTPUT 0x15
39#define DA7218_SYSTEM_STATUS 0x16
40#define DA7218_IN_1L_FILTER_CTRL 0x18
41#define DA7218_IN_1R_FILTER_CTRL 0x19
42#define DA7218_IN_2L_FILTER_CTRL 0x1A
43#define DA7218_IN_2R_FILTER_CTRL 0x1B
44#define DA7218_OUT_1L_FILTER_CTRL 0x20
45#define DA7218_OUT_1R_FILTER_CTRL 0x21
46#define DA7218_OUT_1_HPF_FILTER_CTRL 0x24
47#define DA7218_OUT_1_EQ_12_FILTER_CTRL 0x25
48#define DA7218_OUT_1_EQ_34_FILTER_CTRL 0x26
49#define DA7218_OUT_1_EQ_5_FILTER_CTRL 0x27
50#define DA7218_OUT_1_BIQ_5STAGE_CTRL 0x28
51#define DA7218_OUT_1_BIQ_5STAGE_DATA 0x29
52#define DA7218_OUT_1_BIQ_5STAGE_ADDR 0x2A
53#define DA7218_MIXIN_1_CTRL 0x2C
54#define DA7218_MIXIN_1_GAIN 0x2D
55#define DA7218_MIXIN_2_CTRL 0x2E
56#define DA7218_MIXIN_2_GAIN 0x2F
57#define DA7218_ALC_CTRL1 0x30
58#define DA7218_ALC_CTRL2 0x31
59#define DA7218_ALC_CTRL3 0x32
60#define DA7218_ALC_NOISE 0x33
61#define DA7218_ALC_TARGET_MIN 0x34
62#define DA7218_ALC_TARGET_MAX 0x35
63#define DA7218_ALC_GAIN_LIMITS 0x36
64#define DA7218_ALC_ANA_GAIN_LIMITS 0x37
65#define DA7218_ALC_ANTICLIP_CTRL 0x38
66#define DA7218_AGS_ENABLE 0x3C
67#define DA7218_AGS_TRIGGER 0x3D
68#define DA7218_AGS_ATT_MAX 0x3E
69#define DA7218_AGS_TIMEOUT 0x3F
70#define DA7218_AGS_ANTICLIP_CTRL 0x40
71#define DA7218_CALIB_CTRL 0x44
72#define DA7218_CALIB_OFFSET_AUTO_M_1 0x45
73#define DA7218_CALIB_OFFSET_AUTO_U_1 0x46
74#define DA7218_CALIB_OFFSET_AUTO_M_2 0x47
75#define DA7218_CALIB_OFFSET_AUTO_U_2 0x48
76#define DA7218_ENV_TRACK_CTRL 0x4C
77#define DA7218_LVL_DET_CTRL 0x50
78#define DA7218_LVL_DET_LEVEL 0x51
79#define DA7218_DGS_TRIGGER 0x54
80#define DA7218_DGS_ENABLE 0x55
81#define DA7218_DGS_RISE_FALL 0x56
82#define DA7218_DGS_SYNC_DELAY 0x57
83#define DA7218_DGS_SYNC_DELAY2 0x58
84#define DA7218_DGS_SYNC_DELAY3 0x59
85#define DA7218_DGS_LEVELS 0x5A
86#define DA7218_DGS_GAIN_CTRL 0x5B
87#define DA7218_DROUTING_OUTDAI_1L 0x5C
88#define DA7218_DMIX_OUTDAI_1L_INFILT_1L_GAIN 0x5D
89#define DA7218_DMIX_OUTDAI_1L_INFILT_1R_GAIN 0x5E
90#define DA7218_DMIX_OUTDAI_1L_INFILT_2L_GAIN 0x5F
91#define DA7218_DMIX_OUTDAI_1L_INFILT_2R_GAIN 0x60
92#define DA7218_DMIX_OUTDAI_1L_TONEGEN_GAIN 0x61
93#define DA7218_DMIX_OUTDAI_1L_INDAI_1L_GAIN 0x62
94#define DA7218_DMIX_OUTDAI_1L_INDAI_1R_GAIN 0x63
95#define DA7218_DROUTING_OUTDAI_1R 0x64
96#define DA7218_DMIX_OUTDAI_1R_INFILT_1L_GAIN 0x65
97#define DA7218_DMIX_OUTDAI_1R_INFILT_1R_GAIN 0x66
98#define DA7218_DMIX_OUTDAI_1R_INFILT_2L_GAIN 0x67
99#define DA7218_DMIX_OUTDAI_1R_INFILT_2R_GAIN 0x68
100#define DA7218_DMIX_OUTDAI_1R_TONEGEN_GAIN 0x69
101#define DA7218_DMIX_OUTDAI_1R_INDAI_1L_GAIN 0x6A
102#define DA7218_DMIX_OUTDAI_1R_INDAI_1R_GAIN 0x6B
103#define DA7218_DROUTING_OUTFILT_1L 0x6C
104#define DA7218_DMIX_OUTFILT_1L_INFILT_1L_GAIN 0x6D
105#define DA7218_DMIX_OUTFILT_1L_INFILT_1R_GAIN 0x6E
106#define DA7218_DMIX_OUTFILT_1L_INFILT_2L_GAIN 0x6F
107#define DA7218_DMIX_OUTFILT_1L_INFILT_2R_GAIN 0x70
108#define DA7218_DMIX_OUTFILT_1L_TONEGEN_GAIN 0x71
109#define DA7218_DMIX_OUTFILT_1L_INDAI_1L_GAIN 0x72
110#define DA7218_DMIX_OUTFILT_1L_INDAI_1R_GAIN 0x73
111#define DA7218_DROUTING_OUTFILT_1R 0x74
112#define DA7218_DMIX_OUTFILT_1R_INFILT_1L_GAIN 0x75
113#define DA7218_DMIX_OUTFILT_1R_INFILT_1R_GAIN 0x76
114#define DA7218_DMIX_OUTFILT_1R_INFILT_2L_GAIN 0x77
115#define DA7218_DMIX_OUTFILT_1R_INFILT_2R_GAIN 0x78
116#define DA7218_DMIX_OUTFILT_1R_TONEGEN_GAIN 0x79
117#define DA7218_DMIX_OUTFILT_1R_INDAI_1L_GAIN 0x7A
118#define DA7218_DMIX_OUTFILT_1R_INDAI_1R_GAIN 0x7B
119#define DA7218_DROUTING_OUTDAI_2L 0x7C
120#define DA7218_DMIX_OUTDAI_2L_INFILT_1L_GAIN 0x7D
121#define DA7218_DMIX_OUTDAI_2L_INFILT_1R_GAIN 0x7E
122#define DA7218_DMIX_OUTDAI_2L_INFILT_2L_GAIN 0x7F
123#define DA7218_DMIX_OUTDAI_2L_INFILT_2R_GAIN 0x80
124#define DA7218_DMIX_OUTDAI_2L_TONEGEN_GAIN 0x81
125#define DA7218_DMIX_OUTDAI_2L_INDAI_1L_GAIN 0x82
126#define DA7218_DMIX_OUTDAI_2L_INDAI_1R_GAIN 0x83
127#define DA7218_DROUTING_OUTDAI_2R 0x84
128#define DA7218_DMIX_OUTDAI_2R_INFILT_1L_GAIN 0x85
129#define DA7218_DMIX_OUTDAI_2R_INFILT_1R_GAIN 0x86
130#define DA7218_DMIX_OUTDAI_2R_INFILT_2L_GAIN 0x87
131#define DA7218_DMIX_OUTDAI_2R_INFILT_2R_GAIN 0x88
132#define DA7218_DMIX_OUTDAI_2R_TONEGEN_GAIN 0x89
133#define DA7218_DMIX_OUTDAI_2R_INDAI_1L_GAIN 0x8A
134#define DA7218_DMIX_OUTDAI_2R_INDAI_1R_GAIN 0x8B
135#define DA7218_DAI_CTRL 0x8C
136#define DA7218_DAI_TDM_CTRL 0x8D
137#define DA7218_DAI_OFFSET_LOWER 0x8E
138#define DA7218_DAI_OFFSET_UPPER 0x8F
139#define DA7218_DAI_CLK_MODE 0x90
140#define DA7218_PLL_CTRL 0x91
141#define DA7218_PLL_FRAC_TOP 0x92
142#define DA7218_PLL_FRAC_BOT 0x93
143#define DA7218_PLL_INTEGER 0x94
144#define DA7218_PLL_STATUS 0x95
145#define DA7218_PLL_REFOSC_CAL 0x98
146#define DA7218_DAC_NG_CTRL 0x9C
147#define DA7218_DAC_NG_SETUP_TIME 0x9D
148#define DA7218_DAC_NG_OFF_THRESH 0x9E
149#define DA7218_DAC_NG_ON_THRESH 0x9F
150#define DA7218_TONE_GEN_CFG1 0xA0
151#define DA7218_TONE_GEN_CFG2 0xA1
152#define DA7218_TONE_GEN_FREQ1_L 0xA2
153#define DA7218_TONE_GEN_FREQ1_U 0xA3
154#define DA7218_TONE_GEN_FREQ2_L 0xA4
155#define DA7218_TONE_GEN_FREQ2_U 0xA5
156#define DA7218_TONE_GEN_CYCLES 0xA6
157#define DA7218_TONE_GEN_ON_PER 0xA7
158#define DA7218_TONE_GEN_OFF_PER 0xA8
159#define DA7218_CP_CTRL 0xAC
160#define DA7218_CP_DELAY 0xAD
161#define DA7218_CP_VOL_THRESHOLD1 0xAE
162#define DA7218_MIC_1_CTRL 0xB4
163#define DA7218_MIC_1_GAIN 0xB5
164#define DA7218_MIC_1_SELECT 0xB7
165#define DA7218_MIC_2_CTRL 0xB8
166#define DA7218_MIC_2_GAIN 0xB9
167#define DA7218_MIC_2_SELECT 0xBB
168#define DA7218_IN_1_HPF_FILTER_CTRL 0xBC
169#define DA7218_IN_2_HPF_FILTER_CTRL 0xBD
170#define DA7218_ADC_1_CTRL 0xC0
171#define DA7218_ADC_2_CTRL 0xC1
172#define DA7218_ADC_MODE 0xC2
173#define DA7218_MIXOUT_L_CTRL 0xCC
174#define DA7218_MIXOUT_L_GAIN 0xCD
175#define DA7218_MIXOUT_R_CTRL 0xCE
176#define DA7218_MIXOUT_R_GAIN 0xCF
177#define DA7218_HP_L_CTRL 0xD0
178#define DA7218_HP_L_GAIN 0xD1
179#define DA7218_HP_R_CTRL 0xD2
180#define DA7218_HP_R_GAIN 0xD3
181#define DA7218_HP_SNGL_CTRL 0xD4
182#define DA7218_HP_DIFF_CTRL 0xD5
183#define DA7218_HP_DIFF_UNLOCK 0xD7
184#define DA7218_HPLDET_JACK 0xD8
185#define DA7218_HPLDET_CTRL 0xD9
186#define DA7218_HPLDET_TEST 0xDA
187#define DA7218_REFERENCES 0xDC
188#define DA7218_IO_CTRL 0xE0
189#define DA7218_LDO_CTRL 0xE1
190#define DA7218_SIDETONE_CTRL 0xE4
191#define DA7218_SIDETONE_IN_SELECT 0xE5
192#define DA7218_SIDETONE_GAIN 0xE6
193#define DA7218_DROUTING_ST_OUTFILT_1L 0xE8
194#define DA7218_DROUTING_ST_OUTFILT_1R 0xE9
195#define DA7218_SIDETONE_BIQ_3STAGE_DATA 0xEA
196#define DA7218_SIDETONE_BIQ_3STAGE_ADDR 0xEB
197#define DA7218_EVENT_STATUS 0xEC
198#define DA7218_EVENT 0xED
199#define DA7218_EVENT_MASK 0xEE
200#define DA7218_DMIC_1_CTRL 0xF0
201#define DA7218_DMIC_2_CTRL 0xF1
202#define DA7218_IN_1L_GAIN 0xF4
203#define DA7218_IN_1R_GAIN 0xF5
204#define DA7218_IN_2L_GAIN 0xF6
205#define DA7218_IN_2R_GAIN 0xF7
206#define DA7218_OUT_1L_GAIN 0xF8
207#define DA7218_OUT_1R_GAIN 0xF9
208#define DA7218_MICBIAS_CTRL 0xFC
209#define DA7218_MICBIAS_EN 0xFD
210
211
212/*
213 * Bit Fields
214 */
215
216#define DA7218_SWITCH_EN_MAX 0x1
217
218/* DA7218_SYSTEM_ACTIVE = 0x0 */
219#define DA7218_SYSTEM_ACTIVE_SHIFT 0
220#define DA7218_SYSTEM_ACTIVE_MASK (0x1 << 0)
221
222/* DA7218_CIF_CTRL = 0x1 */
223#define DA7218_CIF_I2C_WRITE_MODE_SHIFT 0
224#define DA7218_CIF_I2C_WRITE_MODE_MASK (0x1 << 0)
225
226/* DA7218_CHIP_ID1 = 0x4 */
227#define DA7218_CHIP_ID1_SHIFT 0
228#define DA7218_CHIP_ID1_MASK (0xFF << 0)
229
230/* DA7218_CHIP_ID2 = 0x5 */
231#define DA7218_CHIP_ID2_SHIFT 0
232#define DA7218_CHIP_ID2_MASK (0xFF << 0)
233
234/* DA7218_CHIP_REVISION = 0x6 */
235#define DA7218_CHIP_MINOR_SHIFT 0
236#define DA7218_CHIP_MINOR_MASK (0xF << 0)
237#define DA7218_CHIP_MAJOR_SHIFT 4
238#define DA7218_CHIP_MAJOR_MASK (0xF << 4)
239
240/* DA7218_SPARE1 = 0x7 */
241#define DA7218_SPARE1_SHIFT 0
242#define DA7218_SPARE1_MASK (0xFF << 0)
243
244/* DA7218_STATUS1 = 0x8 */
245#define DA7218_STATUS_SPARE1_SHIFT 0
246#define DA7218_STATUS_SPARE1_MASK (0xFF << 0)
247
248/* DA7218_SOFT_RESET = 0x9 */
249#define DA7218_CIF_REG_SOFT_RESET_SHIFT 7
250#define DA7218_CIF_REG_SOFT_RESET_MASK (0x1 << 7)
251
252/* DA7218_SR = 0xB */
253#define DA7218_SR_ADC_SHIFT 0
254#define DA7218_SR_ADC_MASK (0xF << 0)
255#define DA7218_SR_DAC_SHIFT 4
256#define DA7218_SR_DAC_MASK (0xF << 4)
257#define DA7218_SR_8000 0x01
258#define DA7218_SR_11025 0x02
259#define DA7218_SR_12000 0x03
260#define DA7218_SR_16000 0x05
261#define DA7218_SR_22050 0x06
262#define DA7218_SR_24000 0x07
263#define DA7218_SR_32000 0x09
264#define DA7218_SR_44100 0x0A
265#define DA7218_SR_48000 0x0B
266#define DA7218_SR_88200 0x0E
267#define DA7218_SR_96000 0x0F
268
269/* DA7218_PC_COUNT = 0xC */
270#define DA7218_PC_FREERUN_SHIFT 0
271#define DA7218_PC_FREERUN_MASK (0x1 << 0)
272#define DA7218_PC_RESYNC_AUTO_SHIFT 1
273#define DA7218_PC_RESYNC_AUTO_MASK (0x1 << 1)
274
275/* DA7218_GAIN_RAMP_CTRL = 0xD */
276#define DA7218_GAIN_RAMP_RATE_SHIFT 0
277#define DA7218_GAIN_RAMP_RATE_MASK (0x3 << 0)
278#define DA7218_GAIN_RAMP_RATE_MAX 4
279
280/* DA7218_CIF_TIMEOUT_CTRL = 0x10 */
281#define DA7218_I2C_TIMEOUT_EN_SHIFT 0
282#define DA7218_I2C_TIMEOUT_EN_MASK (0x1 << 0)
283
284/* DA7218_SYSTEM_MODES_INPUT = 0x14 */
285#define DA7218_MODE_SUBMIT_SHIFT 0
286#define DA7218_MODE_SUBMIT_MASK (0x1 << 0)
287#define DA7218_ADC_MODE_SHIFT 1
288#define DA7218_ADC_MODE_MASK (0x7F << 1)
289
290/* DA7218_SYSTEM_MODES_OUTPUT = 0x15 */
291#define DA7218_MODE_SUBMIT_SHIFT 0
292#define DA7218_MODE_SUBMIT_MASK (0x1 << 0)
293#define DA7218_DAC_MODE_SHIFT 1
294#define DA7218_DAC_MODE_MASK (0x7F << 1)
295
296/* DA7218_SYSTEM_STATUS = 0x16 */
297#define DA7218_SC1_BUSY_SHIFT 0
298#define DA7218_SC1_BUSY_MASK (0x1 << 0)
299#define DA7218_SC2_BUSY_SHIFT 1
300#define DA7218_SC2_BUSY_MASK (0x1 << 1)
301
302/* DA7218_IN_1L_FILTER_CTRL = 0x18 */
303#define DA7218_IN_1L_RAMP_EN_SHIFT 5
304#define DA7218_IN_1L_RAMP_EN_MASK (0x1 << 5)
305#define DA7218_IN_1L_MUTE_EN_SHIFT 6
306#define DA7218_IN_1L_MUTE_EN_MASK (0x1 << 6)
307#define DA7218_IN_1L_FILTER_EN_SHIFT 7
308#define DA7218_IN_1L_FILTER_EN_MASK (0x1 << 7)
309
310/* DA7218_IN_1R_FILTER_CTRL = 0x19 */
311#define DA7218_IN_1R_RAMP_EN_SHIFT 5
312#define DA7218_IN_1R_RAMP_EN_MASK (0x1 << 5)
313#define DA7218_IN_1R_MUTE_EN_SHIFT 6
314#define DA7218_IN_1R_MUTE_EN_MASK (0x1 << 6)
315#define DA7218_IN_1R_FILTER_EN_SHIFT 7
316#define DA7218_IN_1R_FILTER_EN_MASK (0x1 << 7)
317
318/* DA7218_IN_2L_FILTER_CTRL = 0x1A */
319#define DA7218_IN_2L_RAMP_EN_SHIFT 5
320#define DA7218_IN_2L_RAMP_EN_MASK (0x1 << 5)
321#define DA7218_IN_2L_MUTE_EN_SHIFT 6
322#define DA7218_IN_2L_MUTE_EN_MASK (0x1 << 6)
323#define DA7218_IN_2L_FILTER_EN_SHIFT 7
324#define DA7218_IN_2L_FILTER_EN_MASK (0x1 << 7)
325
326/* DA7218_IN_2R_FILTER_CTRL = 0x1B */
327#define DA7218_IN_2R_RAMP_EN_SHIFT 5
328#define DA7218_IN_2R_RAMP_EN_MASK (0x1 << 5)
329#define DA7218_IN_2R_MUTE_EN_SHIFT 6
330#define DA7218_IN_2R_MUTE_EN_MASK (0x1 << 6)
331#define DA7218_IN_2R_FILTER_EN_SHIFT 7
332#define DA7218_IN_2R_FILTER_EN_MASK (0x1 << 7)
333
334/* DA7218_OUT_1L_FILTER_CTRL = 0x20 */
335#define DA7218_OUT_1L_BIQ_5STAGE_SEL_SHIFT 3
336#define DA7218_OUT_1L_BIQ_5STAGE_SEL_MASK (0x1 << 3)
337#define DA7218_OUT_BIQ_5STAGE_SEL_MAX 2
338#define DA7218_OUT_1L_SUBRANGE_EN_SHIFT 4
339#define DA7218_OUT_1L_SUBRANGE_EN_MASK (0x1 << 4)
340#define DA7218_OUT_1L_RAMP_EN_SHIFT 5
341#define DA7218_OUT_1L_RAMP_EN_MASK (0x1 << 5)
342#define DA7218_OUT_1L_MUTE_EN_SHIFT 6
343#define DA7218_OUT_1L_MUTE_EN_MASK (0x1 << 6)
344#define DA7218_OUT_1L_FILTER_EN_SHIFT 7
345#define DA7218_OUT_1L_FILTER_EN_MASK (0x1 << 7)
346
347/* DA7218_OUT_1R_FILTER_CTRL = 0x21 */
348#define DA7218_OUT_1R_BIQ_5STAGE_SEL_SHIFT 3
349#define DA7218_OUT_1R_BIQ_5STAGE_SEL_MASK (0x1 << 3)
350#define DA7218_OUT_1R_SUBRANGE_EN_SHIFT 4
351#define DA7218_OUT_1R_SUBRANGE_EN_MASK (0x1 << 4)
352#define DA7218_OUT_1R_RAMP_EN_SHIFT 5
353#define DA7218_OUT_1R_RAMP_EN_MASK (0x1 << 5)
354#define DA7218_OUT_1R_MUTE_EN_SHIFT 6
355#define DA7218_OUT_1R_MUTE_EN_MASK (0x1 << 6)
356#define DA7218_OUT_1R_FILTER_EN_SHIFT 7
357#define DA7218_OUT_1R_FILTER_EN_MASK (0x1 << 7)
358
359/* DA7218_OUT_1_HPF_FILTER_CTRL = 0x24 */
360#define DA7218_OUT_1_VOICE_HPF_CORNER_SHIFT 0
361#define DA7218_OUT_1_VOICE_HPF_CORNER_MASK (0x7 << 0)
362#define DA7218_VOICE_HPF_CORNER_MAX 8
363#define DA7218_OUT_1_VOICE_EN_SHIFT 3
364#define DA7218_OUT_1_VOICE_EN_MASK (0x1 << 3)
365#define DA7218_OUT_1_AUDIO_HPF_CORNER_SHIFT 4
366#define DA7218_OUT_1_AUDIO_HPF_CORNER_MASK (0x3 << 4)
367#define DA7218_AUDIO_HPF_CORNER_MAX 4
368#define DA7218_OUT_1_HPF_EN_SHIFT 7
369#define DA7218_OUT_1_HPF_EN_MASK (0x1 << 7)
370#define DA7218_HPF_MODE_SHIFT 0
371#define DA7218_HPF_DISABLED ((0x0 << 3) | (0x0 << 7))
372#define DA7218_HPF_AUDIO_EN ((0x0 << 3) | (0x1 << 7))
373#define DA7218_HPF_VOICE_EN ((0x1 << 3) | (0x1 << 7))
374#define DA7218_HPF_MODE_MASK ((0x1 << 3) | (0x1 << 7))
375#define DA7218_HPF_MODE_MAX 3
376
377/* DA7218_OUT_1_EQ_12_FILTER_CTRL = 0x25 */
378#define DA7218_OUT_1_EQ_BAND1_SHIFT 0
379#define DA7218_OUT_1_EQ_BAND1_MASK (0xF << 0)
380#define DA7218_OUT_EQ_BAND_MAX 0xF
381#define DA7218_OUT_1_EQ_BAND2_SHIFT 4
382#define DA7218_OUT_1_EQ_BAND2_MASK (0xF << 4)
383
384/* DA7218_OUT_1_EQ_34_FILTER_CTRL = 0x26 */
385#define DA7218_OUT_1_EQ_BAND3_SHIFT 0
386#define DA7218_OUT_1_EQ_BAND3_MASK (0xF << 0)
387#define DA7218_OUT_1_EQ_BAND4_SHIFT 4
388#define DA7218_OUT_1_EQ_BAND4_MASK (0xF << 4)
389
390/* DA7218_OUT_1_EQ_5_FILTER_CTRL = 0x27 */
391#define DA7218_OUT_1_EQ_BAND5_SHIFT 0
392#define DA7218_OUT_1_EQ_BAND5_MASK (0xF << 0)
393#define DA7218_OUT_1_EQ_EN_SHIFT 7
394#define DA7218_OUT_1_EQ_EN_MASK (0x1 << 7)
395
396/* DA7218_OUT_1_BIQ_5STAGE_CTRL = 0x28 */
397#define DA7218_OUT_1_BIQ_5STAGE_MUTE_EN_SHIFT 6
398#define DA7218_OUT_1_BIQ_5STAGE_MUTE_EN_MASK (0x1 << 6)
399#define DA7218_OUT_1_BIQ_5STAGE_FILTER_EN_SHIFT 7
400#define DA7218_OUT_1_BIQ_5STAGE_FILTER_EN_MASK (0x1 << 7)
401
402/* DA7218_OUT_1_BIQ_5STAGE_DATA = 0x29 */
403#define DA7218_OUT_1_BIQ_5STAGE_DATA_SHIFT 0
404#define DA7218_OUT_1_BIQ_5STAGE_DATA_MASK (0xFF << 0)
405
406/* DA7218_OUT_1_BIQ_5STAGE_ADDR = 0x2A */
407#define DA7218_OUT_1_BIQ_5STAGE_ADDR_SHIFT 0
408#define DA7218_OUT_1_BIQ_5STAGE_ADDR_MASK (0x3F << 0)
409#define DA7218_OUT_1_BIQ_5STAGE_CFG_SIZE 50
410
411/* DA7218_MIXIN_1_CTRL = 0x2C */
412#define DA7218_MIXIN_1_MIX_SEL_SHIFT 3
413#define DA7218_MIXIN_1_MIX_SEL_MASK (0x1 << 3)
414#define DA7218_MIXIN_1_AMP_ZC_EN_SHIFT 4
415#define DA7218_MIXIN_1_AMP_ZC_EN_MASK (0x1 << 4)
416#define DA7218_MIXIN_1_AMP_RAMP_EN_SHIFT 5
417#define DA7218_MIXIN_1_AMP_RAMP_EN_MASK (0x1 << 5)
418#define DA7218_MIXIN_1_AMP_MUTE_EN_SHIFT 6
419#define DA7218_MIXIN_1_AMP_MUTE_EN_MASK (0x1 << 6)
420#define DA7218_MIXIN_1_AMP_EN_SHIFT 7
421#define DA7218_MIXIN_1_AMP_EN_MASK (0x1 << 7)
422
423/* DA7218_MIXIN_1_GAIN = 0x2D */
424#define DA7218_MIXIN_1_AMP_GAIN_SHIFT 0
425#define DA7218_MIXIN_1_AMP_GAIN_MASK (0xF << 0)
426#define DA7218_MIXIN_AMP_GAIN_MAX 0xF
427
428/* DA7218_MIXIN_2_CTRL = 0x2E */
429#define DA7218_MIXIN_2_MIX_SEL_SHIFT 3
430#define DA7218_MIXIN_2_MIX_SEL_MASK (0x1 << 3)
431#define DA7218_MIXIN_2_AMP_ZC_EN_SHIFT 4
432#define DA7218_MIXIN_2_AMP_ZC_EN_MASK (0x1 << 4)
433#define DA7218_MIXIN_2_AMP_RAMP_EN_SHIFT 5
434#define DA7218_MIXIN_2_AMP_RAMP_EN_MASK (0x1 << 5)
435#define DA7218_MIXIN_2_AMP_MUTE_EN_SHIFT 6
436#define DA7218_MIXIN_2_AMP_MUTE_EN_MASK (0x1 << 6)
437#define DA7218_MIXIN_2_AMP_EN_SHIFT 7
438#define DA7218_MIXIN_2_AMP_EN_MASK (0x1 << 7)
439
440/* DA7218_MIXIN_2_GAIN = 0x2F */
441#define DA7218_MIXIN_2_AMP_GAIN_SHIFT 0
442#define DA7218_MIXIN_2_AMP_GAIN_MASK (0xF << 0)
443
444/* DA7218_ALC_CTRL1 = 0x30 */
445#define DA7218_ALC_EN_SHIFT 0
446#define DA7218_ALC_EN_MASK (0xF << 0)
447#define DA7218_ALC_CHAN1_L_EN_SHIFT 0
448#define DA7218_ALC_CHAN1_R_EN_SHIFT 1
449#define DA7218_ALC_CHAN2_L_EN_SHIFT 2
450#define DA7218_ALC_CHAN2_R_EN_SHIFT 3
451#define DA7218_ALC_SYNC_MODE_SHIFT 4
452#define DA7218_ALC_SYNC_MODE_MASK (0xF << 4)
453#define DA7218_ALC_SYNC_MODE_CH1 (0x1 << 4)
454#define DA7218_ALC_SYNC_MODE_CH2 (0x4 << 4)
455
456/* DA7218_ALC_CTRL2 = 0x31 */
457#define DA7218_ALC_ATTACK_SHIFT 0
458#define DA7218_ALC_ATTACK_MASK (0xF << 0)
459#define DA7218_ALC_ATTACK_MAX 13
460#define DA7218_ALC_RELEASE_SHIFT 4
461#define DA7218_ALC_RELEASE_MASK (0xF << 4)
462#define DA7218_ALC_RELEASE_MAX 11
463
464/* DA7218_ALC_CTRL3 = 0x32 */
465#define DA7218_ALC_HOLD_SHIFT 0
466#define DA7218_ALC_HOLD_MASK (0xF << 0)
467#define DA7218_ALC_HOLD_MAX 16
468
469/* DA7218_ALC_NOISE = 0x33 */
470#define DA7218_ALC_NOISE_SHIFT 0
471#define DA7218_ALC_NOISE_MASK (0x3F << 0)
472#define DA7218_ALC_THRESHOLD_MAX 0x3F
473
474/* DA7218_ALC_TARGET_MIN = 0x34 */
475#define DA7218_ALC_THRESHOLD_MIN_SHIFT 0
476#define DA7218_ALC_THRESHOLD_MIN_MASK (0x3F << 0)
477
478/* DA7218_ALC_TARGET_MAX = 0x35 */
479#define DA7218_ALC_THRESHOLD_MAX_SHIFT 0
480#define DA7218_ALC_THRESHOLD_MAX_MASK (0x3F << 0)
481
482/* DA7218_ALC_GAIN_LIMITS = 0x36 */
483#define DA7218_ALC_ATTEN_MAX_SHIFT 0
484#define DA7218_ALC_ATTEN_MAX_MASK (0xF << 0)
485#define DA7218_ALC_ATTEN_GAIN_MAX 0xF
486#define DA7218_ALC_GAIN_MAX_SHIFT 4
487#define DA7218_ALC_GAIN_MAX_MASK (0xF << 4)
488
489/* DA7218_ALC_ANA_GAIN_LIMITS = 0x37 */
490#define DA7218_ALC_ANA_GAIN_MIN_SHIFT 0
491#define DA7218_ALC_ANA_GAIN_MIN_MASK (0x7 << 0)
492#define DA7218_ALC_ANA_GAIN_MIN 0x1
493#define DA7218_ALC_ANA_GAIN_MAX 0x7
494#define DA7218_ALC_ANA_GAIN_MAX_SHIFT 4
495#define DA7218_ALC_ANA_GAIN_MAX_MASK (0x7 << 4)
496
497/* DA7218_ALC_ANTICLIP_CTRL = 0x38 */
498#define DA7218_ALC_ANTICLIP_STEP_SHIFT 0
499#define DA7218_ALC_ANTICLIP_STEP_MASK (0x3 << 0)
500#define DA7218_ALC_ANTICLIP_STEP_MAX 4
501#define DA7218_ALC_ANTICLIP_EN_SHIFT 7
502#define DA7218_ALC_ANTICLIP_EN_MASK (0x1 << 7)
503
504/* DA7218_AGS_ENABLE = 0x3C */
505#define DA7218_AGS_ENABLE_SHIFT 0
506#define DA7218_AGS_ENABLE_MASK (0x3 << 0)
507#define DA7218_AGS_ENABLE_CHAN1_SHIFT 0
508#define DA7218_AGS_ENABLE_CHAN2_SHIFT 1
509
510/* DA7218_AGS_TRIGGER = 0x3D */
511#define DA7218_AGS_TRIGGER_SHIFT 0
512#define DA7218_AGS_TRIGGER_MASK (0xF << 0)
513#define DA7218_AGS_TRIGGER_MAX 0xF
514
515/* DA7218_AGS_ATT_MAX = 0x3E */
516#define DA7218_AGS_ATT_MAX_SHIFT 0
517#define DA7218_AGS_ATT_MAX_MASK (0x7 << 0)
518#define DA7218_AGS_ATT_MAX_MAX 0x7
519
520/* DA7218_AGS_TIMEOUT = 0x3F */
521#define DA7218_AGS_TIMEOUT_EN_SHIFT 0
522#define DA7218_AGS_TIMEOUT_EN_MASK (0x1 << 0)
523
524/* DA7218_AGS_ANTICLIP_CTRL = 0x40 */
525#define DA7218_AGS_ANTICLIP_EN_SHIFT 7
526#define DA7218_AGS_ANTICLIP_EN_MASK (0x1 << 7)
527
528/* DA7218_CALIB_CTRL = 0x44 */
529#define DA7218_CALIB_OFFSET_EN_SHIFT 0
530#define DA7218_CALIB_OFFSET_EN_MASK (0x1 << 0)
531#define DA7218_CALIB_AUTO_EN_SHIFT 2
532#define DA7218_CALIB_AUTO_EN_MASK (0x1 << 2)
533#define DA7218_CALIB_OVERFLOW_SHIFT 3
534#define DA7218_CALIB_OVERFLOW_MASK (0x1 << 3)
535
536/* DA7218_CALIB_OFFSET_AUTO_M_1 = 0x45 */
537#define DA7218_CALIB_OFFSET_AUTO_M_1_SHIFT 0
538#define DA7218_CALIB_OFFSET_AUTO_M_1_MASK (0xFF << 0)
539
540/* DA7218_CALIB_OFFSET_AUTO_U_1 = 0x46 */
541#define DA7218_CALIB_OFFSET_AUTO_U_1_SHIFT 0
542#define DA7218_CALIB_OFFSET_AUTO_U_1_MASK (0xF << 0)
543
544/* DA7218_CALIB_OFFSET_AUTO_M_2 = 0x47 */
545#define DA7218_CALIB_OFFSET_AUTO_M_2_SHIFT 0
546#define DA7218_CALIB_OFFSET_AUTO_M_2_MASK (0xFF << 0)
547
548/* DA7218_CALIB_OFFSET_AUTO_U_2 = 0x48 */
549#define DA7218_CALIB_OFFSET_AUTO_U_2_SHIFT 0
550#define DA7218_CALIB_OFFSET_AUTO_U_2_MASK (0xF << 0)
551
552/* DA7218_ENV_TRACK_CTRL = 0x4C */
553#define DA7218_INTEG_ATTACK_SHIFT 0
554#define DA7218_INTEG_ATTACK_MASK (0x3 << 0)
555#define DA7218_INTEG_RELEASE_SHIFT 4
556#define DA7218_INTEG_RELEASE_MASK (0x3 << 4)
557#define DA7218_INTEG_MAX 4
558
559/* DA7218_LVL_DET_CTRL = 0x50 */
560#define DA7218_LVL_DET_EN_SHIFT 0
561#define DA7218_LVL_DET_EN_MASK (0xF << 0)
562#define DA7218_LVL_DET_EN_CHAN1L_SHIFT 0
563#define DA7218_LVL_DET_EN_CHAN1R_SHIFT 1
564#define DA7218_LVL_DET_EN_CHAN2L_SHIFT 2
565#define DA7218_LVL_DET_EN_CHAN2R_SHIFT 3
566
567/* DA7218_LVL_DET_LEVEL = 0x51 */
568#define DA7218_LVL_DET_LEVEL_SHIFT 0
569#define DA7218_LVL_DET_LEVEL_MASK (0x7F << 0)
570#define DA7218_LVL_DET_LEVEL_MAX 0x7F
571
572/* DA7218_DGS_TRIGGER = 0x54 */
573#define DA7218_DGS_TRIGGER_LVL_SHIFT 0
574#define DA7218_DGS_TRIGGER_LVL_MASK (0x3F << 0)
575#define DA7218_DGS_TRIGGER_MAX 0x3F
576
577/* DA7218_DGS_ENABLE = 0x55 */
578#define DA7218_DGS_ENABLE_SHIFT 0
579#define DA7218_DGS_ENABLE_MASK (0x3 << 0)
580#define DA7218_DGS_ENABLE_L_SHIFT 0
581#define DA7218_DGS_ENABLE_R_SHIFT 1
582
583/* DA7218_DGS_RISE_FALL = 0x56 */
584#define DA7218_DGS_RISE_COEFF_SHIFT 0
585#define DA7218_DGS_RISE_COEFF_MASK (0x7 << 0)
586#define DA7218_DGS_RISE_COEFF_MAX 7
587#define DA7218_DGS_FALL_COEFF_SHIFT 4
588#define DA7218_DGS_FALL_COEFF_MASK (0x7 << 4)
589#define DA7218_DGS_FALL_COEFF_MAX 8
590
591/* DA7218_DGS_SYNC_DELAY = 0x57 */
592#define DA7218_DGS_SYNC_DELAY_SHIFT 0
593#define DA7218_DGS_SYNC_DELAY_MASK (0xFF << 0)
594#define DA7218_DGS_SYNC_DELAY_MAX 0xFF
595
596/* DA7218_DGS_SYNC_DELAY2 = 0x58 */
597#define DA7218_DGS_SYNC_DELAY2_SHIFT 0
598#define DA7218_DGS_SYNC_DELAY2_MASK (0xFF << 0)
599
600/* DA7218_DGS_SYNC_DELAY3 = 0x59 */
601#define DA7218_DGS_SYNC_DELAY3_SHIFT 0
602#define DA7218_DGS_SYNC_DELAY3_MASK (0x7F << 0)
603#define DA7218_DGS_SYNC_DELAY3_MAX 0x7F
604
605/* DA7218_DGS_LEVELS = 0x5A */
606#define DA7218_DGS_ANTICLIP_LVL_SHIFT 0
607#define DA7218_DGS_ANTICLIP_LVL_MASK (0x7 << 0)
608#define DA7218_DGS_ANTICLIP_LVL_MAX 0x7
609#define DA7218_DGS_SIGNAL_LVL_SHIFT 4
610#define DA7218_DGS_SIGNAL_LVL_MASK (0xF << 4)
611#define DA7218_DGS_SIGNAL_LVL_MAX 0xF
612
613/* DA7218_DGS_GAIN_CTRL = 0x5B */
614#define DA7218_DGS_STEPS_SHIFT 0
615#define DA7218_DGS_STEPS_MASK (0x1F << 0)
616#define DA7218_DGS_STEPS_MAX 0x1F
617#define DA7218_DGS_RAMP_EN_SHIFT 5
618#define DA7218_DGS_RAMP_EN_MASK (0x1 << 5)
619#define DA7218_DGS_SUBR_EN_SHIFT 6
620#define DA7218_DGS_SUBR_EN_MASK (0x1 << 6)
621
622/* DA7218_DROUTING_OUTDAI_1L = 0x5C */
623#define DA7218_OUTDAI_1L_SRC_SHIFT 0
624#define DA7218_OUTDAI_1L_SRC_MASK (0x7F << 0)
625#define DA7218_DMIX_SRC_INFILT1L 0
626#define DA7218_DMIX_SRC_INFILT1R 1
627#define DA7218_DMIX_SRC_INFILT2L 2
628#define DA7218_DMIX_SRC_INFILT2R 3
629#define DA7218_DMIX_SRC_TONEGEN 4
630#define DA7218_DMIX_SRC_DAIL 5
631#define DA7218_DMIX_SRC_DAIR 6
632
633/* DA7218_DMIX_OUTDAI_1L_INFILT_1L_GAIN = 0x5D */
634#define DA7218_OUTDAI_1L_INFILT_1L_GAIN_SHIFT 0
635#define DA7218_OUTDAI_1L_INFILT_1L_GAIN_MASK (0x1F << 0)
636#define DA7218_DMIX_GAIN_MAX 0x1F
637
638/* DA7218_DMIX_OUTDAI_1L_INFILT_1R_GAIN = 0x5E */
639#define DA7218_OUTDAI_1L_INFILT_1R_GAIN_SHIFT 0
640#define DA7218_OUTDAI_1L_INFILT_1R_GAIN_MASK (0x1F << 0)
641
642/* DA7218_DMIX_OUTDAI_1L_INFILT_2L_GAIN = 0x5F */
643#define DA7218_OUTDAI_1L_INFILT_2L_GAIN_SHIFT 0
644#define DA7218_OUTDAI_1L_INFILT_2L_GAIN_MASK (0x1F << 0)
645
646/* DA7218_DMIX_OUTDAI_1L_INFILT_2R_GAIN = 0x60 */
647#define DA7218_OUTDAI_1L_INFILT_2R_GAIN_SHIFT 0
648#define DA7218_OUTDAI_1L_INFILT_2R_GAIN_MASK (0x1F << 0)
649
650/* DA7218_DMIX_OUTDAI_1L_TONEGEN_GAIN = 0x61 */
651#define DA7218_OUTDAI_1L_TONEGEN_GAIN_SHIFT 0
652#define DA7218_OUTDAI_1L_TONEGEN_GAIN_MASK (0x1F << 0)
653
654/* DA7218_DMIX_OUTDAI_1L_INDAI_1L_GAIN = 0x62 */
655#define DA7218_OUTDAI_1L_INDAI_1L_GAIN_SHIFT 0
656#define DA7218_OUTDAI_1L_INDAI_1L_GAIN_MASK (0x1F << 0)
657
658/* DA7218_DMIX_OUTDAI_1L_INDAI_1R_GAIN = 0x63 */
659#define DA7218_OUTDAI_1L_INDAI_1R_GAIN_SHIFT 0
660#define DA7218_OUTDAI_1L_INDAI_1R_GAIN_MASK (0x1F << 0)
661
662/* DA7218_DROUTING_OUTDAI_1R = 0x64 */
663#define DA7218_OUTDAI_1R_SRC_SHIFT 0
664#define DA7218_OUTDAI_1R_SRC_MASK (0x7F << 0)
665
666/* DA7218_DMIX_OUTDAI_1R_INFILT_1L_GAIN = 0x65 */
667#define DA7218_OUTDAI_1R_INFILT_1L_GAIN_SHIFT 0
668#define DA7218_OUTDAI_1R_INFILT_1L_GAIN_MASK (0x1F << 0)
669
670/* DA7218_DMIX_OUTDAI_1R_INFILT_1R_GAIN = 0x66 */
671#define DA7218_OUTDAI_1R_INFILT_1R_GAIN_SHIFT 0
672#define DA7218_OUTDAI_1R_INFILT_1R_GAIN_MASK (0x1F << 0)
673
674/* DA7218_DMIX_OUTDAI_1R_INFILT_2L_GAIN = 0x67 */
675#define DA7218_OUTDAI_1R_INFILT_2L_GAIN_SHIFT 0
676#define DA7218_OUTDAI_1R_INFILT_2L_GAIN_MASK (0x1F << 0)
677
678/* DA7218_DMIX_OUTDAI_1R_INFILT_2R_GAIN = 0x68 */
679#define DA7218_OUTDAI_1R_INFILT_2R_GAIN_SHIFT 0
680#define DA7218_OUTDAI_1R_INFILT_2R_GAIN_MASK (0x1F << 0)
681
682/* DA7218_DMIX_OUTDAI_1R_TONEGEN_GAIN = 0x69 */
683#define DA7218_OUTDAI_1R_TONEGEN_GAIN_SHIFT 0
684#define DA7218_OUTDAI_1R_TONEGEN_GAIN_MASK (0x1F << 0)
685
686/* DA7218_DMIX_OUTDAI_1R_INDAI_1L_GAIN = 0x6A */
687#define DA7218_OUTDAI_1R_INDAI_1L_GAIN_SHIFT 0
688#define DA7218_OUTDAI_1R_INDAI_1L_GAIN_MASK (0x1F << 0)
689
690/* DA7218_DMIX_OUTDAI_1R_INDAI_1R_GAIN = 0x6B */
691#define DA7218_OUTDAI_1R_INDAI_1R_GAIN_SHIFT 0
692#define DA7218_OUTDAI_1R_INDAI_1R_GAIN_MASK (0x1F << 0)
693
694/* DA7218_DROUTING_OUTFILT_1L = 0x6C */
695#define DA7218_OUTFILT_1L_SRC_SHIFT 0
696#define DA7218_OUTFILT_1L_SRC_MASK (0x7F << 0)
697
698/* DA7218_DMIX_OUTFILT_1L_INFILT_1L_GAIN = 0x6D */
699#define DA7218_OUTFILT_1L_INFILT_1L_GAIN_SHIFT 0
700#define DA7218_OUTFILT_1L_INFILT_1L_GAIN_MASK (0x1F << 0)
701
702/* DA7218_DMIX_OUTFILT_1L_INFILT_1R_GAIN = 0x6E */
703#define DA7218_OUTFILT_1L_INFILT_1R_GAIN_SHIFT 0
704#define DA7218_OUTFILT_1L_INFILT_1R_GAIN_MASK (0x1F << 0)
705
706/* DA7218_DMIX_OUTFILT_1L_INFILT_2L_GAIN = 0x6F */
707#define DA7218_OUTFILT_1L_INFILT_2L_GAIN_SHIFT 0
708#define DA7218_OUTFILT_1L_INFILT_2L_GAIN_MASK (0x1F << 0)
709
710/* DA7218_DMIX_OUTFILT_1L_INFILT_2R_GAIN = 0x70 */
711#define DA7218_OUTFILT_1L_INFILT_2R_GAIN_SHIFT 0
712#define DA7218_OUTFILT_1L_INFILT_2R_GAIN_MASK (0x1F << 0)
713
714/* DA7218_DMIX_OUTFILT_1L_TONEGEN_GAIN = 0x71 */
715#define DA7218_OUTFILT_1L_TONEGEN_GAIN_SHIFT 0
716#define DA7218_OUTFILT_1L_TONEGEN_GAIN_MASK (0x1F << 0)
717
718/* DA7218_DMIX_OUTFILT_1L_INDAI_1L_GAIN = 0x72 */
719#define DA7218_OUTFILT_1L_INDAI_1L_GAIN_SHIFT 0
720#define DA7218_OUTFILT_1L_INDAI_1L_GAIN_MASK (0x1F << 0)
721
722/* DA7218_DMIX_OUTFILT_1L_INDAI_1R_GAIN = 0x73 */
723#define DA7218_OUTFILT_1L_INDAI_1R_GAIN_SHIFT 0
724#define DA7218_OUTFILT_1L_INDAI_1R_GAIN_MASK (0x1F << 0)
725
726/* DA7218_DROUTING_OUTFILT_1R = 0x74 */
727#define DA7218_OUTFILT_1R_SRC_SHIFT 0
728#define DA7218_OUTFILT_1R_SRC_MASK (0x7F << 0)
729
730/* DA7218_DMIX_OUTFILT_1R_INFILT_1L_GAIN = 0x75 */
731#define DA7218_OUTFILT_1R_INFILT_1L_GAIN_SHIFT 0
732#define DA7218_OUTFILT_1R_INFILT_1L_GAIN_MASK (0x1F << 0)
733
734/* DA7218_DMIX_OUTFILT_1R_INFILT_1R_GAIN = 0x76 */
735#define DA7218_OUTFILT_1R_INFILT_1R_GAIN_SHIFT 0
736#define DA7218_OUTFILT_1R_INFILT_1R_GAIN_MASK (0x1F << 0)
737
738/* DA7218_DMIX_OUTFILT_1R_INFILT_2L_GAIN = 0x77 */
739#define DA7218_OUTFILT_1R_INFILT_2L_GAIN_SHIFT 0
740#define DA7218_OUTFILT_1R_INFILT_2L_GAIN_MASK (0x1F << 0)
741
742/* DA7218_DMIX_OUTFILT_1R_INFILT_2R_GAIN = 0x78 */
743#define DA7218_OUTFILT_1R_INFILT_2R_GAIN_SHIFT 0
744#define DA7218_OUTFILT_1R_INFILT_2R_GAIN_MASK (0x1F << 0)
745
746/* DA7218_DMIX_OUTFILT_1R_TONEGEN_GAIN = 0x79 */
747#define DA7218_OUTFILT_1R_TONEGEN_GAIN_SHIFT 0
748#define DA7218_OUTFILT_1R_TONEGEN_GAIN_MASK (0x1F << 0)
749
750/* DA7218_DMIX_OUTFILT_1R_INDAI_1L_GAIN = 0x7A */
751#define DA7218_OUTFILT_1R_INDAI_1L_GAIN_SHIFT 0
752#define DA7218_OUTFILT_1R_INDAI_1L_GAIN_MASK (0x1F << 0)
753
754/* DA7218_DMIX_OUTFILT_1R_INDAI_1R_GAIN = 0x7B */
755#define DA7218_OUTFILT_1R_INDAI_1R_GAIN_SHIFT 0
756#define DA7218_OUTFILT_1R_INDAI_1R_GAIN_MASK (0x1F << 0)
757
758/* DA7218_DROUTING_OUTDAI_2L = 0x7C */
759#define DA7218_OUTDAI_2L_SRC_SHIFT 0
760#define DA7218_OUTDAI_2L_SRC_MASK (0x7F << 0)
761
762/* DA7218_DMIX_OUTDAI_2L_INFILT_1L_GAIN = 0x7D */
763#define DA7218_OUTDAI_2L_INFILT_1L_GAIN_SHIFT 0
764#define DA7218_OUTDAI_2L_INFILT_1L_GAIN_MASK (0x1F << 0)
765
766/* DA7218_DMIX_OUTDAI_2L_INFILT_1R_GAIN = 0x7E */
767#define DA7218_OUTDAI_2L_INFILT_1R_GAIN_SHIFT 0
768#define DA7218_OUTDAI_2L_INFILT_1R_GAIN_MASK (0x1F << 0)
769
770/* DA7218_DMIX_OUTDAI_2L_INFILT_2L_GAIN = 0x7F */
771#define DA7218_OUTDAI_2L_INFILT_2L_GAIN_SHIFT 0
772#define DA7218_OUTDAI_2L_INFILT_2L_GAIN_MASK (0x1F << 0)
773
774/* DA7218_DMIX_OUTDAI_2L_INFILT_2R_GAIN = 0x80 */
775#define DA7218_OUTDAI_2L_INFILT_2R_GAIN_SHIFT 0
776#define DA7218_OUTDAI_2L_INFILT_2R_GAIN_MASK (0x1F << 0)
777
778/* DA7218_DMIX_OUTDAI_2L_TONEGEN_GAIN = 0x81 */
779#define DA7218_OUTDAI_2L_TONEGEN_GAIN_SHIFT 0
780#define DA7218_OUTDAI_2L_TONEGEN_GAIN_MASK (0x1F << 0)
781
782/* DA7218_DMIX_OUTDAI_2L_INDAI_1L_GAIN = 0x82 */
783#define DA7218_OUTDAI_2L_INDAI_1L_GAIN_SHIFT 0
784#define DA7218_OUTDAI_2L_INDAI_1L_GAIN_MASK (0x1F << 0)
785
786/* DA7218_DMIX_OUTDAI_2L_INDAI_1R_GAIN = 0x83 */
787#define DA7218_OUTDAI_2L_INDAI_1R_GAIN_SHIFT 0
788#define DA7218_OUTDAI_2L_INDAI_1R_GAIN_MASK (0x1F << 0)
789
790/* DA7218_DROUTING_OUTDAI_2R = 0x84 */
791#define DA7218_OUTDAI_2R_SRC_SHIFT 0
792#define DA7218_OUTDAI_2R_SRC_MASK (0x7F << 0)
793
794/* DA7218_DMIX_OUTDAI_2R_INFILT_1L_GAIN = 0x85 */
795#define DA7218_OUTDAI_2R_INFILT_1L_GAIN_SHIFT 0
796#define DA7218_OUTDAI_2R_INFILT_1L_GAIN_MASK (0x1F << 0)
797
798/* DA7218_DMIX_OUTDAI_2R_INFILT_1R_GAIN = 0x86 */
799#define DA7218_OUTDAI_2R_INFILT_1R_GAIN_SHIFT 0
800#define DA7218_OUTDAI_2R_INFILT_1R_GAIN_MASK (0x1F << 0)
801
802/* DA7218_DMIX_OUTDAI_2R_INFILT_2L_GAIN = 0x87 */
803#define DA7218_OUTDAI_2R_INFILT_2L_GAIN_SHIFT 0
804#define DA7218_OUTDAI_2R_INFILT_2L_GAIN_MASK (0x1F << 0)
805
806/* DA7218_DMIX_OUTDAI_2R_INFILT_2R_GAIN = 0x88 */
807#define DA7218_OUTDAI_2R_INFILT_2R_GAIN_SHIFT 0
808#define DA7218_OUTDAI_2R_INFILT_2R_GAIN_MASK (0x1F << 0)
809
810/* DA7218_DMIX_OUTDAI_2R_TONEGEN_GAIN = 0x89 */
811#define DA7218_OUTDAI_2R_TONEGEN_GAIN_SHIFT 0
812#define DA7218_OUTDAI_2R_TONEGEN_GAIN_MASK (0x1F << 0)
813
814/* DA7218_DMIX_OUTDAI_2R_INDAI_1L_GAIN = 0x8A */
815#define DA7218_OUTDAI_2R_INDAI_1L_GAIN_SHIFT 0
816#define DA7218_OUTDAI_2R_INDAI_1L_GAIN_MASK (0x1F << 0)
817
818/* DA7218_DMIX_OUTDAI_2R_INDAI_1R_GAIN = 0x8B */
819#define DA7218_OUTDAI_2R_INDAI_1R_GAIN_SHIFT 0
820#define DA7218_OUTDAI_2R_INDAI_1R_GAIN_MASK (0x1F << 0)
821
822/* DA7218_DAI_CTRL = 0x8C */
823#define DA7218_DAI_FORMAT_SHIFT 0
824#define DA7218_DAI_FORMAT_MASK (0x3 << 0)
825#define DA7218_DAI_FORMAT_I2S (0x0 << 0)
826#define DA7218_DAI_FORMAT_LEFT_J (0x1 << 0)
827#define DA7218_DAI_FORMAT_RIGHT_J (0x2 << 0)
828#define DA7218_DAI_FORMAT_DSP (0x3 << 0)
829#define DA7218_DAI_WORD_LENGTH_SHIFT 2
830#define DA7218_DAI_WORD_LENGTH_MASK (0x3 << 2)
831#define DA7218_DAI_WORD_LENGTH_S16_LE (0x0 << 2)
832#define DA7218_DAI_WORD_LENGTH_S20_LE (0x1 << 2)
833#define DA7218_DAI_WORD_LENGTH_S24_LE (0x2 << 2)
834#define DA7218_DAI_WORD_LENGTH_S32_LE (0x3 << 2)
835#define DA7218_DAI_CH_NUM_SHIFT 4
836#define DA7218_DAI_CH_NUM_MASK (0x7 << 4)
837#define DA7218_DAI_CH_NUM_MAX 4
838#define DA7218_DAI_EN_SHIFT 7
839#define DA7218_DAI_EN_MASK (0x1 << 7)
840
841/* DA7218_DAI_TDM_CTRL = 0x8D */
842#define DA7218_DAI_TDM_CH_EN_SHIFT 0
843#define DA7218_DAI_TDM_CH_EN_MASK (0xF << 0)
844#define DA7218_DAI_TDM_MAX_SLOTS 4
845#define DA7218_DAI_OE_SHIFT 6
846#define DA7218_DAI_OE_MASK (0x1 << 6)
847#define DA7218_DAI_TDM_MODE_EN_SHIFT 7
848#define DA7218_DAI_TDM_MODE_EN_MASK (0x1 << 7)
849
850/* DA7218_DAI_OFFSET_LOWER = 0x8E */
851#define DA7218_DAI_OFFSET_LOWER_SHIFT 0
852#define DA7218_DAI_OFFSET_LOWER_MASK (0xFF << 0)
853
854/* DA7218_DAI_OFFSET_UPPER = 0x8F */
855#define DA7218_DAI_OFFSET_UPPER_SHIFT 0
856#define DA7218_DAI_OFFSET_UPPER_MASK (0x7 << 0)
857
858/* DA7218_DAI_CLK_MODE = 0x90 */
859#define DA7218_DAI_BCLKS_PER_WCLK_SHIFT 0
860#define DA7218_DAI_BCLKS_PER_WCLK_MASK (0x3 << 0)
861#define DA7218_DAI_BCLKS_PER_WCLK_32 (0x0 << 0)
862#define DA7218_DAI_BCLKS_PER_WCLK_64 (0x1 << 0)
863#define DA7218_DAI_BCLKS_PER_WCLK_128 (0x2 << 0)
864#define DA7218_DAI_BCLKS_PER_WCLK_256 (0x3 << 0)
865#define DA7218_DAI_CLK_POL_SHIFT 2
866#define DA7218_DAI_CLK_POL_MASK (0x1 << 2)
867#define DA7218_DAI_CLK_POL_INV (0x1 << 2)
868#define DA7218_DAI_WCLK_POL_SHIFT 3
869#define DA7218_DAI_WCLK_POL_MASK (0x1 << 3)
870#define DA7218_DAI_WCLK_POL_INV (0x1 << 3)
871#define DA7218_DAI_WCLK_TRI_STATE_SHIFT 4
872#define DA7218_DAI_WCLK_TRI_STATE_MASK (0x1 << 4)
873#define DA7218_DAI_CLK_EN_SHIFT 7
874#define DA7218_DAI_CLK_EN_MASK (0x1 << 7)
875
876/* DA7218_PLL_CTRL = 0x91 */
877#define DA7218_PLL_INDIV_SHIFT 0
878#define DA7218_PLL_INDIV_MASK (0x7 << 0)
879#define DA7218_PLL_INDIV_2_5_MHZ (0x0 << 0)
880#define DA7218_PLL_INDIV_5_10_MHZ (0x1 << 0)
881#define DA7218_PLL_INDIV_10_20_MHZ (0x2 << 0)
882#define DA7218_PLL_INDIV_20_40_MHZ (0x3 << 0)
883#define DA7218_PLL_INDIV_40_54_MHZ (0x4 << 0)
884#define DA7218_PLL_INDIV_2_10_MHZ_VAL 2
885#define DA7218_PLL_INDIV_10_20_MHZ_VAL 4
886#define DA7218_PLL_INDIV_20_40_MHZ_VAL 8
887#define DA7218_PLL_INDIV_40_54_MHZ_VAL 16
888#define DA7218_PLL_MCLK_SQR_EN_SHIFT 4
889#define DA7218_PLL_MCLK_SQR_EN_MASK (0x1 << 4)
890#define DA7218_PLL_MODE_SHIFT 6
891#define DA7218_PLL_MODE_MASK (0x3 << 6)
892#define DA7218_PLL_MODE_BYPASS (0x0 << 6)
893#define DA7218_PLL_MODE_NORMAL (0x1 << 6)
894#define DA7218_PLL_MODE_SRM (0x2 << 6)
895#define DA7218_PLL_MODE_32KHZ (0x3 << 6)
896
897/* DA7218_PLL_FRAC_TOP = 0x92 */
898#define DA7218_PLL_FBDIV_FRAC_TOP_SHIFT 0
899#define DA7218_PLL_FBDIV_FRAC_TOP_MASK (0x1F << 0)
900
901/* DA7218_PLL_FRAC_BOT = 0x93 */
902#define DA7218_PLL_FBDIV_FRAC_BOT_SHIFT 0
903#define DA7218_PLL_FBDIV_FRAC_BOT_MASK (0xFF << 0)
904
905/* DA7218_PLL_INTEGER = 0x94 */
906#define DA7218_PLL_FBDIV_INTEGER_SHIFT 0
907#define DA7218_PLL_FBDIV_INTEGER_MASK (0x7F << 0)
908
909/* DA7218_PLL_STATUS = 0x95 */
910#define DA7218_PLL_SRM_STATUS_SHIFT 0
911#define DA7218_PLL_SRM_STATUS_MASK (0xFF << 0)
912#define DA7218_PLL_SRM_STATUS_SRM_LOCK (0x1 << 7)
913
914/* DA7218_PLL_REFOSC_CAL = 0x98 */
915#define DA7218_PLL_REFOSC_CAL_CTRL_SHIFT 0
916#define DA7218_PLL_REFOSC_CAL_CTRL_MASK (0x1F << 0)
917#define DA7218_PLL_REFOSC_CAL_START_SHIFT 6
918#define DA7218_PLL_REFOSC_CAL_START_MASK (0x1 << 6)
919#define DA7218_PLL_REFOSC_CAL_EN_SHIFT 7
920#define DA7218_PLL_REFOSC_CAL_EN_MASK (0x1 << 7)
921
922/* DA7218_DAC_NG_CTRL = 0x9C */
923#define DA7218_DAC_NG_EN_SHIFT 7
924#define DA7218_DAC_NG_EN_MASK (0x1 << 7)
925
926/* DA7218_DAC_NG_SETUP_TIME = 0x9D */
927#define DA7218_DAC_NG_SETUP_TIME_SHIFT 0
928#define DA7218_DAC_NG_SETUP_TIME_MASK (0x3 << 0)
929#define DA7218_DAC_NG_SETUP_TIME_MAX 4
930#define DA7218_DAC_NG_RAMPUP_RATE_SHIFT 2
931#define DA7218_DAC_NG_RAMPUP_RATE_MASK (0x1 << 2)
932#define DA7218_DAC_NG_RAMPUP_RATE_MAX 2
933#define DA7218_DAC_NG_RAMPDN_RATE_SHIFT 3
934#define DA7218_DAC_NG_RAMPDN_RATE_MASK (0x1 << 3)
935#define DA7218_DAC_NG_RAMPDN_RATE_MAX 2
936
937/* DA7218_DAC_NG_OFF_THRESH = 0x9E */
938#define DA7218_DAC_NG_OFF_THRESHOLD_SHIFT 0
939#define DA7218_DAC_NG_OFF_THRESHOLD_MASK (0x7 << 0)
940#define DA7218_DAC_NG_THRESHOLD_MAX 0x7
941
942/* DA7218_DAC_NG_ON_THRESH = 0x9F */
943#define DA7218_DAC_NG_ON_THRESHOLD_SHIFT 0
944#define DA7218_DAC_NG_ON_THRESHOLD_MASK (0x7 << 0)
945
946/* DA7218_TONE_GEN_CFG1 = 0xA0 */
947#define DA7218_DTMF_REG_SHIFT 0
948#define DA7218_DTMF_REG_MASK (0xF << 0)
949#define DA7218_DTMF_REG_MAX 16
950#define DA7218_DTMF_EN_SHIFT 4
951#define DA7218_DTMF_EN_MASK (0x1 << 4)
952#define DA7218_START_STOPN_SHIFT 7
953#define DA7218_START_STOPN_MASK (0x1 << 7)
954
955/* DA7218_TONE_GEN_CFG2 = 0xA1 */
956#define DA7218_SWG_SEL_SHIFT 0
957#define DA7218_SWG_SEL_MASK (0x3 << 0)
958#define DA7218_SWG_SEL_MAX 4
959
960/* DA7218_TONE_GEN_FREQ1_L = 0xA2 */
961#define DA7218_FREQ1_L_SHIFT 0
962#define DA7218_FREQ1_L_MASK (0xFF << 0)
963#define DA7218_FREQ_MAX 0xFFFF
964
965/* DA7218_TONE_GEN_FREQ1_U = 0xA3 */
966#define DA7218_FREQ1_U_SHIFT 0
967#define DA7218_FREQ1_U_MASK (0xFF << 0)
968
969/* DA7218_TONE_GEN_FREQ2_L = 0xA4 */
970#define DA7218_FREQ2_L_SHIFT 0
971#define DA7218_FREQ2_L_MASK (0xFF << 0)
972
973/* DA7218_TONE_GEN_FREQ2_U = 0xA5 */
974#define DA7218_FREQ2_U_SHIFT 0
975#define DA7218_FREQ2_U_MASK (0xFF << 0)
976
977/* DA7218_TONE_GEN_CYCLES = 0xA6 */
978#define DA7218_BEEP_CYCLES_SHIFT 0
979#define DA7218_BEEP_CYCLES_MASK (0x7 << 0)
980
981/* DA7218_TONE_GEN_ON_PER = 0xA7 */
982#define DA7218_BEEP_ON_PER_SHIFT 0
983#define DA7218_BEEP_ON_PER_MASK (0x3F << 0)
984
985/* DA7218_TONE_GEN_OFF_PER = 0xA8 */
986#define DA7218_BEEP_OFF_PER_SHIFT 0
987#define DA7218_BEEP_OFF_PER_MASK (0x3F << 0)
988#define DA7218_BEEP_ON_OFF_MAX 0x3F
989
990/* DA7218_CP_CTRL = 0xAC */
991#define DA7218_CP_MOD_SHIFT 2
992#define DA7218_CP_MOD_MASK (0x3 << 2)
993#define DA7218_CP_MCHANGE_SHIFT 4
994#define DA7218_CP_MCHANGE_MASK (0x3 << 4)
995#define DA7218_CP_MCHANGE_REL_MASK 0x3
996#define DA7218_CP_MCHANGE_MAX 3
997#define DA7218_CP_MCHANGE_LARGEST_VOL 0x1
998#define DA7218_CP_MCHANGE_DAC_VOL 0x2
999#define DA7218_CP_MCHANGE_SIG_MAG 0x3
1000#define DA7218_CP_SMALL_SWITCH_FREQ_EN_SHIFT 6
1001#define DA7218_CP_SMALL_SWITCH_FREQ_EN_MASK (0x1 << 6)
1002#define DA7218_CP_EN_SHIFT 7
1003#define DA7218_CP_EN_MASK (0x1 << 7)
1004
1005/* DA7218_CP_DELAY = 0xAD */
1006#define DA7218_CP_FCONTROL_SHIFT 0
1007#define DA7218_CP_FCONTROL_MASK (0x7 << 0)
1008#define DA7218_CP_FCONTROL_MAX 6
1009#define DA7218_CP_TAU_DELAY_SHIFT 3
1010#define DA7218_CP_TAU_DELAY_MASK (0x7 << 3)
1011#define DA7218_CP_TAU_DELAY_MAX 8
1012
1013/* DA7218_CP_VOL_THRESHOLD1 = 0xAE */
1014#define DA7218_CP_THRESH_VDD2_SHIFT 0
1015#define DA7218_CP_THRESH_VDD2_MASK (0x3F << 0)
1016#define DA7218_CP_THRESH_VDD2_MAX 0x3F
1017
1018/* DA7218_MIC_1_CTRL = 0xB4 */
1019#define DA7218_MIC_1_AMP_MUTE_EN_SHIFT 6
1020#define DA7218_MIC_1_AMP_MUTE_EN_MASK (0x1 << 6)
1021#define DA7218_MIC_1_AMP_EN_SHIFT 7
1022#define DA7218_MIC_1_AMP_EN_MASK (0x1 << 7)
1023
1024/* DA7218_MIC_1_GAIN = 0xB5 */
1025#define DA7218_MIC_1_AMP_GAIN_SHIFT 0
1026#define DA7218_MIC_1_AMP_GAIN_MASK (0x7 << 0)
1027#define DA7218_MIC_AMP_GAIN_MAX 0x7
1028
1029/* DA7218_MIC_1_SELECT = 0xB7 */
1030#define DA7218_MIC_1_AMP_IN_SEL_SHIFT 0
1031#define DA7218_MIC_1_AMP_IN_SEL_MASK (0x3 << 0)
1032
1033/* DA7218_MIC_2_CTRL = 0xB8 */
1034#define DA7218_MIC_2_AMP_MUTE_EN_SHIFT 6
1035#define DA7218_MIC_2_AMP_MUTE_EN_MASK (0x1 << 6)
1036#define DA7218_MIC_2_AMP_EN_SHIFT 7
1037#define DA7218_MIC_2_AMP_EN_MASK (0x1 << 7)
1038
1039/* DA7218_MIC_2_GAIN = 0xB9 */
1040#define DA7218_MIC_2_AMP_GAIN_SHIFT 0
1041#define DA7218_MIC_2_AMP_GAIN_MASK (0x7 << 0)
1042
1043/* DA7218_MIC_2_SELECT = 0xBB */
1044#define DA7218_MIC_2_AMP_IN_SEL_SHIFT 0
1045#define DA7218_MIC_2_AMP_IN_SEL_MASK (0x3 << 0)
1046
1047/* DA7218_IN_1_HPF_FILTER_CTRL = 0xBC */
1048#define DA7218_IN_1_VOICE_HPF_CORNER_SHIFT 0
1049#define DA7218_IN_1_VOICE_HPF_CORNER_MASK (0x7 << 0)
1050#define DA7218_IN_VOICE_HPF_CORNER_MAX 8
1051#define DA7218_IN_1_VOICE_EN_SHIFT 3
1052#define DA7218_IN_1_VOICE_EN_MASK (0x1 << 3)
1053#define DA7218_IN_1_AUDIO_HPF_CORNER_SHIFT 4
1054#define DA7218_IN_1_AUDIO_HPF_CORNER_MASK (0x3 << 4)
1055#define DA7218_IN_1_HPF_EN_SHIFT 7
1056#define DA7218_IN_1_HPF_EN_MASK (0x1 << 7)
1057
1058/* DA7218_IN_2_HPF_FILTER_CTRL = 0xBD */
1059#define DA7218_IN_2_VOICE_HPF_CORNER_SHIFT 0
1060#define DA7218_IN_2_VOICE_HPF_CORNER_MASK (0x7 << 0)
1061#define DA7218_IN_2_VOICE_EN_SHIFT 3
1062#define DA7218_IN_2_VOICE_EN_MASK (0x1 << 3)
1063#define DA7218_IN_2_AUDIO_HPF_CORNER_SHIFT 4
1064#define DA7218_IN_2_AUDIO_HPF_CORNER_MASK (0x3 << 4)
1065#define DA7218_IN_2_HPF_EN_SHIFT 7
1066#define DA7218_IN_2_HPF_EN_MASK (0x1 << 7)
1067
1068/* DA7218_ADC_1_CTRL = 0xC0 */
1069#define DA7218_ADC_1_AAF_EN_SHIFT 2
1070#define DA7218_ADC_1_AAF_EN_MASK (0x1 << 2)
1071
1072/* DA7218_ADC_2_CTRL = 0xC1 */
1073#define DA7218_ADC_2_AAF_EN_SHIFT 2
1074#define DA7218_ADC_2_AAF_EN_MASK (0x1 << 2)
1075
1076/* DA7218_ADC_MODE = 0xC2 */
1077#define DA7218_ADC_LP_MODE_SHIFT 0
1078#define DA7218_ADC_LP_MODE_MASK (0x1 << 0)
1079#define DA7218_ADC_LVLDET_MODE_SHIFT 1
1080#define DA7218_ADC_LVLDET_MODE_MASK (0x1 << 1)
1081#define DA7218_ADC_LVLDET_AUTO_EXIT_SHIFT 2
1082#define DA7218_ADC_LVLDET_AUTO_EXIT_MASK (0x1 << 2)
1083
1084/* DA7218_MIXOUT_L_CTRL = 0xCC */
1085#define DA7218_MIXOUT_L_AMP_EN_SHIFT 7
1086#define DA7218_MIXOUT_L_AMP_EN_MASK (0x1 << 7)
1087
1088/* DA7218_MIXOUT_L_GAIN = 0xCD */
1089#define DA7218_MIXOUT_L_AMP_GAIN_SHIFT 0
1090#define DA7218_MIXOUT_L_AMP_GAIN_MASK (0x3 << 0)
1091#define DA7218_MIXOUT_AMP_GAIN_MIN 0x1
1092#define DA7218_MIXOUT_AMP_GAIN_MAX 0x3
1093
1094/* DA7218_MIXOUT_R_CTRL = 0xCE */
1095#define DA7218_MIXOUT_R_AMP_EN_SHIFT 7
1096#define DA7218_MIXOUT_R_AMP_EN_MASK (0x1 << 7)
1097
1098/* DA7218_MIXOUT_R_GAIN = 0xCF */
1099#define DA7218_MIXOUT_R_AMP_GAIN_SHIFT 0
1100#define DA7218_MIXOUT_R_AMP_GAIN_MASK (0x3 << 0)
1101
1102/* DA7218_HP_L_CTRL = 0xD0 */
1103#define DA7218_HP_L_AMP_MIN_GAIN_EN_SHIFT 2
1104#define DA7218_HP_L_AMP_MIN_GAIN_EN_MASK (0x1 << 2)
1105#define DA7218_HP_L_AMP_OE_SHIFT 3
1106#define DA7218_HP_L_AMP_OE_MASK (0x1 << 3)
1107#define DA7218_HP_L_AMP_ZC_EN_SHIFT 4
1108#define DA7218_HP_L_AMP_ZC_EN_MASK (0x1 << 4)
1109#define DA7218_HP_L_AMP_RAMP_EN_SHIFT 5
1110#define DA7218_HP_L_AMP_RAMP_EN_MASK (0x1 << 5)
1111#define DA7218_HP_L_AMP_MUTE_EN_SHIFT 6
1112#define DA7218_HP_L_AMP_MUTE_EN_MASK (0x1 << 6)
1113#define DA7218_HP_L_AMP_EN_SHIFT 7
1114#define DA7218_HP_L_AMP_EN_MASK (0x1 << 7)
1115#define DA7218_HP_AMP_OE_MASK (0x1 << 3)
1116
1117/* DA7218_HP_L_GAIN = 0xD1 */
1118#define DA7218_HP_L_AMP_GAIN_SHIFT 0
1119#define DA7218_HP_L_AMP_GAIN_MASK (0x3F << 0)
1120#define DA7218_HP_AMP_GAIN_MIN 0x15
1121#define DA7218_HP_AMP_GAIN_MAX 0x3F
1122
1123/* DA7218_HP_R_CTRL = 0xD2 */
1124#define DA7218_HP_R_AMP_MIN_GAIN_EN_SHIFT 2
1125#define DA7218_HP_R_AMP_MIN_GAIN_EN_MASK (0x1 << 2)
1126#define DA7218_HP_R_AMP_OE_SHIFT 3
1127#define DA7218_HP_R_AMP_OE_MASK (0x1 << 3)
1128#define DA7218_HP_R_AMP_ZC_EN_SHIFT 4
1129#define DA7218_HP_R_AMP_ZC_EN_MASK (0x1 << 4)
1130#define DA7218_HP_R_AMP_RAMP_EN_SHIFT 5
1131#define DA7218_HP_R_AMP_RAMP_EN_MASK (0x1 << 5)
1132#define DA7218_HP_R_AMP_MUTE_EN_SHIFT 6
1133#define DA7218_HP_R_AMP_MUTE_EN_MASK (0x1 << 6)
1134#define DA7218_HP_R_AMP_EN_SHIFT 7
1135#define DA7218_HP_R_AMP_EN_MASK (0x1 << 7)
1136
1137/* DA7218_HP_R_GAIN = 0xD3 */
1138#define DA7218_HP_R_AMP_GAIN_SHIFT 0
1139#define DA7218_HP_R_AMP_GAIN_MASK (0x3F << 0)
1140
1141/* DA7218_HP_SNGL_CTRL = 0xD4 */
1142#define DA7218_HP_AMP_STEREO_DETECT_STATUS_SHIFT 0
1143#define DA7218_HP_AMP_STEREO_DETECT_STATUS_MASK (0x1 << 0)
1144#define DA7218_HPL_AMP_LOAD_DETECT_STATUS_SHIFT 1
1145#define DA7218_HPL_AMP_LOAD_DETECT_STATUS_MASK (0x1 << 1)
1146#define DA7218_HPR_AMP_LOAD_DETECT_STATUS_SHIFT 2
1147#define DA7218_HPR_AMP_LOAD_DETECT_STATUS_MASK (0x1 << 2)
1148#define DA7218_HP_AMP_LOAD_DETECT_EN_SHIFT 6
1149#define DA7218_HP_AMP_LOAD_DETECT_EN_MASK (0x1 << 6)
1150#define DA7218_HP_AMP_STEREO_DETECT_EN_SHIFT 7
1151#define DA7218_HP_AMP_STEREO_DETECT_EN_MASK (0x1 << 7)
1152
1153/* DA7218_HP_DIFF_CTRL = 0xD5 */
1154#define DA7218_HP_AMP_DIFF_MODE_EN_SHIFT 0
1155#define DA7218_HP_AMP_DIFF_MODE_EN_MASK (0x1 << 0)
1156#define DA7218_HP_AMP_SINGLE_SUPPLY_EN_SHIFT 4
1157#define DA7218_HP_AMP_SINGLE_SUPPLY_EN_MASK (0x1 << 4)
1158
1159/* DA7218_HP_DIFF_UNLOCK = 0xD7 */
1160#define DA7218_HP_DIFF_UNLOCK_SHIFT 0
1161#define DA7218_HP_DIFF_UNLOCK_MASK (0x1 << 0)
1162#define DA7218_HP_DIFF_UNLOCK_VAL 0xC3
1163
1164/* DA7218_HPLDET_JACK = 0xD8 */
1165#define DA7218_HPLDET_JACK_RATE_SHIFT 0
1166#define DA7218_HPLDET_JACK_RATE_MASK (0x7 << 0)
1167#define DA7218_HPLDET_JACK_DEBOUNCE_SHIFT 3
1168#define DA7218_HPLDET_JACK_DEBOUNCE_MASK (0x3 << 3)
1169#define DA7218_HPLDET_JACK_THR_SHIFT 5
1170#define DA7218_HPLDET_JACK_THR_MASK (0x3 << 5)
1171#define DA7218_HPLDET_JACK_EN_SHIFT 7
1172#define DA7218_HPLDET_JACK_EN_MASK (0x1 << 7)
1173
1174/* DA7218_HPLDET_CTRL = 0xD9 */
1175#define DA7218_HPLDET_COMP_INV_SHIFT 0
1176#define DA7218_HPLDET_COMP_INV_MASK (0x1 << 0)
1177#define DA7218_HPLDET_HYST_EN_SHIFT 1
1178#define DA7218_HPLDET_HYST_EN_MASK (0x1 << 1)
1179#define DA7218_HPLDET_DISCHARGE_EN_SHIFT 7
1180#define DA7218_HPLDET_DISCHARGE_EN_MASK (0x1 << 7)
1181
1182/* DA7218_HPLDET_TEST = 0xDA */
1183#define DA7218_HPLDET_COMP_STS_SHIFT 4
1184#define DA7218_HPLDET_COMP_STS_MASK (0x1 << 4)
1185
1186/* DA7218_REFERENCES = 0xDC */
1187#define DA7218_BIAS_EN_SHIFT 3
1188#define DA7218_BIAS_EN_MASK (0x1 << 3)
1189
1190/* DA7218_IO_CTRL = 0xE0 */
1191#define DA7218_IO_VOLTAGE_LEVEL_SHIFT 0
1192#define DA7218_IO_VOLTAGE_LEVEL_MASK (0x1 << 0)
1193#define DA7218_IO_VOLTAGE_LEVEL_2_5V_3_6V 0
1194#define DA7218_IO_VOLTAGE_LEVEL_1_5V_2_5V 1
1195
1196/* DA7218_LDO_CTRL = 0xE1 */
1197#define DA7218_LDO_LEVEL_SELECT_SHIFT 4
1198#define DA7218_LDO_LEVEL_SELECT_MASK (0x3 << 4)
1199#define DA7218_LDO_EN_SHIFT 7
1200#define DA7218_LDO_EN_MASK (0x1 << 7)
1201
1202/* DA7218_SIDETONE_CTRL = 0xE4 */
1203#define DA7218_SIDETONE_MUTE_EN_SHIFT 6
1204#define DA7218_SIDETONE_MUTE_EN_MASK (0x1 << 6)
1205#define DA7218_SIDETONE_FILTER_EN_SHIFT 7
1206#define DA7218_SIDETONE_FILTER_EN_MASK (0x1 << 7)
1207
1208/* DA7218_SIDETONE_IN_SELECT = 0xE5 */
1209#define DA7218_SIDETONE_IN_SELECT_SHIFT 0
1210#define DA7218_SIDETONE_IN_SELECT_MASK (0x3 << 0)
1211#define DA7218_SIDETONE_IN_SELECT_MAX 4
1212
1213/* DA7218_SIDETONE_GAIN = 0xE6 */
1214#define DA7218_SIDETONE_GAIN_SHIFT 0
1215#define DA7218_SIDETONE_GAIN_MASK (0x1F << 0)
1216
1217/* DA7218_DROUTING_ST_OUTFILT_1L = 0xE8 */
1218#define DA7218_OUTFILT_ST_1L_SRC_SHIFT 0
1219#define DA7218_OUTFILT_ST_1L_SRC_MASK (0x7 << 0)
1220#define DA7218_DMIX_ST_SRC_OUTFILT1L 0
1221#define DA7218_DMIX_ST_SRC_OUTFILT1R 1
1222#define DA7218_DMIX_ST_SRC_SIDETONE 2
1223
1224/* DA7218_DROUTING_ST_OUTFILT_1R = 0xE9 */
1225#define DA7218_OUTFILT_ST_1R_SRC_SHIFT 0
1226#define DA7218_OUTFILT_ST_1R_SRC_MASK (0x7 << 0)
1227
1228/* DA7218_SIDETONE_BIQ_3STAGE_DATA = 0xEA */
1229#define DA7218_SIDETONE_BIQ_3STAGE_DATA_SHIFT 0
1230#define DA7218_SIDETONE_BIQ_3STAGE_DATA_MASK (0xFF << 0)
1231
1232/* DA7218_SIDETONE_BIQ_3STAGE_ADDR = 0xEB */
1233#define DA7218_SIDETONE_BIQ_3STAGE_ADDR_SHIFT 0
1234#define DA7218_SIDETONE_BIQ_3STAGE_ADDR_MASK (0x1F << 0)
1235#define DA7218_SIDETONE_BIQ_3STAGE_CFG_SIZE 30
1236
1237/* DA7218_EVENT_STATUS = 0xEC */
1238#define DA7218_HPLDET_JACK_STS_SHIFT 7
1239#define DA7218_HPLDET_JACK_STS_MASK (0x1 << 7)
1240
1241/* DA7218_EVENT = 0xED */
1242#define DA7218_LVL_DET_EVENT_SHIFT 0
1243#define DA7218_LVL_DET_EVENT_MASK (0x1 << 0)
1244#define DA7218_HPLDET_JACK_EVENT_SHIFT 7
1245#define DA7218_HPLDET_JACK_EVENT_MASK (0x1 << 7)
1246
1247/* DA7218_EVENT_MASK = 0xEE */
1248#define DA7218_LVL_DET_EVENT_MSK_SHIFT 0
1249#define DA7218_LVL_DET_EVENT_MSK_MASK (0x1 << 0)
1250#define DA7218_HPLDET_JACK_EVENT_IRQ_MSK_SHIFT 7
1251#define DA7218_HPLDET_JACK_EVENT_IRQ_MSK_MASK (0x1 << 7)
1252
1253/* DA7218_DMIC_1_CTRL = 0xF0 */
1254#define DA7218_DMIC_1_DATA_SEL_SHIFT 0
1255#define DA7218_DMIC_1_DATA_SEL_MASK (0x1 << 0)
1256#define DA7218_DMIC_1_SAMPLEPHASE_SHIFT 1
1257#define DA7218_DMIC_1_SAMPLEPHASE_MASK (0x1 << 1)
1258#define DA7218_DMIC_1_CLK_RATE_SHIFT 2
1259#define DA7218_DMIC_1_CLK_RATE_MASK (0x1 << 2)
1260#define DA7218_DMIC_1L_EN_SHIFT 6
1261#define DA7218_DMIC_1L_EN_MASK (0x1 << 6)
1262#define DA7218_DMIC_1R_EN_SHIFT 7
1263#define DA7218_DMIC_1R_EN_MASK (0x1 << 7)
1264
1265/* DA7218_DMIC_2_CTRL = 0xF1 */
1266#define DA7218_DMIC_2_DATA_SEL_SHIFT 0
1267#define DA7218_DMIC_2_DATA_SEL_MASK (0x1 << 0)
1268#define DA7218_DMIC_2_SAMPLEPHASE_SHIFT 1
1269#define DA7218_DMIC_2_SAMPLEPHASE_MASK (0x1 << 1)
1270#define DA7218_DMIC_2_CLK_RATE_SHIFT 2
1271#define DA7218_DMIC_2_CLK_RATE_MASK (0x1 << 2)
1272#define DA7218_DMIC_2L_EN_SHIFT 6
1273#define DA7218_DMIC_2L_EN_MASK (0x1 << 6)
1274#define DA7218_DMIC_2R_EN_SHIFT 7
1275#define DA7218_DMIC_2R_EN_MASK (0x1 << 7)
1276
1277/* DA7218_IN_1L_GAIN = 0xF4 */
1278#define DA7218_IN_1L_DIGITAL_GAIN_SHIFT 0
1279#define DA7218_IN_1L_DIGITAL_GAIN_MASK (0x7F << 0)
1280#define DA7218_IN_DIGITAL_GAIN_MAX 0x7F
1281
1282/* DA7218_IN_1R_GAIN = 0xF5 */
1283#define DA7218_IN_1R_DIGITAL_GAIN_SHIFT 0
1284#define DA7218_IN_1R_DIGITAL_GAIN_MASK (0x7F << 0)
1285
1286/* DA7218_IN_2L_GAIN = 0xF6 */
1287#define DA7218_IN_2L_DIGITAL_GAIN_SHIFT 0
1288#define DA7218_IN_2L_DIGITAL_GAIN_MASK (0x7F << 0)
1289
1290/* DA7218_IN_2R_GAIN = 0xF7 */
1291#define DA7218_IN_2R_DIGITAL_GAIN_SHIFT 0
1292#define DA7218_IN_2R_DIGITAL_GAIN_MASK (0x7F << 0)
1293
1294/* DA7218_OUT_1L_GAIN = 0xF8 */
1295#define DA7218_OUT_1L_DIGITAL_GAIN_SHIFT 0
1296#define DA7218_OUT_1L_DIGITAL_GAIN_MASK (0xFF << 0)
1297#define DA7218_OUT_DIGITAL_GAIN_MIN 0x0
1298#define DA7218_OUT_DIGITAL_GAIN_MAX 0x97
1299
1300/* DA7218_OUT_1R_GAIN = 0xF9 */
1301#define DA7218_OUT_1R_DIGITAL_GAIN_SHIFT 0
1302#define DA7218_OUT_1R_DIGITAL_GAIN_MASK (0xFF << 0)
1303
1304/* DA7218_MICBIAS_CTRL = 0xFC */
1305#define DA7218_MICBIAS_1_LEVEL_SHIFT 0
1306#define DA7218_MICBIAS_1_LEVEL_MASK (0x7 << 0)
1307#define DA7218_MICBIAS_1_LP_MODE_SHIFT 3
1308#define DA7218_MICBIAS_1_LP_MODE_MASK (0x1 << 3)
1309#define DA7218_MICBIAS_2_LEVEL_SHIFT 4
1310#define DA7218_MICBIAS_2_LEVEL_MASK (0x7 << 4)
1311#define DA7218_MICBIAS_2_LP_MODE_SHIFT 7
1312#define DA7218_MICBIAS_2_LP_MODE_MASK (0x1 << 7)
1313
1314/* DA7218_MICBIAS_EN = 0xFD */
1315#define DA7218_MICBIAS_1_EN_SHIFT 0
1316#define DA7218_MICBIAS_1_EN_MASK (0x1 << 0)
1317#define DA7218_MICBIAS_2_EN_SHIFT 4
1318#define DA7218_MICBIAS_2_EN_MASK (0x1 << 4)
1319
1320
1321/*
1322 * General defines & data
1323 */
1324
1325/* Register inversion */
1326#define DA7218_NO_INVERT 0
1327#define DA7218_INVERT 1
1328
1329/* Byte related defines */
1330#define DA7218_BYTE_SHIFT 8
1331#define DA7218_BYTE_MASK 0xFF
1332#define DA7218_2BYTE_SHIFT 16
1333#define DA7218_2BYTE_MASK 0xFFFF
1334
1335/* PLL Output Frequencies */
1336#define DA7218_PLL_FREQ_OUT_90316 90316800
1337#define DA7218_PLL_FREQ_OUT_98304 98304000
1338
1339/* ALC Calibration */
1340#define DA7218_ALC_CALIB_DELAY_MIN 2500
1341#define DA7218_ALC_CALIB_DELAY_MAX 5000
1342#define DA7218_ALC_CALIB_MAX_TRIES 5
1343
1344/* Ref Oscillator */
1345#define DA7218_REF_OSC_CHECK_DELAY_MIN 5000
1346#define DA7218_REF_OSC_CHECK_DELAY_MAX 10000
1347#define DA7218_REF_OSC_CHECK_TRIES 4
1348
1349/* SRM */
1350#define DA7218_SRM_CHECK_DELAY 50
1351#define DA7218_SRM_CHECK_TRIES 8
1352
1353/* Mic Level Detect */
1354#define DA7218_MIC_LVL_DET_DELAY 50
1355
1356enum da7218_biq_cfg {
1357 DA7218_BIQ_CFG_DATA = 0,
1358 DA7218_BIQ_CFG_ADDR,
1359 DA7218_BIQ_CFG_SIZE,
1360};
1361
1362enum da7218_clk_src {
1363 DA7218_CLKSRC_MCLK = 0,
1364 DA7218_CLKSRC_MCLK_SQR,
1365};
1366
1367enum da7218_sys_clk {
1368 DA7218_SYSCLK_MCLK = 0,
1369 DA7218_SYSCLK_PLL,
1370 DA7218_SYSCLK_PLL_SRM,
1371 DA7218_SYSCLK_PLL_32KHZ
1372};
1373
1374enum da7218_dev_id {
1375 DA7217_DEV_ID = 0,
1376 DA7218_DEV_ID,
1377};
1378
1379/* Regulators */
1380enum da7218_supplies {
1381 DA7218_SUPPLY_VDD = 0,
1382 DA7218_SUPPLY_VDDMIC,
1383 DA7218_SUPPLY_VDDIO,
1384 DA7218_NUM_SUPPLIES,
1385};
1386
1387/* Private data */
1388struct da7218_priv {
1389 struct da7218_pdata *pdata;
1390
1391 struct regulator_bulk_data supplies[DA7218_NUM_SUPPLIES];
1392 struct regmap *regmap;
1393 int dev_id;
1394
1395 struct snd_soc_jack *jack;
1396 int irq;
1397
1398 struct clk *mclk;
1399 unsigned int mclk_rate;
1400
1401 bool hp_single_supply;
1402 bool master;
1403 u8 alc_en;
1404 u8 in_filt_en;
1405 u8 mic_lvl_det_en;
1406
1407 u8 biq_5stage_coeff[DA7218_OUT_1_BIQ_5STAGE_CFG_SIZE];
1408 u8 stbiq_3stage_coeff[DA7218_SIDETONE_BIQ_3STAGE_CFG_SIZE];
1409};
1410
1411/* HP detect control */
1412int da7218_hpldet(struct snd_soc_codec *codec, struct snd_soc_jack *jack);
1413
1414#endif /* _DA7218_H */
diff --git a/sound/soc/codecs/da7219.c b/sound/soc/codecs/da7219.c
index f238c1e8a69c..81c0708b85c1 100644
--- a/sound/soc/codecs/da7219.c
+++ b/sound/soc/codecs/da7219.c
@@ -968,10 +968,11 @@ static const struct snd_soc_dapm_route da7219_audio_map[] = {
968 {"Mixin PGA", NULL, "Mic PGA"}, 968 {"Mixin PGA", NULL, "Mic PGA"},
969 {"ADC", NULL, "Mixin PGA"}, 969 {"ADC", NULL, "Mixin PGA"},
970 970
971 {"Sidetone Filter", NULL, "ADC"},
972 {"Mixer In", NULL, "Mixer In Supply"}, 971 {"Mixer In", NULL, "Mixer In Supply"},
973 {"Mixer In", "Mic Switch", "ADC"}, 972 {"Mixer In", "Mic Switch", "ADC"},
974 973
974 {"Sidetone Filter", NULL, "Mixer In"},
975
975 {"Tone Generator", NULL, "TONE"}, 976 {"Tone Generator", NULL, "TONE"},
976 977
977 DA7219_OUT_DAI_MUX_ROUTES("Out DAIL Mux"), 978 DA7219_OUT_DAI_MUX_ROUTES("Out DAIL Mux"),
@@ -1073,11 +1074,8 @@ static int da7219_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
1073 u32 freq_ref; 1074 u32 freq_ref;
1074 u64 frac_div; 1075 u64 frac_div;
1075 1076
1076 /* Verify 32KHz, 2MHz - 54MHz MCLK provided, and set input divider */ 1077 /* Verify 2MHz - 54MHz MCLK provided, and set input divider */
1077 if (da7219->mclk_rate == 32768) { 1078 if (da7219->mclk_rate < 2000000) {
1078 indiv_bits = DA7219_PLL_INDIV_2_5_MHZ;
1079 indiv = DA7219_PLL_INDIV_2_5_MHZ_VAL;
1080 } else if (da7219->mclk_rate < 2000000) {
1081 dev_err(codec->dev, "PLL input clock %d below valid range\n", 1079 dev_err(codec->dev, "PLL input clock %d below valid range\n",
1082 da7219->mclk_rate); 1080 da7219->mclk_rate);
1083 return -EINVAL; 1081 return -EINVAL;
@@ -1118,9 +1116,6 @@ static int da7219_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
1118 case DA7219_SYSCLK_PLL_SRM: 1116 case DA7219_SYSCLK_PLL_SRM:
1119 pll_ctrl |= DA7219_PLL_MODE_SRM; 1117 pll_ctrl |= DA7219_PLL_MODE_SRM;
1120 break; 1118 break;
1121 case DA7219_SYSCLK_PLL_32KHZ:
1122 pll_ctrl |= DA7219_PLL_MODE_32KHZ;
1123 break;
1124 default: 1119 default:
1125 dev_err(codec->dev, "Invalid PLL config\n"); 1120 dev_err(codec->dev, "Invalid PLL config\n");
1126 return -EINVAL; 1121 return -EINVAL;
@@ -1161,18 +1156,44 @@ static int da7219_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
1161 return -EINVAL; 1156 return -EINVAL;
1162 } 1157 }
1163 1158
1164 switch (fmt & SND_SOC_DAIFMT_INV_MASK) { 1159 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
1165 case SND_SOC_DAIFMT_NB_NF: 1160 case SND_SOC_DAIFMT_I2S:
1166 break; 1161 case SND_SOC_DAIFMT_LEFT_J:
1167 case SND_SOC_DAIFMT_NB_IF: 1162 case SND_SOC_DAIFMT_RIGHT_J:
1168 dai_clk_mode |= DA7219_DAI_WCLK_POL_INV; 1163 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
1169 break; 1164 case SND_SOC_DAIFMT_NB_NF:
1170 case SND_SOC_DAIFMT_IB_NF: 1165 break;
1171 dai_clk_mode |= DA7219_DAI_CLK_POL_INV; 1166 case SND_SOC_DAIFMT_NB_IF:
1167 dai_clk_mode |= DA7219_DAI_WCLK_POL_INV;
1168 break;
1169 case SND_SOC_DAIFMT_IB_NF:
1170 dai_clk_mode |= DA7219_DAI_CLK_POL_INV;
1171 break;
1172 case SND_SOC_DAIFMT_IB_IF:
1173 dai_clk_mode |= DA7219_DAI_WCLK_POL_INV |
1174 DA7219_DAI_CLK_POL_INV;
1175 break;
1176 default:
1177 return -EINVAL;
1178 }
1172 break; 1179 break;
1173 case SND_SOC_DAIFMT_IB_IF: 1180 case SND_SOC_DAIFMT_DSP_B:
1174 dai_clk_mode |= DA7219_DAI_WCLK_POL_INV | 1181 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
1175 DA7219_DAI_CLK_POL_INV; 1182 case SND_SOC_DAIFMT_NB_NF:
1183 dai_clk_mode |= DA7219_DAI_CLK_POL_INV;
1184 break;
1185 case SND_SOC_DAIFMT_NB_IF:
1186 dai_clk_mode |= DA7219_DAI_WCLK_POL_INV |
1187 DA7219_DAI_CLK_POL_INV;
1188 break;
1189 case SND_SOC_DAIFMT_IB_NF:
1190 break;
1191 case SND_SOC_DAIFMT_IB_IF:
1192 dai_clk_mode |= DA7219_DAI_WCLK_POL_INV;
1193 break;
1194 default:
1195 return -EINVAL;
1196 }
1176 break; 1197 break;
1177 default: 1198 default:
1178 return -EINVAL; 1199 return -EINVAL;
@@ -1306,7 +1327,7 @@ static int da7219_hw_params(struct snd_pcm_substream *substream,
1306 } 1327 }
1307 1328
1308 channels = params_channels(params); 1329 channels = params_channels(params);
1309 if ((channels < 1) | (channels > DA7219_DAI_CH_NUM_MAX)) { 1330 if ((channels < 1) || (channels > DA7219_DAI_CH_NUM_MAX)) {
1310 dev_err(codec->dev, 1331 dev_err(codec->dev,
1311 "Invalid number of channels, only 1 to %d supported\n", 1332 "Invalid number of channels, only 1 to %d supported\n",
1312 DA7219_DAI_CH_NUM_MAX); 1333 DA7219_DAI_CH_NUM_MAX);
@@ -1405,28 +1426,12 @@ static const struct of_device_id da7219_of_match[] = {
1405}; 1426};
1406MODULE_DEVICE_TABLE(of, da7219_of_match); 1427MODULE_DEVICE_TABLE(of, da7219_of_match);
1407 1428
1408static enum da7219_ldo_lvl_sel da7219_of_ldo_lvl(struct snd_soc_codec *codec,
1409 u32 val)
1410{
1411 switch (val) {
1412 case 1050:
1413 return DA7219_LDO_LVL_SEL_1_05V;
1414 case 1100:
1415 return DA7219_LDO_LVL_SEL_1_10V;
1416 case 1200:
1417 return DA7219_LDO_LVL_SEL_1_20V;
1418 case 1400:
1419 return DA7219_LDO_LVL_SEL_1_40V;
1420 default:
1421 dev_warn(codec->dev, "Invalid LDO level");
1422 return DA7219_LDO_LVL_SEL_1_05V;
1423 }
1424}
1425
1426static enum da7219_micbias_voltage 1429static enum da7219_micbias_voltage
1427 da7219_of_micbias_lvl(struct snd_soc_codec *codec, u32 val) 1430 da7219_of_micbias_lvl(struct snd_soc_codec *codec, u32 val)
1428{ 1431{
1429 switch (val) { 1432 switch (val) {
1433 case 1600:
1434 return DA7219_MICBIAS_1_6V;
1430 case 1800: 1435 case 1800:
1431 return DA7219_MICBIAS_1_8V; 1436 return DA7219_MICBIAS_1_8V;
1432 case 2000: 1437 case 2000:
@@ -1469,9 +1474,6 @@ static struct da7219_pdata *da7219_of_to_pdata(struct snd_soc_codec *codec)
1469 if (!pdata) 1474 if (!pdata)
1470 return NULL; 1475 return NULL;
1471 1476
1472 if (of_property_read_u32(np, "dlg,ldo-lvl", &of_val32) >= 0)
1473 pdata->ldo_lvl_sel = da7219_of_ldo_lvl(codec, of_val32);
1474
1475 if (of_property_read_u32(np, "dlg,micbias-lvl", &of_val32) >= 0) 1477 if (of_property_read_u32(np, "dlg,micbias-lvl", &of_val32) >= 0)
1476 pdata->micbias_lvl = da7219_of_micbias_lvl(codec, of_val32); 1478 pdata->micbias_lvl = da7219_of_micbias_lvl(codec, of_val32);
1477 else 1479 else
@@ -1516,24 +1518,13 @@ static int da7219_set_bias_level(struct snd_soc_codec *codec,
1516 snd_soc_update_bits(codec, DA7219_REFERENCES, 1518 snd_soc_update_bits(codec, DA7219_REFERENCES,
1517 DA7219_BIAS_EN_MASK, 1519 DA7219_BIAS_EN_MASK,
1518 DA7219_BIAS_EN_MASK); 1520 DA7219_BIAS_EN_MASK);
1519
1520 /* Enable Internal Digital LDO */
1521 snd_soc_update_bits(codec, DA7219_LDO_CTRL,
1522 DA7219_LDO_EN_MASK,
1523 DA7219_LDO_EN_MASK);
1524 } 1521 }
1525 break; 1522 break;
1526 case SND_SOC_BIAS_OFF: 1523 case SND_SOC_BIAS_OFF:
1527 /* Only disable if jack detection not active */ 1524 /* Only disable master bias if jack detection not active */
1528 if (!da7219->aad->jack) { 1525 if (!da7219->aad->jack)
1529 /* Bypass Internal Digital LDO */
1530 snd_soc_update_bits(codec, DA7219_LDO_CTRL,
1531 DA7219_LDO_EN_MASK, 0);
1532
1533 /* Master bias */
1534 snd_soc_update_bits(codec, DA7219_REFERENCES, 1526 snd_soc_update_bits(codec, DA7219_REFERENCES,
1535 DA7219_BIAS_EN_MASK, 0); 1527 DA7219_BIAS_EN_MASK, 0);
1536 }
1537 1528
1538 /* MCLK */ 1529 /* MCLK */
1539 if (da7219->mclk) 1530 if (da7219->mclk)
@@ -1600,21 +1591,9 @@ static void da7219_handle_pdata(struct snd_soc_codec *codec)
1600 if (pdata) { 1591 if (pdata) {
1601 u8 micbias_lvl = 0; 1592 u8 micbias_lvl = 0;
1602 1593
1603 /* Internal LDO */
1604 switch (pdata->ldo_lvl_sel) {
1605 case DA7219_LDO_LVL_SEL_1_05V:
1606 case DA7219_LDO_LVL_SEL_1_10V:
1607 case DA7219_LDO_LVL_SEL_1_20V:
1608 case DA7219_LDO_LVL_SEL_1_40V:
1609 snd_soc_update_bits(codec, DA7219_LDO_CTRL,
1610 DA7219_LDO_LEVEL_SELECT_MASK,
1611 (pdata->ldo_lvl_sel <<
1612 DA7219_LDO_LEVEL_SELECT_SHIFT));
1613 break;
1614 }
1615
1616 /* Mic Bias voltages */ 1594 /* Mic Bias voltages */
1617 switch (pdata->micbias_lvl) { 1595 switch (pdata->micbias_lvl) {
1596 case DA7219_MICBIAS_1_6V:
1618 case DA7219_MICBIAS_1_8V: 1597 case DA7219_MICBIAS_1_8V:
1619 case DA7219_MICBIAS_2_0V: 1598 case DA7219_MICBIAS_2_0V:
1620 case DA7219_MICBIAS_2_2V: 1599 case DA7219_MICBIAS_2_2V:
@@ -1639,9 +1618,14 @@ static void da7219_handle_pdata(struct snd_soc_codec *codec)
1639 } 1618 }
1640} 1619}
1641 1620
1621static struct reg_sequence da7219_rev_aa_patch[] = {
1622 { DA7219_REFERENCES, 0x08 },
1623};
1624
1642static int da7219_probe(struct snd_soc_codec *codec) 1625static int da7219_probe(struct snd_soc_codec *codec)
1643{ 1626{
1644 struct da7219_priv *da7219 = snd_soc_codec_get_drvdata(codec); 1627 struct da7219_priv *da7219 = snd_soc_codec_get_drvdata(codec);
1628 unsigned int rev;
1645 int ret; 1629 int ret;
1646 1630
1647 mutex_init(&da7219->lock); 1631 mutex_init(&da7219->lock);
@@ -1651,6 +1635,26 @@ static int da7219_probe(struct snd_soc_codec *codec)
1651 if (ret) 1635 if (ret)
1652 return ret; 1636 return ret;
1653 1637
1638 ret = regmap_read(da7219->regmap, DA7219_CHIP_REVISION, &rev);
1639 if (ret) {
1640 dev_err(codec->dev, "Failed to read chip revision: %d\n", ret);
1641 goto err_disable_reg;
1642 }
1643
1644 switch (rev & DA7219_CHIP_MINOR_MASK) {
1645 case 0:
1646 ret = regmap_register_patch(da7219->regmap, da7219_rev_aa_patch,
1647 ARRAY_SIZE(da7219_rev_aa_patch));
1648 if (ret) {
1649 dev_err(codec->dev, "Failed to register AA patch: %d\n",
1650 ret);
1651 goto err_disable_reg;
1652 }
1653 break;
1654 default:
1655 break;
1656 }
1657
1654 /* Handle DT/Platform data */ 1658 /* Handle DT/Platform data */
1655 if (codec->dev->of_node) 1659 if (codec->dev->of_node)
1656 da7219->pdata = da7219_of_to_pdata(codec); 1660 da7219->pdata = da7219_of_to_pdata(codec);
@@ -1662,10 +1666,12 @@ static int da7219_probe(struct snd_soc_codec *codec)
1662 /* Check if MCLK provided */ 1666 /* Check if MCLK provided */
1663 da7219->mclk = devm_clk_get(codec->dev, "mclk"); 1667 da7219->mclk = devm_clk_get(codec->dev, "mclk");
1664 if (IS_ERR(da7219->mclk)) { 1668 if (IS_ERR(da7219->mclk)) {
1665 if (PTR_ERR(da7219->mclk) != -ENOENT) 1669 if (PTR_ERR(da7219->mclk) != -ENOENT) {
1666 return PTR_ERR(da7219->mclk); 1670 ret = PTR_ERR(da7219->mclk);
1667 else 1671 goto err_disable_reg;
1672 } else {
1668 da7219->mclk = NULL; 1673 da7219->mclk = NULL;
1674 }
1669 } 1675 }
1670 1676
1671 /* Default PC counter to free-running */ 1677 /* Default PC counter to free-running */
@@ -1693,7 +1699,16 @@ static int da7219_probe(struct snd_soc_codec *codec)
1693 snd_soc_write(codec, DA7219_TONE_GEN_CYCLES, DA7219_BEEP_CYCLES_MASK); 1699 snd_soc_write(codec, DA7219_TONE_GEN_CYCLES, DA7219_BEEP_CYCLES_MASK);
1694 1700
1695 /* Initialise AAD block */ 1701 /* Initialise AAD block */
1696 return da7219_aad_init(codec); 1702 ret = da7219_aad_init(codec);
1703 if (ret)
1704 goto err_disable_reg;
1705
1706 return 0;
1707
1708err_disable_reg:
1709 regulator_bulk_disable(DA7219_NUM_SUPPLIES, da7219->supplies);
1710
1711 return ret;
1697} 1712}
1698 1713
1699static int da7219_remove(struct snd_soc_codec *codec) 1714static int da7219_remove(struct snd_soc_codec *codec)
@@ -1776,7 +1791,7 @@ static struct reg_default da7219_reg_defaults[] = {
1776 { DA7219_DIG_ROUTING_DAC, 0x32 }, 1791 { DA7219_DIG_ROUTING_DAC, 0x32 },
1777 { DA7219_DAI_OFFSET_LOWER, 0x00 }, 1792 { DA7219_DAI_OFFSET_LOWER, 0x00 },
1778 { DA7219_DAI_OFFSET_UPPER, 0x00 }, 1793 { DA7219_DAI_OFFSET_UPPER, 0x00 },
1779 { DA7219_REFERENCES, 0x00 }, 1794 { DA7219_REFERENCES, 0x08 },
1780 { DA7219_MIXIN_L_SELECT, 0x00 }, 1795 { DA7219_MIXIN_L_SELECT, 0x00 },
1781 { DA7219_MIXIN_L_GAIN, 0x03 }, 1796 { DA7219_MIXIN_L_GAIN, 0x03 },
1782 { DA7219_ADC_L_GAIN, 0x6F }, 1797 { DA7219_ADC_L_GAIN, 0x6F },
@@ -1810,8 +1825,6 @@ static struct reg_default da7219_reg_defaults[] = {
1810 { DA7219_MIXOUT_R_CTRL, 0x10 }, 1825 { DA7219_MIXOUT_R_CTRL, 0x10 },
1811 { DA7219_CHIP_ID1, 0x23 }, 1826 { DA7219_CHIP_ID1, 0x23 },
1812 { DA7219_CHIP_ID2, 0x93 }, 1827 { DA7219_CHIP_ID2, 0x93 },
1813 { DA7219_CHIP_REVISION, 0x00 },
1814 { DA7219_LDO_CTRL, 0x00 },
1815 { DA7219_IO_CTRL, 0x00 }, 1828 { DA7219_IO_CTRL, 0x00 },
1816 { DA7219_GAIN_RAMP_CTRL, 0x00 }, 1829 { DA7219_GAIN_RAMP_CTRL, 0x00 },
1817 { DA7219_PC_COUNT, 0x02 }, 1830 { DA7219_PC_COUNT, 0x02 },
diff --git a/sound/soc/codecs/da7219.h b/sound/soc/codecs/da7219.h
index b514268c6c56..5a787e738084 100644
--- a/sound/soc/codecs/da7219.h
+++ b/sound/soc/codecs/da7219.h
@@ -85,7 +85,6 @@
85#define DA7219_CHIP_ID1 0x81 85#define DA7219_CHIP_ID1 0x81
86#define DA7219_CHIP_ID2 0x82 86#define DA7219_CHIP_ID2 0x82
87#define DA7219_CHIP_REVISION 0x83 87#define DA7219_CHIP_REVISION 0x83
88#define DA7219_LDO_CTRL 0x90
89#define DA7219_IO_CTRL 0x91 88#define DA7219_IO_CTRL 0x91
90#define DA7219_GAIN_RAMP_CTRL 0x92 89#define DA7219_GAIN_RAMP_CTRL 0x92
91#define DA7219_PC_COUNT 0x94 90#define DA7219_PC_COUNT 0x94
@@ -207,7 +206,6 @@
207#define DA7219_PLL_MODE_BYPASS (0x0 << 6) 206#define DA7219_PLL_MODE_BYPASS (0x0 << 6)
208#define DA7219_PLL_MODE_NORMAL (0x1 << 6) 207#define DA7219_PLL_MODE_NORMAL (0x1 << 6)
209#define DA7219_PLL_MODE_SRM (0x2 << 6) 208#define DA7219_PLL_MODE_SRM (0x2 << 6)
210#define DA7219_PLL_MODE_32KHZ (0x3 << 6)
211 209
212/* DA7219_PLL_FRAC_TOP = 0x22 */ 210/* DA7219_PLL_FRAC_TOP = 0x22 */
213#define DA7219_PLL_FBDIV_FRAC_TOP_SHIFT 0 211#define DA7219_PLL_FBDIV_FRAC_TOP_SHIFT 0
@@ -569,12 +567,6 @@
569#define DA7219_CHIP_MAJOR_SHIFT 4 567#define DA7219_CHIP_MAJOR_SHIFT 4
570#define DA7219_CHIP_MAJOR_MASK (0xF << 4) 568#define DA7219_CHIP_MAJOR_MASK (0xF << 4)
571 569
572/* DA7219_LDO_CTRL = 0x90 */
573#define DA7219_LDO_LEVEL_SELECT_SHIFT 4
574#define DA7219_LDO_LEVEL_SELECT_MASK (0x3 << 4)
575#define DA7219_LDO_EN_SHIFT 7
576#define DA7219_LDO_EN_MASK (0x1 << 7)
577
578/* DA7219_IO_CTRL = 0x91 */ 570/* DA7219_IO_CTRL = 0x91 */
579#define DA7219_IO_VOLTAGE_LEVEL_SHIFT 0 571#define DA7219_IO_VOLTAGE_LEVEL_SHIFT 0
580#define DA7219_IO_VOLTAGE_LEVEL_MASK (0x1 << 0) 572#define DA7219_IO_VOLTAGE_LEVEL_MASK (0x1 << 0)
@@ -787,7 +779,6 @@ enum da7219_sys_clk {
787 DA7219_SYSCLK_MCLK = 0, 779 DA7219_SYSCLK_MCLK = 0,
788 DA7219_SYSCLK_PLL, 780 DA7219_SYSCLK_PLL,
789 DA7219_SYSCLK_PLL_SRM, 781 DA7219_SYSCLK_PLL_SRM,
790 DA7219_SYSCLK_PLL_32KHZ
791}; 782};
792 783
793/* Regulators */ 784/* Regulators */
diff --git a/sound/soc/codecs/hdac_hdmi.c b/sound/soc/codecs/hdac_hdmi.c
new file mode 100644
index 000000000000..5a1ec0f7a1a6
--- /dev/null
+++ b/sound/soc/codecs/hdac_hdmi.c
@@ -0,0 +1,697 @@
1/*
2 * hdac_hdmi.c - ASoc HDA-HDMI codec driver for Intel platforms
3 *
4 * Copyright (C) 2014-2015 Intel Corp
5 * Author: Samreen Nilofer <samreen.nilofer@intel.com>
6 * Subhransu S. Prusty <subhransu.s.prusty@intel.com>
7 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; version 2 of the License.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 *
18 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
19 */
20#include <linux/init.h>
21#include <linux/delay.h>
22#include <linux/module.h>
23#include <linux/pm_runtime.h>
24#include <linux/hdmi.h>
25#include <sound/pcm_params.h>
26#include <sound/soc.h>
27#include <sound/hdaudio_ext.h>
28#include <sound/hda_i915.h>
29#include "../../hda/local.h"
30
31#define AMP_OUT_MUTE 0xb080
32#define AMP_OUT_UNMUTE 0xb000
33#define PIN_OUT (AC_PINCTL_OUT_EN)
34
35#define HDA_MAX_CONNECTIONS 32
36
37struct hdac_hdmi_cvt_params {
38 unsigned int channels_min;
39 unsigned int channels_max;
40 u32 rates;
41 u64 formats;
42 unsigned int maxbps;
43};
44
45struct hdac_hdmi_cvt {
46 struct list_head head;
47 hda_nid_t nid;
48 struct hdac_hdmi_cvt_params params;
49};
50
51struct hdac_hdmi_pin {
52 struct list_head head;
53 hda_nid_t nid;
54 int num_mux_nids;
55 hda_nid_t mux_nids[HDA_MAX_CONNECTIONS];
56};
57
58struct hdac_hdmi_dai_pin_map {
59 int dai_id;
60 struct hdac_hdmi_pin *pin;
61 struct hdac_hdmi_cvt *cvt;
62};
63
64struct hdac_hdmi_priv {
65 struct hdac_hdmi_dai_pin_map dai_map[3];
66 struct list_head pin_list;
67 struct list_head cvt_list;
68 int num_pin;
69 int num_cvt;
70};
71
72static inline struct hdac_ext_device *to_hda_ext_device(struct device *dev)
73{
74 struct hdac_device *hdac = dev_to_hdac_dev(dev);
75
76 return to_ehdac_device(hdac);
77}
78
79static int hdac_hdmi_setup_stream(struct hdac_ext_device *hdac,
80 hda_nid_t cvt_nid, hda_nid_t pin_nid,
81 u32 stream_tag, int format)
82{
83 unsigned int val;
84
85 dev_dbg(&hdac->hdac.dev, "cvt nid %d pnid %d stream %d format 0x%x\n",
86 cvt_nid, pin_nid, stream_tag, format);
87
88 val = (stream_tag << 4);
89
90 snd_hdac_codec_write(&hdac->hdac, cvt_nid, 0,
91 AC_VERB_SET_CHANNEL_STREAMID, val);
92 snd_hdac_codec_write(&hdac->hdac, cvt_nid, 0,
93 AC_VERB_SET_STREAM_FORMAT, format);
94
95 return 0;
96}
97
98static void
99hdac_hdmi_set_dip_index(struct hdac_ext_device *hdac, hda_nid_t pin_nid,
100 int packet_index, int byte_index)
101{
102 int val;
103
104 val = (packet_index << 5) | (byte_index & 0x1f);
105
106 snd_hdac_codec_write(&hdac->hdac, pin_nid, 0,
107 AC_VERB_SET_HDMI_DIP_INDEX, val);
108}
109
110static int hdac_hdmi_setup_audio_infoframe(struct hdac_ext_device *hdac,
111 hda_nid_t cvt_nid, hda_nid_t pin_nid)
112{
113 uint8_t buffer[HDMI_INFOFRAME_HEADER_SIZE + HDMI_AUDIO_INFOFRAME_SIZE];
114 struct hdmi_audio_infoframe frame;
115 u8 *dip = (u8 *)&frame;
116 int ret;
117 int i;
118
119 hdmi_audio_infoframe_init(&frame);
120
121 /* Default stereo for now */
122 frame.channels = 2;
123
124 /* setup channel count */
125 snd_hdac_codec_write(&hdac->hdac, cvt_nid, 0,
126 AC_VERB_SET_CVT_CHAN_COUNT, frame.channels - 1);
127
128 ret = hdmi_audio_infoframe_pack(&frame, buffer, sizeof(buffer));
129 if (ret < 0)
130 return ret;
131
132 /* stop infoframe transmission */
133 hdac_hdmi_set_dip_index(hdac, pin_nid, 0x0, 0x0);
134 snd_hdac_codec_write(&hdac->hdac, pin_nid, 0,
135 AC_VERB_SET_HDMI_DIP_XMIT, AC_DIPXMIT_DISABLE);
136
137
138 /* Fill infoframe. Index auto-incremented */
139 hdac_hdmi_set_dip_index(hdac, pin_nid, 0x0, 0x0);
140 for (i = 0; i < sizeof(frame); i++)
141 snd_hdac_codec_write(&hdac->hdac, pin_nid, 0,
142 AC_VERB_SET_HDMI_DIP_DATA, dip[i]);
143
144 /* Start infoframe */
145 hdac_hdmi_set_dip_index(hdac, pin_nid, 0x0, 0x0);
146 snd_hdac_codec_write(&hdac->hdac, pin_nid, 0,
147 AC_VERB_SET_HDMI_DIP_XMIT, AC_DIPXMIT_BEST);
148
149 return 0;
150}
151
152static void hdac_hdmi_set_power_state(struct hdac_ext_device *edev,
153 struct hdac_hdmi_dai_pin_map *dai_map, unsigned int pwr_state)
154{
155 /* Power up pin widget */
156 if (!snd_hdac_check_power_state(&edev->hdac, dai_map->pin->nid,
157 pwr_state))
158 snd_hdac_codec_write(&edev->hdac, dai_map->pin->nid, 0,
159 AC_VERB_SET_POWER_STATE, pwr_state);
160
161 /* Power up converter */
162 if (!snd_hdac_check_power_state(&edev->hdac, dai_map->cvt->nid,
163 pwr_state))
164 snd_hdac_codec_write(&edev->hdac, dai_map->cvt->nid, 0,
165 AC_VERB_SET_POWER_STATE, pwr_state);
166}
167
168static int hdac_hdmi_playback_prepare(struct snd_pcm_substream *substream,
169 struct snd_soc_dai *dai)
170{
171 struct hdac_ext_device *hdac = snd_soc_dai_get_drvdata(dai);
172 struct hdac_hdmi_priv *hdmi = hdac->private_data;
173 struct hdac_hdmi_dai_pin_map *dai_map;
174 struct hdac_ext_dma_params *dd;
175 int ret;
176
177 if (dai->id > 0) {
178 dev_err(&hdac->hdac.dev, "Only one dai supported as of now\n");
179 return -ENODEV;
180 }
181
182 dai_map = &hdmi->dai_map[dai->id];
183
184 dd = (struct hdac_ext_dma_params *)snd_soc_dai_get_dma_data(dai, substream);
185 dev_dbg(&hdac->hdac.dev, "stream tag from cpu dai %d format in cvt 0x%x\n",
186 dd->stream_tag, dd->format);
187
188 ret = hdac_hdmi_setup_audio_infoframe(hdac, dai_map->cvt->nid,
189 dai_map->pin->nid);
190 if (ret < 0)
191 return ret;
192
193 return hdac_hdmi_setup_stream(hdac, dai_map->cvt->nid,
194 dai_map->pin->nid, dd->stream_tag, dd->format);
195}
196
197static int hdac_hdmi_set_hw_params(struct snd_pcm_substream *substream,
198 struct snd_pcm_hw_params *hparams, struct snd_soc_dai *dai)
199{
200 struct hdac_ext_device *hdac = snd_soc_dai_get_drvdata(dai);
201 struct hdac_ext_dma_params *dd;
202
203 if (dai->id > 0) {
204 dev_err(&hdac->hdac.dev, "Only one dai supported as of now\n");
205 return -ENODEV;
206 }
207
208 dd = kzalloc(sizeof(*dd), GFP_KERNEL);
209 if (!dd)
210 return -ENOMEM;
211 dd->format = snd_hdac_calc_stream_format(params_rate(hparams),
212 params_channels(hparams), params_format(hparams),
213 24, 0);
214
215 snd_soc_dai_set_dma_data(dai, substream, (void *)dd);
216
217 return 0;
218}
219
220static int hdac_hdmi_playback_cleanup(struct snd_pcm_substream *substream,
221 struct snd_soc_dai *dai)
222{
223 struct hdac_ext_device *edev = snd_soc_dai_get_drvdata(dai);
224 struct hdac_ext_dma_params *dd;
225 struct hdac_hdmi_priv *hdmi = edev->private_data;
226 struct hdac_hdmi_dai_pin_map *dai_map;
227
228 dai_map = &hdmi->dai_map[dai->id];
229
230 snd_hdac_codec_write(&edev->hdac, dai_map->cvt->nid, 0,
231 AC_VERB_SET_CHANNEL_STREAMID, 0);
232 snd_hdac_codec_write(&edev->hdac, dai_map->cvt->nid, 0,
233 AC_VERB_SET_STREAM_FORMAT, 0);
234
235 dd = (struct hdac_ext_dma_params *)snd_soc_dai_get_dma_data(dai, substream);
236 snd_soc_dai_set_dma_data(dai, substream, NULL);
237
238 kfree(dd);
239
240 return 0;
241}
242
243static int hdac_hdmi_pcm_open(struct snd_pcm_substream *substream,
244 struct snd_soc_dai *dai)
245{
246 struct hdac_ext_device *hdac = snd_soc_dai_get_drvdata(dai);
247 struct hdac_hdmi_priv *hdmi = hdac->private_data;
248 struct hdac_hdmi_dai_pin_map *dai_map;
249 int val;
250
251 if (dai->id > 0) {
252 dev_err(&hdac->hdac.dev, "Only one dai supported as of now\n");
253 return -ENODEV;
254 }
255
256 dai_map = &hdmi->dai_map[dai->id];
257
258 val = snd_hdac_codec_read(&hdac->hdac, dai_map->pin->nid, 0,
259 AC_VERB_GET_PIN_SENSE, 0);
260 dev_info(&hdac->hdac.dev, "Val for AC_VERB_GET_PIN_SENSE: %x\n", val);
261
262 if ((!(val & AC_PINSENSE_PRESENCE)) || (!(val & AC_PINSENSE_ELDV))) {
263 dev_err(&hdac->hdac.dev, "Monitor presence invalid with val: %x\n", val);
264 return -ENODEV;
265 }
266
267 hdac_hdmi_set_power_state(hdac, dai_map, AC_PWRST_D0);
268
269 snd_hdac_codec_write(&hdac->hdac, dai_map->pin->nid, 0,
270 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE);
271
272 snd_pcm_hw_constraint_step(substream->runtime, 0,
273 SNDRV_PCM_HW_PARAM_CHANNELS, 2);
274
275 return 0;
276}
277
278static void hdac_hdmi_pcm_close(struct snd_pcm_substream *substream,
279 struct snd_soc_dai *dai)
280{
281 struct hdac_ext_device *hdac = snd_soc_dai_get_drvdata(dai);
282 struct hdac_hdmi_priv *hdmi = hdac->private_data;
283 struct hdac_hdmi_dai_pin_map *dai_map;
284
285 dai_map = &hdmi->dai_map[dai->id];
286
287 hdac_hdmi_set_power_state(hdac, dai_map, AC_PWRST_D3);
288
289 snd_hdac_codec_write(&hdac->hdac, dai_map->pin->nid, 0,
290 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
291}
292
293static int
294hdac_hdmi_query_cvt_params(struct hdac_device *hdac, struct hdac_hdmi_cvt *cvt)
295{
296 int err;
297
298 /* Only stereo supported as of now */
299 cvt->params.channels_min = cvt->params.channels_max = 2;
300
301 err = snd_hdac_query_supported_pcm(hdac, cvt->nid,
302 &cvt->params.rates,
303 &cvt->params.formats,
304 &cvt->params.maxbps);
305 if (err < 0)
306 dev_err(&hdac->dev,
307 "Failed to query pcm params for nid %d: %d\n",
308 cvt->nid, err);
309
310 return err;
311}
312
313static void hdac_hdmi_fill_widget_info(struct snd_soc_dapm_widget *w,
314 enum snd_soc_dapm_type id,
315 const char *wname, const char *stream)
316{
317 w->id = id;
318 w->name = wname;
319 w->sname = stream;
320 w->reg = SND_SOC_NOPM;
321 w->shift = 0;
322 w->kcontrol_news = NULL;
323 w->num_kcontrols = 0;
324 w->priv = NULL;
325}
326
327static void hdac_hdmi_fill_route(struct snd_soc_dapm_route *route,
328 const char *sink, const char *control, const char *src)
329{
330 route->sink = sink;
331 route->source = src;
332 route->control = control;
333 route->connected = NULL;
334}
335
336static void create_fill_widget_route_map(struct snd_soc_dapm_context *dapm,
337 struct hdac_hdmi_dai_pin_map *dai_map)
338{
339 struct snd_soc_dapm_route route[1];
340 struct snd_soc_dapm_widget widgets[2] = { {0} };
341
342 memset(&route, 0, sizeof(route));
343
344 hdac_hdmi_fill_widget_info(&widgets[0], snd_soc_dapm_output,
345 "hif1 Output", NULL);
346 hdac_hdmi_fill_widget_info(&widgets[1], snd_soc_dapm_aif_in,
347 "Coverter 1", "hif1");
348
349 hdac_hdmi_fill_route(&route[0], "hif1 Output", NULL, "Coverter 1");
350
351 snd_soc_dapm_new_controls(dapm, widgets, ARRAY_SIZE(widgets));
352 snd_soc_dapm_add_routes(dapm, route, ARRAY_SIZE(route));
353}
354
355static int hdac_hdmi_init_dai_map(struct hdac_ext_device *edev)
356{
357 struct hdac_hdmi_priv *hdmi = edev->private_data;
358 struct hdac_hdmi_dai_pin_map *dai_map = &hdmi->dai_map[0];
359 struct hdac_hdmi_cvt *cvt;
360 struct hdac_hdmi_pin *pin;
361
362 if (list_empty(&hdmi->cvt_list) || list_empty(&hdmi->pin_list))
363 return -EINVAL;
364
365 /*
366 * Currently on board only 1 pin and 1 converter is enabled for
367 * simplification, more will be added eventually
368 * So using fixed map for dai_id:pin:cvt
369 */
370 cvt = list_first_entry(&hdmi->cvt_list, struct hdac_hdmi_cvt, head);
371 pin = list_first_entry(&hdmi->pin_list, struct hdac_hdmi_pin, head);
372
373 dai_map->dai_id = 0;
374 dai_map->pin = pin;
375
376 dai_map->cvt = cvt;
377
378 /* Enable out path for this pin widget */
379 snd_hdac_codec_write(&edev->hdac, pin->nid, 0,
380 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
381
382 /* Enable transmission */
383 snd_hdac_codec_write(&edev->hdac, cvt->nid, 0,
384 AC_VERB_SET_DIGI_CONVERT_1, 1);
385
386 /* Category Code (CC) to zero */
387 snd_hdac_codec_write(&edev->hdac, cvt->nid, 0,
388 AC_VERB_SET_DIGI_CONVERT_2, 0);
389
390 snd_hdac_codec_write(&edev->hdac, pin->nid, 0,
391 AC_VERB_SET_CONNECT_SEL, 0);
392
393 return 0;
394}
395
396static int hdac_hdmi_add_cvt(struct hdac_ext_device *edev, hda_nid_t nid)
397{
398 struct hdac_hdmi_priv *hdmi = edev->private_data;
399 struct hdac_hdmi_cvt *cvt;
400
401 cvt = kzalloc(sizeof(*cvt), GFP_KERNEL);
402 if (!cvt)
403 return -ENOMEM;
404
405 cvt->nid = nid;
406
407 list_add_tail(&cvt->head, &hdmi->cvt_list);
408 hdmi->num_cvt++;
409
410 return hdac_hdmi_query_cvt_params(&edev->hdac, cvt);
411}
412
413static int hdac_hdmi_add_pin(struct hdac_ext_device *edev, hda_nid_t nid)
414{
415 struct hdac_hdmi_priv *hdmi = edev->private_data;
416 struct hdac_hdmi_pin *pin;
417
418 pin = kzalloc(sizeof(*pin), GFP_KERNEL);
419 if (!pin)
420 return -ENOMEM;
421
422 pin->nid = nid;
423
424 list_add_tail(&pin->head, &hdmi->pin_list);
425 hdmi->num_pin++;
426
427 return 0;
428}
429
430/*
431 * Parse all nodes and store the cvt/pin nids in array
432 * Add one time initialization for pin and cvt widgets
433 */
434static int hdac_hdmi_parse_and_map_nid(struct hdac_ext_device *edev)
435{
436 hda_nid_t nid;
437 int i, num_nodes;
438 struct hdac_device *hdac = &edev->hdac;
439 struct hdac_hdmi_priv *hdmi = edev->private_data;
440 int ret;
441
442 num_nodes = snd_hdac_get_sub_nodes(hdac, hdac->afg, &nid);
443 if (!nid || num_nodes <= 0) {
444 dev_warn(&hdac->dev, "HDMI: failed to get afg sub nodes\n");
445 return -EINVAL;
446 }
447
448 hdac->num_nodes = num_nodes;
449 hdac->start_nid = nid;
450
451 for (i = 0; i < hdac->num_nodes; i++, nid++) {
452 unsigned int caps;
453 unsigned int type;
454
455 caps = get_wcaps(hdac, nid);
456 type = get_wcaps_type(caps);
457
458 if (!(caps & AC_WCAP_DIGITAL))
459 continue;
460
461 switch (type) {
462
463 case AC_WID_AUD_OUT:
464 ret = hdac_hdmi_add_cvt(edev, nid);
465 if (ret < 0)
466 return ret;
467 break;
468
469 case AC_WID_PIN:
470 ret = hdac_hdmi_add_pin(edev, nid);
471 if (ret < 0)
472 return ret;
473 break;
474 }
475 }
476
477 hdac->end_nid = nid;
478
479 if (!hdmi->num_pin || !hdmi->num_cvt)
480 return -EIO;
481
482 return hdac_hdmi_init_dai_map(edev);
483}
484
485static int hdmi_codec_probe(struct snd_soc_codec *codec)
486{
487 struct hdac_ext_device *edev = snd_soc_codec_get_drvdata(codec);
488 struct hdac_hdmi_priv *hdmi = edev->private_data;
489 struct snd_soc_dapm_context *dapm =
490 snd_soc_component_get_dapm(&codec->component);
491
492 edev->scodec = codec;
493
494 create_fill_widget_route_map(dapm, &hdmi->dai_map[0]);
495
496 /* Imp: Store the card pointer in hda_codec */
497 edev->card = dapm->card->snd_card;
498
499 /*
500 * hdac_device core already sets the state to active and calls
501 * get_noresume. So enable runtime and set the device to suspend.
502 */
503 pm_runtime_enable(&edev->hdac.dev);
504 pm_runtime_put(&edev->hdac.dev);
505 pm_runtime_suspend(&edev->hdac.dev);
506
507 return 0;
508}
509
510static int hdmi_codec_remove(struct snd_soc_codec *codec)
511{
512 struct hdac_ext_device *edev = snd_soc_codec_get_drvdata(codec);
513
514 pm_runtime_disable(&edev->hdac.dev);
515 return 0;
516}
517
518static struct snd_soc_codec_driver hdmi_hda_codec = {
519 .probe = hdmi_codec_probe,
520 .remove = hdmi_codec_remove,
521 .idle_bias_off = true,
522};
523
524static struct snd_soc_dai_ops hdmi_dai_ops = {
525 .startup = hdac_hdmi_pcm_open,
526 .shutdown = hdac_hdmi_pcm_close,
527 .hw_params = hdac_hdmi_set_hw_params,
528 .prepare = hdac_hdmi_playback_prepare,
529 .hw_free = hdac_hdmi_playback_cleanup,
530};
531
532static struct snd_soc_dai_driver hdmi_dais[] = {
533 { .name = "intel-hdmi-hif1",
534 .playback = {
535 .stream_name = "hif1",
536 .channels_min = 2,
537 .channels_max = 2,
538 .rates = SNDRV_PCM_RATE_32000 |
539 SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 |
540 SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000 |
541 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_192000,
542 .formats = SNDRV_PCM_FMTBIT_S16_LE |
543 SNDRV_PCM_FMTBIT_S20_3LE |
544 SNDRV_PCM_FMTBIT_S24_LE |
545 SNDRV_PCM_FMTBIT_S32_LE,
546
547 },
548 .ops = &hdmi_dai_ops,
549 },
550};
551
552static int hdac_hdmi_dev_probe(struct hdac_ext_device *edev)
553{
554 struct hdac_device *codec = &edev->hdac;
555 struct hdac_hdmi_priv *hdmi_priv;
556 int ret = 0;
557
558 hdmi_priv = devm_kzalloc(&codec->dev, sizeof(*hdmi_priv), GFP_KERNEL);
559 if (hdmi_priv == NULL)
560 return -ENOMEM;
561
562 edev->private_data = hdmi_priv;
563
564 dev_set_drvdata(&codec->dev, edev);
565
566 INIT_LIST_HEAD(&hdmi_priv->pin_list);
567 INIT_LIST_HEAD(&hdmi_priv->cvt_list);
568
569 ret = hdac_hdmi_parse_and_map_nid(edev);
570 if (ret < 0)
571 return ret;
572
573 /* ASoC specific initialization */
574 return snd_soc_register_codec(&codec->dev, &hdmi_hda_codec,
575 hdmi_dais, ARRAY_SIZE(hdmi_dais));
576}
577
578static int hdac_hdmi_dev_remove(struct hdac_ext_device *edev)
579{
580 struct hdac_hdmi_priv *hdmi = edev->private_data;
581 struct hdac_hdmi_pin *pin, *pin_next;
582 struct hdac_hdmi_cvt *cvt, *cvt_next;
583
584 snd_soc_unregister_codec(&edev->hdac.dev);
585
586 list_for_each_entry_safe(cvt, cvt_next, &hdmi->cvt_list, head) {
587 list_del(&cvt->head);
588 kfree(cvt);
589 }
590
591 list_for_each_entry_safe(pin, pin_next, &hdmi->pin_list, head) {
592 list_del(&pin->head);
593 kfree(pin);
594 }
595
596 return 0;
597}
598
599#ifdef CONFIG_PM
600static int hdac_hdmi_runtime_suspend(struct device *dev)
601{
602 struct hdac_ext_device *edev = to_hda_ext_device(dev);
603 struct hdac_device *hdac = &edev->hdac;
604 struct hdac_bus *bus = hdac->bus;
605 int err;
606
607 dev_dbg(dev, "Enter: %s\n", __func__);
608
609 /* controller may not have been initialized for the first time */
610 if (!bus)
611 return 0;
612
613 /* Power down afg */
614 if (!snd_hdac_check_power_state(hdac, hdac->afg, AC_PWRST_D3))
615 snd_hdac_codec_write(hdac, hdac->afg, 0,
616 AC_VERB_SET_POWER_STATE, AC_PWRST_D3);
617
618 err = snd_hdac_display_power(bus, false);
619 if (err < 0) {
620 dev_err(bus->dev, "Cannot turn on display power on i915\n");
621 return err;
622 }
623
624 return 0;
625}
626
627static int hdac_hdmi_runtime_resume(struct device *dev)
628{
629 struct hdac_ext_device *edev = to_hda_ext_device(dev);
630 struct hdac_device *hdac = &edev->hdac;
631 struct hdac_bus *bus = hdac->bus;
632 int err;
633
634 dev_dbg(dev, "Enter: %s\n", __func__);
635
636 /* controller may not have been initialized for the first time */
637 if (!bus)
638 return 0;
639
640 err = snd_hdac_display_power(bus, true);
641 if (err < 0) {
642 dev_err(bus->dev, "Cannot turn on display power on i915\n");
643 return err;
644 }
645
646 /* Power up afg */
647 if (!snd_hdac_check_power_state(hdac, hdac->afg, AC_PWRST_D0))
648 snd_hdac_codec_write(hdac, hdac->afg, 0,
649 AC_VERB_SET_POWER_STATE, AC_PWRST_D0);
650
651 return 0;
652}
653#else
654#define hdac_hdmi_runtime_suspend NULL
655#define hdac_hdmi_runtime_resume NULL
656#endif
657
658static const struct dev_pm_ops hdac_hdmi_pm = {
659 SET_RUNTIME_PM_OPS(hdac_hdmi_runtime_suspend, hdac_hdmi_runtime_resume, NULL)
660};
661
662static const struct hda_device_id hdmi_list[] = {
663 HDA_CODEC_EXT_ENTRY(0x80862809, 0x100000, "Skylake HDMI", 0),
664 {}
665};
666
667MODULE_DEVICE_TABLE(hdaudio, hdmi_list);
668
669static struct hdac_ext_driver hdmi_driver = {
670 . hdac = {
671 .driver = {
672 .name = "HDMI HDA Codec",
673 .pm = &hdac_hdmi_pm,
674 },
675 .id_table = hdmi_list,
676 },
677 .probe = hdac_hdmi_dev_probe,
678 .remove = hdac_hdmi_dev_remove,
679};
680
681static int __init hdmi_init(void)
682{
683 return snd_hda_ext_driver_register(&hdmi_driver);
684}
685
686static void __exit hdmi_exit(void)
687{
688 snd_hda_ext_driver_unregister(&hdmi_driver);
689}
690
691module_init(hdmi_init);
692module_exit(hdmi_exit);
693
694MODULE_LICENSE("GPL v2");
695MODULE_DESCRIPTION("HDMI HD codec");
696MODULE_AUTHOR("Samreen Nilofer<samreen.nilofer@intel.com>");
697MODULE_AUTHOR("Subhransu S. Prusty<subhransu.s.prusty@intel.com>");
diff --git a/sound/soc/codecs/inno_rk3036.c b/sound/soc/codecs/inno_rk3036.c
new file mode 100644
index 000000000000..9b6e8840a1b5
--- /dev/null
+++ b/sound/soc/codecs/inno_rk3036.c
@@ -0,0 +1,490 @@
1/*
2 * Driver of Inno codec for rk3036 by Rockchip Inc.
3 *
4 * Author: Rockchip Inc.
5 * Author: Zheng ShunQian<zhengsq@rock-chips.com>
6 */
7
8#include <sound/soc.h>
9#include <sound/tlv.h>
10#include <sound/soc-dapm.h>
11#include <sound/soc-dai.h>
12#include <sound/pcm.h>
13#include <sound/pcm_params.h>
14
15#include <linux/platform_device.h>
16#include <linux/of.h>
17#include <linux/clk.h>
18#include <linux/regmap.h>
19#include <linux/device.h>
20#include <linux/mfd/syscon.h>
21#include <linux/module.h>
22#include <linux/io.h>
23
24#include "inno_rk3036.h"
25
26struct rk3036_codec_priv {
27 void __iomem *base;
28 struct clk *pclk;
29 struct regmap *regmap;
30 struct device *dev;
31};
32
33static const DECLARE_TLV_DB_MINMAX(rk3036_codec_hp_tlv, -39, 0);
34
35static int rk3036_codec_antipop_info(struct snd_kcontrol *kcontrol,
36 struct snd_ctl_elem_info *uinfo)
37{
38 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
39 uinfo->count = 2;
40 uinfo->value.integer.min = 0;
41 uinfo->value.integer.max = 1;
42
43 return 0;
44}
45
46static int rk3036_codec_antipop_get(struct snd_kcontrol *kcontrol,
47 struct snd_ctl_elem_value *ucontrol)
48{
49 struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
50 int val, ret, regval;
51
52 ret = snd_soc_component_read(component, INNO_R09, &regval);
53 if (ret)
54 return ret;
55 val = ((regval >> INNO_R09_HPL_ANITPOP_SHIFT) &
56 INNO_R09_HP_ANTIPOP_MSK) == INNO_R09_HP_ANTIPOP_ON;
57 ucontrol->value.integer.value[0] = val;
58
59 val = ((regval >> INNO_R09_HPR_ANITPOP_SHIFT) &
60 INNO_R09_HP_ANTIPOP_MSK) == INNO_R09_HP_ANTIPOP_ON;
61 ucontrol->value.integer.value[1] = val;
62
63 return 0;
64}
65
66static int rk3036_codec_antipop_put(struct snd_kcontrol *kcontrol,
67 struct snd_ctl_elem_value *ucontrol)
68{
69 struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
70 int val, ret, regmsk;
71
72 val = (ucontrol->value.integer.value[0] ?
73 INNO_R09_HP_ANTIPOP_ON : INNO_R09_HP_ANTIPOP_OFF) <<
74 INNO_R09_HPL_ANITPOP_SHIFT;
75 val |= (ucontrol->value.integer.value[1] ?
76 INNO_R09_HP_ANTIPOP_ON : INNO_R09_HP_ANTIPOP_OFF) <<
77 INNO_R09_HPR_ANITPOP_SHIFT;
78
79 regmsk = INNO_R09_HP_ANTIPOP_MSK << INNO_R09_HPL_ANITPOP_SHIFT |
80 INNO_R09_HP_ANTIPOP_MSK << INNO_R09_HPR_ANITPOP_SHIFT;
81
82 ret = snd_soc_component_update_bits(component, INNO_R09,
83 regmsk, val);
84 if (ret < 0)
85 return ret;
86
87 return 0;
88}
89
90#define SOC_RK3036_CODEC_ANTIPOP_DECL(xname) \
91{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
92 .info = rk3036_codec_antipop_info, .get = rk3036_codec_antipop_get, \
93 .put = rk3036_codec_antipop_put, }
94
95static const struct snd_kcontrol_new rk3036_codec_dapm_controls[] = {
96 SOC_DOUBLE_R_RANGE_TLV("Headphone Volume", INNO_R07, INNO_R08,
97 INNO_HP_GAIN_SHIFT, INNO_HP_GAIN_N39DB,
98 INNO_HP_GAIN_0DB, 0, rk3036_codec_hp_tlv),
99 SOC_DOUBLE("Zero Cross Switch", INNO_R06, INNO_R06_VOUTL_CZ_SHIFT,
100 INNO_R06_VOUTR_CZ_SHIFT, 1, 0),
101 SOC_DOUBLE("Headphone Switch", INNO_R09, INNO_R09_HPL_MUTE_SHIFT,
102 INNO_R09_HPR_MUTE_SHIFT, 1, 0),
103 SOC_RK3036_CODEC_ANTIPOP_DECL("Anti-pop Switch"),
104};
105
106static const struct snd_kcontrol_new rk3036_codec_hpl_mixer_controls[] = {
107 SOC_DAPM_SINGLE("DAC Left Out Switch", INNO_R09,
108 INNO_R09_DACL_SWITCH_SHIFT, 1, 0),
109};
110
111static const struct snd_kcontrol_new rk3036_codec_hpr_mixer_controls[] = {
112 SOC_DAPM_SINGLE("DAC Right Out Switch", INNO_R09,
113 INNO_R09_DACR_SWITCH_SHIFT, 1, 0),
114};
115
116static const struct snd_kcontrol_new rk3036_codec_hpl_switch_controls[] = {
117 SOC_DAPM_SINGLE("HP Left Out Switch", INNO_R05,
118 INNO_R05_HPL_WORK_SHIFT, 1, 0),
119};
120
121static const struct snd_kcontrol_new rk3036_codec_hpr_switch_controls[] = {
122 SOC_DAPM_SINGLE("HP Right Out Switch", INNO_R05,
123 INNO_R05_HPR_WORK_SHIFT, 1, 0),
124};
125
126static const struct snd_soc_dapm_widget rk3036_codec_dapm_widgets[] = {
127 SND_SOC_DAPM_SUPPLY_S("DAC PWR", 1, INNO_R06,
128 INNO_R06_DAC_EN_SHIFT, 0, NULL, 0),
129 SND_SOC_DAPM_SUPPLY_S("DACL VREF", 2, INNO_R04,
130 INNO_R04_DACL_VREF_SHIFT, 0, NULL, 0),
131 SND_SOC_DAPM_SUPPLY_S("DACR VREF", 2, INNO_R04,
132 INNO_R04_DACR_VREF_SHIFT, 0, NULL, 0),
133 SND_SOC_DAPM_SUPPLY_S("DACL HiLo VREF", 3, INNO_R06,
134 INNO_R06_DACL_HILO_VREF_SHIFT, 0, NULL, 0),
135 SND_SOC_DAPM_SUPPLY_S("DACR HiLo VREF", 3, INNO_R06,
136 INNO_R06_DACR_HILO_VREF_SHIFT, 0, NULL, 0),
137 SND_SOC_DAPM_SUPPLY_S("DACR CLK", 3, INNO_R04,
138 INNO_R04_DACR_CLK_SHIFT, 0, NULL, 0),
139 SND_SOC_DAPM_SUPPLY_S("DACL CLK", 3, INNO_R04,
140 INNO_R04_DACL_CLK_SHIFT, 0, NULL, 0),
141
142 SND_SOC_DAPM_DAC("DACL", "Left Playback", INNO_R04,
143 INNO_R04_DACL_SW_SHIFT, 0),
144 SND_SOC_DAPM_DAC("DACR", "Right Playback", INNO_R04,
145 INNO_R04_DACR_SW_SHIFT, 0),
146
147 SND_SOC_DAPM_MIXER("Left Headphone Mixer", SND_SOC_NOPM, 0, 0,
148 rk3036_codec_hpl_mixer_controls,
149 ARRAY_SIZE(rk3036_codec_hpl_mixer_controls)),
150 SND_SOC_DAPM_MIXER("Right Headphone Mixer", SND_SOC_NOPM, 0, 0,
151 rk3036_codec_hpr_mixer_controls,
152 ARRAY_SIZE(rk3036_codec_hpr_mixer_controls)),
153
154 SND_SOC_DAPM_PGA("HP Left Out", INNO_R05,
155 INNO_R05_HPL_EN_SHIFT, 0, NULL, 0),
156 SND_SOC_DAPM_PGA("HP Right Out", INNO_R05,
157 INNO_R05_HPR_EN_SHIFT, 0, NULL, 0),
158
159 SND_SOC_DAPM_MIXER("HP Left Switch", SND_SOC_NOPM, 0, 0,
160 rk3036_codec_hpl_switch_controls,
161 ARRAY_SIZE(rk3036_codec_hpl_switch_controls)),
162 SND_SOC_DAPM_MIXER("HP Right Switch", SND_SOC_NOPM, 0, 0,
163 rk3036_codec_hpr_switch_controls,
164 ARRAY_SIZE(rk3036_codec_hpr_switch_controls)),
165
166 SND_SOC_DAPM_OUTPUT("HPL"),
167 SND_SOC_DAPM_OUTPUT("HPR"),
168};
169
170static const struct snd_soc_dapm_route rk3036_codec_dapm_routes[] = {
171 {"DACL VREF", NULL, "DAC PWR"},
172 {"DACR VREF", NULL, "DAC PWR"},
173 {"DACL HiLo VREF", NULL, "DAC PWR"},
174 {"DACR HiLo VREF", NULL, "DAC PWR"},
175 {"DACL CLK", NULL, "DAC PWR"},
176 {"DACR CLK", NULL, "DAC PWR"},
177
178 {"DACL", NULL, "DACL VREF"},
179 {"DACL", NULL, "DACL HiLo VREF"},
180 {"DACL", NULL, "DACL CLK"},
181 {"DACR", NULL, "DACR VREF"},
182 {"DACR", NULL, "DACR HiLo VREF"},
183 {"DACR", NULL, "DACR CLK"},
184
185 {"Left Headphone Mixer", "DAC Left Out Switch", "DACL"},
186 {"Right Headphone Mixer", "DAC Right Out Switch", "DACR"},
187 {"HP Left Out", NULL, "Left Headphone Mixer"},
188 {"HP Right Out", NULL, "Right Headphone Mixer"},
189
190 {"HP Left Switch", "HP Left Out Switch", "HP Left Out"},
191 {"HP Right Switch", "HP Right Out Switch", "HP Right Out"},
192
193 {"HPL", NULL, "HP Left Switch"},
194 {"HPR", NULL, "HP Right Switch"},
195};
196
197static int rk3036_codec_dai_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
198{
199 struct snd_soc_codec *codec = dai->codec;
200 unsigned int reg01_val = 0, reg02_val = 0, reg03_val = 0;
201
202 dev_dbg(codec->dev, "rk3036_codec dai set fmt : %08x\n", fmt);
203
204 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
205 case SND_SOC_DAIFMT_CBS_CFS:
206 reg01_val |= INNO_R01_PINDIR_IN_SLAVE |
207 INNO_R01_I2SMODE_SLAVE;
208 break;
209 case SND_SOC_DAIFMT_CBM_CFM:
210 reg01_val |= INNO_R01_PINDIR_OUT_MASTER |
211 INNO_R01_I2SMODE_MASTER;
212 break;
213 default:
214 dev_err(codec->dev, "invalid fmt\n");
215 return -EINVAL;
216 }
217
218 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
219 case SND_SOC_DAIFMT_DSP_A:
220 reg02_val |= INNO_R02_DACM_PCM;
221 break;
222 case SND_SOC_DAIFMT_I2S:
223 reg02_val |= INNO_R02_DACM_I2S;
224 break;
225 case SND_SOC_DAIFMT_RIGHT_J:
226 reg02_val |= INNO_R02_DACM_RJM;
227 break;
228 case SND_SOC_DAIFMT_LEFT_J:
229 reg02_val |= INNO_R02_DACM_LJM;
230 break;
231 default:
232 dev_err(codec->dev, "set dai format failed\n");
233 return -EINVAL;
234 }
235
236 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
237 case SND_SOC_DAIFMT_NB_NF:
238 reg02_val |= INNO_R02_LRCP_NORMAL;
239 reg03_val |= INNO_R03_BCP_NORMAL;
240 break;
241 case SND_SOC_DAIFMT_IB_IF:
242 reg02_val |= INNO_R02_LRCP_REVERSAL;
243 reg03_val |= INNO_R03_BCP_REVERSAL;
244 break;
245 case SND_SOC_DAIFMT_IB_NF:
246 reg02_val |= INNO_R02_LRCP_REVERSAL;
247 reg03_val |= INNO_R03_BCP_NORMAL;
248 break;
249 case SND_SOC_DAIFMT_NB_IF:
250 reg02_val |= INNO_R02_LRCP_NORMAL;
251 reg03_val |= INNO_R03_BCP_REVERSAL;
252 break;
253 default:
254 dev_err(codec->dev, "set dai format failed\n");
255 return -EINVAL;
256 }
257
258 snd_soc_update_bits(codec, INNO_R01, INNO_R01_I2SMODE_MSK |
259 INNO_R01_PINDIR_MSK, reg01_val);
260 snd_soc_update_bits(codec, INNO_R02, INNO_R02_LRCP_MSK |
261 INNO_R02_DACM_MSK, reg02_val);
262 snd_soc_update_bits(codec, INNO_R03, INNO_R03_BCP_MSK, reg03_val);
263
264 return 0;
265}
266
267static int rk3036_codec_dai_hw_params(struct snd_pcm_substream *substream,
268 struct snd_pcm_hw_params *hw_params,
269 struct snd_soc_dai *dai)
270{
271 struct snd_soc_codec *codec = dai->codec;
272 unsigned int reg02_val = 0, reg03_val = 0;
273
274 switch (params_format(hw_params)) {
275 case SNDRV_PCM_FORMAT_S16_LE:
276 reg02_val |= INNO_R02_VWL_16BIT;
277 break;
278 case SNDRV_PCM_FORMAT_S20_3LE:
279 reg02_val |= INNO_R02_VWL_20BIT;
280 break;
281 case SNDRV_PCM_FORMAT_S24_LE:
282 reg02_val |= INNO_R02_VWL_24BIT;
283 break;
284 case SNDRV_PCM_FORMAT_S32_LE:
285 reg02_val |= INNO_R02_VWL_32BIT;
286 break;
287 default:
288 return -EINVAL;
289 }
290
291 reg02_val |= INNO_R02_LRCP_NORMAL;
292 reg03_val |= INNO_R03_FWL_32BIT | INNO_R03_DACR_WORK;
293
294 snd_soc_update_bits(codec, INNO_R02, INNO_R02_LRCP_MSK |
295 INNO_R02_VWL_MSK, reg02_val);
296 snd_soc_update_bits(codec, INNO_R03, INNO_R03_DACR_MSK |
297 INNO_R03_FWL_MSK, reg03_val);
298 return 0;
299}
300
301#define RK3036_CODEC_RATES (SNDRV_PCM_RATE_8000 | \
302 SNDRV_PCM_RATE_16000 | \
303 SNDRV_PCM_RATE_32000 | \
304 SNDRV_PCM_RATE_44100 | \
305 SNDRV_PCM_RATE_48000 | \
306 SNDRV_PCM_RATE_96000)
307
308#define RK3036_CODEC_FMTS (SNDRV_PCM_FMTBIT_S16_LE | \
309 SNDRV_PCM_FMTBIT_S20_3LE | \
310 SNDRV_PCM_FMTBIT_S24_LE | \
311 SNDRV_PCM_FMTBIT_S32_LE)
312
313static struct snd_soc_dai_ops rk3036_codec_dai_ops = {
314 .set_fmt = rk3036_codec_dai_set_fmt,
315 .hw_params = rk3036_codec_dai_hw_params,
316};
317
318static struct snd_soc_dai_driver rk3036_codec_dai_driver[] = {
319 {
320 .name = "rk3036-codec-dai",
321 .playback = {
322 .stream_name = "Playback",
323 .channels_min = 1,
324 .channels_max = 2,
325 .rates = RK3036_CODEC_RATES,
326 .formats = RK3036_CODEC_FMTS,
327 },
328 .ops = &rk3036_codec_dai_ops,
329 .symmetric_rates = 1,
330 },
331};
332
333static void rk3036_codec_reset(struct snd_soc_codec *codec)
334{
335 snd_soc_write(codec, INNO_R00,
336 INNO_R00_CSR_RESET | INNO_R00_CDCR_RESET);
337 snd_soc_write(codec, INNO_R00,
338 INNO_R00_CSR_WORK | INNO_R00_CDCR_WORK);
339}
340
341static int rk3036_codec_probe(struct snd_soc_codec *codec)
342{
343 rk3036_codec_reset(codec);
344 return 0;
345}
346
347static int rk3036_codec_remove(struct snd_soc_codec *codec)
348{
349 rk3036_codec_reset(codec);
350 return 0;
351}
352
353static int rk3036_codec_set_bias_level(struct snd_soc_codec *codec,
354 enum snd_soc_bias_level level)
355{
356 switch (level) {
357 case SND_SOC_BIAS_STANDBY:
358 /* set a big current for capacitor charging. */
359 snd_soc_write(codec, INNO_R10, INNO_R10_MAX_CUR);
360 /* start precharge */
361 snd_soc_write(codec, INNO_R06, INNO_R06_DAC_PRECHARGE);
362
363 break;
364
365 case SND_SOC_BIAS_OFF:
366 /* set a big current for capacitor discharging. */
367 snd_soc_write(codec, INNO_R10, INNO_R10_MAX_CUR);
368 /* start discharge. */
369 snd_soc_write(codec, INNO_R06, INNO_R06_DAC_DISCHARGE);
370
371 break;
372 default:
373 break;
374 }
375
376 return 0;
377}
378
379static struct snd_soc_codec_driver rk3036_codec_driver = {
380 .probe = rk3036_codec_probe,
381 .remove = rk3036_codec_remove,
382 .set_bias_level = rk3036_codec_set_bias_level,
383 .controls = rk3036_codec_dapm_controls,
384 .num_controls = ARRAY_SIZE(rk3036_codec_dapm_controls),
385 .dapm_routes = rk3036_codec_dapm_routes,
386 .num_dapm_routes = ARRAY_SIZE(rk3036_codec_dapm_routes),
387 .dapm_widgets = rk3036_codec_dapm_widgets,
388 .num_dapm_widgets = ARRAY_SIZE(rk3036_codec_dapm_widgets),
389};
390
391static const struct regmap_config rk3036_codec_regmap_config = {
392 .reg_bits = 32,
393 .reg_stride = 4,
394 .val_bits = 32,
395};
396
397#define GRF_SOC_CON0 0x00140
398#define GRF_ACODEC_SEL (BIT(10) | BIT(16 + 10))
399
400static int rk3036_codec_platform_probe(struct platform_device *pdev)
401{
402 struct rk3036_codec_priv *priv;
403 struct device_node *of_node = pdev->dev.of_node;
404 struct resource *res;
405 void __iomem *base;
406 struct regmap *grf;
407 int ret;
408
409 priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
410 if (!priv)
411 return -ENOMEM;
412
413 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
414 base = devm_ioremap_resource(&pdev->dev, res);
415 if (IS_ERR(base))
416 return PTR_ERR(base);
417
418 priv->base = base;
419 priv->regmap = devm_regmap_init_mmio(&pdev->dev, priv->base,
420 &rk3036_codec_regmap_config);
421 if (IS_ERR(priv->regmap)) {
422 dev_err(&pdev->dev, "init regmap failed\n");
423 return PTR_ERR(priv->regmap);
424 }
425
426 grf = syscon_regmap_lookup_by_phandle(of_node, "rockchip,grf");
427 if (IS_ERR(grf)) {
428 dev_err(&pdev->dev, "needs 'rockchip,grf' property\n");
429 return PTR_ERR(grf);
430 }
431 ret = regmap_write(grf, GRF_SOC_CON0, GRF_ACODEC_SEL);
432 if (ret) {
433 dev_err(&pdev->dev, "Could not write to GRF: %d\n", ret);
434 return ret;
435 }
436
437 priv->pclk = devm_clk_get(&pdev->dev, "acodec_pclk");
438 if (IS_ERR(priv->pclk))
439 return PTR_ERR(priv->pclk);
440
441 ret = clk_prepare_enable(priv->pclk);
442 if (ret < 0) {
443 dev_err(&pdev->dev, "failed to enable clk\n");
444 return ret;
445 }
446
447 priv->dev = &pdev->dev;
448 dev_set_drvdata(&pdev->dev, priv);
449
450 ret = snd_soc_register_codec(&pdev->dev, &rk3036_codec_driver,
451 rk3036_codec_dai_driver,
452 ARRAY_SIZE(rk3036_codec_dai_driver));
453 if (ret) {
454 clk_disable_unprepare(priv->pclk);
455 dev_set_drvdata(&pdev->dev, NULL);
456 }
457
458 return ret;
459}
460
461static int rk3036_codec_platform_remove(struct platform_device *pdev)
462{
463 struct rk3036_codec_priv *priv = dev_get_drvdata(&pdev->dev);
464
465 snd_soc_unregister_codec(&pdev->dev);
466 clk_disable_unprepare(priv->pclk);
467
468 return 0;
469}
470
471static const struct of_device_id rk3036_codec_of_match[] = {
472 { .compatible = "rockchip,rk3036-codec", },
473 {}
474};
475MODULE_DEVICE_TABLE(of, rk3036_codec_of_match);
476
477static struct platform_driver rk3036_codec_platform_driver = {
478 .driver = {
479 .name = "rk3036-codec-platform",
480 .of_match_table = of_match_ptr(rk3036_codec_of_match),
481 },
482 .probe = rk3036_codec_platform_probe,
483 .remove = rk3036_codec_platform_remove,
484};
485
486module_platform_driver(rk3036_codec_platform_driver);
487
488MODULE_AUTHOR("Rockchip Inc.");
489MODULE_DESCRIPTION("Rockchip rk3036 codec driver");
490MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/inno_rk3036.h b/sound/soc/codecs/inno_rk3036.h
new file mode 100644
index 000000000000..da759c6c7501
--- /dev/null
+++ b/sound/soc/codecs/inno_rk3036.h
@@ -0,0 +1,123 @@
1/*
2 * Driver of Inno Codec for rk3036 by Rockchip Inc.
3 *
4 * Author: Zheng ShunQian<zhengsq@rock-chips.com>
5 */
6
7#ifndef _INNO_RK3036_CODEC_H
8#define _INNO_RK3036_CODEC_H
9
10/* codec registers */
11#define INNO_R00 0x00
12#define INNO_R01 0x0c
13#define INNO_R02 0x10
14#define INNO_R03 0x14
15#define INNO_R04 0x88
16#define INNO_R05 0x8c
17#define INNO_R06 0x90
18#define INNO_R07 0x94
19#define INNO_R08 0x98
20#define INNO_R09 0x9c
21#define INNO_R10 0xa0
22
23/* register bit filed */
24#define INNO_R00_CSR_RESET (0x0 << 0) /*codec system reset*/
25#define INNO_R00_CSR_WORK (0x1 << 0)
26#define INNO_R00_CDCR_RESET (0x0 << 1) /*codec digital core reset*/
27#define INNO_R00_CDCR_WORK (0x1 << 1)
28#define INNO_R00_PRB_DISABLE (0x0 << 6) /*power reset bypass*/
29#define INNO_R00_PRB_ENABLE (0x1 << 6)
30
31#define INNO_R01_I2SMODE_MSK (0x1 << 4)
32#define INNO_R01_I2SMODE_SLAVE (0x0 << 4)
33#define INNO_R01_I2SMODE_MASTER (0x1 << 4)
34#define INNO_R01_PINDIR_MSK (0x1 << 5)
35#define INNO_R01_PINDIR_IN_SLAVE (0x0 << 5) /*direction of pin*/
36#define INNO_R01_PINDIR_OUT_MASTER (0x1 << 5)
37
38#define INNO_R02_LRS_MSK (0x1 << 2)
39#define INNO_R02_LRS_NORMAL (0x0 << 2) /*DAC Left Right Swap*/
40#define INNO_R02_LRS_SWAP (0x1 << 2)
41#define INNO_R02_DACM_MSK (0x3 << 3)
42#define INNO_R02_DACM_PCM (0x3 << 3) /*DAC Mode*/
43#define INNO_R02_DACM_I2S (0x2 << 3)
44#define INNO_R02_DACM_LJM (0x1 << 3)
45#define INNO_R02_DACM_RJM (0x0 << 3)
46#define INNO_R02_VWL_MSK (0x3 << 5)
47#define INNO_R02_VWL_32BIT (0x3 << 5) /*1/2Frame Valid Word Len*/
48#define INNO_R02_VWL_24BIT (0x2 << 5)
49#define INNO_R02_VWL_20BIT (0x1 << 5)
50#define INNO_R02_VWL_16BIT (0x0 << 5)
51#define INNO_R02_LRCP_MSK (0x1 << 7)
52#define INNO_R02_LRCP_NORMAL (0x0 << 7) /*Left Right Polarity*/
53#define INNO_R02_LRCP_REVERSAL (0x1 << 7)
54
55#define INNO_R03_BCP_MSK (0x1 << 0)
56#define INNO_R03_BCP_NORMAL (0x0 << 0) /*DAC bit clock polarity*/
57#define INNO_R03_BCP_REVERSAL (0x1 << 0)
58#define INNO_R03_DACR_MSK (0x1 << 1)
59#define INNO_R03_DACR_RESET (0x0 << 1) /*DAC Reset*/
60#define INNO_R03_DACR_WORK (0x1 << 1)
61#define INNO_R03_FWL_MSK (0x3 << 2)
62#define INNO_R03_FWL_32BIT (0x3 << 2) /*1/2Frame Word Length*/
63#define INNO_R03_FWL_24BIT (0x2 << 2)
64#define INNO_R03_FWL_20BIT (0x1 << 2)
65#define INNO_R03_FWL_16BIT (0x0 << 2)
66
67#define INNO_R04_DACR_SW_SHIFT 0
68#define INNO_R04_DACL_SW_SHIFT 1
69#define INNO_R04_DACR_CLK_SHIFT 2
70#define INNO_R04_DACL_CLK_SHIFT 3
71#define INNO_R04_DACR_VREF_SHIFT 4
72#define INNO_R04_DACL_VREF_SHIFT 5
73
74#define INNO_R05_HPR_EN_SHIFT 0
75#define INNO_R05_HPL_EN_SHIFT 1
76#define INNO_R05_HPR_WORK_SHIFT 2
77#define INNO_R05_HPL_WORK_SHIFT 3
78
79#define INNO_R06_VOUTR_CZ_SHIFT 0
80#define INNO_R06_VOUTL_CZ_SHIFT 1
81#define INNO_R06_DACR_HILO_VREF_SHIFT 2
82#define INNO_R06_DACL_HILO_VREF_SHIFT 3
83#define INNO_R06_DAC_EN_SHIFT 5
84
85#define INNO_R06_DAC_PRECHARGE (0x0 << 4) /*PreCharge control for DAC*/
86#define INNO_R06_DAC_DISCHARGE (0x1 << 4)
87
88#define INNO_HP_GAIN_SHIFT 0
89/* Gain of output, 1.5db step: -39db(0x0) ~ 0db(0x1a) ~ 6db(0x1f) */
90#define INNO_HP_GAIN_0DB 0x1a
91#define INNO_HP_GAIN_N39DB 0x0
92
93#define INNO_R09_HP_ANTIPOP_MSK 0x3
94#define INNO_R09_HP_ANTIPOP_OFF 0x1
95#define INNO_R09_HP_ANTIPOP_ON 0x2
96#define INNO_R09_HPR_ANITPOP_SHIFT 0
97#define INNO_R09_HPL_ANITPOP_SHIFT 2
98#define INNO_R09_HPR_MUTE_SHIFT 4
99#define INNO_R09_HPL_MUTE_SHIFT 5
100#define INNO_R09_DACR_SWITCH_SHIFT 6
101#define INNO_R09_DACL_SWITCH_SHIFT 7
102
103#define INNO_R10_CHARGE_SEL_CUR_400I_YES (0x0 << 0)
104#define INNO_R10_CHARGE_SEL_CUR_400I_NO (0x1 << 0)
105#define INNO_R10_CHARGE_SEL_CUR_260I_YES (0x0 << 1)
106#define INNO_R10_CHARGE_SEL_CUR_260I_NO (0x1 << 1)
107#define INNO_R10_CHARGE_SEL_CUR_130I_YES (0x0 << 2)
108#define INNO_R10_CHARGE_SEL_CUR_130I_NO (0x1 << 2)
109#define INNO_R10_CHARGE_SEL_CUR_100I_YES (0x0 << 3)
110#define INNO_R10_CHARGE_SEL_CUR_100I_NO (0x1 << 3)
111#define INNO_R10_CHARGE_SEL_CUR_050I_YES (0x0 << 4)
112#define INNO_R10_CHARGE_SEL_CUR_050I_NO (0x1 << 4)
113#define INNO_R10_CHARGE_SEL_CUR_027I_YES (0x0 << 5)
114#define INNO_R10_CHARGE_SEL_CUR_027I_NO (0x1 << 5)
115
116#define INNO_R10_MAX_CUR (INNO_R10_CHARGE_SEL_CUR_400I_YES | \
117 INNO_R10_CHARGE_SEL_CUR_260I_YES | \
118 INNO_R10_CHARGE_SEL_CUR_130I_YES | \
119 INNO_R10_CHARGE_SEL_CUR_100I_YES | \
120 INNO_R10_CHARGE_SEL_CUR_050I_YES | \
121 INNO_R10_CHARGE_SEL_CUR_027I_YES)
122
123#endif
diff --git a/sound/soc/codecs/max98357a.c b/sound/soc/codecs/max98357a.c
index f5e3dce2633a..5b1dfb1518fb 100644
--- a/sound/soc/codecs/max98357a.c
+++ b/sound/soc/codecs/max98357a.c
@@ -12,6 +12,7 @@
12 * max98357a.c -- MAX98357A ALSA SoC Codec driver 12 * max98357a.c -- MAX98357A ALSA SoC Codec driver
13 */ 13 */
14 14
15#include <linux/acpi.h>
15#include <linux/device.h> 16#include <linux/device.h>
16#include <linux/err.h> 17#include <linux/err.h>
17#include <linux/gpio.h> 18#include <linux/gpio.h>
@@ -123,10 +124,19 @@ static const struct of_device_id max98357a_device_id[] = {
123MODULE_DEVICE_TABLE(of, max98357a_device_id); 124MODULE_DEVICE_TABLE(of, max98357a_device_id);
124#endif 125#endif
125 126
127#ifdef CONFIG_ACPI
128static const struct acpi_device_id max98357a_acpi_match[] = {
129 { "MX98357A", 0 },
130 {},
131};
132MODULE_DEVICE_TABLE(acpi, max98357a_acpi_match);
133#endif
134
126static struct platform_driver max98357a_platform_driver = { 135static struct platform_driver max98357a_platform_driver = {
127 .driver = { 136 .driver = {
128 .name = "max98357a", 137 .name = "max98357a",
129 .of_match_table = of_match_ptr(max98357a_device_id), 138 .of_match_table = of_match_ptr(max98357a_device_id),
139 .acpi_match_table = ACPI_PTR(max98357a_acpi_match),
130 }, 140 },
131 .probe = max98357a_platform_probe, 141 .probe = max98357a_platform_probe,
132 .remove = max98357a_platform_remove, 142 .remove = max98357a_platform_remove,
diff --git a/sound/soc/codecs/pcm1792a.c b/sound/soc/codecs/pcm1792a.c
deleted file mode 100644
index 08bb4863e96f..000000000000
--- a/sound/soc/codecs/pcm1792a.c
+++ /dev/null
@@ -1,271 +0,0 @@
1/*
2 * PCM1792A ASoC codec driver
3 *
4 * Copyright (c) Amarula Solutions B.V. 2013
5 *
6 * Michael Trimarchi <michael@amarulasolutions.com>
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * as published by the Free Software Foundation; either version 2
11 * of the License, or (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 */
18
19#include <linux/module.h>
20#include <linux/slab.h>
21#include <linux/kernel.h>
22#include <linux/device.h>
23#include <linux/spi/spi.h>
24
25#include <sound/core.h>
26#include <sound/pcm.h>
27#include <sound/pcm_params.h>
28#include <sound/initval.h>
29#include <sound/soc.h>
30#include <sound/tlv.h>
31#include <linux/of.h>
32#include <linux/of_device.h>
33
34#include "pcm1792a.h"
35
36#define PCM1792A_DAC_VOL_LEFT 0x10
37#define PCM1792A_DAC_VOL_RIGHT 0x11
38#define PCM1792A_FMT_CONTROL 0x12
39#define PCM1792A_MODE_CONTROL 0x13
40#define PCM1792A_SOFT_MUTE PCM1792A_FMT_CONTROL
41
42#define PCM1792A_FMT_MASK 0x70
43#define PCM1792A_FMT_SHIFT 4
44#define PCM1792A_MUTE_MASK 0x01
45#define PCM1792A_MUTE_SHIFT 0
46#define PCM1792A_ATLD_ENABLE (1 << 7)
47
48static const struct reg_default pcm1792a_reg_defaults[] = {
49 { 0x10, 0xff },
50 { 0x11, 0xff },
51 { 0x12, 0x50 },
52 { 0x13, 0x00 },
53 { 0x14, 0x00 },
54 { 0x15, 0x01 },
55 { 0x16, 0x00 },
56 { 0x17, 0x00 },
57};
58
59static bool pcm1792a_accessible_reg(struct device *dev, unsigned int reg)
60{
61 return reg >= 0x10 && reg <= 0x17;
62}
63
64static bool pcm1792a_writeable_reg(struct device *dev, unsigned register reg)
65{
66 bool accessible;
67
68 accessible = pcm1792a_accessible_reg(dev, reg);
69
70 return accessible && reg != 0x16 && reg != 0x17;
71}
72
73struct pcm1792a_private {
74 struct regmap *regmap;
75 unsigned int format;
76 unsigned int rate;
77};
78
79static int pcm1792a_set_dai_fmt(struct snd_soc_dai *codec_dai,
80 unsigned int format)
81{
82 struct snd_soc_codec *codec = codec_dai->codec;
83 struct pcm1792a_private *priv = snd_soc_codec_get_drvdata(codec);
84
85 priv->format = format;
86
87 return 0;
88}
89
90static int pcm1792a_digital_mute(struct snd_soc_dai *dai, int mute)
91{
92 struct snd_soc_codec *codec = dai->codec;
93 struct pcm1792a_private *priv = snd_soc_codec_get_drvdata(codec);
94 int ret;
95
96 ret = regmap_update_bits(priv->regmap, PCM1792A_SOFT_MUTE,
97 PCM1792A_MUTE_MASK, !!mute);
98 if (ret < 0)
99 return ret;
100
101 return 0;
102}
103
104static int pcm1792a_hw_params(struct snd_pcm_substream *substream,
105 struct snd_pcm_hw_params *params,
106 struct snd_soc_dai *dai)
107{
108 struct snd_soc_codec *codec = dai->codec;
109 struct pcm1792a_private *priv = snd_soc_codec_get_drvdata(codec);
110 int val = 0, ret;
111
112 priv->rate = params_rate(params);
113
114 switch (priv->format & SND_SOC_DAIFMT_FORMAT_MASK) {
115 case SND_SOC_DAIFMT_RIGHT_J:
116 switch (params_width(params)) {
117 case 24:
118 case 32:
119 val = 2;
120 break;
121 case 16:
122 val = 0;
123 break;
124 default:
125 return -EINVAL;
126 }
127 break;
128 case SND_SOC_DAIFMT_I2S:
129 switch (params_width(params)) {
130 case 24:
131 case 32:
132 val = 5;
133 break;
134 case 16:
135 val = 4;
136 break;
137 default:
138 return -EINVAL;
139 }
140 break;
141 default:
142 dev_err(codec->dev, "Invalid DAI format\n");
143 return -EINVAL;
144 }
145
146 val = val << PCM1792A_FMT_SHIFT | PCM1792A_ATLD_ENABLE;
147
148 ret = regmap_update_bits(priv->regmap, PCM1792A_FMT_CONTROL,
149 PCM1792A_FMT_MASK | PCM1792A_ATLD_ENABLE, val);
150 if (ret < 0)
151 return ret;
152
153 return 0;
154}
155
156static const struct snd_soc_dai_ops pcm1792a_dai_ops = {
157 .set_fmt = pcm1792a_set_dai_fmt,
158 .hw_params = pcm1792a_hw_params,
159 .digital_mute = pcm1792a_digital_mute,
160};
161
162static const DECLARE_TLV_DB_SCALE(pcm1792a_dac_tlv, -12000, 50, 1);
163
164static const struct snd_kcontrol_new pcm1792a_controls[] = {
165 SOC_DOUBLE_R_RANGE_TLV("DAC Playback Volume", PCM1792A_DAC_VOL_LEFT,
166 PCM1792A_DAC_VOL_RIGHT, 0, 0xf, 0xff, 0,
167 pcm1792a_dac_tlv),
168 SOC_SINGLE("DAC Invert Output Switch", PCM1792A_MODE_CONTROL, 7, 1, 0),
169 SOC_SINGLE("DAC Rolloff Filter Switch", PCM1792A_MODE_CONTROL, 1, 1, 0),
170};
171
172static const struct snd_soc_dapm_widget pcm1792a_dapm_widgets[] = {
173SND_SOC_DAPM_OUTPUT("IOUTL+"),
174SND_SOC_DAPM_OUTPUT("IOUTL-"),
175SND_SOC_DAPM_OUTPUT("IOUTR+"),
176SND_SOC_DAPM_OUTPUT("IOUTR-"),
177};
178
179static const struct snd_soc_dapm_route pcm1792a_dapm_routes[] = {
180 { "IOUTL+", NULL, "Playback" },
181 { "IOUTL-", NULL, "Playback" },
182 { "IOUTR+", NULL, "Playback" },
183 { "IOUTR-", NULL, "Playback" },
184};
185
186static struct snd_soc_dai_driver pcm1792a_dai = {
187 .name = "pcm1792a-hifi",
188 .playback = {
189 .stream_name = "Playback",
190 .channels_min = 2,
191 .channels_max = 2,
192 .rates = PCM1792A_RATES,
193 .formats = PCM1792A_FORMATS, },
194 .ops = &pcm1792a_dai_ops,
195};
196
197static const struct of_device_id pcm1792a_of_match[] = {
198 { .compatible = "ti,pcm1792a", },
199 { }
200};
201MODULE_DEVICE_TABLE(of, pcm1792a_of_match);
202
203static const struct regmap_config pcm1792a_regmap = {
204 .reg_bits = 8,
205 .val_bits = 8,
206 .max_register = 23,
207 .reg_defaults = pcm1792a_reg_defaults,
208 .num_reg_defaults = ARRAY_SIZE(pcm1792a_reg_defaults),
209 .writeable_reg = pcm1792a_writeable_reg,
210 .readable_reg = pcm1792a_accessible_reg,
211};
212
213static struct snd_soc_codec_driver soc_codec_dev_pcm1792a = {
214 .controls = pcm1792a_controls,
215 .num_controls = ARRAY_SIZE(pcm1792a_controls),
216 .dapm_widgets = pcm1792a_dapm_widgets,
217 .num_dapm_widgets = ARRAY_SIZE(pcm1792a_dapm_widgets),
218 .dapm_routes = pcm1792a_dapm_routes,
219 .num_dapm_routes = ARRAY_SIZE(pcm1792a_dapm_routes),
220};
221
222static int pcm1792a_spi_probe(struct spi_device *spi)
223{
224 struct pcm1792a_private *pcm1792a;
225 int ret;
226
227 pcm1792a = devm_kzalloc(&spi->dev, sizeof(struct pcm1792a_private),
228 GFP_KERNEL);
229 if (!pcm1792a)
230 return -ENOMEM;
231
232 spi_set_drvdata(spi, pcm1792a);
233
234 pcm1792a->regmap = devm_regmap_init_spi(spi, &pcm1792a_regmap);
235 if (IS_ERR(pcm1792a->regmap)) {
236 ret = PTR_ERR(pcm1792a->regmap);
237 dev_err(&spi->dev, "Failed to register regmap: %d\n", ret);
238 return ret;
239 }
240
241 return snd_soc_register_codec(&spi->dev,
242 &soc_codec_dev_pcm1792a, &pcm1792a_dai, 1);
243}
244
245static int pcm1792a_spi_remove(struct spi_device *spi)
246{
247 snd_soc_unregister_codec(&spi->dev);
248 return 0;
249}
250
251static const struct spi_device_id pcm1792a_spi_ids[] = {
252 { "pcm1792a", 0 },
253 { },
254};
255MODULE_DEVICE_TABLE(spi, pcm1792a_spi_ids);
256
257static struct spi_driver pcm1792a_codec_driver = {
258 .driver = {
259 .name = "pcm1792a",
260 .of_match_table = of_match_ptr(pcm1792a_of_match),
261 },
262 .id_table = pcm1792a_spi_ids,
263 .probe = pcm1792a_spi_probe,
264 .remove = pcm1792a_spi_remove,
265};
266
267module_spi_driver(pcm1792a_codec_driver);
268
269MODULE_DESCRIPTION("ASoC PCM1792A driver");
270MODULE_AUTHOR("Michael Trimarchi <michael@amarulasolutions.com>");
271MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/pcm179x.c b/sound/soc/codecs/pcm179x.c
new file mode 100644
index 000000000000..a56c7b767d90
--- /dev/null
+++ b/sound/soc/codecs/pcm179x.c
@@ -0,0 +1,271 @@
1/*
2 * PCM179X ASoC codec driver
3 *
4 * Copyright (c) Amarula Solutions B.V. 2013
5 *
6 * Michael Trimarchi <michael@amarulasolutions.com>
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * as published by the Free Software Foundation; either version 2
11 * of the License, or (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 */
18
19#include <linux/module.h>
20#include <linux/slab.h>
21#include <linux/kernel.h>
22#include <linux/device.h>
23#include <linux/spi/spi.h>
24
25#include <sound/core.h>
26#include <sound/pcm.h>
27#include <sound/pcm_params.h>
28#include <sound/initval.h>
29#include <sound/soc.h>
30#include <sound/tlv.h>
31#include <linux/of.h>
32#include <linux/of_device.h>
33
34#include "pcm179x.h"
35
36#define PCM179X_DAC_VOL_LEFT 0x10
37#define PCM179X_DAC_VOL_RIGHT 0x11
38#define PCM179X_FMT_CONTROL 0x12
39#define PCM179X_MODE_CONTROL 0x13
40#define PCM179X_SOFT_MUTE PCM179X_FMT_CONTROL
41
42#define PCM179X_FMT_MASK 0x70
43#define PCM179X_FMT_SHIFT 4
44#define PCM179X_MUTE_MASK 0x01
45#define PCM179X_MUTE_SHIFT 0
46#define PCM179X_ATLD_ENABLE (1 << 7)
47
48static const struct reg_default pcm179x_reg_defaults[] = {
49 { 0x10, 0xff },
50 { 0x11, 0xff },
51 { 0x12, 0x50 },
52 { 0x13, 0x00 },
53 { 0x14, 0x00 },
54 { 0x15, 0x01 },
55 { 0x16, 0x00 },
56 { 0x17, 0x00 },
57};
58
59static bool pcm179x_accessible_reg(struct device *dev, unsigned int reg)
60{
61 return reg >= 0x10 && reg <= 0x17;
62}
63
64static bool pcm179x_writeable_reg(struct device *dev, unsigned register reg)
65{
66 bool accessible;
67
68 accessible = pcm179x_accessible_reg(dev, reg);
69
70 return accessible && reg != 0x16 && reg != 0x17;
71}
72
73struct pcm179x_private {
74 struct regmap *regmap;
75 unsigned int format;
76 unsigned int rate;
77};
78
79static int pcm179x_set_dai_fmt(struct snd_soc_dai *codec_dai,
80 unsigned int format)
81{
82 struct snd_soc_codec *codec = codec_dai->codec;
83 struct pcm179x_private *priv = snd_soc_codec_get_drvdata(codec);
84
85 priv->format = format;
86
87 return 0;
88}
89
90static int pcm179x_digital_mute(struct snd_soc_dai *dai, int mute)
91{
92 struct snd_soc_codec *codec = dai->codec;
93 struct pcm179x_private *priv = snd_soc_codec_get_drvdata(codec);
94 int ret;
95
96 ret = regmap_update_bits(priv->regmap, PCM179X_SOFT_MUTE,
97 PCM179X_MUTE_MASK, !!mute);
98 if (ret < 0)
99 return ret;
100
101 return 0;
102}
103
104static int pcm179x_hw_params(struct snd_pcm_substream *substream,
105 struct snd_pcm_hw_params *params,
106 struct snd_soc_dai *dai)
107{
108 struct snd_soc_codec *codec = dai->codec;
109 struct pcm179x_private *priv = snd_soc_codec_get_drvdata(codec);
110 int val = 0, ret;
111
112 priv->rate = params_rate(params);
113
114 switch (priv->format & SND_SOC_DAIFMT_FORMAT_MASK) {
115 case SND_SOC_DAIFMT_RIGHT_J:
116 switch (params_width(params)) {
117 case 24:
118 case 32:
119 val = 2;
120 break;
121 case 16:
122 val = 0;
123 break;
124 default:
125 return -EINVAL;
126 }
127 break;
128 case SND_SOC_DAIFMT_I2S:
129 switch (params_width(params)) {
130 case 24:
131 case 32:
132 val = 5;
133 break;
134 case 16:
135 val = 4;
136 break;
137 default:
138 return -EINVAL;
139 }
140 break;
141 default:
142 dev_err(codec->dev, "Invalid DAI format\n");
143 return -EINVAL;
144 }
145
146 val = val << PCM179X_FMT_SHIFT | PCM179X_ATLD_ENABLE;
147
148 ret = regmap_update_bits(priv->regmap, PCM179X_FMT_CONTROL,
149 PCM179X_FMT_MASK | PCM179X_ATLD_ENABLE, val);
150 if (ret < 0)
151 return ret;
152
153 return 0;
154}
155
156static const struct snd_soc_dai_ops pcm179x_dai_ops = {
157 .set_fmt = pcm179x_set_dai_fmt,
158 .hw_params = pcm179x_hw_params,
159 .digital_mute = pcm179x_digital_mute,
160};
161
162static const DECLARE_TLV_DB_SCALE(pcm179x_dac_tlv, -12000, 50, 1);
163
164static const struct snd_kcontrol_new pcm179x_controls[] = {
165 SOC_DOUBLE_R_RANGE_TLV("DAC Playback Volume", PCM179X_DAC_VOL_LEFT,
166 PCM179X_DAC_VOL_RIGHT, 0, 0xf, 0xff, 0,
167 pcm179x_dac_tlv),
168 SOC_SINGLE("DAC Invert Output Switch", PCM179X_MODE_CONTROL, 7, 1, 0),
169 SOC_SINGLE("DAC Rolloff Filter Switch", PCM179X_MODE_CONTROL, 1, 1, 0),
170};
171
172static const struct snd_soc_dapm_widget pcm179x_dapm_widgets[] = {
173SND_SOC_DAPM_OUTPUT("IOUTL+"),
174SND_SOC_DAPM_OUTPUT("IOUTL-"),
175SND_SOC_DAPM_OUTPUT("IOUTR+"),
176SND_SOC_DAPM_OUTPUT("IOUTR-"),
177};
178
179static const struct snd_soc_dapm_route pcm179x_dapm_routes[] = {
180 { "IOUTL+", NULL, "Playback" },
181 { "IOUTL-", NULL, "Playback" },
182 { "IOUTR+", NULL, "Playback" },
183 { "IOUTR-", NULL, "Playback" },
184};
185
186static struct snd_soc_dai_driver pcm179x_dai = {
187 .name = "pcm179x-hifi",
188 .playback = {
189 .stream_name = "Playback",
190 .channels_min = 2,
191 .channels_max = 2,
192 .rates = PCM1792A_RATES,
193 .formats = PCM1792A_FORMATS, },
194 .ops = &pcm179x_dai_ops,
195};
196
197static const struct of_device_id pcm179x_of_match[] = {
198 { .compatible = "ti,pcm1792a", },
199 { }
200};
201MODULE_DEVICE_TABLE(of, pcm179x_of_match);
202
203static const struct regmap_config pcm179x_regmap = {
204 .reg_bits = 8,
205 .val_bits = 8,
206 .max_register = 23,
207 .reg_defaults = pcm179x_reg_defaults,
208 .num_reg_defaults = ARRAY_SIZE(pcm179x_reg_defaults),
209 .writeable_reg = pcm179x_writeable_reg,
210 .readable_reg = pcm179x_accessible_reg,
211};
212
213static struct snd_soc_codec_driver soc_codec_dev_pcm179x = {
214 .controls = pcm179x_controls,
215 .num_controls = ARRAY_SIZE(pcm179x_controls),
216 .dapm_widgets = pcm179x_dapm_widgets,
217 .num_dapm_widgets = ARRAY_SIZE(pcm179x_dapm_widgets),
218 .dapm_routes = pcm179x_dapm_routes,
219 .num_dapm_routes = ARRAY_SIZE(pcm179x_dapm_routes),
220};
221
222static int pcm179x_spi_probe(struct spi_device *spi)
223{
224 struct pcm179x_private *pcm179x;
225 int ret;
226
227 pcm179x = devm_kzalloc(&spi->dev, sizeof(struct pcm179x_private),
228 GFP_KERNEL);
229 if (!pcm179x)
230 return -ENOMEM;
231
232 spi_set_drvdata(spi, pcm179x);
233
234 pcm179x->regmap = devm_regmap_init_spi(spi, &pcm179x_regmap);
235 if (IS_ERR(pcm179x->regmap)) {
236 ret = PTR_ERR(pcm179x->regmap);
237 dev_err(&spi->dev, "Failed to register regmap: %d\n", ret);
238 return ret;
239 }
240
241 return snd_soc_register_codec(&spi->dev,
242 &soc_codec_dev_pcm179x, &pcm179x_dai, 1);
243}
244
245static int pcm179x_spi_remove(struct spi_device *spi)
246{
247 snd_soc_unregister_codec(&spi->dev);
248 return 0;
249}
250
251static const struct spi_device_id pcm179x_spi_ids[] = {
252 { "pcm179x", 0 },
253 { },
254};
255MODULE_DEVICE_TABLE(spi, pcm179x_spi_ids);
256
257static struct spi_driver pcm179x_codec_driver = {
258 .driver = {
259 .name = "pcm179x",
260 .of_match_table = of_match_ptr(pcm179x_of_match),
261 },
262 .id_table = pcm179x_spi_ids,
263 .probe = pcm179x_spi_probe,
264 .remove = pcm179x_spi_remove,
265};
266
267module_spi_driver(pcm179x_codec_driver);
268
269MODULE_DESCRIPTION("ASoC PCM179X driver");
270MODULE_AUTHOR("Michael Trimarchi <michael@amarulasolutions.com>");
271MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/pcm1792a.h b/sound/soc/codecs/pcm179x.h
index 51d5470fee16..c6fdc062a497 100644
--- a/sound/soc/codecs/pcm1792a.h
+++ b/sound/soc/codecs/pcm179x.h
@@ -1,5 +1,5 @@
1/* 1/*
2 * definitions for PCM1792A 2 * definitions for PCM179X
3 * 3 *
4 * Copyright 2013 Amarula Solutions 4 * Copyright 2013 Amarula Solutions
5 * 5 *
@@ -14,8 +14,8 @@
14 * GNU General Public License for more details. 14 * GNU General Public License for more details.
15 */ 15 */
16 16
17#ifndef __PCM1792A_H__ 17#ifndef __PCM179X_H__
18#define __PCM1792A_H__ 18#define __PCM179X_H__
19 19
20#define PCM1792A_RATES (SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_8000_48000 | \ 20#define PCM1792A_RATES (SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_8000_48000 | \
21 SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000 | \ 21 SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000 | \
diff --git a/sound/soc/codecs/pcm3168a-i2c.c b/sound/soc/codecs/pcm3168a-i2c.c
new file mode 100644
index 000000000000..6feb0901dfeb
--- /dev/null
+++ b/sound/soc/codecs/pcm3168a-i2c.c
@@ -0,0 +1,66 @@
1/*
2 * PCM3168A codec i2c driver
3 *
4 * Copyright (C) 2015 Imagination Technologies Ltd.
5 *
6 * Author: Damien Horsley <Damien.Horsley@imgtec.com>
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms and conditions of the GNU General Public License,
10 * version 2, as published by the Free Software Foundation.
11 */
12
13#include <linux/i2c.h>
14#include <linux/init.h>
15#include <linux/module.h>
16
17#include <sound/soc.h>
18
19#include "pcm3168a.h"
20
21static int pcm3168a_i2c_probe(struct i2c_client *i2c,
22 const struct i2c_device_id *id)
23{
24 struct regmap *regmap;
25
26 regmap = devm_regmap_init_i2c(i2c, &pcm3168a_regmap);
27 if (IS_ERR(regmap))
28 return PTR_ERR(regmap);
29
30 return pcm3168a_probe(&i2c->dev, regmap);
31}
32
33static int pcm3168a_i2c_remove(struct i2c_client *i2c)
34{
35 pcm3168a_remove(&i2c->dev);
36
37 return 0;
38}
39
40static const struct i2c_device_id pcm3168a_i2c_id[] = {
41 { "pcm3168a", },
42 { }
43};
44MODULE_DEVICE_TABLE(i2c, pcm3168a_i2c_id);
45
46static const struct of_device_id pcm3168a_of_match[] = {
47 { .compatible = "ti,pcm3168a", },
48 { }
49};
50MODULE_DEVICE_TABLE(of, pcm3168a_of_match);
51
52static struct i2c_driver pcm3168a_i2c_driver = {
53 .probe = pcm3168a_i2c_probe,
54 .remove = pcm3168a_i2c_remove,
55 .id_table = pcm3168a_i2c_id,
56 .driver = {
57 .name = "pcm3168a",
58 .of_match_table = pcm3168a_of_match,
59 .pm = &pcm3168a_pm_ops,
60 },
61};
62module_i2c_driver(pcm3168a_i2c_driver);
63
64MODULE_DESCRIPTION("PCM3168A I2C codec driver");
65MODULE_AUTHOR("Damien Horsley <Damien.Horsley@imgtec.com>");
66MODULE_LICENSE("GPL v2");
diff --git a/sound/soc/codecs/pcm3168a-spi.c b/sound/soc/codecs/pcm3168a-spi.c
new file mode 100644
index 000000000000..03945a27ae40
--- /dev/null
+++ b/sound/soc/codecs/pcm3168a-spi.c
@@ -0,0 +1,65 @@
1/*
2 * PCM3168A codec spi driver
3 *
4 * Copyright (C) 2015 Imagination Technologies Ltd.
5 *
6 * Author: Damien Horsley <Damien.Horsley@imgtec.com>
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms and conditions of the GNU General Public License,
10 * version 2, as published by the Free Software Foundation.
11 */
12
13#include <linux/init.h>
14#include <linux/module.h>
15#include <linux/spi/spi.h>
16
17#include <sound/soc.h>
18
19#include "pcm3168a.h"
20
21static int pcm3168a_spi_probe(struct spi_device *spi)
22{
23 struct regmap *regmap;
24
25 regmap = devm_regmap_init_spi(spi, &pcm3168a_regmap);
26 if (IS_ERR(regmap))
27 return PTR_ERR(regmap);
28
29 return pcm3168a_probe(&spi->dev, regmap);
30}
31
32static int pcm3168a_spi_remove(struct spi_device *spi)
33{
34 pcm3168a_remove(&spi->dev);
35
36 return 0;
37}
38
39static const struct spi_device_id pcm3168a_spi_id[] = {
40 { "pcm3168a", },
41 { },
42};
43MODULE_DEVICE_TABLE(spi, pcm3168a_spi_id);
44
45static const struct of_device_id pcm3168a_of_match[] = {
46 { .compatible = "ti,pcm3168a", },
47 { }
48};
49MODULE_DEVICE_TABLE(of, pcm3168a_of_match);
50
51static struct spi_driver pcm3168a_spi_driver = {
52 .probe = pcm3168a_spi_probe,
53 .remove = pcm3168a_spi_remove,
54 .id_table = pcm3168a_spi_id,
55 .driver = {
56 .name = "pcm3168a",
57 .of_match_table = pcm3168a_of_match,
58 .pm = &pcm3168a_pm_ops,
59 },
60};
61module_spi_driver(pcm3168a_spi_driver);
62
63MODULE_DESCRIPTION("PCM3168A SPI codec driver");
64MODULE_AUTHOR("Damien Horsley <Damien.Horsley@imgtec.com>");
65MODULE_LICENSE("GPL v2");
diff --git a/sound/soc/codecs/pcm3168a.c b/sound/soc/codecs/pcm3168a.c
new file mode 100644
index 000000000000..44b268aa4dd8
--- /dev/null
+++ b/sound/soc/codecs/pcm3168a.c
@@ -0,0 +1,767 @@
1/*
2 * PCM3168A codec driver
3 *
4 * Copyright (C) 2015 Imagination Technologies Ltd.
5 *
6 * Author: Damien Horsley <Damien.Horsley@imgtec.com>
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms and conditions of the GNU General Public License,
10 * version 2, as published by the Free Software Foundation.
11 */
12
13#include <linux/clk.h>
14#include <linux/delay.h>
15#include <linux/module.h>
16#include <linux/pm_runtime.h>
17#include <linux/regulator/consumer.h>
18
19#include <sound/pcm_params.h>
20#include <sound/soc.h>
21#include <sound/tlv.h>
22
23#include "pcm3168a.h"
24
25#define PCM3168A_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | \
26 SNDRV_PCM_FMTBIT_S24_3LE | \
27 SNDRV_PCM_FMTBIT_S24_LE | \
28 SNDRV_PCM_FMTBIT_S32_LE)
29
30#define PCM3168A_FMT_I2S 0x0
31#define PCM3168A_FMT_LEFT_J 0x1
32#define PCM3168A_FMT_RIGHT_J 0x2
33#define PCM3168A_FMT_RIGHT_J_16 0x3
34#define PCM3168A_FMT_DSP_A 0x4
35#define PCM3168A_FMT_DSP_B 0x5
36#define PCM3168A_FMT_DSP_MASK 0x4
37
38#define PCM3168A_NUM_SUPPLIES 6
39static const char *const pcm3168a_supply_names[PCM3168A_NUM_SUPPLIES] = {
40 "VDD1",
41 "VDD2",
42 "VCCAD1",
43 "VCCAD2",
44 "VCCDA1",
45 "VCCDA2"
46};
47
48struct pcm3168a_priv {
49 struct regulator_bulk_data supplies[PCM3168A_NUM_SUPPLIES];
50 struct regmap *regmap;
51 struct clk *scki;
52 bool adc_master_mode;
53 bool dac_master_mode;
54 unsigned long sysclk;
55 unsigned int adc_fmt;
56 unsigned int dac_fmt;
57};
58
59static const char *const pcm3168a_roll_off[] = { "Sharp", "Slow" };
60
61static SOC_ENUM_SINGLE_DECL(pcm3168a_d1_roll_off, PCM3168A_DAC_OP_FLT,
62 PCM3168A_DAC_FLT_SHIFT, pcm3168a_roll_off);
63static SOC_ENUM_SINGLE_DECL(pcm3168a_d2_roll_off, PCM3168A_DAC_OP_FLT,
64 PCM3168A_DAC_FLT_SHIFT + 1, pcm3168a_roll_off);
65static SOC_ENUM_SINGLE_DECL(pcm3168a_d3_roll_off, PCM3168A_DAC_OP_FLT,
66 PCM3168A_DAC_FLT_SHIFT + 2, pcm3168a_roll_off);
67static SOC_ENUM_SINGLE_DECL(pcm3168a_d4_roll_off, PCM3168A_DAC_OP_FLT,
68 PCM3168A_DAC_FLT_SHIFT + 3, pcm3168a_roll_off);
69
70static const char *const pcm3168a_volume_type[] = {
71 "Individual", "Master + Individual" };
72
73static SOC_ENUM_SINGLE_DECL(pcm3168a_dac_volume_type, PCM3168A_DAC_ATT_DEMP_ZF,
74 PCM3168A_DAC_ATMDDA_SHIFT, pcm3168a_volume_type);
75
76static const char *const pcm3168a_att_speed_mult[] = { "2048", "4096" };
77
78static SOC_ENUM_SINGLE_DECL(pcm3168a_dac_att_mult, PCM3168A_DAC_ATT_DEMP_ZF,
79 PCM3168A_DAC_ATSPDA_SHIFT, pcm3168a_att_speed_mult);
80
81static const char *const pcm3168a_demp[] = {
82 "Disabled", "48khz", "44.1khz", "32khz" };
83
84static SOC_ENUM_SINGLE_DECL(pcm3168a_dac_demp, PCM3168A_DAC_ATT_DEMP_ZF,
85 PCM3168A_DAC_DEMP_SHIFT, pcm3168a_demp);
86
87static const char *const pcm3168a_zf_func[] = {
88 "DAC 1/2/3/4 AND", "DAC 1/2/3/4 OR", "DAC 1/2/3 AND",
89 "DAC 1/2/3 OR", "DAC 4 AND", "DAC 4 OR" };
90
91static SOC_ENUM_SINGLE_DECL(pcm3168a_dac_zf_func, PCM3168A_DAC_ATT_DEMP_ZF,
92 PCM3168A_DAC_AZRO_SHIFT, pcm3168a_zf_func);
93
94static const char *const pcm3168a_pol[] = { "Active High", "Active Low" };
95
96static SOC_ENUM_SINGLE_DECL(pcm3168a_dac_zf_pol, PCM3168A_DAC_ATT_DEMP_ZF,
97 PCM3168A_DAC_ATSPDA_SHIFT, pcm3168a_pol);
98
99static const char *const pcm3168a_con[] = { "Differential", "Single-Ended" };
100
101static SOC_ENUM_DOUBLE_DECL(pcm3168a_adc1_con, PCM3168A_ADC_SEAD,
102 0, 1, pcm3168a_con);
103static SOC_ENUM_DOUBLE_DECL(pcm3168a_adc2_con, PCM3168A_ADC_SEAD,
104 2, 3, pcm3168a_con);
105static SOC_ENUM_DOUBLE_DECL(pcm3168a_adc3_con, PCM3168A_ADC_SEAD,
106 4, 5, pcm3168a_con);
107
108static SOC_ENUM_SINGLE_DECL(pcm3168a_adc_volume_type, PCM3168A_ADC_ATT_OVF,
109 PCM3168A_ADC_ATMDAD_SHIFT, pcm3168a_volume_type);
110
111static SOC_ENUM_SINGLE_DECL(pcm3168a_adc_att_mult, PCM3168A_ADC_ATT_OVF,
112 PCM3168A_ADC_ATSPAD_SHIFT, pcm3168a_att_speed_mult);
113
114static SOC_ENUM_SINGLE_DECL(pcm3168a_adc_ov_pol, PCM3168A_ADC_ATT_OVF,
115 PCM3168A_ADC_OVFP_SHIFT, pcm3168a_pol);
116
117/* -100db to 0db, register values 0-54 cause mute */
118static const DECLARE_TLV_DB_SCALE(pcm3168a_dac_tlv, -10050, 50, 1);
119
120/* -100db to 20db, register values 0-14 cause mute */
121static const DECLARE_TLV_DB_SCALE(pcm3168a_adc_tlv, -10050, 50, 1);
122
123static const struct snd_kcontrol_new pcm3168a_snd_controls[] = {
124 SOC_SINGLE("DAC Power-Save Switch", PCM3168A_DAC_PWR_MST_FMT,
125 PCM3168A_DAC_PSMDA_SHIFT, 1, 1),
126 SOC_ENUM("DAC1 Digital Filter roll-off", pcm3168a_d1_roll_off),
127 SOC_ENUM("DAC2 Digital Filter roll-off", pcm3168a_d2_roll_off),
128 SOC_ENUM("DAC3 Digital Filter roll-off", pcm3168a_d3_roll_off),
129 SOC_ENUM("DAC4 Digital Filter roll-off", pcm3168a_d4_roll_off),
130 SOC_DOUBLE("DAC1 Invert Switch", PCM3168A_DAC_INV, 0, 1, 1, 0),
131 SOC_DOUBLE("DAC2 Invert Switch", PCM3168A_DAC_INV, 2, 3, 1, 0),
132 SOC_DOUBLE("DAC3 Invert Switch", PCM3168A_DAC_INV, 4, 5, 1, 0),
133 SOC_DOUBLE("DAC4 Invert Switch", PCM3168A_DAC_INV, 6, 7, 1, 0),
134 SOC_DOUBLE_STS("DAC1 Zero Flag", PCM3168A_DAC_ZERO, 0, 1, 1, 0),
135 SOC_DOUBLE_STS("DAC2 Zero Flag", PCM3168A_DAC_ZERO, 2, 3, 1, 0),
136 SOC_DOUBLE_STS("DAC3 Zero Flag", PCM3168A_DAC_ZERO, 4, 5, 1, 0),
137 SOC_DOUBLE_STS("DAC4 Zero Flag", PCM3168A_DAC_ZERO, 6, 7, 1, 0),
138 SOC_ENUM("DAC Volume Control Type", pcm3168a_dac_volume_type),
139 SOC_ENUM("DAC Volume Rate Multiplier", pcm3168a_dac_att_mult),
140 SOC_ENUM("DAC De-Emphasis", pcm3168a_dac_demp),
141 SOC_ENUM("DAC Zero Flag Function", pcm3168a_dac_zf_func),
142 SOC_ENUM("DAC Zero Flag Polarity", pcm3168a_dac_zf_pol),
143 SOC_SINGLE_RANGE_TLV("Master Playback Volume",
144 PCM3168A_DAC_VOL_MASTER, 0, 54, 255, 0,
145 pcm3168a_dac_tlv),
146 SOC_DOUBLE_R_RANGE_TLV("DAC1 Playback Volume",
147 PCM3168A_DAC_VOL_CHAN_START,
148 PCM3168A_DAC_VOL_CHAN_START + 1,
149 0, 54, 255, 0, pcm3168a_dac_tlv),
150 SOC_DOUBLE_R_RANGE_TLV("DAC2 Playback Volume",
151 PCM3168A_DAC_VOL_CHAN_START + 2,
152 PCM3168A_DAC_VOL_CHAN_START + 3,
153 0, 54, 255, 0, pcm3168a_dac_tlv),
154 SOC_DOUBLE_R_RANGE_TLV("DAC3 Playback Volume",
155 PCM3168A_DAC_VOL_CHAN_START + 4,
156 PCM3168A_DAC_VOL_CHAN_START + 5,
157 0, 54, 255, 0, pcm3168a_dac_tlv),
158 SOC_DOUBLE_R_RANGE_TLV("DAC4 Playback Volume",
159 PCM3168A_DAC_VOL_CHAN_START + 6,
160 PCM3168A_DAC_VOL_CHAN_START + 7,
161 0, 54, 255, 0, pcm3168a_dac_tlv),
162 SOC_SINGLE("ADC1 High-Pass Filter Switch", PCM3168A_ADC_PWR_HPFB,
163 PCM3168A_ADC_BYP_SHIFT, 1, 1),
164 SOC_SINGLE("ADC2 High-Pass Filter Switch", PCM3168A_ADC_PWR_HPFB,
165 PCM3168A_ADC_BYP_SHIFT + 1, 1, 1),
166 SOC_SINGLE("ADC3 High-Pass Filter Switch", PCM3168A_ADC_PWR_HPFB,
167 PCM3168A_ADC_BYP_SHIFT + 2, 1, 1),
168 SOC_ENUM("ADC1 Connection Type", pcm3168a_adc1_con),
169 SOC_ENUM("ADC2 Connection Type", pcm3168a_adc2_con),
170 SOC_ENUM("ADC3 Connection Type", pcm3168a_adc3_con),
171 SOC_DOUBLE("ADC1 Invert Switch", PCM3168A_ADC_INV, 0, 1, 1, 0),
172 SOC_DOUBLE("ADC2 Invert Switch", PCM3168A_ADC_INV, 2, 3, 1, 0),
173 SOC_DOUBLE("ADC3 Invert Switch", PCM3168A_ADC_INV, 4, 5, 1, 0),
174 SOC_DOUBLE("ADC1 Mute Switch", PCM3168A_ADC_MUTE, 0, 1, 1, 0),
175 SOC_DOUBLE("ADC2 Mute Switch", PCM3168A_ADC_MUTE, 2, 3, 1, 0),
176 SOC_DOUBLE("ADC3 Mute Switch", PCM3168A_ADC_MUTE, 4, 5, 1, 0),
177 SOC_DOUBLE_STS("ADC1 Overflow Flag", PCM3168A_ADC_OV, 0, 1, 1, 0),
178 SOC_DOUBLE_STS("ADC2 Overflow Flag", PCM3168A_ADC_OV, 2, 3, 1, 0),
179 SOC_DOUBLE_STS("ADC3 Overflow Flag", PCM3168A_ADC_OV, 4, 5, 1, 0),
180 SOC_ENUM("ADC Volume Control Type", pcm3168a_adc_volume_type),
181 SOC_ENUM("ADC Volume Rate Multiplier", pcm3168a_adc_att_mult),
182 SOC_ENUM("ADC Overflow Flag Polarity", pcm3168a_adc_ov_pol),
183 SOC_SINGLE_RANGE_TLV("Master Capture Volume",
184 PCM3168A_ADC_VOL_MASTER, 0, 14, 255, 0,
185 pcm3168a_adc_tlv),
186 SOC_DOUBLE_R_RANGE_TLV("ADC1 Capture Volume",
187 PCM3168A_ADC_VOL_CHAN_START,
188 PCM3168A_ADC_VOL_CHAN_START + 1,
189 0, 14, 255, 0, pcm3168a_adc_tlv),
190 SOC_DOUBLE_R_RANGE_TLV("ADC2 Capture Volume",
191 PCM3168A_ADC_VOL_CHAN_START + 2,
192 PCM3168A_ADC_VOL_CHAN_START + 3,
193 0, 14, 255, 0, pcm3168a_adc_tlv),
194 SOC_DOUBLE_R_RANGE_TLV("ADC3 Capture Volume",
195 PCM3168A_ADC_VOL_CHAN_START + 4,
196 PCM3168A_ADC_VOL_CHAN_START + 5,
197 0, 14, 255, 0, pcm3168a_adc_tlv)
198};
199
200static const struct snd_soc_dapm_widget pcm3168a_dapm_widgets[] = {
201 SND_SOC_DAPM_DAC("DAC1", "Playback", PCM3168A_DAC_OP_FLT,
202 PCM3168A_DAC_OPEDA_SHIFT, 1),
203 SND_SOC_DAPM_DAC("DAC2", "Playback", PCM3168A_DAC_OP_FLT,
204 PCM3168A_DAC_OPEDA_SHIFT + 1, 1),
205 SND_SOC_DAPM_DAC("DAC3", "Playback", PCM3168A_DAC_OP_FLT,
206 PCM3168A_DAC_OPEDA_SHIFT + 2, 1),
207 SND_SOC_DAPM_DAC("DAC4", "Playback", PCM3168A_DAC_OP_FLT,
208 PCM3168A_DAC_OPEDA_SHIFT + 3, 1),
209
210 SND_SOC_DAPM_OUTPUT("AOUT1L"),
211 SND_SOC_DAPM_OUTPUT("AOUT1R"),
212 SND_SOC_DAPM_OUTPUT("AOUT2L"),
213 SND_SOC_DAPM_OUTPUT("AOUT2R"),
214 SND_SOC_DAPM_OUTPUT("AOUT3L"),
215 SND_SOC_DAPM_OUTPUT("AOUT3R"),
216 SND_SOC_DAPM_OUTPUT("AOUT4L"),
217 SND_SOC_DAPM_OUTPUT("AOUT4R"),
218
219 SND_SOC_DAPM_ADC("ADC1", "Capture", PCM3168A_ADC_PWR_HPFB,
220 PCM3168A_ADC_PSVAD_SHIFT, 1),
221 SND_SOC_DAPM_ADC("ADC2", "Capture", PCM3168A_ADC_PWR_HPFB,
222 PCM3168A_ADC_PSVAD_SHIFT + 1, 1),
223 SND_SOC_DAPM_ADC("ADC3", "Capture", PCM3168A_ADC_PWR_HPFB,
224 PCM3168A_ADC_PSVAD_SHIFT + 2, 1),
225
226 SND_SOC_DAPM_INPUT("AIN1L"),
227 SND_SOC_DAPM_INPUT("AIN1R"),
228 SND_SOC_DAPM_INPUT("AIN2L"),
229 SND_SOC_DAPM_INPUT("AIN2R"),
230 SND_SOC_DAPM_INPUT("AIN3L"),
231 SND_SOC_DAPM_INPUT("AIN3R")
232};
233
234static const struct snd_soc_dapm_route pcm3168a_dapm_routes[] = {
235 /* Playback */
236 { "AOUT1L", NULL, "DAC1" },
237 { "AOUT1R", NULL, "DAC1" },
238
239 { "AOUT2L", NULL, "DAC2" },
240 { "AOUT2R", NULL, "DAC2" },
241
242 { "AOUT3L", NULL, "DAC3" },
243 { "AOUT3R", NULL, "DAC3" },
244
245 { "AOUT4L", NULL, "DAC4" },
246 { "AOUT4R", NULL, "DAC4" },
247
248 /* Capture */
249 { "ADC1", NULL, "AIN1L" },
250 { "ADC1", NULL, "AIN1R" },
251
252 { "ADC2", NULL, "AIN2L" },
253 { "ADC2", NULL, "AIN2R" },
254
255 { "ADC3", NULL, "AIN3L" },
256 { "ADC3", NULL, "AIN3R" }
257};
258
259static unsigned int pcm3168a_scki_ratios[] = {
260 768,
261 512,
262 384,
263 256,
264 192,
265 128
266};
267
268#define PCM3168A_NUM_SCKI_RATIOS_DAC ARRAY_SIZE(pcm3168a_scki_ratios)
269#define PCM3168A_NUM_SCKI_RATIOS_ADC (ARRAY_SIZE(pcm3168a_scki_ratios) - 2)
270
271#define PCM1368A_MAX_SYSCLK 36864000
272
273static int pcm3168a_reset(struct pcm3168a_priv *pcm3168a)
274{
275 int ret;
276
277 ret = regmap_write(pcm3168a->regmap, PCM3168A_RST_SMODE, 0);
278 if (ret)
279 return ret;
280
281 /* Internal reset is de-asserted after 3846 SCKI cycles */
282 msleep(DIV_ROUND_UP(3846 * 1000, pcm3168a->sysclk));
283
284 return regmap_write(pcm3168a->regmap, PCM3168A_RST_SMODE,
285 PCM3168A_MRST_MASK | PCM3168A_SRST_MASK);
286}
287
288static int pcm3168a_digital_mute(struct snd_soc_dai *dai, int mute)
289{
290 struct snd_soc_codec *codec = dai->codec;
291 struct pcm3168a_priv *pcm3168a = snd_soc_codec_get_drvdata(codec);
292
293 regmap_write(pcm3168a->regmap, PCM3168A_DAC_MUTE, mute ? 0xff : 0);
294
295 return 0;
296}
297
298static int pcm3168a_set_dai_sysclk(struct snd_soc_dai *dai,
299 int clk_id, unsigned int freq, int dir)
300{
301 struct pcm3168a_priv *pcm3168a = snd_soc_codec_get_drvdata(dai->codec);
302
303 if (freq > PCM1368A_MAX_SYSCLK)
304 return -EINVAL;
305
306 pcm3168a->sysclk = freq;
307
308 return 0;
309}
310
311static int pcm3168a_set_dai_fmt(struct snd_soc_dai *dai,
312 unsigned int format, bool dac)
313{
314 struct snd_soc_codec *codec = dai->codec;
315 struct pcm3168a_priv *pcm3168a = snd_soc_codec_get_drvdata(codec);
316 u32 fmt, reg, mask, shift;
317 bool master_mode;
318
319 switch (format & SND_SOC_DAIFMT_FORMAT_MASK) {
320 case SND_SOC_DAIFMT_LEFT_J:
321 fmt = PCM3168A_FMT_LEFT_J;
322 break;
323 case SND_SOC_DAIFMT_I2S:
324 fmt = PCM3168A_FMT_I2S;
325 break;
326 case SND_SOC_DAIFMT_RIGHT_J:
327 fmt = PCM3168A_FMT_RIGHT_J;
328 break;
329 case SND_SOC_DAIFMT_DSP_A:
330 fmt = PCM3168A_FMT_DSP_A;
331 break;
332 case SND_SOC_DAIFMT_DSP_B:
333 fmt = PCM3168A_FMT_DSP_B;
334 break;
335 default:
336 dev_err(codec->dev, "unsupported dai format\n");
337 return -EINVAL;
338 }
339
340 switch (format & SND_SOC_DAIFMT_MASTER_MASK) {
341 case SND_SOC_DAIFMT_CBS_CFS:
342 master_mode = false;
343 break;
344 case SND_SOC_DAIFMT_CBM_CFM:
345 master_mode = true;
346 break;
347 default:
348 dev_err(codec->dev, "unsupported master/slave mode\n");
349 return -EINVAL;
350 }
351
352 switch (format & SND_SOC_DAIFMT_INV_MASK) {
353 case SND_SOC_DAIFMT_NB_NF:
354 break;
355 default:
356 return -EINVAL;
357 }
358
359 if (dac) {
360 reg = PCM3168A_DAC_PWR_MST_FMT;
361 mask = PCM3168A_DAC_FMT_MASK;
362 shift = PCM3168A_DAC_FMT_SHIFT;
363 pcm3168a->dac_master_mode = master_mode;
364 pcm3168a->dac_fmt = fmt;
365 } else {
366 reg = PCM3168A_ADC_MST_FMT;
367 mask = PCM3168A_ADC_FMTAD_MASK;
368 shift = PCM3168A_ADC_FMTAD_SHIFT;
369 pcm3168a->adc_master_mode = master_mode;
370 pcm3168a->adc_fmt = fmt;
371 }
372
373 regmap_update_bits(pcm3168a->regmap, reg, mask, fmt << shift);
374
375 return 0;
376}
377
378static int pcm3168a_set_dai_fmt_dac(struct snd_soc_dai *dai,
379 unsigned int format)
380{
381 return pcm3168a_set_dai_fmt(dai, format, true);
382}
383
384static int pcm3168a_set_dai_fmt_adc(struct snd_soc_dai *dai,
385 unsigned int format)
386{
387 return pcm3168a_set_dai_fmt(dai, format, false);
388}
389
390static int pcm3168a_hw_params(struct snd_pcm_substream *substream,
391 struct snd_pcm_hw_params *params,
392 struct snd_soc_dai *dai)
393{
394 struct snd_soc_codec *codec = dai->codec;
395 struct pcm3168a_priv *pcm3168a = snd_soc_codec_get_drvdata(codec);
396 bool tx, master_mode;
397 u32 val, mask, shift, reg;
398 unsigned int rate, channels, fmt, ratio, max_ratio;
399 int i, min_frame_size;
400 snd_pcm_format_t format;
401
402 rate = params_rate(params);
403 format = params_format(params);
404 channels = params_channels(params);
405
406 ratio = pcm3168a->sysclk / rate;
407
408 tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
409 if (tx) {
410 max_ratio = PCM3168A_NUM_SCKI_RATIOS_DAC;
411 reg = PCM3168A_DAC_PWR_MST_FMT;
412 mask = PCM3168A_DAC_MSDA_MASK;
413 shift = PCM3168A_DAC_MSDA_SHIFT;
414 master_mode = pcm3168a->dac_master_mode;
415 fmt = pcm3168a->dac_fmt;
416 } else {
417 max_ratio = PCM3168A_NUM_SCKI_RATIOS_ADC;
418 reg = PCM3168A_ADC_MST_FMT;
419 mask = PCM3168A_ADC_MSAD_MASK;
420 shift = PCM3168A_ADC_MSAD_SHIFT;
421 master_mode = pcm3168a->adc_master_mode;
422 fmt = pcm3168a->adc_fmt;
423 }
424
425 for (i = 0; i < max_ratio; i++) {
426 if (pcm3168a_scki_ratios[i] == ratio)
427 break;
428 }
429
430 if (i == max_ratio) {
431 dev_err(codec->dev, "unsupported sysclk ratio\n");
432 return -EINVAL;
433 }
434
435 min_frame_size = params_width(params) * 2;
436 switch (min_frame_size) {
437 case 32:
438 if (master_mode || (fmt != PCM3168A_FMT_RIGHT_J)) {
439 dev_err(codec->dev, "32-bit frames are supported only for slave mode using right justified\n");
440 return -EINVAL;
441 }
442 fmt = PCM3168A_FMT_RIGHT_J_16;
443 break;
444 case 48:
445 if (master_mode || (fmt & PCM3168A_FMT_DSP_MASK)) {
446 dev_err(codec->dev, "48-bit frames not supported in master mode, or slave mode using DSP\n");
447 return -EINVAL;
448 }
449 break;
450 case 64:
451 break;
452 default:
453 dev_err(codec->dev, "unsupported frame size: %d\n", min_frame_size);
454 return -EINVAL;
455 }
456
457 if (master_mode)
458 val = ((i + 1) << shift);
459 else
460 val = 0;
461
462 regmap_update_bits(pcm3168a->regmap, reg, mask, val);
463
464 if (tx) {
465 mask = PCM3168A_DAC_FMT_MASK;
466 shift = PCM3168A_DAC_FMT_SHIFT;
467 } else {
468 mask = PCM3168A_ADC_FMTAD_MASK;
469 shift = PCM3168A_ADC_FMTAD_SHIFT;
470 }
471
472 regmap_update_bits(pcm3168a->regmap, reg, mask, fmt << shift);
473
474 return 0;
475}
476
477static const struct snd_soc_dai_ops pcm3168a_dac_dai_ops = {
478 .set_fmt = pcm3168a_set_dai_fmt_dac,
479 .set_sysclk = pcm3168a_set_dai_sysclk,
480 .hw_params = pcm3168a_hw_params,
481 .digital_mute = pcm3168a_digital_mute
482};
483
484static const struct snd_soc_dai_ops pcm3168a_adc_dai_ops = {
485 .set_fmt = pcm3168a_set_dai_fmt_adc,
486 .set_sysclk = pcm3168a_set_dai_sysclk,
487 .hw_params = pcm3168a_hw_params
488};
489
490static struct snd_soc_dai_driver pcm3168a_dais[] = {
491 {
492 .name = "pcm3168a-dac",
493 .playback = {
494 .stream_name = "Playback",
495 .channels_min = 1,
496 .channels_max = 8,
497 .rates = SNDRV_PCM_RATE_8000_192000,
498 .formats = PCM3168A_FORMATS
499 },
500 .ops = &pcm3168a_dac_dai_ops
501 },
502 {
503 .name = "pcm3168a-adc",
504 .capture = {
505 .stream_name = "Capture",
506 .channels_min = 1,
507 .channels_max = 6,
508 .rates = SNDRV_PCM_RATE_8000_96000,
509 .formats = PCM3168A_FORMATS
510 },
511 .ops = &pcm3168a_adc_dai_ops
512 },
513};
514
515static const struct reg_default pcm3168a_reg_default[] = {
516 { PCM3168A_RST_SMODE, PCM3168A_MRST_MASK | PCM3168A_SRST_MASK },
517 { PCM3168A_DAC_PWR_MST_FMT, 0x00 },
518 { PCM3168A_DAC_OP_FLT, 0x00 },
519 { PCM3168A_DAC_INV, 0x00 },
520 { PCM3168A_DAC_MUTE, 0x00 },
521 { PCM3168A_DAC_ZERO, 0x00 },
522 { PCM3168A_DAC_ATT_DEMP_ZF, 0x00 },
523 { PCM3168A_DAC_VOL_MASTER, 0xff },
524 { PCM3168A_DAC_VOL_CHAN_START, 0xff },
525 { PCM3168A_DAC_VOL_CHAN_START + 1, 0xff },
526 { PCM3168A_DAC_VOL_CHAN_START + 2, 0xff },
527 { PCM3168A_DAC_VOL_CHAN_START + 3, 0xff },
528 { PCM3168A_DAC_VOL_CHAN_START + 4, 0xff },
529 { PCM3168A_DAC_VOL_CHAN_START + 5, 0xff },
530 { PCM3168A_DAC_VOL_CHAN_START + 6, 0xff },
531 { PCM3168A_DAC_VOL_CHAN_START + 7, 0xff },
532 { PCM3168A_ADC_SMODE, 0x00 },
533 { PCM3168A_ADC_MST_FMT, 0x00 },
534 { PCM3168A_ADC_PWR_HPFB, 0x00 },
535 { PCM3168A_ADC_SEAD, 0x00 },
536 { PCM3168A_ADC_INV, 0x00 },
537 { PCM3168A_ADC_MUTE, 0x00 },
538 { PCM3168A_ADC_OV, 0x00 },
539 { PCM3168A_ADC_ATT_OVF, 0x00 },
540 { PCM3168A_ADC_VOL_MASTER, 0xd3 },
541 { PCM3168A_ADC_VOL_CHAN_START, 0xd3 },
542 { PCM3168A_ADC_VOL_CHAN_START + 1, 0xd3 },
543 { PCM3168A_ADC_VOL_CHAN_START + 2, 0xd3 },
544 { PCM3168A_ADC_VOL_CHAN_START + 3, 0xd3 },
545 { PCM3168A_ADC_VOL_CHAN_START + 4, 0xd3 },
546 { PCM3168A_ADC_VOL_CHAN_START + 5, 0xd3 }
547};
548
549static bool pcm3168a_readable_register(struct device *dev, unsigned int reg)
550{
551 if (reg >= PCM3168A_RST_SMODE)
552 return true;
553 else
554 return false;
555}
556
557static bool pcm3168a_volatile_register(struct device *dev, unsigned int reg)
558{
559 switch (reg) {
560 case PCM3168A_DAC_ZERO:
561 case PCM3168A_ADC_OV:
562 return true;
563 default:
564 return false;
565 }
566}
567
568static bool pcm3168a_writeable_register(struct device *dev, unsigned int reg)
569{
570 if (reg < PCM3168A_RST_SMODE)
571 return false;
572
573 switch (reg) {
574 case PCM3168A_DAC_ZERO:
575 case PCM3168A_ADC_OV:
576 return false;
577 default:
578 return true;
579 }
580}
581
582const struct regmap_config pcm3168a_regmap = {
583 .reg_bits = 8,
584 .val_bits = 8,
585
586 .max_register = PCM3168A_ADC_VOL_CHAN_START + 5,
587 .reg_defaults = pcm3168a_reg_default,
588 .num_reg_defaults = ARRAY_SIZE(pcm3168a_reg_default),
589 .readable_reg = pcm3168a_readable_register,
590 .volatile_reg = pcm3168a_volatile_register,
591 .writeable_reg = pcm3168a_writeable_register,
592 .cache_type = REGCACHE_FLAT
593};
594EXPORT_SYMBOL_GPL(pcm3168a_regmap);
595
596static const struct snd_soc_codec_driver pcm3168a_driver = {
597 .idle_bias_off = true,
598 .controls = pcm3168a_snd_controls,
599 .num_controls = ARRAY_SIZE(pcm3168a_snd_controls),
600 .dapm_widgets = pcm3168a_dapm_widgets,
601 .num_dapm_widgets = ARRAY_SIZE(pcm3168a_dapm_widgets),
602 .dapm_routes = pcm3168a_dapm_routes,
603 .num_dapm_routes = ARRAY_SIZE(pcm3168a_dapm_routes)
604};
605
606int pcm3168a_probe(struct device *dev, struct regmap *regmap)
607{
608 struct pcm3168a_priv *pcm3168a;
609 int ret, i;
610
611 pcm3168a = devm_kzalloc(dev, sizeof(*pcm3168a), GFP_KERNEL);
612 if (pcm3168a == NULL)
613 return -ENOMEM;
614
615 dev_set_drvdata(dev, pcm3168a);
616
617 pcm3168a->scki = devm_clk_get(dev, "scki");
618 if (IS_ERR(pcm3168a->scki)) {
619 ret = PTR_ERR(pcm3168a->scki);
620 if (ret != -EPROBE_DEFER)
621 dev_err(dev, "failed to acquire clock 'scki': %d\n", ret);
622 return ret;
623 }
624
625 ret = clk_prepare_enable(pcm3168a->scki);
626 if (ret) {
627 dev_err(dev, "Failed to enable mclk: %d\n", ret);
628 return ret;
629 }
630
631 pcm3168a->sysclk = clk_get_rate(pcm3168a->scki);
632
633 for (i = 0; i < ARRAY_SIZE(pcm3168a->supplies); i++)
634 pcm3168a->supplies[i].supply = pcm3168a_supply_names[i];
635
636 ret = devm_regulator_bulk_get(dev,
637 ARRAY_SIZE(pcm3168a->supplies), pcm3168a->supplies);
638 if (ret) {
639 if (ret != -EPROBE_DEFER)
640 dev_err(dev, "failed to request supplies: %d\n", ret);
641 goto err_clk;
642 }
643
644 ret = regulator_bulk_enable(ARRAY_SIZE(pcm3168a->supplies),
645 pcm3168a->supplies);
646 if (ret) {
647 dev_err(dev, "failed to enable supplies: %d\n", ret);
648 goto err_clk;
649 }
650
651 pcm3168a->regmap = regmap;
652 if (IS_ERR(pcm3168a->regmap)) {
653 ret = PTR_ERR(pcm3168a->regmap);
654 dev_err(dev, "failed to allocate regmap: %d\n", ret);
655 goto err_regulator;
656 }
657
658 ret = pcm3168a_reset(pcm3168a);
659 if (ret) {
660 dev_err(dev, "Failed to reset device: %d\n", ret);
661 goto err_regulator;
662 }
663
664 pm_runtime_set_active(dev);
665 pm_runtime_enable(dev);
666 pm_runtime_idle(dev);
667
668 ret = snd_soc_register_codec(dev, &pcm3168a_driver, pcm3168a_dais,
669 ARRAY_SIZE(pcm3168a_dais));
670 if (ret) {
671 dev_err(dev, "failed to register codec: %d\n", ret);
672 goto err_regulator;
673 }
674
675 return 0;
676
677err_regulator:
678 regulator_bulk_disable(ARRAY_SIZE(pcm3168a->supplies),
679 pcm3168a->supplies);
680err_clk:
681 clk_disable_unprepare(pcm3168a->scki);
682
683 return ret;
684}
685EXPORT_SYMBOL_GPL(pcm3168a_probe);
686
687void pcm3168a_remove(struct device *dev)
688{
689 struct pcm3168a_priv *pcm3168a = dev_get_drvdata(dev);
690
691 snd_soc_unregister_codec(dev);
692 pm_runtime_disable(dev);
693 regulator_bulk_disable(ARRAY_SIZE(pcm3168a->supplies),
694 pcm3168a->supplies);
695 clk_disable_unprepare(pcm3168a->scki);
696}
697EXPORT_SYMBOL_GPL(pcm3168a_remove);
698
699#ifdef CONFIG_PM
700static int pcm3168a_rt_resume(struct device *dev)
701{
702 struct pcm3168a_priv *pcm3168a = dev_get_drvdata(dev);
703 int ret;
704
705 ret = clk_prepare_enable(pcm3168a->scki);
706 if (ret) {
707 dev_err(dev, "Failed to enable mclk: %d\n", ret);
708 return ret;
709 }
710
711 ret = regulator_bulk_enable(ARRAY_SIZE(pcm3168a->supplies),
712 pcm3168a->supplies);
713 if (ret) {
714 dev_err(dev, "Failed to enable supplies: %d\n", ret);
715 goto err_clk;
716 }
717
718 ret = pcm3168a_reset(pcm3168a);
719 if (ret) {
720 dev_err(dev, "Failed to reset device: %d\n", ret);
721 goto err_regulator;
722 }
723
724 regcache_cache_only(pcm3168a->regmap, false);
725
726 regcache_mark_dirty(pcm3168a->regmap);
727
728 ret = regcache_sync(pcm3168a->regmap);
729 if (ret) {
730 dev_err(dev, "Failed to sync regmap: %d\n", ret);
731 goto err_regulator;
732 }
733
734 return 0;
735
736err_regulator:
737 regulator_bulk_disable(ARRAY_SIZE(pcm3168a->supplies),
738 pcm3168a->supplies);
739err_clk:
740 clk_disable_unprepare(pcm3168a->scki);
741
742 return ret;
743}
744
745static int pcm3168a_rt_suspend(struct device *dev)
746{
747 struct pcm3168a_priv *pcm3168a = dev_get_drvdata(dev);
748
749 regcache_cache_only(pcm3168a->regmap, true);
750
751 regulator_bulk_disable(ARRAY_SIZE(pcm3168a->supplies),
752 pcm3168a->supplies);
753
754 clk_disable_unprepare(pcm3168a->scki);
755
756 return 0;
757}
758#endif
759
760const struct dev_pm_ops pcm3168a_pm_ops = {
761 SET_RUNTIME_PM_OPS(pcm3168a_rt_suspend, pcm3168a_rt_resume, NULL)
762};
763EXPORT_SYMBOL_GPL(pcm3168a_pm_ops);
764
765MODULE_DESCRIPTION("PCM3168A codec driver");
766MODULE_AUTHOR("Damien Horsley <Damien.Horsley@imgtec.com>");
767MODULE_LICENSE("GPL v2");
diff --git a/sound/soc/codecs/pcm3168a.h b/sound/soc/codecs/pcm3168a.h
new file mode 100644
index 000000000000..56c8332d82fb
--- /dev/null
+++ b/sound/soc/codecs/pcm3168a.h
@@ -0,0 +1,100 @@
1/*
2 * PCM3168A codec driver header
3 *
4 * Copyright (C) 2015 Imagination Technologies Ltd.
5 *
6 * Author: Damien Horsley <Damien.Horsley@imgtec.com>
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms and conditions of the GNU General Public License,
10 * version 2, as published by the Free Software Foundation.
11 */
12
13#ifndef __PCM3168A_H__
14#define __PCM3168A_H__
15
16extern const struct dev_pm_ops pcm3168a_pm_ops;
17extern const struct regmap_config pcm3168a_regmap;
18
19extern int pcm3168a_probe(struct device *dev, struct regmap *regmap);
20extern void pcm3168a_remove(struct device *dev);
21
22#define PCM3168A_RST_SMODE 0x40
23#define PCM3168A_MRST_MASK 0x80
24#define PCM3168A_SRST_MASK 0x40
25#define PCM3168A_DAC_SRDA_SHIFT 0
26#define PCM3168A_DAC_SRDA_MASK 0x3
27
28#define PCM3168A_DAC_PWR_MST_FMT 0x41
29#define PCM3168A_DAC_PSMDA_SHIFT 7
30#define PCM3168A_DAC_PSMDA_MASK 0x80
31#define PCM3168A_DAC_MSDA_SHIFT 4
32#define PCM3168A_DAC_MSDA_MASK 0x70
33#define PCM3168A_DAC_FMT_SHIFT 0
34#define PCM3168A_DAC_FMT_MASK 0xf
35
36#define PCM3168A_DAC_OP_FLT 0x42
37#define PCM3168A_DAC_OPEDA_SHIFT 4
38#define PCM3168A_DAC_OPEDA_MASK 0xf0
39#define PCM3168A_DAC_FLT_SHIFT 0
40#define PCM3168A_DAC_FLT_MASK 0xf
41
42#define PCM3168A_DAC_INV 0x43
43
44#define PCM3168A_DAC_MUTE 0x44
45
46#define PCM3168A_DAC_ZERO 0x45
47
48#define PCM3168A_DAC_ATT_DEMP_ZF 0x46
49#define PCM3168A_DAC_ATMDDA_MASK 0x80
50#define PCM3168A_DAC_ATMDDA_SHIFT 7
51#define PCM3168A_DAC_ATSPDA_MASK 0x40
52#define PCM3168A_DAC_ATSPDA_SHIFT 6
53#define PCM3168A_DAC_DEMP_SHIFT 4
54#define PCM3168A_DAC_DEMP_MASK 0x30
55#define PCM3168A_DAC_AZRO_SHIFT 1
56#define PCM3168A_DAC_AZRO_MASK 0xe
57#define PCM3168A_DAC_ZREV_MASK 0x1
58#define PCM3168A_DAC_ZREV_SHIFT 0
59
60#define PCM3168A_DAC_VOL_MASTER 0x47
61
62#define PCM3168A_DAC_VOL_CHAN_START 0x48
63
64#define PCM3168A_ADC_SMODE 0x50
65#define PCM3168A_ADC_SRAD_SHIFT 0
66#define PCM3168A_ADC_SRAD_MASK 0x3
67
68#define PCM3168A_ADC_MST_FMT 0x51
69#define PCM3168A_ADC_MSAD_SHIFT 4
70#define PCM3168A_ADC_MSAD_MASK 0x70
71#define PCM3168A_ADC_FMTAD_SHIFT 0
72#define PCM3168A_ADC_FMTAD_MASK 0x7
73
74#define PCM3168A_ADC_PWR_HPFB 0x52
75#define PCM3168A_ADC_PSVAD_SHIFT 4
76#define PCM3168A_ADC_PSVAD_MASK 0x70
77#define PCM3168A_ADC_BYP_SHIFT 0
78#define PCM3168A_ADC_BYP_MASK 0x7
79
80#define PCM3168A_ADC_SEAD 0x53
81
82#define PCM3168A_ADC_INV 0x54
83
84#define PCM3168A_ADC_MUTE 0x55
85
86#define PCM3168A_ADC_OV 0x56
87
88#define PCM3168A_ADC_ATT_OVF 0x57
89#define PCM3168A_ADC_ATMDAD_MASK 0x80
90#define PCM3168A_ADC_ATMDAD_SHIFT 7
91#define PCM3168A_ADC_ATSPAD_MASK 0x40
92#define PCM3168A_ADC_ATSPAD_SHIFT 6
93#define PCM3168A_ADC_OVFP_MASK 0x1
94#define PCM3168A_ADC_OVFP_SHIFT 0
95
96#define PCM3168A_ADC_VOL_MASTER 0x58
97
98#define PCM3168A_ADC_VOL_CHAN_START 0x59
99
100#endif
diff --git a/sound/soc/codecs/rt286.c b/sound/soc/codecs/rt286.c
index af2ed774b552..bc08f0c5a5f6 100644
--- a/sound/soc/codecs/rt286.c
+++ b/sound/soc/codecs/rt286.c
@@ -1114,6 +1114,12 @@ static const struct dmi_system_id force_combo_jack_table[] = {
1114 DMI_MATCH(DMI_BOARD_NAME, "Wilson Beach SDS") 1114 DMI_MATCH(DMI_BOARD_NAME, "Wilson Beach SDS")
1115 } 1115 }
1116 }, 1116 },
1117 {
1118 .ident = "Intel Skylake RVP",
1119 .matches = {
1120 DMI_MATCH(DMI_PRODUCT_NAME, "Skylake Client platform")
1121 }
1122 },
1117 { } 1123 { }
1118}; 1124};
1119 1125
diff --git a/sound/soc/codecs/rt298.c b/sound/soc/codecs/rt298.c
index b3f795c60749..30c6de62ae6c 100644
--- a/sound/soc/codecs/rt298.c
+++ b/sound/soc/codecs/rt298.c
@@ -855,8 +855,6 @@ static int rt298_set_dai_sysclk(struct snd_soc_dai *dai,
855 snd_soc_update_bits(codec, 855 snd_soc_update_bits(codec,
856 RT298_I2S_CTRL2, 0x0100, 0x0100); 856 RT298_I2S_CTRL2, 0x0100, 0x0100);
857 snd_soc_update_bits(codec, 857 snd_soc_update_bits(codec,
858 RT298_PLL_CTRL, 0x4, 0x4);
859 snd_soc_update_bits(codec,
860 RT298_PLL_CTRL1, 0x20, 0x0); 858 RT298_PLL_CTRL1, 0x20, 0x0);
861 } 859 }
862 860
diff --git a/sound/soc/codecs/rt5616.c b/sound/soc/codecs/rt5616.c
new file mode 100644
index 000000000000..1c10d8ed39d2
--- /dev/null
+++ b/sound/soc/codecs/rt5616.c
@@ -0,0 +1,1381 @@
1/*
2 * rt5616.c -- RT5616 ALSA SoC audio codec driver
3 *
4 * Copyright 2015 Realtek Semiconductor Corp.
5 * Author: Bard Liao <bardliao@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/i2c.h>
18#include <linux/platform_device.h>
19#include <linux/spi/spi.h>
20#include <sound/core.h>
21#include <sound/pcm.h>
22#include <sound/pcm_params.h>
23#include <sound/soc.h>
24#include <sound/soc-dapm.h>
25#include <sound/initval.h>
26#include <sound/tlv.h>
27
28#include "rl6231.h"
29#include "rt5616.h"
30
31#define RT5616_PR_RANGE_BASE (0xff + 1)
32#define RT5616_PR_SPACING 0x100
33
34#define RT5616_PR_BASE (RT5616_PR_RANGE_BASE + (0 * RT5616_PR_SPACING))
35
36static const struct regmap_range_cfg rt5616_ranges[] = {
37 {
38 .name = "PR",
39 .range_min = RT5616_PR_BASE,
40 .range_max = RT5616_PR_BASE + 0xf8,
41 .selector_reg = RT5616_PRIV_INDEX,
42 .selector_mask = 0xff,
43 .selector_shift = 0x0,
44 .window_start = RT5616_PRIV_DATA,
45 .window_len = 0x1,
46 },
47};
48
49static const struct reg_sequence init_list[] = {
50 {RT5616_PR_BASE + 0x3d, 0x3e00},
51 {RT5616_PR_BASE + 0x25, 0x6110},
52 {RT5616_PR_BASE + 0x20, 0x611f},
53 {RT5616_PR_BASE + 0x21, 0x4040},
54 {RT5616_PR_BASE + 0x23, 0x0004},
55};
56#define RT5616_INIT_REG_LEN ARRAY_SIZE(init_list)
57
58static const struct reg_default rt5616_reg[] = {
59 { 0x00, 0x0021 },
60 { 0x02, 0xc8c8 },
61 { 0x03, 0xc8c8 },
62 { 0x05, 0x0000 },
63 { 0x0d, 0x0000 },
64 { 0x0f, 0x0808 },
65 { 0x19, 0xafaf },
66 { 0x1c, 0x2f2f },
67 { 0x1e, 0x0000 },
68 { 0x27, 0x7860 },
69 { 0x29, 0x8080 },
70 { 0x2a, 0x5252 },
71 { 0x3b, 0x0000 },
72 { 0x3c, 0x006f },
73 { 0x3d, 0x0000 },
74 { 0x3e, 0x006f },
75 { 0x45, 0x6000 },
76 { 0x4d, 0x0000 },
77 { 0x4e, 0x0000 },
78 { 0x4f, 0x0279 },
79 { 0x50, 0x0000 },
80 { 0x51, 0x0000 },
81 { 0x52, 0x0279 },
82 { 0x53, 0xf000 },
83 { 0x61, 0x0000 },
84 { 0x62, 0x0000 },
85 { 0x63, 0x00c0 },
86 { 0x64, 0x0000 },
87 { 0x65, 0x0000 },
88 { 0x66, 0x0000 },
89 { 0x70, 0x8000 },
90 { 0x73, 0x1104 },
91 { 0x74, 0x0c00 },
92 { 0x80, 0x0000 },
93 { 0x81, 0x0000 },
94 { 0x82, 0x0000 },
95 { 0x8b, 0x0600 },
96 { 0x8e, 0x0004 },
97 { 0x8f, 0x1100 },
98 { 0x90, 0x0000 },
99 { 0x91, 0x0000 },
100 { 0x92, 0x0000 },
101 { 0x93, 0x2000 },
102 { 0x94, 0x0200 },
103 { 0x95, 0x0000 },
104 { 0xb0, 0x2080 },
105 { 0xb1, 0x0000 },
106 { 0xb2, 0x0000 },
107 { 0xb4, 0x2206 },
108 { 0xb5, 0x1f00 },
109 { 0xb6, 0x0000 },
110 { 0xb7, 0x0000 },
111 { 0xbb, 0x0000 },
112 { 0xbc, 0x0000 },
113 { 0xbd, 0x0000 },
114 { 0xbe, 0x0000 },
115 { 0xbf, 0x0000 },
116 { 0xc0, 0x0100 },
117 { 0xc1, 0x0000 },
118 { 0xc2, 0x0000 },
119 { 0xc8, 0x0000 },
120 { 0xc9, 0x0000 },
121 { 0xca, 0x0000 },
122 { 0xcb, 0x0000 },
123 { 0xcc, 0x0000 },
124 { 0xcd, 0x0000 },
125 { 0xce, 0x0000 },
126 { 0xcf, 0x0013 },
127 { 0xd0, 0x0680 },
128 { 0xd1, 0x1c17 },
129 { 0xd3, 0xb320 },
130 { 0xd4, 0x0000 },
131 { 0xd6, 0x0000 },
132 { 0xd7, 0x0000 },
133 { 0xd9, 0x0809 },
134 { 0xda, 0x0000 },
135 { 0xfa, 0x0010 },
136 { 0xfb, 0x0000 },
137 { 0xfc, 0x0000 },
138 { 0xfe, 0x10ec },
139 { 0xff, 0x6281 },
140};
141
142struct rt5616_priv {
143 struct snd_soc_codec *codec;
144 struct delayed_work patch_work;
145 struct regmap *regmap;
146
147 int sysclk;
148 int sysclk_src;
149 int lrck[RT5616_AIFS];
150 int bclk[RT5616_AIFS];
151 int master[RT5616_AIFS];
152
153 int pll_src;
154 int pll_in;
155 int pll_out;
156
157};
158
159static bool rt5616_volatile_register(struct device *dev, unsigned int reg)
160{
161 int i;
162
163 for (i = 0; i < ARRAY_SIZE(rt5616_ranges); i++) {
164 if (reg >= rt5616_ranges[i].range_min &&
165 reg <= rt5616_ranges[i].range_max) {
166 return true;
167 }
168 }
169
170 switch (reg) {
171 case RT5616_RESET:
172 case RT5616_PRIV_DATA:
173 case RT5616_EQ_CTRL1:
174 case RT5616_DRC_AGC_1:
175 case RT5616_IRQ_CTRL2:
176 case RT5616_INT_IRQ_ST:
177 case RT5616_PGM_REG_ARR1:
178 case RT5616_PGM_REG_ARR3:
179 case RT5616_VENDOR_ID:
180 case RT5616_DEVICE_ID:
181 return true;
182 default:
183 return false;
184 }
185}
186
187static bool rt5616_readable_register(struct device *dev, unsigned int reg)
188{
189 int i;
190
191 for (i = 0; i < ARRAY_SIZE(rt5616_ranges); i++) {
192 if (reg >= rt5616_ranges[i].range_min &&
193 reg <= rt5616_ranges[i].range_max) {
194 return true;
195 }
196 }
197
198 switch (reg) {
199 case RT5616_RESET:
200 case RT5616_VERSION_ID:
201 case RT5616_VENDOR_ID:
202 case RT5616_DEVICE_ID:
203 case RT5616_HP_VOL:
204 case RT5616_LOUT_CTRL1:
205 case RT5616_LOUT_CTRL2:
206 case RT5616_IN1_IN2:
207 case RT5616_INL1_INR1_VOL:
208 case RT5616_DAC1_DIG_VOL:
209 case RT5616_ADC_DIG_VOL:
210 case RT5616_ADC_BST_VOL:
211 case RT5616_STO1_ADC_MIXER:
212 case RT5616_AD_DA_MIXER:
213 case RT5616_STO_DAC_MIXER:
214 case RT5616_REC_L1_MIXER:
215 case RT5616_REC_L2_MIXER:
216 case RT5616_REC_R1_MIXER:
217 case RT5616_REC_R2_MIXER:
218 case RT5616_HPO_MIXER:
219 case RT5616_OUT_L1_MIXER:
220 case RT5616_OUT_L2_MIXER:
221 case RT5616_OUT_L3_MIXER:
222 case RT5616_OUT_R1_MIXER:
223 case RT5616_OUT_R2_MIXER:
224 case RT5616_OUT_R3_MIXER:
225 case RT5616_LOUT_MIXER:
226 case RT5616_PWR_DIG1:
227 case RT5616_PWR_DIG2:
228 case RT5616_PWR_ANLG1:
229 case RT5616_PWR_ANLG2:
230 case RT5616_PWR_MIXER:
231 case RT5616_PWR_VOL:
232 case RT5616_PRIV_INDEX:
233 case RT5616_PRIV_DATA:
234 case RT5616_I2S1_SDP:
235 case RT5616_ADDA_CLK1:
236 case RT5616_ADDA_CLK2:
237 case RT5616_GLB_CLK:
238 case RT5616_PLL_CTRL1:
239 case RT5616_PLL_CTRL2:
240 case RT5616_HP_OVCD:
241 case RT5616_DEPOP_M1:
242 case RT5616_DEPOP_M2:
243 case RT5616_DEPOP_M3:
244 case RT5616_CHARGE_PUMP:
245 case RT5616_PV_DET_SPK_G:
246 case RT5616_MICBIAS:
247 case RT5616_A_JD_CTL1:
248 case RT5616_A_JD_CTL2:
249 case RT5616_EQ_CTRL1:
250 case RT5616_EQ_CTRL2:
251 case RT5616_WIND_FILTER:
252 case RT5616_DRC_AGC_1:
253 case RT5616_DRC_AGC_2:
254 case RT5616_DRC_AGC_3:
255 case RT5616_SVOL_ZC:
256 case RT5616_JD_CTRL1:
257 case RT5616_JD_CTRL2:
258 case RT5616_IRQ_CTRL1:
259 case RT5616_IRQ_CTRL2:
260 case RT5616_INT_IRQ_ST:
261 case RT5616_GPIO_CTRL1:
262 case RT5616_GPIO_CTRL2:
263 case RT5616_GPIO_CTRL3:
264 case RT5616_PGM_REG_ARR1:
265 case RT5616_PGM_REG_ARR2:
266 case RT5616_PGM_REG_ARR3:
267 case RT5616_PGM_REG_ARR4:
268 case RT5616_PGM_REG_ARR5:
269 case RT5616_SCB_FUNC:
270 case RT5616_SCB_CTRL:
271 case RT5616_BASE_BACK:
272 case RT5616_MP3_PLUS1:
273 case RT5616_MP3_PLUS2:
274 case RT5616_ADJ_HPF_CTRL1:
275 case RT5616_ADJ_HPF_CTRL2:
276 case RT5616_HP_CALIB_AMP_DET:
277 case RT5616_HP_CALIB2:
278 case RT5616_SV_ZCD1:
279 case RT5616_SV_ZCD2:
280 case RT5616_D_MISC:
281 case RT5616_DUMMY2:
282 case RT5616_DUMMY3:
283 return true;
284 default:
285 return false;
286 }
287}
288
289static const DECLARE_TLV_DB_SCALE(out_vol_tlv, -4650, 150, 0);
290static const DECLARE_TLV_DB_SCALE(dac_vol_tlv, -65625, 375, 0);
291static const DECLARE_TLV_DB_SCALE(in_vol_tlv, -3450, 150, 0);
292static const DECLARE_TLV_DB_SCALE(adc_vol_tlv, -17625, 375, 0);
293static const DECLARE_TLV_DB_SCALE(adc_bst_tlv, 0, 1200, 0);
294
295/* {0, +20, +24, +30, +35, +40, +44, +50, +52} dB */
296static unsigned int bst_tlv[] = {
297 TLV_DB_RANGE_HEAD(7),
298 0, 0, TLV_DB_SCALE_ITEM(0, 0, 0),
299 1, 1, TLV_DB_SCALE_ITEM(2000, 0, 0),
300 2, 2, TLV_DB_SCALE_ITEM(2400, 0, 0),
301 3, 5, TLV_DB_SCALE_ITEM(3000, 500, 0),
302 6, 6, TLV_DB_SCALE_ITEM(4400, 0, 0),
303 7, 7, TLV_DB_SCALE_ITEM(5000, 0, 0),
304 8, 8, TLV_DB_SCALE_ITEM(5200, 0, 0),
305};
306
307static const struct snd_kcontrol_new rt5616_snd_controls[] = {
308 /* Headphone Output Volume */
309 SOC_DOUBLE("HP Playback Switch", RT5616_HP_VOL,
310 RT5616_L_MUTE_SFT, RT5616_R_MUTE_SFT, 1, 1),
311 SOC_DOUBLE_TLV("HP Playback Volume", RT5616_HP_VOL,
312 RT5616_L_VOL_SFT, RT5616_R_VOL_SFT, 39, 1, out_vol_tlv),
313 /* OUTPUT Control */
314 SOC_DOUBLE("OUT Playback Switch", RT5616_LOUT_CTRL1,
315 RT5616_L_MUTE_SFT, RT5616_R_MUTE_SFT, 1, 1),
316 SOC_DOUBLE("OUT Channel Switch", RT5616_LOUT_CTRL1,
317 RT5616_VOL_L_SFT, RT5616_VOL_R_SFT, 1, 1),
318 SOC_DOUBLE_TLV("OUT Playback Volume", RT5616_LOUT_CTRL1,
319 RT5616_L_VOL_SFT, RT5616_R_VOL_SFT, 39, 1, out_vol_tlv),
320
321 /* DAC Digital Volume */
322 SOC_DOUBLE_TLV("DAC1 Playback Volume", RT5616_DAC1_DIG_VOL,
323 RT5616_L_VOL_SFT, RT5616_R_VOL_SFT,
324 175, 0, dac_vol_tlv),
325 /* IN1/IN2 Control */
326 SOC_SINGLE_TLV("IN1 Boost Volume", RT5616_IN1_IN2,
327 RT5616_BST_SFT1, 8, 0, bst_tlv),
328 SOC_SINGLE_TLV("IN2 Boost Volume", RT5616_IN1_IN2,
329 RT5616_BST_SFT2, 8, 0, bst_tlv),
330 /* INL/INR Volume Control */
331 SOC_DOUBLE_TLV("IN Capture Volume", RT5616_INL1_INR1_VOL,
332 RT5616_INL_VOL_SFT, RT5616_INR_VOL_SFT,
333 31, 1, in_vol_tlv),
334 /* ADC Digital Volume Control */
335 SOC_DOUBLE("ADC Capture Switch", RT5616_ADC_DIG_VOL,
336 RT5616_L_MUTE_SFT, RT5616_R_MUTE_SFT, 1, 1),
337 SOC_DOUBLE_TLV("ADC Capture Volume", RT5616_ADC_DIG_VOL,
338 RT5616_L_VOL_SFT, RT5616_R_VOL_SFT,
339 127, 0, adc_vol_tlv),
340
341 /* ADC Boost Volume Control */
342 SOC_DOUBLE_TLV("ADC Boost Volume", RT5616_ADC_BST_VOL,
343 RT5616_ADC_L_BST_SFT, RT5616_ADC_R_BST_SFT,
344 3, 0, adc_bst_tlv),
345};
346
347static int is_sys_clk_from_pll(struct snd_soc_dapm_widget *source,
348 struct snd_soc_dapm_widget *sink)
349{
350 unsigned int val;
351
352 val = snd_soc_read(snd_soc_dapm_to_codec(source->dapm), RT5616_GLB_CLK);
353 val &= RT5616_SCLK_SRC_MASK;
354 if (val == RT5616_SCLK_SRC_PLL1)
355 return 1;
356 else
357 return 0;
358}
359
360/* Digital Mixer */
361static const struct snd_kcontrol_new rt5616_sto1_adc_l_mix[] = {
362 SOC_DAPM_SINGLE("ADC1 Switch", RT5616_STO1_ADC_MIXER,
363 RT5616_M_STO1_ADC_L1_SFT, 1, 1),
364};
365
366static const struct snd_kcontrol_new rt5616_sto1_adc_r_mix[] = {
367 SOC_DAPM_SINGLE("ADC1 Switch", RT5616_STO1_ADC_MIXER,
368 RT5616_M_STO1_ADC_R1_SFT, 1, 1),
369};
370
371static const struct snd_kcontrol_new rt5616_dac_l_mix[] = {
372 SOC_DAPM_SINGLE("Stereo ADC Switch", RT5616_AD_DA_MIXER,
373 RT5616_M_ADCMIX_L_SFT, 1, 1),
374 SOC_DAPM_SINGLE("INF1 Switch", RT5616_AD_DA_MIXER,
375 RT5616_M_IF1_DAC_L_SFT, 1, 1),
376};
377
378static const struct snd_kcontrol_new rt5616_dac_r_mix[] = {
379 SOC_DAPM_SINGLE("Stereo ADC Switch", RT5616_AD_DA_MIXER,
380 RT5616_M_ADCMIX_R_SFT, 1, 1),
381 SOC_DAPM_SINGLE("INF1 Switch", RT5616_AD_DA_MIXER,
382 RT5616_M_IF1_DAC_R_SFT, 1, 1),
383};
384
385static const struct snd_kcontrol_new rt5616_sto_dac_l_mix[] = {
386 SOC_DAPM_SINGLE("DAC L1 Switch", RT5616_STO_DAC_MIXER,
387 RT5616_M_DAC_L1_MIXL_SFT, 1, 1),
388 SOC_DAPM_SINGLE("DAC R1 Switch", RT5616_STO_DAC_MIXER,
389 RT5616_M_DAC_R1_MIXL_SFT, 1, 1),
390};
391
392static const struct snd_kcontrol_new rt5616_sto_dac_r_mix[] = {
393 SOC_DAPM_SINGLE("DAC R1 Switch", RT5616_STO_DAC_MIXER,
394 RT5616_M_DAC_R1_MIXR_SFT, 1, 1),
395 SOC_DAPM_SINGLE("DAC L1 Switch", RT5616_STO_DAC_MIXER,
396 RT5616_M_DAC_L1_MIXR_SFT, 1, 1),
397};
398
399/* Analog Input Mixer */
400static const struct snd_kcontrol_new rt5616_rec_l_mix[] = {
401 SOC_DAPM_SINGLE("INL1 Switch", RT5616_REC_L2_MIXER,
402 RT5616_M_IN1_L_RM_L_SFT, 1, 1),
403 SOC_DAPM_SINGLE("BST2 Switch", RT5616_REC_L2_MIXER,
404 RT5616_M_BST2_RM_L_SFT, 1, 1),
405 SOC_DAPM_SINGLE("BST1 Switch", RT5616_REC_L2_MIXER,
406 RT5616_M_BST1_RM_L_SFT, 1, 1),
407};
408
409static const struct snd_kcontrol_new rt5616_rec_r_mix[] = {
410 SOC_DAPM_SINGLE("INR1 Switch", RT5616_REC_R2_MIXER,
411 RT5616_M_IN1_R_RM_R_SFT, 1, 1),
412 SOC_DAPM_SINGLE("BST2 Switch", RT5616_REC_R2_MIXER,
413 RT5616_M_BST2_RM_R_SFT, 1, 1),
414 SOC_DAPM_SINGLE("BST1 Switch", RT5616_REC_R2_MIXER,
415 RT5616_M_BST1_RM_R_SFT, 1, 1),
416};
417
418/* Analog Output Mixer */
419
420static const struct snd_kcontrol_new rt5616_out_l_mix[] = {
421 SOC_DAPM_SINGLE("BST1 Switch", RT5616_OUT_L3_MIXER,
422 RT5616_M_BST1_OM_L_SFT, 1, 1),
423 SOC_DAPM_SINGLE("BST2 Switch", RT5616_OUT_L3_MIXER,
424 RT5616_M_BST2_OM_L_SFT, 1, 1),
425 SOC_DAPM_SINGLE("INL1 Switch", RT5616_OUT_L3_MIXER,
426 RT5616_M_IN1_L_OM_L_SFT, 1, 1),
427 SOC_DAPM_SINGLE("REC MIXL Switch", RT5616_OUT_L3_MIXER,
428 RT5616_M_RM_L_OM_L_SFT, 1, 1),
429 SOC_DAPM_SINGLE("DAC L1 Switch", RT5616_OUT_L3_MIXER,
430 RT5616_M_DAC_L1_OM_L_SFT, 1, 1),
431};
432
433static const struct snd_kcontrol_new rt5616_out_r_mix[] = {
434 SOC_DAPM_SINGLE("BST2 Switch", RT5616_OUT_R3_MIXER,
435 RT5616_M_BST2_OM_R_SFT, 1, 1),
436 SOC_DAPM_SINGLE("BST1 Switch", RT5616_OUT_R3_MIXER,
437 RT5616_M_BST1_OM_R_SFT, 1, 1),
438 SOC_DAPM_SINGLE("INR1 Switch", RT5616_OUT_R3_MIXER,
439 RT5616_M_IN1_R_OM_R_SFT, 1, 1),
440 SOC_DAPM_SINGLE("REC MIXR Switch", RT5616_OUT_R3_MIXER,
441 RT5616_M_RM_R_OM_R_SFT, 1, 1),
442 SOC_DAPM_SINGLE("DAC R1 Switch", RT5616_OUT_R3_MIXER,
443 RT5616_M_DAC_R1_OM_R_SFT, 1, 1),
444};
445
446static const struct snd_kcontrol_new rt5616_hpo_mix[] = {
447 SOC_DAPM_SINGLE("DAC1 Switch", RT5616_HPO_MIXER,
448 RT5616_M_DAC1_HM_SFT, 1, 1),
449 SOC_DAPM_SINGLE("HPVOL Switch", RT5616_HPO_MIXER,
450 RT5616_M_HPVOL_HM_SFT, 1, 1),
451};
452
453static const struct snd_kcontrol_new rt5616_lout_mix[] = {
454 SOC_DAPM_SINGLE("DAC L1 Switch", RT5616_LOUT_MIXER,
455 RT5616_M_DAC_L1_LM_SFT, 1, 1),
456 SOC_DAPM_SINGLE("DAC R1 Switch", RT5616_LOUT_MIXER,
457 RT5616_M_DAC_R1_LM_SFT, 1, 1),
458 SOC_DAPM_SINGLE("OUTVOL L Switch", RT5616_LOUT_MIXER,
459 RT5616_M_OV_L_LM_SFT, 1, 1),
460 SOC_DAPM_SINGLE("OUTVOL R Switch", RT5616_LOUT_MIXER,
461 RT5616_M_OV_R_LM_SFT, 1, 1),
462};
463
464static int rt5616_adc_event(struct snd_soc_dapm_widget *w,
465 struct snd_kcontrol *kcontrol, int event)
466{
467 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
468
469 switch (event) {
470 case SND_SOC_DAPM_POST_PMU:
471 snd_soc_update_bits(codec, RT5616_ADC_DIG_VOL,
472 RT5616_L_MUTE | RT5616_R_MUTE, 0);
473 break;
474
475 case SND_SOC_DAPM_POST_PMD:
476 snd_soc_update_bits(codec, RT5616_ADC_DIG_VOL,
477 RT5616_L_MUTE | RT5616_R_MUTE,
478 RT5616_L_MUTE | RT5616_R_MUTE);
479 break;
480
481 default:
482 return 0;
483 }
484
485 return 0;
486}
487
488static int rt5616_charge_pump_event(struct snd_soc_dapm_widget *w,
489 struct snd_kcontrol *kcontrol, int event)
490{
491 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
492
493 switch (event) {
494 case SND_SOC_DAPM_POST_PMU:
495 /* depop parameters */
496 snd_soc_update_bits(codec, RT5616_DEPOP_M2,
497 RT5616_DEPOP_MASK, RT5616_DEPOP_MAN);
498 snd_soc_update_bits(codec, RT5616_DEPOP_M1,
499 RT5616_HP_CP_MASK | RT5616_HP_SG_MASK |
500 RT5616_HP_CB_MASK, RT5616_HP_CP_PU |
501 RT5616_HP_SG_DIS | RT5616_HP_CB_PU);
502 snd_soc_write(codec, RT5616_PR_BASE +
503 RT5616_HP_DCC_INT1, 0x9f00);
504 /* headphone amp power on */
505 snd_soc_update_bits(codec, RT5616_PWR_ANLG1,
506 RT5616_PWR_FV1 | RT5616_PWR_FV2, 0);
507 snd_soc_update_bits(codec, RT5616_PWR_VOL,
508 RT5616_PWR_HV_L | RT5616_PWR_HV_R,
509 RT5616_PWR_HV_L | RT5616_PWR_HV_R);
510 snd_soc_update_bits(codec, RT5616_PWR_ANLG1,
511 RT5616_PWR_HP_L | RT5616_PWR_HP_R |
512 RT5616_PWR_HA, RT5616_PWR_HP_L |
513 RT5616_PWR_HP_R | RT5616_PWR_HA);
514 msleep(50);
515 snd_soc_update_bits(codec, RT5616_PWR_ANLG1,
516 RT5616_PWR_FV1 | RT5616_PWR_FV2,
517 RT5616_PWR_FV1 | RT5616_PWR_FV2);
518
519 snd_soc_update_bits(codec, RT5616_CHARGE_PUMP,
520 RT5616_PM_HP_MASK, RT5616_PM_HP_HV);
521 snd_soc_update_bits(codec, RT5616_PR_BASE +
522 RT5616_CHOP_DAC_ADC, 0x0200, 0x0200);
523 snd_soc_update_bits(codec, RT5616_DEPOP_M1,
524 RT5616_HP_CO_MASK | RT5616_HP_SG_MASK,
525 RT5616_HP_CO_EN | RT5616_HP_SG_EN);
526 break;
527 case SND_SOC_DAPM_PRE_PMD:
528 snd_soc_update_bits(codec, RT5616_PR_BASE +
529 RT5616_CHOP_DAC_ADC, 0x0200, 0x0);
530 snd_soc_update_bits(codec, RT5616_DEPOP_M1,
531 RT5616_HP_SG_MASK | RT5616_HP_L_SMT_MASK |
532 RT5616_HP_R_SMT_MASK, RT5616_HP_SG_DIS |
533 RT5616_HP_L_SMT_DIS | RT5616_HP_R_SMT_DIS);
534 /* headphone amp power down */
535 snd_soc_update_bits(codec, RT5616_DEPOP_M1,
536 RT5616_SMT_TRIG_MASK | RT5616_HP_CD_PD_MASK |
537 RT5616_HP_CO_MASK | RT5616_HP_CP_MASK |
538 RT5616_HP_SG_MASK | RT5616_HP_CB_MASK,
539 RT5616_SMT_TRIG_DIS | RT5616_HP_CD_PD_EN |
540 RT5616_HP_CO_DIS | RT5616_HP_CP_PD |
541 RT5616_HP_SG_EN | RT5616_HP_CB_PD);
542 snd_soc_update_bits(codec, RT5616_PWR_ANLG1,
543 RT5616_PWR_HP_L | RT5616_PWR_HP_R |
544 RT5616_PWR_HA, 0);
545 break;
546 default:
547 return 0;
548 }
549
550 return 0;
551}
552
553static int rt5616_hp_event(struct snd_soc_dapm_widget *w,
554 struct snd_kcontrol *kcontrol, int event)
555{
556 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
557
558 switch (event) {
559 case SND_SOC_DAPM_POST_PMU:
560 /* headphone unmute sequence */
561 snd_soc_update_bits(codec, RT5616_DEPOP_M3,
562 RT5616_CP_FQ1_MASK | RT5616_CP_FQ2_MASK |
563 RT5616_CP_FQ3_MASK,
564 (RT5616_CP_FQ_192_KHZ << RT5616_CP_FQ1_SFT) |
565 (RT5616_CP_FQ_12_KHZ << RT5616_CP_FQ2_SFT) |
566 (RT5616_CP_FQ_192_KHZ << RT5616_CP_FQ3_SFT));
567 snd_soc_write(codec, RT5616_PR_BASE +
568 RT5616_MAMP_INT_REG2, 0xfc00);
569 snd_soc_update_bits(codec, RT5616_DEPOP_M1,
570 RT5616_SMT_TRIG_MASK, RT5616_SMT_TRIG_EN);
571 snd_soc_update_bits(codec, RT5616_DEPOP_M1,
572 RT5616_RSTN_MASK, RT5616_RSTN_EN);
573 snd_soc_update_bits(codec, RT5616_DEPOP_M1,
574 RT5616_RSTN_MASK | RT5616_HP_L_SMT_MASK |
575 RT5616_HP_R_SMT_MASK, RT5616_RSTN_DIS |
576 RT5616_HP_L_SMT_EN | RT5616_HP_R_SMT_EN);
577 snd_soc_update_bits(codec, RT5616_HP_VOL,
578 RT5616_L_MUTE | RT5616_R_MUTE, 0);
579 msleep(100);
580 snd_soc_update_bits(codec, RT5616_DEPOP_M1,
581 RT5616_HP_SG_MASK | RT5616_HP_L_SMT_MASK |
582 RT5616_HP_R_SMT_MASK, RT5616_HP_SG_DIS |
583 RT5616_HP_L_SMT_DIS | RT5616_HP_R_SMT_DIS);
584 msleep(20);
585 snd_soc_update_bits(codec, RT5616_HP_CALIB_AMP_DET,
586 RT5616_HPD_PS_MASK, RT5616_HPD_PS_EN);
587 break;
588
589 case SND_SOC_DAPM_PRE_PMD:
590 /* headphone mute sequence */
591 snd_soc_update_bits(codec, RT5616_DEPOP_M3,
592 RT5616_CP_FQ1_MASK | RT5616_CP_FQ2_MASK |
593 RT5616_CP_FQ3_MASK,
594 (RT5616_CP_FQ_96_KHZ << RT5616_CP_FQ1_SFT) |
595 (RT5616_CP_FQ_12_KHZ << RT5616_CP_FQ2_SFT) |
596 (RT5616_CP_FQ_96_KHZ << RT5616_CP_FQ3_SFT));
597 snd_soc_write(codec, RT5616_PR_BASE +
598 RT5616_MAMP_INT_REG2, 0xfc00);
599 snd_soc_update_bits(codec, RT5616_DEPOP_M1,
600 RT5616_HP_SG_MASK, RT5616_HP_SG_EN);
601 snd_soc_update_bits(codec, RT5616_DEPOP_M1,
602 RT5616_RSTP_MASK, RT5616_RSTP_EN);
603 snd_soc_update_bits(codec, RT5616_DEPOP_M1,
604 RT5616_RSTP_MASK | RT5616_HP_L_SMT_MASK |
605 RT5616_HP_R_SMT_MASK, RT5616_RSTP_DIS |
606 RT5616_HP_L_SMT_EN | RT5616_HP_R_SMT_EN);
607 snd_soc_update_bits(codec, RT5616_HP_CALIB_AMP_DET,
608 RT5616_HPD_PS_MASK, RT5616_HPD_PS_DIS);
609 msleep(90);
610 snd_soc_update_bits(codec, RT5616_HP_VOL,
611 RT5616_L_MUTE | RT5616_R_MUTE,
612 RT5616_L_MUTE | RT5616_R_MUTE);
613 msleep(30);
614 break;
615
616 default:
617 return 0;
618 }
619
620 return 0;
621}
622
623static int rt5616_lout_event(struct snd_soc_dapm_widget *w,
624 struct snd_kcontrol *kcontrol, int event)
625{
626 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
627
628 switch (event) {
629 case SND_SOC_DAPM_POST_PMU:
630 snd_soc_update_bits(codec, RT5616_PWR_ANLG1,
631 RT5616_PWR_LM, RT5616_PWR_LM);
632 snd_soc_update_bits(codec, RT5616_LOUT_CTRL1,
633 RT5616_L_MUTE | RT5616_R_MUTE, 0);
634 break;
635
636 case SND_SOC_DAPM_PRE_PMD:
637 snd_soc_update_bits(codec, RT5616_LOUT_CTRL1,
638 RT5616_L_MUTE | RT5616_R_MUTE,
639 RT5616_L_MUTE | RT5616_R_MUTE);
640 snd_soc_update_bits(codec, RT5616_PWR_ANLG1,
641 RT5616_PWR_LM, 0);
642 break;
643
644 default:
645 return 0;
646 }
647
648 return 0;
649}
650
651static int rt5616_bst1_event(struct snd_soc_dapm_widget *w,
652 struct snd_kcontrol *kcontrol, int event)
653{
654 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
655
656 switch (event) {
657 case SND_SOC_DAPM_POST_PMU:
658 snd_soc_update_bits(codec, RT5616_PWR_ANLG2,
659 RT5616_PWR_BST1_OP2, RT5616_PWR_BST1_OP2);
660 break;
661
662 case SND_SOC_DAPM_PRE_PMD:
663 snd_soc_update_bits(codec, RT5616_PWR_ANLG2,
664 RT5616_PWR_BST1_OP2, 0);
665 break;
666
667 default:
668 return 0;
669 }
670
671 return 0;
672}
673
674static int rt5616_bst2_event(struct snd_soc_dapm_widget *w,
675 struct snd_kcontrol *kcontrol, int event)
676{
677 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
678
679 switch (event) {
680 case SND_SOC_DAPM_POST_PMU:
681 snd_soc_update_bits(codec, RT5616_PWR_ANLG2,
682 RT5616_PWR_BST2_OP2, RT5616_PWR_BST2_OP2);
683 break;
684
685 case SND_SOC_DAPM_PRE_PMD:
686 snd_soc_update_bits(codec, RT5616_PWR_ANLG2,
687 RT5616_PWR_BST2_OP2, 0);
688 break;
689
690 default:
691 return 0;
692 }
693
694 return 0;
695}
696
697static const struct snd_soc_dapm_widget rt5616_dapm_widgets[] = {
698 SND_SOC_DAPM_SUPPLY("PLL1", RT5616_PWR_ANLG2,
699 RT5616_PWR_PLL_BIT, 0, NULL, 0),
700 /* Input Side */
701 /* micbias */
702 SND_SOC_DAPM_SUPPLY("LDO", RT5616_PWR_ANLG1,
703 RT5616_PWR_LDO_BIT, 0, NULL, 0),
704 SND_SOC_DAPM_SUPPLY("micbias1", RT5616_PWR_ANLG2,
705 RT5616_PWR_MB1_BIT, 0, NULL, 0),
706
707 /* Input Lines */
708 SND_SOC_DAPM_INPUT("MIC1"),
709 SND_SOC_DAPM_INPUT("MIC2"),
710
711 SND_SOC_DAPM_INPUT("IN1P"),
712 SND_SOC_DAPM_INPUT("IN2P"),
713 SND_SOC_DAPM_INPUT("IN2N"),
714
715 /* Boost */
716 SND_SOC_DAPM_PGA_E("BST1", RT5616_PWR_ANLG2,
717 RT5616_PWR_BST1_BIT, 0, NULL, 0, rt5616_bst1_event,
718 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
719 SND_SOC_DAPM_PGA_E("BST2", RT5616_PWR_ANLG2,
720 RT5616_PWR_BST2_BIT, 0, NULL, 0, rt5616_bst2_event,
721 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
722 /* Input Volume */
723 SND_SOC_DAPM_PGA("INL1 VOL", RT5616_PWR_VOL,
724 RT5616_PWR_IN1_L_BIT, 0, NULL, 0),
725 SND_SOC_DAPM_PGA("INR1 VOL", RT5616_PWR_VOL,
726 RT5616_PWR_IN1_R_BIT, 0, NULL, 0),
727 SND_SOC_DAPM_PGA("INL2 VOL", RT5616_PWR_VOL,
728 RT5616_PWR_IN2_L_BIT, 0, NULL, 0),
729 SND_SOC_DAPM_PGA("INR2 VOL", RT5616_PWR_VOL,
730 RT5616_PWR_IN2_R_BIT, 0, NULL, 0),
731
732 /* REC Mixer */
733 SND_SOC_DAPM_MIXER("RECMIXL", RT5616_PWR_MIXER, RT5616_PWR_RM_L_BIT, 0,
734 rt5616_rec_l_mix, ARRAY_SIZE(rt5616_rec_l_mix)),
735 SND_SOC_DAPM_MIXER("RECMIXR", RT5616_PWR_MIXER, RT5616_PWR_RM_R_BIT, 0,
736 rt5616_rec_r_mix, ARRAY_SIZE(rt5616_rec_r_mix)),
737 /* ADCs */
738 SND_SOC_DAPM_ADC_E("ADC L", NULL, RT5616_PWR_DIG1,
739 RT5616_PWR_ADC_L_BIT, 0, rt5616_adc_event,
740 SND_SOC_DAPM_POST_PMD | SND_SOC_DAPM_POST_PMU),
741 SND_SOC_DAPM_ADC_E("ADC R", NULL, RT5616_PWR_DIG1,
742 RT5616_PWR_ADC_R_BIT, 0, rt5616_adc_event,
743 SND_SOC_DAPM_POST_PMD | SND_SOC_DAPM_POST_PMU),
744
745 /* ADC Mixer */
746 SND_SOC_DAPM_SUPPLY("stereo1 filter", RT5616_PWR_DIG2,
747 RT5616_PWR_ADC_STO1_F_BIT, 0, NULL, 0),
748 SND_SOC_DAPM_MIXER("Stereo1 ADC MIXL", SND_SOC_NOPM, 0, 0,
749 rt5616_sto1_adc_l_mix, ARRAY_SIZE(rt5616_sto1_adc_l_mix)),
750 SND_SOC_DAPM_MIXER("Stereo1 ADC MIXR", SND_SOC_NOPM, 0, 0,
751 rt5616_sto1_adc_r_mix, ARRAY_SIZE(rt5616_sto1_adc_r_mix)),
752
753 /* Digital Interface */
754 SND_SOC_DAPM_SUPPLY("I2S1", RT5616_PWR_DIG1,
755 RT5616_PWR_I2S1_BIT, 0, NULL, 0),
756 SND_SOC_DAPM_PGA("IF1 DAC", SND_SOC_NOPM, 0, 0, NULL, 0),
757 SND_SOC_DAPM_PGA("IF1 DAC1 L", SND_SOC_NOPM, 0, 0, NULL, 0),
758 SND_SOC_DAPM_PGA("IF1 DAC1 R", SND_SOC_NOPM, 0, 0, NULL, 0),
759 SND_SOC_DAPM_PGA("IF1 ADC1", SND_SOC_NOPM, 0, 0, NULL, 0),
760
761 /* Digital Interface Select */
762
763 /* Audio Interface */
764 SND_SOC_DAPM_AIF_IN("AIF1RX", "AIF1 Playback", 0, SND_SOC_NOPM, 0, 0),
765 SND_SOC_DAPM_AIF_OUT("AIF1TX", "AIF1 Capture", 0, SND_SOC_NOPM, 0, 0),
766
767 /* Audio DSP */
768 SND_SOC_DAPM_PGA("Audio DSP", SND_SOC_NOPM, 0, 0, NULL, 0),
769
770 /* Output Side */
771 /* DAC mixer before sound effect */
772 SND_SOC_DAPM_MIXER("DAC MIXL", SND_SOC_NOPM, 0, 0,
773 rt5616_dac_l_mix, ARRAY_SIZE(rt5616_dac_l_mix)),
774 SND_SOC_DAPM_MIXER("DAC MIXR", SND_SOC_NOPM, 0, 0,
775 rt5616_dac_r_mix, ARRAY_SIZE(rt5616_dac_r_mix)),
776
777 SND_SOC_DAPM_SUPPLY("Stero1 DAC Power", RT5616_PWR_DIG2,
778 RT5616_PWR_DAC_STO1_F_BIT, 0, NULL, 0),
779
780 /* DAC Mixer */
781 SND_SOC_DAPM_MIXER("Stereo DAC MIXL", SND_SOC_NOPM, 0, 0,
782 rt5616_sto_dac_l_mix, ARRAY_SIZE(rt5616_sto_dac_l_mix)),
783 SND_SOC_DAPM_MIXER("Stereo DAC MIXR", SND_SOC_NOPM, 0, 0,
784 rt5616_sto_dac_r_mix, ARRAY_SIZE(rt5616_sto_dac_r_mix)),
785
786 /* DACs */
787 SND_SOC_DAPM_DAC("DAC L1", NULL, RT5616_PWR_DIG1,
788 RT5616_PWR_DAC_L1_BIT, 0),
789 SND_SOC_DAPM_DAC("DAC R1", NULL, RT5616_PWR_DIG1,
790 RT5616_PWR_DAC_R1_BIT, 0),
791 /* OUT Mixer */
792 SND_SOC_DAPM_MIXER("OUT MIXL", RT5616_PWR_MIXER, RT5616_PWR_OM_L_BIT,
793 0, rt5616_out_l_mix, ARRAY_SIZE(rt5616_out_l_mix)),
794 SND_SOC_DAPM_MIXER("OUT MIXR", RT5616_PWR_MIXER, RT5616_PWR_OM_R_BIT,
795 0, rt5616_out_r_mix, ARRAY_SIZE(rt5616_out_r_mix)),
796 /* Output Volume */
797 SND_SOC_DAPM_PGA("OUTVOL L", RT5616_PWR_VOL,
798 RT5616_PWR_OV_L_BIT, 0, NULL, 0),
799 SND_SOC_DAPM_PGA("OUTVOL R", RT5616_PWR_VOL,
800 RT5616_PWR_OV_R_BIT, 0, NULL, 0),
801 SND_SOC_DAPM_PGA("HPOVOL L", RT5616_PWR_VOL,
802 RT5616_PWR_HV_L_BIT, 0, NULL, 0),
803 SND_SOC_DAPM_PGA("HPOVOL R", RT5616_PWR_VOL,
804 RT5616_PWR_HV_R_BIT, 0, NULL, 0),
805 SND_SOC_DAPM_PGA("DAC 1", SND_SOC_NOPM,
806 0, 0, NULL, 0),
807 SND_SOC_DAPM_PGA("DAC 2", SND_SOC_NOPM,
808 0, 0, NULL, 0),
809 SND_SOC_DAPM_PGA("HPOVOL", SND_SOC_NOPM,
810 0, 0, NULL, 0),
811 SND_SOC_DAPM_PGA("INL1", RT5616_PWR_VOL,
812 RT5616_PWR_IN1_L_BIT, 0, NULL, 0),
813 SND_SOC_DAPM_PGA("INR1", RT5616_PWR_VOL,
814 RT5616_PWR_IN1_R_BIT, 0, NULL, 0),
815 SND_SOC_DAPM_PGA("INL2", RT5616_PWR_VOL,
816 RT5616_PWR_IN2_L_BIT, 0, NULL, 0),
817 SND_SOC_DAPM_PGA("INR2", RT5616_PWR_VOL,
818 RT5616_PWR_IN2_R_BIT, 0, NULL, 0),
819 /* HPO/LOUT/Mono Mixer */
820 SND_SOC_DAPM_MIXER("HPO MIX", SND_SOC_NOPM, 0, 0,
821 rt5616_hpo_mix, ARRAY_SIZE(rt5616_hpo_mix)),
822 SND_SOC_DAPM_MIXER("LOUT MIX", SND_SOC_NOPM, 0, 0,
823 rt5616_lout_mix, ARRAY_SIZE(rt5616_lout_mix)),
824
825 SND_SOC_DAPM_PGA_S("HP amp", 1, SND_SOC_NOPM, 0, 0,
826 rt5616_hp_event, SND_SOC_DAPM_PRE_PMD |
827 SND_SOC_DAPM_POST_PMU),
828 SND_SOC_DAPM_PGA_S("LOUT amp", 1, SND_SOC_NOPM, 0, 0,
829 rt5616_lout_event, SND_SOC_DAPM_PRE_PMD |
830 SND_SOC_DAPM_POST_PMU),
831
832 SND_SOC_DAPM_SUPPLY_S("Charge Pump", 1, SND_SOC_NOPM, 0, 0,
833 rt5616_charge_pump_event, SND_SOC_DAPM_POST_PMU |
834 SND_SOC_DAPM_PRE_PMD),
835
836 /* Output Lines */
837 SND_SOC_DAPM_OUTPUT("HPOL"),
838 SND_SOC_DAPM_OUTPUT("HPOR"),
839 SND_SOC_DAPM_OUTPUT("LOUTL"),
840 SND_SOC_DAPM_OUTPUT("LOUTR"),
841};
842
843static const struct snd_soc_dapm_route rt5616_dapm_routes[] = {
844 {"IN1P", NULL, "LDO"},
845 {"IN2P", NULL, "LDO"},
846
847 {"IN1P", NULL, "MIC1"},
848 {"IN2P", NULL, "MIC2"},
849 {"IN2N", NULL, "MIC2"},
850
851 {"BST1", NULL, "IN1P"},
852 {"BST2", NULL, "IN2P"},
853 {"BST2", NULL, "IN2N"},
854 {"BST1", NULL, "micbias1"},
855 {"BST2", NULL, "micbias1"},
856
857 {"INL1 VOL", NULL, "IN2P"},
858 {"INR1 VOL", NULL, "IN2N"},
859
860 {"RECMIXL", "INL1 Switch", "INL1 VOL"},
861 {"RECMIXL", "BST2 Switch", "BST2"},
862 {"RECMIXL", "BST1 Switch", "BST1"},
863
864 {"RECMIXR", "INR1 Switch", "INR1 VOL"},
865 {"RECMIXR", "BST2 Switch", "BST2"},
866 {"RECMIXR", "BST1 Switch", "BST1"},
867
868 {"ADC L", NULL, "RECMIXL"},
869 {"ADC R", NULL, "RECMIXR"},
870
871 {"Stereo1 ADC MIXL", "ADC1 Switch", "ADC L"},
872 {"Stereo1 ADC MIXL", NULL, "stereo1 filter"},
873 {"stereo1 filter", NULL, "PLL1", is_sys_clk_from_pll},
874
875 {"Stereo1 ADC MIXR", "ADC1 Switch", "ADC R"},
876 {"Stereo1 ADC MIXR", NULL, "stereo1 filter"},
877 {"stereo1 filter", NULL, "PLL1", is_sys_clk_from_pll},
878
879 {"IF1 ADC1", NULL, "Stereo1 ADC MIXL"},
880 {"IF1 ADC1", NULL, "Stereo1 ADC MIXR"},
881 {"IF1 ADC1", NULL, "I2S1"},
882
883 {"AIF1TX", NULL, "IF1 ADC1"},
884
885 {"IF1 DAC", NULL, "AIF1RX"},
886 {"IF1 DAC", NULL, "I2S1"},
887
888 {"IF1 DAC1 L", NULL, "IF1 DAC"},
889 {"IF1 DAC1 R", NULL, "IF1 DAC"},
890
891 {"DAC MIXL", "Stereo ADC Switch", "Stereo1 ADC MIXL"},
892 {"DAC MIXL", "INF1 Switch", "IF1 DAC1 L"},
893 {"DAC MIXR", "Stereo ADC Switch", "Stereo1 ADC MIXR"},
894 {"DAC MIXR", "INF1 Switch", "IF1 DAC1 R"},
895
896 {"Audio DSP", NULL, "DAC MIXL"},
897 {"Audio DSP", NULL, "DAC MIXR"},
898
899 {"Stereo DAC MIXL", "DAC L1 Switch", "Audio DSP"},
900 {"Stereo DAC MIXL", "DAC R1 Switch", "DAC MIXR"},
901 {"Stereo DAC MIXL", NULL, "Stero1 DAC Power"},
902 {"Stereo DAC MIXR", "DAC R1 Switch", "Audio DSP"},
903 {"Stereo DAC MIXR", "DAC L1 Switch", "DAC MIXL"},
904 {"Stereo DAC MIXR", NULL, "Stero1 DAC Power"},
905
906 {"DAC L1", NULL, "Stereo DAC MIXL"},
907 {"DAC L1", NULL, "PLL1", is_sys_clk_from_pll},
908 {"DAC R1", NULL, "Stereo DAC MIXR"},
909 {"DAC R1", NULL, "PLL1", is_sys_clk_from_pll},
910
911 {"OUT MIXL", "BST1 Switch", "BST1"},
912 {"OUT MIXL", "BST2 Switch", "BST2"},
913 {"OUT MIXL", "INL1 Switch", "INL1 VOL"},
914 {"OUT MIXL", "REC MIXL Switch", "RECMIXL"},
915 {"OUT MIXL", "DAC L1 Switch", "DAC L1"},
916
917 {"OUT MIXR", "BST2 Switch", "BST2"},
918 {"OUT MIXR", "BST1 Switch", "BST1"},
919 {"OUT MIXR", "INR1 Switch", "INR1 VOL"},
920 {"OUT MIXR", "REC MIXR Switch", "RECMIXR"},
921 {"OUT MIXR", "DAC R1 Switch", "DAC R1"},
922
923 {"HPOVOL L", NULL, "OUT MIXL"},
924 {"HPOVOL R", NULL, "OUT MIXR"},
925 {"OUTVOL L", NULL, "OUT MIXL"},
926 {"OUTVOL R", NULL, "OUT MIXR"},
927
928 {"DAC 1", NULL, "DAC L1"},
929 {"DAC 1", NULL, "DAC R1"},
930 {"HPOVOL", NULL, "HPOVOL L"},
931 {"HPOVOL", NULL, "HPOVOL R"},
932 {"HPO MIX", "DAC1 Switch", "DAC 1"},
933 {"HPO MIX", "HPVOL Switch", "HPOVOL"},
934
935 {"LOUT MIX", "DAC L1 Switch", "DAC L1"},
936 {"LOUT MIX", "DAC R1 Switch", "DAC R1"},
937 {"LOUT MIX", "OUTVOL L Switch", "OUTVOL L"},
938 {"LOUT MIX", "OUTVOL R Switch", "OUTVOL R"},
939
940 {"HP amp", NULL, "HPO MIX"},
941 {"HP amp", NULL, "Charge Pump"},
942 {"HPOL", NULL, "HP amp"},
943 {"HPOR", NULL, "HP amp"},
944
945 {"LOUT amp", NULL, "LOUT MIX"},
946 {"LOUT amp", NULL, "Charge Pump"},
947 {"LOUTL", NULL, "LOUT amp"},
948 {"LOUTR", NULL, "LOUT amp"},
949
950};
951
952static int rt5616_hw_params(struct snd_pcm_substream *substream,
953 struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
954{
955 struct snd_soc_pcm_runtime *rtd = substream->private_data;
956 struct snd_soc_codec *codec = rtd->codec;
957 struct rt5616_priv *rt5616 = snd_soc_codec_get_drvdata(codec);
958 unsigned int val_len = 0, val_clk, mask_clk;
959 int pre_div, bclk_ms, frame_size;
960
961 rt5616->lrck[dai->id] = params_rate(params);
962
963 pre_div = rl6231_get_clk_info(rt5616->sysclk, rt5616->lrck[dai->id]);
964
965 if (pre_div < 0) {
966 dev_err(codec->dev, "Unsupported clock setting\n");
967 return -EINVAL;
968 }
969 frame_size = snd_soc_params_to_frame_size(params);
970 if (frame_size < 0) {
971 dev_err(codec->dev, "Unsupported frame size: %d\n", frame_size);
972 return -EINVAL;
973 }
974 bclk_ms = frame_size > 32 ? 1 : 0;
975 rt5616->bclk[dai->id] = rt5616->lrck[dai->id] * (32 << bclk_ms);
976
977 dev_dbg(dai->dev, "bclk is %dHz and lrck is %dHz\n",
978 rt5616->bclk[dai->id], rt5616->lrck[dai->id]);
979 dev_dbg(dai->dev, "bclk_ms is %d and pre_div is %d for iis %d\n",
980 bclk_ms, pre_div, dai->id);
981
982 switch (params_format(params)) {
983 case SNDRV_PCM_FORMAT_S16_LE:
984 break;
985 case SNDRV_PCM_FORMAT_S20_3LE:
986 val_len |= RT5616_I2S_DL_20;
987 break;
988 case SNDRV_PCM_FORMAT_S24_LE:
989 val_len |= RT5616_I2S_DL_24;
990 break;
991 case SNDRV_PCM_FORMAT_S8:
992 val_len |= RT5616_I2S_DL_8;
993 break;
994 default:
995 return -EINVAL;
996 }
997
998 mask_clk = RT5616_I2S_PD1_MASK;
999 val_clk = pre_div << RT5616_I2S_PD1_SFT;
1000 snd_soc_update_bits(codec, RT5616_I2S1_SDP,
1001 RT5616_I2S_DL_MASK, val_len);
1002 snd_soc_update_bits(codec, RT5616_ADDA_CLK1, mask_clk, val_clk);
1003
1004
1005 return 0;
1006}
1007
1008static int rt5616_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
1009{
1010 struct snd_soc_codec *codec = dai->codec;
1011 struct rt5616_priv *rt5616 = snd_soc_codec_get_drvdata(codec);
1012 unsigned int reg_val = 0;
1013
1014 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
1015 case SND_SOC_DAIFMT_CBM_CFM:
1016 rt5616->master[dai->id] = 1;
1017 break;
1018 case SND_SOC_DAIFMT_CBS_CFS:
1019 reg_val |= RT5616_I2S_MS_S;
1020 rt5616->master[dai->id] = 0;
1021 break;
1022 default:
1023 return -EINVAL;
1024 }
1025
1026 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
1027 case SND_SOC_DAIFMT_NB_NF:
1028 break;
1029 case SND_SOC_DAIFMT_IB_NF:
1030 reg_val |= RT5616_I2S_BP_INV;
1031 break;
1032 default:
1033 return -EINVAL;
1034 }
1035
1036 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
1037 case SND_SOC_DAIFMT_I2S:
1038 break;
1039 case SND_SOC_DAIFMT_LEFT_J:
1040 reg_val |= RT5616_I2S_DF_LEFT;
1041 break;
1042 case SND_SOC_DAIFMT_DSP_A:
1043 reg_val |= RT5616_I2S_DF_PCM_A;
1044 break;
1045 case SND_SOC_DAIFMT_DSP_B:
1046 reg_val |= RT5616_I2S_DF_PCM_B;
1047 break;
1048 default:
1049 return -EINVAL;
1050 }
1051
1052 snd_soc_update_bits(codec, RT5616_I2S1_SDP,
1053 RT5616_I2S_MS_MASK | RT5616_I2S_BP_MASK |
1054 RT5616_I2S_DF_MASK, reg_val);
1055
1056
1057 return 0;
1058}
1059
1060static int rt5616_set_dai_sysclk(struct snd_soc_dai *dai,
1061 int clk_id, unsigned int freq, int dir)
1062{
1063 struct snd_soc_codec *codec = dai->codec;
1064 struct rt5616_priv *rt5616 = snd_soc_codec_get_drvdata(codec);
1065 unsigned int reg_val = 0;
1066
1067 if (freq == rt5616->sysclk && clk_id == rt5616->sysclk_src)
1068 return 0;
1069
1070 switch (clk_id) {
1071 case RT5616_SCLK_S_MCLK:
1072 reg_val |= RT5616_SCLK_SRC_MCLK;
1073 break;
1074 case RT5616_SCLK_S_PLL1:
1075 reg_val |= RT5616_SCLK_SRC_PLL1;
1076 break;
1077 default:
1078 dev_err(codec->dev, "Invalid clock id (%d)\n", clk_id);
1079 return -EINVAL;
1080 }
1081 snd_soc_update_bits(codec, RT5616_GLB_CLK,
1082 RT5616_SCLK_SRC_MASK, reg_val);
1083 rt5616->sysclk = freq;
1084 rt5616->sysclk_src = clk_id;
1085
1086 dev_dbg(dai->dev, "Sysclk is %dHz and clock id is %d\n", freq, clk_id);
1087
1088 return 0;
1089}
1090
1091static int rt5616_set_dai_pll(struct snd_soc_dai *dai, int pll_id, int source,
1092 unsigned int freq_in, unsigned int freq_out)
1093{
1094 struct snd_soc_codec *codec = dai->codec;
1095 struct rt5616_priv *rt5616 = snd_soc_codec_get_drvdata(codec);
1096 struct rl6231_pll_code pll_code;
1097 int ret;
1098
1099 if (source == rt5616->pll_src && freq_in == rt5616->pll_in &&
1100 freq_out == rt5616->pll_out)
1101 return 0;
1102
1103 if (!freq_in || !freq_out) {
1104 dev_dbg(codec->dev, "PLL disabled\n");
1105
1106 rt5616->pll_in = 0;
1107 rt5616->pll_out = 0;
1108 snd_soc_update_bits(codec, RT5616_GLB_CLK,
1109 RT5616_SCLK_SRC_MASK, RT5616_SCLK_SRC_MCLK);
1110 return 0;
1111 }
1112
1113 switch (source) {
1114 case RT5616_PLL1_S_MCLK:
1115 snd_soc_update_bits(codec, RT5616_GLB_CLK,
1116 RT5616_PLL1_SRC_MASK, RT5616_PLL1_SRC_MCLK);
1117 break;
1118 case RT5616_PLL1_S_BCLK1:
1119 case RT5616_PLL1_S_BCLK2:
1120 snd_soc_update_bits(codec, RT5616_GLB_CLK,
1121 RT5616_PLL1_SRC_MASK, RT5616_PLL1_SRC_BCLK1);
1122 break;
1123 default:
1124 dev_err(codec->dev, "Unknown PLL source %d\n", source);
1125 return -EINVAL;
1126 }
1127
1128 ret = rl6231_pll_calc(freq_in, freq_out, &pll_code);
1129 if (ret < 0) {
1130 dev_err(codec->dev, "Unsupport input clock %d\n", freq_in);
1131 return ret;
1132 }
1133
1134 dev_dbg(codec->dev, "bypass=%d m=%d n=%d k=%d\n",
1135 pll_code.m_bp, (pll_code.m_bp ? 0 : pll_code.m_code),
1136 pll_code.n_code, pll_code.k_code);
1137
1138 snd_soc_write(codec, RT5616_PLL_CTRL1,
1139 pll_code.n_code << RT5616_PLL_N_SFT | pll_code.k_code);
1140 snd_soc_write(codec, RT5616_PLL_CTRL2,
1141 (pll_code.m_bp ? 0 : pll_code.m_code) << RT5616_PLL_M_SFT |
1142 pll_code.m_bp << RT5616_PLL_M_BP_SFT);
1143
1144 rt5616->pll_in = freq_in;
1145 rt5616->pll_out = freq_out;
1146 rt5616->pll_src = source;
1147
1148 return 0;
1149}
1150
1151static int rt5616_set_bias_level(struct snd_soc_codec *codec,
1152 enum snd_soc_bias_level level)
1153{
1154 switch (level) {
1155 case SND_SOC_BIAS_STANDBY:
1156 if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF) {
1157 snd_soc_update_bits(codec, RT5616_PWR_ANLG1,
1158 RT5616_PWR_VREF1 | RT5616_PWR_MB |
1159 RT5616_PWR_BG | RT5616_PWR_VREF2,
1160 RT5616_PWR_VREF1 | RT5616_PWR_MB |
1161 RT5616_PWR_BG | RT5616_PWR_VREF2);
1162 mdelay(10);
1163 snd_soc_update_bits(codec, RT5616_PWR_ANLG1,
1164 RT5616_PWR_FV1 | RT5616_PWR_FV2,
1165 RT5616_PWR_FV1 | RT5616_PWR_FV2);
1166 snd_soc_update_bits(codec, RT5616_D_MISC,
1167 RT5616_D_GATE_EN, RT5616_D_GATE_EN);
1168 }
1169 break;
1170
1171 case SND_SOC_BIAS_OFF:
1172 snd_soc_update_bits(codec, RT5616_D_MISC, RT5616_D_GATE_EN, 0);
1173 snd_soc_write(codec, RT5616_PWR_DIG1, 0x0000);
1174 snd_soc_write(codec, RT5616_PWR_DIG2, 0x0000);
1175 snd_soc_write(codec, RT5616_PWR_VOL, 0x0000);
1176 snd_soc_write(codec, RT5616_PWR_MIXER, 0x0000);
1177 snd_soc_write(codec, RT5616_PWR_ANLG1, 0x0000);
1178 snd_soc_write(codec, RT5616_PWR_ANLG2, 0x0000);
1179 break;
1180
1181 default:
1182 break;
1183 }
1184
1185 return 0;
1186}
1187
1188static int rt5616_probe(struct snd_soc_codec *codec)
1189{
1190 struct rt5616_priv *rt5616 = snd_soc_codec_get_drvdata(codec);
1191
1192 rt5616->codec = codec;
1193
1194 return 0;
1195}
1196
1197#ifdef CONFIG_PM
1198static int rt5616_suspend(struct snd_soc_codec *codec)
1199{
1200 struct rt5616_priv *rt5616 = snd_soc_codec_get_drvdata(codec);
1201
1202 regcache_cache_only(rt5616->regmap, true);
1203 regcache_mark_dirty(rt5616->regmap);
1204
1205 return 0;
1206}
1207
1208static int rt5616_resume(struct snd_soc_codec *codec)
1209{
1210 struct rt5616_priv *rt5616 = snd_soc_codec_get_drvdata(codec);
1211
1212 regcache_cache_only(rt5616->regmap, false);
1213 regcache_sync(rt5616->regmap);
1214 return 0;
1215}
1216#else
1217#define rt5616_suspend NULL
1218#define rt5616_resume NULL
1219#endif
1220
1221#define RT5616_STEREO_RATES SNDRV_PCM_RATE_8000_96000
1222#define RT5616_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \
1223 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S8)
1224
1225
1226struct snd_soc_dai_ops rt5616_aif_dai_ops = {
1227 .hw_params = rt5616_hw_params,
1228 .set_fmt = rt5616_set_dai_fmt,
1229 .set_sysclk = rt5616_set_dai_sysclk,
1230 .set_pll = rt5616_set_dai_pll,
1231};
1232
1233struct snd_soc_dai_driver rt5616_dai[] = {
1234 {
1235 .name = "rt5616-aif1",
1236 .id = RT5616_AIF1,
1237 .playback = {
1238 .stream_name = "AIF1 Playback",
1239 .channels_min = 1,
1240 .channels_max = 2,
1241 .rates = RT5616_STEREO_RATES,
1242 .formats = RT5616_FORMATS,
1243 },
1244 .capture = {
1245 .stream_name = "AIF1 Capture",
1246 .channels_min = 1,
1247 .channels_max = 2,
1248 .rates = RT5616_STEREO_RATES,
1249 .formats = RT5616_FORMATS,
1250 },
1251 .ops = &rt5616_aif_dai_ops,
1252 },
1253};
1254
1255static struct snd_soc_codec_driver soc_codec_dev_rt5616 = {
1256 .probe = rt5616_probe,
1257 .suspend = rt5616_suspend,
1258 .resume = rt5616_resume,
1259 .set_bias_level = rt5616_set_bias_level,
1260 .idle_bias_off = true,
1261 .controls = rt5616_snd_controls,
1262 .num_controls = ARRAY_SIZE(rt5616_snd_controls),
1263 .dapm_widgets = rt5616_dapm_widgets,
1264 .num_dapm_widgets = ARRAY_SIZE(rt5616_dapm_widgets),
1265 .dapm_routes = rt5616_dapm_routes,
1266 .num_dapm_routes = ARRAY_SIZE(rt5616_dapm_routes),
1267};
1268
1269static const struct regmap_config rt5616_regmap = {
1270 .reg_bits = 8,
1271 .val_bits = 16,
1272 .use_single_rw = true,
1273 .max_register = RT5616_DEVICE_ID + 1 + (ARRAY_SIZE(rt5616_ranges) *
1274 RT5616_PR_SPACING),
1275 .volatile_reg = rt5616_volatile_register,
1276 .readable_reg = rt5616_readable_register,
1277 .cache_type = REGCACHE_RBTREE,
1278 .reg_defaults = rt5616_reg,
1279 .num_reg_defaults = ARRAY_SIZE(rt5616_reg),
1280 .ranges = rt5616_ranges,
1281 .num_ranges = ARRAY_SIZE(rt5616_ranges),
1282};
1283
1284static const struct i2c_device_id rt5616_i2c_id[] = {
1285 { "rt5616", 0 },
1286 { }
1287};
1288MODULE_DEVICE_TABLE(i2c, rt5616_i2c_id);
1289
1290#if defined(CONFIG_OF)
1291static const struct of_device_id rt5616_of_match[] = {
1292 { .compatible = "realtek,rt5616", },
1293 {},
1294};
1295MODULE_DEVICE_TABLE(of, rt5616_of_match);
1296#endif
1297
1298static int rt5616_i2c_probe(struct i2c_client *i2c,
1299 const struct i2c_device_id *id)
1300{
1301 struct rt5616_priv *rt5616;
1302 unsigned int val;
1303 int ret;
1304
1305 rt5616 = devm_kzalloc(&i2c->dev, sizeof(struct rt5616_priv),
1306 GFP_KERNEL);
1307 if (rt5616 == NULL)
1308 return -ENOMEM;
1309
1310 i2c_set_clientdata(i2c, rt5616);
1311
1312 rt5616->regmap = devm_regmap_init_i2c(i2c, &rt5616_regmap);
1313 if (IS_ERR(rt5616->regmap)) {
1314 ret = PTR_ERR(rt5616->regmap);
1315 dev_err(&i2c->dev, "Failed to allocate register map: %d\n",
1316 ret);
1317 return ret;
1318 }
1319
1320 regmap_read(rt5616->regmap, RT5616_DEVICE_ID, &val);
1321 if (val != 0x6281) {
1322 dev_err(&i2c->dev,
1323 "Device with ID register %#x is not rt5616\n",
1324 val);
1325 return -ENODEV;
1326 }
1327 regmap_write(rt5616->regmap, RT5616_RESET, 0);
1328 regmap_update_bits(rt5616->regmap, RT5616_PWR_ANLG1,
1329 RT5616_PWR_VREF1 | RT5616_PWR_MB |
1330 RT5616_PWR_BG | RT5616_PWR_VREF2,
1331 RT5616_PWR_VREF1 | RT5616_PWR_MB |
1332 RT5616_PWR_BG | RT5616_PWR_VREF2);
1333 mdelay(10);
1334 regmap_update_bits(rt5616->regmap, RT5616_PWR_ANLG1,
1335 RT5616_PWR_FV1 | RT5616_PWR_FV2,
1336 RT5616_PWR_FV1 | RT5616_PWR_FV2);
1337
1338 ret = regmap_register_patch(rt5616->regmap, init_list,
1339 ARRAY_SIZE(init_list));
1340 if (ret != 0)
1341 dev_warn(&i2c->dev, "Failed to apply regmap patch: %d\n", ret);
1342
1343 regmap_update_bits(rt5616->regmap, RT5616_PWR_ANLG1,
1344 RT5616_PWR_LDO_DVO_MASK, RT5616_PWR_LDO_DVO_1_2V);
1345
1346 return snd_soc_register_codec(&i2c->dev, &soc_codec_dev_rt5616,
1347 rt5616_dai, ARRAY_SIZE(rt5616_dai));
1348
1349}
1350
1351static int rt5616_i2c_remove(struct i2c_client *i2c)
1352{
1353 snd_soc_unregister_codec(&i2c->dev);
1354
1355 return 0;
1356}
1357
1358static void rt5616_i2c_shutdown(struct i2c_client *client)
1359{
1360 struct rt5616_priv *rt5616 = i2c_get_clientdata(client);
1361
1362 regmap_write(rt5616->regmap, RT5616_HP_VOL, 0xc8c8);
1363 regmap_write(rt5616->regmap, RT5616_LOUT_CTRL1, 0xc8c8);
1364
1365}
1366
1367static struct i2c_driver rt5616_i2c_driver = {
1368 .driver = {
1369 .name = "rt5616",
1370 .of_match_table = of_match_ptr(rt5616_of_match),
1371 },
1372 .probe = rt5616_i2c_probe,
1373 .remove = rt5616_i2c_remove,
1374 .shutdown = rt5616_i2c_shutdown,
1375 .id_table = rt5616_i2c_id,
1376};
1377module_i2c_driver(rt5616_i2c_driver);
1378
1379MODULE_DESCRIPTION("ASoC RT5616 driver");
1380MODULE_AUTHOR("Bard Liao <bardliao@realtek.com>");
1381MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/rt5616.h b/sound/soc/codecs/rt5616.h
new file mode 100644
index 000000000000..f88cdddbc34a
--- /dev/null
+++ b/sound/soc/codecs/rt5616.h
@@ -0,0 +1,1819 @@
1/*
2 * rt5616.h -- RT5616 ALSA SoC audio driver
3 *
4 * Copyright 2011 Realtek Microelectronics
5 * Author: Johnny Hsu <johnnyhsu@realtek.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11
12#ifndef __RT5616_H__
13#define __RT5616_H__
14
15/* Info */
16#define RT5616_RESET 0x00
17#define RT5616_VERSION_ID 0xfd
18#define RT5616_VENDOR_ID 0xfe
19#define RT5616_DEVICE_ID 0xff
20/* I/O - Output */
21#define RT5616_HP_VOL 0x02
22#define RT5616_LOUT_CTRL1 0x03
23#define RT5616_LOUT_CTRL2 0x05
24/* I/O - Input */
25#define RT5616_IN1_IN2 0x0d
26#define RT5616_INL1_INR1_VOL 0x0f
27/* I/O - ADC/DAC/DMIC */
28#define RT5616_DAC1_DIG_VOL 0x19
29#define RT5616_ADC_DIG_VOL 0x1c
30#define RT5616_ADC_BST_VOL 0x1e
31/* Mixer - D-D */
32#define RT5616_STO1_ADC_MIXER 0x27
33#define RT5616_AD_DA_MIXER 0x29
34#define RT5616_STO_DAC_MIXER 0x2a
35
36/* Mixer - ADC */
37#define RT5616_REC_L1_MIXER 0x3b
38#define RT5616_REC_L2_MIXER 0x3c
39#define RT5616_REC_R1_MIXER 0x3d
40#define RT5616_REC_R2_MIXER 0x3e
41/* Mixer - DAC */
42#define RT5616_HPO_MIXER 0x45
43#define RT5616_OUT_L1_MIXER 0x4d
44#define RT5616_OUT_L2_MIXER 0x4e
45#define RT5616_OUT_L3_MIXER 0x4f
46#define RT5616_OUT_R1_MIXER 0x50
47#define RT5616_OUT_R2_MIXER 0x51
48#define RT5616_OUT_R3_MIXER 0x52
49#define RT5616_LOUT_MIXER 0x53
50/* Power */
51#define RT5616_PWR_DIG1 0x61
52#define RT5616_PWR_DIG2 0x62
53#define RT5616_PWR_ANLG1 0x63
54#define RT5616_PWR_ANLG2 0x64
55#define RT5616_PWR_MIXER 0x65
56#define RT5616_PWR_VOL 0x66
57/* Private Register Control */
58#define RT5616_PRIV_INDEX 0x6a
59#define RT5616_PRIV_DATA 0x6c
60/* Format - ADC/DAC */
61#define RT5616_I2S1_SDP 0x70
62#define RT5616_ADDA_CLK1 0x73
63#define RT5616_ADDA_CLK2 0x74
64
65/* Function - Analog */
66#define RT5616_GLB_CLK 0x80
67#define RT5616_PLL_CTRL1 0x81
68#define RT5616_PLL_CTRL2 0x82
69#define RT5616_HP_OVCD 0x8b
70#define RT5616_DEPOP_M1 0x8e
71#define RT5616_DEPOP_M2 0x8f
72#define RT5616_DEPOP_M3 0x90
73#define RT5616_CHARGE_PUMP 0x91
74#define RT5616_PV_DET_SPK_G 0x92
75#define RT5616_MICBIAS 0x93
76#define RT5616_A_JD_CTL1 0x94
77#define RT5616_A_JD_CTL2 0x95
78/* Function - Digital */
79#define RT5616_EQ_CTRL1 0xb0
80#define RT5616_EQ_CTRL2 0xb1
81#define RT5616_WIND_FILTER 0xb2
82#define RT5616_DRC_AGC_1 0xb4
83#define RT5616_DRC_AGC_2 0xb5
84#define RT5616_DRC_AGC_3 0xb6
85#define RT5616_SVOL_ZC 0xb7
86#define RT5616_JD_CTRL1 0xbb
87#define RT5616_JD_CTRL2 0xbc
88#define RT5616_IRQ_CTRL1 0xbd
89#define RT5616_IRQ_CTRL2 0xbe
90#define RT5616_INT_IRQ_ST 0xbf
91#define RT5616_GPIO_CTRL1 0xc0
92#define RT5616_GPIO_CTRL2 0xc1
93#define RT5616_GPIO_CTRL3 0xc2
94#define RT5616_PGM_REG_ARR1 0xc8
95#define RT5616_PGM_REG_ARR2 0xc9
96#define RT5616_PGM_REG_ARR3 0xca
97#define RT5616_PGM_REG_ARR4 0xcb
98#define RT5616_PGM_REG_ARR5 0xcc
99#define RT5616_SCB_FUNC 0xcd
100#define RT5616_SCB_CTRL 0xce
101#define RT5616_BASE_BACK 0xcf
102#define RT5616_MP3_PLUS1 0xd0
103#define RT5616_MP3_PLUS2 0xd1
104#define RT5616_ADJ_HPF_CTRL1 0xd3
105#define RT5616_ADJ_HPF_CTRL2 0xd4
106#define RT5616_HP_CALIB_AMP_DET 0xd6
107#define RT5616_HP_CALIB2 0xd7
108#define RT5616_SV_ZCD1 0xd9
109#define RT5616_SV_ZCD2 0xda
110#define RT5616_D_MISC 0xfa
111/* Dummy Register */
112#define RT5616_DUMMY2 0xfb
113#define RT5616_DUMMY3 0xfc
114
115
116/* Index of Codec Private Register definition */
117#define RT5616_BIAS_CUR1 0x12
118#define RT5616_BIAS_CUR3 0x14
119#define RT5616_CLSD_INT_REG1 0x1c
120#define RT5616_MAMP_INT_REG2 0x37
121#define RT5616_CHOP_DAC_ADC 0x3d
122#define RT5616_3D_SPK 0x63
123#define RT5616_WND_1 0x6c
124#define RT5616_WND_2 0x6d
125#define RT5616_WND_3 0x6e
126#define RT5616_WND_4 0x6f
127#define RT5616_WND_5 0x70
128#define RT5616_WND_8 0x73
129#define RT5616_DIP_SPK_INF 0x75
130#define RT5616_HP_DCC_INT1 0x77
131#define RT5616_EQ_BW_LOP 0xa0
132#define RT5616_EQ_GN_LOP 0xa1
133#define RT5616_EQ_FC_BP1 0xa2
134#define RT5616_EQ_BW_BP1 0xa3
135#define RT5616_EQ_GN_BP1 0xa4
136#define RT5616_EQ_FC_BP2 0xa5
137#define RT5616_EQ_BW_BP2 0xa6
138#define RT5616_EQ_GN_BP2 0xa7
139#define RT5616_EQ_FC_BP3 0xa8
140#define RT5616_EQ_BW_BP3 0xa9
141#define RT5616_EQ_GN_BP3 0xaa
142#define RT5616_EQ_FC_BP4 0xab
143#define RT5616_EQ_BW_BP4 0xac
144#define RT5616_EQ_GN_BP4 0xad
145#define RT5616_EQ_FC_HIP1 0xae
146#define RT5616_EQ_GN_HIP1 0xaf
147#define RT5616_EQ_FC_HIP2 0xb0
148#define RT5616_EQ_BW_HIP2 0xb1
149#define RT5616_EQ_GN_HIP2 0xb2
150#define RT5616_EQ_PRE_VOL 0xb3
151#define RT5616_EQ_PST_VOL 0xb4
152
153
154/* global definition */
155#define RT5616_L_MUTE (0x1 << 15)
156#define RT5616_L_MUTE_SFT 15
157#define RT5616_VOL_L_MUTE (0x1 << 14)
158#define RT5616_VOL_L_SFT 14
159#define RT5616_R_MUTE (0x1 << 7)
160#define RT5616_R_MUTE_SFT 7
161#define RT5616_VOL_R_MUTE (0x1 << 6)
162#define RT5616_VOL_R_SFT 6
163#define RT5616_L_VOL_MASK (0x3f << 8)
164#define RT5616_L_VOL_SFT 8
165#define RT5616_R_VOL_MASK (0x3f)
166#define RT5616_R_VOL_SFT 0
167
168/* LOUT Control 2(0x05) */
169#define RT5616_EN_DFO (0x1 << 15)
170
171/* IN1 and IN2 Control (0x0d) */
172/* IN3 and IN4 Control (0x0e) */
173#define RT5616_BST_MASK1 (0xf<<12)
174#define RT5616_BST_SFT1 12
175#define RT5616_BST_MASK2 (0xf<<8)
176#define RT5616_BST_SFT2 8
177#define RT5616_IN_DF1 (0x1 << 7)
178#define RT5616_IN_SFT1 7
179#define RT5616_IN_DF2 (0x1 << 6)
180#define RT5616_IN_SFT2 6
181
182/* INL1 and INR1 Volume Control (0x0f) */
183#define RT5616_INL_VOL_MASK (0x1f << 8)
184#define RT5616_INL_VOL_SFT 8
185#define RT5616_INR_SEL_MASK (0x1 << 7)
186#define RT5616_INR_SEL_SFT 7
187#define RT5616_INR_SEL_IN4N (0x0 << 7)
188#define RT5616_INR_SEL_MONON (0x1 << 7)
189#define RT5616_INR_VOL_MASK (0x1f)
190#define RT5616_INR_VOL_SFT 0
191
192/* DAC1 Digital Volume (0x19) */
193#define RT5616_DAC_L1_VOL_MASK (0xff << 8)
194#define RT5616_DAC_L1_VOL_SFT 8
195#define RT5616_DAC_R1_VOL_MASK (0xff)
196#define RT5616_DAC_R1_VOL_SFT 0
197
198/* DAC2 Digital Volume (0x1a) */
199#define RT5616_DAC_L2_VOL_MASK (0xff << 8)
200#define RT5616_DAC_L2_VOL_SFT 8
201#define RT5616_DAC_R2_VOL_MASK (0xff)
202#define RT5616_DAC_R2_VOL_SFT 0
203
204/* ADC Digital Volume Control (0x1c) */
205#define RT5616_ADC_L_VOL_MASK (0x7f << 8)
206#define RT5616_ADC_L_VOL_SFT 8
207#define RT5616_ADC_R_VOL_MASK (0x7f)
208#define RT5616_ADC_R_VOL_SFT 0
209
210/* Mono ADC Digital Volume Control (0x1d) */
211#define RT5616_M_MONO_ADC_L (0x1 << 15)
212#define RT5616_M_MONO_ADC_L_SFT 15
213#define RT5616_MONO_ADC_L_VOL_MASK (0x7f << 8)
214#define RT5616_MONO_ADC_L_VOL_SFT 8
215#define RT5616_M_MONO_ADC_R (0x1 << 7)
216#define RT5616_M_MONO_ADC_R_SFT 7
217#define RT5616_MONO_ADC_R_VOL_MASK (0x7f)
218#define RT5616_MONO_ADC_R_VOL_SFT 0
219
220/* ADC Boost Volume Control (0x1e) */
221#define RT5616_ADC_L_BST_MASK (0x3 << 14)
222#define RT5616_ADC_L_BST_SFT 14
223#define RT5616_ADC_R_BST_MASK (0x3 << 12)
224#define RT5616_ADC_R_BST_SFT 12
225#define RT5616_ADC_COMP_MASK (0x3 << 10)
226#define RT5616_ADC_COMP_SFT 10
227
228/* Stereo ADC1 Mixer Control (0x27) */
229#define RT5616_M_STO1_ADC_L1 (0x1 << 14)
230#define RT5616_M_STO1_ADC_L1_SFT 14
231#define RT5616_M_STO1_ADC_R1 (0x1 << 6)
232#define RT5616_M_STO1_ADC_R1_SFT 6
233
234/* ADC Mixer to DAC Mixer Control (0x29) */
235#define RT5616_M_ADCMIX_L (0x1 << 15)
236#define RT5616_M_ADCMIX_L_SFT 15
237#define RT5616_M_IF1_DAC_L (0x1 << 14)
238#define RT5616_M_IF1_DAC_L_SFT 14
239#define RT5616_M_ADCMIX_R (0x1 << 7)
240#define RT5616_M_ADCMIX_R_SFT 7
241#define RT5616_M_IF1_DAC_R (0x1 << 6)
242#define RT5616_M_IF1_DAC_R_SFT 6
243
244/* Stereo DAC Mixer Control (0x2a) */
245#define RT5616_M_DAC_L1_MIXL (0x1 << 14)
246#define RT5616_M_DAC_L1_MIXL_SFT 14
247#define RT5616_DAC_L1_STO_L_VOL_MASK (0x1 << 13)
248#define RT5616_DAC_L1_STO_L_VOL_SFT 13
249#define RT5616_M_DAC_R1_MIXL (0x1 << 9)
250#define RT5616_M_DAC_R1_MIXL_SFT 9
251#define RT5616_DAC_R1_STO_L_VOL_MASK (0x1 << 8)
252#define RT5616_DAC_R1_STO_L_VOL_SFT 8
253#define RT5616_M_DAC_R1_MIXR (0x1 << 6)
254#define RT5616_M_DAC_R1_MIXR_SFT 6
255#define RT5616_DAC_R1_STO_R_VOL_MASK (0x1 << 5)
256#define RT5616_DAC_R1_STO_R_VOL_SFT 5
257#define RT5616_M_DAC_L1_MIXR (0x1 << 1)
258#define RT5616_M_DAC_L1_MIXR_SFT 1
259#define RT5616_DAC_L1_STO_R_VOL_MASK (0x1)
260#define RT5616_DAC_L1_STO_R_VOL_SFT 0
261
262/* DD Mixer Control (0x2b) */
263#define RT5616_M_STO_DD_L1 (0x1 << 14)
264#define RT5616_M_STO_DD_L1_SFT 14
265#define RT5616_STO_DD_L1_VOL_MASK (0x1 << 13)
266#define RT5616_DAC_DD_L1_VOL_SFT 13
267#define RT5616_M_STO_DD_L2 (0x1 << 12)
268#define RT5616_M_STO_DD_L2_SFT 12
269#define RT5616_STO_DD_L2_VOL_MASK (0x1 << 11)
270#define RT5616_STO_DD_L2_VOL_SFT 11
271#define RT5616_M_STO_DD_R2_L (0x1 << 10)
272#define RT5616_M_STO_DD_R2_L_SFT 10
273#define RT5616_STO_DD_R2_L_VOL_MASK (0x1 << 9)
274#define RT5616_STO_DD_R2_L_VOL_SFT 9
275#define RT5616_M_STO_DD_R1 (0x1 << 6)
276#define RT5616_M_STO_DD_R1_SFT 6
277#define RT5616_STO_DD_R1_VOL_MASK (0x1 << 5)
278#define RT5616_STO_DD_R1_VOL_SFT 5
279#define RT5616_M_STO_DD_R2 (0x1 << 4)
280#define RT5616_M_STO_DD_R2_SFT 4
281#define RT5616_STO_DD_R2_VOL_MASK (0x1 << 3)
282#define RT5616_STO_DD_R2_VOL_SFT 3
283#define RT5616_M_STO_DD_L2_R (0x1 << 2)
284#define RT5616_M_STO_DD_L2_R_SFT 2
285#define RT5616_STO_DD_L2_R_VOL_MASK (0x1 << 1)
286#define RT5616_STO_DD_L2_R_VOL_SFT 1
287
288/* Digital Mixer Control (0x2c) */
289#define RT5616_M_STO_L_DAC_L (0x1 << 15)
290#define RT5616_M_STO_L_DAC_L_SFT 15
291#define RT5616_STO_L_DAC_L_VOL_MASK (0x1 << 14)
292#define RT5616_STO_L_DAC_L_VOL_SFT 14
293#define RT5616_M_DAC_L2_DAC_L (0x1 << 13)
294#define RT5616_M_DAC_L2_DAC_L_SFT 13
295#define RT5616_DAC_L2_DAC_L_VOL_MASK (0x1 << 12)
296#define RT5616_DAC_L2_DAC_L_VOL_SFT 12
297#define RT5616_M_STO_R_DAC_R (0x1 << 11)
298#define RT5616_M_STO_R_DAC_R_SFT 11
299#define RT5616_STO_R_DAC_R_VOL_MASK (0x1 << 10)
300#define RT5616_STO_R_DAC_R_VOL_SFT 10
301#define RT5616_M_DAC_R2_DAC_R (0x1 << 9)
302#define RT5616_M_DAC_R2_DAC_R_SFT 9
303#define RT5616_DAC_R2_DAC_R_VOL_MASK (0x1 << 8)
304#define RT5616_DAC_R2_DAC_R_VOL_SFT 8
305
306/* DSP Path Control 1 (0x2d) */
307#define RT5616_RXDP_SRC_MASK (0x1 << 15)
308#define RT5616_RXDP_SRC_SFT 15
309#define RT5616_RXDP_SRC_NOR (0x0 << 15)
310#define RT5616_RXDP_SRC_DIV3 (0x1 << 15)
311#define RT5616_TXDP_SRC_MASK (0x1 << 14)
312#define RT5616_TXDP_SRC_SFT 14
313#define RT5616_TXDP_SRC_NOR (0x0 << 14)
314#define RT5616_TXDP_SRC_DIV3 (0x1 << 14)
315
316/* DSP Path Control 2 (0x2e) */
317#define RT5616_DAC_L2_SEL_MASK (0x3 << 14)
318#define RT5616_DAC_L2_SEL_SFT 14
319#define RT5616_DAC_L2_SEL_IF2 (0x0 << 14)
320#define RT5616_DAC_L2_SEL_IF3 (0x1 << 14)
321#define RT5616_DAC_L2_SEL_TXDC (0x2 << 14)
322#define RT5616_DAC_L2_SEL_BASS (0x3 << 14)
323#define RT5616_DAC_R2_SEL_MASK (0x3 << 12)
324#define RT5616_DAC_R2_SEL_SFT 12
325#define RT5616_DAC_R2_SEL_IF2 (0x0 << 12)
326#define RT5616_DAC_R2_SEL_IF3 (0x1 << 12)
327#define RT5616_DAC_R2_SEL_TXDC (0x2 << 12)
328#define RT5616_IF2_ADC_L_SEL_MASK (0x1 << 11)
329#define RT5616_IF2_ADC_L_SEL_SFT 11
330#define RT5616_IF2_ADC_L_SEL_TXDP (0x0 << 11)
331#define RT5616_IF2_ADC_L_SEL_PASS (0x1 << 11)
332#define RT5616_IF2_ADC_R_SEL_MASK (0x1 << 10)
333#define RT5616_IF2_ADC_R_SEL_SFT 10
334#define RT5616_IF2_ADC_R_SEL_TXDP (0x0 << 10)
335#define RT5616_IF2_ADC_R_SEL_PASS (0x1 << 10)
336#define RT5616_RXDC_SEL_MASK (0x3 << 8)
337#define RT5616_RXDC_SEL_SFT 8
338#define RT5616_RXDC_SEL_NOR (0x0 << 8)
339#define RT5616_RXDC_SEL_L2R (0x1 << 8)
340#define RT5616_RXDC_SEL_R2L (0x2 << 8)
341#define RT5616_RXDC_SEL_SWAP (0x3 << 8)
342#define RT5616_RXDP_SEL_MASK (0x3 << 6)
343#define RT5616_RXDP_SEL_SFT 6
344#define RT5616_RXDP_SEL_NOR (0x0 << 6)
345#define RT5616_RXDP_SEL_L2R (0x1 << 6)
346#define RT5616_RXDP_SEL_R2L (0x2 << 6)
347#define RT5616_RXDP_SEL_SWAP (0x3 << 6)
348#define RT5616_TXDC_SEL_MASK (0x3 << 4)
349#define RT5616_TXDC_SEL_SFT 4
350#define RT5616_TXDC_SEL_NOR (0x0 << 4)
351#define RT5616_TXDC_SEL_L2R (0x1 << 4)
352#define RT5616_TXDC_SEL_R2L (0x2 << 4)
353#define RT5616_TXDC_SEL_SWAP (0x3 << 4)
354#define RT5616_TXDP_SEL_MASK (0x3 << 2)
355#define RT5616_TXDP_SEL_SFT 2
356#define RT5616_TXDP_SEL_NOR (0x0 << 2)
357#define RT5616_TXDP_SEL_L2R (0x1 << 2)
358#define RT5616_TXDP_SEL_R2L (0x2 << 2)
359#define RT5616_TRXDP_SEL_SWAP (0x3 << 2)
360
361/* REC Left Mixer Control 1 (0x3b) */
362#define RT5616_G_LN_L2_RM_L_MASK (0x7 << 13)
363#define RT5616_G_IN_L2_RM_L_SFT 13
364#define RT5616_G_LN_L1_RM_L_MASK (0x7 << 10)
365#define RT5616_G_IN_L1_RM_L_SFT 10
366#define RT5616_G_BST3_RM_L_MASK (0x7 << 4)
367#define RT5616_G_BST3_RM_L_SFT 4
368#define RT5616_G_BST2_RM_L_MASK (0x7 << 1)
369#define RT5616_G_BST2_RM_L_SFT 1
370
371/* REC Left Mixer Control 2 (0x3c) */
372#define RT5616_G_BST1_RM_L_MASK (0x7 << 13)
373#define RT5616_G_BST1_RM_L_SFT 13
374#define RT5616_G_OM_L_RM_L_MASK (0x7 << 10)
375#define RT5616_G_OM_L_RM_L_SFT 10
376#define RT5616_M_IN2_L_RM_L (0x1 << 6)
377#define RT5616_M_IN2_L_RM_L_SFT 6
378#define RT5616_M_IN1_L_RM_L (0x1 << 5)
379#define RT5616_M_IN1_L_RM_L_SFT 5
380#define RT5616_M_BST3_RM_L (0x1 << 3)
381#define RT5616_M_BST3_RM_L_SFT 3
382#define RT5616_M_BST2_RM_L (0x1 << 2)
383#define RT5616_M_BST2_RM_L_SFT 2
384#define RT5616_M_BST1_RM_L (0x1 << 1)
385#define RT5616_M_BST1_RM_L_SFT 1
386#define RT5616_M_OM_L_RM_L (0x1)
387#define RT5616_M_OM_L_RM_L_SFT 0
388
389/* REC Right Mixer Control 1 (0x3d) */
390#define RT5616_G_IN2_R_RM_R_MASK (0x7 << 13)
391#define RT5616_G_IN2_R_RM_R_SFT 13
392#define RT5616_G_IN1_R_RM_R_MASK (0x7 << 10)
393#define RT5616_G_IN1_R_RM_R_SFT 10
394#define RT5616_G_BST3_RM_R_MASK (0x7 << 4)
395#define RT5616_G_BST3_RM_R_SFT 4
396#define RT5616_G_BST2_RM_R_MASK (0x7 << 1)
397#define RT5616_G_BST2_RM_R_SFT 1
398
399/* REC Right Mixer Control 2 (0x3e) */
400#define RT5616_G_BST1_RM_R_MASK (0x7 << 13)
401#define RT5616_G_BST1_RM_R_SFT 13
402#define RT5616_G_OM_R_RM_R_MASK (0x7 << 10)
403#define RT5616_G_OM_R_RM_R_SFT 10
404#define RT5616_M_IN2_R_RM_R (0x1 << 6)
405#define RT5616_M_IN2_R_RM_R_SFT 6
406#define RT5616_M_IN1_R_RM_R (0x1 << 5)
407#define RT5616_M_IN1_R_RM_R_SFT 5
408#define RT5616_M_BST3_RM_R (0x1 << 3)
409#define RT5616_M_BST3_RM_R_SFT 3
410#define RT5616_M_BST2_RM_R (0x1 << 2)
411#define RT5616_M_BST2_RM_R_SFT 2
412#define RT5616_M_BST1_RM_R (0x1 << 1)
413#define RT5616_M_BST1_RM_R_SFT 1
414#define RT5616_M_OM_R_RM_R (0x1)
415#define RT5616_M_OM_R_RM_R_SFT 0
416
417/* HPMIX Control (0x45) */
418#define RT5616_M_DAC1_HM (0x1 << 14)
419#define RT5616_M_DAC1_HM_SFT 14
420#define RT5616_M_HPVOL_HM (0x1 << 13)
421#define RT5616_M_HPVOL_HM_SFT 13
422#define RT5616_G_HPOMIX_MASK (0x1 << 12)
423#define RT5616_G_HPOMIX_SFT 12
424
425/* SPK Left Mixer Control (0x46) */
426#define RT5616_G_RM_L_SM_L_MASK (0x3 << 14)
427#define RT5616_G_RM_L_SM_L_SFT 14
428#define RT5616_G_IN_L_SM_L_MASK (0x3 << 12)
429#define RT5616_G_IN_L_SM_L_SFT 12
430#define RT5616_G_DAC_L1_SM_L_MASK (0x3 << 10)
431#define RT5616_G_DAC_L1_SM_L_SFT 10
432#define RT5616_G_DAC_L2_SM_L_MASK (0x3 << 8)
433#define RT5616_G_DAC_L2_SM_L_SFT 8
434#define RT5616_G_OM_L_SM_L_MASK (0x3 << 6)
435#define RT5616_G_OM_L_SM_L_SFT 6
436#define RT5616_M_RM_L_SM_L (0x1 << 5)
437#define RT5616_M_RM_L_SM_L_SFT 5
438#define RT5616_M_IN_L_SM_L (0x1 << 4)
439#define RT5616_M_IN_L_SM_L_SFT 4
440#define RT5616_M_DAC_L1_SM_L (0x1 << 3)
441#define RT5616_M_DAC_L1_SM_L_SFT 3
442#define RT5616_M_DAC_L2_SM_L (0x1 << 2)
443#define RT5616_M_DAC_L2_SM_L_SFT 2
444#define RT5616_M_OM_L_SM_L (0x1 << 1)
445#define RT5616_M_OM_L_SM_L_SFT 1
446
447/* SPK Right Mixer Control (0x47) */
448#define RT5616_G_RM_R_SM_R_MASK (0x3 << 14)
449#define RT5616_G_RM_R_SM_R_SFT 14
450#define RT5616_G_IN_R_SM_R_MASK (0x3 << 12)
451#define RT5616_G_IN_R_SM_R_SFT 12
452#define RT5616_G_DAC_R1_SM_R_MASK (0x3 << 10)
453#define RT5616_G_DAC_R1_SM_R_SFT 10
454#define RT5616_G_DAC_R2_SM_R_MASK (0x3 << 8)
455#define RT5616_G_DAC_R2_SM_R_SFT 8
456#define RT5616_G_OM_R_SM_R_MASK (0x3 << 6)
457#define RT5616_G_OM_R_SM_R_SFT 6
458#define RT5616_M_RM_R_SM_R (0x1 << 5)
459#define RT5616_M_RM_R_SM_R_SFT 5
460#define RT5616_M_IN_R_SM_R (0x1 << 4)
461#define RT5616_M_IN_R_SM_R_SFT 4
462#define RT5616_M_DAC_R1_SM_R (0x1 << 3)
463#define RT5616_M_DAC_R1_SM_R_SFT 3
464#define RT5616_M_DAC_R2_SM_R (0x1 << 2)
465#define RT5616_M_DAC_R2_SM_R_SFT 2
466#define RT5616_M_OM_R_SM_R (0x1 << 1)
467#define RT5616_M_OM_R_SM_R_SFT 1
468
469/* SPOLMIX Control (0x48) */
470#define RT5616_M_DAC_R1_SPM_L (0x1 << 15)
471#define RT5616_M_DAC_R1_SPM_L_SFT 15
472#define RT5616_M_DAC_L1_SPM_L (0x1 << 14)
473#define RT5616_M_DAC_L1_SPM_L_SFT 14
474#define RT5616_M_SV_R_SPM_L (0x1 << 13)
475#define RT5616_M_SV_R_SPM_L_SFT 13
476#define RT5616_M_SV_L_SPM_L (0x1 << 12)
477#define RT5616_M_SV_L_SPM_L_SFT 12
478#define RT5616_M_BST1_SPM_L (0x1 << 11)
479#define RT5616_M_BST1_SPM_L_SFT 11
480
481/* SPORMIX Control (0x49) */
482#define RT5616_M_DAC_R1_SPM_R (0x1 << 13)
483#define RT5616_M_DAC_R1_SPM_R_SFT 13
484#define RT5616_M_SV_R_SPM_R (0x1 << 12)
485#define RT5616_M_SV_R_SPM_R_SFT 12
486#define RT5616_M_BST1_SPM_R (0x1 << 11)
487#define RT5616_M_BST1_SPM_R_SFT 11
488
489/* SPOLMIX / SPORMIX Ratio Control (0x4a) */
490#define RT5616_SPO_CLSD_RATIO_MASK (0x7)
491#define RT5616_SPO_CLSD_RATIO_SFT 0
492
493/* Mono Output Mixer Control (0x4c) */
494#define RT5616_M_DAC_R2_MM (0x1 << 15)
495#define RT5616_M_DAC_R2_MM_SFT 15
496#define RT5616_M_DAC_L2_MM (0x1 << 14)
497#define RT5616_M_DAC_L2_MM_SFT 14
498#define RT5616_M_OV_R_MM (0x1 << 13)
499#define RT5616_M_OV_R_MM_SFT 13
500#define RT5616_M_OV_L_MM (0x1 << 12)
501#define RT5616_M_OV_L_MM_SFT 12
502#define RT5616_M_BST1_MM (0x1 << 11)
503#define RT5616_M_BST1_MM_SFT 11
504#define RT5616_G_MONOMIX_MASK (0x1 << 10)
505#define RT5616_G_MONOMIX_SFT 10
506
507/* Output Left Mixer Control 1 (0x4d) */
508#define RT5616_G_BST2_OM_L_MASK (0x7 << 10)
509#define RT5616_G_BST2_OM_L_SFT 10
510#define RT5616_G_BST1_OM_L_MASK (0x7 << 7)
511#define RT5616_G_BST1_OM_L_SFT 7
512#define RT5616_G_IN1_L_OM_L_MASK (0x7 << 4)
513#define RT5616_G_IN1_L_OM_L_SFT 4
514#define RT5616_G_RM_L_OM_L_MASK (0x7 << 1)
515#define RT5616_G_RM_L_OM_L_SFT 1
516
517/* Output Left Mixer Control 2 (0x4e) */
518#define RT5616_G_DAC_L1_OM_L_MASK (0x7 << 7)
519#define RT5616_G_DAC_L1_OM_L_SFT 7
520#define RT5616_G_IN2_L_OM_L_MASK (0x7 << 4)
521#define RT5616_G_IN2_L_OM_L_SFT 4
522
523/* Output Left Mixer Control 3 (0x4f) */
524#define RT5616_M_IN2_L_OM_L (0x1 << 9)
525#define RT5616_M_IN2_L_OM_L_SFT 9
526#define RT5616_M_BST2_OM_L (0x1 << 6)
527#define RT5616_M_BST2_OM_L_SFT 6
528#define RT5616_M_BST1_OM_L (0x1 << 5)
529#define RT5616_M_BST1_OM_L_SFT 5
530#define RT5616_M_IN1_L_OM_L (0x1 << 4)
531#define RT5616_M_IN1_L_OM_L_SFT 4
532#define RT5616_M_RM_L_OM_L (0x1 << 3)
533#define RT5616_M_RM_L_OM_L_SFT 3
534#define RT5616_M_DAC_L1_OM_L (0x1)
535#define RT5616_M_DAC_L1_OM_L_SFT 0
536
537/* Output Right Mixer Control 1 (0x50) */
538#define RT5616_G_BST2_OM_R_MASK (0x7 << 10)
539#define RT5616_G_BST2_OM_R_SFT 10
540#define RT5616_G_BST1_OM_R_MASK (0x7 << 7)
541#define RT5616_G_BST1_OM_R_SFT 7
542#define RT5616_G_IN1_R_OM_R_MASK (0x7 << 4)
543#define RT5616_G_IN1_R_OM_R_SFT 4
544#define RT5616_G_RM_R_OM_R_MASK (0x7 << 1)
545#define RT5616_G_RM_R_OM_R_SFT 1
546
547/* Output Right Mixer Control 2 (0x51) */
548#define RT5616_G_DAC_R1_OM_R_MASK (0x7 << 7)
549#define RT5616_G_DAC_R1_OM_R_SFT 7
550#define RT5616_G_IN2_R_OM_R_MASK (0x7 << 4)
551#define RT5616_G_IN2_R_OM_R_SFT 4
552
553/* Output Right Mixer Control 3 (0x52) */
554#define RT5616_M_IN2_R_OM_R (0x1 << 9)
555#define RT5616_M_IN2_R_OM_R_SFT 9
556#define RT5616_M_BST2_OM_R (0x1 << 6)
557#define RT5616_M_BST2_OM_R_SFT 6
558#define RT5616_M_BST1_OM_R (0x1 << 5)
559#define RT5616_M_BST1_OM_R_SFT 5
560#define RT5616_M_IN1_R_OM_R (0x1 << 4)
561#define RT5616_M_IN1_R_OM_R_SFT 4
562#define RT5616_M_RM_R_OM_R (0x1 << 3)
563#define RT5616_M_RM_R_OM_R_SFT 3
564#define RT5616_M_DAC_R1_OM_R (0x1)
565#define RT5616_M_DAC_R1_OM_R_SFT 0
566
567/* LOUT Mixer Control (0x53) */
568#define RT5616_M_DAC_L1_LM (0x1 << 15)
569#define RT5616_M_DAC_L1_LM_SFT 15
570#define RT5616_M_DAC_R1_LM (0x1 << 14)
571#define RT5616_M_DAC_R1_LM_SFT 14
572#define RT5616_M_OV_L_LM (0x1 << 13)
573#define RT5616_M_OV_L_LM_SFT 13
574#define RT5616_M_OV_R_LM (0x1 << 12)
575#define RT5616_M_OV_R_LM_SFT 12
576#define RT5616_G_LOUTMIX_MASK (0x1 << 11)
577#define RT5616_G_LOUTMIX_SFT 11
578
579/* Power Management for Digital 1 (0x61) */
580#define RT5616_PWR_I2S1 (0x1 << 15)
581#define RT5616_PWR_I2S1_BIT 15
582#define RT5616_PWR_I2S2 (0x1 << 14)
583#define RT5616_PWR_I2S2_BIT 14
584#define RT5616_PWR_DAC_L1 (0x1 << 12)
585#define RT5616_PWR_DAC_L1_BIT 12
586#define RT5616_PWR_DAC_R1 (0x1 << 11)
587#define RT5616_PWR_DAC_R1_BIT 11
588#define RT5616_PWR_ADC_L (0x1 << 2)
589#define RT5616_PWR_ADC_L_BIT 2
590#define RT5616_PWR_ADC_R (0x1 << 1)
591#define RT5616_PWR_ADC_R_BIT 1
592
593/* Power Management for Digital 2 (0x62) */
594#define RT5616_PWR_ADC_STO1_F (0x1 << 15)
595#define RT5616_PWR_ADC_STO1_F_BIT 15
596#define RT5616_PWR_DAC_STO1_F (0x1 << 11)
597#define RT5616_PWR_DAC_STO1_F_BIT 11
598
599/* Power Management for Analog 1 (0x63) */
600#define RT5616_PWR_VREF1 (0x1 << 15)
601#define RT5616_PWR_VREF1_BIT 15
602#define RT5616_PWR_FV1 (0x1 << 14)
603#define RT5616_PWR_FV1_BIT 14
604#define RT5616_PWR_MB (0x1 << 13)
605#define RT5616_PWR_MB_BIT 13
606#define RT5616_PWR_LM (0x1 << 12)
607#define RT5616_PWR_LM_BIT 12
608#define RT5616_PWR_BG (0x1 << 11)
609#define RT5616_PWR_BG_BIT 11
610#define RT5616_PWR_HP_L (0x1 << 7)
611#define RT5616_PWR_HP_L_BIT 7
612#define RT5616_PWR_HP_R (0x1 << 6)
613#define RT5616_PWR_HP_R_BIT 6
614#define RT5616_PWR_HA (0x1 << 5)
615#define RT5616_PWR_HA_BIT 5
616#define RT5616_PWR_VREF2 (0x1 << 4)
617#define RT5616_PWR_VREF2_BIT 4
618#define RT5616_PWR_FV2 (0x1 << 3)
619#define RT5616_PWR_FV2_BIT 3
620#define RT5616_PWR_LDO (0x1 << 2)
621#define RT5616_PWR_LDO_BIT 2
622#define RT5616_PWR_LDO_DVO_MASK (0x3)
623#define RT5616_PWR_LDO_DVO_1_0V 0
624#define RT5616_PWR_LDO_DVO_1_1V 1
625#define RT5616_PWR_LDO_DVO_1_2V 2
626#define RT5616_PWR_LDO_DVO_1_3V 3
627
628/* Power Management for Analog 2 (0x64) */
629#define RT5616_PWR_BST1 (0x1 << 15)
630#define RT5616_PWR_BST1_BIT 15
631#define RT5616_PWR_BST2 (0x1 << 14)
632#define RT5616_PWR_BST2_BIT 14
633#define RT5616_PWR_MB1 (0x1 << 11)
634#define RT5616_PWR_MB1_BIT 11
635#define RT5616_PWR_PLL (0x1 << 9)
636#define RT5616_PWR_PLL_BIT 9
637#define RT5616_PWR_BST1_OP2 (0x1 << 5)
638#define RT5616_PWR_BST1_OP2_BIT 5
639#define RT5616_PWR_BST2_OP2 (0x1 << 4)
640#define RT5616_PWR_BST2_OP2_BIT 4
641#define RT5616_PWR_BST3_OP2 (0x1 << 3)
642#define RT5616_PWR_BST3_OP2_BIT 3
643#define RT5616_PWR_JD_M (0x1 << 2)
644#define RT5616_PWM_JD_M_BIT 2
645#define RT5616_PWR_JD2 (0x1 << 1)
646#define RT5616_PWM_JD2_BIT 1
647#define RT5616_PWR_JD3 (0x1)
648#define RT5616_PWM_JD3_BIT 0
649
650/* Power Management for Mixer (0x65) */
651#define RT5616_PWR_OM_L (0x1 << 15)
652#define RT5616_PWR_OM_L_BIT 15
653#define RT5616_PWR_OM_R (0x1 << 14)
654#define RT5616_PWR_OM_R_BIT 14
655#define RT5616_PWR_RM_L (0x1 << 11)
656#define RT5616_PWR_RM_L_BIT 11
657#define RT5616_PWR_RM_R (0x1 << 10)
658#define RT5616_PWR_RM_R_BIT 10
659
660/* Power Management for Volume (0x66) */
661#define RT5616_PWR_OV_L (0x1 << 13)
662#define RT5616_PWR_OV_L_BIT 13
663#define RT5616_PWR_OV_R (0x1 << 12)
664#define RT5616_PWR_OV_R_BIT 12
665#define RT5616_PWR_HV_L (0x1 << 11)
666#define RT5616_PWR_HV_L_BIT 11
667#define RT5616_PWR_HV_R (0x1 << 10)
668#define RT5616_PWR_HV_R_BIT 10
669#define RT5616_PWR_IN1_L (0x1 << 9)
670#define RT5616_PWR_IN1_L_BIT 9
671#define RT5616_PWR_IN1_R (0x1 << 8)
672#define RT5616_PWR_IN1_R_BIT 8
673#define RT5616_PWR_IN2_L (0x1 << 7)
674#define RT5616_PWR_IN2_L_BIT 7
675#define RT5616_PWR_IN2_R (0x1 << 6)
676#define RT5616_PWR_IN2_R_BIT 6
677
678/* I2S1/2/3 Audio Serial Data Port Control (0x70 0x71) */
679#define RT5616_I2S_MS_MASK (0x1 << 15)
680#define RT5616_I2S_MS_SFT 15
681#define RT5616_I2S_MS_M (0x0 << 15)
682#define RT5616_I2S_MS_S (0x1 << 15)
683#define RT5616_I2S_O_CP_MASK (0x3 << 10)
684#define RT5616_I2S_O_CP_SFT 10
685#define RT5616_I2S_O_CP_OFF (0x0 << 10)
686#define RT5616_I2S_O_CP_U_LAW (0x1 << 10)
687#define RT5616_I2S_O_CP_A_LAW (0x2 << 10)
688#define RT5616_I2S_I_CP_MASK (0x3 << 8)
689#define RT5616_I2S_I_CP_SFT 8
690#define RT5616_I2S_I_CP_OFF (0x0 << 8)
691#define RT5616_I2S_I_CP_U_LAW (0x1 << 8)
692#define RT5616_I2S_I_CP_A_LAW (0x2 << 8)
693#define RT5616_I2S_BP_MASK (0x1 << 7)
694#define RT5616_I2S_BP_SFT 7
695#define RT5616_I2S_BP_NOR (0x0 << 7)
696#define RT5616_I2S_BP_INV (0x1 << 7)
697#define RT5616_I2S_DL_MASK (0x3 << 2)
698#define RT5616_I2S_DL_SFT 2
699#define RT5616_I2S_DL_16 (0x0 << 2)
700#define RT5616_I2S_DL_20 (0x1 << 2)
701#define RT5616_I2S_DL_24 (0x2 << 2)
702#define RT5616_I2S_DL_8 (0x3 << 2)
703#define RT5616_I2S_DF_MASK (0x3)
704#define RT5616_I2S_DF_SFT 0
705#define RT5616_I2S_DF_I2S (0x0)
706#define RT5616_I2S_DF_LEFT (0x1)
707#define RT5616_I2S_DF_PCM_A (0x2)
708#define RT5616_I2S_DF_PCM_B (0x3)
709
710/* ADC/DAC Clock Control 1 (0x73) */
711#define RT5616_I2S_PD1_MASK (0x7 << 12)
712#define RT5616_I2S_PD1_SFT 12
713#define RT5616_I2S_PD1_1 (0x0 << 12)
714#define RT5616_I2S_PD1_2 (0x1 << 12)
715#define RT5616_I2S_PD1_3 (0x2 << 12)
716#define RT5616_I2S_PD1_4 (0x3 << 12)
717#define RT5616_I2S_PD1_6 (0x4 << 12)
718#define RT5616_I2S_PD1_8 (0x5 << 12)
719#define RT5616_I2S_PD1_12 (0x6 << 12)
720#define RT5616_I2S_PD1_16 (0x7 << 12)
721#define RT5616_I2S_BCLK_MS2_MASK (0x1 << 11)
722#define RT5616_DAC_OSR_MASK (0x3 << 2)
723#define RT5616_DAC_OSR_SFT 2
724#define RT5616_DAC_OSR_128 (0x0 << 2)
725#define RT5616_DAC_OSR_64 (0x1 << 2)
726#define RT5616_DAC_OSR_32 (0x2 << 2)
727#define RT5616_DAC_OSR_128_3 (0x3 << 2)
728#define RT5616_ADC_OSR_MASK (0x3)
729#define RT5616_ADC_OSR_SFT 0
730#define RT5616_ADC_OSR_128 (0x0)
731#define RT5616_ADC_OSR_64 (0x1)
732#define RT5616_ADC_OSR_32 (0x2)
733#define RT5616_ADC_OSR_128_3 (0x3)
734
735/* ADC/DAC Clock Control 2 (0x74) */
736#define RT5616_DAHPF_EN (0x1 << 11)
737#define RT5616_DAHPF_EN_SFT 11
738#define RT5616_ADHPF_EN (0x1 << 10)
739#define RT5616_ADHPF_EN_SFT 10
740
741/* TDM Control 1 (0x77) */
742#define RT5616_TDM_INTEL_SEL_MASK (0x1 << 15)
743#define RT5616_TDM_INTEL_SEL_SFT 15
744#define RT5616_TDM_INTEL_SEL_64 (0x0 << 15)
745#define RT5616_TDM_INTEL_SEL_50 (0x1 << 15)
746#define RT5616_TDM_MODE_SEL_MASK (0x1 << 14)
747#define RT5616_TDM_MODE_SEL_SFT 14
748#define RT5616_TDM_MODE_SEL_NOR (0x0 << 14)
749#define RT5616_TDM_MODE_SEL_TDM (0x1 << 14)
750#define RT5616_TDM_CH_NUM_SEL_MASK (0x3 << 12)
751#define RT5616_TDM_CH_NUM_SEL_SFT 12
752#define RT5616_TDM_CH_NUM_SEL_2 (0x0 << 12)
753#define RT5616_TDM_CH_NUM_SEL_4 (0x1 << 12)
754#define RT5616_TDM_CH_NUM_SEL_6 (0x2 << 12)
755#define RT5616_TDM_CH_NUM_SEL_8 (0x3 << 12)
756#define RT5616_TDM_CH_LEN_SEL_MASK (0x3 << 10)
757#define RT5616_TDM_CH_LEN_SEL_SFT 10
758#define RT5616_TDM_CH_LEN_SEL_16 (0x0 << 10)
759#define RT5616_TDM_CH_LEN_SEL_20 (0x1 << 10)
760#define RT5616_TDM_CH_LEN_SEL_24 (0x2 << 10)
761#define RT5616_TDM_CH_LEN_SEL_32 (0x3 << 10)
762#define RT5616_TDM_ADC_SEL_MASK (0x1 << 9)
763#define RT5616_TDM_ADC_SEL_SFT 9
764#define RT5616_TDM_ADC_SEL_NOR (0x0 << 9)
765#define RT5616_TDM_ADC_SEL_SWAP (0x1 << 9)
766#define RT5616_TDM_ADC_START_SEL_MASK (0x1 << 8)
767#define RT5616_TDM_ADC_START_SEL_SFT 8
768#define RT5616_TDM_ADC_START_SEL_SL0 (0x0 << 8)
769#define RT5616_TDM_ADC_START_SEL_SL4 (0x1 << 8)
770#define RT5616_TDM_I2S_CH2_SEL_MASK (0x3 << 6)
771#define RT5616_TDM_I2S_CH2_SEL_SFT 6
772#define RT5616_TDM_I2S_CH2_SEL_LR (0x0 << 6)
773#define RT5616_TDM_I2S_CH2_SEL_RL (0x1 << 6)
774#define RT5616_TDM_I2S_CH2_SEL_LL (0x2 << 6)
775#define RT5616_TDM_I2S_CH2_SEL_RR (0x3 << 6)
776#define RT5616_TDM_I2S_CH4_SEL_MASK (0x3 << 4)
777#define RT5616_TDM_I2S_CH4_SEL_SFT 4
778#define RT5616_TDM_I2S_CH4_SEL_LR (0x0 << 4)
779#define RT5616_TDM_I2S_CH4_SEL_RL (0x1 << 4)
780#define RT5616_TDM_I2S_CH4_SEL_LL (0x2 << 4)
781#define RT5616_TDM_I2S_CH4_SEL_RR (0x3 << 4)
782#define RT5616_TDM_I2S_CH6_SEL_MASK (0x3 << 2)
783#define RT5616_TDM_I2S_CH6_SEL_SFT 2
784#define RT5616_TDM_I2S_CH6_SEL_LR (0x0 << 2)
785#define RT5616_TDM_I2S_CH6_SEL_RL (0x1 << 2)
786#define RT5616_TDM_I2S_CH6_SEL_LL (0x2 << 2)
787#define RT5616_TDM_I2S_CH6_SEL_RR (0x3 << 2)
788#define RT5616_TDM_I2S_CH8_SEL_MASK (0x3)
789#define RT5616_TDM_I2S_CH8_SEL_SFT 0
790#define RT5616_TDM_I2S_CH8_SEL_LR (0x0)
791#define RT5616_TDM_I2S_CH8_SEL_RL (0x1)
792#define RT5616_TDM_I2S_CH8_SEL_LL (0x2)
793#define RT5616_TDM_I2S_CH8_SEL_RR (0x3)
794
795/* TDM Control 2 (0x78) */
796#define RT5616_TDM_LRCK_POL_SEL_MASK (0x1 << 15)
797#define RT5616_TDM_LRCK_POL_SEL_SFT 15
798#define RT5616_TDM_LRCK_POL_SEL_NOR (0x0 << 15)
799#define RT5616_TDM_LRCK_POL_SEL_INV (0x1 << 15)
800#define RT5616_TDM_CH_VAL_SEL_MASK (0x1 << 14)
801#define RT5616_TDM_CH_VAL_SEL_SFT 14
802#define RT5616_TDM_CH_VAL_SEL_CH01 (0x0 << 14)
803#define RT5616_TDM_CH_VAL_SEL_CH0123 (0x1 << 14)
804#define RT5616_TDM_CH_VAL_EN (0x1 << 13)
805#define RT5616_TDM_CH_VAL_SFT 13
806#define RT5616_TDM_LPBK_EN (0x1 << 12)
807#define RT5616_TDM_LPBK_SFT 12
808#define RT5616_TDM_LRCK_PULSE_SEL_MASK (0x1 << 11)
809#define RT5616_TDM_LRCK_PULSE_SEL_SFT 11
810#define RT5616_TDM_LRCK_PULSE_SEL_BCLK (0x0 << 11)
811#define RT5616_TDM_LRCK_PULSE_SEL_CH (0x1 << 11)
812#define RT5616_TDM_END_EDGE_SEL_MASK (0x1 << 10)
813#define RT5616_TDM_END_EDGE_SEL_SFT 10
814#define RT5616_TDM_END_EDGE_SEL_POS (0x0 << 10)
815#define RT5616_TDM_END_EDGE_SEL_NEG (0x1 << 10)
816#define RT5616_TDM_END_EDGE_EN (0x1 << 9)
817#define RT5616_TDM_END_EDGE_EN_SFT 9
818#define RT5616_TDM_TRAN_EDGE_SEL_MASK (0x1 << 8)
819#define RT5616_TDM_TRAN_EDGE_SEL_SFT 8
820#define RT5616_TDM_TRAN_EDGE_SEL_POS (0x0 << 8)
821#define RT5616_TDM_TRAN_EDGE_SEL_NEG (0x1 << 8)
822#define RT5616_M_TDM2_L (0x1 << 7)
823#define RT5616_M_TDM2_L_SFT 7
824#define RT5616_M_TDM2_R (0x1 << 6)
825#define RT5616_M_TDM2_R_SFT 6
826#define RT5616_M_TDM4_L (0x1 << 5)
827#define RT5616_M_TDM4_L_SFT 5
828#define RT5616_M_TDM4_R (0x1 << 4)
829#define RT5616_M_TDM4_R_SFT 4
830
831/* Global Clock Control (0x80) */
832#define RT5616_SCLK_SRC_MASK (0x3 << 14)
833#define RT5616_SCLK_SRC_SFT 14
834#define RT5616_SCLK_SRC_MCLK (0x0 << 14)
835#define RT5616_SCLK_SRC_PLL1 (0x1 << 14)
836#define RT5616_PLL1_SRC_MASK (0x3 << 12)
837#define RT5616_PLL1_SRC_SFT 12
838#define RT5616_PLL1_SRC_MCLK (0x0 << 12)
839#define RT5616_PLL1_SRC_BCLK1 (0x1 << 12)
840#define RT5616_PLL1_SRC_BCLK2 (0x2 << 12)
841#define RT5616_PLL1_PD_MASK (0x1 << 3)
842#define RT5616_PLL1_PD_SFT 3
843#define RT5616_PLL1_PD_1 (0x0 << 3)
844#define RT5616_PLL1_PD_2 (0x1 << 3)
845
846#define RT5616_PLL_INP_MAX 40000000
847#define RT5616_PLL_INP_MIN 256000
848/* PLL M/N/K Code Control 1 (0x81) */
849#define RT5616_PLL_N_MAX 0x1ff
850#define RT5616_PLL_N_MASK (RT5616_PLL_N_MAX << 7)
851#define RT5616_PLL_N_SFT 7
852#define RT5616_PLL_K_MAX 0x1f
853#define RT5616_PLL_K_MASK (RT5616_PLL_K_MAX)
854#define RT5616_PLL_K_SFT 0
855
856/* PLL M/N/K Code Control 2 (0x82) */
857#define RT5616_PLL_M_MAX 0xf
858#define RT5616_PLL_M_MASK (RT5616_PLL_M_MAX << 12)
859#define RT5616_PLL_M_SFT 12
860#define RT5616_PLL_M_BP (0x1 << 11)
861#define RT5616_PLL_M_BP_SFT 11
862
863/* PLL tracking mode 1 (0x83) */
864#define RT5616_STO1_T_MASK (0x1 << 15)
865#define RT5616_STO1_T_SFT 15
866#define RT5616_STO1_T_SCLK (0x0 << 15)
867#define RT5616_STO1_T_LRCK1 (0x1 << 15)
868#define RT5616_STO2_T_MASK (0x1 << 12)
869#define RT5616_STO2_T_SFT 12
870#define RT5616_STO2_T_I2S2 (0x0 << 12)
871#define RT5616_STO2_T_LRCK2 (0x1 << 12)
872#define RT5616_ASRC2_REF_MASK (0x1 << 11)
873#define RT5616_ASRC2_REF_SFT 11
874#define RT5616_ASRC2_REF_LRCK2 (0x0 << 11)
875#define RT5616_ASRC2_REF_LRCK1 (0x1 << 11)
876#define RT5616_DMIC_1_M_MASK (0x1 << 9)
877#define RT5616_DMIC_1_M_SFT 9
878#define RT5616_DMIC_1_M_NOR (0x0 << 9)
879#define RT5616_DMIC_1_M_ASYN (0x1 << 9)
880
881/* PLL tracking mode 2 (0x84) */
882#define RT5616_STO1_ASRC_EN (0x1 << 15)
883#define RT5616_STO1_ASRC_EN_SFT 15
884#define RT5616_STO2_ASRC_EN (0x1 << 14)
885#define RT5616_STO2_ASRC_EN_SFT 14
886#define RT5616_STO1_DAC_M_MASK (0x1 << 13)
887#define RT5616_STO1_DAC_M_SFT 13
888#define RT5616_STO1_DAC_M_NOR (0x0 << 13)
889#define RT5616_STO1_DAC_M_ASRC (0x1 << 13)
890#define RT5616_STO2_DAC_M_MASK (0x1 << 12)
891#define RT5616_STO2_DAC_M_SFT 12
892#define RT5616_STO2_DAC_M_NOR (0x0 << 12)
893#define RT5616_STO2_DAC_M_ASRC (0x1 << 12)
894#define RT5616_ADC_M_MASK (0x1 << 11)
895#define RT5616_ADC_M_SFT 11
896#define RT5616_ADC_M_NOR (0x0 << 11)
897#define RT5616_ADC_M_ASRC (0x1 << 11)
898#define RT5616_I2S1_R_D_MASK (0x1 << 4)
899#define RT5616_I2S1_R_D_SFT 4
900#define RT5616_I2S1_R_D_DIS (0x0 << 4)
901#define RT5616_I2S1_R_D_EN (0x1 << 4)
902#define RT5616_I2S2_R_D_MASK (0x1 << 3)
903#define RT5616_I2S2_R_D_SFT 3
904#define RT5616_I2S2_R_D_DIS (0x0 << 3)
905#define RT5616_I2S2_R_D_EN (0x1 << 3)
906#define RT5616_PRE_SCLK_MASK (0x3)
907#define RT5616_PRE_SCLK_SFT 0
908#define RT5616_PRE_SCLK_512 (0x0)
909#define RT5616_PRE_SCLK_1024 (0x1)
910#define RT5616_PRE_SCLK_2048 (0x2)
911
912/* PLL tracking mode 3 (0x85) */
913#define RT5616_I2S1_RATE_MASK (0xf << 12)
914#define RT5616_I2S1_RATE_SFT 12
915#define RT5616_I2S2_RATE_MASK (0xf << 8)
916#define RT5616_I2S2_RATE_SFT 8
917#define RT5616_G_ASRC_LP_MASK (0x1 << 3)
918#define RT5616_G_ASRC_LP_SFT 3
919#define RT5616_ASRC_LP_F_M (0x1 << 2)
920#define RT5616_ASRC_LP_F_SFT 2
921#define RT5616_ASRC_LP_F_NOR (0x0 << 2)
922#define RT5616_ASRC_LP_F_SB (0x1 << 2)
923#define RT5616_FTK_PH_DET_MASK (0x3)
924#define RT5616_FTK_PH_DET_SFT 0
925#define RT5616_FTK_PH_DET_DIV1 (0x0)
926#define RT5616_FTK_PH_DET_DIV2 (0x1)
927#define RT5616_FTK_PH_DET_DIV4 (0x2)
928#define RT5616_FTK_PH_DET_DIV8 (0x3)
929
930/*PLL tracking mode 6 (0x89) */
931#define RT5616_I2S1_PD_MASK (0x7 << 12)
932#define RT5616_I2S1_PD_SFT 12
933#define RT5616_I2S2_PD_MASK (0x7 << 8)
934#define RT5616_I2S2_PD_SFT 8
935
936/*PLL tracking mode 7 (0x8a) */
937#define RT5616_FSI1_RATE_MASK (0xf << 12)
938#define RT5616_FSI1_RATE_SFT 12
939#define RT5616_FSI2_RATE_MASK (0xf << 8)
940#define RT5616_FSI2_RATE_SFT 8
941
942/* HPOUT Over Current Detection (0x8b) */
943#define RT5616_HP_OVCD_MASK (0x1 << 10)
944#define RT5616_HP_OVCD_SFT 10
945#define RT5616_HP_OVCD_DIS (0x0 << 10)
946#define RT5616_HP_OVCD_EN (0x1 << 10)
947#define RT5616_HP_OC_TH_MASK (0x3 << 8)
948#define RT5616_HP_OC_TH_SFT 8
949#define RT5616_HP_OC_TH_90 (0x0 << 8)
950#define RT5616_HP_OC_TH_105 (0x1 << 8)
951#define RT5616_HP_OC_TH_120 (0x2 << 8)
952#define RT5616_HP_OC_TH_135 (0x3 << 8)
953
954/* Depop Mode Control 1 (0x8e) */
955#define RT5616_SMT_TRIG_MASK (0x1 << 15)
956#define RT5616_SMT_TRIG_SFT 15
957#define RT5616_SMT_TRIG_DIS (0x0 << 15)
958#define RT5616_SMT_TRIG_EN (0x1 << 15)
959#define RT5616_HP_L_SMT_MASK (0x1 << 9)
960#define RT5616_HP_L_SMT_SFT 9
961#define RT5616_HP_L_SMT_DIS (0x0 << 9)
962#define RT5616_HP_L_SMT_EN (0x1 << 9)
963#define RT5616_HP_R_SMT_MASK (0x1 << 8)
964#define RT5616_HP_R_SMT_SFT 8
965#define RT5616_HP_R_SMT_DIS (0x0 << 8)
966#define RT5616_HP_R_SMT_EN (0x1 << 8)
967#define RT5616_HP_CD_PD_MASK (0x1 << 7)
968#define RT5616_HP_CD_PD_SFT 7
969#define RT5616_HP_CD_PD_DIS (0x0 << 7)
970#define RT5616_HP_CD_PD_EN (0x1 << 7)
971#define RT5616_RSTN_MASK (0x1 << 6)
972#define RT5616_RSTN_SFT 6
973#define RT5616_RSTN_DIS (0x0 << 6)
974#define RT5616_RSTN_EN (0x1 << 6)
975#define RT5616_RSTP_MASK (0x1 << 5)
976#define RT5616_RSTP_SFT 5
977#define RT5616_RSTP_DIS (0x0 << 5)
978#define RT5616_RSTP_EN (0x1 << 5)
979#define RT5616_HP_CO_MASK (0x1 << 4)
980#define RT5616_HP_CO_SFT 4
981#define RT5616_HP_CO_DIS (0x0 << 4)
982#define RT5616_HP_CO_EN (0x1 << 4)
983#define RT5616_HP_CP_MASK (0x1 << 3)
984#define RT5616_HP_CP_SFT 3
985#define RT5616_HP_CP_PD (0x0 << 3)
986#define RT5616_HP_CP_PU (0x1 << 3)
987#define RT5616_HP_SG_MASK (0x1 << 2)
988#define RT5616_HP_SG_SFT 2
989#define RT5616_HP_SG_DIS (0x0 << 2)
990#define RT5616_HP_SG_EN (0x1 << 2)
991#define RT5616_HP_DP_MASK (0x1 << 1)
992#define RT5616_HP_DP_SFT 1
993#define RT5616_HP_DP_PD (0x0 << 1)
994#define RT5616_HP_DP_PU (0x1 << 1)
995#define RT5616_HP_CB_MASK (0x1)
996#define RT5616_HP_CB_SFT 0
997#define RT5616_HP_CB_PD (0x0)
998#define RT5616_HP_CB_PU (0x1)
999
1000/* Depop Mode Control 2 (0x8f) */
1001#define RT5616_DEPOP_MASK (0x1 << 13)
1002#define RT5616_DEPOP_SFT 13
1003#define RT5616_DEPOP_AUTO (0x0 << 13)
1004#define RT5616_DEPOP_MAN (0x1 << 13)
1005#define RT5616_RAMP_MASK (0x1 << 12)
1006#define RT5616_RAMP_SFT 12
1007#define RT5616_RAMP_DIS (0x0 << 12)
1008#define RT5616_RAMP_EN (0x1 << 12)
1009#define RT5616_BPS_MASK (0x1 << 11)
1010#define RT5616_BPS_SFT 11
1011#define RT5616_BPS_DIS (0x0 << 11)
1012#define RT5616_BPS_EN (0x1 << 11)
1013#define RT5616_FAST_UPDN_MASK (0x1 << 10)
1014#define RT5616_FAST_UPDN_SFT 10
1015#define RT5616_FAST_UPDN_DIS (0x0 << 10)
1016#define RT5616_FAST_UPDN_EN (0x1 << 10)
1017#define RT5616_MRES_MASK (0x3 << 8)
1018#define RT5616_MRES_SFT 8
1019#define RT5616_MRES_15MO (0x0 << 8)
1020#define RT5616_MRES_25MO (0x1 << 8)
1021#define RT5616_MRES_35MO (0x2 << 8)
1022#define RT5616_MRES_45MO (0x3 << 8)
1023#define RT5616_VLO_MASK (0x1 << 7)
1024#define RT5616_VLO_SFT 7
1025#define RT5616_VLO_3V (0x0 << 7)
1026#define RT5616_VLO_32V (0x1 << 7)
1027#define RT5616_DIG_DP_MASK (0x1 << 6)
1028#define RT5616_DIG_DP_SFT 6
1029#define RT5616_DIG_DP_DIS (0x0 << 6)
1030#define RT5616_DIG_DP_EN (0x1 << 6)
1031#define RT5616_DP_TH_MASK (0x3 << 4)
1032#define RT5616_DP_TH_SFT 4
1033
1034/* Depop Mode Control 3 (0x90) */
1035#define RT5616_CP_SYS_MASK (0x7 << 12)
1036#define RT5616_CP_SYS_SFT 12
1037#define RT5616_CP_FQ1_MASK (0x7 << 8)
1038#define RT5616_CP_FQ1_SFT 8
1039#define RT5616_CP_FQ2_MASK (0x7 << 4)
1040#define RT5616_CP_FQ2_SFT 4
1041#define RT5616_CP_FQ3_MASK (0x7)
1042#define RT5616_CP_FQ3_SFT 0
1043#define RT5616_CP_FQ_1_5_KHZ 0
1044#define RT5616_CP_FQ_3_KHZ 1
1045#define RT5616_CP_FQ_6_KHZ 2
1046#define RT5616_CP_FQ_12_KHZ 3
1047#define RT5616_CP_FQ_24_KHZ 4
1048#define RT5616_CP_FQ_48_KHZ 5
1049#define RT5616_CP_FQ_96_KHZ 6
1050#define RT5616_CP_FQ_192_KHZ 7
1051
1052/* HPOUT charge pump (0x91) */
1053#define RT5616_OSW_L_MASK (0x1 << 11)
1054#define RT5616_OSW_L_SFT 11
1055#define RT5616_OSW_L_DIS (0x0 << 11)
1056#define RT5616_OSW_L_EN (0x1 << 11)
1057#define RT5616_OSW_R_MASK (0x1 << 10)
1058#define RT5616_OSW_R_SFT 10
1059#define RT5616_OSW_R_DIS (0x0 << 10)
1060#define RT5616_OSW_R_EN (0x1 << 10)
1061#define RT5616_PM_HP_MASK (0x3 << 8)
1062#define RT5616_PM_HP_SFT 8
1063#define RT5616_PM_HP_LV (0x0 << 8)
1064#define RT5616_PM_HP_MV (0x1 << 8)
1065#define RT5616_PM_HP_HV (0x2 << 8)
1066#define RT5616_IB_HP_MASK (0x3 << 6)
1067#define RT5616_IB_HP_SFT 6
1068#define RT5616_IB_HP_125IL (0x0 << 6)
1069#define RT5616_IB_HP_25IL (0x1 << 6)
1070#define RT5616_IB_HP_5IL (0x2 << 6)
1071#define RT5616_IB_HP_1IL (0x3 << 6)
1072
1073/* Micbias Control (0x93) */
1074#define RT5616_MIC1_BS_MASK (0x1 << 15)
1075#define RT5616_MIC1_BS_SFT 15
1076#define RT5616_MIC1_BS_9AV (0x0 << 15)
1077#define RT5616_MIC1_BS_75AV (0x1 << 15)
1078#define RT5616_MIC1_CLK_MASK (0x1 << 13)
1079#define RT5616_MIC1_CLK_SFT 13
1080#define RT5616_MIC1_CLK_DIS (0x0 << 13)
1081#define RT5616_MIC1_CLK_EN (0x1 << 13)
1082#define RT5616_MIC1_OVCD_MASK (0x1 << 11)
1083#define RT5616_MIC1_OVCD_SFT 11
1084#define RT5616_MIC1_OVCD_DIS (0x0 << 11)
1085#define RT5616_MIC1_OVCD_EN (0x1 << 11)
1086#define RT5616_MIC1_OVTH_MASK (0x3 << 9)
1087#define RT5616_MIC1_OVTH_SFT 9
1088#define RT5616_MIC1_OVTH_600UA (0x0 << 9)
1089#define RT5616_MIC1_OVTH_1500UA (0x1 << 9)
1090#define RT5616_MIC1_OVTH_2000UA (0x2 << 9)
1091#define RT5616_PWR_MB_MASK (0x1 << 5)
1092#define RT5616_PWR_MB_SFT 5
1093#define RT5616_PWR_MB_PD (0x0 << 5)
1094#define RT5616_PWR_MB_PU (0x1 << 5)
1095#define RT5616_PWR_CLK12M_MASK (0x1 << 4)
1096#define RT5616_PWR_CLK12M_SFT 4
1097#define RT5616_PWR_CLK12M_PD (0x0 << 4)
1098#define RT5616_PWR_CLK12M_PU (0x1 << 4)
1099
1100/* Analog JD Control 1 (0x94) */
1101#define RT5616_JD2_CMP_MASK (0x7 << 12)
1102#define RT5616_JD2_CMP_SFT 12
1103#define RT5616_JD_PU (0x1 << 11)
1104#define RT5616_JD_PU_SFT 11
1105#define RT5616_JD_PD (0x1 << 10)
1106#define RT5616_JD_PD_SFT 10
1107#define RT5616_JD_MODE_SEL_MASK (0x3 << 8)
1108#define RT5616_JD_MODE_SEL_SFT 8
1109#define RT5616_JD_MODE_SEL_M0 (0x0 << 8)
1110#define RT5616_JD_MODE_SEL_M1 (0x1 << 8)
1111#define RT5616_JD_MODE_SEL_M2 (0x2 << 8)
1112#define RT5616_JD_M_CMP (0x7 << 4)
1113#define RT5616_JD_M_CMP_SFT 4
1114#define RT5616_JD_M_PU (0x1 << 3)
1115#define RT5616_JD_M_PU_SFT 3
1116#define RT5616_JD_M_PD (0x1 << 2)
1117#define RT5616_JD_M_PD_SFT 2
1118#define RT5616_JD_M_MODE_SEL_MASK (0x3)
1119#define RT5616_JD_M_MODE_SEL_SFT 0
1120#define RT5616_JD_M_MODE_SEL_M0 (0x0)
1121#define RT5616_JD_M_MODE_SEL_M1 (0x1)
1122#define RT5616_JD_M_MODE_SEL_M2 (0x2)
1123
1124/* Analog JD Control 2 (0x95) */
1125#define RT5616_JD3_CMP_MASK (0x7 << 12)
1126#define RT5616_JD3_CMP_SFT 12
1127
1128/* EQ Control 1 (0xb0) */
1129#define RT5616_EQ_SRC_MASK (0x1 << 15)
1130#define RT5616_EQ_SRC_SFT 15
1131#define RT5616_EQ_SRC_DAC (0x0 << 15)
1132#define RT5616_EQ_SRC_ADC (0x1 << 15)
1133#define RT5616_EQ_UPD (0x1 << 14)
1134#define RT5616_EQ_UPD_BIT 14
1135#define RT5616_EQ_CD_MASK (0x1 << 13)
1136#define RT5616_EQ_CD_SFT 13
1137#define RT5616_EQ_CD_DIS (0x0 << 13)
1138#define RT5616_EQ_CD_EN (0x1 << 13)
1139#define RT5616_EQ_DITH_MASK (0x3 << 8)
1140#define RT5616_EQ_DITH_SFT 8
1141#define RT5616_EQ_DITH_NOR (0x0 << 8)
1142#define RT5616_EQ_DITH_LSB (0x1 << 8)
1143#define RT5616_EQ_DITH_LSB_1 (0x2 << 8)
1144#define RT5616_EQ_DITH_LSB_2 (0x3 << 8)
1145#define RT5616_EQ_CD_F (0x1 << 7)
1146#define RT5616_EQ_CD_F_BIT 7
1147#define RT5616_EQ_STA_HP2 (0x1 << 6)
1148#define RT5616_EQ_STA_HP2_BIT 6
1149#define RT5616_EQ_STA_HP1 (0x1 << 5)
1150#define RT5616_EQ_STA_HP1_BIT 5
1151#define RT5616_EQ_STA_BP4 (0x1 << 4)
1152#define RT5616_EQ_STA_BP4_BIT 4
1153#define RT5616_EQ_STA_BP3 (0x1 << 3)
1154#define RT5616_EQ_STA_BP3_BIT 3
1155#define RT5616_EQ_STA_BP2 (0x1 << 2)
1156#define RT5616_EQ_STA_BP2_BIT 2
1157#define RT5616_EQ_STA_BP1 (0x1 << 1)
1158#define RT5616_EQ_STA_BP1_BIT 1
1159#define RT5616_EQ_STA_LP (0x1)
1160#define RT5616_EQ_STA_LP_BIT 0
1161
1162/* EQ Control 2 (0xb1) */
1163#define RT5616_EQ_HPF1_M_MASK (0x1 << 8)
1164#define RT5616_EQ_HPF1_M_SFT 8
1165#define RT5616_EQ_HPF1_M_HI (0x0 << 8)
1166#define RT5616_EQ_HPF1_M_1ST (0x1 << 8)
1167#define RT5616_EQ_LPF1_M_MASK (0x1 << 7)
1168#define RT5616_EQ_LPF1_M_SFT 7
1169#define RT5616_EQ_LPF1_M_LO (0x0 << 7)
1170#define RT5616_EQ_LPF1_M_1ST (0x1 << 7)
1171#define RT5616_EQ_HPF2_MASK (0x1 << 6)
1172#define RT5616_EQ_HPF2_SFT 6
1173#define RT5616_EQ_HPF2_DIS (0x0 << 6)
1174#define RT5616_EQ_HPF2_EN (0x1 << 6)
1175#define RT5616_EQ_HPF1_MASK (0x1 << 5)
1176#define RT5616_EQ_HPF1_SFT 5
1177#define RT5616_EQ_HPF1_DIS (0x0 << 5)
1178#define RT5616_EQ_HPF1_EN (0x1 << 5)
1179#define RT5616_EQ_BPF4_MASK (0x1 << 4)
1180#define RT5616_EQ_BPF4_SFT 4
1181#define RT5616_EQ_BPF4_DIS (0x0 << 4)
1182#define RT5616_EQ_BPF4_EN (0x1 << 4)
1183#define RT5616_EQ_BPF3_MASK (0x1 << 3)
1184#define RT5616_EQ_BPF3_SFT 3
1185#define RT5616_EQ_BPF3_DIS (0x0 << 3)
1186#define RT5616_EQ_BPF3_EN (0x1 << 3)
1187#define RT5616_EQ_BPF2_MASK (0x1 << 2)
1188#define RT5616_EQ_BPF2_SFT 2
1189#define RT5616_EQ_BPF2_DIS (0x0 << 2)
1190#define RT5616_EQ_BPF2_EN (0x1 << 2)
1191#define RT5616_EQ_BPF1_MASK (0x1 << 1)
1192#define RT5616_EQ_BPF1_SFT 1
1193#define RT5616_EQ_BPF1_DIS (0x0 << 1)
1194#define RT5616_EQ_BPF1_EN (0x1 << 1)
1195#define RT5616_EQ_LPF_MASK (0x1)
1196#define RT5616_EQ_LPF_SFT 0
1197#define RT5616_EQ_LPF_DIS (0x0)
1198#define RT5616_EQ_LPF_EN (0x1)
1199#define RT5616_EQ_CTRL_MASK (0x7f)
1200
1201/* Memory Test (0xb2) */
1202#define RT5616_MT_MASK (0x1 << 15)
1203#define RT5616_MT_SFT 15
1204#define RT5616_MT_DIS (0x0 << 15)
1205#define RT5616_MT_EN (0x1 << 15)
1206
1207/* DRC/AGC Control 1 (0xb4) */
1208#define RT5616_DRC_AGC_P_MASK (0x1 << 15)
1209#define RT5616_DRC_AGC_P_SFT 15
1210#define RT5616_DRC_AGC_P_DAC (0x0 << 15)
1211#define RT5616_DRC_AGC_P_ADC (0x1 << 15)
1212#define RT5616_DRC_AGC_MASK (0x1 << 14)
1213#define RT5616_DRC_AGC_SFT 14
1214#define RT5616_DRC_AGC_DIS (0x0 << 14)
1215#define RT5616_DRC_AGC_EN (0x1 << 14)
1216#define RT5616_DRC_AGC_UPD (0x1 << 13)
1217#define RT5616_DRC_AGC_UPD_BIT 13
1218#define RT5616_DRC_AGC_AR_MASK (0x1f << 8)
1219#define RT5616_DRC_AGC_AR_SFT 8
1220#define RT5616_DRC_AGC_R_MASK (0x7 << 5)
1221#define RT5616_DRC_AGC_R_SFT 5
1222#define RT5616_DRC_AGC_R_48K (0x1 << 5)
1223#define RT5616_DRC_AGC_R_96K (0x2 << 5)
1224#define RT5616_DRC_AGC_R_192K (0x3 << 5)
1225#define RT5616_DRC_AGC_R_441K (0x5 << 5)
1226#define RT5616_DRC_AGC_R_882K (0x6 << 5)
1227#define RT5616_DRC_AGC_R_1764K (0x7 << 5)
1228#define RT5616_DRC_AGC_RC_MASK (0x1f)
1229#define RT5616_DRC_AGC_RC_SFT 0
1230
1231/* DRC/AGC Control 2 (0xb5) */
1232#define RT5616_DRC_AGC_POB_MASK (0x3f << 8)
1233#define RT5616_DRC_AGC_POB_SFT 8
1234#define RT5616_DRC_AGC_CP_MASK (0x1 << 7)
1235#define RT5616_DRC_AGC_CP_SFT 7
1236#define RT5616_DRC_AGC_CP_DIS (0x0 << 7)
1237#define RT5616_DRC_AGC_CP_EN (0x1 << 7)
1238#define RT5616_DRC_AGC_CPR_MASK (0x3 << 5)
1239#define RT5616_DRC_AGC_CPR_SFT 5
1240#define RT5616_DRC_AGC_CPR_1_1 (0x0 << 5)
1241#define RT5616_DRC_AGC_CPR_1_2 (0x1 << 5)
1242#define RT5616_DRC_AGC_CPR_1_3 (0x2 << 5)
1243#define RT5616_DRC_AGC_CPR_1_4 (0x3 << 5)
1244#define RT5616_DRC_AGC_PRB_MASK (0x1f)
1245#define RT5616_DRC_AGC_PRB_SFT 0
1246
1247/* DRC/AGC Control 3 (0xb6) */
1248#define RT5616_DRC_AGC_NGB_MASK (0xf << 12)
1249#define RT5616_DRC_AGC_NGB_SFT 12
1250#define RT5616_DRC_AGC_TAR_MASK (0x1f << 7)
1251#define RT5616_DRC_AGC_TAR_SFT 7
1252#define RT5616_DRC_AGC_NG_MASK (0x1 << 6)
1253#define RT5616_DRC_AGC_NG_SFT 6
1254#define RT5616_DRC_AGC_NG_DIS (0x0 << 6)
1255#define RT5616_DRC_AGC_NG_EN (0x1 << 6)
1256#define RT5616_DRC_AGC_NGH_MASK (0x1 << 5)
1257#define RT5616_DRC_AGC_NGH_SFT 5
1258#define RT5616_DRC_AGC_NGH_DIS (0x0 << 5)
1259#define RT5616_DRC_AGC_NGH_EN (0x1 << 5)
1260#define RT5616_DRC_AGC_NGT_MASK (0x1f)
1261#define RT5616_DRC_AGC_NGT_SFT 0
1262
1263/* Jack Detect Control 1 (0xbb) */
1264#define RT5616_JD_MASK (0x7 << 13)
1265#define RT5616_JD_SFT 13
1266#define RT5616_JD_DIS (0x0 << 13)
1267#define RT5616_JD_GPIO1 (0x1 << 13)
1268#define RT5616_JD_GPIO2 (0x2 << 13)
1269#define RT5616_JD_GPIO3 (0x3 << 13)
1270#define RT5616_JD_GPIO4 (0x4 << 13)
1271#define RT5616_JD_GPIO5 (0x5 << 13)
1272#define RT5616_JD_GPIO6 (0x6 << 13)
1273#define RT5616_JD_HP_MASK (0x1 << 11)
1274#define RT5616_JD_HP_SFT 11
1275#define RT5616_JD_HP_DIS (0x0 << 11)
1276#define RT5616_JD_HP_EN (0x1 << 11)
1277#define RT5616_JD_HP_TRG_MASK (0x1 << 10)
1278#define RT5616_JD_HP_TRG_SFT 10
1279#define RT5616_JD_HP_TRG_LO (0x0 << 10)
1280#define RT5616_JD_HP_TRG_HI (0x1 << 10)
1281#define RT5616_JD_SPL_MASK (0x1 << 9)
1282#define RT5616_JD_SPL_SFT 9
1283#define RT5616_JD_SPL_DIS (0x0 << 9)
1284#define RT5616_JD_SPL_EN (0x1 << 9)
1285#define RT5616_JD_SPL_TRG_MASK (0x1 << 8)
1286#define RT5616_JD_SPL_TRG_SFT 8
1287#define RT5616_JD_SPL_TRG_LO (0x0 << 8)
1288#define RT5616_JD_SPL_TRG_HI (0x1 << 8)
1289#define RT5616_JD_SPR_MASK (0x1 << 7)
1290#define RT5616_JD_SPR_SFT 7
1291#define RT5616_JD_SPR_DIS (0x0 << 7)
1292#define RT5616_JD_SPR_EN (0x1 << 7)
1293#define RT5616_JD_SPR_TRG_MASK (0x1 << 6)
1294#define RT5616_JD_SPR_TRG_SFT 6
1295#define RT5616_JD_SPR_TRG_LO (0x0 << 6)
1296#define RT5616_JD_SPR_TRG_HI (0x1 << 6)
1297#define RT5616_JD_LO_MASK (0x1 << 3)
1298#define RT5616_JD_LO_SFT 3
1299#define RT5616_JD_LO_DIS (0x0 << 3)
1300#define RT5616_JD_LO_EN (0x1 << 3)
1301#define RT5616_JD_LO_TRG_MASK (0x1 << 2)
1302#define RT5616_JD_LO_TRG_SFT 2
1303#define RT5616_JD_LO_TRG_LO (0x0 << 2)
1304#define RT5616_JD_LO_TRG_HI (0x1 << 2)
1305
1306/* Jack Detect Control 2 (0xbc) */
1307#define RT5616_JD_TRG_SEL_MASK (0x7 << 9)
1308#define RT5616_JD_TRG_SEL_SFT 9
1309#define RT5616_JD_TRG_SEL_GPIO (0x0 << 9)
1310#define RT5616_JD_TRG_SEL_JD1_1 (0x1 << 9)
1311#define RT5616_JD_TRG_SEL_JD1_2 (0x2 << 9)
1312#define RT5616_JD_TRG_SEL_JD2 (0x3 << 9)
1313#define RT5616_JD_TRG_SEL_JD3 (0x4 << 9)
1314#define RT5616_JD3_IRQ_EN (0x1 << 8)
1315#define RT5616_JD3_IRQ_EN_SFT 8
1316#define RT5616_JD3_EN_STKY (0x1 << 7)
1317#define RT5616_JD3_EN_STKY_SFT 7
1318#define RT5616_JD3_INV (0x1 << 6)
1319#define RT5616_JD3_INV_SFT 6
1320
1321/* IRQ Control 1 (0xbd) */
1322#define RT5616_IRQ_JD_MASK (0x1 << 15)
1323#define RT5616_IRQ_JD_SFT 15
1324#define RT5616_IRQ_JD_BP (0x0 << 15)
1325#define RT5616_IRQ_JD_NOR (0x1 << 15)
1326#define RT5616_JD_STKY_MASK (0x1 << 13)
1327#define RT5616_JD_STKY_SFT 13
1328#define RT5616_JD_STKY_DIS (0x0 << 13)
1329#define RT5616_JD_STKY_EN (0x1 << 13)
1330#define RT5616_JD_P_MASK (0x1 << 11)
1331#define RT5616_JD_P_SFT 11
1332#define RT5616_JD_P_NOR (0x0 << 11)
1333#define RT5616_JD_P_INV (0x1 << 11)
1334#define RT5616_JD1_1_IRQ_EN (0x1 << 9)
1335#define RT5616_JD1_1_IRQ_EN_SFT 9
1336#define RT5616_JD1_1_EN_STKY (0x1 << 8)
1337#define RT5616_JD1_1_EN_STKY_SFT 8
1338#define RT5616_JD1_1_INV (0x1 << 7)
1339#define RT5616_JD1_1_INV_SFT 7
1340#define RT5616_JD1_2_IRQ_EN (0x1 << 6)
1341#define RT5616_JD1_2_IRQ_EN_SFT 6
1342#define RT5616_JD1_2_EN_STKY (0x1 << 5)
1343#define RT5616_JD1_2_EN_STKY_SFT 5
1344#define RT5616_JD1_2_INV (0x1 << 4)
1345#define RT5616_JD1_2_INV_SFT 4
1346#define RT5616_JD2_IRQ_EN (0x1 << 3)
1347#define RT5616_JD2_IRQ_EN_SFT 3
1348#define RT5616_JD2_EN_STKY (0x1 << 2)
1349#define RT5616_JD2_EN_STKY_SFT 2
1350#define RT5616_JD2_INV (0x1 << 1)
1351#define RT5616_JD2_INV_SFT 1
1352
1353/* IRQ Control 2 (0xbe) */
1354#define RT5616_IRQ_MB1_OC_MASK (0x1 << 15)
1355#define RT5616_IRQ_MB1_OC_SFT 15
1356#define RT5616_IRQ_MB1_OC_BP (0x0 << 15)
1357#define RT5616_IRQ_MB1_OC_NOR (0x1 << 15)
1358#define RT5616_MB1_OC_STKY_MASK (0x1 << 11)
1359#define RT5616_MB1_OC_STKY_SFT 11
1360#define RT5616_MB1_OC_STKY_DIS (0x0 << 11)
1361#define RT5616_MB1_OC_STKY_EN (0x1 << 11)
1362#define RT5616_MB1_OC_P_MASK (0x1 << 7)
1363#define RT5616_MB1_OC_P_SFT 7
1364#define RT5616_MB1_OC_P_NOR (0x0 << 7)
1365#define RT5616_MB1_OC_P_INV (0x1 << 7)
1366#define RT5616_MB2_OC_P_MASK (0x1 << 6)
1367#define RT5616_MB1_OC_CLR (0x1 << 3)
1368#define RT5616_MB1_OC_CLR_SFT 3
1369#define RT5616_STA_GPIO8 (0x1)
1370#define RT5616_STA_GPIO8_BIT 0
1371
1372/* Internal Status and GPIO status (0xbf) */
1373#define RT5616_STA_JD3 (0x1 << 15)
1374#define RT5616_STA_JD3_BIT 15
1375#define RT5616_STA_JD2 (0x1 << 14)
1376#define RT5616_STA_JD2_BIT 14
1377#define RT5616_STA_JD1_2 (0x1 << 13)
1378#define RT5616_STA_JD1_2_BIT 13
1379#define RT5616_STA_JD1_1 (0x1 << 12)
1380#define RT5616_STA_JD1_1_BIT 12
1381#define RT5616_STA_GP7 (0x1 << 11)
1382#define RT5616_STA_GP7_BIT 11
1383#define RT5616_STA_GP6 (0x1 << 10)
1384#define RT5616_STA_GP6_BIT 10
1385#define RT5616_STA_GP5 (0x1 << 9)
1386#define RT5616_STA_GP5_BIT 9
1387#define RT5616_STA_GP1 (0x1 << 8)
1388#define RT5616_STA_GP1_BIT 8
1389#define RT5616_STA_GP2 (0x1 << 7)
1390#define RT5616_STA_GP2_BIT 7
1391#define RT5616_STA_GP3 (0x1 << 6)
1392#define RT5616_STA_GP3_BIT 6
1393#define RT5616_STA_GP4 (0x1 << 5)
1394#define RT5616_STA_GP4_BIT 5
1395#define RT5616_STA_GP_JD (0x1 << 4)
1396#define RT5616_STA_GP_JD_BIT 4
1397
1398/* GPIO Control 1 (0xc0) */
1399#define RT5616_GP1_PIN_MASK (0x1 << 15)
1400#define RT5616_GP1_PIN_SFT 15
1401#define RT5616_GP1_PIN_GPIO1 (0x0 << 15)
1402#define RT5616_GP1_PIN_IRQ (0x1 << 15)
1403#define RT5616_GP2_PIN_MASK (0x1 << 14)
1404#define RT5616_GP2_PIN_SFT 14
1405#define RT5616_GP2_PIN_GPIO2 (0x0 << 14)
1406#define RT5616_GP2_PIN_DMIC1_SCL (0x1 << 14)
1407#define RT5616_GPIO_M_MASK (0x1 << 9)
1408#define RT5616_GPIO_M_SFT 9
1409#define RT5616_GPIO_M_FLT (0x0 << 9)
1410#define RT5616_GPIO_M_PH (0x1 << 9)
1411#define RT5616_I2S2_SEL_MASK (0x1 << 8)
1412#define RT5616_I2S2_SEL_SFT 8
1413#define RT5616_I2S2_SEL_I2S (0x0 << 8)
1414#define RT5616_I2S2_SEL_GPIO (0x1 << 8)
1415#define RT5616_GP5_PIN_MASK (0x1 << 7)
1416#define RT5616_GP5_PIN_SFT 7
1417#define RT5616_GP5_PIN_GPIO5 (0x0 << 7)
1418#define RT5616_GP5_PIN_IRQ (0x1 << 7)
1419#define RT5616_GP6_PIN_MASK (0x1 << 6)
1420#define RT5616_GP6_PIN_SFT 6
1421#define RT5616_GP6_PIN_GPIO6 (0x0 << 6)
1422#define RT5616_GP6_PIN_DMIC_SDA (0x1 << 6)
1423#define RT5616_GP7_PIN_MASK (0x1 << 5)
1424#define RT5616_GP7_PIN_SFT 5
1425#define RT5616_GP7_PIN_GPIO7 (0x0 << 5)
1426#define RT5616_GP7_PIN_IRQ (0x1 << 5)
1427#define RT5616_GP8_PIN_MASK (0x1 << 4)
1428#define RT5616_GP8_PIN_SFT 4
1429#define RT5616_GP8_PIN_GPIO8 (0x0 << 4)
1430#define RT5616_GP8_PIN_DMIC_SDA (0x1 << 4)
1431#define RT5616_GPIO_PDM_SEL_MASK (0x1 << 3)
1432#define RT5616_GPIO_PDM_SEL_SFT 3
1433#define RT5616_GPIO_PDM_SEL_GPIO (0x0 << 3)
1434#define RT5616_GPIO_PDM_SEL_PDM (0x1 << 3)
1435
1436/* GPIO Control 2 (0xc1) */
1437#define RT5616_GP5_DR_MASK (0x1 << 14)
1438#define RT5616_GP5_DR_SFT 14
1439#define RT5616_GP5_DR_IN (0x0 << 14)
1440#define RT5616_GP5_DR_OUT (0x1 << 14)
1441#define RT5616_GP5_OUT_MASK (0x1 << 13)
1442#define RT5616_GP5_OUT_SFT 13
1443#define RT5616_GP5_OUT_LO (0x0 << 13)
1444#define RT5616_GP5_OUT_HI (0x1 << 13)
1445#define RT5616_GP5_P_MASK (0x1 << 12)
1446#define RT5616_GP5_P_SFT 12
1447#define RT5616_GP5_P_NOR (0x0 << 12)
1448#define RT5616_GP5_P_INV (0x1 << 12)
1449#define RT5616_GP4_DR_MASK (0x1 << 11)
1450#define RT5616_GP4_DR_SFT 11
1451#define RT5616_GP4_DR_IN (0x0 << 11)
1452#define RT5616_GP4_DR_OUT (0x1 << 11)
1453#define RT5616_GP4_OUT_MASK (0x1 << 10)
1454#define RT5616_GP4_OUT_SFT 10
1455#define RT5616_GP4_OUT_LO (0x0 << 10)
1456#define RT5616_GP4_OUT_HI (0x1 << 10)
1457#define RT5616_GP4_P_MASK (0x1 << 9)
1458#define RT5616_GP4_P_SFT 9
1459#define RT5616_GP4_P_NOR (0x0 << 9)
1460#define RT5616_GP4_P_INV (0x1 << 9)
1461#define RT5616_GP3_DR_MASK (0x1 << 8)
1462#define RT5616_GP3_DR_SFT 8
1463#define RT5616_GP3_DR_IN (0x0 << 8)
1464#define RT5616_GP3_DR_OUT (0x1 << 8)
1465#define RT5616_GP3_OUT_MASK (0x1 << 7)
1466#define RT5616_GP3_OUT_SFT 7
1467#define RT5616_GP3_OUT_LO (0x0 << 7)
1468#define RT5616_GP3_OUT_HI (0x1 << 7)
1469#define RT5616_GP3_P_MASK (0x1 << 6)
1470#define RT5616_GP3_P_SFT 6
1471#define RT5616_GP3_P_NOR (0x0 << 6)
1472#define RT5616_GP3_P_INV (0x1 << 6)
1473#define RT5616_GP2_DR_MASK (0x1 << 5)
1474#define RT5616_GP2_DR_SFT 5
1475#define RT5616_GP2_DR_IN (0x0 << 5)
1476#define RT5616_GP2_DR_OUT (0x1 << 5)
1477#define RT5616_GP2_OUT_MASK (0x1 << 4)
1478#define RT5616_GP2_OUT_SFT 4
1479#define RT5616_GP2_OUT_LO (0x0 << 4)
1480#define RT5616_GP2_OUT_HI (0x1 << 4)
1481#define RT5616_GP2_P_MASK (0x1 << 3)
1482#define RT5616_GP2_P_SFT 3
1483#define RT5616_GP2_P_NOR (0x0 << 3)
1484#define RT5616_GP2_P_INV (0x1 << 3)
1485#define RT5616_GP1_DR_MASK (0x1 << 2)
1486#define RT5616_GP1_DR_SFT 2
1487#define RT5616_GP1_DR_IN (0x0 << 2)
1488#define RT5616_GP1_DR_OUT (0x1 << 2)
1489#define RT5616_GP1_OUT_MASK (0x1 << 1)
1490#define RT5616_GP1_OUT_SFT 1
1491#define RT5616_GP1_OUT_LO (0x0 << 1)
1492#define RT5616_GP1_OUT_HI (0x1 << 1)
1493#define RT5616_GP1_P_MASK (0x1)
1494#define RT5616_GP1_P_SFT 0
1495#define RT5616_GP1_P_NOR (0x0)
1496#define RT5616_GP1_P_INV (0x1)
1497
1498/* GPIO Control 3 (0xc2) */
1499#define RT5616_GP8_DR_MASK (0x1 << 8)
1500#define RT5616_GP8_DR_SFT 8
1501#define RT5616_GP8_DR_IN (0x0 << 8)
1502#define RT5616_GP8_DR_OUT (0x1 << 8)
1503#define RT5616_GP8_OUT_MASK (0x1 << 7)
1504#define RT5616_GP8_OUT_SFT 7
1505#define RT5616_GP8_OUT_LO (0x0 << 7)
1506#define RT5616_GP8_OUT_HI (0x1 << 7)
1507#define RT5616_GP8_P_MASK (0x1 << 6)
1508#define RT5616_GP8_P_SFT 6
1509#define RT5616_GP8_P_NOR (0x0 << 6)
1510#define RT5616_GP8_P_INV (0x1 << 6)
1511#define RT5616_GP7_DR_MASK (0x1 << 5)
1512#define RT5616_GP7_DR_SFT 5
1513#define RT5616_GP7_DR_IN (0x0 << 5)
1514#define RT5616_GP7_DR_OUT (0x1 << 5)
1515#define RT5616_GP7_OUT_MASK (0x1 << 4)
1516#define RT5616_GP7_OUT_SFT 4
1517#define RT5616_GP7_OUT_LO (0x0 << 4)
1518#define RT5616_GP7_OUT_HI (0x1 << 4)
1519#define RT5616_GP7_P_MASK (0x1 << 3)
1520#define RT5616_GP7_P_SFT 3
1521#define RT5616_GP7_P_NOR (0x0 << 3)
1522#define RT5616_GP7_P_INV (0x1 << 3)
1523#define RT5616_GP6_DR_MASK (0x1 << 2)
1524#define RT5616_GP6_DR_SFT 2
1525#define RT5616_GP6_DR_IN (0x0 << 2)
1526#define RT5616_GP6_DR_OUT (0x1 << 2)
1527#define RT5616_GP6_OUT_MASK (0x1 << 1)
1528#define RT5616_GP6_OUT_SFT 1
1529#define RT5616_GP6_OUT_LO (0x0 << 1)
1530#define RT5616_GP6_OUT_HI (0x1 << 1)
1531#define RT5616_GP6_P_MASK (0x1)
1532#define RT5616_GP6_P_SFT 0
1533#define RT5616_GP6_P_NOR (0x0)
1534#define RT5616_GP6_P_INV (0x1)
1535
1536/* Scramble Control (0xce) */
1537#define RT5616_SCB_SWAP_MASK (0x1 << 15)
1538#define RT5616_SCB_SWAP_SFT 15
1539#define RT5616_SCB_SWAP_DIS (0x0 << 15)
1540#define RT5616_SCB_SWAP_EN (0x1 << 15)
1541#define RT5616_SCB_MASK (0x1 << 14)
1542#define RT5616_SCB_SFT 14
1543#define RT5616_SCB_DIS (0x0 << 14)
1544#define RT5616_SCB_EN (0x1 << 14)
1545
1546/* Baseback Control (0xcf) */
1547#define RT5616_BB_MASK (0x1 << 15)
1548#define RT5616_BB_SFT 15
1549#define RT5616_BB_DIS (0x0 << 15)
1550#define RT5616_BB_EN (0x1 << 15)
1551#define RT5616_BB_CT_MASK (0x7 << 12)
1552#define RT5616_BB_CT_SFT 12
1553#define RT5616_BB_CT_A (0x0 << 12)
1554#define RT5616_BB_CT_B (0x1 << 12)
1555#define RT5616_BB_CT_C (0x2 << 12)
1556#define RT5616_BB_CT_D (0x3 << 12)
1557#define RT5616_M_BB_L_MASK (0x1 << 9)
1558#define RT5616_M_BB_L_SFT 9
1559#define RT5616_M_BB_R_MASK (0x1 << 8)
1560#define RT5616_M_BB_R_SFT 8
1561#define RT5616_M_BB_HPF_L_MASK (0x1 << 7)
1562#define RT5616_M_BB_HPF_L_SFT 7
1563#define RT5616_M_BB_HPF_R_MASK (0x1 << 6)
1564#define RT5616_M_BB_HPF_R_SFT 6
1565#define RT5616_G_BB_BST_MASK (0x3f)
1566#define RT5616_G_BB_BST_SFT 0
1567
1568/* MP3 Plus Control 1 (0xd0) */
1569#define RT5616_M_MP3_L_MASK (0x1 << 15)
1570#define RT5616_M_MP3_L_SFT 15
1571#define RT5616_M_MP3_R_MASK (0x1 << 14)
1572#define RT5616_M_MP3_R_SFT 14
1573#define RT5616_M_MP3_MASK (0x1 << 13)
1574#define RT5616_M_MP3_SFT 13
1575#define RT5616_M_MP3_DIS (0x0 << 13)
1576#define RT5616_M_MP3_EN (0x1 << 13)
1577#define RT5616_EG_MP3_MASK (0x1f << 8)
1578#define RT5616_EG_MP3_SFT 8
1579#define RT5616_MP3_HLP_MASK (0x1 << 7)
1580#define RT5616_MP3_HLP_SFT 7
1581#define RT5616_MP3_HLP_DIS (0x0 << 7)
1582#define RT5616_MP3_HLP_EN (0x1 << 7)
1583#define RT5616_M_MP3_ORG_L_MASK (0x1 << 6)
1584#define RT5616_M_MP3_ORG_L_SFT 6
1585#define RT5616_M_MP3_ORG_R_MASK (0x1 << 5)
1586#define RT5616_M_MP3_ORG_R_SFT 5
1587
1588/* MP3 Plus Control 2 (0xd1) */
1589#define RT5616_MP3_WT_MASK (0x1 << 13)
1590#define RT5616_MP3_WT_SFT 13
1591#define RT5616_MP3_WT_1_4 (0x0 << 13)
1592#define RT5616_MP3_WT_1_2 (0x1 << 13)
1593#define RT5616_OG_MP3_MASK (0x1f << 8)
1594#define RT5616_OG_MP3_SFT 8
1595#define RT5616_HG_MP3_MASK (0x3f)
1596#define RT5616_HG_MP3_SFT 0
1597
1598/* 3D HP Control 1 (0xd2) */
1599#define RT5616_3D_CF_MASK (0x1 << 15)
1600#define RT5616_3D_CF_SFT 15
1601#define RT5616_3D_CF_DIS (0x0 << 15)
1602#define RT5616_3D_CF_EN (0x1 << 15)
1603#define RT5616_3D_HP_MASK (0x1 << 14)
1604#define RT5616_3D_HP_SFT 14
1605#define RT5616_3D_HP_DIS (0x0 << 14)
1606#define RT5616_3D_HP_EN (0x1 << 14)
1607#define RT5616_3D_BT_MASK (0x1 << 13)
1608#define RT5616_3D_BT_SFT 13
1609#define RT5616_3D_BT_DIS (0x0 << 13)
1610#define RT5616_3D_BT_EN (0x1 << 13)
1611#define RT5616_3D_1F_MIX_MASK (0x3 << 11)
1612#define RT5616_3D_1F_MIX_SFT 11
1613#define RT5616_3D_HP_M_MASK (0x1 << 10)
1614#define RT5616_3D_HP_M_SFT 10
1615#define RT5616_3D_HP_M_SUR (0x0 << 10)
1616#define RT5616_3D_HP_M_FRO (0x1 << 10)
1617#define RT5616_M_3D_HRTF_MASK (0x1 << 9)
1618#define RT5616_M_3D_HRTF_SFT 9
1619#define RT5616_M_3D_D2H_MASK (0x1 << 8)
1620#define RT5616_M_3D_D2H_SFT 8
1621#define RT5616_M_3D_D2R_MASK (0x1 << 7)
1622#define RT5616_M_3D_D2R_SFT 7
1623#define RT5616_M_3D_REVB_MASK (0x1 << 6)
1624#define RT5616_M_3D_REVB_SFT 6
1625
1626/* Adjustable high pass filter control 1 (0xd3) */
1627#define RT5616_2ND_HPF_MASK (0x1 << 15)
1628#define RT5616_2ND_HPF_SFT 15
1629#define RT5616_2ND_HPF_DIS (0x0 << 15)
1630#define RT5616_2ND_HPF_EN (0x1 << 15)
1631#define RT5616_HPF_CF_L_MASK (0x7 << 12)
1632#define RT5616_HPF_CF_L_SFT 12
1633#define RT5616_HPF_CF_R_MASK (0x7 << 8)
1634#define RT5616_HPF_CF_R_SFT 8
1635#define RT5616_ZD_T_MASK (0x3 << 6)
1636#define RT5616_ZD_T_SFT 6
1637#define RT5616_ZD_F_MASK (0x3 << 4)
1638#define RT5616_ZD_F_SFT 4
1639#define RT5616_ZD_F_IM (0x0 << 4)
1640#define RT5616_ZD_F_ZC_IM (0x1 << 4)
1641#define RT5616_ZD_F_ZC_IOD (0x2 << 4)
1642#define RT5616_ZD_F_UN (0x3 << 4)
1643
1644/* Adjustable high pass filter control 2 (0xd4) */
1645#define RT5616_HPF_CF_L_NUM_MASK (0x3f << 8)
1646#define RT5616_HPF_CF_L_NUM_SFT 8
1647#define RT5616_HPF_CF_R_NUM_MASK (0x3f)
1648#define RT5616_HPF_CF_R_NUM_SFT 0
1649
1650/* HP calibration control and Amp detection (0xd6) */
1651#define RT5616_SI_DAC_MASK (0x1 << 11)
1652#define RT5616_SI_DAC_SFT 11
1653#define RT5616_SI_DAC_AUTO (0x0 << 11)
1654#define RT5616_SI_DAC_TEST (0x1 << 11)
1655#define RT5616_DC_CAL_M_MASK (0x1 << 10)
1656#define RT5616_DC_CAL_M_SFT 10
1657#define RT5616_DC_CAL_M_NOR (0x0 << 10)
1658#define RT5616_DC_CAL_M_CAL (0x1 << 10)
1659#define RT5616_DC_CAL_MASK (0x1 << 9)
1660#define RT5616_DC_CAL_SFT 9
1661#define RT5616_DC_CAL_DIS (0x0 << 9)
1662#define RT5616_DC_CAL_EN (0x1 << 9)
1663#define RT5616_HPD_RCV_MASK (0x7 << 6)
1664#define RT5616_HPD_RCV_SFT 6
1665#define RT5616_HPD_PS_MASK (0x1 << 5)
1666#define RT5616_HPD_PS_SFT 5
1667#define RT5616_HPD_PS_DIS (0x0 << 5)
1668#define RT5616_HPD_PS_EN (0x1 << 5)
1669#define RT5616_CAL_M_MASK (0x1 << 4)
1670#define RT5616_CAL_M_SFT 4
1671#define RT5616_CAL_M_DEP (0x0 << 4)
1672#define RT5616_CAL_M_CAL (0x1 << 4)
1673#define RT5616_CAL_MASK (0x1 << 3)
1674#define RT5616_CAL_SFT 3
1675#define RT5616_CAL_DIS (0x0 << 3)
1676#define RT5616_CAL_EN (0x1 << 3)
1677#define RT5616_CAL_TEST_MASK (0x1 << 2)
1678#define RT5616_CAL_TEST_SFT 2
1679#define RT5616_CAL_TEST_DIS (0x0 << 2)
1680#define RT5616_CAL_TEST_EN (0x1 << 2)
1681#define RT5616_CAL_P_MASK (0x3)
1682#define RT5616_CAL_P_SFT 0
1683#define RT5616_CAL_P_NONE (0x0)
1684#define RT5616_CAL_P_CAL (0x1)
1685#define RT5616_CAL_P_DAC_CAL (0x2)
1686
1687/* Soft volume and zero cross control 1 (0xd9) */
1688#define RT5616_SV_MASK (0x1 << 15)
1689#define RT5616_SV_SFT 15
1690#define RT5616_SV_DIS (0x0 << 15)
1691#define RT5616_SV_EN (0x1 << 15)
1692#define RT5616_OUT_SV_MASK (0x1 << 13)
1693#define RT5616_OUT_SV_SFT 13
1694#define RT5616_OUT_SV_DIS (0x0 << 13)
1695#define RT5616_OUT_SV_EN (0x1 << 13)
1696#define RT5616_HP_SV_MASK (0x1 << 12)
1697#define RT5616_HP_SV_SFT 12
1698#define RT5616_HP_SV_DIS (0x0 << 12)
1699#define RT5616_HP_SV_EN (0x1 << 12)
1700#define RT5616_ZCD_DIG_MASK (0x1 << 11)
1701#define RT5616_ZCD_DIG_SFT 11
1702#define RT5616_ZCD_DIG_DIS (0x0 << 11)
1703#define RT5616_ZCD_DIG_EN (0x1 << 11)
1704#define RT5616_ZCD_MASK (0x1 << 10)
1705#define RT5616_ZCD_SFT 10
1706#define RT5616_ZCD_PD (0x0 << 10)
1707#define RT5616_ZCD_PU (0x1 << 10)
1708#define RT5616_M_ZCD_MASK (0x3f << 4)
1709#define RT5616_M_ZCD_SFT 4
1710#define RT5616_M_ZCD_OM_L (0x1 << 7)
1711#define RT5616_M_ZCD_OM_R (0x1 << 6)
1712#define RT5616_M_ZCD_RM_L (0x1 << 5)
1713#define RT5616_M_ZCD_RM_R (0x1 << 4)
1714#define RT5616_SV_DLY_MASK (0xf)
1715#define RT5616_SV_DLY_SFT 0
1716
1717/* Soft volume and zero cross control 2 (0xda) */
1718#define RT5616_ZCD_HP_MASK (0x1 << 15)
1719#define RT5616_ZCD_HP_SFT 15
1720#define RT5616_ZCD_HP_DIS (0x0 << 15)
1721#define RT5616_ZCD_HP_EN (0x1 << 15)
1722
1723/* Digital Misc Control (0xfa) */
1724#define RT5616_I2S2_MS_SP_MASK (0x1 << 8)
1725#define RT5616_I2S2_MS_SP_SEL 8
1726#define RT5616_I2S2_MS_SP_64 (0x0 << 8)
1727#define RT5616_I2S2_MS_SP_50 (0x1 << 8)
1728#define RT5616_CLK_DET_EN (0x1 << 3)
1729#define RT5616_CLK_DET_EN_SFT 3
1730#define RT5616_AMP_DET_EN (0x1 << 1)
1731#define RT5616_AMP_DET_EN_SFT 1
1732#define RT5616_D_GATE_EN (0x1)
1733#define RT5616_D_GATE_EN_SFT 0
1734
1735/* Codec Private Register definition */
1736/* 3D Speaker Control (0x63) */
1737#define RT5616_3D_SPK_MASK (0x1 << 15)
1738#define RT5616_3D_SPK_SFT 15
1739#define RT5616_3D_SPK_DIS (0x0 << 15)
1740#define RT5616_3D_SPK_EN (0x1 << 15)
1741#define RT5616_3D_SPK_M_MASK (0x3 << 13)
1742#define RT5616_3D_SPK_M_SFT 13
1743#define RT5616_3D_SPK_CG_MASK (0x1f << 8)
1744#define RT5616_3D_SPK_CG_SFT 8
1745#define RT5616_3D_SPK_SG_MASK (0x1f)
1746#define RT5616_3D_SPK_SG_SFT 0
1747
1748/* Wind Noise Detection Control 1 (0x6c) */
1749#define RT5616_WND_MASK (0x1 << 15)
1750#define RT5616_WND_SFT 15
1751#define RT5616_WND_DIS (0x0 << 15)
1752#define RT5616_WND_EN (0x1 << 15)
1753
1754/* Wind Noise Detection Control 2 (0x6d) */
1755#define RT5616_WND_FC_NW_MASK (0x3f << 10)
1756#define RT5616_WND_FC_NW_SFT 10
1757#define RT5616_WND_FC_WK_MASK (0x3f << 4)
1758#define RT5616_WND_FC_WK_SFT 4
1759
1760/* Wind Noise Detection Control 3 (0x6e) */
1761#define RT5616_HPF_FC_MASK (0x3f << 6)
1762#define RT5616_HPF_FC_SFT 6
1763#define RT5616_WND_FC_ST_MASK (0x3f)
1764#define RT5616_WND_FC_ST_SFT 0
1765
1766/* Wind Noise Detection Control 4 (0x6f) */
1767#define RT5616_WND_TH_LO_MASK (0x3ff)
1768#define RT5616_WND_TH_LO_SFT 0
1769
1770/* Wind Noise Detection Control 5 (0x70) */
1771#define RT5616_WND_TH_HI_MASK (0x3ff)
1772#define RT5616_WND_TH_HI_SFT 0
1773
1774/* Wind Noise Detection Control 8 (0x73) */
1775#define RT5616_WND_WIND_MASK (0x1 << 13) /* Read-Only */
1776#define RT5616_WND_WIND_SFT 13
1777#define RT5616_WND_STRONG_MASK (0x1 << 12) /* Read-Only */
1778#define RT5616_WND_STRONG_SFT 12
1779enum {
1780 RT5616_NO_WIND,
1781 RT5616_BREEZE,
1782 RT5616_STORM,
1783};
1784
1785/* Dipole Speaker Interface (0x75) */
1786#define RT5616_DP_ATT_MASK (0x3 << 14)
1787#define RT5616_DP_ATT_SFT 14
1788#define RT5616_DP_SPK_MASK (0x1 << 10)
1789#define RT5616_DP_SPK_SFT 10
1790#define RT5616_DP_SPK_DIS (0x0 << 10)
1791#define RT5616_DP_SPK_EN (0x1 << 10)
1792
1793/* EQ Pre Volume Control (0xb3) */
1794#define RT5616_EQ_PRE_VOL_MASK (0xffff)
1795#define RT5616_EQ_PRE_VOL_SFT 0
1796
1797/* EQ Post Volume Control (0xb4) */
1798#define RT5616_EQ_PST_VOL_MASK (0xffff)
1799#define RT5616_EQ_PST_VOL_SFT 0
1800
1801/* System Clock Source */
1802enum {
1803 RT5616_SCLK_S_MCLK,
1804 RT5616_SCLK_S_PLL1,
1805};
1806
1807/* PLL1 Source */
1808enum {
1809 RT5616_PLL1_S_MCLK,
1810 RT5616_PLL1_S_BCLK1,
1811 RT5616_PLL1_S_BCLK2,
1812};
1813
1814enum {
1815 RT5616_AIF1,
1816 RT5616_AIFS,
1817};
1818
1819#endif /* __RT5616_H__ */
diff --git a/sound/soc/codecs/rt5640.c b/sound/soc/codecs/rt5640.c
index f2beb1aa5763..11d032cdc658 100644
--- a/sound/soc/codecs/rt5640.c
+++ b/sound/soc/codecs/rt5640.c
@@ -488,6 +488,18 @@ static int is_sys_clk_from_pll(struct snd_soc_dapm_widget *source,
488 return 0; 488 return 0;
489} 489}
490 490
491static int is_using_asrc(struct snd_soc_dapm_widget *source,
492 struct snd_soc_dapm_widget *sink)
493{
494 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(source->dapm);
495 struct rt5640_priv *rt5640 = snd_soc_codec_get_drvdata(codec);
496
497 if (!rt5640->asrc_en)
498 return 0;
499
500 return 1;
501}
502
491/* Digital Mixer */ 503/* Digital Mixer */
492static const struct snd_kcontrol_new rt5640_sto_adc_l_mix[] = { 504static const struct snd_kcontrol_new rt5640_sto_adc_l_mix[] = {
493 SOC_DAPM_SINGLE("ADC1 Switch", RT5640_STO_ADC_MIXER, 505 SOC_DAPM_SINGLE("ADC1 Switch", RT5640_STO_ADC_MIXER,
@@ -1059,6 +1071,20 @@ static int rt5640_hp_post_event(struct snd_soc_dapm_widget *w,
1059static const struct snd_soc_dapm_widget rt5640_dapm_widgets[] = { 1071static const struct snd_soc_dapm_widget rt5640_dapm_widgets[] = {
1060 SND_SOC_DAPM_SUPPLY("PLL1", RT5640_PWR_ANLG2, 1072 SND_SOC_DAPM_SUPPLY("PLL1", RT5640_PWR_ANLG2,
1061 RT5640_PWR_PLL_BIT, 0, NULL, 0), 1073 RT5640_PWR_PLL_BIT, 0, NULL, 0),
1074
1075 /* ASRC */
1076 SND_SOC_DAPM_SUPPLY_S("Stereo Filter ASRC", 1, RT5640_ASRC_1,
1077 15, 0, NULL, 0),
1078 SND_SOC_DAPM_SUPPLY_S("I2S2 Filter ASRC", 1, RT5640_ASRC_1,
1079 12, 0, NULL, 0),
1080 SND_SOC_DAPM_SUPPLY_S("I2S2 ASRC", 1, RT5640_ASRC_1,
1081 11, 0, NULL, 0),
1082 SND_SOC_DAPM_SUPPLY_S("DMIC1 ASRC", 1, RT5640_ASRC_1,
1083 9, 0, NULL, 0),
1084 SND_SOC_DAPM_SUPPLY_S("DMIC2 ASRC", 1, RT5640_ASRC_1,
1085 8, 0, NULL, 0),
1086
1087
1062 /* Input Side */ 1088 /* Input Side */
1063 /* micbias */ 1089 /* micbias */
1064 SND_SOC_DAPM_SUPPLY("LDO2", RT5640_PWR_ANLG1, 1090 SND_SOC_DAPM_SUPPLY("LDO2", RT5640_PWR_ANLG1,
@@ -1319,6 +1345,12 @@ static const struct snd_soc_dapm_widget rt5639_specific_dapm_widgets[] = {
1319}; 1345};
1320 1346
1321static const struct snd_soc_dapm_route rt5640_dapm_routes[] = { 1347static const struct snd_soc_dapm_route rt5640_dapm_routes[] = {
1348 { "I2S1", NULL, "Stereo Filter ASRC", is_using_asrc },
1349 { "I2S2", NULL, "I2S2 ASRC", is_using_asrc },
1350 { "I2S2", NULL, "I2S2 Filter ASRC", is_using_asrc },
1351 { "DMIC1", NULL, "DMIC1 ASRC", is_using_asrc },
1352 { "DMIC2", NULL, "DMIC2 ASRC", is_using_asrc },
1353
1322 {"IN1P", NULL, "LDO2"}, 1354 {"IN1P", NULL, "LDO2"},
1323 {"IN2P", NULL, "LDO2"}, 1355 {"IN2P", NULL, "LDO2"},
1324 {"IN3P", NULL, "LDO2"}, 1356 {"IN3P", NULL, "LDO2"},
@@ -1981,6 +2013,76 @@ int rt5640_dmic_enable(struct snd_soc_codec *codec,
1981} 2013}
1982EXPORT_SYMBOL_GPL(rt5640_dmic_enable); 2014EXPORT_SYMBOL_GPL(rt5640_dmic_enable);
1983 2015
2016int rt5640_sel_asrc_clk_src(struct snd_soc_codec *codec,
2017 unsigned int filter_mask, unsigned int clk_src)
2018{
2019 struct rt5640_priv *rt5640 = snd_soc_codec_get_drvdata(codec);
2020 unsigned int asrc2_mask = 0;
2021 unsigned int asrc2_value = 0;
2022
2023 switch (clk_src) {
2024 case RT5640_CLK_SEL_SYS:
2025 case RT5640_CLK_SEL_ASRC:
2026 break;
2027
2028 default:
2029 return -EINVAL;
2030 }
2031
2032 if (!filter_mask)
2033 return -EINVAL;
2034
2035 if (filter_mask & RT5640_DA_STEREO_FILTER) {
2036 asrc2_mask |= RT5640_STO_DAC_M_MASK;
2037 asrc2_value = (asrc2_value & ~RT5640_STO_DAC_M_MASK)
2038 | (clk_src << RT5640_STO_DAC_M_SFT);
2039 }
2040
2041 if (filter_mask & RT5640_DA_MONO_L_FILTER) {
2042 asrc2_mask |= RT5640_MDA_L_M_MASK;
2043 asrc2_value = (asrc2_value & ~RT5640_MDA_L_M_MASK)
2044 | (clk_src << RT5640_MDA_L_M_SFT);
2045 }
2046
2047 if (filter_mask & RT5640_DA_MONO_R_FILTER) {
2048 asrc2_mask |= RT5640_MDA_R_M_MASK;
2049 asrc2_value = (asrc2_value & ~RT5640_MDA_R_M_MASK)
2050 | (clk_src << RT5640_MDA_R_M_SFT);
2051 }
2052
2053 if (filter_mask & RT5640_AD_STEREO_FILTER) {
2054 asrc2_mask |= RT5640_ADC_M_MASK;
2055 asrc2_value = (asrc2_value & ~RT5640_ADC_M_MASK)
2056 | (clk_src << RT5640_ADC_M_SFT);
2057 }
2058
2059 if (filter_mask & RT5640_AD_MONO_L_FILTER) {
2060 asrc2_mask |= RT5640_MAD_L_M_MASK;
2061 asrc2_value = (asrc2_value & ~RT5640_MAD_L_M_MASK)
2062 | (clk_src << RT5640_MAD_L_M_SFT);
2063 }
2064
2065 if (filter_mask & RT5640_AD_MONO_R_FILTER) {
2066 asrc2_mask |= RT5640_MAD_R_M_MASK;
2067 asrc2_value = (asrc2_value & ~RT5640_MAD_R_M_MASK)
2068 | (clk_src << RT5640_MAD_R_M_SFT);
2069 }
2070
2071 snd_soc_update_bits(codec, RT5640_ASRC_2,
2072 asrc2_mask, asrc2_value);
2073
2074 if (snd_soc_read(codec, RT5640_ASRC_2)) {
2075 rt5640->asrc_en = true;
2076 snd_soc_update_bits(codec, RT5640_JD_CTRL, 0x3, 0x3);
2077 } else {
2078 rt5640->asrc_en = false;
2079 snd_soc_update_bits(codec, RT5640_JD_CTRL, 0x3, 0x0);
2080 }
2081
2082 return 0;
2083}
2084EXPORT_SYMBOL_GPL(rt5640_sel_asrc_clk_src);
2085
1984static int rt5640_probe(struct snd_soc_codec *codec) 2086static int rt5640_probe(struct snd_soc_codec *codec)
1985{ 2087{
1986 struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec); 2088 struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
@@ -2175,6 +2277,7 @@ static const struct acpi_device_id rt5640_acpi_match[] = {
2175 { "INT33CA", 0 }, 2277 { "INT33CA", 0 },
2176 { "10EC5640", 0 }, 2278 { "10EC5640", 0 },
2177 { "10EC5642", 0 }, 2279 { "10EC5642", 0 },
2280 { "INTCCFFD", 0 },
2178 { }, 2281 { },
2179}; 2282};
2180MODULE_DEVICE_TABLE(acpi, rt5640_acpi_match); 2283MODULE_DEVICE_TABLE(acpi, rt5640_acpi_match);
diff --git a/sound/soc/codecs/rt5640.h b/sound/soc/codecs/rt5640.h
index 3deb8babeabb..83a7150ddc24 100644
--- a/sound/soc/codecs/rt5640.h
+++ b/sound/soc/codecs/rt5640.h
@@ -1033,6 +1033,10 @@
1033#define RT5640_DMIC_2_M_NOR (0x0 << 8) 1033#define RT5640_DMIC_2_M_NOR (0x0 << 8)
1034#define RT5640_DMIC_2_M_ASYN (0x1 << 8) 1034#define RT5640_DMIC_2_M_ASYN (0x1 << 8)
1035 1035
1036/* ASRC clock source selection (0x84) */
1037#define RT5640_CLK_SEL_SYS (0x0)
1038#define RT5640_CLK_SEL_ASRC (0x1)
1039
1036/* ASRC Control 2 (0x84) */ 1040/* ASRC Control 2 (0x84) */
1037#define RT5640_MDA_L_M_MASK (0x1 << 15) 1041#define RT5640_MDA_L_M_MASK (0x1 << 15)
1038#define RT5640_MDA_L_M_SFT 15 1042#define RT5640_MDA_L_M_SFT 15
@@ -2079,6 +2083,16 @@ enum {
2079 RT5640_DMIC2, 2083 RT5640_DMIC2,
2080}; 2084};
2081 2085
2086/* filter mask */
2087enum {
2088 RT5640_DA_STEREO_FILTER = 0x1,
2089 RT5640_DA_MONO_L_FILTER = (0x1 << 1),
2090 RT5640_DA_MONO_R_FILTER = (0x1 << 2),
2091 RT5640_AD_STEREO_FILTER = (0x1 << 3),
2092 RT5640_AD_MONO_L_FILTER = (0x1 << 4),
2093 RT5640_AD_MONO_R_FILTER = (0x1 << 5),
2094};
2095
2082struct rt5640_priv { 2096struct rt5640_priv {
2083 struct snd_soc_codec *codec; 2097 struct snd_soc_codec *codec;
2084 struct rt5640_platform_data pdata; 2098 struct rt5640_platform_data pdata;
@@ -2095,9 +2109,12 @@ struct rt5640_priv {
2095 int pll_out; 2109 int pll_out;
2096 2110
2097 bool hp_mute; 2111 bool hp_mute;
2112 bool asrc_en;
2098}; 2113};
2099 2114
2100int rt5640_dmic_enable(struct snd_soc_codec *codec, 2115int rt5640_dmic_enable(struct snd_soc_codec *codec,
2101 bool dmic1_data_pin, bool dmic2_data_pin); 2116 bool dmic1_data_pin, bool dmic2_data_pin);
2117int rt5640_sel_asrc_clk_src(struct snd_soc_codec *codec,
2118 unsigned int filter_mask, unsigned int clk_src);
2102 2119
2103#endif 2120#endif
diff --git a/sound/soc/codecs/rt5645.c b/sound/soc/codecs/rt5645.c
index 3e3c7f6be29d..c61d38b585fb 100644
--- a/sound/soc/codecs/rt5645.c
+++ b/sound/soc/codecs/rt5645.c
@@ -64,7 +64,6 @@ static const struct reg_sequence init_list[] = {
64 {RT5645_PR_BASE + 0x21, 0x4040}, 64 {RT5645_PR_BASE + 0x21, 0x4040},
65 {RT5645_PR_BASE + 0x23, 0x0004}, 65 {RT5645_PR_BASE + 0x23, 0x0004},
66}; 66};
67#define RT5645_INIT_REG_LEN ARRAY_SIZE(init_list)
68 67
69static const struct reg_sequence rt5650_init_list[] = { 68static const struct reg_sequence rt5650_init_list[] = {
70 {0xf6, 0x0100}, 69 {0xf6, 0x0100},
@@ -226,6 +225,163 @@ static const struct reg_default rt5645_reg[] = {
226 { 0xff, 0x6308 }, 225 { 0xff, 0x6308 },
227}; 226};
228 227
228static const struct reg_default rt5650_reg[] = {
229 { 0x00, 0x0000 },
230 { 0x01, 0xc8c8 },
231 { 0x02, 0xc8c8 },
232 { 0x03, 0xc8c8 },
233 { 0x0a, 0x0002 },
234 { 0x0b, 0x2827 },
235 { 0x0c, 0xe000 },
236 { 0x0d, 0x0000 },
237 { 0x0e, 0x0000 },
238 { 0x0f, 0x0808 },
239 { 0x14, 0x3333 },
240 { 0x16, 0x4b00 },
241 { 0x18, 0x018b },
242 { 0x19, 0xafaf },
243 { 0x1a, 0xafaf },
244 { 0x1b, 0x0001 },
245 { 0x1c, 0x2f2f },
246 { 0x1d, 0x2f2f },
247 { 0x1e, 0x0000 },
248 { 0x20, 0x0000 },
249 { 0x27, 0x7060 },
250 { 0x28, 0x7070 },
251 { 0x29, 0x8080 },
252 { 0x2a, 0x5656 },
253 { 0x2b, 0x5454 },
254 { 0x2c, 0xaaa0 },
255 { 0x2d, 0x0000 },
256 { 0x2f, 0x1002 },
257 { 0x31, 0x5000 },
258 { 0x32, 0x0000 },
259 { 0x33, 0x0000 },
260 { 0x34, 0x0000 },
261 { 0x35, 0x0000 },
262 { 0x3b, 0x0000 },
263 { 0x3c, 0x007f },
264 { 0x3d, 0x0000 },
265 { 0x3e, 0x007f },
266 { 0x3f, 0x0000 },
267 { 0x40, 0x001f },
268 { 0x41, 0x0000 },
269 { 0x42, 0x001f },
270 { 0x45, 0x6000 },
271 { 0x46, 0x003e },
272 { 0x47, 0x003e },
273 { 0x48, 0xf807 },
274 { 0x4a, 0x0004 },
275 { 0x4d, 0x0000 },
276 { 0x4e, 0x0000 },
277 { 0x4f, 0x01ff },
278 { 0x50, 0x0000 },
279 { 0x51, 0x0000 },
280 { 0x52, 0x01ff },
281 { 0x53, 0xf000 },
282 { 0x56, 0x0111 },
283 { 0x57, 0x0064 },
284 { 0x58, 0xef0e },
285 { 0x59, 0xf0f0 },
286 { 0x5a, 0xef0e },
287 { 0x5b, 0xf0f0 },
288 { 0x5c, 0xef0e },
289 { 0x5d, 0xf0f0 },
290 { 0x5e, 0xf000 },
291 { 0x5f, 0x0000 },
292 { 0x61, 0x0300 },
293 { 0x62, 0x0000 },
294 { 0x63, 0x00c2 },
295 { 0x64, 0x0000 },
296 { 0x65, 0x0000 },
297 { 0x66, 0x0000 },
298 { 0x6a, 0x0000 },
299 { 0x6c, 0x0aaa },
300 { 0x70, 0x8000 },
301 { 0x71, 0x8000 },
302 { 0x72, 0x8000 },
303 { 0x73, 0x7770 },
304 { 0x74, 0x3e00 },
305 { 0x75, 0x2409 },
306 { 0x76, 0x000a },
307 { 0x77, 0x0c00 },
308 { 0x78, 0x0000 },
309 { 0x79, 0x0123 },
310 { 0x7a, 0x0123 },
311 { 0x80, 0x0000 },
312 { 0x81, 0x0000 },
313 { 0x82, 0x0000 },
314 { 0x83, 0x0000 },
315 { 0x84, 0x0000 },
316 { 0x85, 0x0000 },
317 { 0x8a, 0x0000 },
318 { 0x8e, 0x0004 },
319 { 0x8f, 0x1100 },
320 { 0x90, 0x0646 },
321 { 0x91, 0x0c06 },
322 { 0x93, 0x0000 },
323 { 0x94, 0x0200 },
324 { 0x95, 0x0000 },
325 { 0x9a, 0x2184 },
326 { 0x9b, 0x010a },
327 { 0x9c, 0x0aea },
328 { 0x9d, 0x000c },
329 { 0x9e, 0x0400 },
330 { 0xa0, 0xa0a8 },
331 { 0xa1, 0x0059 },
332 { 0xa2, 0x0001 },
333 { 0xae, 0x6000 },
334 { 0xaf, 0x0000 },
335 { 0xb0, 0x6000 },
336 { 0xb1, 0x0000 },
337 { 0xb2, 0x0000 },
338 { 0xb3, 0x001f },
339 { 0xb4, 0x020c },
340 { 0xb5, 0x1f00 },
341 { 0xb6, 0x0000 },
342 { 0xbb, 0x0000 },
343 { 0xbc, 0x0000 },
344 { 0xbd, 0x0000 },
345 { 0xbe, 0x0000 },
346 { 0xbf, 0x3100 },
347 { 0xc0, 0x0000 },
348 { 0xc1, 0x0000 },
349 { 0xc2, 0x0000 },
350 { 0xc3, 0x2000 },
351 { 0xcd, 0x0000 },
352 { 0xce, 0x0000 },
353 { 0xcf, 0x1813 },
354 { 0xd0, 0x0690 },
355 { 0xd1, 0x1c17 },
356 { 0xd3, 0xb320 },
357 { 0xd4, 0x0000 },
358 { 0xd6, 0x0400 },
359 { 0xd9, 0x0809 },
360 { 0xda, 0x0000 },
361 { 0xdb, 0x0003 },
362 { 0xdc, 0x0049 },
363 { 0xdd, 0x001b },
364 { 0xdf, 0x0008 },
365 { 0xe0, 0x4000 },
366 { 0xe6, 0x8000 },
367 { 0xe7, 0x0200 },
368 { 0xec, 0xb300 },
369 { 0xed, 0x0000 },
370 { 0xf0, 0x001f },
371 { 0xf1, 0x020c },
372 { 0xf2, 0x1f00 },
373 { 0xf3, 0x0000 },
374 { 0xf4, 0x4000 },
375 { 0xf8, 0x0000 },
376 { 0xf9, 0x0000 },
377 { 0xfa, 0x2060 },
378 { 0xfb, 0x4040 },
379 { 0xfc, 0x0000 },
380 { 0xfd, 0x0002 },
381 { 0xfe, 0x10ec },
382 { 0xff, 0x6308 },
383};
384
229struct rt5645_eq_param_s { 385struct rt5645_eq_param_s {
230 unsigned short reg; 386 unsigned short reg;
231 unsigned short val; 387 unsigned short val;
@@ -248,6 +404,7 @@ struct rt5645_priv {
248 struct delayed_work jack_detect_work, rcclock_work; 404 struct delayed_work jack_detect_work, rcclock_work;
249 struct regulator_bulk_data supplies[ARRAY_SIZE(rt5645_supply_names)]; 405 struct regulator_bulk_data supplies[ARRAY_SIZE(rt5645_supply_names)];
250 struct rt5645_eq_param_s *eq_param; 406 struct rt5645_eq_param_s *eq_param;
407 struct timer_list btn_check_timer;
251 408
252 int codec_type; 409 int codec_type;
253 int sysclk; 410 int sysclk;
@@ -572,14 +729,12 @@ static int rt5645_spk_put_volsw(struct snd_kcontrol *kcontrol,
572 struct rt5645_priv *rt5645 = snd_soc_component_get_drvdata(component); 729 struct rt5645_priv *rt5645 = snd_soc_component_get_drvdata(component);
573 int ret; 730 int ret;
574 731
575 cancel_delayed_work_sync(&rt5645->rcclock_work);
576
577 regmap_update_bits(rt5645->regmap, RT5645_MICBIAS, 732 regmap_update_bits(rt5645->regmap, RT5645_MICBIAS,
578 RT5645_PWR_CLK25M_MASK, RT5645_PWR_CLK25M_PU); 733 RT5645_PWR_CLK25M_MASK, RT5645_PWR_CLK25M_PU);
579 734
580 ret = snd_soc_put_volsw(kcontrol, ucontrol); 735 ret = snd_soc_put_volsw(kcontrol, ucontrol);
581 736
582 queue_delayed_work(system_power_efficient_wq, &rt5645->rcclock_work, 737 mod_delayed_work(system_power_efficient_wq, &rt5645->rcclock_work,
583 msecs_to_jiffies(200)); 738 msecs_to_jiffies(200));
584 739
585 return ret; 740 return ret;
@@ -2911,6 +3066,7 @@ static void rt5645_enable_push_button_irq(struct snd_soc_codec *codec,
2911 snd_soc_dapm_force_enable_pin(dapm, "ADC R power"); 3066 snd_soc_dapm_force_enable_pin(dapm, "ADC R power");
2912 snd_soc_dapm_sync(dapm); 3067 snd_soc_dapm_sync(dapm);
2913 3068
3069 snd_soc_update_bits(codec, RT5650_4BTN_IL_CMD1, 0x3, 0x3);
2914 snd_soc_update_bits(codec, 3070 snd_soc_update_bits(codec,
2915 RT5645_INT_IRQ_ST, 0x8, 0x8); 3071 RT5645_INT_IRQ_ST, 0x8, 0x8);
2916 snd_soc_update_bits(codec, 3072 snd_soc_update_bits(codec,
@@ -2979,7 +3135,7 @@ static int rt5645_jack_detect(struct snd_soc_codec *codec, int jack_insert)
2979 } 3135 }
2980 if (rt5645->pdata.jd_invert) 3136 if (rt5645->pdata.jd_invert)
2981 regmap_update_bits(rt5645->regmap, RT5645_IRQ_CTRL2, 3137 regmap_update_bits(rt5645->regmap, RT5645_IRQ_CTRL2,
2982 RT5645_JD_1_1_MASK, RT5645_JD_1_1_INV); 3138 RT5645_JD_1_1_MASK, RT5645_JD_1_1_NOR);
2983 } else { /* jack out */ 3139 } else { /* jack out */
2984 rt5645->jack_type = 0; 3140 rt5645->jack_type = 0;
2985 3141
@@ -3000,7 +3156,7 @@ static int rt5645_jack_detect(struct snd_soc_codec *codec, int jack_insert)
3000 snd_soc_dapm_sync(dapm); 3156 snd_soc_dapm_sync(dapm);
3001 if (rt5645->pdata.jd_invert) 3157 if (rt5645->pdata.jd_invert)
3002 regmap_update_bits(rt5645->regmap, RT5645_IRQ_CTRL2, 3158 regmap_update_bits(rt5645->regmap, RT5645_IRQ_CTRL2,
3003 RT5645_JD_1_1_MASK, RT5645_JD_1_1_NOR); 3159 RT5645_JD_1_1_MASK, RT5645_JD_1_1_INV);
3004 } 3160 }
3005 3161
3006 return rt5645->jack_type; 3162 return rt5645->jack_type;
@@ -3124,6 +3280,12 @@ static void rt5645_jack_detect_work(struct work_struct *work)
3124 } 3280 }
3125 if (btn_type == 0)/* button release */ 3281 if (btn_type == 0)/* button release */
3126 report = rt5645->jack_type; 3282 report = rt5645->jack_type;
3283 else {
3284 if (rt5645->pdata.jd_invert) {
3285 mod_timer(&rt5645->btn_check_timer,
3286 msecs_to_jiffies(100));
3287 }
3288 }
3127 3289
3128 break; 3290 break;
3129 /* jack out */ 3291 /* jack out */
@@ -3166,6 +3328,14 @@ static irqreturn_t rt5645_irq(int irq, void *data)
3166 return IRQ_HANDLED; 3328 return IRQ_HANDLED;
3167} 3329}
3168 3330
3331static void rt5645_btn_check_callback(unsigned long data)
3332{
3333 struct rt5645_priv *rt5645 = (struct rt5645_priv *)data;
3334
3335 queue_delayed_work(system_power_efficient_wq,
3336 &rt5645->jack_detect_work, msecs_to_jiffies(5));
3337}
3338
3169static int rt5645_probe(struct snd_soc_codec *codec) 3339static int rt5645_probe(struct snd_soc_codec *codec)
3170{ 3340{
3171 struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec); 3341 struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
@@ -3322,6 +3492,31 @@ static const struct regmap_config rt5645_regmap = {
3322 .num_ranges = ARRAY_SIZE(rt5645_ranges), 3492 .num_ranges = ARRAY_SIZE(rt5645_ranges),
3323}; 3493};
3324 3494
3495static const struct regmap_config rt5650_regmap = {
3496 .reg_bits = 8,
3497 .val_bits = 16,
3498 .use_single_rw = true,
3499 .max_register = RT5645_VENDOR_ID2 + 1 + (ARRAY_SIZE(rt5645_ranges) *
3500 RT5645_PR_SPACING),
3501 .volatile_reg = rt5645_volatile_register,
3502 .readable_reg = rt5645_readable_register,
3503
3504 .cache_type = REGCACHE_RBTREE,
3505 .reg_defaults = rt5650_reg,
3506 .num_reg_defaults = ARRAY_SIZE(rt5650_reg),
3507 .ranges = rt5645_ranges,
3508 .num_ranges = ARRAY_SIZE(rt5645_ranges),
3509};
3510
3511static const struct regmap_config temp_regmap = {
3512 .name="nocache",
3513 .reg_bits = 8,
3514 .val_bits = 16,
3515 .use_single_rw = true,
3516 .max_register = RT5645_VENDOR_ID2 + 1,
3517 .cache_type = REGCACHE_NONE,
3518};
3519
3325static const struct i2c_device_id rt5645_i2c_id[] = { 3520static const struct i2c_device_id rt5645_i2c_id[] = {
3326 { "rt5645", 0 }, 3521 { "rt5645", 0 },
3327 { "rt5650", 0 }, 3522 { "rt5650", 0 },
@@ -3330,7 +3525,7 @@ static const struct i2c_device_id rt5645_i2c_id[] = {
3330MODULE_DEVICE_TABLE(i2c, rt5645_i2c_id); 3525MODULE_DEVICE_TABLE(i2c, rt5645_i2c_id);
3331 3526
3332#ifdef CONFIG_ACPI 3527#ifdef CONFIG_ACPI
3333static struct acpi_device_id rt5645_acpi_match[] = { 3528static const struct acpi_device_id rt5645_acpi_match[] = {
3334 { "10EC5645", 0 }, 3529 { "10EC5645", 0 },
3335 { "10EC5650", 0 }, 3530 { "10EC5650", 0 },
3336 {}, 3531 {},
@@ -3338,69 +3533,23 @@ static struct acpi_device_id rt5645_acpi_match[] = {
3338MODULE_DEVICE_TABLE(acpi, rt5645_acpi_match); 3533MODULE_DEVICE_TABLE(acpi, rt5645_acpi_match);
3339#endif 3534#endif
3340 3535
3341static struct rt5645_platform_data *rt5645_pdata; 3536static struct rt5645_platform_data general_platform_data = {
3342
3343static struct rt5645_platform_data strago_platform_data = {
3344 .dmic1_data_pin = RT5645_DMIC1_DISABLE, 3537 .dmic1_data_pin = RT5645_DMIC1_DISABLE,
3345 .dmic2_data_pin = RT5645_DMIC_DATA_IN2P, 3538 .dmic2_data_pin = RT5645_DMIC_DATA_IN2P,
3346 .jd_mode = 3, 3539 .jd_mode = 3,
3347}; 3540};
3348 3541
3349static int strago_quirk_cb(const struct dmi_system_id *id)
3350{
3351 rt5645_pdata = &strago_platform_data;
3352
3353 return 1;
3354}
3355
3356static const struct dmi_system_id dmi_platform_intel_braswell[] = { 3542static const struct dmi_system_id dmi_platform_intel_braswell[] = {
3357 { 3543 {
3358 .ident = "Intel Strago", 3544 .ident = "Intel Strago",
3359 .callback = strago_quirk_cb,
3360 .matches = { 3545 .matches = {
3361 DMI_MATCH(DMI_PRODUCT_NAME, "Strago"), 3546 DMI_MATCH(DMI_PRODUCT_NAME, "Strago"),
3362 }, 3547 },
3363 }, 3548 },
3364 { 3549 {
3365 .ident = "Google Celes", 3550 .ident = "Google Chrome",
3366 .callback = strago_quirk_cb,
3367 .matches = {
3368 DMI_MATCH(DMI_PRODUCT_NAME, "Celes"),
3369 },
3370 },
3371 {
3372 .ident = "Google Ultima",
3373 .callback = strago_quirk_cb,
3374 .matches = {
3375 DMI_MATCH(DMI_PRODUCT_NAME, "Ultima"),
3376 },
3377 },
3378 {
3379 .ident = "Google Reks",
3380 .callback = strago_quirk_cb,
3381 .matches = {
3382 DMI_MATCH(DMI_PRODUCT_NAME, "Reks"),
3383 },
3384 },
3385 {
3386 .ident = "Google Edgar",
3387 .callback = strago_quirk_cb,
3388 .matches = { 3551 .matches = {
3389 DMI_MATCH(DMI_PRODUCT_NAME, "Edgar"), 3552 DMI_MATCH(DMI_SYS_VENDOR, "GOOGLE"),
3390 },
3391 },
3392 {
3393 .ident = "Google Wizpig",
3394 .callback = strago_quirk_cb,
3395 .matches = {
3396 DMI_MATCH(DMI_PRODUCT_NAME, "Wizpig"),
3397 },
3398 },
3399 {
3400 .ident = "Google Terra",
3401 .callback = strago_quirk_cb,
3402 .matches = {
3403 DMI_MATCH(DMI_PRODUCT_NAME, "Terra"),
3404 }, 3553 },
3405 }, 3554 },
3406 { } 3555 { }
@@ -3413,17 +3562,9 @@ static struct rt5645_platform_data buddy_platform_data = {
3413 .jd_invert = true, 3562 .jd_invert = true,
3414}; 3563};
3415 3564
3416static int buddy_quirk_cb(const struct dmi_system_id *id)
3417{
3418 rt5645_pdata = &buddy_platform_data;
3419
3420 return 1;
3421}
3422
3423static struct dmi_system_id dmi_platform_intel_broadwell[] = { 3565static struct dmi_system_id dmi_platform_intel_broadwell[] = {
3424 { 3566 {
3425 .ident = "Chrome Buddy", 3567 .ident = "Chrome Buddy",
3426 .callback = buddy_quirk_cb,
3427 .matches = { 3568 .matches = {
3428 DMI_MATCH(DMI_PRODUCT_NAME, "Buddy"), 3569 DMI_MATCH(DMI_PRODUCT_NAME, "Buddy"),
3429 }, 3570 },
@@ -3431,6 +3572,16 @@ static struct dmi_system_id dmi_platform_intel_broadwell[] = {
3431 { } 3572 { }
3432}; 3573};
3433 3574
3575static bool rt5645_check_dp(struct device *dev)
3576{
3577 if (device_property_present(dev, "realtek,in2-differential") ||
3578 device_property_present(dev, "realtek,dmic1-data-pin") ||
3579 device_property_present(dev, "realtek,dmic2-data-pin") ||
3580 device_property_present(dev, "realtek,jd-mode"))
3581 return true;
3582
3583 return false;
3584}
3434 3585
3435static int rt5645_parse_dt(struct rt5645_priv *rt5645, struct device *dev) 3586static int rt5645_parse_dt(struct rt5645_priv *rt5645, struct device *dev)
3436{ 3587{
@@ -3453,6 +3604,7 @@ static int rt5645_i2c_probe(struct i2c_client *i2c,
3453 struct rt5645_priv *rt5645; 3604 struct rt5645_priv *rt5645;
3454 int ret, i; 3605 int ret, i;
3455 unsigned int val; 3606 unsigned int val;
3607 struct regmap *regmap;
3456 3608
3457 rt5645 = devm_kzalloc(&i2c->dev, sizeof(struct rt5645_priv), 3609 rt5645 = devm_kzalloc(&i2c->dev, sizeof(struct rt5645_priv),
3458 GFP_KERNEL); 3610 GFP_KERNEL);
@@ -3464,11 +3616,12 @@ static int rt5645_i2c_probe(struct i2c_client *i2c,
3464 3616
3465 if (pdata) 3617 if (pdata)
3466 rt5645->pdata = *pdata; 3618 rt5645->pdata = *pdata;
3467 else if (dmi_check_system(dmi_platform_intel_braswell) || 3619 else if (dmi_check_system(dmi_platform_intel_broadwell))
3468 dmi_check_system(dmi_platform_intel_broadwell)) 3620 rt5645->pdata = buddy_platform_data;
3469 rt5645->pdata = *rt5645_pdata; 3621 else if (rt5645_check_dp(&i2c->dev))
3470 else
3471 rt5645_parse_dt(rt5645, &i2c->dev); 3622 rt5645_parse_dt(rt5645, &i2c->dev);
3623 else if (dmi_check_system(dmi_platform_intel_braswell))
3624 rt5645->pdata = general_platform_data;
3472 3625
3473 rt5645->gpiod_hp_det = devm_gpiod_get_optional(&i2c->dev, "hp-detect", 3626 rt5645->gpiod_hp_det = devm_gpiod_get_optional(&i2c->dev, "hp-detect",
3474 GPIOD_IN); 3627 GPIOD_IN);
@@ -3478,14 +3631,6 @@ static int rt5645_i2c_probe(struct i2c_client *i2c,
3478 return PTR_ERR(rt5645->gpiod_hp_det); 3631 return PTR_ERR(rt5645->gpiod_hp_det);
3479 } 3632 }
3480 3633
3481 rt5645->regmap = devm_regmap_init_i2c(i2c, &rt5645_regmap);
3482 if (IS_ERR(rt5645->regmap)) {
3483 ret = PTR_ERR(rt5645->regmap);
3484 dev_err(&i2c->dev, "Failed to allocate register map: %d\n",
3485 ret);
3486 return ret;
3487 }
3488
3489 for (i = 0; i < ARRAY_SIZE(rt5645->supplies); i++) 3634 for (i = 0; i < ARRAY_SIZE(rt5645->supplies); i++)
3490 rt5645->supplies[i].supply = rt5645_supply_names[i]; 3635 rt5645->supplies[i].supply = rt5645_supply_names[i];
3491 3636
@@ -3504,13 +3649,22 @@ static int rt5645_i2c_probe(struct i2c_client *i2c,
3504 return ret; 3649 return ret;
3505 } 3650 }
3506 3651
3507 regmap_read(rt5645->regmap, RT5645_VENDOR_ID2, &val); 3652 regmap = devm_regmap_init_i2c(i2c, &temp_regmap);
3653 if (IS_ERR(regmap)) {
3654 ret = PTR_ERR(regmap);
3655 dev_err(&i2c->dev, "Failed to allocate temp register map: %d\n",
3656 ret);
3657 return ret;
3658 }
3659 regmap_read(regmap, RT5645_VENDOR_ID2, &val);
3508 3660
3509 switch (val) { 3661 switch (val) {
3510 case RT5645_DEVICE_ID: 3662 case RT5645_DEVICE_ID:
3663 rt5645->regmap = devm_regmap_init_i2c(i2c, &rt5645_regmap);
3511 rt5645->codec_type = CODEC_TYPE_RT5645; 3664 rt5645->codec_type = CODEC_TYPE_RT5645;
3512 break; 3665 break;
3513 case RT5650_DEVICE_ID: 3666 case RT5650_DEVICE_ID:
3667 rt5645->regmap = devm_regmap_init_i2c(i2c, &rt5650_regmap);
3514 rt5645->codec_type = CODEC_TYPE_RT5650; 3668 rt5645->codec_type = CODEC_TYPE_RT5650;
3515 break; 3669 break;
3516 default: 3670 default:
@@ -3521,6 +3675,13 @@ static int rt5645_i2c_probe(struct i2c_client *i2c,
3521 goto err_enable; 3675 goto err_enable;
3522 } 3676 }
3523 3677
3678 if (IS_ERR(rt5645->regmap)) {
3679 ret = PTR_ERR(rt5645->regmap);
3680 dev_err(&i2c->dev, "Failed to allocate register map: %d\n",
3681 ret);
3682 return ret;
3683 }
3684
3524 regmap_write(rt5645->regmap, RT5645_RESET, 0); 3685 regmap_write(rt5645->regmap, RT5645_RESET, 0);
3525 3686
3526 ret = regmap_register_patch(rt5645->regmap, init_list, 3687 ret = regmap_register_patch(rt5645->regmap, init_list,
@@ -3641,6 +3802,13 @@ static int rt5645_i2c_probe(struct i2c_client *i2c,
3641 } 3802 }
3642 } 3803 }
3643 3804
3805 if (rt5645->pdata.jd_invert) {
3806 regmap_update_bits(rt5645->regmap, RT5645_IRQ_CTRL2,
3807 RT5645_JD_1_1_MASK, RT5645_JD_1_1_INV);
3808 setup_timer(&rt5645->btn_check_timer,
3809 rt5645_btn_check_callback, (unsigned long)rt5645);
3810 }
3811
3644 INIT_DELAYED_WORK(&rt5645->jack_detect_work, rt5645_jack_detect_work); 3812 INIT_DELAYED_WORK(&rt5645->jack_detect_work, rt5645_jack_detect_work);
3645 INIT_DELAYED_WORK(&rt5645->rcclock_work, rt5645_rcclock_work); 3813 INIT_DELAYED_WORK(&rt5645->rcclock_work, rt5645_rcclock_work);
3646 3814
diff --git a/sound/soc/codecs/rt5651.c b/sound/soc/codecs/rt5651.c
index 1d4031818966..7a6197042423 100644
--- a/sound/soc/codecs/rt5651.c
+++ b/sound/soc/codecs/rt5651.c
@@ -18,6 +18,7 @@
18#include <linux/regmap.h> 18#include <linux/regmap.h>
19#include <linux/platform_device.h> 19#include <linux/platform_device.h>
20#include <linux/spi/spi.h> 20#include <linux/spi/spi.h>
21#include <linux/acpi.h>
21#include <sound/core.h> 22#include <sound/core.h>
22#include <sound/pcm.h> 23#include <sound/pcm.h>
23#include <sound/pcm_params.h> 24#include <sound/pcm_params.h>
@@ -1735,12 +1736,38 @@ static const struct regmap_config rt5651_regmap = {
1735 .num_ranges = ARRAY_SIZE(rt5651_ranges), 1736 .num_ranges = ARRAY_SIZE(rt5651_ranges),
1736}; 1737};
1737 1738
1739#if defined(CONFIG_OF)
1740static const struct of_device_id rt5651_of_match[] = {
1741 { .compatible = "realtek,rt5651", },
1742 {},
1743};
1744MODULE_DEVICE_TABLE(of, rt5651_of_match);
1745#endif
1746
1747#ifdef CONFIG_ACPI
1748static const struct acpi_device_id rt5651_acpi_match[] = {
1749 { "10EC5651", 0 },
1750 { },
1751};
1752MODULE_DEVICE_TABLE(acpi, rt5651_acpi_match);
1753#endif
1754
1738static const struct i2c_device_id rt5651_i2c_id[] = { 1755static const struct i2c_device_id rt5651_i2c_id[] = {
1739 { "rt5651", 0 }, 1756 { "rt5651", 0 },
1740 { } 1757 { }
1741}; 1758};
1742MODULE_DEVICE_TABLE(i2c, rt5651_i2c_id); 1759MODULE_DEVICE_TABLE(i2c, rt5651_i2c_id);
1743 1760
1761static int rt5651_parse_dt(struct rt5651_priv *rt5651, struct device_node *np)
1762{
1763 rt5651->pdata.in2_diff = of_property_read_bool(np,
1764 "realtek,in2-differential");
1765 rt5651->pdata.dmic_en = of_property_read_bool(np,
1766 "realtek,dmic-en");
1767
1768 return 0;
1769}
1770
1744static int rt5651_i2c_probe(struct i2c_client *i2c, 1771static int rt5651_i2c_probe(struct i2c_client *i2c,
1745 const struct i2c_device_id *id) 1772 const struct i2c_device_id *id)
1746{ 1773{
@@ -1757,6 +1784,8 @@ static int rt5651_i2c_probe(struct i2c_client *i2c,
1757 1784
1758 if (pdata) 1785 if (pdata)
1759 rt5651->pdata = *pdata; 1786 rt5651->pdata = *pdata;
1787 else if (i2c->dev.of_node)
1788 rt5651_parse_dt(rt5651, i2c->dev.of_node);
1760 1789
1761 rt5651->regmap = devm_regmap_init_i2c(i2c, &rt5651_regmap); 1790 rt5651->regmap = devm_regmap_init_i2c(i2c, &rt5651_regmap);
1762 if (IS_ERR(rt5651->regmap)) { 1791 if (IS_ERR(rt5651->regmap)) {
@@ -1806,6 +1835,8 @@ static int rt5651_i2c_remove(struct i2c_client *i2c)
1806static struct i2c_driver rt5651_i2c_driver = { 1835static struct i2c_driver rt5651_i2c_driver = {
1807 .driver = { 1836 .driver = {
1808 .name = "rt5651", 1837 .name = "rt5651",
1838 .acpi_match_table = ACPI_PTR(rt5651_acpi_match),
1839 .of_match_table = of_match_ptr(rt5651_of_match),
1809 }, 1840 },
1810 .probe = rt5651_i2c_probe, 1841 .probe = rt5651_i2c_probe,
1811 .remove = rt5651_i2c_remove, 1842 .remove = rt5651_i2c_remove,
diff --git a/sound/soc/codecs/rt5659.c b/sound/soc/codecs/rt5659.c
new file mode 100644
index 000000000000..820d8fa62b5e
--- /dev/null
+++ b/sound/soc/codecs/rt5659.c
@@ -0,0 +1,4223 @@
1/*
2 * rt5659.c -- RT5659/RT5658 ALSA SoC audio codec driver
3 *
4 * Copyright 2015 Realtek Semiconductor Corp.
5 * Author: Bard Liao <bardliao@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/i2c.h>
18#include <linux/platform_device.h>
19#include <linux/spi/spi.h>
20#include <linux/acpi.h>
21#include <linux/gpio.h>
22#include <linux/gpio/consumer.h>
23#include <sound/core.h>
24#include <sound/pcm.h>
25#include <sound/pcm_params.h>
26#include <sound/jack.h>
27#include <sound/soc.h>
28#include <sound/soc-dapm.h>
29#include <sound/initval.h>
30#include <sound/tlv.h>
31#include <sound/rt5659.h>
32
33#include "rl6231.h"
34#include "rt5659.h"
35
36static const struct reg_default rt5659_reg[] = {
37 { 0x0000, 0x0000 },
38 { 0x0001, 0x4848 },
39 { 0x0002, 0x8080 },
40 { 0x0003, 0xc8c8 },
41 { 0x0004, 0xc80a },
42 { 0x0005, 0x0000 },
43 { 0x0006, 0x0000 },
44 { 0x0007, 0x0103 },
45 { 0x0008, 0x0080 },
46 { 0x0009, 0x0000 },
47 { 0x000a, 0x0000 },
48 { 0x000c, 0x0000 },
49 { 0x000d, 0x0000 },
50 { 0x000f, 0x0808 },
51 { 0x0010, 0x3080 },
52 { 0x0011, 0x4a00 },
53 { 0x0012, 0x4e00 },
54 { 0x0015, 0x42c1 },
55 { 0x0016, 0x0000 },
56 { 0x0018, 0x000b },
57 { 0x0019, 0xafaf },
58 { 0x001a, 0xafaf },
59 { 0x001b, 0x0011 },
60 { 0x001c, 0x2f2f },
61 { 0x001d, 0x2f2f },
62 { 0x001e, 0x2f2f },
63 { 0x001f, 0x0000 },
64 { 0x0020, 0x0000 },
65 { 0x0021, 0x0000 },
66 { 0x0022, 0x5757 },
67 { 0x0023, 0x0039 },
68 { 0x0026, 0xc060 },
69 { 0x0027, 0xd8d8 },
70 { 0x0029, 0x8080 },
71 { 0x002a, 0xaaaa },
72 { 0x002b, 0xaaaa },
73 { 0x002c, 0x00af },
74 { 0x002d, 0x0000 },
75 { 0x002f, 0x1002 },
76 { 0x0031, 0x5000 },
77 { 0x0032, 0x0000 },
78 { 0x0033, 0x0000 },
79 { 0x0034, 0x0000 },
80 { 0x0035, 0x0000 },
81 { 0x0036, 0x0000 },
82 { 0x003a, 0x0000 },
83 { 0x003b, 0x0000 },
84 { 0x003c, 0x007f },
85 { 0x003d, 0x0000 },
86 { 0x003e, 0x007f },
87 { 0x0040, 0x0808 },
88 { 0x0046, 0x001f },
89 { 0x0047, 0x001f },
90 { 0x0048, 0x0003 },
91 { 0x0049, 0xe061 },
92 { 0x004a, 0x0000 },
93 { 0x004b, 0x031f },
94 { 0x004d, 0x0000 },
95 { 0x004e, 0x001f },
96 { 0x004f, 0x0000 },
97 { 0x0050, 0x001f },
98 { 0x0052, 0xf000 },
99 { 0x0053, 0x0111 },
100 { 0x0054, 0x0064 },
101 { 0x0055, 0x0080 },
102 { 0x0056, 0xef0e },
103 { 0x0057, 0xf0f0 },
104 { 0x0058, 0xef0e },
105 { 0x0059, 0xf0f0 },
106 { 0x005a, 0xef0e },
107 { 0x005b, 0xf0f0 },
108 { 0x005c, 0xf000 },
109 { 0x005d, 0x0000 },
110 { 0x005e, 0x1f2c },
111 { 0x005f, 0x1f2c },
112 { 0x0060, 0x2717 },
113 { 0x0061, 0x0000 },
114 { 0x0062, 0x0000 },
115 { 0x0063, 0x003e },
116 { 0x0064, 0x0000 },
117 { 0x0065, 0x0000 },
118 { 0x0066, 0x0000 },
119 { 0x0067, 0x0000 },
120 { 0x006a, 0x0000 },
121 { 0x006b, 0x0000 },
122 { 0x006c, 0x0000 },
123 { 0x006e, 0x0000 },
124 { 0x006f, 0x0000 },
125 { 0x0070, 0x8000 },
126 { 0x0071, 0x8000 },
127 { 0x0072, 0x8000 },
128 { 0x0073, 0x1110 },
129 { 0x0074, 0xfe00 },
130 { 0x0075, 0x2409 },
131 { 0x0076, 0x000a },
132 { 0x0077, 0x00f0 },
133 { 0x0078, 0x0000 },
134 { 0x0079, 0x0000 },
135 { 0x007a, 0x0123 },
136 { 0x007b, 0x8003 },
137 { 0x0080, 0x0000 },
138 { 0x0081, 0x0000 },
139 { 0x0082, 0x0000 },
140 { 0x0083, 0x0000 },
141 { 0x0084, 0x0000 },
142 { 0x0085, 0x0000 },
143 { 0x0086, 0x0008 },
144 { 0x0087, 0x0000 },
145 { 0x0088, 0x0000 },
146 { 0x0089, 0x0000 },
147 { 0x008a, 0x0000 },
148 { 0x008b, 0x0000 },
149 { 0x008c, 0x0003 },
150 { 0x008e, 0x0000 },
151 { 0x008f, 0x1000 },
152 { 0x0090, 0x0646 },
153 { 0x0091, 0x0c16 },
154 { 0x0092, 0x0073 },
155 { 0x0093, 0x0000 },
156 { 0x0094, 0x0080 },
157 { 0x0097, 0x0000 },
158 { 0x0098, 0x0000 },
159 { 0x0099, 0x0000 },
160 { 0x009a, 0x0000 },
161 { 0x009b, 0x0000 },
162 { 0x009c, 0x007f },
163 { 0x009d, 0x0000 },
164 { 0x009e, 0x007f },
165 { 0x009f, 0x0000 },
166 { 0x00a0, 0x0060 },
167 { 0x00a1, 0x90a1 },
168 { 0x00ae, 0x2000 },
169 { 0x00af, 0x0000 },
170 { 0x00b0, 0x2000 },
171 { 0x00b1, 0x0000 },
172 { 0x00b2, 0x0000 },
173 { 0x00b6, 0x0000 },
174 { 0x00b7, 0x0000 },
175 { 0x00b8, 0x0000 },
176 { 0x00b9, 0x0000 },
177 { 0x00ba, 0x0000 },
178 { 0x00bb, 0x0000 },
179 { 0x00be, 0x0000 },
180 { 0x00bf, 0x0000 },
181 { 0x00c0, 0x0000 },
182 { 0x00c1, 0x0000 },
183 { 0x00c2, 0x0000 },
184 { 0x00c3, 0x0000 },
185 { 0x00c4, 0x0003 },
186 { 0x00c5, 0x0000 },
187 { 0x00cb, 0xa02f },
188 { 0x00cc, 0x0000 },
189 { 0x00cd, 0x0e02 },
190 { 0x00d6, 0x0000 },
191 { 0x00d7, 0x2244 },
192 { 0x00d9, 0x0809 },
193 { 0x00da, 0x0000 },
194 { 0x00db, 0x0008 },
195 { 0x00dc, 0x00c0 },
196 { 0x00dd, 0x6724 },
197 { 0x00de, 0x3131 },
198 { 0x00df, 0x0008 },
199 { 0x00e0, 0x4000 },
200 { 0x00e1, 0x3131 },
201 { 0x00e4, 0x400c },
202 { 0x00e5, 0x8031 },
203 { 0x00ea, 0xb320 },
204 { 0x00eb, 0x0000 },
205 { 0x00ec, 0xb300 },
206 { 0x00ed, 0x0000 },
207 { 0x00f0, 0x0000 },
208 { 0x00f1, 0x0202 },
209 { 0x00f2, 0x0ddd },
210 { 0x00f3, 0x0ddd },
211 { 0x00f4, 0x0ddd },
212 { 0x00f6, 0x0000 },
213 { 0x00f7, 0x0000 },
214 { 0x00f8, 0x0000 },
215 { 0x00f9, 0x0000 },
216 { 0x00fa, 0x8000 },
217 { 0x00fb, 0x0000 },
218 { 0x00fc, 0x0000 },
219 { 0x00fd, 0x0001 },
220 { 0x00fe, 0x10ec },
221 { 0x00ff, 0x6311 },
222 { 0x0100, 0xaaaa },
223 { 0x010a, 0xaaaa },
224 { 0x010b, 0x00a0 },
225 { 0x010c, 0xaeae },
226 { 0x010d, 0xaaaa },
227 { 0x010e, 0xaaa8 },
228 { 0x010f, 0xa0aa },
229 { 0x0110, 0xe02a },
230 { 0x0111, 0xa702 },
231 { 0x0112, 0xaaaa },
232 { 0x0113, 0x2800 },
233 { 0x0116, 0x0000 },
234 { 0x0117, 0x0f00 },
235 { 0x011a, 0x0020 },
236 { 0x011b, 0x0011 },
237 { 0x011c, 0x0150 },
238 { 0x011d, 0x0000 },
239 { 0x011e, 0x0000 },
240 { 0x011f, 0x0000 },
241 { 0x0120, 0x0000 },
242 { 0x0121, 0x009b },
243 { 0x0122, 0x5014 },
244 { 0x0123, 0x0421 },
245 { 0x0124, 0x7cea },
246 { 0x0125, 0x0420 },
247 { 0x0126, 0x5550 },
248 { 0x0132, 0x0000 },
249 { 0x0133, 0x0000 },
250 { 0x0137, 0x5055 },
251 { 0x0138, 0x3700 },
252 { 0x0139, 0x79a1 },
253 { 0x013a, 0x2020 },
254 { 0x013b, 0x2020 },
255 { 0x013c, 0x2005 },
256 { 0x013e, 0x1f00 },
257 { 0x013f, 0x0000 },
258 { 0x0145, 0x0002 },
259 { 0x0146, 0x0000 },
260 { 0x0147, 0x0000 },
261 { 0x0148, 0x0000 },
262 { 0x0150, 0x1813 },
263 { 0x0151, 0x0690 },
264 { 0x0152, 0x1c17 },
265 { 0x0153, 0x6883 },
266 { 0x0154, 0xd3ce },
267 { 0x0155, 0x352d },
268 { 0x0156, 0x00eb },
269 { 0x0157, 0x3717 },
270 { 0x0158, 0x4c6a },
271 { 0x0159, 0xe41b },
272 { 0x015a, 0x2a13 },
273 { 0x015b, 0xb600 },
274 { 0x015c, 0xc730 },
275 { 0x015d, 0x35d4 },
276 { 0x015e, 0x00bf },
277 { 0x0160, 0x0ec0 },
278 { 0x0161, 0x0020 },
279 { 0x0162, 0x0080 },
280 { 0x0163, 0x0800 },
281 { 0x0164, 0x0000 },
282 { 0x0165, 0x0000 },
283 { 0x0166, 0x0000 },
284 { 0x0167, 0x001f },
285 { 0x0170, 0x4e80 },
286 { 0x0171, 0x0020 },
287 { 0x0172, 0x0080 },
288 { 0x0173, 0x0800 },
289 { 0x0174, 0x000c },
290 { 0x0175, 0x0000 },
291 { 0x0190, 0x3300 },
292 { 0x0191, 0x2200 },
293 { 0x0192, 0x0000 },
294 { 0x01b0, 0x4b38 },
295 { 0x01b1, 0x0000 },
296 { 0x01b2, 0x0000 },
297 { 0x01b3, 0x0000 },
298 { 0x01c0, 0x0045 },
299 { 0x01c1, 0x0540 },
300 { 0x01c2, 0x0000 },
301 { 0x01c3, 0x0030 },
302 { 0x01c7, 0x0000 },
303 { 0x01c8, 0x5757 },
304 { 0x01c9, 0x5757 },
305 { 0x01ca, 0x5757 },
306 { 0x01cb, 0x5757 },
307 { 0x01cc, 0x5757 },
308 { 0x01cd, 0x5757 },
309 { 0x01ce, 0x006f },
310 { 0x01da, 0x0000 },
311 { 0x01db, 0x0000 },
312 { 0x01de, 0x7d00 },
313 { 0x01df, 0x10c0 },
314 { 0x01e0, 0x06a1 },
315 { 0x01e1, 0x0000 },
316 { 0x01e2, 0x0000 },
317 { 0x01e3, 0x0000 },
318 { 0x01e4, 0x0001 },
319 { 0x01e6, 0x0000 },
320 { 0x01e7, 0x0000 },
321 { 0x01e8, 0x0000 },
322 { 0x01ea, 0x0000 },
323 { 0x01eb, 0x0000 },
324 { 0x01ec, 0x0000 },
325 { 0x01ed, 0x0000 },
326 { 0x01ee, 0x0000 },
327 { 0x01ef, 0x0000 },
328 { 0x01f0, 0x0000 },
329 { 0x01f1, 0x0000 },
330 { 0x01f2, 0x0000 },
331 { 0x01f6, 0x1e04 },
332 { 0x01f7, 0x01a1 },
333 { 0x01f8, 0x0000 },
334 { 0x01f9, 0x0000 },
335 { 0x01fa, 0x0002 },
336 { 0x01fb, 0x0000 },
337 { 0x01fc, 0x0000 },
338 { 0x01fd, 0x0000 },
339 { 0x01fe, 0x0000 },
340 { 0x0200, 0x066c },
341 { 0x0201, 0x7fff },
342 { 0x0202, 0x7fff },
343 { 0x0203, 0x0000 },
344 { 0x0204, 0x0000 },
345 { 0x0205, 0x0000 },
346 { 0x0206, 0x0000 },
347 { 0x0207, 0x0000 },
348 { 0x0208, 0x0000 },
349 { 0x0256, 0x0000 },
350 { 0x0257, 0x0000 },
351 { 0x0258, 0x0000 },
352 { 0x0259, 0x0000 },
353 { 0x025a, 0x0000 },
354 { 0x025b, 0x3333 },
355 { 0x025c, 0x3333 },
356 { 0x025d, 0x3333 },
357 { 0x025e, 0x0000 },
358 { 0x025f, 0x0000 },
359 { 0x0260, 0x0000 },
360 { 0x0261, 0x0022 },
361 { 0x0262, 0x0300 },
362 { 0x0265, 0x1e80 },
363 { 0x0266, 0x0131 },
364 { 0x0267, 0x0003 },
365 { 0x0268, 0x0000 },
366 { 0x0269, 0x0000 },
367 { 0x026a, 0x0000 },
368 { 0x026b, 0x0000 },
369 { 0x026c, 0x0000 },
370 { 0x026d, 0x0000 },
371 { 0x026e, 0x0000 },
372 { 0x026f, 0x0000 },
373 { 0x0270, 0x0000 },
374 { 0x0271, 0x0000 },
375 { 0x0272, 0x0000 },
376 { 0x0273, 0x0000 },
377 { 0x0280, 0x0000 },
378 { 0x0281, 0x0000 },
379 { 0x0282, 0x0418 },
380 { 0x0283, 0x7fff },
381 { 0x0284, 0x7000 },
382 { 0x0290, 0x01d0 },
383 { 0x0291, 0x0100 },
384 { 0x02fa, 0x0000 },
385 { 0x02fb, 0x0000 },
386 { 0x02fc, 0x0000 },
387 { 0x0300, 0x001f },
388 { 0x0301, 0x032c },
389 { 0x0302, 0x5f21 },
390 { 0x0303, 0x4000 },
391 { 0x0304, 0x4000 },
392 { 0x0305, 0x0600 },
393 { 0x0306, 0x8000 },
394 { 0x0307, 0x0700 },
395 { 0x0308, 0x001f },
396 { 0x0309, 0x032c },
397 { 0x030a, 0x5f21 },
398 { 0x030b, 0x4000 },
399 { 0x030c, 0x4000 },
400 { 0x030d, 0x0600 },
401 { 0x030e, 0x8000 },
402 { 0x030f, 0x0700 },
403 { 0x0310, 0x4560 },
404 { 0x0311, 0xa4a8 },
405 { 0x0312, 0x7418 },
406 { 0x0313, 0x0000 },
407 { 0x0314, 0x0006 },
408 { 0x0315, 0x00ff },
409 { 0x0316, 0xc400 },
410 { 0x0317, 0x4560 },
411 { 0x0318, 0xa4a8 },
412 { 0x0319, 0x7418 },
413 { 0x031a, 0x0000 },
414 { 0x031b, 0x0006 },
415 { 0x031c, 0x00ff },
416 { 0x031d, 0xc400 },
417 { 0x0320, 0x0f20 },
418 { 0x0321, 0x8700 },
419 { 0x0322, 0x7dc2 },
420 { 0x0323, 0xa178 },
421 { 0x0324, 0x5383 },
422 { 0x0325, 0x7dc2 },
423 { 0x0326, 0xa178 },
424 { 0x0327, 0x5383 },
425 { 0x0328, 0x003e },
426 { 0x0329, 0x02c1 },
427 { 0x032a, 0xd37d },
428 { 0x0330, 0x00a6 },
429 { 0x0331, 0x04c3 },
430 { 0x0332, 0x27c8 },
431 { 0x0333, 0xbf50 },
432 { 0x0334, 0x0045 },
433 { 0x0335, 0x2007 },
434 { 0x0336, 0x7418 },
435 { 0x0337, 0x0501 },
436 { 0x0338, 0x0000 },
437 { 0x0339, 0x0010 },
438 { 0x033a, 0x1010 },
439 { 0x0340, 0x0800 },
440 { 0x0341, 0x0800 },
441 { 0x0342, 0x0800 },
442 { 0x0343, 0x0800 },
443 { 0x0344, 0x0000 },
444 { 0x0345, 0x0000 },
445 { 0x0346, 0x0000 },
446 { 0x0347, 0x0000 },
447 { 0x0348, 0x0000 },
448 { 0x0349, 0x0000 },
449 { 0x034a, 0x0000 },
450 { 0x034b, 0x0000 },
451 { 0x034c, 0x0000 },
452 { 0x034d, 0x0000 },
453 { 0x034e, 0x0000 },
454 { 0x034f, 0x0000 },
455 { 0x0350, 0x0000 },
456 { 0x0351, 0x0000 },
457 { 0x0352, 0x0000 },
458 { 0x0353, 0x0000 },
459 { 0x0354, 0x0000 },
460 { 0x0355, 0x0000 },
461 { 0x0356, 0x0000 },
462 { 0x0357, 0x0000 },
463 { 0x0358, 0x0000 },
464 { 0x0359, 0x0000 },
465 { 0x035a, 0x0000 },
466 { 0x035b, 0x0000 },
467 { 0x035c, 0x0000 },
468 { 0x035d, 0x0000 },
469 { 0x035e, 0x2000 },
470 { 0x035f, 0x0000 },
471 { 0x0360, 0x2000 },
472 { 0x0361, 0x2000 },
473 { 0x0362, 0x0000 },
474 { 0x0363, 0x2000 },
475 { 0x0364, 0x0200 },
476 { 0x0365, 0x0000 },
477 { 0x0366, 0x0000 },
478 { 0x0367, 0x0000 },
479 { 0x0368, 0x0000 },
480 { 0x0369, 0x0000 },
481 { 0x036a, 0x0000 },
482 { 0x036b, 0x0000 },
483 { 0x036c, 0x0000 },
484 { 0x036d, 0x0000 },
485 { 0x036e, 0x0200 },
486 { 0x036f, 0x0000 },
487 { 0x0370, 0x0000 },
488 { 0x0371, 0x0000 },
489 { 0x0372, 0x0000 },
490 { 0x0373, 0x0000 },
491 { 0x0374, 0x0000 },
492 { 0x0375, 0x0000 },
493 { 0x0376, 0x0000 },
494 { 0x0377, 0x0000 },
495 { 0x03d0, 0x0000 },
496 { 0x03d1, 0x0000 },
497 { 0x03d2, 0x0000 },
498 { 0x03d3, 0x0000 },
499 { 0x03d4, 0x2000 },
500 { 0x03d5, 0x2000 },
501 { 0x03d6, 0x0000 },
502 { 0x03d7, 0x0000 },
503 { 0x03d8, 0x2000 },
504 { 0x03d9, 0x2000 },
505 { 0x03da, 0x2000 },
506 { 0x03db, 0x2000 },
507 { 0x03dc, 0x0000 },
508 { 0x03dd, 0x0000 },
509 { 0x03de, 0x0000 },
510 { 0x03df, 0x2000 },
511 { 0x03e0, 0x0000 },
512 { 0x03e1, 0x0000 },
513 { 0x03e2, 0x0000 },
514 { 0x03e3, 0x0000 },
515 { 0x03e4, 0x0000 },
516 { 0x03e5, 0x0000 },
517 { 0x03e6, 0x0000 },
518 { 0x03e7, 0x0000 },
519 { 0x03e8, 0x0000 },
520 { 0x03e9, 0x0000 },
521 { 0x03ea, 0x0000 },
522 { 0x03eb, 0x0000 },
523 { 0x03ec, 0x0000 },
524 { 0x03ed, 0x0000 },
525 { 0x03ee, 0x0000 },
526 { 0x03ef, 0x0000 },
527 { 0x03f0, 0x0800 },
528 { 0x03f1, 0x0800 },
529 { 0x03f2, 0x0800 },
530 { 0x03f3, 0x0800 },
531};
532
533static bool rt5659_volatile_register(struct device *dev, unsigned int reg)
534{
535 switch (reg) {
536 case RT5659_RESET:
537 case RT5659_EJD_CTRL_2:
538 case RT5659_SILENCE_CTRL:
539 case RT5659_DAC2_DIG_VOL:
540 case RT5659_HP_IMP_GAIN_2:
541 case RT5659_PDM_OUT_CTRL:
542 case RT5659_PDM_DATA_CTRL_1:
543 case RT5659_PDM_DATA_CTRL_4:
544 case RT5659_HAPTIC_GEN_CTRL_1:
545 case RT5659_HAPTIC_GEN_CTRL_3:
546 case RT5659_HAPTIC_LPF_CTRL_3:
547 case RT5659_CLK_DET:
548 case RT5659_MICBIAS_1:
549 case RT5659_ASRC_11:
550 case RT5659_ADC_EQ_CTRL_1:
551 case RT5659_DAC_EQ_CTRL_1:
552 case RT5659_INT_ST_1:
553 case RT5659_INT_ST_2:
554 case RT5659_GPIO_STA:
555 case RT5659_SINE_GEN_CTRL_1:
556 case RT5659_IL_CMD_1:
557 case RT5659_4BTN_IL_CMD_1:
558 case RT5659_PSV_IL_CMD_1:
559 case RT5659_AJD1_CTRL:
560 case RT5659_AJD2_AJD3_CTRL:
561 case RT5659_JD_CTRL_3:
562 case RT5659_VENDOR_ID:
563 case RT5659_VENDOR_ID_1:
564 case RT5659_DEVICE_ID:
565 case RT5659_MEMORY_TEST:
566 case RT5659_SOFT_RAMP_DEPOP_DAC_CLK_CTRL:
567 case RT5659_VOL_TEST:
568 case RT5659_STO_NG2_CTRL_1:
569 case RT5659_STO_NG2_CTRL_5:
570 case RT5659_STO_NG2_CTRL_6:
571 case RT5659_STO_NG2_CTRL_7:
572 case RT5659_MONO_NG2_CTRL_1:
573 case RT5659_MONO_NG2_CTRL_5:
574 case RT5659_MONO_NG2_CTRL_6:
575 case RT5659_HP_IMP_SENS_CTRL_1:
576 case RT5659_HP_IMP_SENS_CTRL_3:
577 case RT5659_HP_IMP_SENS_CTRL_4:
578 case RT5659_HP_CALIB_CTRL_1:
579 case RT5659_HP_CALIB_CTRL_9:
580 case RT5659_HP_CALIB_STA_1:
581 case RT5659_HP_CALIB_STA_2:
582 case RT5659_HP_CALIB_STA_3:
583 case RT5659_HP_CALIB_STA_4:
584 case RT5659_HP_CALIB_STA_5:
585 case RT5659_HP_CALIB_STA_6:
586 case RT5659_HP_CALIB_STA_7:
587 case RT5659_HP_CALIB_STA_8:
588 case RT5659_HP_CALIB_STA_9:
589 case RT5659_MONO_AMP_CALIB_CTRL_1:
590 case RT5659_MONO_AMP_CALIB_CTRL_3:
591 case RT5659_MONO_AMP_CALIB_STA_1:
592 case RT5659_MONO_AMP_CALIB_STA_2:
593 case RT5659_MONO_AMP_CALIB_STA_3:
594 case RT5659_MONO_AMP_CALIB_STA_4:
595 case RT5659_SPK_PWR_LMT_STA_1:
596 case RT5659_SPK_PWR_LMT_STA_2:
597 case RT5659_SPK_PWR_LMT_STA_3:
598 case RT5659_SPK_PWR_LMT_STA_4:
599 case RT5659_SPK_PWR_LMT_STA_5:
600 case RT5659_SPK_PWR_LMT_STA_6:
601 case RT5659_SPK_DC_CAILB_CTRL_1:
602 case RT5659_SPK_DC_CAILB_STA_1:
603 case RT5659_SPK_DC_CAILB_STA_2:
604 case RT5659_SPK_DC_CAILB_STA_3:
605 case RT5659_SPK_DC_CAILB_STA_4:
606 case RT5659_SPK_DC_CAILB_STA_5:
607 case RT5659_SPK_DC_CAILB_STA_6:
608 case RT5659_SPK_DC_CAILB_STA_7:
609 case RT5659_SPK_DC_CAILB_STA_8:
610 case RT5659_SPK_DC_CAILB_STA_9:
611 case RT5659_SPK_DC_CAILB_STA_10:
612 case RT5659_SPK_VDD_STA_1:
613 case RT5659_SPK_VDD_STA_2:
614 case RT5659_SPK_DC_DET_CTRL_1:
615 case RT5659_PURE_DC_DET_CTRL_1:
616 case RT5659_PURE_DC_DET_CTRL_2:
617 case RT5659_DRC1_PRIV_1:
618 case RT5659_DRC1_PRIV_4:
619 case RT5659_DRC1_PRIV_5:
620 case RT5659_DRC1_PRIV_6:
621 case RT5659_DRC1_PRIV_7:
622 case RT5659_DRC2_PRIV_1:
623 case RT5659_DRC2_PRIV_4:
624 case RT5659_DRC2_PRIV_5:
625 case RT5659_DRC2_PRIV_6:
626 case RT5659_DRC2_PRIV_7:
627 case RT5659_ALC_PGA_STA_1:
628 case RT5659_ALC_PGA_STA_2:
629 case RT5659_ALC_PGA_STA_3:
630 return true;
631 default:
632 return false;
633 }
634}
635
636static bool rt5659_readable_register(struct device *dev, unsigned int reg)
637{
638 switch (reg) {
639 case RT5659_RESET:
640 case RT5659_SPO_VOL:
641 case RT5659_HP_VOL:
642 case RT5659_LOUT:
643 case RT5659_MONO_OUT:
644 case RT5659_HPL_GAIN:
645 case RT5659_HPR_GAIN:
646 case RT5659_MONO_GAIN:
647 case RT5659_SPDIF_CTRL_1:
648 case RT5659_SPDIF_CTRL_2:
649 case RT5659_CAL_BST_CTRL:
650 case RT5659_IN1_IN2:
651 case RT5659_IN3_IN4:
652 case RT5659_INL1_INR1_VOL:
653 case RT5659_EJD_CTRL_1:
654 case RT5659_EJD_CTRL_2:
655 case RT5659_EJD_CTRL_3:
656 case RT5659_SILENCE_CTRL:
657 case RT5659_PSV_CTRL:
658 case RT5659_SIDETONE_CTRL:
659 case RT5659_DAC1_DIG_VOL:
660 case RT5659_DAC2_DIG_VOL:
661 case RT5659_DAC_CTRL:
662 case RT5659_STO1_ADC_DIG_VOL:
663 case RT5659_MONO_ADC_DIG_VOL:
664 case RT5659_STO2_ADC_DIG_VOL:
665 case RT5659_STO1_BOOST:
666 case RT5659_MONO_BOOST:
667 case RT5659_STO2_BOOST:
668 case RT5659_HP_IMP_GAIN_1:
669 case RT5659_HP_IMP_GAIN_2:
670 case RT5659_STO1_ADC_MIXER:
671 case RT5659_MONO_ADC_MIXER:
672 case RT5659_AD_DA_MIXER:
673 case RT5659_STO_DAC_MIXER:
674 case RT5659_MONO_DAC_MIXER:
675 case RT5659_DIG_MIXER:
676 case RT5659_A_DAC_MUX:
677 case RT5659_DIG_INF23_DATA:
678 case RT5659_PDM_OUT_CTRL:
679 case RT5659_PDM_DATA_CTRL_1:
680 case RT5659_PDM_DATA_CTRL_2:
681 case RT5659_PDM_DATA_CTRL_3:
682 case RT5659_PDM_DATA_CTRL_4:
683 case RT5659_SPDIF_CTRL:
684 case RT5659_REC1_GAIN:
685 case RT5659_REC1_L1_MIXER:
686 case RT5659_REC1_L2_MIXER:
687 case RT5659_REC1_R1_MIXER:
688 case RT5659_REC1_R2_MIXER:
689 case RT5659_CAL_REC:
690 case RT5659_REC2_L1_MIXER:
691 case RT5659_REC2_L2_MIXER:
692 case RT5659_REC2_R1_MIXER:
693 case RT5659_REC2_R2_MIXER:
694 case RT5659_SPK_L_MIXER:
695 case RT5659_SPK_R_MIXER:
696 case RT5659_SPO_AMP_GAIN:
697 case RT5659_ALC_BACK_GAIN:
698 case RT5659_MONOMIX_GAIN:
699 case RT5659_MONOMIX_IN_GAIN:
700 case RT5659_OUT_L_GAIN:
701 case RT5659_OUT_L_MIXER:
702 case RT5659_OUT_R_GAIN:
703 case RT5659_OUT_R_MIXER:
704 case RT5659_LOUT_MIXER:
705 case RT5659_HAPTIC_GEN_CTRL_1:
706 case RT5659_HAPTIC_GEN_CTRL_2:
707 case RT5659_HAPTIC_GEN_CTRL_3:
708 case RT5659_HAPTIC_GEN_CTRL_4:
709 case RT5659_HAPTIC_GEN_CTRL_5:
710 case RT5659_HAPTIC_GEN_CTRL_6:
711 case RT5659_HAPTIC_GEN_CTRL_7:
712 case RT5659_HAPTIC_GEN_CTRL_8:
713 case RT5659_HAPTIC_GEN_CTRL_9:
714 case RT5659_HAPTIC_GEN_CTRL_10:
715 case RT5659_HAPTIC_GEN_CTRL_11:
716 case RT5659_HAPTIC_LPF_CTRL_1:
717 case RT5659_HAPTIC_LPF_CTRL_2:
718 case RT5659_HAPTIC_LPF_CTRL_3:
719 case RT5659_PWR_DIG_1:
720 case RT5659_PWR_DIG_2:
721 case RT5659_PWR_ANLG_1:
722 case RT5659_PWR_ANLG_2:
723 case RT5659_PWR_ANLG_3:
724 case RT5659_PWR_MIXER:
725 case RT5659_PWR_VOL:
726 case RT5659_PRIV_INDEX:
727 case RT5659_CLK_DET:
728 case RT5659_PRIV_DATA:
729 case RT5659_PRE_DIV_1:
730 case RT5659_PRE_DIV_2:
731 case RT5659_I2S1_SDP:
732 case RT5659_I2S2_SDP:
733 case RT5659_I2S3_SDP:
734 case RT5659_ADDA_CLK_1:
735 case RT5659_ADDA_CLK_2:
736 case RT5659_DMIC_CTRL_1:
737 case RT5659_DMIC_CTRL_2:
738 case RT5659_TDM_CTRL_1:
739 case RT5659_TDM_CTRL_2:
740 case RT5659_TDM_CTRL_3:
741 case RT5659_TDM_CTRL_4:
742 case RT5659_TDM_CTRL_5:
743 case RT5659_GLB_CLK:
744 case RT5659_PLL_CTRL_1:
745 case RT5659_PLL_CTRL_2:
746 case RT5659_ASRC_1:
747 case RT5659_ASRC_2:
748 case RT5659_ASRC_3:
749 case RT5659_ASRC_4:
750 case RT5659_ASRC_5:
751 case RT5659_ASRC_6:
752 case RT5659_ASRC_7:
753 case RT5659_ASRC_8:
754 case RT5659_ASRC_9:
755 case RT5659_ASRC_10:
756 case RT5659_DEPOP_1:
757 case RT5659_DEPOP_2:
758 case RT5659_DEPOP_3:
759 case RT5659_HP_CHARGE_PUMP_1:
760 case RT5659_HP_CHARGE_PUMP_2:
761 case RT5659_MICBIAS_1:
762 case RT5659_MICBIAS_2:
763 case RT5659_ASRC_11:
764 case RT5659_ASRC_12:
765 case RT5659_ASRC_13:
766 case RT5659_REC_M1_M2_GAIN_CTRL:
767 case RT5659_RC_CLK_CTRL:
768 case RT5659_CLASSD_CTRL_1:
769 case RT5659_CLASSD_CTRL_2:
770 case RT5659_ADC_EQ_CTRL_1:
771 case RT5659_ADC_EQ_CTRL_2:
772 case RT5659_DAC_EQ_CTRL_1:
773 case RT5659_DAC_EQ_CTRL_2:
774 case RT5659_DAC_EQ_CTRL_3:
775 case RT5659_IRQ_CTRL_1:
776 case RT5659_IRQ_CTRL_2:
777 case RT5659_IRQ_CTRL_3:
778 case RT5659_IRQ_CTRL_4:
779 case RT5659_IRQ_CTRL_5:
780 case RT5659_IRQ_CTRL_6:
781 case RT5659_INT_ST_1:
782 case RT5659_INT_ST_2:
783 case RT5659_GPIO_CTRL_1:
784 case RT5659_GPIO_CTRL_2:
785 case RT5659_GPIO_CTRL_3:
786 case RT5659_GPIO_CTRL_4:
787 case RT5659_GPIO_CTRL_5:
788 case RT5659_GPIO_STA:
789 case RT5659_SINE_GEN_CTRL_1:
790 case RT5659_SINE_GEN_CTRL_2:
791 case RT5659_SINE_GEN_CTRL_3:
792 case RT5659_HP_AMP_DET_CTRL_1:
793 case RT5659_HP_AMP_DET_CTRL_2:
794 case RT5659_SV_ZCD_1:
795 case RT5659_SV_ZCD_2:
796 case RT5659_IL_CMD_1:
797 case RT5659_IL_CMD_2:
798 case RT5659_IL_CMD_3:
799 case RT5659_IL_CMD_4:
800 case RT5659_4BTN_IL_CMD_1:
801 case RT5659_4BTN_IL_CMD_2:
802 case RT5659_4BTN_IL_CMD_3:
803 case RT5659_PSV_IL_CMD_1:
804 case RT5659_PSV_IL_CMD_2:
805 case RT5659_ADC_STO1_HP_CTRL_1:
806 case RT5659_ADC_STO1_HP_CTRL_2:
807 case RT5659_ADC_MONO_HP_CTRL_1:
808 case RT5659_ADC_MONO_HP_CTRL_2:
809 case RT5659_AJD1_CTRL:
810 case RT5659_AJD2_AJD3_CTRL:
811 case RT5659_JD1_THD:
812 case RT5659_JD2_THD:
813 case RT5659_JD3_THD:
814 case RT5659_JD_CTRL_1:
815 case RT5659_JD_CTRL_2:
816 case RT5659_JD_CTRL_3:
817 case RT5659_JD_CTRL_4:
818 case RT5659_DIG_MISC:
819 case RT5659_DUMMY_2:
820 case RT5659_DUMMY_3:
821 case RT5659_VENDOR_ID:
822 case RT5659_VENDOR_ID_1:
823 case RT5659_DEVICE_ID:
824 case RT5659_DAC_ADC_DIG_VOL:
825 case RT5659_BIAS_CUR_CTRL_1:
826 case RT5659_BIAS_CUR_CTRL_2:
827 case RT5659_BIAS_CUR_CTRL_3:
828 case RT5659_BIAS_CUR_CTRL_4:
829 case RT5659_BIAS_CUR_CTRL_5:
830 case RT5659_BIAS_CUR_CTRL_6:
831 case RT5659_BIAS_CUR_CTRL_7:
832 case RT5659_BIAS_CUR_CTRL_8:
833 case RT5659_BIAS_CUR_CTRL_9:
834 case RT5659_BIAS_CUR_CTRL_10:
835 case RT5659_MEMORY_TEST:
836 case RT5659_VREF_REC_OP_FB_CAP_CTRL:
837 case RT5659_CLASSD_0:
838 case RT5659_CLASSD_1:
839 case RT5659_CLASSD_2:
840 case RT5659_CLASSD_3:
841 case RT5659_CLASSD_4:
842 case RT5659_CLASSD_5:
843 case RT5659_CLASSD_6:
844 case RT5659_CLASSD_7:
845 case RT5659_CLASSD_8:
846 case RT5659_CLASSD_9:
847 case RT5659_CLASSD_10:
848 case RT5659_CHARGE_PUMP_1:
849 case RT5659_CHARGE_PUMP_2:
850 case RT5659_DIG_IN_CTRL_1:
851 case RT5659_DIG_IN_CTRL_2:
852 case RT5659_PAD_DRIVING_CTRL:
853 case RT5659_SOFT_RAMP_DEPOP:
854 case RT5659_PLL:
855 case RT5659_CHOP_DAC:
856 case RT5659_CHOP_ADC:
857 case RT5659_CALIB_ADC_CTRL:
858 case RT5659_SOFT_RAMP_DEPOP_DAC_CLK_CTRL:
859 case RT5659_VOL_TEST:
860 case RT5659_TEST_MODE_CTRL_1:
861 case RT5659_TEST_MODE_CTRL_2:
862 case RT5659_TEST_MODE_CTRL_3:
863 case RT5659_TEST_MODE_CTRL_4:
864 case RT5659_BASSBACK_CTRL:
865 case RT5659_MP3_PLUS_CTRL_1:
866 case RT5659_MP3_PLUS_CTRL_2:
867 case RT5659_MP3_HPF_A1:
868 case RT5659_MP3_HPF_A2:
869 case RT5659_MP3_HPF_H0:
870 case RT5659_MP3_LPF_H0:
871 case RT5659_3D_SPK_CTRL:
872 case RT5659_3D_SPK_COEF_1:
873 case RT5659_3D_SPK_COEF_2:
874 case RT5659_3D_SPK_COEF_3:
875 case RT5659_3D_SPK_COEF_4:
876 case RT5659_3D_SPK_COEF_5:
877 case RT5659_3D_SPK_COEF_6:
878 case RT5659_3D_SPK_COEF_7:
879 case RT5659_STO_NG2_CTRL_1:
880 case RT5659_STO_NG2_CTRL_2:
881 case RT5659_STO_NG2_CTRL_3:
882 case RT5659_STO_NG2_CTRL_4:
883 case RT5659_STO_NG2_CTRL_5:
884 case RT5659_STO_NG2_CTRL_6:
885 case RT5659_STO_NG2_CTRL_7:
886 case RT5659_STO_NG2_CTRL_8:
887 case RT5659_MONO_NG2_CTRL_1:
888 case RT5659_MONO_NG2_CTRL_2:
889 case RT5659_MONO_NG2_CTRL_3:
890 case RT5659_MONO_NG2_CTRL_4:
891 case RT5659_MONO_NG2_CTRL_5:
892 case RT5659_MONO_NG2_CTRL_6:
893 case RT5659_MID_HP_AMP_DET:
894 case RT5659_LOW_HP_AMP_DET:
895 case RT5659_LDO_CTRL:
896 case RT5659_HP_DECROSS_CTRL_1:
897 case RT5659_HP_DECROSS_CTRL_2:
898 case RT5659_HP_DECROSS_CTRL_3:
899 case RT5659_HP_DECROSS_CTRL_4:
900 case RT5659_HP_IMP_SENS_CTRL_1:
901 case RT5659_HP_IMP_SENS_CTRL_2:
902 case RT5659_HP_IMP_SENS_CTRL_3:
903 case RT5659_HP_IMP_SENS_CTRL_4:
904 case RT5659_HP_IMP_SENS_MAP_1:
905 case RT5659_HP_IMP_SENS_MAP_2:
906 case RT5659_HP_IMP_SENS_MAP_3:
907 case RT5659_HP_IMP_SENS_MAP_4:
908 case RT5659_HP_IMP_SENS_MAP_5:
909 case RT5659_HP_IMP_SENS_MAP_6:
910 case RT5659_HP_IMP_SENS_MAP_7:
911 case RT5659_HP_IMP_SENS_MAP_8:
912 case RT5659_HP_LOGIC_CTRL_1:
913 case RT5659_HP_LOGIC_CTRL_2:
914 case RT5659_HP_CALIB_CTRL_1:
915 case RT5659_HP_CALIB_CTRL_2:
916 case RT5659_HP_CALIB_CTRL_3:
917 case RT5659_HP_CALIB_CTRL_4:
918 case RT5659_HP_CALIB_CTRL_5:
919 case RT5659_HP_CALIB_CTRL_6:
920 case RT5659_HP_CALIB_CTRL_7:
921 case RT5659_HP_CALIB_CTRL_9:
922 case RT5659_HP_CALIB_CTRL_10:
923 case RT5659_HP_CALIB_CTRL_11:
924 case RT5659_HP_CALIB_STA_1:
925 case RT5659_HP_CALIB_STA_2:
926 case RT5659_HP_CALIB_STA_3:
927 case RT5659_HP_CALIB_STA_4:
928 case RT5659_HP_CALIB_STA_5:
929 case RT5659_HP_CALIB_STA_6:
930 case RT5659_HP_CALIB_STA_7:
931 case RT5659_HP_CALIB_STA_8:
932 case RT5659_HP_CALIB_STA_9:
933 case RT5659_MONO_AMP_CALIB_CTRL_1:
934 case RT5659_MONO_AMP_CALIB_CTRL_2:
935 case RT5659_MONO_AMP_CALIB_CTRL_3:
936 case RT5659_MONO_AMP_CALIB_CTRL_4:
937 case RT5659_MONO_AMP_CALIB_CTRL_5:
938 case RT5659_MONO_AMP_CALIB_STA_1:
939 case RT5659_MONO_AMP_CALIB_STA_2:
940 case RT5659_MONO_AMP_CALIB_STA_3:
941 case RT5659_MONO_AMP_CALIB_STA_4:
942 case RT5659_SPK_PWR_LMT_CTRL_1:
943 case RT5659_SPK_PWR_LMT_CTRL_2:
944 case RT5659_SPK_PWR_LMT_CTRL_3:
945 case RT5659_SPK_PWR_LMT_STA_1:
946 case RT5659_SPK_PWR_LMT_STA_2:
947 case RT5659_SPK_PWR_LMT_STA_3:
948 case RT5659_SPK_PWR_LMT_STA_4:
949 case RT5659_SPK_PWR_LMT_STA_5:
950 case RT5659_SPK_PWR_LMT_STA_6:
951 case RT5659_FLEX_SPK_BST_CTRL_1:
952 case RT5659_FLEX_SPK_BST_CTRL_2:
953 case RT5659_FLEX_SPK_BST_CTRL_3:
954 case RT5659_FLEX_SPK_BST_CTRL_4:
955 case RT5659_SPK_EX_LMT_CTRL_1:
956 case RT5659_SPK_EX_LMT_CTRL_2:
957 case RT5659_SPK_EX_LMT_CTRL_3:
958 case RT5659_SPK_EX_LMT_CTRL_4:
959 case RT5659_SPK_EX_LMT_CTRL_5:
960 case RT5659_SPK_EX_LMT_CTRL_6:
961 case RT5659_SPK_EX_LMT_CTRL_7:
962 case RT5659_ADJ_HPF_CTRL_1:
963 case RT5659_ADJ_HPF_CTRL_2:
964 case RT5659_SPK_DC_CAILB_CTRL_1:
965 case RT5659_SPK_DC_CAILB_CTRL_2:
966 case RT5659_SPK_DC_CAILB_CTRL_3:
967 case RT5659_SPK_DC_CAILB_CTRL_4:
968 case RT5659_SPK_DC_CAILB_CTRL_5:
969 case RT5659_SPK_DC_CAILB_STA_1:
970 case RT5659_SPK_DC_CAILB_STA_2:
971 case RT5659_SPK_DC_CAILB_STA_3:
972 case RT5659_SPK_DC_CAILB_STA_4:
973 case RT5659_SPK_DC_CAILB_STA_5:
974 case RT5659_SPK_DC_CAILB_STA_6:
975 case RT5659_SPK_DC_CAILB_STA_7:
976 case RT5659_SPK_DC_CAILB_STA_8:
977 case RT5659_SPK_DC_CAILB_STA_9:
978 case RT5659_SPK_DC_CAILB_STA_10:
979 case RT5659_SPK_VDD_STA_1:
980 case RT5659_SPK_VDD_STA_2:
981 case RT5659_SPK_DC_DET_CTRL_1:
982 case RT5659_SPK_DC_DET_CTRL_2:
983 case RT5659_SPK_DC_DET_CTRL_3:
984 case RT5659_PURE_DC_DET_CTRL_1:
985 case RT5659_PURE_DC_DET_CTRL_2:
986 case RT5659_DUMMY_4:
987 case RT5659_DUMMY_5:
988 case RT5659_DUMMY_6:
989 case RT5659_DRC1_CTRL_1:
990 case RT5659_DRC1_CTRL_2:
991 case RT5659_DRC1_CTRL_3:
992 case RT5659_DRC1_CTRL_4:
993 case RT5659_DRC1_CTRL_5:
994 case RT5659_DRC1_CTRL_6:
995 case RT5659_DRC1_HARD_LMT_CTRL_1:
996 case RT5659_DRC1_HARD_LMT_CTRL_2:
997 case RT5659_DRC2_CTRL_1:
998 case RT5659_DRC2_CTRL_2:
999 case RT5659_DRC2_CTRL_3:
1000 case RT5659_DRC2_CTRL_4:
1001 case RT5659_DRC2_CTRL_5:
1002 case RT5659_DRC2_CTRL_6:
1003 case RT5659_DRC2_HARD_LMT_CTRL_1:
1004 case RT5659_DRC2_HARD_LMT_CTRL_2:
1005 case RT5659_DRC1_PRIV_1:
1006 case RT5659_DRC1_PRIV_2:
1007 case RT5659_DRC1_PRIV_3:
1008 case RT5659_DRC1_PRIV_4:
1009 case RT5659_DRC1_PRIV_5:
1010 case RT5659_DRC1_PRIV_6:
1011 case RT5659_DRC1_PRIV_7:
1012 case RT5659_DRC2_PRIV_1:
1013 case RT5659_DRC2_PRIV_2:
1014 case RT5659_DRC2_PRIV_3:
1015 case RT5659_DRC2_PRIV_4:
1016 case RT5659_DRC2_PRIV_5:
1017 case RT5659_DRC2_PRIV_6:
1018 case RT5659_DRC2_PRIV_7:
1019 case RT5659_MULTI_DRC_CTRL:
1020 case RT5659_CROSS_OVER_1:
1021 case RT5659_CROSS_OVER_2:
1022 case RT5659_CROSS_OVER_3:
1023 case RT5659_CROSS_OVER_4:
1024 case RT5659_CROSS_OVER_5:
1025 case RT5659_CROSS_OVER_6:
1026 case RT5659_CROSS_OVER_7:
1027 case RT5659_CROSS_OVER_8:
1028 case RT5659_CROSS_OVER_9:
1029 case RT5659_CROSS_OVER_10:
1030 case RT5659_ALC_PGA_CTRL_1:
1031 case RT5659_ALC_PGA_CTRL_2:
1032 case RT5659_ALC_PGA_CTRL_3:
1033 case RT5659_ALC_PGA_CTRL_4:
1034 case RT5659_ALC_PGA_CTRL_5:
1035 case RT5659_ALC_PGA_CTRL_6:
1036 case RT5659_ALC_PGA_CTRL_7:
1037 case RT5659_ALC_PGA_CTRL_8:
1038 case RT5659_ALC_PGA_STA_1:
1039 case RT5659_ALC_PGA_STA_2:
1040 case RT5659_ALC_PGA_STA_3:
1041 case RT5659_DAC_L_EQ_PRE_VOL:
1042 case RT5659_DAC_R_EQ_PRE_VOL:
1043 case RT5659_DAC_L_EQ_POST_VOL:
1044 case RT5659_DAC_R_EQ_POST_VOL:
1045 case RT5659_DAC_L_EQ_LPF1_A1:
1046 case RT5659_DAC_L_EQ_LPF1_H0:
1047 case RT5659_DAC_R_EQ_LPF1_A1:
1048 case RT5659_DAC_R_EQ_LPF1_H0:
1049 case RT5659_DAC_L_EQ_BPF2_A1:
1050 case RT5659_DAC_L_EQ_BPF2_A2:
1051 case RT5659_DAC_L_EQ_BPF2_H0:
1052 case RT5659_DAC_R_EQ_BPF2_A1:
1053 case RT5659_DAC_R_EQ_BPF2_A2:
1054 case RT5659_DAC_R_EQ_BPF2_H0:
1055 case RT5659_DAC_L_EQ_BPF3_A1:
1056 case RT5659_DAC_L_EQ_BPF3_A2:
1057 case RT5659_DAC_L_EQ_BPF3_H0:
1058 case RT5659_DAC_R_EQ_BPF3_A1:
1059 case RT5659_DAC_R_EQ_BPF3_A2:
1060 case RT5659_DAC_R_EQ_BPF3_H0:
1061 case RT5659_DAC_L_EQ_BPF4_A1:
1062 case RT5659_DAC_L_EQ_BPF4_A2:
1063 case RT5659_DAC_L_EQ_BPF4_H0:
1064 case RT5659_DAC_R_EQ_BPF4_A1:
1065 case RT5659_DAC_R_EQ_BPF4_A2:
1066 case RT5659_DAC_R_EQ_BPF4_H0:
1067 case RT5659_DAC_L_EQ_HPF1_A1:
1068 case RT5659_DAC_L_EQ_HPF1_H0:
1069 case RT5659_DAC_R_EQ_HPF1_A1:
1070 case RT5659_DAC_R_EQ_HPF1_H0:
1071 case RT5659_DAC_L_EQ_HPF2_A1:
1072 case RT5659_DAC_L_EQ_HPF2_A2:
1073 case RT5659_DAC_L_EQ_HPF2_H0:
1074 case RT5659_DAC_R_EQ_HPF2_A1:
1075 case RT5659_DAC_R_EQ_HPF2_A2:
1076 case RT5659_DAC_R_EQ_HPF2_H0:
1077 case RT5659_DAC_L_BI_EQ_BPF1_H0_1:
1078 case RT5659_DAC_L_BI_EQ_BPF1_H0_2:
1079 case RT5659_DAC_L_BI_EQ_BPF1_B1_1:
1080 case RT5659_DAC_L_BI_EQ_BPF1_B1_2:
1081 case RT5659_DAC_L_BI_EQ_BPF1_B2_1:
1082 case RT5659_DAC_L_BI_EQ_BPF1_B2_2:
1083 case RT5659_DAC_L_BI_EQ_BPF1_A1_1:
1084 case RT5659_DAC_L_BI_EQ_BPF1_A1_2:
1085 case RT5659_DAC_L_BI_EQ_BPF1_A2_1:
1086 case RT5659_DAC_L_BI_EQ_BPF1_A2_2:
1087 case RT5659_DAC_R_BI_EQ_BPF1_H0_1:
1088 case RT5659_DAC_R_BI_EQ_BPF1_H0_2:
1089 case RT5659_DAC_R_BI_EQ_BPF1_B1_1:
1090 case RT5659_DAC_R_BI_EQ_BPF1_B1_2:
1091 case RT5659_DAC_R_BI_EQ_BPF1_B2_1:
1092 case RT5659_DAC_R_BI_EQ_BPF1_B2_2:
1093 case RT5659_DAC_R_BI_EQ_BPF1_A1_1:
1094 case RT5659_DAC_R_BI_EQ_BPF1_A1_2:
1095 case RT5659_DAC_R_BI_EQ_BPF1_A2_1:
1096 case RT5659_DAC_R_BI_EQ_BPF1_A2_2:
1097 case RT5659_ADC_L_EQ_LPF1_A1:
1098 case RT5659_ADC_R_EQ_LPF1_A1:
1099 case RT5659_ADC_L_EQ_LPF1_H0:
1100 case RT5659_ADC_R_EQ_LPF1_H0:
1101 case RT5659_ADC_L_EQ_BPF1_A1:
1102 case RT5659_ADC_R_EQ_BPF1_A1:
1103 case RT5659_ADC_L_EQ_BPF1_A2:
1104 case RT5659_ADC_R_EQ_BPF1_A2:
1105 case RT5659_ADC_L_EQ_BPF1_H0:
1106 case RT5659_ADC_R_EQ_BPF1_H0:
1107 case RT5659_ADC_L_EQ_BPF2_A1:
1108 case RT5659_ADC_R_EQ_BPF2_A1:
1109 case RT5659_ADC_L_EQ_BPF2_A2:
1110 case RT5659_ADC_R_EQ_BPF2_A2:
1111 case RT5659_ADC_L_EQ_BPF2_H0:
1112 case RT5659_ADC_R_EQ_BPF2_H0:
1113 case RT5659_ADC_L_EQ_BPF3_A1:
1114 case RT5659_ADC_R_EQ_BPF3_A1:
1115 case RT5659_ADC_L_EQ_BPF3_A2:
1116 case RT5659_ADC_R_EQ_BPF3_A2:
1117 case RT5659_ADC_L_EQ_BPF3_H0:
1118 case RT5659_ADC_R_EQ_BPF3_H0:
1119 case RT5659_ADC_L_EQ_BPF4_A1:
1120 case RT5659_ADC_R_EQ_BPF4_A1:
1121 case RT5659_ADC_L_EQ_BPF4_A2:
1122 case RT5659_ADC_R_EQ_BPF4_A2:
1123 case RT5659_ADC_L_EQ_BPF4_H0:
1124 case RT5659_ADC_R_EQ_BPF4_H0:
1125 case RT5659_ADC_L_EQ_HPF1_A1:
1126 case RT5659_ADC_R_EQ_HPF1_A1:
1127 case RT5659_ADC_L_EQ_HPF1_H0:
1128 case RT5659_ADC_R_EQ_HPF1_H0:
1129 case RT5659_ADC_L_EQ_PRE_VOL:
1130 case RT5659_ADC_R_EQ_PRE_VOL:
1131 case RT5659_ADC_L_EQ_POST_VOL:
1132 case RT5659_ADC_R_EQ_POST_VOL:
1133 return true;
1134 default:
1135 return false;
1136 }
1137}
1138
1139static const DECLARE_TLV_DB_SCALE(hp_vol_tlv, -2325, 75, 0);
1140static const DECLARE_TLV_DB_SCALE(out_vol_tlv, -4650, 150, 0);
1141static const DECLARE_TLV_DB_SCALE(dac_vol_tlv, -65625, 375, 0);
1142static const DECLARE_TLV_DB_SCALE(in_vol_tlv, -3450, 150, 0);
1143static const DECLARE_TLV_DB_SCALE(adc_vol_tlv, -17625, 375, 0);
1144static const DECLARE_TLV_DB_SCALE(adc_bst_tlv, 0, 1200, 0);
1145static const DECLARE_TLV_DB_SCALE(in_bst_tlv, -1200, 75, 0);
1146
1147/* Interface data select */
1148static const char * const rt5659_data_select[] = {
1149 "L/R", "R/L", "L/L", "R/R"
1150};
1151
1152static const SOC_ENUM_SINGLE_DECL(rt5659_if1_01_adc_enum,
1153 RT5659_TDM_CTRL_2, RT5659_DS_ADC_SLOT01_SFT, rt5659_data_select);
1154
1155static const SOC_ENUM_SINGLE_DECL(rt5659_if1_23_adc_enum,
1156 RT5659_TDM_CTRL_2, RT5659_DS_ADC_SLOT23_SFT, rt5659_data_select);
1157
1158static const SOC_ENUM_SINGLE_DECL(rt5659_if1_45_adc_enum,
1159 RT5659_TDM_CTRL_2, RT5659_DS_ADC_SLOT45_SFT, rt5659_data_select);
1160
1161static const SOC_ENUM_SINGLE_DECL(rt5659_if1_67_adc_enum,
1162 RT5659_TDM_CTRL_2, RT5659_DS_ADC_SLOT67_SFT, rt5659_data_select);
1163
1164static const SOC_ENUM_SINGLE_DECL(rt5659_if2_dac_enum,
1165 RT5659_DIG_INF23_DATA, RT5659_IF2_DAC_SEL_SFT, rt5659_data_select);
1166
1167static const SOC_ENUM_SINGLE_DECL(rt5659_if2_adc_enum,
1168 RT5659_DIG_INF23_DATA, RT5659_IF2_ADC_SEL_SFT, rt5659_data_select);
1169
1170static const SOC_ENUM_SINGLE_DECL(rt5659_if3_dac_enum,
1171 RT5659_DIG_INF23_DATA, RT5659_IF3_DAC_SEL_SFT, rt5659_data_select);
1172
1173static const SOC_ENUM_SINGLE_DECL(rt5659_if3_adc_enum,
1174 RT5659_DIG_INF23_DATA, RT5659_IF3_ADC_SEL_SFT, rt5659_data_select);
1175
1176static const struct snd_kcontrol_new rt5659_if1_01_adc_swap_mux =
1177 SOC_DAPM_ENUM("IF1 01 ADC Swap Source", rt5659_if1_01_adc_enum);
1178
1179static const struct snd_kcontrol_new rt5659_if1_23_adc_swap_mux =
1180 SOC_DAPM_ENUM("IF1 23 ADC1 Swap Source", rt5659_if1_23_adc_enum);
1181
1182static const struct snd_kcontrol_new rt5659_if1_45_adc_swap_mux =
1183 SOC_DAPM_ENUM("IF1 45 ADC1 Swap Source", rt5659_if1_45_adc_enum);
1184
1185static const struct snd_kcontrol_new rt5659_if1_67_adc_swap_mux =
1186 SOC_DAPM_ENUM("IF1 67 ADC1 Swap Source", rt5659_if1_67_adc_enum);
1187
1188static const struct snd_kcontrol_new rt5659_if2_dac_swap_mux =
1189 SOC_DAPM_ENUM("IF2 DAC Swap Source", rt5659_if2_dac_enum);
1190
1191static const struct snd_kcontrol_new rt5659_if2_adc_swap_mux =
1192 SOC_DAPM_ENUM("IF2 ADC Swap Source", rt5659_if2_adc_enum);
1193
1194static const struct snd_kcontrol_new rt5659_if3_dac_swap_mux =
1195 SOC_DAPM_ENUM("IF3 DAC Swap Source", rt5659_if3_dac_enum);
1196
1197static const struct snd_kcontrol_new rt5659_if3_adc_swap_mux =
1198 SOC_DAPM_ENUM("IF3 ADC Swap Source", rt5659_if3_adc_enum);
1199
1200static const char * const rt5659_asrc_clk_src[] = {
1201 "clk_sysy_div_out", "clk_i2s1_track", "clk_i2s2_track",
1202 "clk_i2s3_track", "clk_sys2", "clk_sys3"
1203};
1204
1205static unsigned int rt5659_asrc_clk_map_values[] = {
1206 0, 1, 2, 3, 5, 6,
1207};
1208
1209static const SOC_VALUE_ENUM_SINGLE_DECL(
1210 rt5659_da_sto_asrc_enum, RT5659_ASRC_2, RT5659_DA_STO_T_SFT, 0x7,
1211 rt5659_asrc_clk_src, rt5659_asrc_clk_map_values);
1212
1213static const SOC_VALUE_ENUM_SINGLE_DECL(
1214 rt5659_da_monol_asrc_enum, RT5659_ASRC_2, RT5659_DA_MONO_L_T_SFT, 0x7,
1215 rt5659_asrc_clk_src, rt5659_asrc_clk_map_values);
1216
1217static const SOC_VALUE_ENUM_SINGLE_DECL(
1218 rt5659_da_monor_asrc_enum, RT5659_ASRC_2, RT5659_DA_MONO_R_T_SFT, 0x7,
1219 rt5659_asrc_clk_src, rt5659_asrc_clk_map_values);
1220
1221static const SOC_VALUE_ENUM_SINGLE_DECL(
1222 rt5659_ad_sto1_asrc_enum, RT5659_ASRC_2, RT5659_AD_STO1_T_SFT, 0x7,
1223 rt5659_asrc_clk_src, rt5659_asrc_clk_map_values);
1224
1225static const SOC_VALUE_ENUM_SINGLE_DECL(
1226 rt5659_ad_sto2_asrc_enum, RT5659_ASRC_3, RT5659_AD_STO2_T_SFT, 0x7,
1227 rt5659_asrc_clk_src, rt5659_asrc_clk_map_values);
1228
1229static const SOC_VALUE_ENUM_SINGLE_DECL(
1230 rt5659_ad_monol_asrc_enum, RT5659_ASRC_3, RT5659_AD_MONO_L_T_SFT, 0x7,
1231 rt5659_asrc_clk_src, rt5659_asrc_clk_map_values);
1232
1233static const SOC_VALUE_ENUM_SINGLE_DECL(
1234 rt5659_ad_monor_asrc_enum, RT5659_ASRC_3, RT5659_AD_MONO_R_T_SFT, 0x7,
1235 rt5659_asrc_clk_src, rt5659_asrc_clk_map_values);
1236
1237static int rt5659_hp_vol_put(struct snd_kcontrol *kcontrol,
1238 struct snd_ctl_elem_value *ucontrol)
1239{
1240 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
1241 int ret = snd_soc_put_volsw(kcontrol, ucontrol);
1242
1243 if (snd_soc_read(codec, RT5659_STO_NG2_CTRL_1) & RT5659_NG2_EN) {
1244 snd_soc_update_bits(codec, RT5659_STO_NG2_CTRL_1,
1245 RT5659_NG2_EN_MASK, RT5659_NG2_DIS);
1246 snd_soc_update_bits(codec, RT5659_STO_NG2_CTRL_1,
1247 RT5659_NG2_EN_MASK, RT5659_NG2_EN);
1248 }
1249
1250 return ret;
1251}
1252
1253static void rt5659_enable_push_button_irq(struct snd_soc_codec *codec,
1254 bool enable)
1255{
1256 struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
1257
1258 if (enable) {
1259 snd_soc_write(codec, RT5659_4BTN_IL_CMD_1, 0x000b);
1260
1261 /* MICBIAS1 and Mic Det Power for button detect*/
1262 snd_soc_dapm_force_enable_pin(dapm, "MICBIAS1");
1263 snd_soc_dapm_force_enable_pin(dapm,
1264 "Mic Det Power");
1265 snd_soc_dapm_sync(dapm);
1266
1267 snd_soc_update_bits(codec, RT5659_PWR_ANLG_2,
1268 RT5659_PWR_MB1, RT5659_PWR_MB1);
1269 snd_soc_update_bits(codec, RT5659_PWR_VOL,
1270 RT5659_PWR_MIC_DET, RT5659_PWR_MIC_DET);
1271
1272 snd_soc_update_bits(codec, RT5659_IRQ_CTRL_2,
1273 RT5659_IL_IRQ_MASK, RT5659_IL_IRQ_EN);
1274 snd_soc_update_bits(codec, RT5659_4BTN_IL_CMD_2,
1275 RT5659_4BTN_IL_MASK, RT5659_4BTN_IL_EN);
1276 } else {
1277 snd_soc_update_bits(codec, RT5659_4BTN_IL_CMD_2,
1278 RT5659_4BTN_IL_MASK, RT5659_4BTN_IL_DIS);
1279 snd_soc_update_bits(codec, RT5659_IRQ_CTRL_2,
1280 RT5659_IL_IRQ_MASK, RT5659_IL_IRQ_DIS);
1281 /* MICBIAS1 and Mic Det Power for button detect*/
1282 snd_soc_dapm_disable_pin(dapm, "MICBIAS1");
1283 snd_soc_dapm_disable_pin(dapm, "Mic Det Power");
1284 snd_soc_dapm_sync(dapm);
1285 }
1286}
1287
1288/**
1289 * rt5659_headset_detect - Detect headset.
1290 * @codec: SoC audio codec device.
1291 * @jack_insert: Jack insert or not.
1292 *
1293 * Detect whether is headset or not when jack inserted.
1294 *
1295 * Returns detect status.
1296 */
1297
1298static int rt5659_headset_detect(struct snd_soc_codec *codec, int jack_insert)
1299{
1300 struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
1301 int val, i = 0, sleep_time[5] = {300, 150, 100, 50, 30};
1302 int reg_63;
1303
1304 struct rt5659_priv *rt5659 = snd_soc_codec_get_drvdata(codec);
1305
1306 if (jack_insert) {
1307 snd_soc_dapm_force_enable_pin(dapm,
1308 "Mic Det Power");
1309 snd_soc_dapm_sync(dapm);
1310 reg_63 = snd_soc_read(codec, RT5659_PWR_ANLG_1);
1311
1312 snd_soc_update_bits(codec, RT5659_PWR_ANLG_1,
1313 RT5659_PWR_VREF2 | RT5659_PWR_MB,
1314 RT5659_PWR_VREF2 | RT5659_PWR_MB);
1315 msleep(20);
1316 snd_soc_update_bits(codec, RT5659_PWR_ANLG_1,
1317 RT5659_PWR_FV2, RT5659_PWR_FV2);
1318
1319 snd_soc_write(codec, RT5659_EJD_CTRL_2, 0x4160);
1320 snd_soc_update_bits(codec, RT5659_EJD_CTRL_1,
1321 0x20, 0x0);
1322 msleep(20);
1323 snd_soc_update_bits(codec, RT5659_EJD_CTRL_1,
1324 0x20, 0x20);
1325
1326 while (i < 5) {
1327 msleep(sleep_time[i]);
1328 val = snd_soc_read(codec, RT5659_EJD_CTRL_2) & 0x0003;
1329 i++;
1330 if (val == 0x1 || val == 0x2 || val == 0x3)
1331 break;
1332 }
1333
1334 switch (val) {
1335 case 1:
1336 rt5659->jack_type = SND_JACK_HEADSET;
1337 rt5659_enable_push_button_irq(codec, true);
1338 break;
1339 default:
1340 snd_soc_write(codec, RT5659_PWR_ANLG_1, reg_63);
1341 rt5659->jack_type = SND_JACK_HEADPHONE;
1342 snd_soc_dapm_disable_pin(dapm, "Mic Det Power");
1343 snd_soc_dapm_sync(dapm);
1344 break;
1345 }
1346 } else {
1347 snd_soc_dapm_disable_pin(dapm, "Mic Det Power");
1348 snd_soc_dapm_sync(dapm);
1349 if (rt5659->jack_type == SND_JACK_HEADSET)
1350 rt5659_enable_push_button_irq(codec, false);
1351 rt5659->jack_type = 0;
1352 }
1353
1354 dev_dbg(codec->dev, "jack_type = %d\n", rt5659->jack_type);
1355 return rt5659->jack_type;
1356}
1357
1358static int rt5659_button_detect(struct snd_soc_codec *codec)
1359{
1360 int btn_type, val;
1361
1362 val = snd_soc_read(codec, RT5659_4BTN_IL_CMD_1);
1363 btn_type = val & 0xfff0;
1364 snd_soc_write(codec, RT5659_4BTN_IL_CMD_1, val);
1365
1366 return btn_type;
1367}
1368
1369static irqreturn_t rt5659_irq(int irq, void *data)
1370{
1371 struct rt5659_priv *rt5659 = data;
1372
1373 queue_delayed_work(system_power_efficient_wq,
1374 &rt5659->jack_detect_work, msecs_to_jiffies(250));
1375
1376 return IRQ_HANDLED;
1377}
1378
1379int rt5659_set_jack_detect(struct snd_soc_codec *codec,
1380 struct snd_soc_jack *hs_jack)
1381{
1382 struct rt5659_priv *rt5659 = snd_soc_codec_get_drvdata(codec);
1383
1384 rt5659->hs_jack = hs_jack;
1385
1386 rt5659_irq(0, rt5659);
1387
1388 return 0;
1389}
1390EXPORT_SYMBOL_GPL(rt5659_set_jack_detect);
1391
1392static void rt5659_jack_detect_work(struct work_struct *work)
1393{
1394 struct rt5659_priv *rt5659 =
1395 container_of(work, struct rt5659_priv, jack_detect_work.work);
1396 int val, btn_type, report = 0;
1397
1398 if (!rt5659->codec)
1399 return;
1400
1401 val = snd_soc_read(rt5659->codec, RT5659_INT_ST_1) & 0x0080;
1402 if (!val) {
1403 /* jack in */
1404 if (rt5659->jack_type == 0) {
1405 /* jack was out, report jack type */
1406 report = rt5659_headset_detect(rt5659->codec, 1);
1407 } else {
1408 /* jack is already in, report button event */
1409 report = SND_JACK_HEADSET;
1410 btn_type = rt5659_button_detect(rt5659->codec);
1411 /**
1412 * rt5659 can report three kinds of button behavior,
1413 * one click, double click and hold. However,
1414 * currently we will report button pressed/released
1415 * event. So all the three button behaviors are
1416 * treated as button pressed.
1417 */
1418 switch (btn_type) {
1419 case 0x8000:
1420 case 0x4000:
1421 case 0x2000:
1422 report |= SND_JACK_BTN_0;
1423 break;
1424 case 0x1000:
1425 case 0x0800:
1426 case 0x0400:
1427 report |= SND_JACK_BTN_1;
1428 break;
1429 case 0x0200:
1430 case 0x0100:
1431 case 0x0080:
1432 report |= SND_JACK_BTN_2;
1433 break;
1434 case 0x0040:
1435 case 0x0020:
1436 case 0x0010:
1437 report |= SND_JACK_BTN_3;
1438 break;
1439 case 0x0000: /* unpressed */
1440 break;
1441 default:
1442 btn_type = 0;
1443 dev_err(rt5659->codec->dev,
1444 "Unexpected button code 0x%04x\n",
1445 btn_type);
1446 break;
1447 }
1448
1449 /* button release or spurious interrput*/
1450 if (btn_type == 0)
1451 report = rt5659->jack_type;
1452 }
1453 } else {
1454 /* jack out */
1455 report = rt5659_headset_detect(rt5659->codec, 0);
1456 }
1457
1458 snd_soc_jack_report(rt5659->hs_jack, report, SND_JACK_HEADSET |
1459 SND_JACK_BTN_0 | SND_JACK_BTN_1 |
1460 SND_JACK_BTN_2 | SND_JACK_BTN_3);
1461}
1462
1463static const struct snd_kcontrol_new rt5659_snd_controls[] = {
1464 /* Speaker Output Volume */
1465 SOC_DOUBLE_TLV("Speaker Playback Volume", RT5659_SPO_VOL,
1466 RT5659_L_VOL_SFT, RT5659_R_VOL_SFT, 39, 1, out_vol_tlv),
1467
1468 /* Headphone Output Volume */
1469 SOC_DOUBLE_R_EXT_TLV("Headphone Playback Volume", RT5659_HPL_GAIN,
1470 RT5659_HPR_GAIN, RT5659_G_HP_SFT, 31, 1, snd_soc_get_volsw,
1471 rt5659_hp_vol_put, hp_vol_tlv),
1472
1473 /* Mono Output Volume */
1474 SOC_SINGLE_TLV("Mono Playback Volume", RT5659_MONO_OUT,
1475 RT5659_L_VOL_SFT, 39, 1, out_vol_tlv),
1476
1477 /* Output Volume */
1478 SOC_DOUBLE_TLV("OUT Playback Volume", RT5659_LOUT,
1479 RT5659_L_VOL_SFT, RT5659_R_VOL_SFT, 39, 1, out_vol_tlv),
1480
1481 /* DAC Digital Volume */
1482 SOC_DOUBLE_TLV("DAC1 Playback Volume", RT5659_DAC1_DIG_VOL,
1483 RT5659_L_VOL_SFT, RT5659_R_VOL_SFT, 175, 0, dac_vol_tlv),
1484 SOC_DOUBLE("DAC1 Playback Switch", RT5659_AD_DA_MIXER,
1485 RT5659_M_DAC1_L_SFT, RT5659_M_DAC1_R_SFT, 1, 1),
1486
1487 SOC_DOUBLE_TLV("DAC2 Playback Volume", RT5659_DAC2_DIG_VOL,
1488 RT5659_L_VOL_SFT, RT5659_R_VOL_SFT, 175, 0, dac_vol_tlv),
1489 SOC_DOUBLE("DAC2 Playback Switch", RT5659_DAC_CTRL,
1490 RT5659_M_DAC2_L_VOL_SFT, RT5659_M_DAC2_R_VOL_SFT, 1, 1),
1491
1492 /* IN1/IN2/IN3/IN4 Volume */
1493 SOC_SINGLE_TLV("IN1 Boost Volume", RT5659_IN1_IN2,
1494 RT5659_BST1_SFT, 69, 0, in_bst_tlv),
1495 SOC_SINGLE_TLV("IN2 Boost Volume", RT5659_IN1_IN2,
1496 RT5659_BST2_SFT, 69, 0, in_bst_tlv),
1497 SOC_SINGLE_TLV("IN3 Boost Volume", RT5659_IN3_IN4,
1498 RT5659_BST3_SFT, 69, 0, in_bst_tlv),
1499 SOC_SINGLE_TLV("IN4 Boost Volume", RT5659_IN3_IN4,
1500 RT5659_BST4_SFT, 69, 0, in_bst_tlv),
1501
1502 /* INL/INR Volume Control */
1503 SOC_DOUBLE_TLV("IN Capture Volume", RT5659_INL1_INR1_VOL,
1504 RT5659_INL_VOL_SFT, RT5659_INR_VOL_SFT, 31, 1, in_vol_tlv),
1505
1506 /* ADC Digital Volume Control */
1507 SOC_DOUBLE("STO1 ADC Capture Switch", RT5659_STO1_ADC_DIG_VOL,
1508 RT5659_L_MUTE_SFT, RT5659_R_MUTE_SFT, 1, 1),
1509 SOC_DOUBLE_TLV("STO1 ADC Capture Volume", RT5659_STO1_ADC_DIG_VOL,
1510 RT5659_L_VOL_SFT, RT5659_R_VOL_SFT, 127, 0, adc_vol_tlv),
1511 SOC_DOUBLE("Mono ADC Capture Switch", RT5659_MONO_ADC_DIG_VOL,
1512 RT5659_L_MUTE_SFT, RT5659_R_MUTE_SFT, 1, 1),
1513 SOC_DOUBLE_TLV("Mono ADC Capture Volume", RT5659_MONO_ADC_DIG_VOL,
1514 RT5659_L_VOL_SFT, RT5659_R_VOL_SFT, 127, 0, adc_vol_tlv),
1515 SOC_DOUBLE("STO2 ADC Capture Switch", RT5659_STO2_ADC_DIG_VOL,
1516 RT5659_L_MUTE_SFT, RT5659_R_MUTE_SFT, 1, 1),
1517 SOC_DOUBLE_TLV("STO2 ADC Capture Volume", RT5659_STO2_ADC_DIG_VOL,
1518 RT5659_L_VOL_SFT, RT5659_R_VOL_SFT, 127, 0, adc_vol_tlv),
1519
1520 /* ADC Boost Volume Control */
1521 SOC_DOUBLE_TLV("STO1 ADC Boost Gain Volume", RT5659_STO1_BOOST,
1522 RT5659_STO1_ADC_L_BST_SFT, RT5659_STO1_ADC_R_BST_SFT,
1523 3, 0, adc_bst_tlv),
1524
1525 SOC_DOUBLE_TLV("Mono ADC Boost Gain Volume", RT5659_MONO_BOOST,
1526 RT5659_MONO_ADC_L_BST_SFT, RT5659_MONO_ADC_R_BST_SFT,
1527 3, 0, adc_bst_tlv),
1528
1529 SOC_DOUBLE_TLV("STO2 ADC Boost Gain Volume", RT5659_STO2_BOOST,
1530 RT5659_STO2_ADC_L_BST_SFT, RT5659_STO2_ADC_R_BST_SFT,
1531 3, 0, adc_bst_tlv),
1532
1533 SOC_SINGLE("DAC IF1 DAC1 L Data Switch", RT5659_TDM_CTRL_4, 12, 7, 0),
1534 SOC_SINGLE("DAC IF1 DAC1 R Data Switch", RT5659_TDM_CTRL_4, 8, 7, 0),
1535 SOC_SINGLE("DAC IF1 DAC2 L Data Switch", RT5659_TDM_CTRL_4, 4, 7, 0),
1536 SOC_SINGLE("DAC IF1 DAC2 R Data Switch", RT5659_TDM_CTRL_4, 0, 7, 0),
1537};
1538
1539/**
1540 * set_dmic_clk - Set parameter of dmic.
1541 *
1542 * @w: DAPM widget.
1543 * @kcontrol: The kcontrol of this widget.
1544 * @event: Event id.
1545 *
1546 * Choose dmic clock between 1MHz and 3MHz.
1547 * It is better for clock to approximate 3MHz.
1548 */
1549static int set_dmic_clk(struct snd_soc_dapm_widget *w,
1550 struct snd_kcontrol *kcontrol, int event)
1551{
1552 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
1553 struct rt5659_priv *rt5659 = snd_soc_codec_get_drvdata(codec);
1554 int pd, idx = -EINVAL;
1555
1556 pd = rl6231_get_pre_div(rt5659->regmap,
1557 RT5659_ADDA_CLK_1, RT5659_I2S_PD1_SFT);
1558 idx = rl6231_calc_dmic_clk(rt5659->sysclk / pd);
1559
1560 if (idx < 0)
1561 dev_err(codec->dev, "Failed to set DMIC clock\n");
1562 else {
1563 snd_soc_update_bits(codec, RT5659_DMIC_CTRL_1,
1564 RT5659_DMIC_CLK_MASK, idx << RT5659_DMIC_CLK_SFT);
1565 }
1566 return idx;
1567}
1568
1569static int set_adc_clk(struct snd_soc_dapm_widget *w,
1570 struct snd_kcontrol *kcontrol, int event)
1571{
1572 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
1573
1574 switch (event) {
1575 case SND_SOC_DAPM_POST_PMU:
1576 snd_soc_update_bits(codec, RT5659_CHOP_ADC,
1577 RT5659_CKXEN_ADCC_MASK | RT5659_CKGEN_ADCC_MASK,
1578 RT5659_CKXEN_ADCC_MASK | RT5659_CKGEN_ADCC_MASK);
1579 break;
1580
1581 case SND_SOC_DAPM_PRE_PMD:
1582 snd_soc_update_bits(codec, RT5659_CHOP_ADC,
1583 RT5659_CKXEN_ADCC_MASK | RT5659_CKGEN_ADCC_MASK, 0);
1584 break;
1585
1586 default:
1587 return 0;
1588 }
1589
1590 return 0;
1591
1592}
1593
1594static int rt5659_charge_pump_event(struct snd_soc_dapm_widget *w,
1595 struct snd_kcontrol *kcontrol, int event)
1596{
1597 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
1598
1599 switch (event) {
1600 case SND_SOC_DAPM_PRE_PMU:
1601 /* Depop */
1602 snd_soc_write(codec, RT5659_DEPOP_1, 0x0009);
1603 break;
1604 case SND_SOC_DAPM_POST_PMD:
1605 snd_soc_write(codec, RT5659_HP_CHARGE_PUMP_1, 0x0c16);
1606 break;
1607 default:
1608 return 0;
1609 }
1610
1611 return 0;
1612}
1613
1614static int is_sys_clk_from_pll(struct snd_soc_dapm_widget *w,
1615 struct snd_soc_dapm_widget *sink)
1616{
1617 unsigned int val;
1618 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
1619
1620 val = snd_soc_read(codec, RT5659_GLB_CLK);
1621 val &= RT5659_SCLK_SRC_MASK;
1622 if (val == RT5659_SCLK_SRC_PLL1)
1623 return 1;
1624 else
1625 return 0;
1626}
1627
1628static int is_using_asrc(struct snd_soc_dapm_widget *w,
1629 struct snd_soc_dapm_widget *sink)
1630{
1631 unsigned int reg, shift, val;
1632 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
1633
1634 switch (w->shift) {
1635 case RT5659_ADC_MONO_R_ASRC_SFT:
1636 reg = RT5659_ASRC_3;
1637 shift = RT5659_AD_MONO_R_T_SFT;
1638 break;
1639 case RT5659_ADC_MONO_L_ASRC_SFT:
1640 reg = RT5659_ASRC_3;
1641 shift = RT5659_AD_MONO_L_T_SFT;
1642 break;
1643 case RT5659_ADC_STO1_ASRC_SFT:
1644 reg = RT5659_ASRC_2;
1645 shift = RT5659_AD_STO1_T_SFT;
1646 break;
1647 case RT5659_DAC_MONO_R_ASRC_SFT:
1648 reg = RT5659_ASRC_2;
1649 shift = RT5659_DA_MONO_R_T_SFT;
1650 break;
1651 case RT5659_DAC_MONO_L_ASRC_SFT:
1652 reg = RT5659_ASRC_2;
1653 shift = RT5659_DA_MONO_L_T_SFT;
1654 break;
1655 case RT5659_DAC_STO_ASRC_SFT:
1656 reg = RT5659_ASRC_2;
1657 shift = RT5659_DA_STO_T_SFT;
1658 break;
1659 default:
1660 return 0;
1661 }
1662
1663 val = (snd_soc_read(codec, reg) >> shift) & 0xf;
1664 switch (val) {
1665 case 1:
1666 case 2:
1667 case 3:
1668 /* I2S_Pre_Div1 should be 1 in asrc mode */
1669 snd_soc_update_bits(codec, RT5659_ADDA_CLK_1,
1670 RT5659_I2S_PD1_MASK, RT5659_I2S_PD1_2);
1671 return 1;
1672 default:
1673 return 0;
1674 }
1675
1676}
1677
1678/* Digital Mixer */
1679static const struct snd_kcontrol_new rt5659_sto1_adc_l_mix[] = {
1680 SOC_DAPM_SINGLE("ADC1 Switch", RT5659_STO1_ADC_MIXER,
1681 RT5659_M_STO1_ADC_L1_SFT, 1, 1),
1682 SOC_DAPM_SINGLE("ADC2 Switch", RT5659_STO1_ADC_MIXER,
1683 RT5659_M_STO1_ADC_L2_SFT, 1, 1),
1684};
1685
1686static const struct snd_kcontrol_new rt5659_sto1_adc_r_mix[] = {
1687 SOC_DAPM_SINGLE("ADC1 Switch", RT5659_STO1_ADC_MIXER,
1688 RT5659_M_STO1_ADC_R1_SFT, 1, 1),
1689 SOC_DAPM_SINGLE("ADC2 Switch", RT5659_STO1_ADC_MIXER,
1690 RT5659_M_STO1_ADC_R2_SFT, 1, 1),
1691};
1692
1693static const struct snd_kcontrol_new rt5659_mono_adc_l_mix[] = {
1694 SOC_DAPM_SINGLE("ADC1 Switch", RT5659_MONO_ADC_MIXER,
1695 RT5659_M_MONO_ADC_L1_SFT, 1, 1),
1696 SOC_DAPM_SINGLE("ADC2 Switch", RT5659_MONO_ADC_MIXER,
1697 RT5659_M_MONO_ADC_L2_SFT, 1, 1),
1698};
1699
1700static const struct snd_kcontrol_new rt5659_mono_adc_r_mix[] = {
1701 SOC_DAPM_SINGLE("ADC1 Switch", RT5659_MONO_ADC_MIXER,
1702 RT5659_M_MONO_ADC_R1_SFT, 1, 1),
1703 SOC_DAPM_SINGLE("ADC2 Switch", RT5659_MONO_ADC_MIXER,
1704 RT5659_M_MONO_ADC_R2_SFT, 1, 1),
1705};
1706
1707static const struct snd_kcontrol_new rt5659_dac_l_mix[] = {
1708 SOC_DAPM_SINGLE("Stereo ADC Switch", RT5659_AD_DA_MIXER,
1709 RT5659_M_ADCMIX_L_SFT, 1, 1),
1710 SOC_DAPM_SINGLE("DAC1 Switch", RT5659_AD_DA_MIXER,
1711 RT5659_M_DAC1_L_SFT, 1, 1),
1712};
1713
1714static const struct snd_kcontrol_new rt5659_dac_r_mix[] = {
1715 SOC_DAPM_SINGLE("Stereo ADC Switch", RT5659_AD_DA_MIXER,
1716 RT5659_M_ADCMIX_R_SFT, 1, 1),
1717 SOC_DAPM_SINGLE("DAC1 Switch", RT5659_AD_DA_MIXER,
1718 RT5659_M_DAC1_R_SFT, 1, 1),
1719};
1720
1721static const struct snd_kcontrol_new rt5659_sto_dac_l_mix[] = {
1722 SOC_DAPM_SINGLE("DAC L1 Switch", RT5659_STO_DAC_MIXER,
1723 RT5659_M_DAC_L1_STO_L_SFT, 1, 1),
1724 SOC_DAPM_SINGLE("DAC R1 Switch", RT5659_STO_DAC_MIXER,
1725 RT5659_M_DAC_R1_STO_L_SFT, 1, 1),
1726 SOC_DAPM_SINGLE("DAC L2 Switch", RT5659_STO_DAC_MIXER,
1727 RT5659_M_DAC_L2_STO_L_SFT, 1, 1),
1728 SOC_DAPM_SINGLE("DAC R2 Switch", RT5659_STO_DAC_MIXER,
1729 RT5659_M_DAC_R2_STO_L_SFT, 1, 1),
1730};
1731
1732static const struct snd_kcontrol_new rt5659_sto_dac_r_mix[] = {
1733 SOC_DAPM_SINGLE("DAC L1 Switch", RT5659_STO_DAC_MIXER,
1734 RT5659_M_DAC_L1_STO_R_SFT, 1, 1),
1735 SOC_DAPM_SINGLE("DAC R1 Switch", RT5659_STO_DAC_MIXER,
1736 RT5659_M_DAC_R1_STO_R_SFT, 1, 1),
1737 SOC_DAPM_SINGLE("DAC L2 Switch", RT5659_STO_DAC_MIXER,
1738 RT5659_M_DAC_L2_STO_R_SFT, 1, 1),
1739 SOC_DAPM_SINGLE("DAC R2 Switch", RT5659_STO_DAC_MIXER,
1740 RT5659_M_DAC_R2_STO_R_SFT, 1, 1),
1741};
1742
1743static const struct snd_kcontrol_new rt5659_mono_dac_l_mix[] = {
1744 SOC_DAPM_SINGLE("DAC L1 Switch", RT5659_MONO_DAC_MIXER,
1745 RT5659_M_DAC_L1_MONO_L_SFT, 1, 1),
1746 SOC_DAPM_SINGLE("DAC R1 Switch", RT5659_MONO_DAC_MIXER,
1747 RT5659_M_DAC_R1_MONO_L_SFT, 1, 1),
1748 SOC_DAPM_SINGLE("DAC L2 Switch", RT5659_MONO_DAC_MIXER,
1749 RT5659_M_DAC_L2_MONO_L_SFT, 1, 1),
1750 SOC_DAPM_SINGLE("DAC R2 Switch", RT5659_MONO_DAC_MIXER,
1751 RT5659_M_DAC_R2_MONO_L_SFT, 1, 1),
1752};
1753
1754static const struct snd_kcontrol_new rt5659_mono_dac_r_mix[] = {
1755 SOC_DAPM_SINGLE("DAC L1 Switch", RT5659_MONO_DAC_MIXER,
1756 RT5659_M_DAC_L1_MONO_R_SFT, 1, 1),
1757 SOC_DAPM_SINGLE("DAC R1 Switch", RT5659_MONO_DAC_MIXER,
1758 RT5659_M_DAC_R1_MONO_R_SFT, 1, 1),
1759 SOC_DAPM_SINGLE("DAC L2 Switch", RT5659_MONO_DAC_MIXER,
1760 RT5659_M_DAC_L2_MONO_R_SFT, 1, 1),
1761 SOC_DAPM_SINGLE("DAC R2 Switch", RT5659_MONO_DAC_MIXER,
1762 RT5659_M_DAC_R2_MONO_R_SFT, 1, 1),
1763};
1764
1765/* Analog Input Mixer */
1766static const struct snd_kcontrol_new rt5659_rec1_l_mix[] = {
1767 SOC_DAPM_SINGLE("SPKVOLL Switch", RT5659_REC1_L2_MIXER,
1768 RT5659_M_SPKVOLL_RM1_L_SFT, 1, 1),
1769 SOC_DAPM_SINGLE("INL Switch", RT5659_REC1_L2_MIXER,
1770 RT5659_M_INL_RM1_L_SFT, 1, 1),
1771 SOC_DAPM_SINGLE("BST4 Switch", RT5659_REC1_L2_MIXER,
1772 RT5659_M_BST4_RM1_L_SFT, 1, 1),
1773 SOC_DAPM_SINGLE("BST3 Switch", RT5659_REC1_L2_MIXER,
1774 RT5659_M_BST3_RM1_L_SFT, 1, 1),
1775 SOC_DAPM_SINGLE("BST2 Switch", RT5659_REC1_L2_MIXER,
1776 RT5659_M_BST2_RM1_L_SFT, 1, 1),
1777 SOC_DAPM_SINGLE("BST1 Switch", RT5659_REC1_L2_MIXER,
1778 RT5659_M_BST1_RM1_L_SFT, 1, 1),
1779};
1780
1781static const struct snd_kcontrol_new rt5659_rec1_r_mix[] = {
1782 SOC_DAPM_SINGLE("HPOVOLR Switch", RT5659_REC1_L2_MIXER,
1783 RT5659_M_HPOVOLR_RM1_R_SFT, 1, 1),
1784 SOC_DAPM_SINGLE("INR Switch", RT5659_REC1_R2_MIXER,
1785 RT5659_M_INR_RM1_R_SFT, 1, 1),
1786 SOC_DAPM_SINGLE("BST4 Switch", RT5659_REC1_R2_MIXER,
1787 RT5659_M_BST4_RM1_R_SFT, 1, 1),
1788 SOC_DAPM_SINGLE("BST3 Switch", RT5659_REC1_R2_MIXER,
1789 RT5659_M_BST3_RM1_R_SFT, 1, 1),
1790 SOC_DAPM_SINGLE("BST2 Switch", RT5659_REC1_R2_MIXER,
1791 RT5659_M_BST2_RM1_R_SFT, 1, 1),
1792 SOC_DAPM_SINGLE("BST1 Switch", RT5659_REC1_R2_MIXER,
1793 RT5659_M_BST1_RM1_R_SFT, 1, 1),
1794};
1795
1796static const struct snd_kcontrol_new rt5659_rec2_l_mix[] = {
1797 SOC_DAPM_SINGLE("SPKVOLL Switch", RT5659_REC2_L2_MIXER,
1798 RT5659_M_SPKVOL_RM2_L_SFT, 1, 1),
1799 SOC_DAPM_SINGLE("OUTVOLL Switch", RT5659_REC2_L2_MIXER,
1800 RT5659_M_OUTVOLL_RM2_L_SFT, 1, 1),
1801 SOC_DAPM_SINGLE("BST4 Switch", RT5659_REC2_L2_MIXER,
1802 RT5659_M_BST4_RM2_L_SFT, 1, 1),
1803 SOC_DAPM_SINGLE("BST3 Switch", RT5659_REC2_L2_MIXER,
1804 RT5659_M_BST3_RM2_L_SFT, 1, 1),
1805 SOC_DAPM_SINGLE("BST2 Switch", RT5659_REC2_L2_MIXER,
1806 RT5659_M_BST2_RM2_L_SFT, 1, 1),
1807 SOC_DAPM_SINGLE("BST1 Switch", RT5659_REC2_L2_MIXER,
1808 RT5659_M_BST1_RM2_L_SFT, 1, 1),
1809};
1810
1811static const struct snd_kcontrol_new rt5659_rec2_r_mix[] = {
1812 SOC_DAPM_SINGLE("MONOVOL Switch", RT5659_REC2_R2_MIXER,
1813 RT5659_M_MONOVOL_RM2_R_SFT, 1, 1),
1814 SOC_DAPM_SINGLE("OUTVOLR Switch", RT5659_REC2_R2_MIXER,
1815 RT5659_M_OUTVOLR_RM2_R_SFT, 1, 1),
1816 SOC_DAPM_SINGLE("BST4 Switch", RT5659_REC2_R2_MIXER,
1817 RT5659_M_BST4_RM2_R_SFT, 1, 1),
1818 SOC_DAPM_SINGLE("BST3 Switch", RT5659_REC2_R2_MIXER,
1819 RT5659_M_BST3_RM2_R_SFT, 1, 1),
1820 SOC_DAPM_SINGLE("BST2 Switch", RT5659_REC2_R2_MIXER,
1821 RT5659_M_BST2_RM2_R_SFT, 1, 1),
1822 SOC_DAPM_SINGLE("BST1 Switch", RT5659_REC2_R2_MIXER,
1823 RT5659_M_BST1_RM2_R_SFT, 1, 1),
1824};
1825
1826static const struct snd_kcontrol_new rt5659_spk_l_mix[] = {
1827 SOC_DAPM_SINGLE("DAC L2 Switch", RT5659_SPK_L_MIXER,
1828 RT5659_M_DAC_L2_SM_L_SFT, 1, 1),
1829 SOC_DAPM_SINGLE("BST1 Switch", RT5659_SPK_L_MIXER,
1830 RT5659_M_BST1_SM_L_SFT, 1, 1),
1831 SOC_DAPM_SINGLE("INL Switch", RT5659_SPK_L_MIXER,
1832 RT5659_M_IN_L_SM_L_SFT, 1, 1),
1833 SOC_DAPM_SINGLE("INR Switch", RT5659_SPK_L_MIXER,
1834 RT5659_M_IN_R_SM_L_SFT, 1, 1),
1835 SOC_DAPM_SINGLE("BST3 Switch", RT5659_SPK_L_MIXER,
1836 RT5659_M_BST3_SM_L_SFT, 1, 1),
1837};
1838
1839static const struct snd_kcontrol_new rt5659_spk_r_mix[] = {
1840 SOC_DAPM_SINGLE("DAC R2 Switch", RT5659_SPK_R_MIXER,
1841 RT5659_M_DAC_R2_SM_R_SFT, 1, 1),
1842 SOC_DAPM_SINGLE("BST4 Switch", RT5659_SPK_R_MIXER,
1843 RT5659_M_BST4_SM_R_SFT, 1, 1),
1844 SOC_DAPM_SINGLE("INL Switch", RT5659_SPK_R_MIXER,
1845 RT5659_M_IN_L_SM_R_SFT, 1, 1),
1846 SOC_DAPM_SINGLE("INR Switch", RT5659_SPK_R_MIXER,
1847 RT5659_M_IN_R_SM_R_SFT, 1, 1),
1848 SOC_DAPM_SINGLE("BST3 Switch", RT5659_SPK_R_MIXER,
1849 RT5659_M_BST3_SM_R_SFT, 1, 1),
1850};
1851
1852static const struct snd_kcontrol_new rt5659_monovol_mix[] = {
1853 SOC_DAPM_SINGLE("DAC L2 Switch", RT5659_MONOMIX_IN_GAIN,
1854 RT5659_M_DAC_L2_MM_SFT, 1, 1),
1855 SOC_DAPM_SINGLE("DAC R2 Switch", RT5659_MONOMIX_IN_GAIN,
1856 RT5659_M_DAC_R2_MM_SFT, 1, 1),
1857 SOC_DAPM_SINGLE("BST1 Switch", RT5659_MONOMIX_IN_GAIN,
1858 RT5659_M_BST1_MM_SFT, 1, 1),
1859 SOC_DAPM_SINGLE("BST2 Switch", RT5659_MONOMIX_IN_GAIN,
1860 RT5659_M_BST2_MM_SFT, 1, 1),
1861 SOC_DAPM_SINGLE("BST3 Switch", RT5659_MONOMIX_IN_GAIN,
1862 RT5659_M_BST3_MM_SFT, 1, 1),
1863};
1864
1865static const struct snd_kcontrol_new rt5659_out_l_mix[] = {
1866 SOC_DAPM_SINGLE("DAC L2 Switch", RT5659_OUT_L_MIXER,
1867 RT5659_M_DAC_L2_OM_L_SFT, 1, 1),
1868 SOC_DAPM_SINGLE("INL Switch", RT5659_OUT_L_MIXER,
1869 RT5659_M_IN_L_OM_L_SFT, 1, 1),
1870 SOC_DAPM_SINGLE("BST1 Switch", RT5659_OUT_L_MIXER,
1871 RT5659_M_BST1_OM_L_SFT, 1, 1),
1872 SOC_DAPM_SINGLE("BST2 Switch", RT5659_OUT_L_MIXER,
1873 RT5659_M_BST2_OM_L_SFT, 1, 1),
1874 SOC_DAPM_SINGLE("BST3 Switch", RT5659_OUT_L_MIXER,
1875 RT5659_M_BST3_OM_L_SFT, 1, 1),
1876};
1877
1878static const struct snd_kcontrol_new rt5659_out_r_mix[] = {
1879 SOC_DAPM_SINGLE("DAC R2 Switch", RT5659_OUT_R_MIXER,
1880 RT5659_M_DAC_R2_OM_R_SFT, 1, 1),
1881 SOC_DAPM_SINGLE("INR Switch", RT5659_OUT_R_MIXER,
1882 RT5659_M_IN_R_OM_R_SFT, 1, 1),
1883 SOC_DAPM_SINGLE("BST2 Switch", RT5659_OUT_R_MIXER,
1884 RT5659_M_BST2_OM_R_SFT, 1, 1),
1885 SOC_DAPM_SINGLE("BST3 Switch", RT5659_OUT_R_MIXER,
1886 RT5659_M_BST3_OM_R_SFT, 1, 1),
1887 SOC_DAPM_SINGLE("BST4 Switch", RT5659_OUT_R_MIXER,
1888 RT5659_M_BST4_OM_R_SFT, 1, 1),
1889};
1890
1891static const struct snd_kcontrol_new rt5659_spo_l_mix[] = {
1892 SOC_DAPM_SINGLE("DAC L2 Switch", RT5659_SPO_AMP_GAIN,
1893 RT5659_M_DAC_L2_SPKOMIX_SFT, 1, 0),
1894 SOC_DAPM_SINGLE("SPKVOL L Switch", RT5659_SPO_AMP_GAIN,
1895 RT5659_M_SPKVOLL_SPKOMIX_SFT, 1, 0),
1896};
1897
1898static const struct snd_kcontrol_new rt5659_spo_r_mix[] = {
1899 SOC_DAPM_SINGLE("DAC R2 Switch", RT5659_SPO_AMP_GAIN,
1900 RT5659_M_DAC_R2_SPKOMIX_SFT, 1, 0),
1901 SOC_DAPM_SINGLE("SPKVOL R Switch", RT5659_SPO_AMP_GAIN,
1902 RT5659_M_SPKVOLR_SPKOMIX_SFT, 1, 0),
1903};
1904
1905static const struct snd_kcontrol_new rt5659_mono_mix[] = {
1906 SOC_DAPM_SINGLE("DAC L2 Switch", RT5659_MONOMIX_IN_GAIN,
1907 RT5659_M_DAC_L2_MA_SFT, 1, 1),
1908 SOC_DAPM_SINGLE("MONOVOL Switch", RT5659_MONOMIX_IN_GAIN,
1909 RT5659_M_MONOVOL_MA_SFT, 1, 1),
1910};
1911
1912static const struct snd_kcontrol_new rt5659_lout_l_mix[] = {
1913 SOC_DAPM_SINGLE("DAC L2 Switch", RT5659_LOUT_MIXER,
1914 RT5659_M_DAC_L2_LM_SFT, 1, 1),
1915 SOC_DAPM_SINGLE("OUTVOL L Switch", RT5659_LOUT_MIXER,
1916 RT5659_M_OV_L_LM_SFT, 1, 1),
1917};
1918
1919static const struct snd_kcontrol_new rt5659_lout_r_mix[] = {
1920 SOC_DAPM_SINGLE("DAC R2 Switch", RT5659_LOUT_MIXER,
1921 RT5659_M_DAC_R2_LM_SFT, 1, 1),
1922 SOC_DAPM_SINGLE("OUTVOL R Switch", RT5659_LOUT_MIXER,
1923 RT5659_M_OV_R_LM_SFT, 1, 1),
1924};
1925
1926/*DAC L2, DAC R2*/
1927/*MX-1B [6:4], MX-1B [2:0]*/
1928static const char * const rt5659_dac2_src[] = {
1929 "IF1 DAC2", "IF2 DAC", "IF3 DAC", "Mono ADC MIX"
1930};
1931
1932static const SOC_ENUM_SINGLE_DECL(
1933 rt5659_dac_l2_enum, RT5659_DAC_CTRL,
1934 RT5659_DAC_L2_SEL_SFT, rt5659_dac2_src);
1935
1936static const struct snd_kcontrol_new rt5659_dac_l2_mux =
1937 SOC_DAPM_ENUM("DAC L2 Source", rt5659_dac_l2_enum);
1938
1939static const SOC_ENUM_SINGLE_DECL(
1940 rt5659_dac_r2_enum, RT5659_DAC_CTRL,
1941 RT5659_DAC_R2_SEL_SFT, rt5659_dac2_src);
1942
1943static const struct snd_kcontrol_new rt5659_dac_r2_mux =
1944 SOC_DAPM_ENUM("DAC R2 Source", rt5659_dac_r2_enum);
1945
1946
1947/* STO1 ADC1 Source */
1948/* MX-26 [13] */
1949static const char * const rt5659_sto1_adc1_src[] = {
1950 "DAC MIX", "ADC"
1951};
1952
1953static const SOC_ENUM_SINGLE_DECL(
1954 rt5659_sto1_adc1_enum, RT5659_STO1_ADC_MIXER,
1955 RT5659_STO1_ADC1_SRC_SFT, rt5659_sto1_adc1_src);
1956
1957static const struct snd_kcontrol_new rt5659_sto1_adc1_mux =
1958 SOC_DAPM_ENUM("Stereo1 ADC1 Source", rt5659_sto1_adc1_enum);
1959
1960/* STO1 ADC Source */
1961/* MX-26 [12] */
1962static const char * const rt5659_sto1_adc_src[] = {
1963 "ADC1", "ADC2"
1964};
1965
1966static const SOC_ENUM_SINGLE_DECL(
1967 rt5659_sto1_adc_enum, RT5659_STO1_ADC_MIXER,
1968 RT5659_STO1_ADC_SRC_SFT, rt5659_sto1_adc_src);
1969
1970static const struct snd_kcontrol_new rt5659_sto1_adc_mux =
1971 SOC_DAPM_ENUM("Stereo1 ADC Source", rt5659_sto1_adc_enum);
1972
1973/* STO1 ADC2 Source */
1974/* MX-26 [11] */
1975static const char * const rt5659_sto1_adc2_src[] = {
1976 "DAC MIX", "DMIC"
1977};
1978
1979static const SOC_ENUM_SINGLE_DECL(
1980 rt5659_sto1_adc2_enum, RT5659_STO1_ADC_MIXER,
1981 RT5659_STO1_ADC2_SRC_SFT, rt5659_sto1_adc2_src);
1982
1983static const struct snd_kcontrol_new rt5659_sto1_adc2_mux =
1984 SOC_DAPM_ENUM("Stereo1 ADC2 Source", rt5659_sto1_adc2_enum);
1985
1986/* STO1 DMIC Source */
1987/* MX-26 [8] */
1988static const char * const rt5659_sto1_dmic_src[] = {
1989 "DMIC1", "DMIC2"
1990};
1991
1992static const SOC_ENUM_SINGLE_DECL(
1993 rt5659_sto1_dmic_enum, RT5659_STO1_ADC_MIXER,
1994 RT5659_STO1_DMIC_SRC_SFT, rt5659_sto1_dmic_src);
1995
1996static const struct snd_kcontrol_new rt5659_sto1_dmic_mux =
1997 SOC_DAPM_ENUM("Stereo1 DMIC Source", rt5659_sto1_dmic_enum);
1998
1999
2000/* MONO ADC L2 Source */
2001/* MX-27 [12] */
2002static const char * const rt5659_mono_adc_l2_src[] = {
2003 "Mono DAC MIXL", "DMIC"
2004};
2005
2006static const SOC_ENUM_SINGLE_DECL(
2007 rt5659_mono_adc_l2_enum, RT5659_MONO_ADC_MIXER,
2008 RT5659_MONO_ADC_L2_SRC_SFT, rt5659_mono_adc_l2_src);
2009
2010static const struct snd_kcontrol_new rt5659_mono_adc_l2_mux =
2011 SOC_DAPM_ENUM("Mono ADC L2 Source", rt5659_mono_adc_l2_enum);
2012
2013
2014/* MONO ADC L1 Source */
2015/* MX-27 [11] */
2016static const char * const rt5659_mono_adc_l1_src[] = {
2017 "Mono DAC MIXL", "ADC"
2018};
2019
2020static const SOC_ENUM_SINGLE_DECL(
2021 rt5659_mono_adc_l1_enum, RT5659_MONO_ADC_MIXER,
2022 RT5659_MONO_ADC_L1_SRC_SFT, rt5659_mono_adc_l1_src);
2023
2024static const struct snd_kcontrol_new rt5659_mono_adc_l1_mux =
2025 SOC_DAPM_ENUM("Mono ADC L1 Source", rt5659_mono_adc_l1_enum);
2026
2027/* MONO ADC L Source, MONO ADC R Source*/
2028/* MX-27 [10:9], MX-27 [2:1] */
2029static const char * const rt5659_mono_adc_src[] = {
2030 "ADC1 L", "ADC1 R", "ADC2 L", "ADC2 R"
2031};
2032
2033static const SOC_ENUM_SINGLE_DECL(
2034 rt5659_mono_adc_l_enum, RT5659_MONO_ADC_MIXER,
2035 RT5659_MONO_ADC_L_SRC_SFT, rt5659_mono_adc_src);
2036
2037static const struct snd_kcontrol_new rt5659_mono_adc_l_mux =
2038 SOC_DAPM_ENUM("Mono ADC L Source", rt5659_mono_adc_l_enum);
2039
2040static const SOC_ENUM_SINGLE_DECL(
2041 rt5659_mono_adcr_enum, RT5659_MONO_ADC_MIXER,
2042 RT5659_MONO_ADC_R_SRC_SFT, rt5659_mono_adc_src);
2043
2044static const struct snd_kcontrol_new rt5659_mono_adc_r_mux =
2045 SOC_DAPM_ENUM("Mono ADC R Source", rt5659_mono_adcr_enum);
2046
2047/* MONO DMIC L Source */
2048/* MX-27 [8] */
2049static const char * const rt5659_mono_dmic_l_src[] = {
2050 "DMIC1 L", "DMIC2 L"
2051};
2052
2053static const SOC_ENUM_SINGLE_DECL(
2054 rt5659_mono_dmic_l_enum, RT5659_MONO_ADC_MIXER,
2055 RT5659_MONO_DMIC_L_SRC_SFT, rt5659_mono_dmic_l_src);
2056
2057static const struct snd_kcontrol_new rt5659_mono_dmic_l_mux =
2058 SOC_DAPM_ENUM("Mono DMIC L Source", rt5659_mono_dmic_l_enum);
2059
2060/* MONO ADC R2 Source */
2061/* MX-27 [4] */
2062static const char * const rt5659_mono_adc_r2_src[] = {
2063 "Mono DAC MIXR", "DMIC"
2064};
2065
2066static const SOC_ENUM_SINGLE_DECL(
2067 rt5659_mono_adc_r2_enum, RT5659_MONO_ADC_MIXER,
2068 RT5659_MONO_ADC_R2_SRC_SFT, rt5659_mono_adc_r2_src);
2069
2070static const struct snd_kcontrol_new rt5659_mono_adc_r2_mux =
2071 SOC_DAPM_ENUM("Mono ADC R2 Source", rt5659_mono_adc_r2_enum);
2072
2073/* MONO ADC R1 Source */
2074/* MX-27 [3] */
2075static const char * const rt5659_mono_adc_r1_src[] = {
2076 "Mono DAC MIXR", "ADC"
2077};
2078
2079static const SOC_ENUM_SINGLE_DECL(
2080 rt5659_mono_adc_r1_enum, RT5659_MONO_ADC_MIXER,
2081 RT5659_MONO_ADC_R1_SRC_SFT, rt5659_mono_adc_r1_src);
2082
2083static const struct snd_kcontrol_new rt5659_mono_adc_r1_mux =
2084 SOC_DAPM_ENUM("Mono ADC R1 Source", rt5659_mono_adc_r1_enum);
2085
2086/* MONO DMIC R Source */
2087/* MX-27 [0] */
2088static const char * const rt5659_mono_dmic_r_src[] = {
2089 "DMIC1 R", "DMIC2 R"
2090};
2091
2092static const SOC_ENUM_SINGLE_DECL(
2093 rt5659_mono_dmic_r_enum, RT5659_MONO_ADC_MIXER,
2094 RT5659_MONO_DMIC_R_SRC_SFT, rt5659_mono_dmic_r_src);
2095
2096static const struct snd_kcontrol_new rt5659_mono_dmic_r_mux =
2097 SOC_DAPM_ENUM("Mono DMIC R Source", rt5659_mono_dmic_r_enum);
2098
2099
2100/* DAC R1 Source, DAC L1 Source*/
2101/* MX-29 [11:10], MX-29 [9:8]*/
2102static const char * const rt5659_dac1_src[] = {
2103 "IF1 DAC1", "IF2 DAC", "IF3 DAC"
2104};
2105
2106static const SOC_ENUM_SINGLE_DECL(
2107 rt5659_dac_r1_enum, RT5659_AD_DA_MIXER,
2108 RT5659_DAC1_R_SEL_SFT, rt5659_dac1_src);
2109
2110static const struct snd_kcontrol_new rt5659_dac_r1_mux =
2111 SOC_DAPM_ENUM("DAC R1 Source", rt5659_dac_r1_enum);
2112
2113static const SOC_ENUM_SINGLE_DECL(
2114 rt5659_dac_l1_enum, RT5659_AD_DA_MIXER,
2115 RT5659_DAC1_L_SEL_SFT, rt5659_dac1_src);
2116
2117static const struct snd_kcontrol_new rt5659_dac_l1_mux =
2118 SOC_DAPM_ENUM("DAC L1 Source", rt5659_dac_l1_enum);
2119
2120/* DAC Digital Mixer L Source, DAC Digital Mixer R Source*/
2121/* MX-2C [6], MX-2C [4]*/
2122static const char * const rt5659_dig_dac_mix_src[] = {
2123 "Stereo DAC Mixer", "Mono DAC Mixer"
2124};
2125
2126static const SOC_ENUM_SINGLE_DECL(
2127 rt5659_dig_dac_mixl_enum, RT5659_DIG_MIXER,
2128 RT5659_DAC_MIX_L_SFT, rt5659_dig_dac_mix_src);
2129
2130static const struct snd_kcontrol_new rt5659_dig_dac_mixl_mux =
2131 SOC_DAPM_ENUM("DAC Digital Mixer L Source", rt5659_dig_dac_mixl_enum);
2132
2133static const SOC_ENUM_SINGLE_DECL(
2134 rt5659_dig_dac_mixr_enum, RT5659_DIG_MIXER,
2135 RT5659_DAC_MIX_R_SFT, rt5659_dig_dac_mix_src);
2136
2137static const struct snd_kcontrol_new rt5659_dig_dac_mixr_mux =
2138 SOC_DAPM_ENUM("DAC Digital Mixer R Source", rt5659_dig_dac_mixr_enum);
2139
2140/* Analog DAC L1 Source, Analog DAC R1 Source*/
2141/* MX-2D [3], MX-2D [2]*/
2142static const char * const rt5659_alg_dac1_src[] = {
2143 "DAC", "Stereo DAC Mixer"
2144};
2145
2146static const SOC_ENUM_SINGLE_DECL(
2147 rt5659_alg_dac_l1_enum, RT5659_A_DAC_MUX,
2148 RT5659_A_DACL1_SFT, rt5659_alg_dac1_src);
2149
2150static const struct snd_kcontrol_new rt5659_alg_dac_l1_mux =
2151 SOC_DAPM_ENUM("Analog DACL1 Source", rt5659_alg_dac_l1_enum);
2152
2153static const SOC_ENUM_SINGLE_DECL(
2154 rt5659_alg_dac_r1_enum, RT5659_A_DAC_MUX,
2155 RT5659_A_DACR1_SFT, rt5659_alg_dac1_src);
2156
2157static const struct snd_kcontrol_new rt5659_alg_dac_r1_mux =
2158 SOC_DAPM_ENUM("Analog DACR1 Source", rt5659_alg_dac_r1_enum);
2159
2160/* Analog DAC LR Source, Analog DAC R2 Source*/
2161/* MX-2D [1], MX-2D [0]*/
2162static const char * const rt5659_alg_dac2_src[] = {
2163 "Stereo DAC Mixer", "Mono DAC Mixer"
2164};
2165
2166static const SOC_ENUM_SINGLE_DECL(
2167 rt5659_alg_dac_l2_enum, RT5659_A_DAC_MUX,
2168 RT5659_A_DACL2_SFT, rt5659_alg_dac2_src);
2169
2170static const struct snd_kcontrol_new rt5659_alg_dac_l2_mux =
2171 SOC_DAPM_ENUM("Analog DAC L2 Source", rt5659_alg_dac_l2_enum);
2172
2173static const SOC_ENUM_SINGLE_DECL(
2174 rt5659_alg_dac_r2_enum, RT5659_A_DAC_MUX,
2175 RT5659_A_DACR2_SFT, rt5659_alg_dac2_src);
2176
2177static const struct snd_kcontrol_new rt5659_alg_dac_r2_mux =
2178 SOC_DAPM_ENUM("Analog DAC R2 Source", rt5659_alg_dac_r2_enum);
2179
2180/* Interface2 ADC Data Input*/
2181/* MX-2F [13:12] */
2182static const char * const rt5659_if2_adc_in_src[] = {
2183 "IF_ADC1", "IF_ADC2", "DAC_REF", "IF_ADC3"
2184};
2185
2186static const SOC_ENUM_SINGLE_DECL(
2187 rt5659_if2_adc_in_enum, RT5659_DIG_INF23_DATA,
2188 RT5659_IF2_ADC_IN_SFT, rt5659_if2_adc_in_src);
2189
2190static const struct snd_kcontrol_new rt5659_if2_adc_in_mux =
2191 SOC_DAPM_ENUM("IF2 ADC IN Source", rt5659_if2_adc_in_enum);
2192
2193/* Interface3 ADC Data Input*/
2194/* MX-2F [1:0] */
2195static const char * const rt5659_if3_adc_in_src[] = {
2196 "IF_ADC1", "IF_ADC2", "DAC_REF", "Stereo2_ADC_L/R"
2197};
2198
2199static const SOC_ENUM_SINGLE_DECL(
2200 rt5659_if3_adc_in_enum, RT5659_DIG_INF23_DATA,
2201 RT5659_IF3_ADC_IN_SFT, rt5659_if3_adc_in_src);
2202
2203static const struct snd_kcontrol_new rt5659_if3_adc_in_mux =
2204 SOC_DAPM_ENUM("IF3 ADC IN Source", rt5659_if3_adc_in_enum);
2205
2206/* PDM 1 L/R*/
2207/* MX-31 [15] [13] */
2208static const char * const rt5659_pdm_src[] = {
2209 "Mono DAC", "Stereo DAC"
2210};
2211
2212static const SOC_ENUM_SINGLE_DECL(
2213 rt5659_pdm_l_enum, RT5659_PDM_OUT_CTRL,
2214 RT5659_PDM1_L_SFT, rt5659_pdm_src);
2215
2216static const struct snd_kcontrol_new rt5659_pdm_l_mux =
2217 SOC_DAPM_ENUM("PDM L Source", rt5659_pdm_l_enum);
2218
2219static const SOC_ENUM_SINGLE_DECL(
2220 rt5659_pdm_r_enum, RT5659_PDM_OUT_CTRL,
2221 RT5659_PDM1_R_SFT, rt5659_pdm_src);
2222
2223static const struct snd_kcontrol_new rt5659_pdm_r_mux =
2224 SOC_DAPM_ENUM("PDM R Source", rt5659_pdm_r_enum);
2225
2226/* SPDIF Output source*/
2227/* MX-36 [1:0] */
2228static const char * const rt5659_spdif_src[] = {
2229 "IF1_DAC1", "IF1_DAC2", "IF2_DAC", "IF3_DAC"
2230};
2231
2232static const SOC_ENUM_SINGLE_DECL(
2233 rt5659_spdif_enum, RT5659_SPDIF_CTRL,
2234 RT5659_SPDIF_SEL_SFT, rt5659_spdif_src);
2235
2236static const struct snd_kcontrol_new rt5659_spdif_mux =
2237 SOC_DAPM_ENUM("SPDIF Source", rt5659_spdif_enum);
2238
2239/* I2S1 TDM ADCDAT Source */
2240/* MX-78[4:0] */
2241static const char * const rt5659_rx_adc_data_src[] = {
2242 "AD1:AD2:DAC:NUL", "AD1:AD2:NUL:DAC", "AD1:DAC:AD2:NUL",
2243 "AD1:DAC:NUL:AD2", "AD1:NUL:DAC:AD2", "AD1:NUL:AD2:DAC",
2244 "AD2:AD1:DAC:NUL", "AD2:AD1:NUL:DAC", "AD2:DAC:AD1:NUL",
2245 "AD2:DAC:NUL:AD1", "AD2:NUL:DAC:AD1", "AD1:NUL:AD1:DAC",
2246 "DAC:AD1:AD2:NUL", "DAC:AD1:NUL:AD2", "DAC:AD2:AD1:NUL",
2247 "DAC:AD2:NUL:AD1", "DAC:NUL:DAC:AD2", "DAC:NUL:AD2:DAC",
2248 "NUL:AD1:AD2:DAC", "NUL:AD1:DAC:AD2", "NUL:AD2:AD1:DAC",
2249 "NUL:AD2:DAC:AD1", "NUL:DAC:DAC:AD2", "NUL:DAC:AD2:DAC"
2250};
2251
2252static const SOC_ENUM_SINGLE_DECL(
2253 rt5659_rx_adc_data_enum, RT5659_TDM_CTRL_2,
2254 RT5659_ADCDAT_SRC_SFT, rt5659_rx_adc_data_src);
2255
2256static const struct snd_kcontrol_new rt5659_rx_adc_dac_mux =
2257 SOC_DAPM_ENUM("TDM ADCDAT Source", rt5659_rx_adc_data_enum);
2258
2259/* Out Volume Switch */
2260static const struct snd_kcontrol_new spkvol_l_switch =
2261 SOC_DAPM_SINGLE("Switch", RT5659_SPO_VOL, RT5659_VOL_L_SFT, 1, 1);
2262
2263static const struct snd_kcontrol_new spkvol_r_switch =
2264 SOC_DAPM_SINGLE("Switch", RT5659_SPO_VOL, RT5659_VOL_R_SFT, 1, 1);
2265
2266static const struct snd_kcontrol_new monovol_switch =
2267 SOC_DAPM_SINGLE("Switch", RT5659_MONO_OUT, RT5659_VOL_L_SFT, 1, 1);
2268
2269static const struct snd_kcontrol_new outvol_l_switch =
2270 SOC_DAPM_SINGLE("Switch", RT5659_LOUT, RT5659_VOL_L_SFT, 1, 1);
2271
2272static const struct snd_kcontrol_new outvol_r_switch =
2273 SOC_DAPM_SINGLE("Switch", RT5659_LOUT, RT5659_VOL_R_SFT, 1, 1);
2274
2275/* Out Switch */
2276static const struct snd_kcontrol_new spo_switch =
2277 SOC_DAPM_SINGLE("Switch", RT5659_CLASSD_2, RT5659_M_RF_DIG_SFT, 1, 1);
2278
2279static const struct snd_kcontrol_new mono_switch =
2280 SOC_DAPM_SINGLE("Switch", RT5659_MONO_OUT, RT5659_L_MUTE_SFT, 1, 1);
2281
2282static const struct snd_kcontrol_new hpo_l_switch =
2283 SOC_DAPM_SINGLE("Switch", RT5659_HP_VOL, RT5659_L_MUTE_SFT, 1, 1);
2284
2285static const struct snd_kcontrol_new hpo_r_switch =
2286 SOC_DAPM_SINGLE("Switch", RT5659_HP_VOL, RT5659_R_MUTE_SFT, 1, 1);
2287
2288static const struct snd_kcontrol_new lout_l_switch =
2289 SOC_DAPM_SINGLE("Switch", RT5659_LOUT, RT5659_L_MUTE_SFT, 1, 1);
2290
2291static const struct snd_kcontrol_new lout_r_switch =
2292 SOC_DAPM_SINGLE("Switch", RT5659_LOUT, RT5659_R_MUTE_SFT, 1, 1);
2293
2294static const struct snd_kcontrol_new pdm_l_switch =
2295 SOC_DAPM_SINGLE("Switch", RT5659_PDM_OUT_CTRL, RT5659_M_PDM1_L_SFT, 1,
2296 1);
2297
2298static const struct snd_kcontrol_new pdm_r_switch =
2299 SOC_DAPM_SINGLE("Switch", RT5659_PDM_OUT_CTRL, RT5659_M_PDM1_R_SFT, 1,
2300 1);
2301
2302static int rt5659_spk_event(struct snd_soc_dapm_widget *w,
2303 struct snd_kcontrol *kcontrol, int event)
2304{
2305 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
2306
2307 switch (event) {
2308 case SND_SOC_DAPM_PRE_PMU:
2309 snd_soc_update_bits(codec, RT5659_CLASSD_CTRL_1,
2310 RT5659_POW_CLSD_DB_MASK, RT5659_POW_CLSD_DB_EN);
2311 snd_soc_update_bits(codec, RT5659_CLASSD_2,
2312 RT5659_M_RI_DIG, RT5659_M_RI_DIG);
2313 snd_soc_write(codec, RT5659_CLASSD_1, 0x0803);
2314 snd_soc_write(codec, RT5659_SPK_DC_CAILB_CTRL_3, 0x0000);
2315 break;
2316
2317 case SND_SOC_DAPM_POST_PMD:
2318 snd_soc_write(codec, RT5659_CLASSD_1, 0x0011);
2319 snd_soc_update_bits(codec, RT5659_CLASSD_2,
2320 RT5659_M_RI_DIG, 0x0);
2321 snd_soc_write(codec, RT5659_SPK_DC_CAILB_CTRL_3, 0x0003);
2322 snd_soc_update_bits(codec, RT5659_CLASSD_CTRL_1,
2323 RT5659_POW_CLSD_DB_MASK, RT5659_POW_CLSD_DB_DIS);
2324 break;
2325
2326 default:
2327 return 0;
2328 }
2329
2330 return 0;
2331
2332}
2333
2334static int rt5659_mono_event(struct snd_soc_dapm_widget *w,
2335 struct snd_kcontrol *kcontrol, int event)
2336{
2337 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
2338
2339 switch (event) {
2340 case SND_SOC_DAPM_PRE_PMU:
2341 snd_soc_write(codec, RT5659_MONO_AMP_CALIB_CTRL_1, 0x1e00);
2342 break;
2343
2344 case SND_SOC_DAPM_POST_PMD:
2345 snd_soc_write(codec, RT5659_MONO_AMP_CALIB_CTRL_1, 0x1e04);
2346 break;
2347
2348 default:
2349 return 0;
2350 }
2351
2352 return 0;
2353
2354}
2355
2356static int rt5659_hp_event(struct snd_soc_dapm_widget *w,
2357 struct snd_kcontrol *kcontrol, int event)
2358{
2359 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
2360
2361 switch (event) {
2362 case SND_SOC_DAPM_POST_PMU:
2363 snd_soc_write(codec, RT5659_HP_CHARGE_PUMP_1, 0x0e1e);
2364 snd_soc_update_bits(codec, RT5659_DEPOP_1, 0x0010, 0x0010);
2365 break;
2366
2367 case SND_SOC_DAPM_PRE_PMD:
2368 snd_soc_write(codec, RT5659_DEPOP_1, 0x0000);
2369 break;
2370
2371 default:
2372 return 0;
2373 }
2374
2375 return 0;
2376}
2377
2378static int set_dmic_power(struct snd_soc_dapm_widget *w,
2379 struct snd_kcontrol *kcontrol, int event)
2380{
2381 switch (event) {
2382 case SND_SOC_DAPM_POST_PMU:
2383 /*Add delay to avoid pop noise*/
2384 msleep(450);
2385 break;
2386
2387 default:
2388 return 0;
2389 }
2390
2391 return 0;
2392}
2393
2394static const struct snd_soc_dapm_widget rt5659_dapm_widgets[] = {
2395 SND_SOC_DAPM_SUPPLY("LDO2", RT5659_PWR_ANLG_3, RT5659_PWR_LDO2_BIT, 0,
2396 NULL, 0),
2397 SND_SOC_DAPM_SUPPLY("PLL", RT5659_PWR_ANLG_3, RT5659_PWR_PLL_BIT, 0,
2398 NULL, 0),
2399 SND_SOC_DAPM_SUPPLY("Mic Det Power", RT5659_PWR_VOL,
2400 RT5659_PWR_MIC_DET_BIT, 0, NULL, 0),
2401 SND_SOC_DAPM_SUPPLY("Mono Vref", RT5659_PWR_ANLG_1,
2402 RT5659_PWR_VREF3_BIT, 0, NULL, 0),
2403
2404 /* ASRC */
2405 SND_SOC_DAPM_SUPPLY_S("I2S1 ASRC", 1, RT5659_ASRC_1,
2406 RT5659_I2S1_ASRC_SFT, 0, NULL, 0),
2407 SND_SOC_DAPM_SUPPLY_S("I2S2 ASRC", 1, RT5659_ASRC_1,
2408 RT5659_I2S2_ASRC_SFT, 0, NULL, 0),
2409 SND_SOC_DAPM_SUPPLY_S("I2S3 ASRC", 1, RT5659_ASRC_1,
2410 RT5659_I2S3_ASRC_SFT, 0, NULL, 0),
2411 SND_SOC_DAPM_SUPPLY_S("DAC STO ASRC", 1, RT5659_ASRC_1,
2412 RT5659_DAC_STO_ASRC_SFT, 0, NULL, 0),
2413 SND_SOC_DAPM_SUPPLY_S("DAC Mono L ASRC", 1, RT5659_ASRC_1,
2414 RT5659_DAC_MONO_L_ASRC_SFT, 0, NULL, 0),
2415 SND_SOC_DAPM_SUPPLY_S("DAC Mono R ASRC", 1, RT5659_ASRC_1,
2416 RT5659_DAC_MONO_R_ASRC_SFT, 0, NULL, 0),
2417 SND_SOC_DAPM_SUPPLY_S("ADC STO1 ASRC", 1, RT5659_ASRC_1,
2418 RT5659_ADC_STO1_ASRC_SFT, 0, NULL, 0),
2419 SND_SOC_DAPM_SUPPLY_S("ADC Mono L ASRC", 1, RT5659_ASRC_1,
2420 RT5659_ADC_MONO_L_ASRC_SFT, 0, NULL, 0),
2421 SND_SOC_DAPM_SUPPLY_S("ADC Mono R ASRC", 1, RT5659_ASRC_1,
2422 RT5659_ADC_MONO_R_ASRC_SFT, 0, NULL, 0),
2423
2424 /* Input Side */
2425 SND_SOC_DAPM_SUPPLY("MICBIAS1", RT5659_PWR_ANLG_2, RT5659_PWR_MB1_BIT,
2426 0, NULL, 0),
2427 SND_SOC_DAPM_SUPPLY("MICBIAS2", RT5659_PWR_ANLG_2, RT5659_PWR_MB2_BIT,
2428 0, NULL, 0),
2429 SND_SOC_DAPM_SUPPLY("MICBIAS3", RT5659_PWR_ANLG_2, RT5659_PWR_MB3_BIT,
2430 0, NULL, 0),
2431
2432 /* Input Lines */
2433 SND_SOC_DAPM_INPUT("DMIC L1"),
2434 SND_SOC_DAPM_INPUT("DMIC R1"),
2435 SND_SOC_DAPM_INPUT("DMIC L2"),
2436 SND_SOC_DAPM_INPUT("DMIC R2"),
2437
2438 SND_SOC_DAPM_INPUT("IN1P"),
2439 SND_SOC_DAPM_INPUT("IN1N"),
2440 SND_SOC_DAPM_INPUT("IN2P"),
2441 SND_SOC_DAPM_INPUT("IN2N"),
2442 SND_SOC_DAPM_INPUT("IN3P"),
2443 SND_SOC_DAPM_INPUT("IN3N"),
2444 SND_SOC_DAPM_INPUT("IN4P"),
2445 SND_SOC_DAPM_INPUT("IN4N"),
2446
2447 SND_SOC_DAPM_PGA("DMIC1", SND_SOC_NOPM, 0, 0, NULL, 0),
2448 SND_SOC_DAPM_PGA("DMIC2", SND_SOC_NOPM, 0, 0, NULL, 0),
2449
2450 SND_SOC_DAPM_SUPPLY("DMIC CLK", SND_SOC_NOPM, 0, 0,
2451 set_dmic_clk, SND_SOC_DAPM_PRE_PMU),
2452 SND_SOC_DAPM_SUPPLY("DMIC1 Power", RT5659_DMIC_CTRL_1,
2453 RT5659_DMIC_1_EN_SFT, 0, set_dmic_power, SND_SOC_DAPM_POST_PMU),
2454 SND_SOC_DAPM_SUPPLY("DMIC2 Power", RT5659_DMIC_CTRL_1,
2455 RT5659_DMIC_2_EN_SFT, 0, set_dmic_power, SND_SOC_DAPM_POST_PMU),
2456
2457 /* Boost */
2458 SND_SOC_DAPM_PGA("BST1", RT5659_PWR_ANLG_2,
2459 RT5659_PWR_BST1_P_BIT, 0, NULL, 0),
2460 SND_SOC_DAPM_PGA("BST2", RT5659_PWR_ANLG_2,
2461 RT5659_PWR_BST2_P_BIT, 0, NULL, 0),
2462 SND_SOC_DAPM_PGA("BST3", RT5659_PWR_ANLG_2,
2463 RT5659_PWR_BST3_P_BIT, 0, NULL, 0),
2464 SND_SOC_DAPM_PGA("BST4", RT5659_PWR_ANLG_2,
2465 RT5659_PWR_BST4_P_BIT, 0, NULL, 0),
2466 SND_SOC_DAPM_SUPPLY("BST1 Power", RT5659_PWR_ANLG_2,
2467 RT5659_PWR_BST1_BIT, 0, NULL, 0),
2468 SND_SOC_DAPM_SUPPLY("BST2 Power", RT5659_PWR_ANLG_2,
2469 RT5659_PWR_BST2_BIT, 0, NULL, 0),
2470 SND_SOC_DAPM_SUPPLY("BST3 Power", RT5659_PWR_ANLG_2,
2471 RT5659_PWR_BST3_BIT, 0, NULL, 0),
2472 SND_SOC_DAPM_SUPPLY("BST4 Power", RT5659_PWR_ANLG_2,
2473 RT5659_PWR_BST4_BIT, 0, NULL, 0),
2474
2475
2476 /* Input Volume */
2477 SND_SOC_DAPM_PGA("INL VOL", RT5659_PWR_VOL, RT5659_PWR_IN_L_BIT,
2478 0, NULL, 0),
2479 SND_SOC_DAPM_PGA("INR VOL", RT5659_PWR_VOL, RT5659_PWR_IN_R_BIT,
2480 0, NULL, 0),
2481
2482 /* REC Mixer */
2483 SND_SOC_DAPM_MIXER("RECMIX1L", RT5659_PWR_MIXER, RT5659_PWR_RM1_L_BIT,
2484 0, rt5659_rec1_l_mix, ARRAY_SIZE(rt5659_rec1_l_mix)),
2485 SND_SOC_DAPM_MIXER("RECMIX1R", RT5659_PWR_MIXER, RT5659_PWR_RM1_R_BIT,
2486 0, rt5659_rec1_r_mix, ARRAY_SIZE(rt5659_rec1_r_mix)),
2487 SND_SOC_DAPM_MIXER("RECMIX2L", RT5659_PWR_MIXER, RT5659_PWR_RM2_L_BIT,
2488 0, rt5659_rec2_l_mix, ARRAY_SIZE(rt5659_rec2_l_mix)),
2489 SND_SOC_DAPM_MIXER("RECMIX2R", RT5659_PWR_MIXER, RT5659_PWR_RM2_R_BIT,
2490 0, rt5659_rec2_r_mix, ARRAY_SIZE(rt5659_rec2_r_mix)),
2491
2492 /* ADCs */
2493 SND_SOC_DAPM_ADC("ADC1 L", NULL, SND_SOC_NOPM, 0, 0),
2494 SND_SOC_DAPM_ADC("ADC1 R", NULL, SND_SOC_NOPM, 0, 0),
2495 SND_SOC_DAPM_ADC("ADC2 L", NULL, SND_SOC_NOPM, 0, 0),
2496 SND_SOC_DAPM_ADC("ADC2 R", NULL, SND_SOC_NOPM, 0, 0),
2497
2498 SND_SOC_DAPM_SUPPLY("ADC1 L Power", RT5659_PWR_DIG_1,
2499 RT5659_PWR_ADC_L1_BIT, 0, NULL, 0),
2500 SND_SOC_DAPM_SUPPLY("ADC1 R Power", RT5659_PWR_DIG_1,
2501 RT5659_PWR_ADC_R1_BIT, 0, NULL, 0),
2502 SND_SOC_DAPM_SUPPLY("ADC2 L Power", RT5659_PWR_DIG_2,
2503 RT5659_PWR_ADC_L2_BIT, 0, NULL, 0),
2504 SND_SOC_DAPM_SUPPLY("ADC2 R Power", RT5659_PWR_DIG_2,
2505 RT5659_PWR_ADC_R2_BIT, 0, NULL, 0),
2506 SND_SOC_DAPM_SUPPLY("ADC1 clock", SND_SOC_NOPM, 0, 0, set_adc_clk,
2507 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
2508 SND_SOC_DAPM_SUPPLY("ADC2 clock", SND_SOC_NOPM, 0, 0, set_adc_clk,
2509 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
2510
2511 /* ADC Mux */
2512 SND_SOC_DAPM_MUX("Stereo1 DMIC L Mux", SND_SOC_NOPM, 0, 0,
2513 &rt5659_sto1_dmic_mux),
2514 SND_SOC_DAPM_MUX("Stereo1 DMIC R Mux", SND_SOC_NOPM, 0, 0,
2515 &rt5659_sto1_dmic_mux),
2516 SND_SOC_DAPM_MUX("Stereo1 ADC L1 Mux", SND_SOC_NOPM, 0, 0,
2517 &rt5659_sto1_adc1_mux),
2518 SND_SOC_DAPM_MUX("Stereo1 ADC R1 Mux", SND_SOC_NOPM, 0, 0,
2519 &rt5659_sto1_adc1_mux),
2520 SND_SOC_DAPM_MUX("Stereo1 ADC L2 Mux", SND_SOC_NOPM, 0, 0,
2521 &rt5659_sto1_adc2_mux),
2522 SND_SOC_DAPM_MUX("Stereo1 ADC R2 Mux", SND_SOC_NOPM, 0, 0,
2523 &rt5659_sto1_adc2_mux),
2524 SND_SOC_DAPM_MUX("Stereo1 ADC L Mux", SND_SOC_NOPM, 0, 0,
2525 &rt5659_sto1_adc_mux),
2526 SND_SOC_DAPM_MUX("Stereo1 ADC R Mux", SND_SOC_NOPM, 0, 0,
2527 &rt5659_sto1_adc_mux),
2528 SND_SOC_DAPM_MUX("Mono ADC L2 Mux", SND_SOC_NOPM, 0, 0,
2529 &rt5659_mono_adc_l2_mux),
2530 SND_SOC_DAPM_MUX("Mono ADC R2 Mux", SND_SOC_NOPM, 0, 0,
2531 &rt5659_mono_adc_r2_mux),
2532 SND_SOC_DAPM_MUX("Mono ADC L1 Mux", SND_SOC_NOPM, 0, 0,
2533 &rt5659_mono_adc_l1_mux),
2534 SND_SOC_DAPM_MUX("Mono ADC R1 Mux", SND_SOC_NOPM, 0, 0,
2535 &rt5659_mono_adc_r1_mux),
2536 SND_SOC_DAPM_MUX("Mono DMIC L Mux", SND_SOC_NOPM, 0, 0,
2537 &rt5659_mono_dmic_l_mux),
2538 SND_SOC_DAPM_MUX("Mono DMIC R Mux", SND_SOC_NOPM, 0, 0,
2539 &rt5659_mono_dmic_r_mux),
2540 SND_SOC_DAPM_MUX("Mono ADC L Mux", SND_SOC_NOPM, 0, 0,
2541 &rt5659_mono_adc_l_mux),
2542 SND_SOC_DAPM_MUX("Mono ADC R Mux", SND_SOC_NOPM, 0, 0,
2543 &rt5659_mono_adc_r_mux),
2544 /* ADC Mixer */
2545 SND_SOC_DAPM_SUPPLY("ADC Stereo1 Filter", RT5659_PWR_DIG_2,
2546 RT5659_PWR_ADC_S1F_BIT, 0, NULL, 0),
2547 SND_SOC_DAPM_SUPPLY("ADC Stereo2 Filter", RT5659_PWR_DIG_2,
2548 RT5659_PWR_ADC_S2F_BIT, 0, NULL, 0),
2549 SND_SOC_DAPM_MIXER("Stereo1 ADC MIXL", SND_SOC_NOPM,
2550 0, 0, rt5659_sto1_adc_l_mix,
2551 ARRAY_SIZE(rt5659_sto1_adc_l_mix)),
2552 SND_SOC_DAPM_MIXER("Stereo1 ADC MIXR", SND_SOC_NOPM,
2553 0, 0, rt5659_sto1_adc_r_mix,
2554 ARRAY_SIZE(rt5659_sto1_adc_r_mix)),
2555 SND_SOC_DAPM_SUPPLY("ADC Mono Left Filter", RT5659_PWR_DIG_2,
2556 RT5659_PWR_ADC_MF_L_BIT, 0, NULL, 0),
2557 SND_SOC_DAPM_MIXER("Mono ADC MIXL", RT5659_MONO_ADC_DIG_VOL,
2558 RT5659_L_MUTE_SFT, 1, rt5659_mono_adc_l_mix,
2559 ARRAY_SIZE(rt5659_mono_adc_l_mix)),
2560 SND_SOC_DAPM_SUPPLY("ADC Mono Right Filter", RT5659_PWR_DIG_2,
2561 RT5659_PWR_ADC_MF_R_BIT, 0, NULL, 0),
2562 SND_SOC_DAPM_MIXER("Mono ADC MIXR", RT5659_MONO_ADC_DIG_VOL,
2563 RT5659_R_MUTE_SFT, 1, rt5659_mono_adc_r_mix,
2564 ARRAY_SIZE(rt5659_mono_adc_r_mix)),
2565
2566 /* ADC PGA */
2567 SND_SOC_DAPM_PGA("IF_ADC1", SND_SOC_NOPM, 0, 0, NULL, 0),
2568 SND_SOC_DAPM_PGA("IF_ADC2", SND_SOC_NOPM, 0, 0, NULL, 0),
2569 SND_SOC_DAPM_PGA("IF_ADC3", SND_SOC_NOPM, 0, 0, NULL, 0),
2570 SND_SOC_DAPM_PGA("IF1_ADC1", SND_SOC_NOPM, 0, 0, NULL, 0),
2571 SND_SOC_DAPM_PGA("IF1_ADC2", SND_SOC_NOPM, 0, 0, NULL, 0),
2572 SND_SOC_DAPM_PGA("IF1_ADC3", SND_SOC_NOPM, 0, 0, NULL, 0),
2573 SND_SOC_DAPM_PGA("IF1_ADC4", SND_SOC_NOPM, 0, 0, NULL, 0),
2574 SND_SOC_DAPM_PGA("Stereo2 ADC LR", SND_SOC_NOPM, 0, 0, NULL, 0),
2575
2576 SND_SOC_DAPM_PGA("Stereo1 ADC Volume L", RT5659_STO1_ADC_DIG_VOL,
2577 RT5659_L_MUTE_SFT, 1, NULL, 0),
2578 SND_SOC_DAPM_PGA("Stereo1 ADC Volume R", RT5659_STO1_ADC_DIG_VOL,
2579 RT5659_R_MUTE_SFT, 1, NULL, 0),
2580
2581 /* Digital Interface */
2582 SND_SOC_DAPM_SUPPLY("I2S1", RT5659_PWR_DIG_1, RT5659_PWR_I2S1_BIT,
2583 0, NULL, 0),
2584 SND_SOC_DAPM_PGA("IF1 DAC1", SND_SOC_NOPM, 0, 0, NULL, 0),
2585 SND_SOC_DAPM_PGA("IF1 DAC2", SND_SOC_NOPM, 0, 0, NULL, 0),
2586 SND_SOC_DAPM_PGA("IF1 DAC1 L", SND_SOC_NOPM, 0, 0, NULL, 0),
2587 SND_SOC_DAPM_PGA("IF1 DAC1 R", SND_SOC_NOPM, 0, 0, NULL, 0),
2588 SND_SOC_DAPM_PGA("IF1 DAC2 L", SND_SOC_NOPM, 0, 0, NULL, 0),
2589 SND_SOC_DAPM_PGA("IF1 DAC2 R", SND_SOC_NOPM, 0, 0, NULL, 0),
2590 SND_SOC_DAPM_PGA("IF1 ADC", SND_SOC_NOPM, 0, 0, NULL, 0),
2591 SND_SOC_DAPM_PGA("IF1 ADC L", SND_SOC_NOPM, 0, 0, NULL, 0),
2592 SND_SOC_DAPM_PGA("IF1 ADC R", SND_SOC_NOPM, 0, 0, NULL, 0),
2593 SND_SOC_DAPM_SUPPLY("I2S2", RT5659_PWR_DIG_1, RT5659_PWR_I2S2_BIT, 0,
2594 NULL, 0),
2595 SND_SOC_DAPM_PGA("IF2 DAC", SND_SOC_NOPM, 0, 0, NULL, 0),
2596 SND_SOC_DAPM_PGA("IF2 DAC L", SND_SOC_NOPM, 0, 0, NULL, 0),
2597 SND_SOC_DAPM_PGA("IF2 DAC R", SND_SOC_NOPM, 0, 0, NULL, 0),
2598 SND_SOC_DAPM_PGA("IF2 ADC", SND_SOC_NOPM, 0, 0, NULL, 0),
2599 SND_SOC_DAPM_PGA("IF2 ADC1", SND_SOC_NOPM, 0, 0, NULL, 0),
2600 SND_SOC_DAPM_PGA("IF2 ADC2", SND_SOC_NOPM, 0, 0, NULL, 0),
2601 SND_SOC_DAPM_SUPPLY("I2S3", RT5659_PWR_DIG_1, RT5659_PWR_I2S3_BIT, 0,
2602 NULL, 0),
2603 SND_SOC_DAPM_PGA("IF3 DAC", SND_SOC_NOPM, 0, 0, NULL, 0),
2604 SND_SOC_DAPM_PGA("IF3 DAC L", SND_SOC_NOPM, 0, 0, NULL, 0),
2605 SND_SOC_DAPM_PGA("IF3 DAC R", SND_SOC_NOPM, 0, 0, NULL, 0),
2606 SND_SOC_DAPM_PGA("IF3 ADC", SND_SOC_NOPM, 0, 0, NULL, 0),
2607 SND_SOC_DAPM_PGA("IF3 ADC L", SND_SOC_NOPM, 0, 0, NULL, 0),
2608 SND_SOC_DAPM_PGA("IF3 ADC R", SND_SOC_NOPM, 0, 0, NULL, 0),
2609
2610 /* Digital Interface Select */
2611 SND_SOC_DAPM_PGA("TDM AD1:AD2:DAC", SND_SOC_NOPM, 0, 0, NULL, 0),
2612 SND_SOC_DAPM_PGA("TDM AD2:DAC", SND_SOC_NOPM, 0, 0, NULL, 0),
2613 SND_SOC_DAPM_MUX("TDM Data Mux", SND_SOC_NOPM, 0, 0,
2614 &rt5659_rx_adc_dac_mux),
2615 SND_SOC_DAPM_MUX("IF2 ADC Mux", SND_SOC_NOPM, 0, 0,
2616 &rt5659_if2_adc_in_mux),
2617 SND_SOC_DAPM_MUX("IF3 ADC Mux", SND_SOC_NOPM, 0, 0,
2618 &rt5659_if3_adc_in_mux),
2619 SND_SOC_DAPM_MUX("IF1 01 ADC Swap Mux", SND_SOC_NOPM, 0, 0,
2620 &rt5659_if1_01_adc_swap_mux),
2621 SND_SOC_DAPM_MUX("IF1 23 ADC Swap Mux", SND_SOC_NOPM, 0, 0,
2622 &rt5659_if1_23_adc_swap_mux),
2623 SND_SOC_DAPM_MUX("IF1 45 ADC Swap Mux", SND_SOC_NOPM, 0, 0,
2624 &rt5659_if1_45_adc_swap_mux),
2625 SND_SOC_DAPM_MUX("IF1 67 ADC Swap Mux", SND_SOC_NOPM, 0, 0,
2626 &rt5659_if1_67_adc_swap_mux),
2627 SND_SOC_DAPM_MUX("IF2 DAC Swap Mux", SND_SOC_NOPM, 0, 0,
2628 &rt5659_if2_dac_swap_mux),
2629 SND_SOC_DAPM_MUX("IF2 ADC Swap Mux", SND_SOC_NOPM, 0, 0,
2630 &rt5659_if2_adc_swap_mux),
2631 SND_SOC_DAPM_MUX("IF3 DAC Swap Mux", SND_SOC_NOPM, 0, 0,
2632 &rt5659_if3_dac_swap_mux),
2633 SND_SOC_DAPM_MUX("IF3 ADC Swap Mux", SND_SOC_NOPM, 0, 0,
2634 &rt5659_if3_adc_swap_mux),
2635
2636 /* Audio Interface */
2637 SND_SOC_DAPM_AIF_IN("AIF1RX", "AIF1 Playback", 0, SND_SOC_NOPM, 0, 0),
2638 SND_SOC_DAPM_AIF_OUT("AIF1TX", "AIF1 Capture", 0, SND_SOC_NOPM, 0, 0),
2639 SND_SOC_DAPM_AIF_IN("AIF2RX", "AIF2 Playback", 0, SND_SOC_NOPM, 0, 0),
2640 SND_SOC_DAPM_AIF_OUT("AIF2TX", "AIF2 Capture", 0, SND_SOC_NOPM, 0, 0),
2641 SND_SOC_DAPM_AIF_IN("AIF3RX", "AIF3 Playback", 0, SND_SOC_NOPM, 0, 0),
2642 SND_SOC_DAPM_AIF_OUT("AIF3TX", "AIF3 Capture", 0, SND_SOC_NOPM, 0, 0),
2643
2644 /* Output Side */
2645 /* DAC mixer before sound effect */
2646 SND_SOC_DAPM_MIXER("DAC1 MIXL", SND_SOC_NOPM, 0, 0,
2647 rt5659_dac_l_mix, ARRAY_SIZE(rt5659_dac_l_mix)),
2648 SND_SOC_DAPM_MIXER("DAC1 MIXR", SND_SOC_NOPM, 0, 0,
2649 rt5659_dac_r_mix, ARRAY_SIZE(rt5659_dac_r_mix)),
2650
2651 /* DAC channel Mux */
2652 SND_SOC_DAPM_MUX("DAC L1 Mux", SND_SOC_NOPM, 0, 0, &rt5659_dac_l1_mux),
2653 SND_SOC_DAPM_MUX("DAC R1 Mux", SND_SOC_NOPM, 0, 0, &rt5659_dac_r1_mux),
2654 SND_SOC_DAPM_MUX("DAC L2 Mux", SND_SOC_NOPM, 0, 0, &rt5659_dac_l2_mux),
2655 SND_SOC_DAPM_MUX("DAC R2 Mux", SND_SOC_NOPM, 0, 0, &rt5659_dac_r2_mux),
2656
2657 SND_SOC_DAPM_MUX("DAC L1 Source", SND_SOC_NOPM, 0, 0,
2658 &rt5659_alg_dac_l1_mux),
2659 SND_SOC_DAPM_MUX("DAC R1 Source", SND_SOC_NOPM, 0, 0,
2660 &rt5659_alg_dac_r1_mux),
2661 SND_SOC_DAPM_MUX("DAC L2 Source", SND_SOC_NOPM, 0, 0,
2662 &rt5659_alg_dac_l2_mux),
2663 SND_SOC_DAPM_MUX("DAC R2 Source", SND_SOC_NOPM, 0, 0,
2664 &rt5659_alg_dac_r2_mux),
2665
2666 /* DAC Mixer */
2667 SND_SOC_DAPM_SUPPLY("DAC Stereo1 Filter", RT5659_PWR_DIG_2,
2668 RT5659_PWR_DAC_S1F_BIT, 0, NULL, 0),
2669 SND_SOC_DAPM_SUPPLY("DAC Mono Left Filter", RT5659_PWR_DIG_2,
2670 RT5659_PWR_DAC_MF_L_BIT, 0, NULL, 0),
2671 SND_SOC_DAPM_SUPPLY("DAC Mono Right Filter", RT5659_PWR_DIG_2,
2672 RT5659_PWR_DAC_MF_R_BIT, 0, NULL, 0),
2673 SND_SOC_DAPM_MIXER("Stereo DAC MIXL", SND_SOC_NOPM, 0, 0,
2674 rt5659_sto_dac_l_mix, ARRAY_SIZE(rt5659_sto_dac_l_mix)),
2675 SND_SOC_DAPM_MIXER("Stereo DAC MIXR", SND_SOC_NOPM, 0, 0,
2676 rt5659_sto_dac_r_mix, ARRAY_SIZE(rt5659_sto_dac_r_mix)),
2677 SND_SOC_DAPM_MIXER("Mono DAC MIXL", SND_SOC_NOPM, 0, 0,
2678 rt5659_mono_dac_l_mix, ARRAY_SIZE(rt5659_mono_dac_l_mix)),
2679 SND_SOC_DAPM_MIXER("Mono DAC MIXR", SND_SOC_NOPM, 0, 0,
2680 rt5659_mono_dac_r_mix, ARRAY_SIZE(rt5659_mono_dac_r_mix)),
2681 SND_SOC_DAPM_MUX("DAC MIXL", SND_SOC_NOPM, 0, 0,
2682 &rt5659_dig_dac_mixl_mux),
2683 SND_SOC_DAPM_MUX("DAC MIXR", SND_SOC_NOPM, 0, 0,
2684 &rt5659_dig_dac_mixr_mux),
2685
2686 /* DACs */
2687 SND_SOC_DAPM_SUPPLY_S("DAC L1 Power", 1, RT5659_PWR_DIG_1,
2688 RT5659_PWR_DAC_L1_BIT, 0, NULL, 0),
2689 SND_SOC_DAPM_SUPPLY_S("DAC R1 Power", 1, RT5659_PWR_DIG_1,
2690 RT5659_PWR_DAC_R1_BIT, 0, NULL, 0),
2691 SND_SOC_DAPM_DAC("DAC L1", NULL, SND_SOC_NOPM, 0, 0),
2692 SND_SOC_DAPM_DAC("DAC R1", NULL, SND_SOC_NOPM, 0, 0),
2693
2694 SND_SOC_DAPM_SUPPLY("DAC L2 Power", RT5659_PWR_DIG_1,
2695 RT5659_PWR_DAC_L2_BIT, 0, NULL, 0),
2696 SND_SOC_DAPM_SUPPLY("DAC R2 Power", RT5659_PWR_DIG_1,
2697 RT5659_PWR_DAC_R2_BIT, 0, NULL, 0),
2698 SND_SOC_DAPM_DAC("DAC L2", NULL, SND_SOC_NOPM, 0, 0),
2699 SND_SOC_DAPM_DAC("DAC R2", NULL, SND_SOC_NOPM, 0, 0),
2700 SND_SOC_DAPM_PGA("DAC_REF", SND_SOC_NOPM, 0, 0, NULL, 0),
2701
2702 /* OUT Mixer */
2703 SND_SOC_DAPM_MIXER("SPK MIXL", RT5659_PWR_MIXER, RT5659_PWR_SM_L_BIT,
2704 0, rt5659_spk_l_mix, ARRAY_SIZE(rt5659_spk_l_mix)),
2705 SND_SOC_DAPM_MIXER("SPK MIXR", RT5659_PWR_MIXER, RT5659_PWR_SM_R_BIT,
2706 0, rt5659_spk_r_mix, ARRAY_SIZE(rt5659_spk_r_mix)),
2707 SND_SOC_DAPM_MIXER("MONOVOL MIX", RT5659_PWR_MIXER, RT5659_PWR_MM_BIT,
2708 0, rt5659_monovol_mix, ARRAY_SIZE(rt5659_monovol_mix)),
2709 SND_SOC_DAPM_MIXER("OUT MIXL", RT5659_PWR_MIXER, RT5659_PWR_OM_L_BIT,
2710 0, rt5659_out_l_mix, ARRAY_SIZE(rt5659_out_l_mix)),
2711 SND_SOC_DAPM_MIXER("OUT MIXR", RT5659_PWR_MIXER, RT5659_PWR_OM_R_BIT,
2712 0, rt5659_out_r_mix, ARRAY_SIZE(rt5659_out_r_mix)),
2713
2714 /* Output Volume */
2715 SND_SOC_DAPM_SWITCH("SPKVOL L", RT5659_PWR_VOL, RT5659_PWR_SV_L_BIT, 0,
2716 &spkvol_l_switch),
2717 SND_SOC_DAPM_SWITCH("SPKVOL R", RT5659_PWR_VOL, RT5659_PWR_SV_R_BIT, 0,
2718 &spkvol_r_switch),
2719 SND_SOC_DAPM_SWITCH("MONOVOL", RT5659_PWR_VOL, RT5659_PWR_MV_BIT, 0,
2720 &monovol_switch),
2721 SND_SOC_DAPM_SWITCH("OUTVOL L", RT5659_PWR_VOL, RT5659_PWR_OV_L_BIT, 0,
2722 &outvol_l_switch),
2723 SND_SOC_DAPM_SWITCH("OUTVOL R", RT5659_PWR_VOL, RT5659_PWR_OV_R_BIT, 0,
2724 &outvol_r_switch),
2725
2726 /* SPO/MONO/HPO/LOUT */
2727 SND_SOC_DAPM_MIXER("SPO L MIX", SND_SOC_NOPM, 0, 0, rt5659_spo_l_mix,
2728 ARRAY_SIZE(rt5659_spo_l_mix)),
2729 SND_SOC_DAPM_MIXER("SPO R MIX", SND_SOC_NOPM, 0, 0, rt5659_spo_r_mix,
2730 ARRAY_SIZE(rt5659_spo_r_mix)),
2731 SND_SOC_DAPM_MIXER("Mono MIX", SND_SOC_NOPM, 0, 0, rt5659_mono_mix,
2732 ARRAY_SIZE(rt5659_mono_mix)),
2733 SND_SOC_DAPM_MIXER("LOUT L MIX", SND_SOC_NOPM, 0, 0, rt5659_lout_l_mix,
2734 ARRAY_SIZE(rt5659_lout_l_mix)),
2735 SND_SOC_DAPM_MIXER("LOUT R MIX", SND_SOC_NOPM, 0, 0, rt5659_lout_r_mix,
2736 ARRAY_SIZE(rt5659_lout_r_mix)),
2737
2738 SND_SOC_DAPM_PGA_S("SPK Amp", 1, RT5659_PWR_DIG_1, RT5659_PWR_CLS_D_BIT,
2739 0, rt5659_spk_event, SND_SOC_DAPM_POST_PMD |
2740 SND_SOC_DAPM_PRE_PMU),
2741 SND_SOC_DAPM_PGA_S("Mono Amp", 1, RT5659_PWR_ANLG_1, RT5659_PWR_MA_BIT,
2742 0, rt5659_mono_event, SND_SOC_DAPM_POST_PMD |
2743 SND_SOC_DAPM_PRE_PMU),
2744 SND_SOC_DAPM_PGA_S("HP Amp", 1, SND_SOC_NOPM, 0, 0, rt5659_hp_event,
2745 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
2746 SND_SOC_DAPM_PGA("LOUT Amp", SND_SOC_NOPM, 0, 0, NULL, 0),
2747
2748 SND_SOC_DAPM_SUPPLY("Charge Pump", SND_SOC_NOPM, 0, 0,
2749 rt5659_charge_pump_event, SND_SOC_DAPM_PRE_PMU |
2750 SND_SOC_DAPM_POST_PMD),
2751
2752 SND_SOC_DAPM_SWITCH("SPO Playback", SND_SOC_NOPM, 0, 0, &spo_switch),
2753 SND_SOC_DAPM_SWITCH("Mono Playback", SND_SOC_NOPM, 0, 0,
2754 &mono_switch),
2755 SND_SOC_DAPM_SWITCH("HPO L Playback", SND_SOC_NOPM, 0, 0,
2756 &hpo_l_switch),
2757 SND_SOC_DAPM_SWITCH("HPO R Playback", SND_SOC_NOPM, 0, 0,
2758 &hpo_r_switch),
2759 SND_SOC_DAPM_SWITCH("LOUT L Playback", SND_SOC_NOPM, 0, 0,
2760 &lout_l_switch),
2761 SND_SOC_DAPM_SWITCH("LOUT R Playback", SND_SOC_NOPM, 0, 0,
2762 &lout_r_switch),
2763 SND_SOC_DAPM_SWITCH("PDM L Playback", SND_SOC_NOPM, 0, 0,
2764 &pdm_l_switch),
2765 SND_SOC_DAPM_SWITCH("PDM R Playback", SND_SOC_NOPM, 0, 0,
2766 &pdm_r_switch),
2767
2768 /* PDM */
2769 SND_SOC_DAPM_SUPPLY("PDM Power", RT5659_PWR_DIG_2,
2770 RT5659_PWR_PDM1_BIT, 0, NULL, 0),
2771 SND_SOC_DAPM_MUX("PDM L Mux", RT5659_PDM_OUT_CTRL,
2772 RT5659_M_PDM1_L_SFT, 1, &rt5659_pdm_l_mux),
2773 SND_SOC_DAPM_MUX("PDM R Mux", RT5659_PDM_OUT_CTRL,
2774 RT5659_M_PDM1_R_SFT, 1, &rt5659_pdm_r_mux),
2775
2776 /* SPDIF */
2777 SND_SOC_DAPM_MUX("SPDIF Mux", SND_SOC_NOPM, 0, 0, &rt5659_spdif_mux),
2778
2779 SND_SOC_DAPM_SUPPLY("SYS CLK DET", RT5659_CLK_DET, 3, 0, NULL, 0),
2780 SND_SOC_DAPM_SUPPLY("CLKDET", RT5659_CLK_DET, 0, 0, NULL, 0),
2781
2782 /* Output Lines */
2783 SND_SOC_DAPM_OUTPUT("HPOL"),
2784 SND_SOC_DAPM_OUTPUT("HPOR"),
2785 SND_SOC_DAPM_OUTPUT("SPOL"),
2786 SND_SOC_DAPM_OUTPUT("SPOR"),
2787 SND_SOC_DAPM_OUTPUT("LOUTL"),
2788 SND_SOC_DAPM_OUTPUT("LOUTR"),
2789 SND_SOC_DAPM_OUTPUT("MONOOUT"),
2790 SND_SOC_DAPM_OUTPUT("PDML"),
2791 SND_SOC_DAPM_OUTPUT("PDMR"),
2792 SND_SOC_DAPM_OUTPUT("SPDIF"),
2793};
2794
2795static const struct snd_soc_dapm_route rt5659_dapm_routes[] = {
2796 /*PLL*/
2797 { "ADC Stereo1 Filter", NULL, "PLL", is_sys_clk_from_pll },
2798 { "ADC Stereo2 Filter", NULL, "PLL", is_sys_clk_from_pll },
2799 { "ADC Mono Left Filter", NULL, "PLL", is_sys_clk_from_pll },
2800 { "ADC Mono Right Filter", NULL, "PLL", is_sys_clk_from_pll },
2801 { "DAC Stereo1 Filter", NULL, "PLL", is_sys_clk_from_pll },
2802 { "DAC Mono Left Filter", NULL, "PLL", is_sys_clk_from_pll },
2803 { "DAC Mono Right Filter", NULL, "PLL", is_sys_clk_from_pll },
2804
2805 /*ASRC*/
2806 { "ADC Stereo1 Filter", NULL, "ADC STO1 ASRC", is_using_asrc },
2807 { "ADC Mono Left Filter", NULL, "ADC Mono L ASRC", is_using_asrc },
2808 { "ADC Mono Right Filter", NULL, "ADC Mono R ASRC", is_using_asrc },
2809 { "DAC Mono Left Filter", NULL, "DAC Mono L ASRC", is_using_asrc },
2810 { "DAC Mono Right Filter", NULL, "DAC Mono R ASRC", is_using_asrc },
2811 { "DAC Stereo1 Filter", NULL, "DAC STO ASRC", is_using_asrc },
2812
2813 { "SYS CLK DET", NULL, "CLKDET" },
2814
2815 { "I2S1", NULL, "I2S1 ASRC" },
2816 { "I2S2", NULL, "I2S2 ASRC" },
2817 { "I2S3", NULL, "I2S3 ASRC" },
2818
2819 { "IN1P", NULL, "LDO2" },
2820 { "IN2P", NULL, "LDO2" },
2821 { "IN3P", NULL, "LDO2" },
2822 { "IN4P", NULL, "LDO2" },
2823
2824 { "DMIC1", NULL, "DMIC L1" },
2825 { "DMIC1", NULL, "DMIC R1" },
2826 { "DMIC2", NULL, "DMIC L2" },
2827 { "DMIC2", NULL, "DMIC R2" },
2828
2829 { "BST1", NULL, "IN1P" },
2830 { "BST1", NULL, "IN1N" },
2831 { "BST1", NULL, "BST1 Power" },
2832 { "BST2", NULL, "IN2P" },
2833 { "BST2", NULL, "IN2N" },
2834 { "BST2", NULL, "BST2 Power" },
2835 { "BST3", NULL, "IN3P" },
2836 { "BST3", NULL, "IN3N" },
2837 { "BST3", NULL, "BST3 Power" },
2838 { "BST4", NULL, "IN4P" },
2839 { "BST4", NULL, "IN4N" },
2840 { "BST4", NULL, "BST4 Power" },
2841
2842 { "INL VOL", NULL, "IN2P" },
2843 { "INR VOL", NULL, "IN2N" },
2844
2845 { "RECMIX1L", "SPKVOLL Switch", "SPKVOL L" },
2846 { "RECMIX1L", "INL Switch", "INL VOL" },
2847 { "RECMIX1L", "BST4 Switch", "BST4" },
2848 { "RECMIX1L", "BST3 Switch", "BST3" },
2849 { "RECMIX1L", "BST2 Switch", "BST2" },
2850 { "RECMIX1L", "BST1 Switch", "BST1" },
2851
2852 { "RECMIX1R", "HPOVOLR Switch", "HPO R Playback" },
2853 { "RECMIX1R", "INR Switch", "INR VOL" },
2854 { "RECMIX1R", "BST4 Switch", "BST4" },
2855 { "RECMIX1R", "BST3 Switch", "BST3" },
2856 { "RECMIX1R", "BST2 Switch", "BST2" },
2857 { "RECMIX1R", "BST1 Switch", "BST1" },
2858
2859 { "RECMIX2L", "SPKVOLL Switch", "SPKVOL L" },
2860 { "RECMIX2L", "OUTVOLL Switch", "OUTVOL L" },
2861 { "RECMIX2L", "BST4 Switch", "BST4" },
2862 { "RECMIX2L", "BST3 Switch", "BST3" },
2863 { "RECMIX2L", "BST2 Switch", "BST2" },
2864 { "RECMIX2L", "BST1 Switch", "BST1" },
2865
2866 { "RECMIX2R", "MONOVOL Switch", "MONOVOL" },
2867 { "RECMIX2R", "OUTVOLR Switch", "OUTVOL R" },
2868 { "RECMIX2R", "BST4 Switch", "BST4" },
2869 { "RECMIX2R", "BST3 Switch", "BST3" },
2870 { "RECMIX2R", "BST2 Switch", "BST2" },
2871 { "RECMIX2R", "BST1 Switch", "BST1" },
2872
2873 { "ADC1 L", NULL, "RECMIX1L" },
2874 { "ADC1 L", NULL, "ADC1 L Power" },
2875 { "ADC1 L", NULL, "ADC1 clock" },
2876 { "ADC1 R", NULL, "RECMIX1R" },
2877 { "ADC1 R", NULL, "ADC1 R Power" },
2878 { "ADC1 R", NULL, "ADC1 clock" },
2879
2880 { "ADC2 L", NULL, "RECMIX2L" },
2881 { "ADC2 L", NULL, "ADC2 L Power" },
2882 { "ADC2 L", NULL, "ADC2 clock" },
2883 { "ADC2 R", NULL, "RECMIX2R" },
2884 { "ADC2 R", NULL, "ADC2 R Power" },
2885 { "ADC2 R", NULL, "ADC2 clock" },
2886
2887 { "DMIC L1", NULL, "DMIC CLK" },
2888 { "DMIC L1", NULL, "DMIC1 Power" },
2889 { "DMIC R1", NULL, "DMIC CLK" },
2890 { "DMIC R1", NULL, "DMIC1 Power" },
2891 { "DMIC L2", NULL, "DMIC CLK" },
2892 { "DMIC L2", NULL, "DMIC2 Power" },
2893 { "DMIC R2", NULL, "DMIC CLK" },
2894 { "DMIC R2", NULL, "DMIC2 Power" },
2895
2896 { "Stereo1 DMIC L Mux", "DMIC1", "DMIC L1" },
2897 { "Stereo1 DMIC L Mux", "DMIC2", "DMIC L2" },
2898
2899 { "Stereo1 DMIC R Mux", "DMIC1", "DMIC R1" },
2900 { "Stereo1 DMIC R Mux", "DMIC2", "DMIC R2" },
2901
2902 { "Mono DMIC L Mux", "DMIC1 L", "DMIC L1" },
2903 { "Mono DMIC L Mux", "DMIC2 L", "DMIC L2" },
2904
2905 { "Mono DMIC R Mux", "DMIC1 R", "DMIC R1" },
2906 { "Mono DMIC R Mux", "DMIC2 R", "DMIC R2" },
2907
2908 { "Stereo1 ADC L Mux", "ADC1", "ADC1 L" },
2909 { "Stereo1 ADC L Mux", "ADC2", "ADC2 L" },
2910 { "Stereo1 ADC R Mux", "ADC1", "ADC1 R" },
2911 { "Stereo1 ADC R Mux", "ADC2", "ADC2 R" },
2912
2913 { "Stereo1 ADC L1 Mux", "ADC", "Stereo1 ADC L Mux" },
2914 { "Stereo1 ADC L1 Mux", "DAC MIX", "DAC MIXL" },
2915 { "Stereo1 ADC L2 Mux", "DMIC", "Stereo1 DMIC L Mux" },
2916 { "Stereo1 ADC L2 Mux", "DAC MIX", "DAC MIXL" },
2917
2918 { "Stereo1 ADC R1 Mux", "ADC", "Stereo1 ADC R Mux" },
2919 { "Stereo1 ADC R1 Mux", "DAC MIX", "DAC MIXR" },
2920 { "Stereo1 ADC R2 Mux", "DMIC", "Stereo1 DMIC R Mux" },
2921 { "Stereo1 ADC R2 Mux", "DAC MIX", "DAC MIXR" },
2922
2923 { "Mono ADC L Mux", "ADC1 L", "ADC1 L" },
2924 { "Mono ADC L Mux", "ADC1 R", "ADC1 R" },
2925 { "Mono ADC L Mux", "ADC2 L", "ADC2 L" },
2926 { "Mono ADC L Mux", "ADC2 R", "ADC2 R" },
2927
2928 { "Mono ADC R Mux", "ADC1 L", "ADC1 L" },
2929 { "Mono ADC R Mux", "ADC1 R", "ADC1 R" },
2930 { "Mono ADC R Mux", "ADC2 L", "ADC2 L" },
2931 { "Mono ADC R Mux", "ADC2 R", "ADC2 R" },
2932
2933 { "Mono ADC L2 Mux", "DMIC", "Mono DMIC L Mux" },
2934 { "Mono ADC L2 Mux", "Mono DAC MIXL", "Mono DAC MIXL" },
2935 { "Mono ADC L1 Mux", "Mono DAC MIXL", "Mono DAC MIXL" },
2936 { "Mono ADC L1 Mux", "ADC", "Mono ADC L Mux" },
2937
2938 { "Mono ADC R1 Mux", "Mono DAC MIXR", "Mono DAC MIXR" },
2939 { "Mono ADC R1 Mux", "ADC", "Mono ADC R Mux" },
2940 { "Mono ADC R2 Mux", "DMIC", "Mono DMIC R Mux" },
2941 { "Mono ADC R2 Mux", "Mono DAC MIXR", "Mono DAC MIXR" },
2942
2943 { "Stereo1 ADC MIXL", "ADC1 Switch", "Stereo1 ADC L1 Mux" },
2944 { "Stereo1 ADC MIXL", "ADC2 Switch", "Stereo1 ADC L2 Mux" },
2945 { "Stereo1 ADC MIXL", NULL, "ADC Stereo1 Filter" },
2946
2947 { "Stereo1 ADC MIXR", "ADC1 Switch", "Stereo1 ADC R1 Mux" },
2948 { "Stereo1 ADC MIXR", "ADC2 Switch", "Stereo1 ADC R2 Mux" },
2949 { "Stereo1 ADC MIXR", NULL, "ADC Stereo1 Filter" },
2950
2951 { "Mono ADC MIXL", "ADC1 Switch", "Mono ADC L1 Mux" },
2952 { "Mono ADC MIXL", "ADC2 Switch", "Mono ADC L2 Mux" },
2953 { "Mono ADC MIXL", NULL, "ADC Mono Left Filter" },
2954
2955 { "Mono ADC MIXR", "ADC1 Switch", "Mono ADC R1 Mux" },
2956 { "Mono ADC MIXR", "ADC2 Switch", "Mono ADC R2 Mux" },
2957 { "Mono ADC MIXR", NULL, "ADC Mono Right Filter" },
2958
2959 { "Stereo1 ADC Volume L", NULL, "Stereo1 ADC MIXL" },
2960 { "Stereo1 ADC Volume R", NULL, "Stereo1 ADC MIXR" },
2961
2962 { "IF_ADC1", NULL, "Stereo1 ADC Volume L" },
2963 { "IF_ADC1", NULL, "Stereo1 ADC Volume R" },
2964 { "IF_ADC2", NULL, "Mono ADC MIXL" },
2965 { "IF_ADC2", NULL, "Mono ADC MIXR" },
2966
2967 { "TDM AD1:AD2:DAC", NULL, "IF_ADC1" },
2968 { "TDM AD1:AD2:DAC", NULL, "IF_ADC2" },
2969 { "TDM AD1:AD2:DAC", NULL, "DAC_REF" },
2970 { "TDM AD2:DAC", NULL, "IF_ADC2" },
2971 { "TDM AD2:DAC", NULL, "DAC_REF" },
2972 { "TDM Data Mux", "AD1:AD2:DAC:NUL", "TDM AD1:AD2:DAC" },
2973 { "TDM Data Mux", "AD1:AD2:NUL:DAC", "TDM AD1:AD2:DAC" },
2974 { "TDM Data Mux", "AD1:DAC:AD2:NUL", "TDM AD1:AD2:DAC" },
2975 { "TDM Data Mux", "AD1:DAC:NUL:AD2", "TDM AD1:AD2:DAC" },
2976 { "TDM Data Mux", "AD1:NUL:DAC:AD2", "TDM AD1:AD2:DAC" },
2977 { "TDM Data Mux", "AD1:NUL:AD2:DAC", "TDM AD1:AD2:DAC" },
2978 { "TDM Data Mux", "AD2:AD1:DAC:NUL", "TDM AD1:AD2:DAC" },
2979 { "TDM Data Mux", "AD2:AD1:NUL:DAC", "TDM AD1:AD2:DAC" },
2980 { "TDM Data Mux", "AD2:DAC:AD1:NUL", "TDM AD1:AD2:DAC" },
2981 { "TDM Data Mux", "AD2:DAC:NUL:AD1", "TDM AD1:AD2:DAC" },
2982 { "TDM Data Mux", "AD2:NUL:DAC:AD1", "TDM AD1:AD2:DAC" },
2983 { "TDM Data Mux", "AD1:NUL:AD1:DAC", "TDM AD1:AD2:DAC" },
2984 { "TDM Data Mux", "DAC:AD1:AD2:NUL", "TDM AD1:AD2:DAC" },
2985 { "TDM Data Mux", "DAC:AD1:NUL:AD2", "TDM AD1:AD2:DAC" },
2986 { "TDM Data Mux", "DAC:AD2:AD1:NUL", "TDM AD1:AD2:DAC" },
2987 { "TDM Data Mux", "DAC:AD2:NUL:AD1", "TDM AD1:AD2:DAC" },
2988 { "TDM Data Mux", "DAC:NUL:DAC:AD2", "TDM AD2:DAC" },
2989 { "TDM Data Mux", "DAC:NUL:AD2:DAC", "TDM AD2:DAC" },
2990 { "TDM Data Mux", "NUL:AD1:AD2:DAC", "TDM AD1:AD2:DAC" },
2991 { "TDM Data Mux", "NUL:AD1:DAC:AD2", "TDM AD1:AD2:DAC" },
2992 { "TDM Data Mux", "NUL:AD2:AD1:DAC", "TDM AD1:AD2:DAC" },
2993 { "TDM Data Mux", "NUL:AD2:DAC:AD1", "TDM AD1:AD2:DAC" },
2994 { "TDM Data Mux", "NUL:DAC:DAC:AD2", "TDM AD2:DAC" },
2995 { "TDM Data Mux", "NUL:DAC:AD2:DAC", "TDM AD2:DAC" },
2996 { "IF1 01 ADC Swap Mux", "L/R", "TDM Data Mux" },
2997 { "IF1 01 ADC Swap Mux", "R/L", "TDM Data Mux" },
2998 { "IF1 01 ADC Swap Mux", "L/L", "TDM Data Mux" },
2999 { "IF1 01 ADC Swap Mux", "R/R", "TDM Data Mux" },
3000 { "IF1 23 ADC Swap Mux", "L/R", "TDM Data Mux" },
3001 { "IF1 23 ADC Swap Mux", "R/L", "TDM Data Mux" },
3002 { "IF1 23 ADC Swap Mux", "L/L", "TDM Data Mux" },
3003 { "IF1 23 ADC Swap Mux", "R/R", "TDM Data Mux" },
3004 { "IF1 45 ADC Swap Mux", "L/R", "TDM Data Mux" },
3005 { "IF1 45 ADC Swap Mux", "R/L", "TDM Data Mux" },
3006 { "IF1 45 ADC Swap Mux", "L/L", "TDM Data Mux" },
3007 { "IF1 45 ADC Swap Mux", "R/R", "TDM Data Mux" },
3008 { "IF1 67 ADC Swap Mux", "L/R", "TDM Data Mux" },
3009 { "IF1 67 ADC Swap Mux", "R/L", "TDM Data Mux" },
3010 { "IF1 67 ADC Swap Mux", "L/L", "TDM Data Mux" },
3011 { "IF1 67 ADC Swap Mux", "R/R", "TDM Data Mux" },
3012 { "IF1 ADC", NULL, "IF1 01 ADC Swap Mux" },
3013 { "IF1 ADC", NULL, "IF1 23 ADC Swap Mux" },
3014 { "IF1 ADC", NULL, "IF1 45 ADC Swap Mux" },
3015 { "IF1 ADC", NULL, "IF1 67 ADC Swap Mux" },
3016 { "IF1 ADC", NULL, "I2S1" },
3017
3018 { "IF2 ADC Mux", "IF_ADC1", "IF_ADC1" },
3019 { "IF2 ADC Mux", "IF_ADC2", "IF_ADC2" },
3020 { "IF2 ADC Mux", "IF_ADC3", "IF_ADC3" },
3021 { "IF2 ADC Mux", "DAC_REF", "DAC_REF" },
3022 { "IF2 ADC", NULL, "IF2 ADC Mux"},
3023 { "IF2 ADC", NULL, "I2S2" },
3024
3025 { "IF3 ADC Mux", "IF_ADC1", "IF_ADC1" },
3026 { "IF3 ADC Mux", "IF_ADC2", "IF_ADC2" },
3027 { "IF3 ADC Mux", "Stereo2_ADC_L/R", "Stereo2 ADC LR" },
3028 { "IF3 ADC Mux", "DAC_REF", "DAC_REF" },
3029 { "IF3 ADC", NULL, "IF3 ADC Mux"},
3030 { "IF3 ADC", NULL, "I2S3" },
3031
3032 { "AIF1TX", NULL, "IF1 ADC" },
3033 { "IF2 ADC Swap Mux", "L/R", "IF2 ADC" },
3034 { "IF2 ADC Swap Mux", "R/L", "IF2 ADC" },
3035 { "IF2 ADC Swap Mux", "L/L", "IF2 ADC" },
3036 { "IF2 ADC Swap Mux", "R/R", "IF2 ADC" },
3037 { "AIF2TX", NULL, "IF2 ADC Swap Mux" },
3038 { "IF3 ADC Swap Mux", "L/R", "IF3 ADC" },
3039 { "IF3 ADC Swap Mux", "R/L", "IF3 ADC" },
3040 { "IF3 ADC Swap Mux", "L/L", "IF3 ADC" },
3041 { "IF3 ADC Swap Mux", "R/R", "IF3 ADC" },
3042 { "AIF3TX", NULL, "IF3 ADC Swap Mux" },
3043
3044 { "IF1 DAC1", NULL, "AIF1RX" },
3045 { "IF1 DAC2", NULL, "AIF1RX" },
3046 { "IF2 DAC Swap Mux", "L/R", "AIF2RX" },
3047 { "IF2 DAC Swap Mux", "R/L", "AIF2RX" },
3048 { "IF2 DAC Swap Mux", "L/L", "AIF2RX" },
3049 { "IF2 DAC Swap Mux", "R/R", "AIF2RX" },
3050 { "IF2 DAC", NULL, "IF2 DAC Swap Mux" },
3051 { "IF3 DAC Swap Mux", "L/R", "AIF3RX" },
3052 { "IF3 DAC Swap Mux", "R/L", "AIF3RX" },
3053 { "IF3 DAC Swap Mux", "L/L", "AIF3RX" },
3054 { "IF3 DAC Swap Mux", "R/R", "AIF3RX" },
3055 { "IF3 DAC", NULL, "IF3 DAC Swap Mux" },
3056
3057 { "IF1 DAC1", NULL, "I2S1" },
3058 { "IF1 DAC2", NULL, "I2S1" },
3059 { "IF2 DAC", NULL, "I2S2" },
3060 { "IF3 DAC", NULL, "I2S3" },
3061
3062 { "IF1 DAC2 L", NULL, "IF1 DAC2" },
3063 { "IF1 DAC2 R", NULL, "IF1 DAC2" },
3064 { "IF1 DAC1 L", NULL, "IF1 DAC1" },
3065 { "IF1 DAC1 R", NULL, "IF1 DAC1" },
3066 { "IF2 DAC L", NULL, "IF2 DAC" },
3067 { "IF2 DAC R", NULL, "IF2 DAC" },
3068 { "IF3 DAC L", NULL, "IF3 DAC" },
3069 { "IF3 DAC R", NULL, "IF3 DAC" },
3070
3071 { "DAC L1 Mux", "IF1 DAC1", "IF1 DAC1 L" },
3072 { "DAC L1 Mux", "IF2 DAC", "IF2 DAC L" },
3073 { "DAC L1 Mux", "IF3 DAC", "IF3 DAC L" },
3074 { "DAC L1 Mux", NULL, "DAC Stereo1 Filter" },
3075
3076 { "DAC R1 Mux", "IF1 DAC1", "IF1 DAC1 R" },
3077 { "DAC R1 Mux", "IF2 DAC", "IF2 DAC R" },
3078 { "DAC R1 Mux", "IF3 DAC", "IF3 DAC R" },
3079 { "DAC R1 Mux", NULL, "DAC Stereo1 Filter" },
3080
3081 { "DAC1 MIXL", "Stereo ADC Switch", "Stereo1 ADC Volume L" },
3082 { "DAC1 MIXL", "DAC1 Switch", "DAC L1 Mux" },
3083 { "DAC1 MIXR", "Stereo ADC Switch", "Stereo1 ADC Volume R" },
3084 { "DAC1 MIXR", "DAC1 Switch", "DAC R1 Mux" },
3085
3086 { "DAC_REF", NULL, "DAC1 MIXL" },
3087 { "DAC_REF", NULL, "DAC1 MIXR" },
3088
3089 { "DAC L2 Mux", "IF1 DAC2", "IF1 DAC2 L" },
3090 { "DAC L2 Mux", "IF2 DAC", "IF2 DAC L" },
3091 { "DAC L2 Mux", "IF3 DAC", "IF3 DAC L" },
3092 { "DAC L2 Mux", "Mono ADC MIX", "Mono ADC MIXL" },
3093 { "DAC L2 Mux", NULL, "DAC Mono Left Filter" },
3094
3095 { "DAC R2 Mux", "IF1 DAC2", "IF1 DAC2 R" },
3096 { "DAC R2 Mux", "IF2 DAC", "IF2 DAC R" },
3097 { "DAC R2 Mux", "IF3 DAC", "IF3 DAC R" },
3098 { "DAC R2 Mux", "Mono ADC MIX", "Mono ADC MIXR" },
3099 { "DAC R2 Mux", NULL, "DAC Mono Right Filter" },
3100
3101 { "Stereo DAC MIXL", "DAC L1 Switch", "DAC1 MIXL" },
3102 { "Stereo DAC MIXL", "DAC R1 Switch", "DAC1 MIXR" },
3103 { "Stereo DAC MIXL", "DAC L2 Switch", "DAC L2 Mux" },
3104 { "Stereo DAC MIXL", "DAC R2 Switch", "DAC R2 Mux" },
3105
3106 { "Stereo DAC MIXR", "DAC R1 Switch", "DAC1 MIXR" },
3107 { "Stereo DAC MIXR", "DAC L1 Switch", "DAC1 MIXL" },
3108 { "Stereo DAC MIXR", "DAC L2 Switch", "DAC L2 Mux" },
3109 { "Stereo DAC MIXR", "DAC R2 Switch", "DAC R2 Mux" },
3110
3111 { "Mono DAC MIXL", "DAC L1 Switch", "DAC1 MIXL" },
3112 { "Mono DAC MIXL", "DAC R1 Switch", "DAC1 MIXR" },
3113 { "Mono DAC MIXL", "DAC L2 Switch", "DAC L2 Mux" },
3114 { "Mono DAC MIXL", "DAC R2 Switch", "DAC R2 Mux" },
3115 { "Mono DAC MIXR", "DAC L1 Switch", "DAC1 MIXL" },
3116 { "Mono DAC MIXR", "DAC R1 Switch", "DAC1 MIXR" },
3117 { "Mono DAC MIXR", "DAC R2 Switch", "DAC R2 Mux" },
3118 { "Mono DAC MIXR", "DAC L2 Switch", "DAC L2 Mux" },
3119
3120 { "DAC MIXL", "Stereo DAC Mixer", "Stereo DAC MIXL" },
3121 { "DAC MIXL", "Mono DAC Mixer", "Mono DAC MIXL" },
3122 { "DAC MIXR", "Stereo DAC Mixer", "Stereo DAC MIXR" },
3123 { "DAC MIXR", "Mono DAC Mixer", "Mono DAC MIXR" },
3124
3125 { "DAC L1 Source", NULL, "DAC L1 Power" },
3126 { "DAC L1 Source", "DAC", "DAC1 MIXL" },
3127 { "DAC L1 Source", "Stereo DAC Mixer", "Stereo DAC MIXL" },
3128 { "DAC R1 Source", NULL, "DAC R1 Power" },
3129 { "DAC R1 Source", "DAC", "DAC1 MIXR" },
3130 { "DAC R1 Source", "Stereo DAC Mixer", "Stereo DAC MIXR" },
3131 { "DAC L2 Source", "Stereo DAC Mixer", "Stereo DAC MIXL" },
3132 { "DAC L2 Source", "Mono DAC Mixer", "Mono DAC MIXL" },
3133 { "DAC L2 Source", NULL, "DAC L2 Power" },
3134 { "DAC R2 Source", "Stereo DAC Mixer", "Stereo DAC MIXR" },
3135 { "DAC R2 Source", "Mono DAC Mixer", "Mono DAC MIXR" },
3136 { "DAC R2 Source", NULL, "DAC R2 Power" },
3137
3138 { "DAC L1", NULL, "DAC L1 Source" },
3139 { "DAC R1", NULL, "DAC R1 Source" },
3140 { "DAC L2", NULL, "DAC L2 Source" },
3141 { "DAC R2", NULL, "DAC R2 Source" },
3142
3143 { "SPK MIXL", "DAC L2 Switch", "DAC L2" },
3144 { "SPK MIXL", "BST1 Switch", "BST1" },
3145 { "SPK MIXL", "INL Switch", "INL VOL" },
3146 { "SPK MIXL", "INR Switch", "INR VOL" },
3147 { "SPK MIXL", "BST3 Switch", "BST3" },
3148 { "SPK MIXR", "DAC R2 Switch", "DAC R2" },
3149 { "SPK MIXR", "BST4 Switch", "BST4" },
3150 { "SPK MIXR", "INL Switch", "INL VOL" },
3151 { "SPK MIXR", "INR Switch", "INR VOL" },
3152 { "SPK MIXR", "BST3 Switch", "BST3" },
3153
3154 { "MONOVOL MIX", "DAC L2 Switch", "DAC L2" },
3155 { "MONOVOL MIX", "DAC R2 Switch", "DAC R2" },
3156 { "MONOVOL MIX", "BST1 Switch", "BST1" },
3157 { "MONOVOL MIX", "BST2 Switch", "BST2" },
3158 { "MONOVOL MIX", "BST3 Switch", "BST3" },
3159
3160 { "OUT MIXL", "DAC L2 Switch", "DAC L2" },
3161 { "OUT MIXL", "INL Switch", "INL VOL" },
3162 { "OUT MIXL", "BST1 Switch", "BST1" },
3163 { "OUT MIXL", "BST2 Switch", "BST2" },
3164 { "OUT MIXL", "BST3 Switch", "BST3" },
3165 { "OUT MIXR", "DAC R2 Switch", "DAC R2" },
3166 { "OUT MIXR", "INR Switch", "INR VOL" },
3167 { "OUT MIXR", "BST2 Switch", "BST2" },
3168 { "OUT MIXR", "BST3 Switch", "BST3" },
3169 { "OUT MIXR", "BST4 Switch", "BST4" },
3170
3171 { "SPKVOL L", "Switch", "SPK MIXL" },
3172 { "SPKVOL R", "Switch", "SPK MIXR" },
3173 { "SPO L MIX", "DAC L2 Switch", "DAC L2" },
3174 { "SPO L MIX", "SPKVOL L Switch", "SPKVOL L" },
3175 { "SPO R MIX", "DAC R2 Switch", "DAC R2" },
3176 { "SPO R MIX", "SPKVOL R Switch", "SPKVOL R" },
3177 { "SPK Amp", NULL, "SPO L MIX" },
3178 { "SPK Amp", NULL, "SPO R MIX" },
3179 { "SPK Amp", NULL, "SYS CLK DET" },
3180 { "SPO Playback", "Switch", "SPK Amp" },
3181 { "SPOL", NULL, "SPO Playback" },
3182 { "SPOR", NULL, "SPO Playback" },
3183
3184 { "MONOVOL", "Switch", "MONOVOL MIX" },
3185 { "Mono MIX", "DAC L2 Switch", "DAC L2" },
3186 { "Mono MIX", "MONOVOL Switch", "MONOVOL" },
3187 { "Mono Amp", NULL, "Mono MIX" },
3188 { "Mono Amp", NULL, "Mono Vref" },
3189 { "Mono Amp", NULL, "SYS CLK DET" },
3190 { "Mono Playback", "Switch", "Mono Amp" },
3191 { "MONOOUT", NULL, "Mono Playback" },
3192
3193 { "HP Amp", NULL, "DAC L1" },
3194 { "HP Amp", NULL, "DAC R1" },
3195 { "HP Amp", NULL, "Charge Pump" },
3196 { "HP Amp", NULL, "SYS CLK DET" },
3197 { "HPO L Playback", "Switch", "HP Amp"},
3198 { "HPO R Playback", "Switch", "HP Amp"},
3199 { "HPOL", NULL, "HPO L Playback" },
3200 { "HPOR", NULL, "HPO R Playback" },
3201
3202 { "OUTVOL L", "Switch", "OUT MIXL" },
3203 { "OUTVOL R", "Switch", "OUT MIXR" },
3204 { "LOUT L MIX", "DAC L2 Switch", "DAC L2" },
3205 { "LOUT L MIX", "OUTVOL L Switch", "OUTVOL L" },
3206 { "LOUT R MIX", "DAC R2 Switch", "DAC R2" },
3207 { "LOUT R MIX", "OUTVOL R Switch", "OUTVOL R" },
3208 { "LOUT Amp", NULL, "LOUT L MIX" },
3209 { "LOUT Amp", NULL, "LOUT R MIX" },
3210 { "LOUT Amp", NULL, "SYS CLK DET" },
3211 { "LOUT L Playback", "Switch", "LOUT Amp" },
3212 { "LOUT R Playback", "Switch", "LOUT Amp" },
3213 { "LOUTL", NULL, "LOUT L Playback" },
3214 { "LOUTR", NULL, "LOUT R Playback" },
3215
3216 { "PDM L Mux", "Mono DAC", "Mono DAC MIXL" },
3217 { "PDM L Mux", "Stereo DAC", "Stereo DAC MIXL" },
3218 { "PDM L Mux", NULL, "PDM Power" },
3219 { "PDM R Mux", "Mono DAC", "Mono DAC MIXR" },
3220 { "PDM R Mux", "Stereo DAC", "Stereo DAC MIXR" },
3221 { "PDM R Mux", NULL, "PDM Power" },
3222 { "PDM L Playback", "Switch", "PDM L Mux" },
3223 { "PDM R Playback", "Switch", "PDM R Mux" },
3224 { "PDML", NULL, "PDM L Playback" },
3225 { "PDMR", NULL, "PDM R Playback" },
3226
3227 { "SPDIF Mux", "IF3_DAC", "IF3 DAC" },
3228 { "SPDIF Mux", "IF2_DAC", "IF2 DAC" },
3229 { "SPDIF Mux", "IF1_DAC2", "IF1 DAC2" },
3230 { "SPDIF Mux", "IF1_DAC1", "IF1 DAC1" },
3231 { "SPDIF", NULL, "SPDIF Mux" },
3232};
3233
3234static int rt5659_hw_params(struct snd_pcm_substream *substream,
3235 struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
3236{
3237 struct snd_soc_codec *codec = dai->codec;
3238 struct rt5659_priv *rt5659 = snd_soc_codec_get_drvdata(codec);
3239 unsigned int val_len = 0, val_clk, mask_clk;
3240 int pre_div, frame_size;
3241
3242 rt5659->lrck[dai->id] = params_rate(params);
3243 pre_div = rl6231_get_clk_info(rt5659->sysclk, rt5659->lrck[dai->id]);
3244 if (pre_div < 0) {
3245 dev_err(codec->dev, "Unsupported clock setting %d for DAI %d\n",
3246 rt5659->lrck[dai->id], dai->id);
3247 return -EINVAL;
3248 }
3249 frame_size = snd_soc_params_to_frame_size(params);
3250 if (frame_size < 0) {
3251 dev_err(codec->dev, "Unsupported frame size: %d\n", frame_size);
3252 return -EINVAL;
3253 }
3254
3255 dev_dbg(dai->dev, "lrck is %dHz and pre_div is %d for iis %d\n",
3256 rt5659->lrck[dai->id], pre_div, dai->id);
3257
3258 switch (params_width(params)) {
3259 case 16:
3260 break;
3261 case 20:
3262 val_len |= RT5659_I2S_DL_20;
3263 break;
3264 case 24:
3265 val_len |= RT5659_I2S_DL_24;
3266 break;
3267 case 8:
3268 val_len |= RT5659_I2S_DL_8;
3269 break;
3270 default:
3271 return -EINVAL;
3272 }
3273
3274 switch (dai->id) {
3275 case RT5659_AIF1:
3276 mask_clk = RT5659_I2S_PD1_MASK;
3277 val_clk = pre_div << RT5659_I2S_PD1_SFT;
3278 snd_soc_update_bits(codec, RT5659_I2S1_SDP,
3279 RT5659_I2S_DL_MASK, val_len);
3280 break;
3281 case RT5659_AIF2:
3282 mask_clk = RT5659_I2S_PD2_MASK;
3283 val_clk = pre_div << RT5659_I2S_PD2_SFT;
3284 snd_soc_update_bits(codec, RT5659_I2S2_SDP,
3285 RT5659_I2S_DL_MASK, val_len);
3286 break;
3287 case RT5659_AIF3:
3288 mask_clk = RT5659_I2S_PD3_MASK;
3289 val_clk = pre_div << RT5659_I2S_PD3_SFT;
3290 snd_soc_update_bits(codec, RT5659_I2S3_SDP,
3291 RT5659_I2S_DL_MASK, val_len);
3292 break;
3293 default:
3294 dev_err(codec->dev, "Invalid dai->id: %d\n", dai->id);
3295 return -EINVAL;
3296 }
3297
3298 snd_soc_update_bits(codec, RT5659_ADDA_CLK_1, mask_clk, val_clk);
3299
3300 switch (rt5659->lrck[dai->id]) {
3301 case 192000:
3302 snd_soc_update_bits(codec, RT5659_ADDA_CLK_1,
3303 RT5659_DAC_OSR_MASK, RT5659_DAC_OSR_32);
3304 break;
3305 case 96000:
3306 snd_soc_update_bits(codec, RT5659_ADDA_CLK_1,
3307 RT5659_DAC_OSR_MASK, RT5659_DAC_OSR_64);
3308 break;
3309 default:
3310 snd_soc_update_bits(codec, RT5659_ADDA_CLK_1,
3311 RT5659_DAC_OSR_MASK, RT5659_DAC_OSR_128);
3312 break;
3313 }
3314
3315 return 0;
3316}
3317
3318static int rt5659_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
3319{
3320 struct snd_soc_codec *codec = dai->codec;
3321 struct rt5659_priv *rt5659 = snd_soc_codec_get_drvdata(codec);
3322 unsigned int reg_val = 0;
3323
3324 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
3325 case SND_SOC_DAIFMT_CBM_CFM:
3326 rt5659->master[dai->id] = 1;
3327 break;
3328 case SND_SOC_DAIFMT_CBS_CFS:
3329 reg_val |= RT5659_I2S_MS_S;
3330 rt5659->master[dai->id] = 0;
3331 break;
3332 default:
3333 return -EINVAL;
3334 }
3335
3336 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
3337 case SND_SOC_DAIFMT_NB_NF:
3338 break;
3339 case SND_SOC_DAIFMT_IB_NF:
3340 reg_val |= RT5659_I2S_BP_INV;
3341 break;
3342 default:
3343 return -EINVAL;
3344 }
3345
3346 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
3347 case SND_SOC_DAIFMT_I2S:
3348 break;
3349 case SND_SOC_DAIFMT_LEFT_J:
3350 reg_val |= RT5659_I2S_DF_LEFT;
3351 break;
3352 case SND_SOC_DAIFMT_DSP_A:
3353 reg_val |= RT5659_I2S_DF_PCM_A;
3354 break;
3355 case SND_SOC_DAIFMT_DSP_B:
3356 reg_val |= RT5659_I2S_DF_PCM_B;
3357 break;
3358 default:
3359 return -EINVAL;
3360 }
3361
3362 switch (dai->id) {
3363 case RT5659_AIF1:
3364 snd_soc_update_bits(codec, RT5659_I2S1_SDP,
3365 RT5659_I2S_MS_MASK | RT5659_I2S_BP_MASK |
3366 RT5659_I2S_DF_MASK, reg_val);
3367 break;
3368 case RT5659_AIF2:
3369 snd_soc_update_bits(codec, RT5659_I2S2_SDP,
3370 RT5659_I2S_MS_MASK | RT5659_I2S_BP_MASK |
3371 RT5659_I2S_DF_MASK, reg_val);
3372 break;
3373 case RT5659_AIF3:
3374 snd_soc_update_bits(codec, RT5659_I2S3_SDP,
3375 RT5659_I2S_MS_MASK | RT5659_I2S_BP_MASK |
3376 RT5659_I2S_DF_MASK, reg_val);
3377 break;
3378 default:
3379 dev_err(codec->dev, "Invalid dai->id: %d\n", dai->id);
3380 return -EINVAL;
3381 }
3382 return 0;
3383}
3384
3385static int rt5659_set_dai_sysclk(struct snd_soc_dai *dai,
3386 int clk_id, unsigned int freq, int dir)
3387{
3388 struct snd_soc_codec *codec = dai->codec;
3389 struct rt5659_priv *rt5659 = snd_soc_codec_get_drvdata(codec);
3390 unsigned int reg_val = 0;
3391
3392 if (freq == rt5659->sysclk && clk_id == rt5659->sysclk_src)
3393 return 0;
3394
3395 switch (clk_id) {
3396 case RT5659_SCLK_S_MCLK:
3397 reg_val |= RT5659_SCLK_SRC_MCLK;
3398 break;
3399 case RT5659_SCLK_S_PLL1:
3400 reg_val |= RT5659_SCLK_SRC_PLL1;
3401 break;
3402 case RT5659_SCLK_S_RCCLK:
3403 reg_val |= RT5659_SCLK_SRC_RCCLK;
3404 break;
3405 default:
3406 dev_err(codec->dev, "Invalid clock id (%d)\n", clk_id);
3407 return -EINVAL;
3408 }
3409 snd_soc_update_bits(codec, RT5659_GLB_CLK,
3410 RT5659_SCLK_SRC_MASK, reg_val);
3411 rt5659->sysclk = freq;
3412 rt5659->sysclk_src = clk_id;
3413
3414 dev_dbg(dai->dev, "Sysclk is %dHz and clock id is %d\n", freq, clk_id);
3415
3416 return 0;
3417}
3418
3419static int rt5659_set_dai_pll(struct snd_soc_dai *dai, int pll_id, int Source,
3420 unsigned int freq_in, unsigned int freq_out)
3421{
3422 struct snd_soc_codec *codec = dai->codec;
3423 struct rt5659_priv *rt5659 = snd_soc_codec_get_drvdata(codec);
3424 struct rl6231_pll_code pll_code;
3425 int ret;
3426
3427 if (Source == rt5659->pll_src && freq_in == rt5659->pll_in &&
3428 freq_out == rt5659->pll_out)
3429 return 0;
3430
3431 if (!freq_in || !freq_out) {
3432 dev_dbg(codec->dev, "PLL disabled\n");
3433
3434 rt5659->pll_in = 0;
3435 rt5659->pll_out = 0;
3436 snd_soc_update_bits(codec, RT5659_GLB_CLK,
3437 RT5659_SCLK_SRC_MASK, RT5659_SCLK_SRC_MCLK);
3438 return 0;
3439 }
3440
3441 switch (Source) {
3442 case RT5659_PLL1_S_MCLK:
3443 snd_soc_update_bits(codec, RT5659_GLB_CLK,
3444 RT5659_PLL1_SRC_MASK, RT5659_PLL1_SRC_MCLK);
3445 break;
3446 case RT5659_PLL1_S_BCLK1:
3447 snd_soc_update_bits(codec, RT5659_GLB_CLK,
3448 RT5659_PLL1_SRC_MASK, RT5659_PLL1_SRC_BCLK1);
3449 break;
3450 case RT5659_PLL1_S_BCLK2:
3451 snd_soc_update_bits(codec, RT5659_GLB_CLK,
3452 RT5659_PLL1_SRC_MASK, RT5659_PLL1_SRC_BCLK2);
3453 break;
3454 case RT5659_PLL1_S_BCLK3:
3455 snd_soc_update_bits(codec, RT5659_GLB_CLK,
3456 RT5659_PLL1_SRC_MASK, RT5659_PLL1_SRC_BCLK3);
3457 break;
3458 default:
3459 dev_err(codec->dev, "Unknown PLL Source %d\n", Source);
3460 return -EINVAL;
3461 }
3462
3463 ret = rl6231_pll_calc(freq_in, freq_out, &pll_code);
3464 if (ret < 0) {
3465 dev_err(codec->dev, "Unsupport input clock %d\n", freq_in);
3466 return ret;
3467 }
3468
3469 dev_dbg(codec->dev, "bypass=%d m=%d n=%d k=%d\n",
3470 pll_code.m_bp, (pll_code.m_bp ? 0 : pll_code.m_code),
3471 pll_code.n_code, pll_code.k_code);
3472
3473 snd_soc_write(codec, RT5659_PLL_CTRL_1,
3474 pll_code.n_code << RT5659_PLL_N_SFT | pll_code.k_code);
3475 snd_soc_write(codec, RT5659_PLL_CTRL_2,
3476 (pll_code.m_bp ? 0 : pll_code.m_code) << RT5659_PLL_M_SFT |
3477 pll_code.m_bp << RT5659_PLL_M_BP_SFT);
3478
3479 rt5659->pll_in = freq_in;
3480 rt5659->pll_out = freq_out;
3481 rt5659->pll_src = Source;
3482
3483 return 0;
3484}
3485
3486static int rt5659_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
3487 unsigned int rx_mask, int slots, int slot_width)
3488{
3489 struct snd_soc_codec *codec = dai->codec;
3490 unsigned int val = 0;
3491
3492 if (rx_mask || tx_mask)
3493 val |= (1 << 15);
3494
3495 switch (slots) {
3496 case 4:
3497 val |= (1 << 10);
3498 val |= (1 << 8);
3499 break;
3500 case 6:
3501 val |= (2 << 10);
3502 val |= (2 << 8);
3503 break;
3504 case 8:
3505 val |= (3 << 10);
3506 val |= (3 << 8);
3507 break;
3508 case 2:
3509 break;
3510 default:
3511 return -EINVAL;
3512 }
3513
3514 switch (slot_width) {
3515 case 20:
3516 val |= (1 << 6);
3517 val |= (1 << 4);
3518 break;
3519 case 24:
3520 val |= (2 << 6);
3521 val |= (2 << 4);
3522 break;
3523 case 32:
3524 val |= (3 << 6);
3525 val |= (3 << 4);
3526 break;
3527 case 16:
3528 break;
3529 default:
3530 return -EINVAL;
3531 }
3532
3533 snd_soc_update_bits(codec, RT5659_TDM_CTRL_1, 0x8ff0, val);
3534
3535 return 0;
3536}
3537
3538static int rt5659_set_bclk_ratio(struct snd_soc_dai *dai, unsigned int ratio)
3539{
3540 struct snd_soc_codec *codec = dai->codec;
3541 struct rt5659_priv *rt5659 = snd_soc_codec_get_drvdata(codec);
3542
3543 dev_dbg(codec->dev, "%s ratio=%d\n", __func__, ratio);
3544
3545 rt5659->bclk[dai->id] = ratio;
3546
3547 if (ratio == 64) {
3548 switch (dai->id) {
3549 case RT5659_AIF2:
3550 snd_soc_update_bits(codec, RT5659_ADDA_CLK_1,
3551 RT5659_I2S_BCLK_MS2_MASK,
3552 RT5659_I2S_BCLK_MS2_64);
3553 break;
3554 case RT5659_AIF3:
3555 snd_soc_update_bits(codec, RT5659_ADDA_CLK_1,
3556 RT5659_I2S_BCLK_MS3_MASK,
3557 RT5659_I2S_BCLK_MS3_64);
3558 break;
3559 }
3560 }
3561
3562 return 0;
3563}
3564
3565static int rt5659_set_bias_level(struct snd_soc_codec *codec,
3566 enum snd_soc_bias_level level)
3567{
3568 struct rt5659_priv *rt5659 = snd_soc_codec_get_drvdata(codec);
3569
3570 switch (level) {
3571 case SND_SOC_BIAS_PREPARE:
3572 regmap_update_bits(rt5659->regmap, RT5659_DIG_MISC,
3573 RT5659_DIG_GATE_CTRL, RT5659_DIG_GATE_CTRL);
3574 regmap_update_bits(rt5659->regmap, RT5659_PWR_DIG_1,
3575 RT5659_PWR_LDO, RT5659_PWR_LDO);
3576 regmap_update_bits(rt5659->regmap, RT5659_PWR_ANLG_1,
3577 RT5659_PWR_MB | RT5659_PWR_VREF1 | RT5659_PWR_VREF2,
3578 RT5659_PWR_MB | RT5659_PWR_VREF1 | RT5659_PWR_VREF2);
3579 msleep(20);
3580 regmap_update_bits(rt5659->regmap, RT5659_PWR_ANLG_1,
3581 RT5659_PWR_FV1 | RT5659_PWR_FV2,
3582 RT5659_PWR_FV1 | RT5659_PWR_FV2);
3583 break;
3584
3585 case SND_SOC_BIAS_OFF:
3586 regmap_update_bits(rt5659->regmap, RT5659_PWR_DIG_1,
3587 RT5659_PWR_LDO, 0);
3588 regmap_update_bits(rt5659->regmap, RT5659_PWR_ANLG_1,
3589 RT5659_PWR_MB | RT5659_PWR_VREF1 | RT5659_PWR_VREF2
3590 | RT5659_PWR_FV1 | RT5659_PWR_FV2,
3591 RT5659_PWR_MB | RT5659_PWR_VREF2);
3592 regmap_update_bits(rt5659->regmap, RT5659_DIG_MISC,
3593 RT5659_DIG_GATE_CTRL, 0);
3594 break;
3595
3596 default:
3597 break;
3598 }
3599
3600 return 0;
3601}
3602
3603static int rt5659_probe(struct snd_soc_codec *codec)
3604{
3605 struct rt5659_priv *rt5659 = snd_soc_codec_get_drvdata(codec);
3606
3607 rt5659->codec = codec;
3608
3609 return 0;
3610}
3611
3612static int rt5659_remove(struct snd_soc_codec *codec)
3613{
3614 struct rt5659_priv *rt5659 = snd_soc_codec_get_drvdata(codec);
3615
3616 regmap_write(rt5659->regmap, RT5659_RESET, 0);
3617
3618 return 0;
3619}
3620
3621#ifdef CONFIG_PM
3622static int rt5659_suspend(struct snd_soc_codec *codec)
3623{
3624 struct rt5659_priv *rt5659 = snd_soc_codec_get_drvdata(codec);
3625
3626 regcache_cache_only(rt5659->regmap, true);
3627 regcache_mark_dirty(rt5659->regmap);
3628 return 0;
3629}
3630
3631static int rt5659_resume(struct snd_soc_codec *codec)
3632{
3633 struct rt5659_priv *rt5659 = snd_soc_codec_get_drvdata(codec);
3634
3635 regcache_cache_only(rt5659->regmap, false);
3636 regcache_sync(rt5659->regmap);
3637
3638 return 0;
3639}
3640#else
3641#define rt5659_suspend NULL
3642#define rt5659_resume NULL
3643#endif
3644
3645#define RT5659_STEREO_RATES SNDRV_PCM_RATE_8000_192000
3646#define RT5659_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \
3647 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S8)
3648
3649static const struct snd_soc_dai_ops rt5659_aif_dai_ops = {
3650 .hw_params = rt5659_hw_params,
3651 .set_fmt = rt5659_set_dai_fmt,
3652 .set_sysclk = rt5659_set_dai_sysclk,
3653 .set_tdm_slot = rt5659_set_tdm_slot,
3654 .set_pll = rt5659_set_dai_pll,
3655 .set_bclk_ratio = rt5659_set_bclk_ratio,
3656};
3657
3658static struct snd_soc_dai_driver rt5659_dai[] = {
3659 {
3660 .name = "rt5659-aif1",
3661 .id = RT5659_AIF1,
3662 .playback = {
3663 .stream_name = "AIF1 Playback",
3664 .channels_min = 1,
3665 .channels_max = 2,
3666 .rates = RT5659_STEREO_RATES,
3667 .formats = RT5659_FORMATS,
3668 },
3669 .capture = {
3670 .stream_name = "AIF1 Capture",
3671 .channels_min = 1,
3672 .channels_max = 2,
3673 .rates = RT5659_STEREO_RATES,
3674 .formats = RT5659_FORMATS,
3675 },
3676 .ops = &rt5659_aif_dai_ops,
3677 },
3678 {
3679 .name = "rt5659-aif2",
3680 .id = RT5659_AIF2,
3681 .playback = {
3682 .stream_name = "AIF2 Playback",
3683 .channels_min = 1,
3684 .channels_max = 2,
3685 .rates = RT5659_STEREO_RATES,
3686 .formats = RT5659_FORMATS,
3687 },
3688 .capture = {
3689 .stream_name = "AIF2 Capture",
3690 .channels_min = 1,
3691 .channels_max = 2,
3692 .rates = RT5659_STEREO_RATES,
3693 .formats = RT5659_FORMATS,
3694 },
3695 .ops = &rt5659_aif_dai_ops,
3696 },
3697 {
3698 .name = "rt5659-aif3",
3699 .id = RT5659_AIF3,
3700 .playback = {
3701 .stream_name = "AIF3 Playback",
3702 .channels_min = 1,
3703 .channels_max = 2,
3704 .rates = RT5659_STEREO_RATES,
3705 .formats = RT5659_FORMATS,
3706 },
3707 .capture = {
3708 .stream_name = "AIF3 Capture",
3709 .channels_min = 1,
3710 .channels_max = 2,
3711 .rates = RT5659_STEREO_RATES,
3712 .formats = RT5659_FORMATS,
3713 },
3714 .ops = &rt5659_aif_dai_ops,
3715 },
3716};
3717
3718static struct snd_soc_codec_driver soc_codec_dev_rt5659 = {
3719 .probe = rt5659_probe,
3720 .remove = rt5659_remove,
3721 .suspend = rt5659_suspend,
3722 .resume = rt5659_resume,
3723 .set_bias_level = rt5659_set_bias_level,
3724 .idle_bias_off = true,
3725 .controls = rt5659_snd_controls,
3726 .num_controls = ARRAY_SIZE(rt5659_snd_controls),
3727 .dapm_widgets = rt5659_dapm_widgets,
3728 .num_dapm_widgets = ARRAY_SIZE(rt5659_dapm_widgets),
3729 .dapm_routes = rt5659_dapm_routes,
3730 .num_dapm_routes = ARRAY_SIZE(rt5659_dapm_routes),
3731};
3732
3733
3734static const struct regmap_config rt5659_regmap = {
3735 .reg_bits = 16,
3736 .val_bits = 16,
3737 .max_register = 0x0400,
3738 .volatile_reg = rt5659_volatile_register,
3739 .readable_reg = rt5659_readable_register,
3740 .cache_type = REGCACHE_RBTREE,
3741 .reg_defaults = rt5659_reg,
3742 .num_reg_defaults = ARRAY_SIZE(rt5659_reg),
3743};
3744
3745static const struct i2c_device_id rt5659_i2c_id[] = {
3746 { "rt5658", 0 },
3747 { "rt5659", 0 },
3748 { }
3749};
3750MODULE_DEVICE_TABLE(i2c, rt5659_i2c_id);
3751
3752static int rt5659_parse_dt(struct rt5659_priv *rt5659, struct device *dev)
3753{
3754 rt5659->pdata.in1_diff = device_property_read_bool(dev,
3755 "realtek,in1-differential");
3756 rt5659->pdata.in3_diff = device_property_read_bool(dev,
3757 "realtek,in3-differential");
3758 rt5659->pdata.in4_diff = device_property_read_bool(dev,
3759 "realtek,in4-differential");
3760
3761
3762 device_property_read_u32(dev, "realtek,dmic1-data-pin",
3763 &rt5659->pdata.dmic1_data_pin);
3764 device_property_read_u32(dev, "realtek,dmic2-data-pin",
3765 &rt5659->pdata.dmic2_data_pin);
3766 device_property_read_u32(dev, "realtek,jd-src",
3767 &rt5659->pdata.jd_src);
3768
3769 return 0;
3770}
3771
3772static void rt5659_calibrate(struct rt5659_priv *rt5659)
3773{
3774 int value, count;
3775
3776 /* Calibrate HPO Start */
3777 /* Fine tune HP Performance */
3778 regmap_write(rt5659->regmap, RT5659_BIAS_CUR_CTRL_8, 0xa502);
3779 regmap_write(rt5659->regmap, RT5659_CHOP_DAC, 0x3030);
3780
3781 regmap_write(rt5659->regmap, RT5659_PRE_DIV_1, 0xef00);
3782 regmap_write(rt5659->regmap, RT5659_PRE_DIV_2, 0xeffc);
3783 regmap_write(rt5659->regmap, RT5659_MICBIAS_2, 0x0280);
3784 regmap_write(rt5659->regmap, RT5659_DIG_MISC, 0x0001);
3785 regmap_write(rt5659->regmap, RT5659_GLB_CLK, 0x8000);
3786
3787 regmap_write(rt5659->regmap, RT5659_PWR_ANLG_1, 0xaa7e);
3788 msleep(60);
3789 regmap_write(rt5659->regmap, RT5659_PWR_ANLG_1, 0xfe7e);
3790 msleep(50);
3791 regmap_write(rt5659->regmap, RT5659_PWR_ANLG_3, 0x0004);
3792 regmap_write(rt5659->regmap, RT5659_PWR_DIG_2, 0x0400);
3793 msleep(50);
3794 regmap_write(rt5659->regmap, RT5659_PWR_DIG_1, 0x0080);
3795 usleep_range(10000, 10005);
3796 regmap_write(rt5659->regmap, RT5659_DEPOP_1, 0x0009);
3797 msleep(50);
3798 regmap_write(rt5659->regmap, RT5659_PWR_DIG_1, 0x0f80);
3799 msleep(50);
3800 regmap_write(rt5659->regmap, RT5659_HP_CHARGE_PUMP_1, 0x0e16);
3801 msleep(50);
3802
3803 /* Enalbe K ADC Power And Clock */
3804 regmap_write(rt5659->regmap, RT5659_CAL_REC, 0x0505);
3805 msleep(50);
3806 regmap_write(rt5659->regmap, RT5659_PWR_ANLG_3, 0x0184);
3807 regmap_write(rt5659->regmap, RT5659_CALIB_ADC_CTRL, 0x3c05);
3808 regmap_write(rt5659->regmap, RT5659_HP_CALIB_CTRL_2, 0x20c1);
3809
3810 /* K Headphone */
3811 regmap_write(rt5659->regmap, RT5659_HP_CALIB_CTRL_2, 0x2cc1);
3812 regmap_write(rt5659->regmap, RT5659_HP_CALIB_CTRL_1, 0x5100);
3813 regmap_write(rt5659->regmap, RT5659_HP_CALIB_CTRL_7, 0x0014);
3814 regmap_write(rt5659->regmap, RT5659_HP_CALIB_CTRL_1, 0xd100);
3815 msleep(60);
3816
3817 /* Manual K ADC Offset */
3818 regmap_write(rt5659->regmap, RT5659_HP_CALIB_CTRL_2, 0x2cc1);
3819 regmap_write(rt5659->regmap, RT5659_HP_CALIB_CTRL_1, 0x4900);
3820 regmap_write(rt5659->regmap, RT5659_HP_CALIB_CTRL_7, 0x0016);
3821 regmap_update_bits(rt5659->regmap, RT5659_HP_CALIB_CTRL_1,
3822 0x8000, 0x8000);
3823
3824 count = 0;
3825 while (true) {
3826 regmap_read(rt5659->regmap, RT5659_HP_CALIB_CTRL_1, &value);
3827 if (value & 0x8000)
3828 usleep_range(10000, 10005);
3829 else
3830 break;
3831
3832 if (count > 30) {
3833 dev_err(rt5659->codec->dev,
3834 "HP Calibration 1 Failure\n");
3835 return;
3836 }
3837
3838 count++;
3839 }
3840
3841 /* Manual K Internal Path Offset */
3842 regmap_write(rt5659->regmap, RT5659_HP_CALIB_CTRL_2, 0x2cc1);
3843 regmap_write(rt5659->regmap, RT5659_HP_VOL, 0x0000);
3844 regmap_write(rt5659->regmap, RT5659_HP_CALIB_CTRL_1, 0x4500);
3845 regmap_write(rt5659->regmap, RT5659_HP_CALIB_CTRL_7, 0x001f);
3846 regmap_update_bits(rt5659->regmap, RT5659_HP_CALIB_CTRL_1,
3847 0x8000, 0x8000);
3848
3849 count = 0;
3850 while (true) {
3851 regmap_read(rt5659->regmap, RT5659_HP_CALIB_CTRL_1, &value);
3852 if (value & 0x8000)
3853 usleep_range(10000, 10005);
3854 else
3855 break;
3856
3857 if (count > 85) {
3858 dev_err(rt5659->codec->dev,
3859 "HP Calibration 2 Failure\n");
3860 return;
3861 }
3862
3863 count++;
3864 }
3865
3866 regmap_write(rt5659->regmap, RT5659_HP_CALIB_CTRL_7, 0x0000);
3867 regmap_write(rt5659->regmap, RT5659_HP_CALIB_CTRL_2, 0x20c0);
3868 /* Calibrate HPO End */
3869
3870 /* Calibrate SPO Start */
3871 regmap_write(rt5659->regmap, RT5659_CLASSD_0, 0x2021);
3872 regmap_write(rt5659->regmap, RT5659_CLASSD_CTRL_1, 0x0260);
3873 regmap_write(rt5659->regmap, RT5659_PWR_MIXER, 0x3000);
3874 regmap_write(rt5659->regmap, RT5659_PWR_VOL, 0xc000);
3875 regmap_write(rt5659->regmap, RT5659_A_DAC_MUX, 0x000c);
3876 regmap_write(rt5659->regmap, RT5659_DIG_MISC, 0x8000);
3877 regmap_write(rt5659->regmap, RT5659_SPO_VOL, 0x0808);
3878 regmap_write(rt5659->regmap, RT5659_SPK_L_MIXER, 0x001e);
3879 regmap_write(rt5659->regmap, RT5659_SPK_R_MIXER, 0x001e);
3880 regmap_write(rt5659->regmap, RT5659_CLASSD_1, 0x0803);
3881 regmap_write(rt5659->regmap, RT5659_CLASSD_2, 0x0554);
3882 regmap_write(rt5659->regmap, RT5659_SPO_AMP_GAIN, 0x1103);
3883
3884 /* Enalbe K ADC Power And Clock */
3885 regmap_write(rt5659->regmap, RT5659_CAL_REC, 0x0909);
3886 regmap_update_bits(rt5659->regmap, RT5659_HP_CALIB_CTRL_2, 0x0001,
3887 0x0001);
3888
3889 /* Start Calibration */
3890 regmap_write(rt5659->regmap, RT5659_SPK_DC_CAILB_CTRL_3, 0x0000);
3891 regmap_write(rt5659->regmap, RT5659_CLASSD_0, 0x0021);
3892 regmap_write(rt5659->regmap, RT5659_SPK_DC_CAILB_CTRL_1, 0x3e80);
3893 regmap_update_bits(rt5659->regmap, RT5659_SPK_DC_CAILB_CTRL_1,
3894 0x8000, 0x8000);
3895
3896 count = 0;
3897 while (true) {
3898 regmap_read(rt5659->regmap,
3899 RT5659_SPK_DC_CAILB_CTRL_1, &value);
3900 if (value & 0x8000)
3901 usleep_range(10000, 10005);
3902 else
3903 break;
3904
3905 if (count > 10) {
3906 dev_err(rt5659->codec->dev,
3907 "SPK Calibration Failure\n");
3908 return;
3909 }
3910
3911 count++;
3912 }
3913 /* Calibrate SPO End */
3914
3915 /* Calibrate MONO Start */
3916 regmap_write(rt5659->regmap, RT5659_DIG_MISC, 0x0000);
3917 regmap_write(rt5659->regmap, RT5659_MONOMIX_IN_GAIN, 0x021f);
3918 regmap_write(rt5659->regmap, RT5659_MONO_OUT, 0x480a);
3919 /* MONO NG2 GAIN 5dB */
3920 regmap_write(rt5659->regmap, RT5659_MONO_GAIN, 0x0003);
3921 regmap_write(rt5659->regmap, RT5659_MONO_NG2_CTRL_5, 0x0009);
3922
3923 /* Start Calibration */
3924 regmap_write(rt5659->regmap, RT5659_SPK_DC_CAILB_CTRL_3, 0x000f);
3925 regmap_write(rt5659->regmap, RT5659_MONO_AMP_CALIB_CTRL_1, 0x1e00);
3926 regmap_update_bits(rt5659->regmap, RT5659_MONO_AMP_CALIB_CTRL_1,
3927 0x8000, 0x8000);
3928
3929 count = 0;
3930 while (true) {
3931 regmap_read(rt5659->regmap, RT5659_MONO_AMP_CALIB_CTRL_1,
3932 &value);
3933 if (value & 0x8000)
3934 usleep_range(10000, 10005);
3935 else
3936 break;
3937
3938 if (count > 35) {
3939 dev_err(rt5659->codec->dev,
3940 "Mono Calibration Failure\n");
3941 return;
3942 }
3943
3944 count++;
3945 }
3946
3947 regmap_write(rt5659->regmap, RT5659_SPK_DC_CAILB_CTRL_3, 0x0003);
3948 /* Calibrate MONO End */
3949
3950 /* Power Off */
3951 regmap_write(rt5659->regmap, RT5659_CAL_REC, 0x0808);
3952 regmap_write(rt5659->regmap, RT5659_PWR_ANLG_3, 0x0000);
3953 regmap_write(rt5659->regmap, RT5659_CALIB_ADC_CTRL, 0x2005);
3954 regmap_write(rt5659->regmap, RT5659_HP_CALIB_CTRL_2, 0x20c0);
3955 regmap_write(rt5659->regmap, RT5659_DEPOP_1, 0x0000);
3956 regmap_write(rt5659->regmap, RT5659_CLASSD_1, 0x0011);
3957 regmap_write(rt5659->regmap, RT5659_CLASSD_2, 0x0150);
3958 regmap_write(rt5659->regmap, RT5659_PWR_ANLG_1, 0xfe3e);
3959 regmap_write(rt5659->regmap, RT5659_MONO_OUT, 0xc80a);
3960 regmap_write(rt5659->regmap, RT5659_MONO_AMP_CALIB_CTRL_1, 0x1e04);
3961 regmap_write(rt5659->regmap, RT5659_PWR_MIXER, 0x0000);
3962 regmap_write(rt5659->regmap, RT5659_PWR_VOL, 0x0000);
3963 regmap_write(rt5659->regmap, RT5659_PWR_DIG_1, 0x0000);
3964 regmap_write(rt5659->regmap, RT5659_PWR_DIG_2, 0x0000);
3965 regmap_write(rt5659->regmap, RT5659_PWR_ANLG_1, 0x003e);
3966 regmap_write(rt5659->regmap, RT5659_CLASSD_CTRL_1, 0x0060);
3967 regmap_write(rt5659->regmap, RT5659_CLASSD_0, 0x2021);
3968 regmap_write(rt5659->regmap, RT5659_GLB_CLK, 0x0000);
3969 regmap_write(rt5659->regmap, RT5659_MICBIAS_2, 0x0080);
3970 regmap_write(rt5659->regmap, RT5659_HP_VOL, 0x8080);
3971 regmap_write(rt5659->regmap, RT5659_HP_CHARGE_PUMP_1, 0x0c16);
3972}
3973
3974static int rt5659_i2c_probe(struct i2c_client *i2c,
3975 const struct i2c_device_id *id)
3976{
3977 struct rt5659_platform_data *pdata = dev_get_platdata(&i2c->dev);
3978 struct rt5659_priv *rt5659;
3979 int ret;
3980 unsigned int val;
3981
3982 rt5659 = devm_kzalloc(&i2c->dev, sizeof(struct rt5659_priv),
3983 GFP_KERNEL);
3984
3985 if (rt5659 == NULL)
3986 return -ENOMEM;
3987
3988 rt5659->i2c = i2c;
3989 i2c_set_clientdata(i2c, rt5659);
3990
3991 if (pdata)
3992 rt5659->pdata = *pdata;
3993 else
3994 rt5659_parse_dt(rt5659, &i2c->dev);
3995
3996 rt5659->gpiod_ldo1_en = devm_gpiod_get_optional(&i2c->dev, "ldo1-en",
3997 GPIOD_OUT_HIGH);
3998 if (IS_ERR(rt5659->gpiod_ldo1_en))
3999 dev_warn(&i2c->dev, "Request ldo1-en GPIO failed\n");
4000
4001 rt5659->gpiod_reset = devm_gpiod_get_optional(&i2c->dev, "reset",
4002 GPIOD_OUT_HIGH);
4003
4004 /* Sleep for 300 ms miniumum */
4005 usleep_range(300000, 350000);
4006
4007 rt5659->regmap = devm_regmap_init_i2c(i2c, &rt5659_regmap);
4008 if (IS_ERR(rt5659->regmap)) {
4009 ret = PTR_ERR(rt5659->regmap);
4010 dev_err(&i2c->dev, "Failed to allocate register map: %d\n",
4011 ret);
4012 return ret;
4013 }
4014
4015 regmap_read(rt5659->regmap, RT5659_DEVICE_ID, &val);
4016 if (val != DEVICE_ID) {
4017 dev_err(&i2c->dev,
4018 "Device with ID register %x is not rt5659\n", val);
4019 return -ENODEV;
4020 }
4021
4022 regmap_write(rt5659->regmap, RT5659_RESET, 0);
4023
4024 rt5659_calibrate(rt5659);
4025
4026 /* line in diff mode*/
4027 if (rt5659->pdata.in1_diff)
4028 regmap_update_bits(rt5659->regmap, RT5659_IN1_IN2,
4029 RT5659_IN1_DF_MASK, RT5659_IN1_DF_MASK);
4030 if (rt5659->pdata.in3_diff)
4031 regmap_update_bits(rt5659->regmap, RT5659_IN3_IN4,
4032 RT5659_IN3_DF_MASK, RT5659_IN3_DF_MASK);
4033 if (rt5659->pdata.in4_diff)
4034 regmap_update_bits(rt5659->regmap, RT5659_IN3_IN4,
4035 RT5659_IN4_DF_MASK, RT5659_IN4_DF_MASK);
4036
4037 /* DMIC pin*/
4038 if (rt5659->pdata.dmic1_data_pin != RT5659_DMIC1_NULL ||
4039 rt5659->pdata.dmic2_data_pin != RT5659_DMIC2_NULL) {
4040 regmap_update_bits(rt5659->regmap, RT5659_GPIO_CTRL_1,
4041 RT5659_GP2_PIN_MASK, RT5659_GP2_PIN_DMIC1_SCL);
4042
4043 switch (rt5659->pdata.dmic1_data_pin) {
4044 case RT5659_DMIC1_DATA_IN2N:
4045 regmap_update_bits(rt5659->regmap, RT5659_DMIC_CTRL_1,
4046 RT5659_DMIC_1_DP_MASK, RT5659_DMIC_1_DP_IN2N);
4047 break;
4048
4049 case RT5659_DMIC1_DATA_GPIO5:
4050 regmap_update_bits(rt5659->regmap,
4051 RT5659_GPIO_CTRL_3,
4052 RT5659_I2S2_PIN_MASK,
4053 RT5659_I2S2_PIN_GPIO);
4054 regmap_update_bits(rt5659->regmap, RT5659_DMIC_CTRL_1,
4055 RT5659_DMIC_1_DP_MASK, RT5659_DMIC_1_DP_GPIO5);
4056 regmap_update_bits(rt5659->regmap, RT5659_GPIO_CTRL_1,
4057 RT5659_GP5_PIN_MASK, RT5659_GP5_PIN_DMIC1_SDA);
4058 break;
4059
4060 case RT5659_DMIC1_DATA_GPIO9:
4061 regmap_update_bits(rt5659->regmap, RT5659_DMIC_CTRL_1,
4062 RT5659_DMIC_1_DP_MASK, RT5659_DMIC_1_DP_GPIO9);
4063 regmap_update_bits(rt5659->regmap, RT5659_GPIO_CTRL_1,
4064 RT5659_GP9_PIN_MASK, RT5659_GP9_PIN_DMIC1_SDA);
4065 break;
4066
4067 case RT5659_DMIC1_DATA_GPIO11:
4068 regmap_update_bits(rt5659->regmap, RT5659_DMIC_CTRL_1,
4069 RT5659_DMIC_1_DP_MASK, RT5659_DMIC_1_DP_GPIO11);
4070 regmap_update_bits(rt5659->regmap, RT5659_GPIO_CTRL_1,
4071 RT5659_GP11_PIN_MASK,
4072 RT5659_GP11_PIN_DMIC1_SDA);
4073 break;
4074
4075 default:
4076 dev_dbg(&i2c->dev, "no DMIC1\n");
4077 break;
4078 }
4079
4080 switch (rt5659->pdata.dmic2_data_pin) {
4081 case RT5659_DMIC2_DATA_IN2P:
4082 regmap_update_bits(rt5659->regmap,
4083 RT5659_DMIC_CTRL_1,
4084 RT5659_DMIC_2_DP_MASK,
4085 RT5659_DMIC_2_DP_IN2P);
4086 break;
4087
4088 case RT5659_DMIC2_DATA_GPIO6:
4089 regmap_update_bits(rt5659->regmap,
4090 RT5659_DMIC_CTRL_1,
4091 RT5659_DMIC_2_DP_MASK,
4092 RT5659_DMIC_2_DP_GPIO6);
4093 regmap_update_bits(rt5659->regmap,
4094 RT5659_GPIO_CTRL_1,
4095 RT5659_GP6_PIN_MASK,
4096 RT5659_GP6_PIN_DMIC2_SDA);
4097 break;
4098
4099 case RT5659_DMIC2_DATA_GPIO10:
4100 regmap_update_bits(rt5659->regmap,
4101 RT5659_DMIC_CTRL_1,
4102 RT5659_DMIC_2_DP_MASK,
4103 RT5659_DMIC_2_DP_GPIO10);
4104 regmap_update_bits(rt5659->regmap,
4105 RT5659_GPIO_CTRL_1,
4106 RT5659_GP10_PIN_MASK,
4107 RT5659_GP10_PIN_DMIC2_SDA);
4108 break;
4109
4110 case RT5659_DMIC2_DATA_GPIO12:
4111 regmap_update_bits(rt5659->regmap,
4112 RT5659_DMIC_CTRL_1,
4113 RT5659_DMIC_2_DP_MASK,
4114 RT5659_DMIC_2_DP_GPIO12);
4115 regmap_update_bits(rt5659->regmap,
4116 RT5659_GPIO_CTRL_1,
4117 RT5659_GP12_PIN_MASK,
4118 RT5659_GP12_PIN_DMIC2_SDA);
4119 break;
4120
4121 default:
4122 dev_dbg(&i2c->dev, "no DMIC2\n");
4123 break;
4124
4125 }
4126 } else {
4127 regmap_update_bits(rt5659->regmap, RT5659_GPIO_CTRL_1,
4128 RT5659_GP2_PIN_MASK | RT5659_GP5_PIN_MASK |
4129 RT5659_GP9_PIN_MASK | RT5659_GP11_PIN_MASK |
4130 RT5659_GP6_PIN_MASK | RT5659_GP10_PIN_MASK |
4131 RT5659_GP12_PIN_MASK,
4132 RT5659_GP2_PIN_GPIO2 | RT5659_GP5_PIN_GPIO5 |
4133 RT5659_GP9_PIN_GPIO9 | RT5659_GP11_PIN_GPIO11 |
4134 RT5659_GP6_PIN_GPIO6 | RT5659_GP10_PIN_GPIO10 |
4135 RT5659_GP12_PIN_GPIO12);
4136 regmap_update_bits(rt5659->regmap, RT5659_DMIC_CTRL_1,
4137 RT5659_DMIC_1_DP_MASK | RT5659_DMIC_2_DP_MASK,
4138 RT5659_DMIC_1_DP_IN2N | RT5659_DMIC_2_DP_IN2P);
4139 }
4140
4141 switch (rt5659->pdata.jd_src) {
4142 case RT5659_JD3:
4143 regmap_write(rt5659->regmap, RT5659_EJD_CTRL_1, 0xa880);
4144 regmap_write(rt5659->regmap, RT5659_RC_CLK_CTRL, 0x9000);
4145 regmap_write(rt5659->regmap, RT5659_GPIO_CTRL_1, 0xc800);
4146 regmap_update_bits(rt5659->regmap, RT5659_PWR_ANLG_1,
4147 RT5659_PWR_MB, RT5659_PWR_MB);
4148 regmap_write(rt5659->regmap, RT5659_PWR_ANLG_2, 0x0001);
4149 regmap_write(rt5659->regmap, RT5659_IRQ_CTRL_2, 0x0040);
4150 break;
4151 case RT5659_JD_NULL:
4152 break;
4153 default:
4154 dev_warn(&i2c->dev, "Currently, support JD3 only\n");
4155 break;
4156 }
4157
4158 INIT_DELAYED_WORK(&rt5659->jack_detect_work, rt5659_jack_detect_work);
4159
4160 if (rt5659->i2c->irq) {
4161 ret = request_threaded_irq(rt5659->i2c->irq, NULL, rt5659_irq,
4162 IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING
4163 | IRQF_ONESHOT, "rt5659", rt5659);
4164 if (ret)
4165 dev_err(&i2c->dev, "Failed to reguest IRQ: %d\n", ret);
4166
4167 }
4168
4169 ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_rt5659,
4170 rt5659_dai, ARRAY_SIZE(rt5659_dai));
4171
4172 if (ret) {
4173 if (rt5659->i2c->irq)
4174 free_irq(rt5659->i2c->irq, rt5659);
4175 }
4176
4177 return 0;
4178}
4179
4180static int rt5659_i2c_remove(struct i2c_client *i2c)
4181{
4182 snd_soc_unregister_codec(&i2c->dev);
4183
4184 return 0;
4185}
4186
4187void rt5659_i2c_shutdown(struct i2c_client *client)
4188{
4189 struct rt5659_priv *rt5659 = i2c_get_clientdata(client);
4190
4191 regmap_write(rt5659->regmap, RT5659_RESET, 0);
4192}
4193
4194static const struct of_device_id rt5659_of_match[] = {
4195 { .compatible = "realtek,rt5658", },
4196 { .compatible = "realtek,rt5659", },
4197 {},
4198};
4199
4200static struct acpi_device_id rt5659_acpi_match[] = {
4201 { "10EC5658", 0},
4202 { "10EC5659", 0},
4203 { },
4204};
4205MODULE_DEVICE_TABLE(acpi, rt5659_acpi_match);
4206
4207struct i2c_driver rt5659_i2c_driver = {
4208 .driver = {
4209 .name = "rt5659",
4210 .owner = THIS_MODULE,
4211 .of_match_table = rt5659_of_match,
4212 .acpi_match_table = ACPI_PTR(rt5659_acpi_match),
4213 },
4214 .probe = rt5659_i2c_probe,
4215 .remove = rt5659_i2c_remove,
4216 .shutdown = rt5659_i2c_shutdown,
4217 .id_table = rt5659_i2c_id,
4218};
4219module_i2c_driver(rt5659_i2c_driver);
4220
4221MODULE_DESCRIPTION("ASoC RT5659 driver");
4222MODULE_AUTHOR("Bard Liao <bardliao@realtek.com>");
4223MODULE_LICENSE("GPL v2");
diff --git a/sound/soc/codecs/rt5659.h b/sound/soc/codecs/rt5659.h
new file mode 100644
index 000000000000..8f07ee903eaa
--- /dev/null
+++ b/sound/soc/codecs/rt5659.h
@@ -0,0 +1,1819 @@
1/*
2 * rt5659.h -- RT5659/RT5658 ALSA SoC audio driver
3 *
4 * Copyright 2015 Realtek Microelectronics
5 * Author: Bard Liao <bardliao@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 __RT5659_H__
13#define __RT5659_H__
14
15#include <sound/rt5659.h>
16
17#define DEVICE_ID 0x6311
18
19/* Info */
20#define RT5659_RESET 0x0000
21#define RT5659_VENDOR_ID 0x00fd
22#define RT5659_VENDOR_ID_1 0x00fe
23#define RT5659_DEVICE_ID 0x00ff
24/* I/O - Output */
25#define RT5659_SPO_VOL 0x0001
26#define RT5659_HP_VOL 0x0002
27#define RT5659_LOUT 0x0003
28#define RT5659_MONO_OUT 0x0004
29#define RT5659_HPL_GAIN 0x0005
30#define RT5659_HPR_GAIN 0x0006
31#define RT5659_MONO_GAIN 0x0007
32#define RT5659_SPDIF_CTRL_1 0x0008
33#define RT5659_SPDIF_CTRL_2 0x0009
34/* I/O - Input */
35#define RT5659_CAL_BST_CTRL 0x000a
36#define RT5659_IN1_IN2 0x000c
37#define RT5659_IN3_IN4 0x000d
38#define RT5659_INL1_INR1_VOL 0x000f
39/* I/O - Speaker */
40#define RT5659_EJD_CTRL_1 0x0010
41#define RT5659_EJD_CTRL_2 0x0011
42#define RT5659_EJD_CTRL_3 0x0012
43#define RT5659_SILENCE_CTRL 0x0015
44#define RT5659_PSV_CTRL 0x0016
45/* I/O - Sidetone */
46#define RT5659_SIDETONE_CTRL 0x0018
47/* I/O - ADC/DAC/DMIC */
48#define RT5659_DAC1_DIG_VOL 0x0019
49#define RT5659_DAC2_DIG_VOL 0x001a
50#define RT5659_DAC_CTRL 0x001b
51#define RT5659_STO1_ADC_DIG_VOL 0x001c
52#define RT5659_MONO_ADC_DIG_VOL 0x001d
53#define RT5659_STO2_ADC_DIG_VOL 0x001e
54#define RT5659_STO1_BOOST 0x001f
55#define RT5659_MONO_BOOST 0x0020
56#define RT5659_STO2_BOOST 0x0021
57#define RT5659_HP_IMP_GAIN_1 0x0022
58#define RT5659_HP_IMP_GAIN_2 0x0023
59/* Mixer - D-D */
60#define RT5659_STO1_ADC_MIXER 0x0026
61#define RT5659_MONO_ADC_MIXER 0x0027
62#define RT5659_AD_DA_MIXER 0x0029
63#define RT5659_STO_DAC_MIXER 0x002a
64#define RT5659_MONO_DAC_MIXER 0x002b
65#define RT5659_DIG_MIXER 0x002c
66#define RT5659_A_DAC_MUX 0x002d
67#define RT5659_DIG_INF23_DATA 0x002f
68/* Mixer - PDM */
69#define RT5659_PDM_OUT_CTRL 0x0031
70#define RT5659_PDM_DATA_CTRL_1 0x0032
71#define RT5659_PDM_DATA_CTRL_2 0x0033
72#define RT5659_PDM_DATA_CTRL_3 0x0034
73#define RT5659_PDM_DATA_CTRL_4 0x0035
74#define RT5659_SPDIF_CTRL 0x0036
75
76/* Mixer - ADC */
77#define RT5659_REC1_GAIN 0x003a
78#define RT5659_REC1_L1_MIXER 0x003b
79#define RT5659_REC1_L2_MIXER 0x003c
80#define RT5659_REC1_R1_MIXER 0x003d
81#define RT5659_REC1_R2_MIXER 0x003e
82#define RT5659_CAL_REC 0x0040
83#define RT5659_REC2_L1_MIXER 0x009b
84#define RT5659_REC2_L2_MIXER 0x009c
85#define RT5659_REC2_R1_MIXER 0x009d
86#define RT5659_REC2_R2_MIXER 0x009e
87#define RT5659_RC_CLK_CTRL 0x009f
88/* Mixer - DAC */
89#define RT5659_SPK_L_MIXER 0x0046
90#define RT5659_SPK_R_MIXER 0x0047
91#define RT5659_SPO_AMP_GAIN 0x0048
92#define RT5659_ALC_BACK_GAIN 0x0049
93#define RT5659_MONOMIX_GAIN 0x004a
94#define RT5659_MONOMIX_IN_GAIN 0x004b
95#define RT5659_OUT_L_GAIN 0x004d
96#define RT5659_OUT_L_MIXER 0x004e
97#define RT5659_OUT_R_GAIN 0x004f
98#define RT5659_OUT_R_MIXER 0x0050
99#define RT5659_LOUT_MIXER 0x0052
100
101#define RT5659_HAPTIC_GEN_CTRL_1 0x0053
102#define RT5659_HAPTIC_GEN_CTRL_2 0x0054
103#define RT5659_HAPTIC_GEN_CTRL_3 0x0055
104#define RT5659_HAPTIC_GEN_CTRL_4 0x0056
105#define RT5659_HAPTIC_GEN_CTRL_5 0x0057
106#define RT5659_HAPTIC_GEN_CTRL_6 0x0058
107#define RT5659_HAPTIC_GEN_CTRL_7 0x0059
108#define RT5659_HAPTIC_GEN_CTRL_8 0x005a
109#define RT5659_HAPTIC_GEN_CTRL_9 0x005b
110#define RT5659_HAPTIC_GEN_CTRL_10 0x005c
111#define RT5659_HAPTIC_GEN_CTRL_11 0x005d
112#define RT5659_HAPTIC_LPF_CTRL_1 0x005e
113#define RT5659_HAPTIC_LPF_CTRL_2 0x005f
114#define RT5659_HAPTIC_LPF_CTRL_3 0x0060
115/* Power */
116#define RT5659_PWR_DIG_1 0x0061
117#define RT5659_PWR_DIG_2 0x0062
118#define RT5659_PWR_ANLG_1 0x0063
119#define RT5659_PWR_ANLG_2 0x0064
120#define RT5659_PWR_ANLG_3 0x0065
121#define RT5659_PWR_MIXER 0x0066
122#define RT5659_PWR_VOL 0x0067
123/* Private Register Control */
124#define RT5659_PRIV_INDEX 0x006a
125#define RT5659_CLK_DET 0x006b
126#define RT5659_PRIV_DATA 0x006c
127/* System Clock Pre Divider Gating Control */
128#define RT5659_PRE_DIV_1 0x006e
129#define RT5659_PRE_DIV_2 0x006f
130/* Format - ADC/DAC */
131#define RT5659_I2S1_SDP 0x0070
132#define RT5659_I2S2_SDP 0x0071
133#define RT5659_I2S3_SDP 0x0072
134#define RT5659_ADDA_CLK_1 0x0073
135#define RT5659_ADDA_CLK_2 0x0074
136#define RT5659_DMIC_CTRL_1 0x0075
137#define RT5659_DMIC_CTRL_2 0x0076
138/* Format - TDM Control */
139#define RT5659_TDM_CTRL_1 0x0077
140#define RT5659_TDM_CTRL_2 0x0078
141#define RT5659_TDM_CTRL_3 0x0079
142#define RT5659_TDM_CTRL_4 0x007a
143#define RT5659_TDM_CTRL_5 0x007b
144
145/* Function - Analog */
146#define RT5659_GLB_CLK 0x0080
147#define RT5659_PLL_CTRL_1 0x0081
148#define RT5659_PLL_CTRL_2 0x0082
149#define RT5659_ASRC_1 0x0083
150#define RT5659_ASRC_2 0x0084
151#define RT5659_ASRC_3 0x0085
152#define RT5659_ASRC_4 0x0086
153#define RT5659_ASRC_5 0x0087
154#define RT5659_ASRC_6 0x0088
155#define RT5659_ASRC_7 0x0089
156#define RT5659_ASRC_8 0x008a
157#define RT5659_ASRC_9 0x008b
158#define RT5659_ASRC_10 0x008c
159#define RT5659_DEPOP_1 0x008e
160#define RT5659_DEPOP_2 0x008f
161#define RT5659_DEPOP_3 0x0090
162#define RT5659_HP_CHARGE_PUMP_1 0x0091
163#define RT5659_HP_CHARGE_PUMP_2 0x0092
164#define RT5659_MICBIAS_1 0x0093
165#define RT5659_MICBIAS_2 0x0094
166#define RT5659_ASRC_11 0x0097
167#define RT5659_ASRC_12 0x0098
168#define RT5659_ASRC_13 0x0099
169#define RT5659_REC_M1_M2_GAIN_CTRL 0x009a
170#define RT5659_CLASSD_CTRL_1 0x00a0
171#define RT5659_CLASSD_CTRL_2 0x00a1
172
173/* Function - Digital */
174#define RT5659_ADC_EQ_CTRL_1 0x00ae
175#define RT5659_ADC_EQ_CTRL_2 0x00af
176#define RT5659_DAC_EQ_CTRL_1 0x00b0
177#define RT5659_DAC_EQ_CTRL_2 0x00b1
178#define RT5659_DAC_EQ_CTRL_3 0x00b2
179
180#define RT5659_IRQ_CTRL_1 0x00b6
181#define RT5659_IRQ_CTRL_2 0x00b7
182#define RT5659_IRQ_CTRL_3 0x00b8
183#define RT5659_IRQ_CTRL_4 0x00b9
184#define RT5659_IRQ_CTRL_5 0x00ba
185#define RT5659_IRQ_CTRL_6 0x00bb
186#define RT5659_INT_ST_1 0x00be
187#define RT5659_INT_ST_2 0x00bf
188#define RT5659_GPIO_CTRL_1 0x00c0
189#define RT5659_GPIO_CTRL_2 0x00c1
190#define RT5659_GPIO_CTRL_3 0x00c2
191#define RT5659_GPIO_CTRL_4 0x00c3
192#define RT5659_GPIO_CTRL_5 0x00c4
193#define RT5659_GPIO_STA 0x00c5
194#define RT5659_SINE_GEN_CTRL_1 0x00cb
195#define RT5659_SINE_GEN_CTRL_2 0x00cc
196#define RT5659_SINE_GEN_CTRL_3 0x00cd
197#define RT5659_HP_AMP_DET_CTRL_1 0x00d6
198#define RT5659_HP_AMP_DET_CTRL_2 0x00d7
199#define RT5659_SV_ZCD_1 0x00d9
200#define RT5659_SV_ZCD_2 0x00da
201#define RT5659_IL_CMD_1 0x00db
202#define RT5659_IL_CMD_2 0x00dc
203#define RT5659_IL_CMD_3 0x00dd
204#define RT5659_IL_CMD_4 0x00de
205#define RT5659_4BTN_IL_CMD_1 0x00df
206#define RT5659_4BTN_IL_CMD_2 0x00e0
207#define RT5659_4BTN_IL_CMD_3 0x00e1
208#define RT5659_PSV_IL_CMD_1 0x00e4
209#define RT5659_PSV_IL_CMD_2 0x00e5
210
211#define RT5659_ADC_STO1_HP_CTRL_1 0x00ea
212#define RT5659_ADC_STO1_HP_CTRL_2 0x00eb
213#define RT5659_ADC_MONO_HP_CTRL_1 0x00ec
214#define RT5659_ADC_MONO_HP_CTRL_2 0x00ed
215#define RT5659_AJD1_CTRL 0x00f0
216#define RT5659_AJD2_AJD3_CTRL 0x00f1
217#define RT5659_JD1_THD 0x00f2
218#define RT5659_JD2_THD 0x00f3
219#define RT5659_JD3_THD 0x00f4
220#define RT5659_JD_CTRL_1 0x00f6
221#define RT5659_JD_CTRL_2 0x00f7
222#define RT5659_JD_CTRL_3 0x00f8
223#define RT5659_JD_CTRL_4 0x00f9
224/* General Control */
225#define RT5659_DIG_MISC 0x00fa
226#define RT5659_DUMMY_2 0x00fb
227#define RT5659_DUMMY_3 0x00fc
228
229#define RT5659_DAC_ADC_DIG_VOL 0x0100
230#define RT5659_BIAS_CUR_CTRL_1 0x010a
231#define RT5659_BIAS_CUR_CTRL_2 0x010b
232#define RT5659_BIAS_CUR_CTRL_3 0x010c
233#define RT5659_BIAS_CUR_CTRL_4 0x010d
234#define RT5659_BIAS_CUR_CTRL_5 0x010e
235#define RT5659_BIAS_CUR_CTRL_6 0x010f
236#define RT5659_BIAS_CUR_CTRL_7 0x0110
237#define RT5659_BIAS_CUR_CTRL_8 0x0111
238#define RT5659_BIAS_CUR_CTRL_9 0x0112
239#define RT5659_BIAS_CUR_CTRL_10 0x0113
240#define RT5659_MEMORY_TEST 0x0116
241#define RT5659_VREF_REC_OP_FB_CAP_CTRL 0x0117
242#define RT5659_CLASSD_0 0x011a
243#define RT5659_CLASSD_1 0x011b
244#define RT5659_CLASSD_2 0x011c
245#define RT5659_CLASSD_3 0x011d
246#define RT5659_CLASSD_4 0x011e
247#define RT5659_CLASSD_5 0x011f
248#define RT5659_CLASSD_6 0x0120
249#define RT5659_CLASSD_7 0x0121
250#define RT5659_CLASSD_8 0x0122
251#define RT5659_CLASSD_9 0x0123
252#define RT5659_CLASSD_10 0x0124
253#define RT5659_CHARGE_PUMP_1 0x0125
254#define RT5659_CHARGE_PUMP_2 0x0126
255#define RT5659_DIG_IN_CTRL_1 0x0132
256#define RT5659_DIG_IN_CTRL_2 0x0133
257#define RT5659_PAD_DRIVING_CTRL 0x0137
258#define RT5659_SOFT_RAMP_DEPOP 0x0138
259#define RT5659_PLL 0x0139
260#define RT5659_CHOP_DAC 0x013a
261#define RT5659_CHOP_ADC 0x013b
262#define RT5659_CALIB_ADC_CTRL 0x013c
263#define RT5659_SOFT_RAMP_DEPOP_DAC_CLK_CTRL 0x013e
264#define RT5659_VOL_TEST 0x013f
265#define RT5659_TEST_MODE_CTRL_1 0x0145
266#define RT5659_TEST_MODE_CTRL_2 0x0146
267#define RT5659_TEST_MODE_CTRL_3 0x0147
268#define RT5659_TEST_MODE_CTRL_4 0x0148
269#define RT5659_BASSBACK_CTRL 0x0150
270#define RT5659_MP3_PLUS_CTRL_1 0x0151
271#define RT5659_MP3_PLUS_CTRL_2 0x0152
272#define RT5659_MP3_HPF_A1 0x0153
273#define RT5659_MP3_HPF_A2 0x0154
274#define RT5659_MP3_HPF_H0 0x0155
275#define RT5659_MP3_LPF_H0 0x0156
276#define RT5659_3D_SPK_CTRL 0x0157
277#define RT5659_3D_SPK_COEF_1 0x0158
278#define RT5659_3D_SPK_COEF_2 0x0159
279#define RT5659_3D_SPK_COEF_3 0x015a
280#define RT5659_3D_SPK_COEF_4 0x015b
281#define RT5659_3D_SPK_COEF_5 0x015c
282#define RT5659_3D_SPK_COEF_6 0x015d
283#define RT5659_3D_SPK_COEF_7 0x015e
284#define RT5659_STO_NG2_CTRL_1 0x0160
285#define RT5659_STO_NG2_CTRL_2 0x0161
286#define RT5659_STO_NG2_CTRL_3 0x0162
287#define RT5659_STO_NG2_CTRL_4 0x0163
288#define RT5659_STO_NG2_CTRL_5 0x0164
289#define RT5659_STO_NG2_CTRL_6 0x0165
290#define RT5659_STO_NG2_CTRL_7 0x0166
291#define RT5659_STO_NG2_CTRL_8 0x0167
292#define RT5659_MONO_NG2_CTRL_1 0x0170
293#define RT5659_MONO_NG2_CTRL_2 0x0171
294#define RT5659_MONO_NG2_CTRL_3 0x0172
295#define RT5659_MONO_NG2_CTRL_4 0x0173
296#define RT5659_MONO_NG2_CTRL_5 0x0174
297#define RT5659_MONO_NG2_CTRL_6 0x0175
298#define RT5659_MID_HP_AMP_DET 0x0190
299#define RT5659_LOW_HP_AMP_DET 0x0191
300#define RT5659_LDO_CTRL 0x0192
301#define RT5659_HP_DECROSS_CTRL_1 0x01b0
302#define RT5659_HP_DECROSS_CTRL_2 0x01b1
303#define RT5659_HP_DECROSS_CTRL_3 0x01b2
304#define RT5659_HP_DECROSS_CTRL_4 0x01b3
305#define RT5659_HP_IMP_SENS_CTRL_1 0x01c0
306#define RT5659_HP_IMP_SENS_CTRL_2 0x01c1
307#define RT5659_HP_IMP_SENS_CTRL_3 0x01c2
308#define RT5659_HP_IMP_SENS_CTRL_4 0x01c3
309#define RT5659_HP_IMP_SENS_MAP_1 0x01c7
310#define RT5659_HP_IMP_SENS_MAP_2 0x01c8
311#define RT5659_HP_IMP_SENS_MAP_3 0x01c9
312#define RT5659_HP_IMP_SENS_MAP_4 0x01ca
313#define RT5659_HP_IMP_SENS_MAP_5 0x01cb
314#define RT5659_HP_IMP_SENS_MAP_6 0x01cc
315#define RT5659_HP_IMP_SENS_MAP_7 0x01cd
316#define RT5659_HP_IMP_SENS_MAP_8 0x01ce
317#define RT5659_HP_LOGIC_CTRL_1 0x01da
318#define RT5659_HP_LOGIC_CTRL_2 0x01db
319#define RT5659_HP_CALIB_CTRL_1 0x01de
320#define RT5659_HP_CALIB_CTRL_2 0x01df
321#define RT5659_HP_CALIB_CTRL_3 0x01e0
322#define RT5659_HP_CALIB_CTRL_4 0x01e1
323#define RT5659_HP_CALIB_CTRL_5 0x01e2
324#define RT5659_HP_CALIB_CTRL_6 0x01e3
325#define RT5659_HP_CALIB_CTRL_7 0x01e4
326#define RT5659_HP_CALIB_CTRL_9 0x01e6
327#define RT5659_HP_CALIB_CTRL_10 0x01e7
328#define RT5659_HP_CALIB_CTRL_11 0x01e8
329#define RT5659_HP_CALIB_STA_1 0x01ea
330#define RT5659_HP_CALIB_STA_2 0x01eb
331#define RT5659_HP_CALIB_STA_3 0x01ec
332#define RT5659_HP_CALIB_STA_4 0x01ed
333#define RT5659_HP_CALIB_STA_5 0x01ee
334#define RT5659_HP_CALIB_STA_6 0x01ef
335#define RT5659_HP_CALIB_STA_7 0x01f0
336#define RT5659_HP_CALIB_STA_8 0x01f1
337#define RT5659_HP_CALIB_STA_9 0x01f2
338#define RT5659_MONO_AMP_CALIB_CTRL_1 0x01f6
339#define RT5659_MONO_AMP_CALIB_CTRL_2 0x01f7
340#define RT5659_MONO_AMP_CALIB_CTRL_3 0x01f8
341#define RT5659_MONO_AMP_CALIB_CTRL_4 0x01f9
342#define RT5659_MONO_AMP_CALIB_CTRL_5 0x01fa
343#define RT5659_MONO_AMP_CALIB_STA_1 0x01fb
344#define RT5659_MONO_AMP_CALIB_STA_2 0x01fc
345#define RT5659_MONO_AMP_CALIB_STA_3 0x01fd
346#define RT5659_MONO_AMP_CALIB_STA_4 0x01fe
347#define RT5659_SPK_PWR_LMT_CTRL_1 0x0200
348#define RT5659_SPK_PWR_LMT_CTRL_2 0x0201
349#define RT5659_SPK_PWR_LMT_CTRL_3 0x0202
350#define RT5659_SPK_PWR_LMT_STA_1 0x0203
351#define RT5659_SPK_PWR_LMT_STA_2 0x0204
352#define RT5659_SPK_PWR_LMT_STA_3 0x0205
353#define RT5659_SPK_PWR_LMT_STA_4 0x0206
354#define RT5659_SPK_PWR_LMT_STA_5 0x0207
355#define RT5659_SPK_PWR_LMT_STA_6 0x0208
356#define RT5659_FLEX_SPK_BST_CTRL_1 0x0256
357#define RT5659_FLEX_SPK_BST_CTRL_2 0x0257
358#define RT5659_FLEX_SPK_BST_CTRL_3 0x0258
359#define RT5659_FLEX_SPK_BST_CTRL_4 0x0259
360#define RT5659_SPK_EX_LMT_CTRL_1 0x025a
361#define RT5659_SPK_EX_LMT_CTRL_2 0x025b
362#define RT5659_SPK_EX_LMT_CTRL_3 0x025c
363#define RT5659_SPK_EX_LMT_CTRL_4 0x025d
364#define RT5659_SPK_EX_LMT_CTRL_5 0x025e
365#define RT5659_SPK_EX_LMT_CTRL_6 0x025f
366#define RT5659_SPK_EX_LMT_CTRL_7 0x0260
367#define RT5659_ADJ_HPF_CTRL_1 0x0261
368#define RT5659_ADJ_HPF_CTRL_2 0x0262
369#define RT5659_SPK_DC_CAILB_CTRL_1 0x0265
370#define RT5659_SPK_DC_CAILB_CTRL_2 0x0266
371#define RT5659_SPK_DC_CAILB_CTRL_3 0x0267
372#define RT5659_SPK_DC_CAILB_CTRL_4 0x0268
373#define RT5659_SPK_DC_CAILB_CTRL_5 0x0269
374#define RT5659_SPK_DC_CAILB_STA_1 0x026a
375#define RT5659_SPK_DC_CAILB_STA_2 0x026b
376#define RT5659_SPK_DC_CAILB_STA_3 0x026c
377#define RT5659_SPK_DC_CAILB_STA_4 0x026d
378#define RT5659_SPK_DC_CAILB_STA_5 0x026e
379#define RT5659_SPK_DC_CAILB_STA_6 0x026f
380#define RT5659_SPK_DC_CAILB_STA_7 0x0270
381#define RT5659_SPK_DC_CAILB_STA_8 0x0271
382#define RT5659_SPK_DC_CAILB_STA_9 0x0272
383#define RT5659_SPK_DC_CAILB_STA_10 0x0273
384#define RT5659_SPK_VDD_STA_1 0x0280
385#define RT5659_SPK_VDD_STA_2 0x0281
386#define RT5659_SPK_DC_DET_CTRL_1 0x0282
387#define RT5659_SPK_DC_DET_CTRL_2 0x0283
388#define RT5659_SPK_DC_DET_CTRL_3 0x0284
389#define RT5659_PURE_DC_DET_CTRL_1 0x0290
390#define RT5659_PURE_DC_DET_CTRL_2 0x0291
391#define RT5659_DUMMY_4 0x02fa
392#define RT5659_DUMMY_5 0x02fb
393#define RT5659_DUMMY_6 0x02fc
394#define RT5659_DRC1_CTRL_1 0x0300
395#define RT5659_DRC1_CTRL_2 0x0301
396#define RT5659_DRC1_CTRL_3 0x0302
397#define RT5659_DRC1_CTRL_4 0x0303
398#define RT5659_DRC1_CTRL_5 0x0304
399#define RT5659_DRC1_CTRL_6 0x0305
400#define RT5659_DRC1_HARD_LMT_CTRL_1 0x0306
401#define RT5659_DRC1_HARD_LMT_CTRL_2 0x0307
402#define RT5659_DRC2_CTRL_1 0x0308
403#define RT5659_DRC2_CTRL_2 0x0309
404#define RT5659_DRC2_CTRL_3 0x030a
405#define RT5659_DRC2_CTRL_4 0x030b
406#define RT5659_DRC2_CTRL_5 0x030c
407#define RT5659_DRC2_CTRL_6 0x030d
408#define RT5659_DRC2_HARD_LMT_CTRL_1 0x030e
409#define RT5659_DRC2_HARD_LMT_CTRL_2 0x030f
410#define RT5659_DRC1_PRIV_1 0x0310
411#define RT5659_DRC1_PRIV_2 0x0311
412#define RT5659_DRC1_PRIV_3 0x0312
413#define RT5659_DRC1_PRIV_4 0x0313
414#define RT5659_DRC1_PRIV_5 0x0314
415#define RT5659_DRC1_PRIV_6 0x0315
416#define RT5659_DRC1_PRIV_7 0x0316
417#define RT5659_DRC2_PRIV_1 0x0317
418#define RT5659_DRC2_PRIV_2 0x0318
419#define RT5659_DRC2_PRIV_3 0x0319
420#define RT5659_DRC2_PRIV_4 0x031a
421#define RT5659_DRC2_PRIV_5 0x031b
422#define RT5659_DRC2_PRIV_6 0x031c
423#define RT5659_DRC2_PRIV_7 0x031d
424#define RT5659_MULTI_DRC_CTRL 0x0320
425#define RT5659_CROSS_OVER_1 0x0321
426#define RT5659_CROSS_OVER_2 0x0322
427#define RT5659_CROSS_OVER_3 0x0323
428#define RT5659_CROSS_OVER_4 0x0324
429#define RT5659_CROSS_OVER_5 0x0325
430#define RT5659_CROSS_OVER_6 0x0326
431#define RT5659_CROSS_OVER_7 0x0327
432#define RT5659_CROSS_OVER_8 0x0328
433#define RT5659_CROSS_OVER_9 0x0329
434#define RT5659_CROSS_OVER_10 0x032a
435#define RT5659_ALC_PGA_CTRL_1 0x0330
436#define RT5659_ALC_PGA_CTRL_2 0x0331
437#define RT5659_ALC_PGA_CTRL_3 0x0332
438#define RT5659_ALC_PGA_CTRL_4 0x0333
439#define RT5659_ALC_PGA_CTRL_5 0x0334
440#define RT5659_ALC_PGA_CTRL_6 0x0335
441#define RT5659_ALC_PGA_CTRL_7 0x0336
442#define RT5659_ALC_PGA_CTRL_8 0x0337
443#define RT5659_ALC_PGA_STA_1 0x0338
444#define RT5659_ALC_PGA_STA_2 0x0339
445#define RT5659_ALC_PGA_STA_3 0x033a
446#define RT5659_DAC_L_EQ_PRE_VOL 0x0340
447#define RT5659_DAC_R_EQ_PRE_VOL 0x0341
448#define RT5659_DAC_L_EQ_POST_VOL 0x0342
449#define RT5659_DAC_R_EQ_POST_VOL 0x0343
450#define RT5659_DAC_L_EQ_LPF1_A1 0x0344
451#define RT5659_DAC_L_EQ_LPF1_H0 0x0345
452#define RT5659_DAC_R_EQ_LPF1_A1 0x0346
453#define RT5659_DAC_R_EQ_LPF1_H0 0x0347
454#define RT5659_DAC_L_EQ_BPF2_A1 0x0348
455#define RT5659_DAC_L_EQ_BPF2_A2 0x0349
456#define RT5659_DAC_L_EQ_BPF2_H0 0x034a
457#define RT5659_DAC_R_EQ_BPF2_A1 0x034b
458#define RT5659_DAC_R_EQ_BPF2_A2 0x034c
459#define RT5659_DAC_R_EQ_BPF2_H0 0x034d
460#define RT5659_DAC_L_EQ_BPF3_A1 0x034e
461#define RT5659_DAC_L_EQ_BPF3_A2 0x034f
462#define RT5659_DAC_L_EQ_BPF3_H0 0x0350
463#define RT5659_DAC_R_EQ_BPF3_A1 0x0351
464#define RT5659_DAC_R_EQ_BPF3_A2 0x0352
465#define RT5659_DAC_R_EQ_BPF3_H0 0x0353
466#define RT5659_DAC_L_EQ_BPF4_A1 0x0354
467#define RT5659_DAC_L_EQ_BPF4_A2 0x0355
468#define RT5659_DAC_L_EQ_BPF4_H0 0x0356
469#define RT5659_DAC_R_EQ_BPF4_A1 0x0357
470#define RT5659_DAC_R_EQ_BPF4_A2 0x0358
471#define RT5659_DAC_R_EQ_BPF4_H0 0x0359
472#define RT5659_DAC_L_EQ_HPF1_A1 0x035a
473#define RT5659_DAC_L_EQ_HPF1_H0 0x035b
474#define RT5659_DAC_R_EQ_HPF1_A1 0x035c
475#define RT5659_DAC_R_EQ_HPF1_H0 0x035d
476#define RT5659_DAC_L_EQ_HPF2_A1 0x035e
477#define RT5659_DAC_L_EQ_HPF2_A2 0x035f
478#define RT5659_DAC_L_EQ_HPF2_H0 0x0360
479#define RT5659_DAC_R_EQ_HPF2_A1 0x0361
480#define RT5659_DAC_R_EQ_HPF2_A2 0x0362
481#define RT5659_DAC_R_EQ_HPF2_H0 0x0363
482#define RT5659_DAC_L_BI_EQ_BPF1_H0_1 0x0364
483#define RT5659_DAC_L_BI_EQ_BPF1_H0_2 0x0365
484#define RT5659_DAC_L_BI_EQ_BPF1_B1_1 0x0366
485#define RT5659_DAC_L_BI_EQ_BPF1_B1_2 0x0367
486#define RT5659_DAC_L_BI_EQ_BPF1_B2_1 0x0368
487#define RT5659_DAC_L_BI_EQ_BPF1_B2_2 0x0369
488#define RT5659_DAC_L_BI_EQ_BPF1_A1_1 0x036a
489#define RT5659_DAC_L_BI_EQ_BPF1_A1_2 0x036b
490#define RT5659_DAC_L_BI_EQ_BPF1_A2_1 0x036c
491#define RT5659_DAC_L_BI_EQ_BPF1_A2_2 0x036d
492#define RT5659_DAC_R_BI_EQ_BPF1_H0_1 0x036e
493#define RT5659_DAC_R_BI_EQ_BPF1_H0_2 0x036f
494#define RT5659_DAC_R_BI_EQ_BPF1_B1_1 0x0370
495#define RT5659_DAC_R_BI_EQ_BPF1_B1_2 0x0371
496#define RT5659_DAC_R_BI_EQ_BPF1_B2_1 0x0372
497#define RT5659_DAC_R_BI_EQ_BPF1_B2_2 0x0373
498#define RT5659_DAC_R_BI_EQ_BPF1_A1_1 0x0374
499#define RT5659_DAC_R_BI_EQ_BPF1_A1_2 0x0375
500#define RT5659_DAC_R_BI_EQ_BPF1_A2_1 0x0376
501#define RT5659_DAC_R_BI_EQ_BPF1_A2_2 0x0377
502#define RT5659_ADC_L_EQ_LPF1_A1 0x03d0
503#define RT5659_ADC_R_EQ_LPF1_A1 0x03d1
504#define RT5659_ADC_L_EQ_LPF1_H0 0x03d2
505#define RT5659_ADC_R_EQ_LPF1_H0 0x03d3
506#define RT5659_ADC_L_EQ_BPF1_A1 0x03d4
507#define RT5659_ADC_R_EQ_BPF1_A1 0x03d5
508#define RT5659_ADC_L_EQ_BPF1_A2 0x03d6
509#define RT5659_ADC_R_EQ_BPF1_A2 0x03d7
510#define RT5659_ADC_L_EQ_BPF1_H0 0x03d8
511#define RT5659_ADC_R_EQ_BPF1_H0 0x03d9
512#define RT5659_ADC_L_EQ_BPF2_A1 0x03da
513#define RT5659_ADC_R_EQ_BPF2_A1 0x03db
514#define RT5659_ADC_L_EQ_BPF2_A2 0x03dc
515#define RT5659_ADC_R_EQ_BPF2_A2 0x03dd
516#define RT5659_ADC_L_EQ_BPF2_H0 0x03de
517#define RT5659_ADC_R_EQ_BPF2_H0 0x03df
518#define RT5659_ADC_L_EQ_BPF3_A1 0x03e0
519#define RT5659_ADC_R_EQ_BPF3_A1 0x03e1
520#define RT5659_ADC_L_EQ_BPF3_A2 0x03e2
521#define RT5659_ADC_R_EQ_BPF3_A2 0x03e3
522#define RT5659_ADC_L_EQ_BPF3_H0 0x03e4
523#define RT5659_ADC_R_EQ_BPF3_H0 0x03e5
524#define RT5659_ADC_L_EQ_BPF4_A1 0x03e6
525#define RT5659_ADC_R_EQ_BPF4_A1 0x03e7
526#define RT5659_ADC_L_EQ_BPF4_A2 0x03e8
527#define RT5659_ADC_R_EQ_BPF4_A2 0x03e9
528#define RT5659_ADC_L_EQ_BPF4_H0 0x03ea
529#define RT5659_ADC_R_EQ_BPF4_H0 0x03eb
530#define RT5659_ADC_L_EQ_HPF1_A1 0x03ec
531#define RT5659_ADC_R_EQ_HPF1_A1 0x03ed
532#define RT5659_ADC_L_EQ_HPF1_H0 0x03ee
533#define RT5659_ADC_R_EQ_HPF1_H0 0x03ef
534#define RT5659_ADC_L_EQ_PRE_VOL 0x03f0
535#define RT5659_ADC_R_EQ_PRE_VOL 0x03f1
536#define RT5659_ADC_L_EQ_POST_VOL 0x03f2
537#define RT5659_ADC_R_EQ_POST_VOL 0x03f3
538
539
540
541/* global definition */
542#define RT5659_L_MUTE (0x1 << 15)
543#define RT5659_L_MUTE_SFT 15
544#define RT5659_VOL_L_MUTE (0x1 << 14)
545#define RT5659_VOL_L_SFT 14
546#define RT5659_R_MUTE (0x1 << 7)
547#define RT5659_R_MUTE_SFT 7
548#define RT5659_VOL_R_MUTE (0x1 << 6)
549#define RT5659_VOL_R_SFT 6
550#define RT5659_L_VOL_MASK (0x3f << 8)
551#define RT5659_L_VOL_SFT 8
552#define RT5659_R_VOL_MASK (0x3f)
553#define RT5659_R_VOL_SFT 0
554
555/*Headphone Amp L/R Analog Gain and Digital NG2 Gain Control (0x0005 0x0006)*/
556#define RT5659_G_HP (0x1f << 8)
557#define RT5659_G_HP_SFT 8
558#define RT5659_G_STO_DA_DMIX (0x1f)
559#define RT5659_G_STO_DA_SFT 0
560
561/* IN1/IN2 Control (0x000c) */
562#define RT5659_IN1_DF_MASK (0x1 << 15)
563#define RT5659_IN1_DF 15
564#define RT5659_BST1_MASK (0x7f << 8)
565#define RT5659_BST1_SFT 8
566#define RT5659_BST2_MASK (0x7f)
567#define RT5659_BST2_SFT 0
568
569/* IN3/IN4 Control (0x000d) */
570#define RT5659_IN3_DF_MASK (0x1 << 15)
571#define RT5659_IN3_DF 15
572#define RT5659_BST3_MASK (0x7f << 8)
573#define RT5659_BST3_SFT 8
574#define RT5659_IN4_DF_MASK (0x1 << 7)
575#define RT5659_IN4_DF 7
576#define RT5659_BST4_MASK (0x7f)
577#define RT5659_BST4_SFT 0
578
579/* INL and INR Volume Control (0x000f) */
580#define RT5659_INL_VOL_MASK (0x1f << 8)
581#define RT5659_INL_VOL_SFT 8
582#define RT5659_INR_VOL_MASK (0x1f)
583#define RT5659_INR_VOL_SFT 0
584
585/* Embeeded Jack and Type Detection Control 1 (0x0010) */
586#define RT5659_EMB_JD_EN (0x1 << 15)
587#define RT5659_EMB_JD_EN_SFT 15
588#define RT5659_JD_MODE (0x1 << 13)
589#define RT5659_JD_MODE_SFT 13
590#define RT5659_EXT_JD_EN (0x1 << 11)
591#define RT5659_EXT_JD_EN_SFT 11
592#define RT5659_EXT_JD_DIG (0x1 << 9)
593
594/* Embeeded Jack and Type Detection Control 2 (0x0011) */
595#define RT5659_EXT_JD_SRC (0x7 << 4)
596#define RT5659_EXT_JD_SRC_SFT 4
597#define RT5659_EXT_JD_SRC_GPIO_JD1 (0x0 << 4)
598#define RT5659_EXT_JD_SRC_GPIO_JD2 (0x1 << 4)
599#define RT5659_EXT_JD_SRC_JD1_1 (0x2 << 4)
600#define RT5659_EXT_JD_SRC_JD1_2 (0x3 << 4)
601#define RT5659_EXT_JD_SRC_JD2 (0x4 << 4)
602#define RT5659_EXT_JD_SRC_JD3 (0x5 << 4)
603#define RT5659_EXT_JD_SRC_MANUAL (0x6 << 4)
604
605/* Slience Detection Control (0x0015) */
606#define RT5659_SIL_DET_MASK (0x1 << 15)
607#define RT5659_SIL_DET_DIS (0x0 << 15)
608#define RT5659_SIL_DET_EN (0x1 << 15)
609
610/* Sidetone Control (0x0018) */
611#define RT5659_ST_SEL_MASK (0x7 << 9)
612#define RT5659_ST_SEL_SFT 9
613#define RT5659_ST_EN (0x1 << 6)
614#define RT5659_ST_EN_SFT 6
615
616/* DAC1 Digital Volume (0x0019) */
617#define RT5659_DAC_L1_VOL_MASK (0xff << 8)
618#define RT5659_DAC_L1_VOL_SFT 8
619#define RT5659_DAC_R1_VOL_MASK (0xff)
620#define RT5659_DAC_R1_VOL_SFT 0
621
622/* DAC2 Digital Volume (0x001a) */
623#define RT5659_DAC_L2_VOL_MASK (0xff << 8)
624#define RT5659_DAC_L2_VOL_SFT 8
625#define RT5659_DAC_R2_VOL_MASK (0xff)
626#define RT5659_DAC_R2_VOL_SFT 0
627
628/* DAC2 Control (0x001b) */
629#define RT5659_M_DAC2_L_VOL (0x1 << 13)
630#define RT5659_M_DAC2_L_VOL_SFT 13
631#define RT5659_M_DAC2_R_VOL (0x1 << 12)
632#define RT5659_M_DAC2_R_VOL_SFT 12
633#define RT5659_DAC_L2_SEL_MASK (0x7 << 4)
634#define RT5659_DAC_L2_SEL_SFT 4
635#define RT5659_DAC_R2_SEL_MASK (0x7 << 0)
636#define RT5659_DAC_R2_SEL_SFT 0
637
638/* ADC Digital Volume Control (0x001c) */
639#define RT5659_ADC_L_VOL_MASK (0x7f << 8)
640#define RT5659_ADC_L_VOL_SFT 8
641#define RT5659_ADC_R_VOL_MASK (0x7f)
642#define RT5659_ADC_R_VOL_SFT 0
643
644/* Mono ADC Digital Volume Control (0x001d) */
645#define RT5659_MONO_ADC_L_VOL_MASK (0x7f << 8)
646#define RT5659_MONO_ADC_L_VOL_SFT 8
647#define RT5659_MONO_ADC_R_VOL_MASK (0x7f)
648#define RT5659_MONO_ADC_R_VOL_SFT 0
649
650/* Stereo1 ADC Boost Gain Control (0x001f) */
651#define RT5659_STO1_ADC_L_BST_MASK (0x3 << 14)
652#define RT5659_STO1_ADC_L_BST_SFT 14
653#define RT5659_STO1_ADC_R_BST_MASK (0x3 << 12)
654#define RT5659_STO1_ADC_R_BST_SFT 12
655
656/* Mono ADC Boost Gain Control (0x0020) */
657#define RT5659_MONO_ADC_L_BST_MASK (0x3 << 14)
658#define RT5659_MONO_ADC_L_BST_SFT 14
659#define RT5659_MONO_ADC_R_BST_MASK (0x3 << 12)
660#define RT5659_MONO_ADC_R_BST_SFT 12
661
662/* Stereo1 ADC Boost Gain Control (0x001f) */
663#define RT5659_STO2_ADC_L_BST_MASK (0x3 << 14)
664#define RT5659_STO2_ADC_L_BST_SFT 14
665#define RT5659_STO2_ADC_R_BST_MASK (0x3 << 12)
666#define RT5659_STO2_ADC_R_BST_SFT 12
667
668/* Stereo ADC Mixer Control (0x0026) */
669#define RT5659_M_STO1_ADC_L1 (0x1 << 15)
670#define RT5659_M_STO1_ADC_L1_SFT 15
671#define RT5659_M_STO1_ADC_L2 (0x1 << 14)
672#define RT5659_M_STO1_ADC_L2_SFT 14
673#define RT5659_STO1_ADC1_SRC_MASK (0x1 << 13)
674#define RT5659_STO1_ADC1_SRC_SFT 13
675#define RT5659_STO1_ADC1_SRC_ADC (0x1 << 13)
676#define RT5659_STO1_ADC1_SRC_DACMIX (0x0 << 13)
677#define RT5659_STO1_ADC_SRC_MASK (0x1 << 12)
678#define RT5659_STO1_ADC_SRC_SFT 12
679#define RT5659_STO1_ADC_SRC_ADC1 (0x1 << 12)
680#define RT5659_STO1_ADC_SRC_ADC2 (0x0 << 12)
681#define RT5659_STO1_ADC2_SRC_MASK (0x1 << 11)
682#define RT5659_STO1_ADC2_SRC_SFT 11
683#define RT5659_STO1_DMIC_SRC_MASK (0x1 << 8)
684#define RT5659_STO1_DMIC_SRC_SFT 8
685#define RT5659_STO1_DMIC_SRC_DMIC2 (0x1 << 8)
686#define RT5659_STO1_DMIC_SRC_DMIC1 (0x0 << 8)
687#define RT5659_M_STO1_ADC_R1 (0x1 << 6)
688#define RT5659_M_STO1_ADC_R1_SFT 6
689#define RT5659_M_STO1_ADC_R2 (0x1 << 5)
690#define RT5659_M_STO1_ADC_R2_SFT 5
691
692/* Mono1 ADC Mixer control (0x0027) */
693#define RT5659_M_MONO_ADC_L1 (0x1 << 15)
694#define RT5659_M_MONO_ADC_L1_SFT 15
695#define RT5659_M_MONO_ADC_L2 (0x1 << 14)
696#define RT5659_M_MONO_ADC_L2_SFT 14
697#define RT5659_MONO_ADC_L2_SRC_MASK (0x1 << 12)
698#define RT5659_MONO_ADC_L2_SRC_SFT 12
699#define RT5659_MONO_ADC_L1_SRC_MASK (0x1 << 11)
700#define RT5659_MONO_ADC_L1_SRC_SFT 11
701#define RT5659_MONO_ADC_L_SRC_MASK (0x3 << 9)
702#define RT5659_MONO_ADC_L_SRC_SFT 9
703#define RT5659_MONO_DMIC_L_SRC_MASK (0x1 << 8)
704#define RT5659_MONO_DMIC_L_SRC_SFT 8
705#define RT5659_M_MONO_ADC_R1 (0x1 << 7)
706#define RT5659_M_MONO_ADC_R1_SFT 7
707#define RT5659_M_MONO_ADC_R2 (0x1 << 6)
708#define RT5659_M_MONO_ADC_R2_SFT 6
709#define RT5659_STO2_ADC_SRC_MASK (0x1 << 5)
710#define RT5659_STO2_ADC_SRC_SFT 5
711#define RT5659_MONO_ADC_R2_SRC_MASK (0x1 << 4)
712#define RT5659_MONO_ADC_R2_SRC_SFT 4
713#define RT5659_MONO_ADC_R1_SRC_MASK (0x1 << 3)
714#define RT5659_MONO_ADC_R1_SRC_SFT 3
715#define RT5659_MONO_ADC_R_SRC_MASK (0x3 << 1)
716#define RT5659_MONO_ADC_R_SRC_SFT 1
717#define RT5659_MONO_DMIC_R_SRC_MASK 0x1
718#define RT5659_MONO_DMIC_R_SRC_SFT 0
719
720/* ADC Mixer to DAC Mixer Control (0x0029) */
721#define RT5659_M_ADCMIX_L (0x1 << 15)
722#define RT5659_M_ADCMIX_L_SFT 15
723#define RT5659_M_DAC1_L (0x1 << 14)
724#define RT5659_M_DAC1_L_SFT 14
725#define RT5659_DAC1_R_SEL_MASK (0x3 << 10)
726#define RT5659_DAC1_R_SEL_SFT 10
727#define RT5659_DAC1_R_SEL_IF1 (0x0 << 10)
728#define RT5659_DAC1_R_SEL_IF2 (0x1 << 10)
729#define RT5659_DAC1_R_SEL_IF3 (0x2 << 10)
730#define RT5659_DAC1_L_SEL_MASK (0x3 << 8)
731#define RT5659_DAC1_L_SEL_SFT 8
732#define RT5659_DAC1_L_SEL_IF1 (0x0 << 8)
733#define RT5659_DAC1_L_SEL_IF2 (0x1 << 8)
734#define RT5659_DAC1_L_SEL_IF3 (0x2 << 8)
735#define RT5659_M_ADCMIX_R (0x1 << 7)
736#define RT5659_M_ADCMIX_R_SFT 7
737#define RT5659_M_DAC1_R (0x1 << 6)
738#define RT5659_M_DAC1_R_SFT 6
739
740/* Stereo DAC Mixer Control (0x002a) */
741#define RT5659_M_DAC_L1_STO_L (0x1 << 15)
742#define RT5659_M_DAC_L1_STO_L_SFT 15
743#define RT5659_G_DAC_L1_STO_L_MASK (0x1 << 14)
744#define RT5659_G_DAC_L1_STO_L_SFT 14
745#define RT5659_M_DAC_R1_STO_L (0x1 << 13)
746#define RT5659_M_DAC_R1_STO_L_SFT 13
747#define RT5659_G_DAC_R1_STO_L_MASK (0x1 << 12)
748#define RT5659_G_DAC_R1_STO_L_SFT 12
749#define RT5659_M_DAC_L2_STO_L (0x1 << 11)
750#define RT5659_M_DAC_L2_STO_L_SFT 11
751#define RT5659_G_DAC_L2_STO_L_MASK (0x1 << 10)
752#define RT5659_G_DAC_L2_STO_L_SFT 10
753#define RT5659_M_DAC_R2_STO_L (0x1 << 9)
754#define RT5659_M_DAC_R2_STO_L_SFT 9
755#define RT5659_G_DAC_R2_STO_L_MASK (0x1 << 8)
756#define RT5659_G_DAC_R2_STO_L_SFT 8
757#define RT5659_M_DAC_L1_STO_R (0x1 << 7)
758#define RT5659_M_DAC_L1_STO_R_SFT 7
759#define RT5659_G_DAC_L1_STO_R_MASK (0x1 << 6)
760#define RT5659_G_DAC_L1_STO_R_SFT 6
761#define RT5659_M_DAC_R1_STO_R (0x1 << 5)
762#define RT5659_M_DAC_R1_STO_R_SFT 5
763#define RT5659_G_DAC_R1_STO_R_MASK (0x1 << 4)
764#define RT5659_G_DAC_R1_STO_R_SFT 4
765#define RT5659_M_DAC_L2_STO_R (0x1 << 3)
766#define RT5659_M_DAC_L2_STO_R_SFT 3
767#define RT5659_G_DAC_L2_STO_R_MASK (0x1 << 2)
768#define RT5659_G_DAC_L2_STO_R_SFT 2
769#define RT5659_M_DAC_R2_STO_R (0x1 << 1)
770#define RT5659_M_DAC_R2_STO_R_SFT 1
771#define RT5659_G_DAC_R2_STO_R_MASK (0x1)
772#define RT5659_G_DAC_R2_STO_R_SFT 0
773
774/* Mono DAC Mixer Control (0x002b) */
775#define RT5659_M_DAC_L1_MONO_L (0x1 << 15)
776#define RT5659_M_DAC_L1_MONO_L_SFT 15
777#define RT5659_G_DAC_L1_MONO_L_MASK (0x1 << 14)
778#define RT5659_G_DAC_L1_MONO_L_SFT 14
779#define RT5659_M_DAC_R1_MONO_L (0x1 << 13)
780#define RT5659_M_DAC_R1_MONO_L_SFT 13
781#define RT5659_G_DAC_R1_MONO_L_MASK (0x1 << 12)
782#define RT5659_G_DAC_R1_MONO_L_SFT 12
783#define RT5659_M_DAC_L2_MONO_L (0x1 << 11)
784#define RT5659_M_DAC_L2_MONO_L_SFT 11
785#define RT5659_G_DAC_L2_MONO_L_MASK (0x1 << 10)
786#define RT5659_G_DAC_L2_MONO_L_SFT 10
787#define RT5659_M_DAC_R2_MONO_L (0x1 << 9)
788#define RT5659_M_DAC_R2_MONO_L_SFT 9
789#define RT5659_G_DAC_R2_MONO_L_MASK (0x1 << 8)
790#define RT5659_G_DAC_R2_MONO_L_SFT 8
791#define RT5659_M_DAC_L1_MONO_R (0x1 << 7)
792#define RT5659_M_DAC_L1_MONO_R_SFT 7
793#define RT5659_G_DAC_L1_MONO_R_MASK (0x1 << 6)
794#define RT5659_G_DAC_L1_MONO_R_SFT 6
795#define RT5659_M_DAC_R1_MONO_R (0x1 << 5)
796#define RT5659_M_DAC_R1_MONO_R_SFT 5
797#define RT5659_G_DAC_R1_MONO_R_MASK (0x1 << 4)
798#define RT5659_G_DAC_R1_MONO_R_SFT 4
799#define RT5659_M_DAC_L2_MONO_R (0x1 << 3)
800#define RT5659_M_DAC_L2_MONO_R_SFT 3
801#define RT5659_G_DAC_L2_MONO_R_MASK (0x1 << 2)
802#define RT5659_G_DAC_L2_MONO_R_SFT 2
803#define RT5659_M_DAC_R2_MONO_R (0x1 << 1)
804#define RT5659_M_DAC_R2_MONO_R_SFT 1
805#define RT5659_G_DAC_R2_MONO_R_MASK (0x1)
806#define RT5659_G_DAC_R2_MONO_R_SFT 0
807
808/* Digital Mixer Control (0x002c) */
809#define RT5659_M_DAC_MIX_L (0x1 << 7)
810#define RT5659_M_DAC_MIX_L_SFT 7
811#define RT5659_DAC_MIX_L_MASK (0x1 << 6)
812#define RT5659_DAC_MIX_L_SFT 6
813#define RT5659_M_DAC_MIX_R (0x1 << 5)
814#define RT5659_M_DAC_MIX_R_SFT 5
815#define RT5659_DAC_MIX_R_MASK (0x1 << 4)
816#define RT5659_DAC_MIX_R_SFT 4
817
818/* Analog DAC Input Source Control (0x002d) */
819#define RT5659_A_DACL1_SEL (0x1 << 3)
820#define RT5659_A_DACL1_SFT 3
821#define RT5659_A_DACR1_SEL (0x1 << 2)
822#define RT5659_A_DACR1_SFT 2
823#define RT5659_A_DACL2_SEL (0x1 << 1)
824#define RT5659_A_DACL2_SFT 1
825#define RT5659_A_DACR2_SEL (0x1 << 0)
826#define RT5659_A_DACR2_SFT 0
827
828/* Digital Interface Data Control (0x002f) */
829#define RT5659_IF2_ADC3_IN_MASK (0x3 << 14)
830#define RT5659_IF2_ADC3_IN_SFT 14
831#define RT5659_IF2_ADC_IN_MASK (0x3 << 12)
832#define RT5659_IF2_ADC_IN_SFT 12
833#define RT5659_IF2_DAC_SEL_MASK (0x3 << 10)
834#define RT5659_IF2_DAC_SEL_SFT 10
835#define RT5659_IF2_ADC_SEL_MASK (0x3 << 8)
836#define RT5659_IF2_ADC_SEL_SFT 8
837#define RT5659_IF3_DAC_SEL_MASK (0x3 << 6)
838#define RT5659_IF3_DAC_SEL_SFT 6
839#define RT5659_IF3_ADC_SEL_MASK (0x3 << 4)
840#define RT5659_IF3_ADC_SEL_SFT 4
841#define RT5659_IF3_ADC_IN_MASK (0x3 << 0)
842#define RT5659_IF3_ADC_IN_SFT 0
843
844/* PDM Output Control (0x0031) */
845#define RT5659_PDM1_L_MASK (0x1 << 15)
846#define RT5659_PDM1_L_SFT 15
847#define RT5659_M_PDM1_L (0x1 << 14)
848#define RT5659_M_PDM1_L_SFT 14
849#define RT5659_PDM1_R_MASK (0x1 << 13)
850#define RT5659_PDM1_R_SFT 13
851#define RT5659_M_PDM1_R (0x1 << 12)
852#define RT5659_M_PDM1_R_SFT 12
853#define RT5659_PDM2_BUSY (0x1 << 7)
854#define RT5659_PDM1_BUSY (0x1 << 6)
855#define RT5659_PDM_PATTERN (0x1 << 5)
856#define RT5659_PDM_GAIN (0x1 << 4)
857#define RT5659_PDM_DIV_MASK (0x3)
858
859/*S/PDIF Output Control (0x0036) */
860#define RT5659_SPDIF_SEL_MASK (0x3 << 0)
861#define RT5659_SPDIF_SEL_SFT 0
862
863/* REC Left Mixer Control 2 (0x003c) */
864#define RT5659_M_BST1_RM1_L (0x1 << 5)
865#define RT5659_M_BST1_RM1_L_SFT 5
866#define RT5659_M_BST2_RM1_L (0x1 << 4)
867#define RT5659_M_BST2_RM1_L_SFT 4
868#define RT5659_M_BST3_RM1_L (0x1 << 3)
869#define RT5659_M_BST3_RM1_L_SFT 3
870#define RT5659_M_BST4_RM1_L (0x1 << 2)
871#define RT5659_M_BST4_RM1_L_SFT 2
872#define RT5659_M_INL_RM1_L (0x1 << 1)
873#define RT5659_M_INL_RM1_L_SFT 1
874#define RT5659_M_SPKVOLL_RM1_L (0x1)
875#define RT5659_M_SPKVOLL_RM1_L_SFT 0
876
877/* REC Right Mixer Control 2 (0x003e) */
878#define RT5659_M_BST1_RM1_R (0x1 << 5)
879#define RT5659_M_BST1_RM1_R_SFT 5
880#define RT5659_M_BST2_RM1_R (0x1 << 4)
881#define RT5659_M_BST2_RM1_R_SFT 4
882#define RT5659_M_BST3_RM1_R (0x1 << 3)
883#define RT5659_M_BST3_RM1_R_SFT 3
884#define RT5659_M_BST4_RM1_R (0x1 << 2)
885#define RT5659_M_BST4_RM1_R_SFT 2
886#define RT5659_M_INR_RM1_R (0x1 << 1)
887#define RT5659_M_INR_RM1_R_SFT 1
888#define RT5659_M_HPOVOLR_RM1_R (0x1)
889#define RT5659_M_HPOVOLR_RM1_R_SFT 0
890
891/* SPK Left Mixer Control (0x0046) */
892#define RT5659_M_BST3_SM_L (0x1 << 4)
893#define RT5659_M_BST3_SM_L_SFT 4
894#define RT5659_M_IN_R_SM_L (0x1 << 3)
895#define RT5659_M_IN_R_SM_L_SFT 3
896#define RT5659_M_IN_L_SM_L (0x1 << 2)
897#define RT5659_M_IN_L_SM_L_SFT 2
898#define RT5659_M_BST1_SM_L (0x1 << 1)
899#define RT5659_M_BST1_SM_L_SFT 1
900#define RT5659_M_DAC_L2_SM_L (0x1)
901#define RT5659_M_DAC_L2_SM_L_SFT 0
902
903/* SPK Right Mixer Control (0x0047) */
904#define RT5659_M_BST3_SM_R (0x1 << 4)
905#define RT5659_M_BST3_SM_R_SFT 4
906#define RT5659_M_IN_R_SM_R (0x1 << 3)
907#define RT5659_M_IN_R_SM_R_SFT 3
908#define RT5659_M_IN_L_SM_R (0x1 << 2)
909#define RT5659_M_IN_L_SM_R_SFT 2
910#define RT5659_M_BST4_SM_R (0x1 << 1)
911#define RT5659_M_BST4_SM_R_SFT 1
912#define RT5659_M_DAC_R2_SM_R (0x1)
913#define RT5659_M_DAC_R2_SM_R_SFT 0
914
915/* SPO Amp Input and Gain Control (0x0048) */
916#define RT5659_M_DAC_L2_SPKOMIX (0x1 << 13)
917#define RT5659_M_DAC_L2_SPKOMIX_SFT 13
918#define RT5659_M_SPKVOLL_SPKOMIX (0x1 << 12)
919#define RT5659_M_SPKVOLL_SPKOMIX_SFT 12
920#define RT5659_M_DAC_R2_SPKOMIX (0x1 << 9)
921#define RT5659_M_DAC_R2_SPKOMIX_SFT 9
922#define RT5659_M_SPKVOLR_SPKOMIX (0x1 << 8)
923#define RT5659_M_SPKVOLR_SPKOMIX_SFT 8
924
925/* MONOMIX Input and Gain Control (0x004b) */
926#define RT5659_M_MONOVOL_MA (0x1 << 9)
927#define RT5659_M_MONOVOL_MA_SFT 9
928#define RT5659_M_DAC_L2_MA (0x1 << 8)
929#define RT5659_M_DAC_L2_MA_SFT 8
930#define RT5659_M_BST3_MM (0x1 << 4)
931#define RT5659_M_BST3_MM_SFT 4
932#define RT5659_M_BST2_MM (0x1 << 3)
933#define RT5659_M_BST2_MM_SFT 3
934#define RT5659_M_BST1_MM (0x1 << 2)
935#define RT5659_M_BST1_MM_SFT 2
936#define RT5659_M_DAC_R2_MM (0x1 << 1)
937#define RT5659_M_DAC_R2_MM_SFT 1
938#define RT5659_M_DAC_L2_MM (0x1)
939#define RT5659_M_DAC_L2_MM_SFT 0
940
941/* Output Left Mixer Control 1 (0x004d) */
942#define RT5659_G_BST3_OM_L_MASK (0x7 << 12)
943#define RT5659_G_BST3_OM_L_SFT 12
944#define RT5659_G_BST2_OM_L_MASK (0x7 << 9)
945#define RT5659_G_BST2_OM_L_SFT 9
946#define RT5659_G_BST1_OM_L_MASK (0x7 << 6)
947#define RT5659_G_BST1_OM_L_SFT 6
948#define RT5659_G_IN_L_OM_L_MASK (0x7 << 3)
949#define RT5659_G_IN_L_OM_L_SFT 3
950#define RT5659_G_DAC_L2_OM_L_MASK (0x7 << 0)
951#define RT5659_G_DAC_L2_OM_L_SFT 0
952
953/* Output Left Mixer Input Control (0x004e) */
954#define RT5659_M_BST3_OM_L (0x1 << 4)
955#define RT5659_M_BST3_OM_L_SFT 4
956#define RT5659_M_BST2_OM_L (0x1 << 3)
957#define RT5659_M_BST2_OM_L_SFT 3
958#define RT5659_M_BST1_OM_L (0x1 << 2)
959#define RT5659_M_BST1_OM_L_SFT 2
960#define RT5659_M_IN_L_OM_L (0x1 << 1)
961#define RT5659_M_IN_L_OM_L_SFT 1
962#define RT5659_M_DAC_L2_OM_L (0x1)
963#define RT5659_M_DAC_L2_OM_L_SFT 0
964
965/* Output Right Mixer Input Control (0x0050) */
966#define RT5659_M_BST4_OM_R (0x1 << 4)
967#define RT5659_M_BST4_OM_R_SFT 4
968#define RT5659_M_BST3_OM_R (0x1 << 3)
969#define RT5659_M_BST3_OM_R_SFT 3
970#define RT5659_M_BST2_OM_R (0x1 << 2)
971#define RT5659_M_BST2_OM_R_SFT 2
972#define RT5659_M_IN_R_OM_R (0x1 << 1)
973#define RT5659_M_IN_R_OM_R_SFT 1
974#define RT5659_M_DAC_R2_OM_R (0x1)
975#define RT5659_M_DAC_R2_OM_R_SFT 0
976
977/* LOUT Mixer Control (0x0052) */
978#define RT5659_M_DAC_L2_LM (0x1 << 15)
979#define RT5659_M_DAC_L2_LM_SFT 15
980#define RT5659_M_DAC_R2_LM (0x1 << 14)
981#define RT5659_M_DAC_R2_LM_SFT 14
982#define RT5659_M_OV_L_LM (0x1 << 13)
983#define RT5659_M_OV_L_LM_SFT 13
984#define RT5659_M_OV_R_LM (0x1 << 12)
985#define RT5659_M_OV_R_LM_SFT 12
986
987/* Power Management for Digital 1 (0x0061) */
988#define RT5659_PWR_I2S1 (0x1 << 15)
989#define RT5659_PWR_I2S1_BIT 15
990#define RT5659_PWR_I2S2 (0x1 << 14)
991#define RT5659_PWR_I2S2_BIT 14
992#define RT5659_PWR_I2S3 (0x1 << 13)
993#define RT5659_PWR_I2S3_BIT 13
994#define RT5659_PWR_SPDIF (0x1 << 12)
995#define RT5659_PWR_SPDIF_BIT 12
996#define RT5659_PWR_DAC_L1 (0x1 << 11)
997#define RT5659_PWR_DAC_L1_BIT 11
998#define RT5659_PWR_DAC_R1 (0x1 << 10)
999#define RT5659_PWR_DAC_R1_BIT 10
1000#define RT5659_PWR_DAC_L2 (0x1 << 9)
1001#define RT5659_PWR_DAC_L2_BIT 9
1002#define RT5659_PWR_DAC_R2 (0x1 << 8)
1003#define RT5659_PWR_DAC_R2_BIT 8
1004#define RT5659_PWR_LDO (0x1 << 7)
1005#define RT5659_PWR_LDO_BIT 7
1006#define RT5659_PWR_ADC_L1 (0x1 << 4)
1007#define RT5659_PWR_ADC_L1_BIT 4
1008#define RT5659_PWR_ADC_R1 (0x1 << 3)
1009#define RT5659_PWR_ADC_R1_BIT 3
1010#define RT5659_PWR_ADC_L2 (0x1 << 2)
1011#define RT5659_PWR_ADC_L2_BIT 4
1012#define RT5659_PWR_ADC_R2 (0x1 << 1)
1013#define RT5659_PWR_ADC_R2_BIT 1
1014#define RT5659_PWR_CLS_D (0x1)
1015#define RT5659_PWR_CLS_D_BIT 0
1016
1017/* Power Management for Digital 2 (0x0062) */
1018#define RT5659_PWR_ADC_S1F (0x1 << 15)
1019#define RT5659_PWR_ADC_S1F_BIT 15
1020#define RT5659_PWR_ADC_S2F (0x1 << 14)
1021#define RT5659_PWR_ADC_S2F_BIT 14
1022#define RT5659_PWR_ADC_MF_L (0x1 << 13)
1023#define RT5659_PWR_ADC_MF_L_BIT 13
1024#define RT5659_PWR_ADC_MF_R (0x1 << 12)
1025#define RT5659_PWR_ADC_MF_R_BIT 12
1026#define RT5659_PWR_DAC_S1F (0x1 << 10)
1027#define RT5659_PWR_DAC_S1F_BIT 10
1028#define RT5659_PWR_DAC_MF_L (0x1 << 9)
1029#define RT5659_PWR_DAC_MF_L_BIT 9
1030#define RT5659_PWR_DAC_MF_R (0x1 << 8)
1031#define RT5659_PWR_DAC_MF_R_BIT 8
1032#define RT5659_PWR_PDM1 (0x1 << 7)
1033#define RT5659_PWR_PDM1_BIT 7
1034
1035/* Power Management for Analog 1 (0x0063) */
1036#define RT5659_PWR_VREF1 (0x1 << 15)
1037#define RT5659_PWR_VREF1_BIT 15
1038#define RT5659_PWR_FV1 (0x1 << 14)
1039#define RT5659_PWR_FV1_BIT 14
1040#define RT5659_PWR_VREF2 (0x1 << 13)
1041#define RT5659_PWR_VREF2_BIT 13
1042#define RT5659_PWR_FV2 (0x1 << 12)
1043#define RT5659_PWR_FV2_BIT 12
1044#define RT5659_PWR_VREF3 (0x1 << 11)
1045#define RT5659_PWR_VREF3_BIT 11
1046#define RT5659_PWR_FV3 (0x1 << 10)
1047#define RT5659_PWR_FV3_BIT 10
1048#define RT5659_PWR_MB (0x1 << 9)
1049#define RT5659_PWR_MB_BIT 9
1050#define RT5659_PWR_LM (0x1 << 8)
1051#define RT5659_PWR_LM_BIT 8
1052#define RT5659_PWR_BG (0x1 << 7)
1053#define RT5659_PWR_BG_BIT 7
1054#define RT5659_PWR_MA (0x1 << 6)
1055#define RT5659_PWR_MA_BIT 6
1056#define RT5659_PWR_HA_L (0x1 << 5)
1057#define RT5659_PWR_HA_L_BIT 5
1058#define RT5659_PWR_HA_R (0x1 << 4)
1059#define RT5659_PWR_HA_R_BIT 4
1060
1061/* Power Management for Analog 2 (0x0064) */
1062#define RT5659_PWR_BST1 (0x1 << 15)
1063#define RT5659_PWR_BST1_BIT 15
1064#define RT5659_PWR_BST2 (0x1 << 14)
1065#define RT5659_PWR_BST2_BIT 14
1066#define RT5659_PWR_BST3 (0x1 << 13)
1067#define RT5659_PWR_BST3_BIT 13
1068#define RT5659_PWR_BST4 (0x1 << 12)
1069#define RT5659_PWR_BST4_BIT 12
1070#define RT5659_PWR_MB1 (0x1 << 11)
1071#define RT5659_PWR_MB1_BIT 11
1072#define RT5659_PWR_MB2 (0x1 << 10)
1073#define RT5659_PWR_MB2_BIT 10
1074#define RT5659_PWR_MB3 (0x1 << 9)
1075#define RT5659_PWR_MB3_BIT 9
1076#define RT5659_PWR_BST1_P (0x1 << 6)
1077#define RT5659_PWR_BST1_P_BIT 6
1078#define RT5659_PWR_BST2_P (0x1 << 5)
1079#define RT5659_PWR_BST2_P_BIT 5
1080#define RT5659_PWR_BST3_P (0x1 << 4)
1081#define RT5659_PWR_BST3_P_BIT 4
1082#define RT5659_PWR_BST4_P (0x1 << 3)
1083#define RT5659_PWR_BST4_P_BIT 3
1084#define RT5659_PWR_JD1 (0x1 << 2)
1085#define RT5659_PWR_JD1_BIT 2
1086#define RT5659_PWR_JD2 (0x1 << 1)
1087#define RT5659_PWR_JD2_BIT 1
1088#define RT5659_PWR_JD3 (0x1)
1089#define RT5659_PWR_JD3_BIT 0
1090
1091/* Power Management for Analog 3 (0x0065) */
1092#define RT5659_PWR_BST_L (0x1 << 8)
1093#define RT5659_PWR_BST_L_BIT 8
1094#define RT5659_PWR_BST_R (0x1 << 7)
1095#define RT5659_PWR_BST_R_BIT 7
1096#define RT5659_PWR_PLL (0x1 << 6)
1097#define RT5659_PWR_PLL_BIT 6
1098#define RT5659_PWR_LDO5 (0x1 << 5)
1099#define RT5659_PWR_LDO5_BIT 5
1100#define RT5659_PWR_LDO4 (0x1 << 4)
1101#define RT5659_PWR_LDO4_BIT 4
1102#define RT5659_PWR_LDO3 (0x1 << 3)
1103#define RT5659_PWR_LDO3_BIT 3
1104#define RT5659_PWR_LDO2 (0x1 << 2)
1105#define RT5659_PWR_LDO2_BIT 2
1106#define RT5659_PWR_SVD (0x1 << 1)
1107#define RT5659_PWR_SVD_BIT 1
1108
1109/* Power Management for Mixer (0x0066) */
1110#define RT5659_PWR_OM_L (0x1 << 15)
1111#define RT5659_PWR_OM_L_BIT 15
1112#define RT5659_PWR_OM_R (0x1 << 14)
1113#define RT5659_PWR_OM_R_BIT 14
1114#define RT5659_PWR_SM_L (0x1 << 13)
1115#define RT5659_PWR_SM_L_BIT 13
1116#define RT5659_PWR_SM_R (0x1 << 12)
1117#define RT5659_PWR_SM_R_BIT 12
1118#define RT5659_PWR_RM1_L (0x1 << 11)
1119#define RT5659_PWR_RM1_L_BIT 11
1120#define RT5659_PWR_RM1_R (0x1 << 10)
1121#define RT5659_PWR_RM1_R_BIT 10
1122#define RT5659_PWR_MM (0x1 << 8)
1123#define RT5659_PWR_MM_BIT 8
1124#define RT5659_PWR_RM2_L (0x1 << 3)
1125#define RT5659_PWR_RM2_L_BIT 3
1126#define RT5659_PWR_RM2_R (0x1 << 2)
1127#define RT5659_PWR_RM2_R_BIT 2
1128
1129/* Power Management for Volume (0x0067) */
1130#define RT5659_PWR_SV_L (0x1 << 15)
1131#define RT5659_PWR_SV_L_BIT 15
1132#define RT5659_PWR_SV_R (0x1 << 14)
1133#define RT5659_PWR_SV_R_BIT 14
1134#define RT5659_PWR_OV_L (0x1 << 13)
1135#define RT5659_PWR_OV_L_BIT 13
1136#define RT5659_PWR_OV_R (0x1 << 12)
1137#define RT5659_PWR_OV_R_BIT 12
1138#define RT5659_PWR_IN_L (0x1 << 9)
1139#define RT5659_PWR_IN_L_BIT 9
1140#define RT5659_PWR_IN_R (0x1 << 8)
1141#define RT5659_PWR_IN_R_BIT 8
1142#define RT5659_PWR_MV (0x1 << 7)
1143#define RT5659_PWR_MV_BIT 7
1144#define RT5659_PWR_MIC_DET (0x1 << 5)
1145#define RT5659_PWR_MIC_DET_BIT 5
1146
1147/* I2S1/2/3 Audio Serial Data Port Control (0x0070 0x0071 0x0072) */
1148#define RT5659_I2S_MS_MASK (0x1 << 15)
1149#define RT5659_I2S_MS_SFT 15
1150#define RT5659_I2S_MS_M (0x0 << 15)
1151#define RT5659_I2S_MS_S (0x1 << 15)
1152#define RT5659_I2S_O_CP_MASK (0x3 << 12)
1153#define RT5659_I2S_O_CP_SFT 12
1154#define RT5659_I2S_O_CP_OFF (0x0 << 12)
1155#define RT5659_I2S_O_CP_U_LAW (0x1 << 12)
1156#define RT5659_I2S_O_CP_A_LAW (0x2 << 12)
1157#define RT5659_I2S_I_CP_MASK (0x3 << 10)
1158#define RT5659_I2S_I_CP_SFT 10
1159#define RT5659_I2S_I_CP_OFF (0x0 << 10)
1160#define RT5659_I2S_I_CP_U_LAW (0x1 << 10)
1161#define RT5659_I2S_I_CP_A_LAW (0x2 << 10)
1162#define RT5659_I2S_BP_MASK (0x1 << 8)
1163#define RT5659_I2S_BP_SFT 8
1164#define RT5659_I2S_BP_NOR (0x0 << 8)
1165#define RT5659_I2S_BP_INV (0x1 << 8)
1166#define RT5659_I2S_DL_MASK (0x3 << 4)
1167#define RT5659_I2S_DL_SFT 4
1168#define RT5659_I2S_DL_16 (0x0 << 4)
1169#define RT5659_I2S_DL_20 (0x1 << 4)
1170#define RT5659_I2S_DL_24 (0x2 << 4)
1171#define RT5659_I2S_DL_8 (0x3 << 4)
1172#define RT5659_I2S_DF_MASK (0x7)
1173#define RT5659_I2S_DF_SFT 0
1174#define RT5659_I2S_DF_I2S (0x0)
1175#define RT5659_I2S_DF_LEFT (0x1)
1176#define RT5659_I2S_DF_PCM_A (0x2)
1177#define RT5659_I2S_DF_PCM_B (0x3)
1178#define RT5659_I2S_DF_PCM_A_N (0x6)
1179#define RT5659_I2S_DF_PCM_B_N (0x7)
1180
1181/* ADC/DAC Clock Control 1 (0x0073) */
1182#define RT5659_I2S_PD1_MASK (0x7 << 12)
1183#define RT5659_I2S_PD1_SFT 12
1184#define RT5659_I2S_PD1_1 (0x0 << 12)
1185#define RT5659_I2S_PD1_2 (0x1 << 12)
1186#define RT5659_I2S_PD1_3 (0x2 << 12)
1187#define RT5659_I2S_PD1_4 (0x3 << 12)
1188#define RT5659_I2S_PD1_6 (0x4 << 12)
1189#define RT5659_I2S_PD1_8 (0x5 << 12)
1190#define RT5659_I2S_PD1_12 (0x6 << 12)
1191#define RT5659_I2S_PD1_16 (0x7 << 12)
1192#define RT5659_I2S_BCLK_MS2_MASK (0x1 << 11)
1193#define RT5659_I2S_BCLK_MS2_SFT 11
1194#define RT5659_I2S_BCLK_MS2_32 (0x0 << 11)
1195#define RT5659_I2S_BCLK_MS2_64 (0x1 << 11)
1196#define RT5659_I2S_PD2_MASK (0x7 << 8)
1197#define RT5659_I2S_PD2_SFT 8
1198#define RT5659_I2S_PD2_1 (0x0 << 8)
1199#define RT5659_I2S_PD2_2 (0x1 << 8)
1200#define RT5659_I2S_PD2_3 (0x2 << 8)
1201#define RT5659_I2S_PD2_4 (0x3 << 8)
1202#define RT5659_I2S_PD2_6 (0x4 << 8)
1203#define RT5659_I2S_PD2_8 (0x5 << 8)
1204#define RT5659_I2S_PD2_12 (0x6 << 8)
1205#define RT5659_I2S_PD2_16 (0x7 << 8)
1206#define RT5659_I2S_BCLK_MS3_MASK (0x1 << 7)
1207#define RT5659_I2S_BCLK_MS3_SFT 7
1208#define RT5659_I2S_BCLK_MS3_32 (0x0 << 7)
1209#define RT5659_I2S_BCLK_MS3_64 (0x1 << 7)
1210#define RT5659_I2S_PD3_MASK (0x7 << 4)
1211#define RT5659_I2S_PD3_SFT 4
1212#define RT5659_I2S_PD3_1 (0x0 << 4)
1213#define RT5659_I2S_PD3_2 (0x1 << 4)
1214#define RT5659_I2S_PD3_3 (0x2 << 4)
1215#define RT5659_I2S_PD3_4 (0x3 << 4)
1216#define RT5659_I2S_PD3_6 (0x4 << 4)
1217#define RT5659_I2S_PD3_8 (0x5 << 4)
1218#define RT5659_I2S_PD3_12 (0x6 << 4)
1219#define RT5659_I2S_PD3_16 (0x7 << 4)
1220#define RT5659_DAC_OSR_MASK (0x3 << 2)
1221#define RT5659_DAC_OSR_SFT 2
1222#define RT5659_DAC_OSR_128 (0x0 << 2)
1223#define RT5659_DAC_OSR_64 (0x1 << 2)
1224#define RT5659_DAC_OSR_32 (0x2 << 2)
1225#define RT5659_DAC_OSR_16 (0x3 << 2)
1226#define RT5659_ADC_OSR_MASK (0x3)
1227#define RT5659_ADC_OSR_SFT 0
1228#define RT5659_ADC_OSR_128 (0x0)
1229#define RT5659_ADC_OSR_64 (0x1)
1230#define RT5659_ADC_OSR_32 (0x2)
1231#define RT5659_ADC_OSR_16 (0x3)
1232
1233/* Digital Microphone Control (0x0075) */
1234#define RT5659_DMIC_1_EN_MASK (0x1 << 15)
1235#define RT5659_DMIC_1_EN_SFT 15
1236#define RT5659_DMIC_1_DIS (0x0 << 15)
1237#define RT5659_DMIC_1_EN (0x1 << 15)
1238#define RT5659_DMIC_2_EN_MASK (0x1 << 14)
1239#define RT5659_DMIC_2_EN_SFT 14
1240#define RT5659_DMIC_2_DIS (0x0 << 14)
1241#define RT5659_DMIC_2_EN (0x1 << 14)
1242#define RT5659_DMIC_1L_LH_MASK (0x1 << 13)
1243#define RT5659_DMIC_1L_LH_SFT 13
1244#define RT5659_DMIC_1L_LH_RISING (0x0 << 13)
1245#define RT5659_DMIC_1L_LH_FALLING (0x1 << 13)
1246#define RT5659_DMIC_1R_LH_MASK (0x1 << 12)
1247#define RT5659_DMIC_1R_LH_SFT 12
1248#define RT5659_DMIC_1R_LH_RISING (0x0 << 12)
1249#define RT5659_DMIC_1R_LH_FALLING (0x1 << 12)
1250#define RT5659_DMIC_2_DP_MASK (0x3 << 10)
1251#define RT5659_DMIC_2_DP_SFT 10
1252#define RT5659_DMIC_2_DP_GPIO6 (0x0 << 10)
1253#define RT5659_DMIC_2_DP_GPIO10 (0x1 << 10)
1254#define RT5659_DMIC_2_DP_GPIO12 (0x2 << 10)
1255#define RT5659_DMIC_2_DP_IN2P (0x3 << 10)
1256#define RT5659_DMIC_CLK_MASK (0x7 << 5)
1257#define RT5659_DMIC_CLK_SFT 5
1258#define RT5659_DMIC_1_DP_MASK (0x3 << 0)
1259#define RT5659_DMIC_1_DP_SFT 0
1260#define RT5659_DMIC_1_DP_GPIO5 (0x0 << 0)
1261#define RT5659_DMIC_1_DP_GPIO9 (0x1 << 0)
1262#define RT5659_DMIC_1_DP_GPIO11 (0x2 << 0)
1263#define RT5659_DMIC_1_DP_IN2N (0x3 << 0)
1264
1265/* TDM control 1 (0x0078)*/
1266#define RT5659_DS_ADC_SLOT01_SFT 14
1267#define RT5659_DS_ADC_SLOT23_SFT 12
1268#define RT5659_DS_ADC_SLOT45_SFT 10
1269#define RT5659_DS_ADC_SLOT67_SFT 8
1270#define RT5659_ADCDAT_SRC_MASK 0x1f
1271#define RT5659_ADCDAT_SRC_SFT 0
1272
1273/* Global Clock Control (0x0080) */
1274#define RT5659_SCLK_SRC_MASK (0x3 << 14)
1275#define RT5659_SCLK_SRC_SFT 14
1276#define RT5659_SCLK_SRC_MCLK (0x0 << 14)
1277#define RT5659_SCLK_SRC_PLL1 (0x1 << 14)
1278#define RT5659_SCLK_SRC_RCCLK (0x2 << 14)
1279#define RT5659_PLL1_SRC_MASK (0x7 << 11)
1280#define RT5659_PLL1_SRC_SFT 11
1281#define RT5659_PLL1_SRC_MCLK (0x0 << 11)
1282#define RT5659_PLL1_SRC_BCLK1 (0x1 << 11)
1283#define RT5659_PLL1_SRC_BCLK2 (0x2 << 11)
1284#define RT5659_PLL1_SRC_BCLK3 (0x3 << 11)
1285#define RT5659_PLL1_PD_MASK (0x1 << 3)
1286#define RT5659_PLL1_PD_SFT 3
1287#define RT5659_PLL1_PD_1 (0x0 << 3)
1288#define RT5659_PLL1_PD_2 (0x1 << 3)
1289
1290#define RT5659_PLL_INP_MAX 40000000
1291#define RT5659_PLL_INP_MIN 256000
1292/* PLL M/N/K Code Control 1 (0x0081) */
1293#define RT5659_PLL_N_MAX 0x001ff
1294#define RT5659_PLL_N_MASK (RT5659_PLL_N_MAX << 7)
1295#define RT5659_PLL_N_SFT 7
1296#define RT5659_PLL_K_MAX 0x001f
1297#define RT5659_PLL_K_MASK (RT5659_PLL_K_MAX)
1298#define RT5659_PLL_K_SFT 0
1299
1300/* PLL M/N/K Code Control 2 (0x0082) */
1301#define RT5659_PLL_M_MAX 0x00f
1302#define RT5659_PLL_M_MASK (RT5659_PLL_M_MAX << 12)
1303#define RT5659_PLL_M_SFT 12
1304#define RT5659_PLL_M_BP (0x1 << 11)
1305#define RT5659_PLL_M_BP_SFT 11
1306
1307/* PLL tracking mode 1 (0x0083) */
1308#define RT5659_I2S3_ASRC_MASK (0x1 << 13)
1309#define RT5659_I2S3_ASRC_SFT 13
1310#define RT5659_I2S2_ASRC_MASK (0x1 << 12)
1311#define RT5659_I2S2_ASRC_SFT 12
1312#define RT5659_I2S1_ASRC_MASK (0x1 << 11)
1313#define RT5659_I2S1_ASRC_SFT 11
1314#define RT5659_DAC_STO_ASRC_MASK (0x1 << 10)
1315#define RT5659_DAC_STO_ASRC_SFT 10
1316#define RT5659_DAC_MONO_L_ASRC_MASK (0x1 << 9)
1317#define RT5659_DAC_MONO_L_ASRC_SFT 9
1318#define RT5659_DAC_MONO_R_ASRC_MASK (0x1 << 8)
1319#define RT5659_DAC_MONO_R_ASRC_SFT 8
1320#define RT5659_DMIC_STO1_ASRC_MASK (0x1 << 7)
1321#define RT5659_DMIC_STO1_ASRC_SFT 7
1322#define RT5659_DMIC_MONO_L_ASRC_MASK (0x1 << 5)
1323#define RT5659_DMIC_MONO_L_ASRC_SFT 5
1324#define RT5659_DMIC_MONO_R_ASRC_MASK (0x1 << 4)
1325#define RT5659_DMIC_MONO_R_ASRC_SFT 4
1326#define RT5659_ADC_STO1_ASRC_MASK (0x1 << 3)
1327#define RT5659_ADC_STO1_ASRC_SFT 3
1328#define RT5659_ADC_MONO_L_ASRC_MASK (0x1 << 1)
1329#define RT5659_ADC_MONO_L_ASRC_SFT 1
1330#define RT5659_ADC_MONO_R_ASRC_MASK (0x1)
1331#define RT5659_ADC_MONO_R_ASRC_SFT 0
1332
1333/* PLL tracking mode 2 (0x0084)*/
1334#define RT5659_DA_STO_T_MASK (0x7 << 12)
1335#define RT5659_DA_STO_T_SFT 12
1336#define RT5659_DA_MONO_L_T_MASK (0x7 << 8)
1337#define RT5659_DA_MONO_L_T_SFT 8
1338#define RT5659_DA_MONO_R_T_MASK (0x7 << 4)
1339#define RT5659_DA_MONO_R_T_SFT 4
1340#define RT5659_AD_STO1_T_MASK (0x7)
1341#define RT5659_AD_STO1_T_SFT 0
1342
1343/* PLL tracking mode 3 (0x0085)*/
1344#define RT5659_AD_STO2_T_MASK (0x7 << 8)
1345#define RT5659_AD_STO2_T_SFT 8
1346#define RT5659_AD_MONO_L_T_MASK (0x7 << 4)
1347#define RT5659_AD_MONO_L_T_SFT 4
1348#define RT5659_AD_MONO_R_T_MASK (0x7)
1349#define RT5659_AD_MONO_R_T_SFT 0
1350
1351/* ASRC Control 4 (0x0086) */
1352#define RT5659_I2S1_RATE_MASK (0xf << 12)
1353#define RT5659_I2S1_RATE_SFT 12
1354#define RT5659_I2S2_RATE_MASK (0xf << 8)
1355#define RT5659_I2S2_RATE_SFT 8
1356#define RT5659_I2S3_RATE_MASK (0xf << 4)
1357#define RT5659_I2S3_RATE_SFT 4
1358
1359/* Depop Mode Control 1 (0x8e) */
1360#define RT5659_SMT_TRIG_MASK (0x1 << 15)
1361#define RT5659_SMT_TRIG_SFT 15
1362#define RT5659_SMT_TRIG_DIS (0x0 << 15)
1363#define RT5659_SMT_TRIG_EN (0x1 << 15)
1364#define RT5659_HP_L_SMT_MASK (0x1 << 9)
1365#define RT5659_HP_L_SMT_SFT 9
1366#define RT5659_HP_L_SMT_DIS (0x0 << 9)
1367#define RT5659_HP_L_SMT_EN (0x1 << 9)
1368#define RT5659_HP_R_SMT_MASK (0x1 << 8)
1369#define RT5659_HP_R_SMT_SFT 8
1370#define RT5659_HP_R_SMT_DIS (0x0 << 8)
1371#define RT5659_HP_R_SMT_EN (0x1 << 8)
1372#define RT5659_HP_CD_PD_MASK (0x1 << 7)
1373#define RT5659_HP_CD_PD_SFT 7
1374#define RT5659_HP_CD_PD_DIS (0x0 << 7)
1375#define RT5659_HP_CD_PD_EN (0x1 << 7)
1376#define RT5659_RSTN_MASK (0x1 << 6)
1377#define RT5659_RSTN_SFT 6
1378#define RT5659_RSTN_DIS (0x0 << 6)
1379#define RT5659_RSTN_EN (0x1 << 6)
1380#define RT5659_RSTP_MASK (0x1 << 5)
1381#define RT5659_RSTP_SFT 5
1382#define RT5659_RSTP_DIS (0x0 << 5)
1383#define RT5659_RSTP_EN (0x1 << 5)
1384#define RT5659_HP_CO_MASK (0x1 << 4)
1385#define RT5659_HP_CO_SFT 4
1386#define RT5659_HP_CO_DIS (0x0 << 4)
1387#define RT5659_HP_CO_EN (0x1 << 4)
1388#define RT5659_HP_CP_MASK (0x1 << 3)
1389#define RT5659_HP_CP_SFT 3
1390#define RT5659_HP_CP_PD (0x0 << 3)
1391#define RT5659_HP_CP_PU (0x1 << 3)
1392#define RT5659_HP_SG_MASK (0x1 << 2)
1393#define RT5659_HP_SG_SFT 2
1394#define RT5659_HP_SG_DIS (0x0 << 2)
1395#define RT5659_HP_SG_EN (0x1 << 2)
1396#define RT5659_HP_DP_MASK (0x1 << 1)
1397#define RT5659_HP_DP_SFT 1
1398#define RT5659_HP_DP_PD (0x0 << 1)
1399#define RT5659_HP_DP_PU (0x1 << 1)
1400#define RT5659_HP_CB_MASK (0x1)
1401#define RT5659_HP_CB_SFT 0
1402#define RT5659_HP_CB_PD (0x0)
1403#define RT5659_HP_CB_PU (0x1)
1404
1405/* Depop Mode Control 2 (0x8f) */
1406#define RT5659_DEPOP_MASK (0x1 << 13)
1407#define RT5659_DEPOP_SFT 13
1408#define RT5659_DEPOP_AUTO (0x0 << 13)
1409#define RT5659_DEPOP_MAN (0x1 << 13)
1410#define RT5659_RAMP_MASK (0x1 << 12)
1411#define RT5659_RAMP_SFT 12
1412#define RT5659_RAMP_DIS (0x0 << 12)
1413#define RT5659_RAMP_EN (0x1 << 12)
1414#define RT5659_BPS_MASK (0x1 << 11)
1415#define RT5659_BPS_SFT 11
1416#define RT5659_BPS_DIS (0x0 << 11)
1417#define RT5659_BPS_EN (0x1 << 11)
1418#define RT5659_FAST_UPDN_MASK (0x1 << 10)
1419#define RT5659_FAST_UPDN_SFT 10
1420#define RT5659_FAST_UPDN_DIS (0x0 << 10)
1421#define RT5659_FAST_UPDN_EN (0x1 << 10)
1422#define RT5659_MRES_MASK (0x3 << 8)
1423#define RT5659_MRES_SFT 8
1424#define RT5659_MRES_15MO (0x0 << 8)
1425#define RT5659_MRES_25MO (0x1 << 8)
1426#define RT5659_MRES_35MO (0x2 << 8)
1427#define RT5659_MRES_45MO (0x3 << 8)
1428#define RT5659_VLO_MASK (0x1 << 7)
1429#define RT5659_VLO_SFT 7
1430#define RT5659_VLO_3V (0x0 << 7)
1431#define RT5659_VLO_32V (0x1 << 7)
1432#define RT5659_DIG_DP_MASK (0x1 << 6)
1433#define RT5659_DIG_DP_SFT 6
1434#define RT5659_DIG_DP_DIS (0x0 << 6)
1435#define RT5659_DIG_DP_EN (0x1 << 6)
1436#define RT5659_DP_TH_MASK (0x3 << 4)
1437#define RT5659_DP_TH_SFT 4
1438
1439/* Depop Mode Control 3 (0x90) */
1440#define RT5659_CP_SYS_MASK (0x7 << 12)
1441#define RT5659_CP_SYS_SFT 12
1442#define RT5659_CP_FQ1_MASK (0x7 << 8)
1443#define RT5659_CP_FQ1_SFT 8
1444#define RT5659_CP_FQ2_MASK (0x7 << 4)
1445#define RT5659_CP_FQ2_SFT 4
1446#define RT5659_CP_FQ3_MASK (0x7)
1447#define RT5659_CP_FQ3_SFT 0
1448#define RT5659_CP_FQ_1_5_KHZ 0
1449#define RT5659_CP_FQ_3_KHZ 1
1450#define RT5659_CP_FQ_6_KHZ 2
1451#define RT5659_CP_FQ_12_KHZ 3
1452#define RT5659_CP_FQ_24_KHZ 4
1453#define RT5659_CP_FQ_48_KHZ 5
1454#define RT5659_CP_FQ_96_KHZ 6
1455#define RT5659_CP_FQ_192_KHZ 7
1456
1457/* HPOUT charge pump 1 (0x0091) */
1458#define RT5659_OSW_L_MASK (0x1 << 11)
1459#define RT5659_OSW_L_SFT 11
1460#define RT5659_OSW_L_DIS (0x0 << 11)
1461#define RT5659_OSW_L_EN (0x1 << 11)
1462#define RT5659_OSW_R_MASK (0x1 << 10)
1463#define RT5659_OSW_R_SFT 10
1464#define RT5659_OSW_R_DIS (0x0 << 10)
1465#define RT5659_OSW_R_EN (0x1 << 10)
1466#define RT5659_PM_HP_MASK (0x3 << 8)
1467#define RT5659_PM_HP_SFT 8
1468#define RT5659_PM_HP_LV (0x0 << 8)
1469#define RT5659_PM_HP_MV (0x1 << 8)
1470#define RT5659_PM_HP_HV (0x2 << 8)
1471#define RT5659_IB_HP_MASK (0x3 << 6)
1472#define RT5659_IB_HP_SFT 6
1473#define RT5659_IB_HP_125IL (0x0 << 6)
1474#define RT5659_IB_HP_25IL (0x1 << 6)
1475#define RT5659_IB_HP_5IL (0x2 << 6)
1476#define RT5659_IB_HP_1IL (0x3 << 6)
1477
1478/* PV detection and SPK gain control (0x92) */
1479#define RT5659_PVDD_DET_MASK (0x1 << 15)
1480#define RT5659_PVDD_DET_SFT 15
1481#define RT5659_PVDD_DET_DIS (0x0 << 15)
1482#define RT5659_PVDD_DET_EN (0x1 << 15)
1483#define RT5659_SPK_AG_MASK (0x1 << 14)
1484#define RT5659_SPK_AG_SFT 14
1485#define RT5659_SPK_AG_DIS (0x0 << 14)
1486#define RT5659_SPK_AG_EN (0x1 << 14)
1487
1488/* Micbias Control (0x93) */
1489#define RT5659_MIC1_BS_MASK (0x1 << 15)
1490#define RT5659_MIC1_BS_SFT 15
1491#define RT5659_MIC1_BS_9AV (0x0 << 15)
1492#define RT5659_MIC1_BS_75AV (0x1 << 15)
1493#define RT5659_MIC2_BS_MASK (0x1 << 14)
1494#define RT5659_MIC2_BS_SFT 14
1495#define RT5659_MIC2_BS_9AV (0x0 << 14)
1496#define RT5659_MIC2_BS_75AV (0x1 << 14)
1497#define RT5659_MIC1_CLK_MASK (0x1 << 13)
1498#define RT5659_MIC1_CLK_SFT 13
1499#define RT5659_MIC1_CLK_DIS (0x0 << 13)
1500#define RT5659_MIC1_CLK_EN (0x1 << 13)
1501#define RT5659_MIC2_CLK_MASK (0x1 << 12)
1502#define RT5659_MIC2_CLK_SFT 12
1503#define RT5659_MIC2_CLK_DIS (0x0 << 12)
1504#define RT5659_MIC2_CLK_EN (0x1 << 12)
1505#define RT5659_MIC1_OVCD_MASK (0x1 << 11)
1506#define RT5659_MIC1_OVCD_SFT 11
1507#define RT5659_MIC1_OVCD_DIS (0x0 << 11)
1508#define RT5659_MIC1_OVCD_EN (0x1 << 11)
1509#define RT5659_MIC1_OVTH_MASK (0x3 << 9)
1510#define RT5659_MIC1_OVTH_SFT 9
1511#define RT5659_MIC1_OVTH_600UA (0x0 << 9)
1512#define RT5659_MIC1_OVTH_1500UA (0x1 << 9)
1513#define RT5659_MIC1_OVTH_2000UA (0x2 << 9)
1514#define RT5659_MIC2_OVCD_MASK (0x1 << 8)
1515#define RT5659_MIC2_OVCD_SFT 8
1516#define RT5659_MIC2_OVCD_DIS (0x0 << 8)
1517#define RT5659_MIC2_OVCD_EN (0x1 << 8)
1518#define RT5659_MIC2_OVTH_MASK (0x3 << 6)
1519#define RT5659_MIC2_OVTH_SFT 6
1520#define RT5659_MIC2_OVTH_600UA (0x0 << 6)
1521#define RT5659_MIC2_OVTH_1500UA (0x1 << 6)
1522#define RT5659_MIC2_OVTH_2000UA (0x2 << 6)
1523#define RT5659_PWR_MB_MASK (0x1 << 5)
1524#define RT5659_PWR_MB_SFT 5
1525#define RT5659_PWR_MB_PD (0x0 << 5)
1526#define RT5659_PWR_MB_PU (0x1 << 5)
1527#define RT5659_PWR_CLK25M_MASK (0x1 << 4)
1528#define RT5659_PWR_CLK25M_SFT 4
1529#define RT5659_PWR_CLK25M_PD (0x0 << 4)
1530#define RT5659_PWR_CLK25M_PU (0x1 << 4)
1531
1532/* REC Mixer 2 Left Control 2 (0x009c) */
1533#define RT5659_M_BST1_RM2_L (0x1 << 5)
1534#define RT5659_M_BST1_RM2_L_SFT 5
1535#define RT5659_M_BST2_RM2_L (0x1 << 4)
1536#define RT5659_M_BST2_RM2_L_SFT 4
1537#define RT5659_M_BST3_RM2_L (0x1 << 3)
1538#define RT5659_M_BST3_RM2_L_SFT 3
1539#define RT5659_M_BST4_RM2_L (0x1 << 2)
1540#define RT5659_M_BST4_RM2_L_SFT 2
1541#define RT5659_M_OUTVOLL_RM2_L (0x1 << 1)
1542#define RT5659_M_OUTVOLL_RM2_L_SFT 1
1543#define RT5659_M_SPKVOL_RM2_L (0x1)
1544#define RT5659_M_SPKVOL_RM2_L_SFT 0
1545
1546/* REC Mixer 2 Right Control 2 (0x009e) */
1547#define RT5659_M_BST1_RM2_R (0x1 << 5)
1548#define RT5659_M_BST1_RM2_R_SFT 5
1549#define RT5659_M_BST2_RM2_R (0x1 << 4)
1550#define RT5659_M_BST2_RM2_R_SFT 4
1551#define RT5659_M_BST3_RM2_R (0x1 << 3)
1552#define RT5659_M_BST3_RM2_R_SFT 3
1553#define RT5659_M_BST4_RM2_R (0x1 << 2)
1554#define RT5659_M_BST4_RM2_R_SFT 2
1555#define RT5659_M_OUTVOLR_RM2_R (0x1 << 1)
1556#define RT5659_M_OUTVOLR_RM2_R_SFT 1
1557#define RT5659_M_MONOVOL_RM2_R (0x1)
1558#define RT5659_M_MONOVOL_RM2_R_SFT 0
1559
1560/* Class D Output Control (0x00a0) */
1561#define RT5659_POW_CLSD_DB_MASK (0x1 << 9)
1562#define RT5659_POW_CLSD_DB_EN (0x1 << 9)
1563#define RT5659_POW_CLSD_DB_DIS (0x0 << 9)
1564
1565/* EQ Control 1 (0x00b0) */
1566#define RT5659_EQ_SRC_DAC (0x0 << 15)
1567#define RT5659_EQ_SRC_ADC (0x1 << 15)
1568#define RT5659_EQ_UPD (0x1 << 14)
1569#define RT5659_EQ_UPD_BIT 14
1570#define RT5659_EQ_CD_MASK (0x1 << 13)
1571#define RT5659_EQ_CD_SFT 13
1572#define RT5659_EQ_CD_DIS (0x0 << 13)
1573#define RT5659_EQ_CD_EN (0x1 << 13)
1574#define RT5659_EQ_DITH_MASK (0x3 << 8)
1575#define RT5659_EQ_DITH_SFT 8
1576#define RT5659_EQ_DITH_NOR (0x0 << 8)
1577#define RT5659_EQ_DITH_LSB (0x1 << 8)
1578#define RT5659_EQ_DITH_LSB_1 (0x2 << 8)
1579#define RT5659_EQ_DITH_LSB_2 (0x3 << 8)
1580
1581/* IRQ Control 1 (0x00b7) */
1582#define RT5659_JD1_1_EN_MASK (0x1 << 15)
1583#define RT5659_JD1_1_EN_SFT 15
1584#define RT5659_JD1_1_DIS (0x0 << 15)
1585#define RT5659_JD1_1_EN (0x1 << 15)
1586#define RT5659_JD1_2_EN_MASK (0x1 << 12)
1587#define RT5659_JD1_2_EN_SFT 12
1588#define RT5659_JD1_2_DIS (0x0 << 12)
1589#define RT5659_JD1_2_EN (0x1 << 12)
1590#define RT5659_IL_IRQ_MASK (0x1 << 3)
1591#define RT5659_IL_IRQ_DIS (0x0 << 3)
1592#define RT5659_IL_IRQ_EN (0x1 << 3)
1593
1594/* IRQ Control 5 (0x00ba) */
1595#define RT5659_IRQ_JD_EN (0x1 << 3)
1596#define RT5659_IRQ_JD_EN_SFT 3
1597
1598/* GPIO Control 1 (0x00c0) */
1599#define RT5659_GP1_PIN_MASK (0x1 << 15)
1600#define RT5659_GP1_PIN_SFT 15
1601#define RT5659_GP1_PIN_GPIO1 (0x0 << 15)
1602#define RT5659_GP1_PIN_IRQ (0x1 << 15)
1603#define RT5659_GP2_PIN_MASK (0x1 << 14)
1604#define RT5659_GP2_PIN_SFT 14
1605#define RT5659_GP2_PIN_GPIO2 (0x0 << 14)
1606#define RT5659_GP2_PIN_DMIC1_SCL (0x1 << 14)
1607#define RT5659_GP3_PIN_MASK (0x1 << 13)
1608#define RT5659_GP3_PIN_SFT 13
1609#define RT5659_GP3_PIN_GPIO3 (0x0 << 13)
1610#define RT5659_GP3_PIN_PDM_SCL (0x1 << 13)
1611#define RT5659_GP4_PIN_MASK (0x1 << 12)
1612#define RT5659_GP4_PIN_SFT 12
1613#define RT5659_GP4_PIN_GPIO4 (0x0 << 12)
1614#define RT5659_GP4_PIN_PDM_SDA (0x1 << 12)
1615#define RT5659_GP5_PIN_MASK (0x1 << 11)
1616#define RT5659_GP5_PIN_SFT 11
1617#define RT5659_GP5_PIN_GPIO5 (0x0 << 11)
1618#define RT5659_GP5_PIN_DMIC1_SDA (0x1 << 11)
1619#define RT5659_GP6_PIN_MASK (0x1 << 10)
1620#define RT5659_GP6_PIN_SFT 10
1621#define RT5659_GP6_PIN_GPIO6 (0x0 << 10)
1622#define RT5659_GP6_PIN_DMIC2_SDA (0x1 << 10)
1623#define RT5659_GP7_PIN_MASK (0x1 << 9)
1624#define RT5659_GP7_PIN_SFT 9
1625#define RT5659_GP7_PIN_GPIO7 (0x0 << 9)
1626#define RT5659_GP7_PIN_PDM_SCL (0x1 << 9)
1627#define RT5659_GP8_PIN_MASK (0x1 << 8)
1628#define RT5659_GP8_PIN_SFT 8
1629#define RT5659_GP8_PIN_GPIO8 (0x0 << 8)
1630#define RT5659_GP8_PIN_PDM_SDA (0x1 << 8)
1631#define RT5659_GP9_PIN_MASK (0x1 << 7)
1632#define RT5659_GP9_PIN_SFT 7
1633#define RT5659_GP9_PIN_GPIO9 (0x0 << 7)
1634#define RT5659_GP9_PIN_DMIC1_SDA (0x1 << 7)
1635#define RT5659_GP10_PIN_MASK (0x1 << 6)
1636#define RT5659_GP10_PIN_SFT 6
1637#define RT5659_GP10_PIN_GPIO10 (0x0 << 6)
1638#define RT5659_GP10_PIN_DMIC2_SDA (0x1 << 6)
1639#define RT5659_GP11_PIN_MASK (0x1 << 5)
1640#define RT5659_GP11_PIN_SFT 5
1641#define RT5659_GP11_PIN_GPIO11 (0x0 << 5)
1642#define RT5659_GP11_PIN_DMIC1_SDA (0x1 << 5)
1643#define RT5659_GP12_PIN_MASK (0x1 << 4)
1644#define RT5659_GP12_PIN_SFT 4
1645#define RT5659_GP12_PIN_GPIO12 (0x0 << 4)
1646#define RT5659_GP12_PIN_DMIC2_SDA (0x1 << 4)
1647#define RT5659_GP13_PIN_MASK (0x3 << 2)
1648#define RT5659_GP13_PIN_SFT 2
1649#define RT5659_GP13_PIN_GPIO13 (0x0 << 2)
1650#define RT5659_GP13_PIN_SPDIF_SDA (0x1 << 2)
1651#define RT5659_GP13_PIN_DMIC2_SCL (0x2 << 2)
1652#define RT5659_GP13_PIN_PDM_SCL (0x3 << 2)
1653#define RT5659_GP15_PIN_MASK (0x3)
1654#define RT5659_GP15_PIN_SFT 0
1655#define RT5659_GP15_PIN_GPIO15 (0x0)
1656#define RT5659_GP15_PIN_DMIC3_SCL (0x1)
1657#define RT5659_GP15_PIN_PDM_SDA (0x2)
1658
1659/* GPIO Control 2 (0x00c1)*/
1660#define RT5659_GP1_PF_IN (0x0 << 2)
1661#define RT5659_GP1_PF_OUT (0x1 << 2)
1662#define RT5659_GP1_PF_MASK (0x1 << 2)
1663#define RT5659_GP1_PF_SFT 2
1664
1665/* GPIO Control 3 (0x00c2) */
1666#define RT5659_I2S2_PIN_MASK (0x1 << 15)
1667#define RT5659_I2S2_PIN_SFT 15
1668#define RT5659_I2S2_PIN_I2S (0x0 << 15)
1669#define RT5659_I2S2_PIN_GPIO (0x1 << 15)
1670
1671/* Soft volume and zero cross control 1 (0x00d9) */
1672#define RT5659_SV_MASK (0x1 << 15)
1673#define RT5659_SV_SFT 15
1674#define RT5659_SV_DIS (0x0 << 15)
1675#define RT5659_SV_EN (0x1 << 15)
1676#define RT5659_OUT_SV_MASK (0x1 << 13)
1677#define RT5659_OUT_SV_SFT 13
1678#define RT5659_OUT_SV_DIS (0x0 << 13)
1679#define RT5659_OUT_SV_EN (0x1 << 13)
1680#define RT5659_HP_SV_MASK (0x1 << 12)
1681#define RT5659_HP_SV_SFT 12
1682#define RT5659_HP_SV_DIS (0x0 << 12)
1683#define RT5659_HP_SV_EN (0x1 << 12)
1684#define RT5659_ZCD_DIG_MASK (0x1 << 11)
1685#define RT5659_ZCD_DIG_SFT 11
1686#define RT5659_ZCD_DIG_DIS (0x0 << 11)
1687#define RT5659_ZCD_DIG_EN (0x1 << 11)
1688#define RT5659_ZCD_MASK (0x1 << 10)
1689#define RT5659_ZCD_SFT 10
1690#define RT5659_ZCD_PD (0x0 << 10)
1691#define RT5659_ZCD_PU (0x1 << 10)
1692#define RT5659_SV_DLY_MASK (0xf)
1693#define RT5659_SV_DLY_SFT 0
1694
1695/* Soft volume and zero cross control 2 (0x00da) */
1696#define RT5659_ZCD_HP_MASK (0x1 << 15)
1697#define RT5659_ZCD_HP_SFT 15
1698#define RT5659_ZCD_HP_DIS (0x0 << 15)
1699#define RT5659_ZCD_HP_EN (0x1 << 15)
1700
1701/* 4 Button Inline Command Control 2 (0x00e0) */
1702#define RT5659_4BTN_IL_MASK (0x1 << 15)
1703#define RT5659_4BTN_IL_EN (0x1 << 15)
1704#define RT5659_4BTN_IL_DIS (0x0 << 15)
1705
1706/* Analog JD Control 1 (0x00f0) */
1707#define RT5659_JD1_MODE_MASK (0x3 << 0)
1708#define RT5659_JD1_MODE_0 (0x0 << 0)
1709#define RT5659_JD1_MODE_1 (0x1 << 0)
1710#define RT5659_JD1_MODE_2 (0x2 << 0)
1711
1712/* Jack Detect Control 3 (0x00f8) */
1713#define RT5659_JD_TRI_HPO_SEL_MASK (0x7)
1714#define RT5659_JD_TRI_HPO_SEL_SFT (0)
1715#define RT5659_JD_HPO_GPIO_JD1 (0x0)
1716#define RT5659_JD_HPO_JD1_1 (0x1)
1717#define RT5659_JD_HPO_JD1_2 (0x2)
1718#define RT5659_JD_HPO_JD2 (0x3)
1719#define RT5659_JD_HPO_GPIO_JD2 (0x4)
1720#define RT5659_JD_HPO_JD3 (0x5)
1721#define RT5659_JD_HPO_JD_D (0x6)
1722
1723/* Digital Misc Control (0x00fa) */
1724#define RT5659_AM_MASK (0x1 << 7)
1725#define RT5659_AM_EN (0x1 << 7)
1726#define RT5659_AM_DIS (0x1 << 7)
1727#define RT5659_DIG_GATE_CTRL 0x1
1728#define RT5659_DIG_GATE_CTRL_SFT (0)
1729
1730/* Chopper and Clock control for ADC (0x011c)*/
1731#define RT5659_M_RF_DIG_MASK (0x1 << 12)
1732#define RT5659_M_RF_DIG_SFT 12
1733#define RT5659_M_RI_DIG (0x1 << 11)
1734
1735/* Chopper and Clock control for DAC (0x013a)*/
1736#define RT5659_CKXEN_DAC1_MASK (0x1 << 13)
1737#define RT5659_CKXEN_DAC1_SFT 13
1738#define RT5659_CKGEN_DAC1_MASK (0x1 << 12)
1739#define RT5659_CKGEN_DAC1_SFT 12
1740#define RT5659_CKXEN_DAC2_MASK (0x1 << 5)
1741#define RT5659_CKXEN_DAC2_SFT 5
1742#define RT5659_CKGEN_DAC2_MASK (0x1 << 4)
1743#define RT5659_CKGEN_DAC2_SFT 4
1744
1745/* Chopper and Clock control for ADC (0x013b)*/
1746#define RT5659_CKXEN_ADCC_MASK (0x1 << 13)
1747#define RT5659_CKXEN_ADCC_SFT 13
1748#define RT5659_CKGEN_ADCC_MASK (0x1 << 12)
1749#define RT5659_CKGEN_ADCC_SFT 12
1750
1751/* Test Mode Control 1 (0x0145) */
1752#define RT5659_AD2DA_LB_MASK (0x1 << 9)
1753#define RT5659_AD2DA_LB_SFT 9
1754
1755/* Stereo Noise Gate Control 1 (0x0160) */
1756#define RT5659_NG2_EN_MASK (0x1 << 15)
1757#define RT5659_NG2_EN (0x1 << 15)
1758#define RT5659_NG2_DIS (0x0 << 15)
1759
1760/* System Clock Source */
1761enum {
1762 RT5659_SCLK_S_MCLK,
1763 RT5659_SCLK_S_PLL1,
1764 RT5659_SCLK_S_RCCLK,
1765};
1766
1767/* PLL1 Source */
1768enum {
1769 RT5659_PLL1_S_MCLK,
1770 RT5659_PLL1_S_BCLK1,
1771 RT5659_PLL1_S_BCLK2,
1772 RT5659_PLL1_S_BCLK3,
1773 RT5659_PLL1_S_BCLK4,
1774};
1775
1776enum {
1777 RT5659_AIF1,
1778 RT5659_AIF2,
1779 RT5659_AIF3,
1780 RT5659_AIF4,
1781 RT5659_AIFS,
1782};
1783
1784struct rt5659_pll_code {
1785 bool m_bp;
1786 int m_code;
1787 int n_code;
1788 int k_code;
1789};
1790
1791struct rt5659_priv {
1792 struct snd_soc_codec *codec;
1793 struct rt5659_platform_data pdata;
1794 struct regmap *regmap;
1795 struct i2c_client *i2c;
1796 struct gpio_desc *gpiod_ldo1_en;
1797 struct gpio_desc *gpiod_reset;
1798 struct snd_soc_jack *hs_jack;
1799 struct delayed_work jack_detect_work;
1800
1801 int sysclk;
1802 int sysclk_src;
1803 int lrck[RT5659_AIFS];
1804 int bclk[RT5659_AIFS];
1805 int master[RT5659_AIFS];
1806 int v_id;
1807
1808 int pll_src;
1809 int pll_in;
1810 int pll_out;
1811
1812 int jack_type;
1813
1814};
1815
1816int rt5659_set_jack_detect(struct snd_soc_codec *codec,
1817 struct snd_soc_jack *hs_jack);
1818
1819#endif /* __RT5659_H__ */
diff --git a/sound/soc/codecs/rt5677.c b/sound/soc/codecs/rt5677.c
index 69d987a9935c..967678e7f48e 100644
--- a/sound/soc/codecs/rt5677.c
+++ b/sound/soc/codecs/rt5677.c
@@ -297,8 +297,6 @@ static bool rt5677_volatile_register(struct device *dev, unsigned int reg)
297 case RT5677_HAP_GENE_CTRL2: 297 case RT5677_HAP_GENE_CTRL2:
298 case RT5677_PWR_DSP_ST: 298 case RT5677_PWR_DSP_ST:
299 case RT5677_PRIV_DATA: 299 case RT5677_PRIV_DATA:
300 case RT5677_PLL1_CTRL2:
301 case RT5677_PLL2_CTRL2:
302 case RT5677_ASRC_22: 300 case RT5677_ASRC_22:
303 case RT5677_ASRC_23: 301 case RT5677_ASRC_23:
304 case RT5677_VAD_CTRL5: 302 case RT5677_VAD_CTRL5:
@@ -4788,7 +4786,7 @@ static int rt5677_remove(struct snd_soc_codec *codec)
4788 4786
4789 regmap_write(rt5677->regmap, RT5677_RESET, 0x10ec); 4787 regmap_write(rt5677->regmap, RT5677_RESET, 0x10ec);
4790 gpiod_set_value_cansleep(rt5677->pow_ldo2, 0); 4788 gpiod_set_value_cansleep(rt5677->pow_ldo2, 0);
4791 gpiod_set_value_cansleep(rt5677->reset_pin, 0); 4789 gpiod_set_value_cansleep(rt5677->reset_pin, 1);
4792 4790
4793 return 0; 4791 return 0;
4794} 4792}
@@ -4803,7 +4801,7 @@ static int rt5677_suspend(struct snd_soc_codec *codec)
4803 regcache_mark_dirty(rt5677->regmap); 4801 regcache_mark_dirty(rt5677->regmap);
4804 4802
4805 gpiod_set_value_cansleep(rt5677->pow_ldo2, 0); 4803 gpiod_set_value_cansleep(rt5677->pow_ldo2, 0);
4806 gpiod_set_value_cansleep(rt5677->reset_pin, 0); 4804 gpiod_set_value_cansleep(rt5677->reset_pin, 1);
4807 } 4805 }
4808 4806
4809 return 0; 4807 return 0;
@@ -4814,8 +4812,11 @@ static int rt5677_resume(struct snd_soc_codec *codec)
4814 struct rt5677_priv *rt5677 = snd_soc_codec_get_drvdata(codec); 4812 struct rt5677_priv *rt5677 = snd_soc_codec_get_drvdata(codec);
4815 4813
4816 if (!rt5677->dsp_vad_en) { 4814 if (!rt5677->dsp_vad_en) {
4815 rt5677->pll_src = 0;
4816 rt5677->pll_in = 0;
4817 rt5677->pll_out = 0;
4817 gpiod_set_value_cansleep(rt5677->pow_ldo2, 1); 4818 gpiod_set_value_cansleep(rt5677->pow_ldo2, 1);
4818 gpiod_set_value_cansleep(rt5677->reset_pin, 1); 4819 gpiod_set_value_cansleep(rt5677->reset_pin, 0);
4819 if (rt5677->pow_ldo2 || rt5677->reset_pin) 4820 if (rt5677->pow_ldo2 || rt5677->reset_pin)
4820 msleep(10); 4821 msleep(10);
4821 4822
@@ -5160,7 +5161,7 @@ static int rt5677_i2c_probe(struct i2c_client *i2c,
5160 return ret; 5161 return ret;
5161 } 5162 }
5162 rt5677->reset_pin = devm_gpiod_get_optional(&i2c->dev, 5163 rt5677->reset_pin = devm_gpiod_get_optional(&i2c->dev,
5163 "realtek,reset", GPIOD_OUT_HIGH); 5164 "realtek,reset", GPIOD_OUT_LOW);
5164 if (IS_ERR(rt5677->reset_pin)) { 5165 if (IS_ERR(rt5677->reset_pin)) {
5165 ret = PTR_ERR(rt5677->reset_pin); 5166 ret = PTR_ERR(rt5677->reset_pin);
5166 dev_err(&i2c->dev, "Failed to request RESET: %d\n", ret); 5167 dev_err(&i2c->dev, "Failed to request RESET: %d\n", ret);
diff --git a/sound/soc/codecs/ssm2518.c b/sound/soc/codecs/ssm2518.c
index 86b81a60ac52..e2e0bfa7ec20 100644
--- a/sound/soc/codecs/ssm2518.c
+++ b/sound/soc/codecs/ssm2518.c
@@ -309,7 +309,7 @@ static const struct snd_pcm_hw_constraint_list ssm2518_constraints_12288000 = {
309 .count = ARRAY_SIZE(ssm2518_rates_12288000), 309 .count = ARRAY_SIZE(ssm2518_rates_12288000),
310}; 310};
311 311
312static unsigned int ssm2518_lookup_mcs(struct ssm2518 *ssm2518, 312static int ssm2518_lookup_mcs(struct ssm2518 *ssm2518,
313 unsigned int rate) 313 unsigned int rate)
314{ 314{
315 const unsigned int *sysclks = NULL; 315 const unsigned int *sysclks = NULL;
diff --git a/sound/soc/codecs/twl6040.c b/sound/soc/codecs/twl6040.c
index 4cad8929d262..bc3de2e844e6 100644
--- a/sound/soc/codecs/twl6040.c
+++ b/sound/soc/codecs/twl6040.c
@@ -1097,8 +1097,7 @@ static int twl6040_probe(struct snd_soc_codec *codec)
1097{ 1097{
1098 struct twl6040_data *priv; 1098 struct twl6040_data *priv;
1099 struct twl6040 *twl6040 = dev_get_drvdata(codec->dev->parent); 1099 struct twl6040 *twl6040 = dev_get_drvdata(codec->dev->parent);
1100 struct platform_device *pdev = container_of(codec->dev, 1100 struct platform_device *pdev = to_platform_device(codec->dev);
1101 struct platform_device, dev);
1102 int ret = 0; 1101 int ret = 0;
1103 1102
1104 priv = devm_kzalloc(codec->dev, sizeof(*priv), GFP_KERNEL); 1103 priv = devm_kzalloc(codec->dev, sizeof(*priv), GFP_KERNEL);
diff --git a/sound/soc/codecs/wm5110.c b/sound/soc/codecs/wm5110.c
index c04c0bc6f58a..6088d30962a9 100644
--- a/sound/soc/codecs/wm5110.c
+++ b/sound/soc/codecs/wm5110.c
@@ -360,15 +360,13 @@ static int wm5110_hp_ev(struct snd_soc_dapm_widget *w,
360 360
361static int wm5110_clear_pga_volume(struct arizona *arizona, int output) 361static int wm5110_clear_pga_volume(struct arizona *arizona, int output)
362{ 362{
363 struct reg_sequence clear_pga = { 363 unsigned int reg = ARIZONA_OUTPUT_PATH_CONFIG_1L + output * 4;
364 ARIZONA_OUTPUT_PATH_CONFIG_1L + output * 4, 0x80
365 };
366 int ret; 364 int ret;
367 365
368 ret = regmap_multi_reg_write_bypassed(arizona->regmap, &clear_pga, 1); 366 ret = regmap_write(arizona->regmap, reg, 0x80);
369 if (ret) 367 if (ret)
370 dev_err(arizona->dev, "Failed to clear PGA (0x%x): %d\n", 368 dev_err(arizona->dev, "Failed to clear PGA (0x%x): %d\n",
371 clear_pga.reg, ret); 369 reg, ret);
372 370
373 return ret; 371 return ret;
374} 372}
@@ -439,18 +437,17 @@ static int wm5110_in_pga_get(struct snd_kcontrol *kcontrol,
439{ 437{
440 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); 438 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
441 struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec); 439 struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
442 struct snd_soc_card *card = dapm->card;
443 int ret; 440 int ret;
444 441
445 /* 442 /*
446 * PGA Volume is also used as part of the enable sequence, so 443 * PGA Volume is also used as part of the enable sequence, so
447 * usage of it should be avoided whilst that is running. 444 * usage of it should be avoided whilst that is running.
448 */ 445 */
449 mutex_lock_nested(&card->dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME); 446 snd_soc_dapm_mutex_lock(dapm);
450 447
451 ret = snd_soc_get_volsw_range(kcontrol, ucontrol); 448 ret = snd_soc_get_volsw_range(kcontrol, ucontrol);
452 449
453 mutex_unlock(&card->dapm_mutex); 450 snd_soc_dapm_mutex_unlock(dapm);
454 451
455 return ret; 452 return ret;
456} 453}
@@ -460,18 +457,17 @@ static int wm5110_in_pga_put(struct snd_kcontrol *kcontrol,
460{ 457{
461 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); 458 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
462 struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec); 459 struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
463 struct snd_soc_card *card = dapm->card;
464 int ret; 460 int ret;
465 461
466 /* 462 /*
467 * PGA Volume is also used as part of the enable sequence, so 463 * PGA Volume is also used as part of the enable sequence, so
468 * usage of it should be avoided whilst that is running. 464 * usage of it should be avoided whilst that is running.
469 */ 465 */
470 mutex_lock_nested(&card->dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME); 466 snd_soc_dapm_mutex_lock(dapm);
471 467
472 ret = snd_soc_put_volsw_range(kcontrol, ucontrol); 468 ret = snd_soc_put_volsw_range(kcontrol, ucontrol);
473 469
474 mutex_unlock(&card->dapm_mutex); 470 snd_soc_dapm_mutex_unlock(dapm);
475 471
476 return ret; 472 return ret;
477} 473}
@@ -575,6 +571,33 @@ static DECLARE_TLV_DB_SCALE(ng_tlv, -10200, 600, 0);
575 SOC_SINGLE(name " NG SPKDAT2L Switch", base, 10, 1, 0), \ 571 SOC_SINGLE(name " NG SPKDAT2L Switch", base, 10, 1, 0), \
576 SOC_SINGLE(name " NG SPKDAT2R Switch", base, 11, 1, 0) 572 SOC_SINGLE(name " NG SPKDAT2R Switch", base, 11, 1, 0)
577 573
574#define WM5110_RXANC_INPUT_ROUTES(widget, name) \
575 { widget, NULL, name " NG Mux" }, \
576 { name " NG Internal", NULL, "RXANC NG Clock" }, \
577 { name " NG Internal", NULL, name " Channel" }, \
578 { name " NG External", NULL, "RXANC NG External Clock" }, \
579 { name " NG External", NULL, name " Channel" }, \
580 { name " NG Mux", "None", name " Channel" }, \
581 { name " NG Mux", "Internal", name " NG Internal" }, \
582 { name " NG Mux", "External", name " NG External" }, \
583 { name " Channel", "Left", name " Left Input" }, \
584 { name " Channel", "Combine", name " Left Input" }, \
585 { name " Channel", "Right", name " Right Input" }, \
586 { name " Channel", "Combine", name " Right Input" }, \
587 { name " Left Input", "IN1", "IN1L PGA" }, \
588 { name " Right Input", "IN1", "IN1R PGA" }, \
589 { name " Left Input", "IN2", "IN2L PGA" }, \
590 { name " Right Input", "IN2", "IN2R PGA" }, \
591 { name " Left Input", "IN3", "IN3L PGA" }, \
592 { name " Right Input", "IN3", "IN3R PGA" }, \
593 { name " Left Input", "IN4", "IN4L PGA" }, \
594 { name " Right Input", "IN4", "IN4R PGA" }
595
596#define WM5110_RXANC_OUTPUT_ROUTES(widget, name) \
597 { widget, NULL, name " ANC Source" }, \
598 { name " ANC Source", "RXANCL", "RXANCL" }, \
599 { name " ANC Source", "RXANCR", "RXANCR" }
600
578static const struct snd_kcontrol_new wm5110_snd_controls[] = { 601static const struct snd_kcontrol_new wm5110_snd_controls[] = {
579SOC_ENUM("IN1 OSR", arizona_in_dmic_osr[0]), 602SOC_ENUM("IN1 OSR", arizona_in_dmic_osr[0]),
580SOC_ENUM("IN2 OSR", arizona_in_dmic_osr[1]), 603SOC_ENUM("IN2 OSR", arizona_in_dmic_osr[1]),
@@ -639,6 +662,15 @@ SOC_SINGLE_TLV("IN4R Digital Volume", ARIZONA_ADC_DIGITAL_VOLUME_4R,
639SOC_ENUM("Input Ramp Up", arizona_in_vi_ramp), 662SOC_ENUM("Input Ramp Up", arizona_in_vi_ramp),
640SOC_ENUM("Input Ramp Down", arizona_in_vd_ramp), 663SOC_ENUM("Input Ramp Down", arizona_in_vd_ramp),
641 664
665SND_SOC_BYTES("RXANC Coefficients", ARIZONA_ANC_COEFF_START,
666 ARIZONA_ANC_COEFF_END - ARIZONA_ANC_COEFF_START + 1),
667SND_SOC_BYTES("RXANCL Config", ARIZONA_FCL_FILTER_CONTROL, 1),
668SND_SOC_BYTES("RXANCL Coefficients", ARIZONA_FCL_COEFF_START,
669 ARIZONA_FCL_COEFF_END - ARIZONA_FCL_COEFF_START + 1),
670SND_SOC_BYTES("RXANCR Config", ARIZONA_FCR_FILTER_CONTROL, 1),
671SND_SOC_BYTES("RXANCR Coefficients", ARIZONA_FCR_COEFF_START,
672 ARIZONA_FCR_COEFF_END - ARIZONA_FCR_COEFF_START + 1),
673
642ARIZONA_MIXER_CONTROLS("EQ1", ARIZONA_EQ1MIX_INPUT_1_SOURCE), 674ARIZONA_MIXER_CONTROLS("EQ1", ARIZONA_EQ1MIX_INPUT_1_SOURCE),
643ARIZONA_MIXER_CONTROLS("EQ2", ARIZONA_EQ2MIX_INPUT_1_SOURCE), 675ARIZONA_MIXER_CONTROLS("EQ2", ARIZONA_EQ2MIX_INPUT_1_SOURCE),
644ARIZONA_MIXER_CONTROLS("EQ3", ARIZONA_EQ3MIX_INPUT_1_SOURCE), 676ARIZONA_MIXER_CONTROLS("EQ3", ARIZONA_EQ3MIX_INPUT_1_SOURCE),
@@ -995,6 +1027,31 @@ static const struct soc_enum wm5110_aec_loopback =
995static const struct snd_kcontrol_new wm5110_aec_loopback_mux = 1027static const struct snd_kcontrol_new wm5110_aec_loopback_mux =
996 SOC_DAPM_ENUM("AEC Loopback", wm5110_aec_loopback); 1028 SOC_DAPM_ENUM("AEC Loopback", wm5110_aec_loopback);
997 1029
1030static const struct snd_kcontrol_new wm5110_anc_input_mux[] = {
1031 SOC_DAPM_ENUM("RXANCL Input", arizona_anc_input_src[0]),
1032 SOC_DAPM_ENUM("RXANCL Channel", arizona_anc_input_src[1]),
1033 SOC_DAPM_ENUM("RXANCR Input", arizona_anc_input_src[2]),
1034 SOC_DAPM_ENUM("RXANCR Channel", arizona_anc_input_src[3]),
1035};
1036
1037static const struct snd_kcontrol_new wm5110_anc_ng_mux =
1038 SOC_DAPM_ENUM("RXANC NG Source", arizona_anc_ng_enum);
1039
1040static const struct snd_kcontrol_new wm5110_output_anc_src[] = {
1041 SOC_DAPM_ENUM("HPOUT1L ANC Source", arizona_output_anc_src[0]),
1042 SOC_DAPM_ENUM("HPOUT1R ANC Source", arizona_output_anc_src[1]),
1043 SOC_DAPM_ENUM("HPOUT2L ANC Source", arizona_output_anc_src[2]),
1044 SOC_DAPM_ENUM("HPOUT2R ANC Source", arizona_output_anc_src[3]),
1045 SOC_DAPM_ENUM("HPOUT3L ANC Source", arizona_output_anc_src[4]),
1046 SOC_DAPM_ENUM("HPOUT3R ANC Source", arizona_output_anc_src[5]),
1047 SOC_DAPM_ENUM("SPKOUTL ANC Source", arizona_output_anc_src[6]),
1048 SOC_DAPM_ENUM("SPKOUTR ANC Source", arizona_output_anc_src[7]),
1049 SOC_DAPM_ENUM("SPKDAT1L ANC Source", arizona_output_anc_src[8]),
1050 SOC_DAPM_ENUM("SPKDAT1R ANC Source", arizona_output_anc_src[9]),
1051 SOC_DAPM_ENUM("SPKDAT2L ANC Source", arizona_output_anc_src[10]),
1052 SOC_DAPM_ENUM("SPKDAT2R ANC Source", arizona_output_anc_src[11]),
1053};
1054
998static const struct snd_soc_dapm_widget wm5110_dapm_widgets[] = { 1055static const struct snd_soc_dapm_widget wm5110_dapm_widgets[] = {
999SND_SOC_DAPM_SUPPLY("SYSCLK", ARIZONA_SYSTEM_CLOCK_1, ARIZONA_SYSCLK_ENA_SHIFT, 1056SND_SOC_DAPM_SUPPLY("SYSCLK", ARIZONA_SYSTEM_CLOCK_1, ARIZONA_SYSCLK_ENA_SHIFT,
1000 0, wm5110_sysclk_ev, SND_SOC_DAPM_POST_PMU), 1057 0, wm5110_sysclk_ev, SND_SOC_DAPM_POST_PMU),
@@ -1185,6 +1242,65 @@ SND_SOC_DAPM_MUX("AEC Loopback", ARIZONA_DAC_AEC_CONTROL_1,
1185 ARIZONA_AEC_LOOPBACK_ENA_SHIFT, 0, 1242 ARIZONA_AEC_LOOPBACK_ENA_SHIFT, 0,
1186 &wm5110_aec_loopback_mux), 1243 &wm5110_aec_loopback_mux),
1187 1244
1245SND_SOC_DAPM_SUPPLY("RXANC NG External Clock", SND_SOC_NOPM,
1246 ARIZONA_EXT_NG_SEL_SET_SHIFT, 0, arizona_anc_ev,
1247 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
1248SND_SOC_DAPM_PGA("RXANCL NG External", SND_SOC_NOPM, 0, 0, NULL, 0),
1249SND_SOC_DAPM_PGA("RXANCR NG External", SND_SOC_NOPM, 0, 0, NULL, 0),
1250
1251SND_SOC_DAPM_SUPPLY("RXANC NG Clock", SND_SOC_NOPM,
1252 ARIZONA_CLK_NG_ENA_SET_SHIFT, 0, arizona_anc_ev,
1253 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
1254SND_SOC_DAPM_PGA("RXANCL NG Internal", SND_SOC_NOPM, 0, 0, NULL, 0),
1255SND_SOC_DAPM_PGA("RXANCR NG Internal", SND_SOC_NOPM, 0, 0, NULL, 0),
1256
1257SND_SOC_DAPM_MUX("RXANCL Left Input", SND_SOC_NOPM, 0, 0,
1258 &wm5110_anc_input_mux[0]),
1259SND_SOC_DAPM_MUX("RXANCL Right Input", SND_SOC_NOPM, 0, 0,
1260 &wm5110_anc_input_mux[0]),
1261SND_SOC_DAPM_MUX("RXANCL Channel", SND_SOC_NOPM, 0, 0,
1262 &wm5110_anc_input_mux[1]),
1263SND_SOC_DAPM_MUX("RXANCL NG Mux", SND_SOC_NOPM, 0, 0, &wm5110_anc_ng_mux),
1264SND_SOC_DAPM_MUX("RXANCR Left Input", SND_SOC_NOPM, 0, 0,
1265 &wm5110_anc_input_mux[2]),
1266SND_SOC_DAPM_MUX("RXANCR Right Input", SND_SOC_NOPM, 0, 0,
1267 &wm5110_anc_input_mux[2]),
1268SND_SOC_DAPM_MUX("RXANCR Channel", SND_SOC_NOPM, 0, 0,
1269 &wm5110_anc_input_mux[3]),
1270SND_SOC_DAPM_MUX("RXANCR NG Mux", SND_SOC_NOPM, 0, 0, &wm5110_anc_ng_mux),
1271
1272SND_SOC_DAPM_PGA_E("RXANCL", SND_SOC_NOPM, ARIZONA_CLK_L_ENA_SET_SHIFT,
1273 0, NULL, 0, arizona_anc_ev,
1274 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
1275SND_SOC_DAPM_PGA_E("RXANCR", SND_SOC_NOPM, ARIZONA_CLK_R_ENA_SET_SHIFT,
1276 0, NULL, 0, arizona_anc_ev,
1277 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
1278
1279SND_SOC_DAPM_MUX("HPOUT1L ANC Source", SND_SOC_NOPM, 0, 0,
1280 &wm5110_output_anc_src[0]),
1281SND_SOC_DAPM_MUX("HPOUT1R ANC Source", SND_SOC_NOPM, 0, 0,
1282 &wm5110_output_anc_src[1]),
1283SND_SOC_DAPM_MUX("HPOUT2L ANC Source", SND_SOC_NOPM, 0, 0,
1284 &wm5110_output_anc_src[2]),
1285SND_SOC_DAPM_MUX("HPOUT2R ANC Source", SND_SOC_NOPM, 0, 0,
1286 &wm5110_output_anc_src[3]),
1287SND_SOC_DAPM_MUX("HPOUT3L ANC Source", SND_SOC_NOPM, 0, 0,
1288 &wm5110_output_anc_src[4]),
1289SND_SOC_DAPM_MUX("HPOUT3R ANC Source", SND_SOC_NOPM, 0, 0,
1290 &wm5110_output_anc_src[5]),
1291SND_SOC_DAPM_MUX("SPKOUTL ANC Source", SND_SOC_NOPM, 0, 0,
1292 &wm5110_output_anc_src[6]),
1293SND_SOC_DAPM_MUX("SPKOUTR ANC Source", SND_SOC_NOPM, 0, 0,
1294 &wm5110_output_anc_src[7]),
1295SND_SOC_DAPM_MUX("SPKDAT1L ANC Source", SND_SOC_NOPM, 0, 0,
1296 &wm5110_output_anc_src[8]),
1297SND_SOC_DAPM_MUX("SPKDAT1R ANC Source", SND_SOC_NOPM, 0, 0,
1298 &wm5110_output_anc_src[9]),
1299SND_SOC_DAPM_MUX("SPKDAT2L ANC Source", SND_SOC_NOPM, 0, 0,
1300 &wm5110_output_anc_src[10]),
1301SND_SOC_DAPM_MUX("SPKDAT2R ANC Source", SND_SOC_NOPM, 0, 0,
1302 &wm5110_output_anc_src[11]),
1303
1188SND_SOC_DAPM_AIF_OUT("AIF1TX1", NULL, 0, 1304SND_SOC_DAPM_AIF_OUT("AIF1TX1", NULL, 0,
1189 ARIZONA_AIF1_TX_ENABLES, ARIZONA_AIF1TX1_ENA_SHIFT, 0), 1305 ARIZONA_AIF1_TX_ENABLES, ARIZONA_AIF1TX1_ENA_SHIFT, 0),
1190SND_SOC_DAPM_AIF_OUT("AIF1TX2", NULL, 0, 1306SND_SOC_DAPM_AIF_OUT("AIF1TX2", NULL, 0,
@@ -1690,6 +1806,9 @@ static const struct snd_soc_dapm_route wm5110_dapm_routes[] = {
1690 { "Slim2 Capture", NULL, "SYSCLK" }, 1806 { "Slim2 Capture", NULL, "SYSCLK" },
1691 { "Slim3 Capture", NULL, "SYSCLK" }, 1807 { "Slim3 Capture", NULL, "SYSCLK" },
1692 1808
1809 { "Voice Control DSP", NULL, "DSP3" },
1810 { "Voice Control DSP", NULL, "SYSCLK" },
1811
1693 { "IN1L PGA", NULL, "IN1L" }, 1812 { "IN1L PGA", NULL, "IN1L" },
1694 { "IN1R PGA", NULL, "IN1R" }, 1813 { "IN1R PGA", NULL, "IN1R" },
1695 1814
@@ -1838,6 +1957,22 @@ static const struct snd_soc_dapm_route wm5110_dapm_routes[] = {
1838 { "SPKDAT2L", NULL, "OUT6L" }, 1957 { "SPKDAT2L", NULL, "OUT6L" },
1839 { "SPKDAT2R", NULL, "OUT6R" }, 1958 { "SPKDAT2R", NULL, "OUT6R" },
1840 1959
1960 WM5110_RXANC_INPUT_ROUTES("RXANCL", "RXANCL"),
1961 WM5110_RXANC_INPUT_ROUTES("RXANCR", "RXANCR"),
1962
1963 WM5110_RXANC_OUTPUT_ROUTES("OUT1L", "HPOUT1L"),
1964 WM5110_RXANC_OUTPUT_ROUTES("OUT1R", "HPOUT1R"),
1965 WM5110_RXANC_OUTPUT_ROUTES("OUT2L", "HPOUT2L"),
1966 WM5110_RXANC_OUTPUT_ROUTES("OUT2R", "HPOUT2R"),
1967 WM5110_RXANC_OUTPUT_ROUTES("OUT3L", "HPOUT3L"),
1968 WM5110_RXANC_OUTPUT_ROUTES("OUT3R", "HPOUT3R"),
1969 WM5110_RXANC_OUTPUT_ROUTES("OUT4L", "SPKOUTL"),
1970 WM5110_RXANC_OUTPUT_ROUTES("OUT4R", "SPKOUTR"),
1971 WM5110_RXANC_OUTPUT_ROUTES("OUT5L", "SPKDAT1L"),
1972 WM5110_RXANC_OUTPUT_ROUTES("OUT5R", "SPKDAT1R"),
1973 WM5110_RXANC_OUTPUT_ROUTES("OUT6L", "SPKDAT2L"),
1974 WM5110_RXANC_OUTPUT_ROUTES("OUT6R", "SPKDAT2R"),
1975
1841 { "MICSUPP", NULL, "SYSCLK" }, 1976 { "MICSUPP", NULL, "SYSCLK" },
1842 1977
1843 { "DRC1 Signal Activity", NULL, "DRC1L" }, 1978 { "DRC1 Signal Activity", NULL, "DRC1L" },
@@ -1996,12 +2131,65 @@ static struct snd_soc_dai_driver wm5110_dai[] = {
1996 }, 2131 },
1997 .ops = &arizona_simple_dai_ops, 2132 .ops = &arizona_simple_dai_ops,
1998 }, 2133 },
2134 {
2135 .name = "wm5110-cpu-voicectrl",
2136 .capture = {
2137 .stream_name = "Voice Control CPU",
2138 .channels_min = 1,
2139 .channels_max = 1,
2140 .rates = WM5110_RATES,
2141 .formats = WM5110_FORMATS,
2142 },
2143 .compress_new = snd_soc_new_compress,
2144 },
2145 {
2146 .name = "wm5110-dsp-voicectrl",
2147 .capture = {
2148 .stream_name = "Voice Control DSP",
2149 .channels_min = 1,
2150 .channels_max = 1,
2151 .rates = WM5110_RATES,
2152 .formats = WM5110_FORMATS,
2153 },
2154 },
1999}; 2155};
2000 2156
2157static int wm5110_open(struct snd_compr_stream *stream)
2158{
2159 struct snd_soc_pcm_runtime *rtd = stream->private_data;
2160 struct wm5110_priv *priv = snd_soc_codec_get_drvdata(rtd->codec);
2161 struct arizona *arizona = priv->core.arizona;
2162 int n_adsp;
2163
2164 if (strcmp(rtd->codec_dai->name, "wm5110-dsp-voicectrl") == 0) {
2165 n_adsp = 2;
2166 } else {
2167 dev_err(arizona->dev,
2168 "No suitable compressed stream for DAI '%s'\n",
2169 rtd->codec_dai->name);
2170 return -EINVAL;
2171 }
2172
2173 return wm_adsp_compr_open(&priv->core.adsp[n_adsp], stream);
2174}
2175
2176static irqreturn_t wm5110_adsp2_irq(int irq, void *data)
2177{
2178 struct wm5110_priv *florida = data;
2179 int ret;
2180
2181 ret = wm_adsp_compr_handle_irq(&florida->core.adsp[2]);
2182 if (ret == -ENODEV)
2183 return IRQ_NONE;
2184
2185 return IRQ_HANDLED;
2186}
2187
2001static int wm5110_codec_probe(struct snd_soc_codec *codec) 2188static int wm5110_codec_probe(struct snd_soc_codec *codec)
2002{ 2189{
2003 struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec); 2190 struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
2004 struct wm5110_priv *priv = snd_soc_codec_get_drvdata(codec); 2191 struct wm5110_priv *priv = snd_soc_codec_get_drvdata(codec);
2192 struct arizona *arizona = priv->core.arizona;
2005 int i, ret; 2193 int i, ret;
2006 2194
2007 priv->core.arizona->dapm = dapm; 2195 priv->core.arizona->dapm = dapm;
@@ -2010,6 +2198,14 @@ static int wm5110_codec_probe(struct snd_soc_codec *codec)
2010 arizona_init_gpio(codec); 2198 arizona_init_gpio(codec);
2011 arizona_init_mono(codec); 2199 arizona_init_mono(codec);
2012 2200
2201 ret = arizona_request_irq(arizona, ARIZONA_IRQ_DSP_IRQ1,
2202 "ADSP2 Compressed IRQ", wm5110_adsp2_irq,
2203 priv);
2204 if (ret != 0) {
2205 dev_err(codec->dev, "Failed to request DSP IRQ: %d\n", ret);
2206 return ret;
2207 }
2208
2013 for (i = 0; i < WM5110_NUM_ADSP; ++i) { 2209 for (i = 0; i < WM5110_NUM_ADSP; ++i) {
2014 ret = wm_adsp2_codec_probe(&priv->core.adsp[i], codec); 2210 ret = wm_adsp2_codec_probe(&priv->core.adsp[i], codec);
2015 if (ret) 2211 if (ret)
@@ -2030,12 +2226,15 @@ err_adsp2_codec_probe:
2030 for (--i; i >= 0; --i) 2226 for (--i; i >= 0; --i)
2031 wm_adsp2_codec_remove(&priv->core.adsp[i], codec); 2227 wm_adsp2_codec_remove(&priv->core.adsp[i], codec);
2032 2228
2229 arizona_free_irq(arizona, ARIZONA_IRQ_DSP_IRQ1, priv);
2230
2033 return ret; 2231 return ret;
2034} 2232}
2035 2233
2036static int wm5110_codec_remove(struct snd_soc_codec *codec) 2234static int wm5110_codec_remove(struct snd_soc_codec *codec)
2037{ 2235{
2038 struct wm5110_priv *priv = snd_soc_codec_get_drvdata(codec); 2236 struct wm5110_priv *priv = snd_soc_codec_get_drvdata(codec);
2237 struct arizona *arizona = priv->core.arizona;
2039 int i; 2238 int i;
2040 2239
2041 for (i = 0; i < WM5110_NUM_ADSP; ++i) 2240 for (i = 0; i < WM5110_NUM_ADSP; ++i)
@@ -2043,6 +2242,8 @@ static int wm5110_codec_remove(struct snd_soc_codec *codec)
2043 2242
2044 priv->core.arizona->dapm = NULL; 2243 priv->core.arizona->dapm = NULL;
2045 2244
2245 arizona_free_irq(arizona, ARIZONA_IRQ_DSP_IRQ1, priv);
2246
2046 return 0; 2247 return 0;
2047} 2248}
2048 2249
@@ -2088,6 +2289,20 @@ static struct snd_soc_codec_driver soc_codec_dev_wm5110 = {
2088 .num_dapm_routes = ARRAY_SIZE(wm5110_dapm_routes), 2289 .num_dapm_routes = ARRAY_SIZE(wm5110_dapm_routes),
2089}; 2290};
2090 2291
2292static struct snd_compr_ops wm5110_compr_ops = {
2293 .open = wm5110_open,
2294 .free = wm_adsp_compr_free,
2295 .set_params = wm_adsp_compr_set_params,
2296 .get_caps = wm_adsp_compr_get_caps,
2297 .trigger = wm_adsp_compr_trigger,
2298 .pointer = wm_adsp_compr_pointer,
2299 .copy = wm_adsp_compr_copy,
2300};
2301
2302static struct snd_soc_platform_driver wm5110_compr_platform = {
2303 .compr_ops = &wm5110_compr_ops,
2304};
2305
2091static int wm5110_probe(struct platform_device *pdev) 2306static int wm5110_probe(struct platform_device *pdev)
2092{ 2307{
2093 struct arizona *arizona = dev_get_drvdata(pdev->dev.parent); 2308 struct arizona *arizona = dev_get_drvdata(pdev->dev.parent);
@@ -2148,8 +2363,21 @@ static int wm5110_probe(struct platform_device *pdev)
2148 pm_runtime_enable(&pdev->dev); 2363 pm_runtime_enable(&pdev->dev);
2149 pm_runtime_idle(&pdev->dev); 2364 pm_runtime_idle(&pdev->dev);
2150 2365
2151 return snd_soc_register_codec(&pdev->dev, &soc_codec_dev_wm5110, 2366 ret = snd_soc_register_platform(&pdev->dev, &wm5110_compr_platform);
2367 if (ret < 0) {
2368 dev_err(&pdev->dev, "Failed to register platform: %d\n", ret);
2369 goto error;
2370 }
2371
2372 ret = snd_soc_register_codec(&pdev->dev, &soc_codec_dev_wm5110,
2152 wm5110_dai, ARRAY_SIZE(wm5110_dai)); 2373 wm5110_dai, ARRAY_SIZE(wm5110_dai));
2374 if (ret < 0) {
2375 dev_err(&pdev->dev, "Failed to register codec: %d\n", ret);
2376 snd_soc_unregister_platform(&pdev->dev);
2377 }
2378
2379error:
2380 return ret;
2153} 2381}
2154 2382
2155static int wm5110_remove(struct platform_device *pdev) 2383static int wm5110_remove(struct platform_device *pdev)
diff --git a/sound/soc/codecs/wm8903.c b/sound/soc/codecs/wm8903.c
index e4cc41e6c23e..2ed6419c181e 100644
--- a/sound/soc/codecs/wm8903.c
+++ b/sound/soc/codecs/wm8903.c
@@ -1804,7 +1804,7 @@ static int wm8903_gpio_get(struct gpio_chip *chip, unsigned offset)
1804 1804
1805 regmap_read(wm8903->regmap, WM8903_GPIO_CONTROL_1 + offset, &reg); 1805 regmap_read(wm8903->regmap, WM8903_GPIO_CONTROL_1 + offset, &reg);
1806 1806
1807 return (reg & WM8903_GP1_LVL_MASK) >> WM8903_GP1_LVL_SHIFT; 1807 return !!((reg & WM8903_GP1_LVL_MASK) >> WM8903_GP1_LVL_SHIFT);
1808} 1808}
1809 1809
1810static int wm8903_gpio_direction_out(struct gpio_chip *chip, 1810static int wm8903_gpio_direction_out(struct gpio_chip *chip,
diff --git a/sound/soc/codecs/wm8904.c b/sound/soc/codecs/wm8904.c
index 2aa23f1b9e3c..8172e499e6ed 100644
--- a/sound/soc/codecs/wm8904.c
+++ b/sound/soc/codecs/wm8904.c
@@ -312,7 +312,7 @@ static bool wm8904_readable_register(struct device *dev, unsigned int reg)
312 case WM8904_FLL_NCO_TEST_1: 312 case WM8904_FLL_NCO_TEST_1:
313 return true; 313 return true;
314 default: 314 default:
315 return true; 315 return false;
316 } 316 }
317} 317}
318 318
diff --git a/sound/soc/codecs/wm8960.c b/sound/soc/codecs/wm8960.c
index 5380798883b5..ff237726775a 100644
--- a/sound/soc/codecs/wm8960.c
+++ b/sound/soc/codecs/wm8960.c
@@ -147,6 +147,13 @@ static const char *wm8960_3d_upper_cutoff[] = {"High", "Low"};
147static const char *wm8960_3d_lower_cutoff[] = {"Low", "High"}; 147static const char *wm8960_3d_lower_cutoff[] = {"Low", "High"};
148static const char *wm8960_alcfunc[] = {"Off", "Right", "Left", "Stereo"}; 148static const char *wm8960_alcfunc[] = {"Off", "Right", "Left", "Stereo"};
149static const char *wm8960_alcmode[] = {"ALC", "Limiter"}; 149static const char *wm8960_alcmode[] = {"ALC", "Limiter"};
150static const char *wm8960_adc_data_output_sel[] = {
151 "Left Data = Left ADC; Right Data = Right ADC",
152 "Left Data = Left ADC; Right Data = Left ADC",
153 "Left Data = Right ADC; Right Data = Right ADC",
154 "Left Data = Right ADC; Right Data = Left ADC",
155};
156static const char *wm8960_dmonomix[] = {"Stereo", "Mono"};
150 157
151static const struct soc_enum wm8960_enum[] = { 158static const struct soc_enum wm8960_enum[] = {
152 SOC_ENUM_SINGLE(WM8960_DACCTL1, 5, 4, wm8960_polarity), 159 SOC_ENUM_SINGLE(WM8960_DACCTL1, 5, 4, wm8960_polarity),
@@ -155,6 +162,8 @@ static const struct soc_enum wm8960_enum[] = {
155 SOC_ENUM_SINGLE(WM8960_3D, 5, 2, wm8960_3d_lower_cutoff), 162 SOC_ENUM_SINGLE(WM8960_3D, 5, 2, wm8960_3d_lower_cutoff),
156 SOC_ENUM_SINGLE(WM8960_ALC1, 7, 4, wm8960_alcfunc), 163 SOC_ENUM_SINGLE(WM8960_ALC1, 7, 4, wm8960_alcfunc),
157 SOC_ENUM_SINGLE(WM8960_ALC3, 8, 2, wm8960_alcmode), 164 SOC_ENUM_SINGLE(WM8960_ALC3, 8, 2, wm8960_alcmode),
165 SOC_ENUM_SINGLE(WM8960_ADDCTL1, 2, 4, wm8960_adc_data_output_sel),
166 SOC_ENUM_SINGLE(WM8960_ADDCTL1, 4, 2, wm8960_dmonomix),
158}; 167};
159 168
160static const int deemph_settings[] = { 0, 32000, 44100, 48000 }; 169static const int deemph_settings[] = { 0, 32000, 44100, 48000 };
@@ -295,6 +304,9 @@ SOC_SINGLE_TLV("Right Output Mixer Boost Bypass Volume",
295 WM8960_BYPASS2, 4, 7, 1, bypass_tlv), 304 WM8960_BYPASS2, 4, 7, 1, bypass_tlv),
296SOC_SINGLE_TLV("Right Output Mixer RINPUT3 Volume", 305SOC_SINGLE_TLV("Right Output Mixer RINPUT3 Volume",
297 WM8960_ROUTMIX, 4, 7, 1, bypass_tlv), 306 WM8960_ROUTMIX, 4, 7, 1, bypass_tlv),
307
308SOC_ENUM("ADC Data Output Select", wm8960_enum[6]),
309SOC_ENUM("DAC Mono Mix", wm8960_enum[7]),
298}; 310};
299 311
300static const struct snd_kcontrol_new wm8960_lin_boost[] = { 312static const struct snd_kcontrol_new wm8960_lin_boost[] = {
@@ -401,8 +413,8 @@ static const struct snd_soc_dapm_route audio_paths[] = {
401 { "Left Boost Mixer", "LINPUT2 Switch", "LINPUT2" }, 413 { "Left Boost Mixer", "LINPUT2 Switch", "LINPUT2" },
402 { "Left Boost Mixer", "LINPUT3 Switch", "LINPUT3" }, 414 { "Left Boost Mixer", "LINPUT3 Switch", "LINPUT3" },
403 415
404 { "Left Input Mixer", "Boost Switch", "Left Boost Mixer", }, 416 { "Left Input Mixer", "Boost Switch", "Left Boost Mixer" },
405 { "Left Input Mixer", NULL, "LINPUT1", }, /* Really Boost Switch */ 417 { "Left Input Mixer", "Boost Switch", "LINPUT1" }, /* Really Boost Switch */
406 { "Left Input Mixer", NULL, "LINPUT2" }, 418 { "Left Input Mixer", NULL, "LINPUT2" },
407 { "Left Input Mixer", NULL, "LINPUT3" }, 419 { "Left Input Mixer", NULL, "LINPUT3" },
408 420
@@ -410,8 +422,8 @@ static const struct snd_soc_dapm_route audio_paths[] = {
410 { "Right Boost Mixer", "RINPUT2 Switch", "RINPUT2" }, 422 { "Right Boost Mixer", "RINPUT2 Switch", "RINPUT2" },
411 { "Right Boost Mixer", "RINPUT3 Switch", "RINPUT3" }, 423 { "Right Boost Mixer", "RINPUT3 Switch", "RINPUT3" },
412 424
413 { "Right Input Mixer", "Boost Switch", "Right Boost Mixer", }, 425 { "Right Input Mixer", "Boost Switch", "Right Boost Mixer" },
414 { "Right Input Mixer", NULL, "RINPUT1", }, /* Really Boost Switch */ 426 { "Right Input Mixer", "Boost Switch", "RINPUT1" }, /* Really Boost Switch */
415 { "Right Input Mixer", NULL, "RINPUT2" }, 427 { "Right Input Mixer", NULL, "RINPUT2" },
416 { "Right Input Mixer", NULL, "RINPUT3" }, 428 { "Right Input Mixer", NULL, "RINPUT3" },
417 429
@@ -419,11 +431,11 @@ static const struct snd_soc_dapm_route audio_paths[] = {
419 { "Right ADC", NULL, "Right Input Mixer" }, 431 { "Right ADC", NULL, "Right Input Mixer" },
420 432
421 { "Left Output Mixer", "LINPUT3 Switch", "LINPUT3" }, 433 { "Left Output Mixer", "LINPUT3 Switch", "LINPUT3" },
422 { "Left Output Mixer", "Boost Bypass Switch", "Left Boost Mixer"} , 434 { "Left Output Mixer", "Boost Bypass Switch", "Left Boost Mixer" },
423 { "Left Output Mixer", "PCM Playback Switch", "Left DAC" }, 435 { "Left Output Mixer", "PCM Playback Switch", "Left DAC" },
424 436
425 { "Right Output Mixer", "RINPUT3 Switch", "RINPUT3" }, 437 { "Right Output Mixer", "RINPUT3 Switch", "RINPUT3" },
426 { "Right Output Mixer", "Boost Bypass Switch", "Right Boost Mixer" } , 438 { "Right Output Mixer", "Boost Bypass Switch", "Right Boost Mixer" },
427 { "Right Output Mixer", "PCM Playback Switch", "Right DAC" }, 439 { "Right Output Mixer", "PCM Playback Switch", "Right DAC" },
428 440
429 { "LOUT1 PGA", NULL, "Left Output Mixer" }, 441 { "LOUT1 PGA", NULL, "Left Output Mixer" },
diff --git a/sound/soc/codecs/wm8962.c b/sound/soc/codecs/wm8962.c
index a7e79784fc16..949f632fc3f8 100644
--- a/sound/soc/codecs/wm8962.c
+++ b/sound/soc/codecs/wm8962.c
@@ -131,7 +131,7 @@ static const struct reg_default wm8962_reg[] = {
131 { 15, 0x6243 }, /* R15 - Software Reset */ 131 { 15, 0x6243 }, /* R15 - Software Reset */
132 132
133 { 17, 0x007B }, /* R17 - ALC1 */ 133 { 17, 0x007B }, /* R17 - ALC1 */
134 134 { 18, 0x0000 }, /* R18 - ALC2 */
135 { 19, 0x1C32 }, /* R19 - ALC3 */ 135 { 19, 0x1C32 }, /* R19 - ALC3 */
136 { 20, 0x3200 }, /* R20 - Noise Gate */ 136 { 20, 0x3200 }, /* R20 - Noise Gate */
137 { 21, 0x00C0 }, /* R21 - Left ADC volume */ 137 { 21, 0x00C0 }, /* R21 - Left ADC volume */
@@ -794,7 +794,6 @@ static bool wm8962_volatile_register(struct device *dev, unsigned int reg)
794 case WM8962_CLOCKING1: 794 case WM8962_CLOCKING1:
795 case WM8962_CLOCKING2: 795 case WM8962_CLOCKING2:
796 case WM8962_SOFTWARE_RESET: 796 case WM8962_SOFTWARE_RESET:
797 case WM8962_ALC2:
798 case WM8962_THERMAL_SHUTDOWN_STATUS: 797 case WM8962_THERMAL_SHUTDOWN_STATUS:
799 case WM8962_ADDITIONAL_CONTROL_4: 798 case WM8962_ADDITIONAL_CONTROL_4:
800 case WM8962_DC_SERVO_6: 799 case WM8962_DC_SERVO_6:
diff --git a/sound/soc/codecs/wm8974.c b/sound/soc/codecs/wm8974.c
index 4c29bd2ae75c..c284c7b6db8b 100644
--- a/sound/soc/codecs/wm8974.c
+++ b/sound/soc/codecs/wm8974.c
@@ -632,9 +632,16 @@ static const struct i2c_device_id wm8974_i2c_id[] = {
632}; 632};
633MODULE_DEVICE_TABLE(i2c, wm8974_i2c_id); 633MODULE_DEVICE_TABLE(i2c, wm8974_i2c_id);
634 634
635static const struct of_device_id wm8974_of_match[] = {
636 { .compatible = "wlf,wm8974", },
637 { }
638};
639MODULE_DEVICE_TABLE(of, wm8974_of_match);
640
635static struct i2c_driver wm8974_i2c_driver = { 641static struct i2c_driver wm8974_i2c_driver = {
636 .driver = { 642 .driver = {
637 .name = "wm8974", 643 .name = "wm8974",
644 .of_match_table = wm8974_of_match,
638 }, 645 },
639 .probe = wm8974_i2c_probe, 646 .probe = wm8974_i2c_probe,
640 .remove = wm8974_i2c_remove, 647 .remove = wm8974_i2c_remove,
diff --git a/sound/soc/codecs/wm8998.c b/sound/soc/codecs/wm8998.c
index 8782dfb628ab..7719bc509e50 100644
--- a/sound/soc/codecs/wm8998.c
+++ b/sound/soc/codecs/wm8998.c
@@ -199,20 +199,20 @@ static const char * const wm8998_inmux_texts[] = {
199 "B", 199 "B",
200}; 200};
201 201
202static const SOC_ENUM_SINGLE_DECL(wm8998_in1muxl_enum, 202static SOC_ENUM_SINGLE_DECL(wm8998_in1muxl_enum,
203 ARIZONA_ADC_DIGITAL_VOLUME_1L, 203 ARIZONA_ADC_DIGITAL_VOLUME_1L,
204 ARIZONA_IN1L_SRC_SHIFT, 204 ARIZONA_IN1L_SRC_SHIFT,
205 wm8998_inmux_texts); 205 wm8998_inmux_texts);
206 206
207static const SOC_ENUM_SINGLE_DECL(wm8998_in1muxr_enum, 207static SOC_ENUM_SINGLE_DECL(wm8998_in1muxr_enum,
208 ARIZONA_ADC_DIGITAL_VOLUME_1R, 208 ARIZONA_ADC_DIGITAL_VOLUME_1R,
209 ARIZONA_IN1R_SRC_SHIFT, 209 ARIZONA_IN1R_SRC_SHIFT,
210 wm8998_inmux_texts); 210 wm8998_inmux_texts);
211 211
212static const SOC_ENUM_SINGLE_DECL(wm8998_in2mux_enum, 212static SOC_ENUM_SINGLE_DECL(wm8998_in2mux_enum,
213 ARIZONA_ADC_DIGITAL_VOLUME_2L, 213 ARIZONA_ADC_DIGITAL_VOLUME_2L,
214 ARIZONA_IN2L_SRC_SHIFT, 214 ARIZONA_IN2L_SRC_SHIFT,
215 wm8998_inmux_texts); 215 wm8998_inmux_texts);
216 216
217static const struct snd_kcontrol_new wm8998_in1mux[2] = { 217static const struct snd_kcontrol_new wm8998_in1mux[2] = {
218 SOC_DAPM_ENUM_EXT("IN1L Mux", wm8998_in1muxl_enum, 218 SOC_DAPM_ENUM_EXT("IN1L Mux", wm8998_in1muxl_enum,
@@ -522,17 +522,17 @@ static const unsigned int wm8998_aec_loopback_values[] = {
522 0, 1, 2, 3, 4, 6, 7, 8, 9, 522 0, 1, 2, 3, 4, 6, 7, 8, 9,
523}; 523};
524 524
525static const SOC_VALUE_ENUM_SINGLE_DECL(wm8998_aec1_loopback, 525static SOC_VALUE_ENUM_SINGLE_DECL(wm8998_aec1_loopback,
526 ARIZONA_DAC_AEC_CONTROL_1, 526 ARIZONA_DAC_AEC_CONTROL_1,
527 ARIZONA_AEC_LOOPBACK_SRC_SHIFT, 0xf, 527 ARIZONA_AEC_LOOPBACK_SRC_SHIFT, 0xf,
528 wm8998_aec_loopback_texts, 528 wm8998_aec_loopback_texts,
529 wm8998_aec_loopback_values); 529 wm8998_aec_loopback_values);
530 530
531static const SOC_VALUE_ENUM_SINGLE_DECL(wm8998_aec2_loopback, 531static SOC_VALUE_ENUM_SINGLE_DECL(wm8998_aec2_loopback,
532 ARIZONA_DAC_AEC_CONTROL_2, 532 ARIZONA_DAC_AEC_CONTROL_2,
533 ARIZONA_AEC_LOOPBACK_SRC_SHIFT, 0xf, 533 ARIZONA_AEC_LOOPBACK_SRC_SHIFT, 0xf,
534 wm8998_aec_loopback_texts, 534 wm8998_aec_loopback_texts,
535 wm8998_aec_loopback_values); 535 wm8998_aec_loopback_values);
536 536
537static const struct snd_kcontrol_new wm8998_aec_loopback_mux[] = { 537static const struct snd_kcontrol_new wm8998_aec_loopback_mux[] = {
538 SOC_DAPM_ENUM("AEC1 Loopback", wm8998_aec1_loopback), 538 SOC_DAPM_ENUM("AEC1 Loopback", wm8998_aec1_loopback),
diff --git a/sound/soc/codecs/wm9713.c b/sound/soc/codecs/wm9713.c
index 4083a5130cbd..79e143625ac3 100644
--- a/sound/soc/codecs/wm9713.c
+++ b/sound/soc/codecs/wm9713.c
@@ -19,6 +19,7 @@
19#include <linux/slab.h> 19#include <linux/slab.h>
20#include <linux/module.h> 20#include <linux/module.h>
21#include <linux/device.h> 21#include <linux/device.h>
22#include <linux/regmap.h>
22#include <sound/core.h> 23#include <sound/core.h>
23#include <sound/pcm.h> 24#include <sound/pcm.h>
24#include <sound/ac97_codec.h> 25#include <sound/ac97_codec.h>
@@ -39,34 +40,6 @@ struct wm9713_priv {
39 struct mutex lock; 40 struct mutex lock;
40}; 41};
41 42
42static unsigned int ac97_read(struct snd_soc_codec *codec,
43 unsigned int reg);
44static int ac97_write(struct snd_soc_codec *codec,
45 unsigned int reg, unsigned int val);
46
47/*
48 * WM9713 register cache
49 * Reg 0x3c bit 15 is used by touch driver.
50 */
51static const u16 wm9713_reg[] = {
52 0x6174, 0x8080, 0x8080, 0x8080,
53 0xc880, 0xe808, 0xe808, 0x0808,
54 0x00da, 0x8000, 0xd600, 0xaaa0,
55 0xaaa0, 0xaaa0, 0x0000, 0x0000,
56 0x0f0f, 0x0040, 0x0000, 0x7f00,
57 0x0405, 0x0410, 0xbb80, 0xbb80,
58 0x0000, 0xbb80, 0x0000, 0x4523,
59 0x0000, 0x2000, 0x7eff, 0xffff,
60 0x0000, 0x0000, 0x0080, 0x0000,
61 0x0000, 0x0000, 0xfffe, 0xffff,
62 0x0000, 0x0000, 0x0000, 0xfffe,
63 0x4000, 0x0000, 0x0000, 0x0000,
64 0xb032, 0x3e00, 0x0000, 0x0000,
65 0x0000, 0x0000, 0x0000, 0x0000,
66 0x0000, 0x0000, 0x0000, 0x0006,
67 0x0001, 0x0000, 0x574d, 0x4c13,
68};
69
70#define HPL_MIXER 0 43#define HPL_MIXER 0
71#define HPR_MIXER 1 44#define HPR_MIXER 1
72 45
@@ -220,18 +193,15 @@ static int wm9713_voice_shutdown(struct snd_soc_dapm_widget *w,
220 struct snd_kcontrol *kcontrol, int event) 193 struct snd_kcontrol *kcontrol, int event)
221{ 194{
222 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); 195 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
223 u16 status, rate;
224 196
225 if (WARN_ON(event != SND_SOC_DAPM_PRE_PMD)) 197 if (WARN_ON(event != SND_SOC_DAPM_PRE_PMD))
226 return -EINVAL; 198 return -EINVAL;
227 199
228 /* Gracefully shut down the voice interface. */ 200 /* Gracefully shut down the voice interface. */
229 status = ac97_read(codec, AC97_EXTENDED_MID) | 0x1000; 201 snd_soc_update_bits(codec, AC97_HANDSET_RATE, 0x0f00, 0x0200);
230 rate = ac97_read(codec, AC97_HANDSET_RATE) & 0xF0FF;
231 ac97_write(codec, AC97_HANDSET_RATE, rate | 0x0200);
232 schedule_timeout_interruptible(msecs_to_jiffies(1)); 202 schedule_timeout_interruptible(msecs_to_jiffies(1));
233 ac97_write(codec, AC97_HANDSET_RATE, rate | 0x0F00); 203 snd_soc_update_bits(codec, AC97_HANDSET_RATE, 0x0f00, 0x0f00);
234 ac97_write(codec, AC97_EXTENDED_MID, status); 204 snd_soc_update_bits(codec, AC97_EXTENDED_MID, 0x1000, 0x1000);
235 205
236 return 0; 206 return 0;
237} 207}
@@ -674,39 +644,97 @@ static const struct snd_soc_dapm_route wm9713_audio_map[] = {
674 {"Capture Mono Mux", "Right", "Right Capture Source"}, 644 {"Capture Mono Mux", "Right", "Right Capture Source"},
675}; 645};
676 646
677static unsigned int ac97_read(struct snd_soc_codec *codec, 647static bool wm9713_readable_reg(struct device *dev, unsigned int reg)
678 unsigned int reg)
679{ 648{
680 struct wm9713_priv *wm9713 = snd_soc_codec_get_drvdata(codec); 649 switch (reg) {
681 u16 *cache = codec->reg_cache; 650 case AC97_RESET ... AC97_PCM_SURR_DAC_RATE:
682 651 case AC97_PCM_LR_ADC_RATE:
683 if (reg == AC97_RESET || reg == AC97_GPIO_STATUS || 652 case AC97_CENTER_LFE_MASTER:
684 reg == AC97_VENDOR_ID1 || reg == AC97_VENDOR_ID2 || 653 case AC97_SPDIF ... AC97_LINE1_LEVEL:
685 reg == AC97_CD) 654 case AC97_GPIO_CFG ... 0x5c:
686 return soc_ac97_ops->read(wm9713->ac97, reg); 655 case AC97_CODEC_CLASS_REV ... AC97_PCI_SID:
687 else { 656 case 0x74 ... AC97_VENDOR_ID2:
688 reg = reg >> 1; 657 return true;
689 658 default:
690 if (reg >= (ARRAY_SIZE(wm9713_reg))) 659 return false;
691 return -EIO;
692
693 return cache[reg];
694 } 660 }
695} 661}
696 662
697static int ac97_write(struct snd_soc_codec *codec, unsigned int reg, 663static bool wm9713_writeable_reg(struct device *dev, unsigned int reg)
698 unsigned int val)
699{ 664{
700 struct wm9713_priv *wm9713 = snd_soc_codec_get_drvdata(codec); 665 switch (reg) {
666 case AC97_VENDOR_ID1:
667 case AC97_VENDOR_ID2:
668 return false;
669 default:
670 return wm9713_readable_reg(dev, reg);
671 }
672}
701 673
702 u16 *cache = codec->reg_cache; 674static const struct reg_default wm9713_reg_defaults[] = {
703 soc_ac97_ops->write(wm9713->ac97, reg, val); 675 { 0x02, 0x8080 }, /* Speaker Output Volume */
704 reg = reg >> 1; 676 { 0x04, 0x8080 }, /* Headphone Output Volume */
705 if (reg < (ARRAY_SIZE(wm9713_reg))) 677 { 0x06, 0x8080 }, /* Out3/OUT4 Volume */
706 cache[reg] = val; 678 { 0x08, 0xc880 }, /* Mono Volume */
679 { 0x0a, 0xe808 }, /* LINEIN Volume */
680 { 0x0c, 0xe808 }, /* DAC PGA Volume */
681 { 0x0e, 0x0808 }, /* MIC PGA Volume */
682 { 0x10, 0x00da }, /* MIC Routing Control */
683 { 0x12, 0x8000 }, /* Record PGA Volume */
684 { 0x14, 0xd600 }, /* Record Routing */
685 { 0x16, 0xaaa0 }, /* PCBEEP Volume */
686 { 0x18, 0xaaa0 }, /* VxDAC Volume */
687 { 0x1a, 0xaaa0 }, /* AUXDAC Volume */
688 { 0x1c, 0x0000 }, /* Output PGA Mux */
689 { 0x1e, 0x0000 }, /* DAC 3D control */
690 { 0x20, 0x0f0f }, /* DAC Tone Control*/
691 { 0x22, 0x0040 }, /* MIC Input Select & Bias */
692 { 0x24, 0x0000 }, /* Output Volume Mapping & Jack */
693 { 0x26, 0x7f00 }, /* Powerdown Ctrl/Stat*/
694 { 0x28, 0x0405 }, /* Extended Audio ID */
695 { 0x2a, 0x0410 }, /* Extended Audio Start/Ctrl */
696 { 0x2c, 0xbb80 }, /* Audio DACs Sample Rate */
697 { 0x2e, 0xbb80 }, /* AUXDAC Sample Rate */
698 { 0x32, 0xbb80 }, /* Audio ADCs Sample Rate */
699 { 0x36, 0x4523 }, /* PCM codec control */
700 { 0x3a, 0x2000 }, /* SPDIF control */
701 { 0x3c, 0xfdff }, /* Powerdown 1 */
702 { 0x3e, 0xffff }, /* Powerdown 2 */
703 { 0x40, 0x0000 }, /* General Purpose */
704 { 0x42, 0x0000 }, /* Fast Power-Up Control */
705 { 0x44, 0x0080 }, /* MCLK/PLL Control */
706 { 0x46, 0x0000 }, /* MCLK/PLL Control */
707 { 0x4c, 0xfffe }, /* GPIO Pin Configuration */
708 { 0x4e, 0xffff }, /* GPIO Pin Polarity / Type */
709 { 0x50, 0x0000 }, /* GPIO Pin Sticky */
710 { 0x52, 0x0000 }, /* GPIO Pin Wake-Up */
711 /* GPIO Pin Status */
712 { 0x56, 0xfffe }, /* GPIO Pin Sharing */
713 { 0x58, 0x4000 }, /* GPIO PullUp/PullDown */
714 { 0x5a, 0x0000 }, /* Additional Functions 1 */
715 { 0x5c, 0x0000 }, /* Additional Functions 2 */
716 { 0x60, 0xb032 }, /* ALC Control */
717 { 0x62, 0x3e00 }, /* ALC / Noise Gate Control */
718 { 0x64, 0x0000 }, /* AUXDAC input control */
719 { 0x74, 0x0000 }, /* Digitiser Reg 1 */
720 { 0x76, 0x0006 }, /* Digitiser Reg 2 */
721 { 0x78, 0x0001 }, /* Digitiser Reg 3 */
722 { 0x7a, 0x0000 }, /* Digitiser Read Back */
723};
707 724
708 return 0; 725static const struct regmap_config wm9713_regmap_config = {
709} 726 .reg_bits = 16,
727 .reg_stride = 2,
728 .val_bits = 16,
729 .max_register = 0x7e,
730 .cache_type = REGCACHE_RBTREE,
731
732 .reg_defaults = wm9713_reg_defaults,
733 .num_reg_defaults = ARRAY_SIZE(wm9713_reg_defaults),
734 .volatile_reg = regmap_ac97_default_volatile,
735 .readable_reg = wm9713_readable_reg,
736 .writeable_reg = wm9713_writeable_reg,
737};
710 738
711/* PLL divisors */ 739/* PLL divisors */
712struct _pll_div { 740struct _pll_div {
@@ -793,10 +821,8 @@ static int wm9713_set_pll(struct snd_soc_codec *codec,
793 /* turn PLL off ? */ 821 /* turn PLL off ? */
794 if (freq_in == 0) { 822 if (freq_in == 0) {
795 /* disable PLL power and select ext source */ 823 /* disable PLL power and select ext source */
796 reg = ac97_read(codec, AC97_HANDSET_RATE); 824 snd_soc_update_bits(codec, AC97_HANDSET_RATE, 0x0080, 0x0080);
797 ac97_write(codec, AC97_HANDSET_RATE, reg | 0x0080); 825 snd_soc_update_bits(codec, AC97_EXTENDED_MID, 0x0200, 0x0200);
798 reg = ac97_read(codec, AC97_EXTENDED_MID);
799 ac97_write(codec, AC97_EXTENDED_MID, reg | 0x0200);
800 wm9713->pll_in = 0; 826 wm9713->pll_in = 0;
801 return 0; 827 return 0;
802 } 828 }
@@ -806,7 +832,7 @@ static int wm9713_set_pll(struct snd_soc_codec *codec,
806 if (pll_div.k == 0) { 832 if (pll_div.k == 0) {
807 reg = (pll_div.n << 12) | (pll_div.lf << 11) | 833 reg = (pll_div.n << 12) | (pll_div.lf << 11) |
808 (pll_div.divsel << 9) | (pll_div.divctl << 8); 834 (pll_div.divsel << 9) | (pll_div.divctl << 8);
809 ac97_write(codec, AC97_LINE1_LEVEL, reg); 835 snd_soc_write(codec, AC97_LINE1_LEVEL, reg);
810 } else { 836 } else {
811 /* write the fractional k to the reg 0x46 pages */ 837 /* write the fractional k to the reg 0x46 pages */
812 reg2 = (pll_div.n << 12) | (pll_div.lf << 11) | (1 << 10) | 838 reg2 = (pll_div.n << 12) | (pll_div.lf << 11) | (1 << 10) |
@@ -814,33 +840,31 @@ static int wm9713_set_pll(struct snd_soc_codec *codec,
814 840
815 /* K [21:20] */ 841 /* K [21:20] */
816 reg = reg2 | (0x5 << 4) | (pll_div.k >> 20); 842 reg = reg2 | (0x5 << 4) | (pll_div.k >> 20);
817 ac97_write(codec, AC97_LINE1_LEVEL, reg); 843 snd_soc_write(codec, AC97_LINE1_LEVEL, reg);
818 844
819 /* K [19:16] */ 845 /* K [19:16] */
820 reg = reg2 | (0x4 << 4) | ((pll_div.k >> 16) & 0xf); 846 reg = reg2 | (0x4 << 4) | ((pll_div.k >> 16) & 0xf);
821 ac97_write(codec, AC97_LINE1_LEVEL, reg); 847 snd_soc_write(codec, AC97_LINE1_LEVEL, reg);
822 848
823 /* K [15:12] */ 849 /* K [15:12] */
824 reg = reg2 | (0x3 << 4) | ((pll_div.k >> 12) & 0xf); 850 reg = reg2 | (0x3 << 4) | ((pll_div.k >> 12) & 0xf);
825 ac97_write(codec, AC97_LINE1_LEVEL, reg); 851 snd_soc_write(codec, AC97_LINE1_LEVEL, reg);
826 852
827 /* K [11:8] */ 853 /* K [11:8] */
828 reg = reg2 | (0x2 << 4) | ((pll_div.k >> 8) & 0xf); 854 reg = reg2 | (0x2 << 4) | ((pll_div.k >> 8) & 0xf);
829 ac97_write(codec, AC97_LINE1_LEVEL, reg); 855 snd_soc_write(codec, AC97_LINE1_LEVEL, reg);
830 856
831 /* K [7:4] */ 857 /* K [7:4] */
832 reg = reg2 | (0x1 << 4) | ((pll_div.k >> 4) & 0xf); 858 reg = reg2 | (0x1 << 4) | ((pll_div.k >> 4) & 0xf);
833 ac97_write(codec, AC97_LINE1_LEVEL, reg); 859 snd_soc_write(codec, AC97_LINE1_LEVEL, reg);
834 860
835 reg = reg2 | (0x0 << 4) | (pll_div.k & 0xf); /* K [3:0] */ 861 reg = reg2 | (0x0 << 4) | (pll_div.k & 0xf); /* K [3:0] */
836 ac97_write(codec, AC97_LINE1_LEVEL, reg); 862 snd_soc_write(codec, AC97_LINE1_LEVEL, reg);
837 } 863 }
838 864
839 /* turn PLL on and select as source */ 865 /* turn PLL on and select as source */
840 reg = ac97_read(codec, AC97_EXTENDED_MID); 866 snd_soc_update_bits(codec, AC97_EXTENDED_MID, 0x0200, 0x0000);
841 ac97_write(codec, AC97_EXTENDED_MID, reg & 0xfdff); 867 snd_soc_update_bits(codec, AC97_HANDSET_RATE, 0x0080, 0x0000);
842 reg = ac97_read(codec, AC97_HANDSET_RATE);
843 ac97_write(codec, AC97_HANDSET_RATE, reg & 0xff7f);
844 wm9713->pll_in = freq_in; 868 wm9713->pll_in = freq_in;
845 869
846 /* wait 10ms AC97 link frames for the link to stabilise */ 870 /* wait 10ms AC97 link frames for the link to stabilise */
@@ -863,10 +887,10 @@ static int wm9713_set_dai_tristate(struct snd_soc_dai *codec_dai,
863 int tristate) 887 int tristate)
864{ 888{
865 struct snd_soc_codec *codec = codec_dai->codec; 889 struct snd_soc_codec *codec = codec_dai->codec;
866 u16 reg = ac97_read(codec, AC97_CENTER_LFE_MASTER) & 0x9fff;
867 890
868 if (tristate) 891 if (tristate)
869 ac97_write(codec, AC97_CENTER_LFE_MASTER, reg); 892 snd_soc_update_bits(codec, AC97_CENTER_LFE_MASTER,
893 0x6000, 0x0000);
870 894
871 return 0; 895 return 0;
872} 896}
@@ -879,36 +903,30 @@ static int wm9713_set_dai_clkdiv(struct snd_soc_dai *codec_dai,
879 int div_id, int div) 903 int div_id, int div)
880{ 904{
881 struct snd_soc_codec *codec = codec_dai->codec; 905 struct snd_soc_codec *codec = codec_dai->codec;
882 u16 reg;
883 906
884 switch (div_id) { 907 switch (div_id) {
885 case WM9713_PCMCLK_DIV: 908 case WM9713_PCMCLK_DIV:
886 reg = ac97_read(codec, AC97_HANDSET_RATE) & 0xf0ff; 909 snd_soc_update_bits(codec, AC97_HANDSET_RATE, 0x0f00, div);
887 ac97_write(codec, AC97_HANDSET_RATE, reg | div);
888 break; 910 break;
889 case WM9713_CLKA_MULT: 911 case WM9713_CLKA_MULT:
890 reg = ac97_read(codec, AC97_HANDSET_RATE) & 0xfffd; 912 snd_soc_update_bits(codec, AC97_HANDSET_RATE, 0x0002, div);
891 ac97_write(codec, AC97_HANDSET_RATE, reg | div);
892 break; 913 break;
893 case WM9713_CLKB_MULT: 914 case WM9713_CLKB_MULT:
894 reg = ac97_read(codec, AC97_HANDSET_RATE) & 0xfffb; 915 snd_soc_update_bits(codec, AC97_HANDSET_RATE, 0x0004, div);
895 ac97_write(codec, AC97_HANDSET_RATE, reg | div);
896 break; 916 break;
897 case WM9713_HIFI_DIV: 917 case WM9713_HIFI_DIV:
898 reg = ac97_read(codec, AC97_HANDSET_RATE) & 0x8fff; 918 snd_soc_update_bits(codec, AC97_HANDSET_RATE, 0x7000, div);
899 ac97_write(codec, AC97_HANDSET_RATE, reg | div);
900 break; 919 break;
901 case WM9713_PCMBCLK_DIV: 920 case WM9713_PCMBCLK_DIV:
902 reg = ac97_read(codec, AC97_CENTER_LFE_MASTER) & 0xf1ff; 921 snd_soc_update_bits(codec, AC97_CENTER_LFE_MASTER, 0x0e00, div);
903 ac97_write(codec, AC97_CENTER_LFE_MASTER, reg | div);
904 break; 922 break;
905 case WM9713_PCMCLK_PLL_DIV: 923 case WM9713_PCMCLK_PLL_DIV:
906 reg = ac97_read(codec, AC97_LINE1_LEVEL) & 0xff80; 924 snd_soc_update_bits(codec, AC97_LINE1_LEVEL,
907 ac97_write(codec, AC97_LINE1_LEVEL, reg | 0x60 | div); 925 0x007f, div | 0x60);
908 break; 926 break;
909 case WM9713_HIFI_PLL_DIV: 927 case WM9713_HIFI_PLL_DIV:
910 reg = ac97_read(codec, AC97_LINE1_LEVEL) & 0xff80; 928 snd_soc_update_bits(codec, AC97_LINE1_LEVEL,
911 ac97_write(codec, AC97_LINE1_LEVEL, reg | 0x70 | div); 929 0x007f, div | 0x70);
912 break; 930 break;
913 default: 931 default:
914 return -EINVAL; 932 return -EINVAL;
@@ -921,7 +939,7 @@ static int wm9713_set_dai_fmt(struct snd_soc_dai *codec_dai,
921 unsigned int fmt) 939 unsigned int fmt)
922{ 940{
923 struct snd_soc_codec *codec = codec_dai->codec; 941 struct snd_soc_codec *codec = codec_dai->codec;
924 u16 gpio = ac97_read(codec, AC97_GPIO_CFG) & 0xffc5; 942 u16 gpio = snd_soc_read(codec, AC97_GPIO_CFG) & 0xffc5;
925 u16 reg = 0x8000; 943 u16 reg = 0x8000;
926 944
927 /* clock masters */ 945 /* clock masters */
@@ -974,8 +992,8 @@ static int wm9713_set_dai_fmt(struct snd_soc_dai *codec_dai,
974 break; 992 break;
975 } 993 }
976 994
977 ac97_write(codec, AC97_GPIO_CFG, gpio); 995 snd_soc_write(codec, AC97_GPIO_CFG, gpio);
978 ac97_write(codec, AC97_CENTER_LFE_MASTER, reg); 996 snd_soc_write(codec, AC97_CENTER_LFE_MASTER, reg);
979 return 0; 997 return 0;
980} 998}
981 999
@@ -984,24 +1002,24 @@ static int wm9713_pcm_hw_params(struct snd_pcm_substream *substream,
984 struct snd_soc_dai *dai) 1002 struct snd_soc_dai *dai)
985{ 1003{
986 struct snd_soc_codec *codec = dai->codec; 1004 struct snd_soc_codec *codec = dai->codec;
987 u16 reg = ac97_read(codec, AC97_CENTER_LFE_MASTER) & 0xfff3;
988 1005
1006 /* enable PCM interface in master mode */
989 switch (params_width(params)) { 1007 switch (params_width(params)) {
990 case 16: 1008 case 16:
991 break; 1009 break;
992 case 20: 1010 case 20:
993 reg |= 0x0004; 1011 snd_soc_update_bits(codec, AC97_CENTER_LFE_MASTER,
1012 0x000c, 0x0004);
994 break; 1013 break;
995 case 24: 1014 case 24:
996 reg |= 0x0008; 1015 snd_soc_update_bits(codec, AC97_CENTER_LFE_MASTER,
1016 0x000c, 0x0008);
997 break; 1017 break;
998 case 32: 1018 case 32:
999 reg |= 0x000c; 1019 snd_soc_update_bits(codec, AC97_CENTER_LFE_MASTER,
1020 0x000c, 0x000c);
1000 break; 1021 break;
1001 } 1022 }
1002
1003 /* enable PCM interface in master mode */
1004 ac97_write(codec, AC97_CENTER_LFE_MASTER, reg);
1005 return 0; 1023 return 0;
1006} 1024}
1007 1025
@@ -1011,17 +1029,15 @@ static int ac97_hifi_prepare(struct snd_pcm_substream *substream,
1011 struct snd_soc_codec *codec = dai->codec; 1029 struct snd_soc_codec *codec = dai->codec;
1012 struct snd_pcm_runtime *runtime = substream->runtime; 1030 struct snd_pcm_runtime *runtime = substream->runtime;
1013 int reg; 1031 int reg;
1014 u16 vra;
1015 1032
1016 vra = ac97_read(codec, AC97_EXTENDED_STATUS); 1033 snd_soc_update_bits(codec, AC97_EXTENDED_STATUS, 0x0001, 0x0001);
1017 ac97_write(codec, AC97_EXTENDED_STATUS, vra | 0x1);
1018 1034
1019 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 1035 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
1020 reg = AC97_PCM_FRONT_DAC_RATE; 1036 reg = AC97_PCM_FRONT_DAC_RATE;
1021 else 1037 else
1022 reg = AC97_PCM_LR_ADC_RATE; 1038 reg = AC97_PCM_LR_ADC_RATE;
1023 1039
1024 return ac97_write(codec, reg, runtime->rate); 1040 return snd_soc_write(codec, reg, runtime->rate);
1025} 1041}
1026 1042
1027static int ac97_aux_prepare(struct snd_pcm_substream *substream, 1043static int ac97_aux_prepare(struct snd_pcm_substream *substream,
@@ -1029,17 +1045,14 @@ static int ac97_aux_prepare(struct snd_pcm_substream *substream,
1029{ 1045{
1030 struct snd_soc_codec *codec = dai->codec; 1046 struct snd_soc_codec *codec = dai->codec;
1031 struct snd_pcm_runtime *runtime = substream->runtime; 1047 struct snd_pcm_runtime *runtime = substream->runtime;
1032 u16 vra, xsle;
1033 1048
1034 vra = ac97_read(codec, AC97_EXTENDED_STATUS); 1049 snd_soc_update_bits(codec, AC97_EXTENDED_STATUS, 0x0001, 0x0001);
1035 ac97_write(codec, AC97_EXTENDED_STATUS, vra | 0x1); 1050 snd_soc_update_bits(codec, AC97_PCI_SID, 0x8000, 0x8000);
1036 xsle = ac97_read(codec, AC97_PCI_SID);
1037 ac97_write(codec, AC97_PCI_SID, xsle | 0x8000);
1038 1051
1039 if (substream->stream != SNDRV_PCM_STREAM_PLAYBACK) 1052 if (substream->stream != SNDRV_PCM_STREAM_PLAYBACK)
1040 return -ENODEV; 1053 return -ENODEV;
1041 1054
1042 return ac97_write(codec, AC97_PCM_SURR_DAC_RATE, runtime->rate); 1055 return snd_soc_write(codec, AC97_PCM_SURR_DAC_RATE, runtime->rate);
1043} 1056}
1044 1057
1045#define WM9713_RATES (SNDRV_PCM_RATE_8000 | \ 1058#define WM9713_RATES (SNDRV_PCM_RATE_8000 | \
@@ -1128,27 +1141,23 @@ static struct snd_soc_dai_driver wm9713_dai[] = {
1128static int wm9713_set_bias_level(struct snd_soc_codec *codec, 1141static int wm9713_set_bias_level(struct snd_soc_codec *codec,
1129 enum snd_soc_bias_level level) 1142 enum snd_soc_bias_level level)
1130{ 1143{
1131 u16 reg;
1132
1133 switch (level) { 1144 switch (level) {
1134 case SND_SOC_BIAS_ON: 1145 case SND_SOC_BIAS_ON:
1135 /* enable thermal shutdown */ 1146 /* enable thermal shutdown */
1136 reg = ac97_read(codec, AC97_EXTENDED_MID) & 0x1bff; 1147 snd_soc_update_bits(codec, AC97_EXTENDED_MID, 0xe400, 0x0000);
1137 ac97_write(codec, AC97_EXTENDED_MID, reg);
1138 break; 1148 break;
1139 case SND_SOC_BIAS_PREPARE: 1149 case SND_SOC_BIAS_PREPARE:
1140 break; 1150 break;
1141 case SND_SOC_BIAS_STANDBY: 1151 case SND_SOC_BIAS_STANDBY:
1142 /* enable master bias and vmid */ 1152 /* enable master bias and vmid */
1143 reg = ac97_read(codec, AC97_EXTENDED_MID) & 0x3bff; 1153 snd_soc_update_bits(codec, AC97_EXTENDED_MID, 0xc400, 0x0000);
1144 ac97_write(codec, AC97_EXTENDED_MID, reg); 1154 snd_soc_write(codec, AC97_POWERDOWN, 0x0000);
1145 ac97_write(codec, AC97_POWERDOWN, 0x0000);
1146 break; 1155 break;
1147 case SND_SOC_BIAS_OFF: 1156 case SND_SOC_BIAS_OFF:
1148 /* disable everything including AC link */ 1157 /* disable everything including AC link */
1149 ac97_write(codec, AC97_EXTENDED_MID, 0xffff); 1158 snd_soc_write(codec, AC97_EXTENDED_MID, 0xffff);
1150 ac97_write(codec, AC97_EXTENDED_MSTATUS, 0xffff); 1159 snd_soc_write(codec, AC97_EXTENDED_MSTATUS, 0xffff);
1151 ac97_write(codec, AC97_POWERDOWN, 0xffff); 1160 snd_soc_write(codec, AC97_POWERDOWN, 0xffff);
1152 break; 1161 break;
1153 } 1162 }
1154 return 0; 1163 return 0;
@@ -1156,16 +1165,14 @@ static int wm9713_set_bias_level(struct snd_soc_codec *codec,
1156 1165
1157static int wm9713_soc_suspend(struct snd_soc_codec *codec) 1166static int wm9713_soc_suspend(struct snd_soc_codec *codec)
1158{ 1167{
1159 u16 reg;
1160
1161 /* Disable everything except touchpanel - that will be handled 1168 /* Disable everything except touchpanel - that will be handled
1162 * by the touch driver and left disabled if touch is not in 1169 * by the touch driver and left disabled if touch is not in
1163 * use. */ 1170 * use. */
1164 reg = ac97_read(codec, AC97_EXTENDED_MID); 1171 snd_soc_update_bits(codec, AC97_EXTENDED_MID, 0x7fff,
1165 ac97_write(codec, AC97_EXTENDED_MID, reg | 0x7fff); 1172 0x7fff);
1166 ac97_write(codec, AC97_EXTENDED_MSTATUS, 0xffff); 1173 snd_soc_write(codec, AC97_EXTENDED_MSTATUS, 0xffff);
1167 ac97_write(codec, AC97_POWERDOWN, 0x6f00); 1174 snd_soc_write(codec, AC97_POWERDOWN, 0x6f00);
1168 ac97_write(codec, AC97_POWERDOWN, 0xffff); 1175 snd_soc_write(codec, AC97_POWERDOWN, 0xffff);
1169 1176
1170 return 0; 1177 return 0;
1171} 1178}
@@ -1173,8 +1180,7 @@ static int wm9713_soc_suspend(struct snd_soc_codec *codec)
1173static int wm9713_soc_resume(struct snd_soc_codec *codec) 1180static int wm9713_soc_resume(struct snd_soc_codec *codec)
1174{ 1181{
1175 struct wm9713_priv *wm9713 = snd_soc_codec_get_drvdata(codec); 1182 struct wm9713_priv *wm9713 = snd_soc_codec_get_drvdata(codec);
1176 int i, ret; 1183 int ret;
1177 u16 *cache = codec->reg_cache;
1178 1184
1179 ret = snd_ac97_reset(wm9713->ac97, true, WM9713_VENDOR_ID, 1185 ret = snd_ac97_reset(wm9713->ac97, true, WM9713_VENDOR_ID,
1180 WM9713_VENDOR_ID_MASK); 1186 WM9713_VENDOR_ID_MASK);
@@ -1189,12 +1195,8 @@ static int wm9713_soc_resume(struct snd_soc_codec *codec)
1189 1195
1190 /* only synchronise the codec if warm reset failed */ 1196 /* only synchronise the codec if warm reset failed */
1191 if (ret == 0) { 1197 if (ret == 0) {
1192 for (i = 2; i < ARRAY_SIZE(wm9713_reg) << 1; i += 2) { 1198 regcache_mark_dirty(codec->component.regmap);
1193 if (i == AC97_POWERDOWN || i == AC97_EXTENDED_MID || 1199 snd_soc_cache_sync(codec);
1194 i == AC97_EXTENDED_MSTATUS || i > 0x66)
1195 continue;
1196 soc_ac97_ops->write(wm9713->ac97, i, cache[i>>1]);
1197 }
1198 } 1200 }
1199 1201
1200 return ret; 1202 return ret;
@@ -1203,16 +1205,23 @@ static int wm9713_soc_resume(struct snd_soc_codec *codec)
1203static int wm9713_soc_probe(struct snd_soc_codec *codec) 1205static int wm9713_soc_probe(struct snd_soc_codec *codec)
1204{ 1206{
1205 struct wm9713_priv *wm9713 = snd_soc_codec_get_drvdata(codec); 1207 struct wm9713_priv *wm9713 = snd_soc_codec_get_drvdata(codec);
1206 int reg; 1208 struct regmap *regmap;
1207 1209
1208 wm9713->ac97 = snd_soc_new_ac97_codec(codec, WM9713_VENDOR_ID, 1210 wm9713->ac97 = snd_soc_new_ac97_codec(codec, WM9713_VENDOR_ID,
1209 WM9713_VENDOR_ID_MASK); 1211 WM9713_VENDOR_ID_MASK);
1210 if (IS_ERR(wm9713->ac97)) 1212 if (IS_ERR(wm9713->ac97))
1211 return PTR_ERR(wm9713->ac97); 1213 return PTR_ERR(wm9713->ac97);
1212 1214
1215 regmap = devm_regmap_init_ac97(wm9713->ac97, &wm9713_regmap_config);
1216 if (IS_ERR(regmap)) {
1217 snd_soc_free_ac97_codec(wm9713->ac97);
1218 return PTR_ERR(regmap);
1219 }
1220
1221 snd_soc_codec_init_regmap(codec, regmap);
1222
1213 /* unmute the adc - move to kcontrol */ 1223 /* unmute the adc - move to kcontrol */
1214 reg = ac97_read(codec, AC97_CD) & 0x7fff; 1224 snd_soc_update_bits(codec, AC97_CD, 0x7fff, 0x0000);
1215 ac97_write(codec, AC97_CD, reg);
1216 1225
1217 return 0; 1226 return 0;
1218} 1227}
@@ -1221,6 +1230,7 @@ static int wm9713_soc_remove(struct snd_soc_codec *codec)
1221{ 1230{
1222 struct wm9713_priv *wm9713 = snd_soc_codec_get_drvdata(codec); 1231 struct wm9713_priv *wm9713 = snd_soc_codec_get_drvdata(codec);
1223 1232
1233 snd_soc_codec_exit_regmap(codec);
1224 snd_soc_free_ac97_codec(wm9713->ac97); 1234 snd_soc_free_ac97_codec(wm9713->ac97);
1225 return 0; 1235 return 0;
1226} 1236}
@@ -1230,13 +1240,7 @@ static struct snd_soc_codec_driver soc_codec_dev_wm9713 = {
1230 .remove = wm9713_soc_remove, 1240 .remove = wm9713_soc_remove,
1231 .suspend = wm9713_soc_suspend, 1241 .suspend = wm9713_soc_suspend,
1232 .resume = wm9713_soc_resume, 1242 .resume = wm9713_soc_resume,
1233 .read = ac97_read,
1234 .write = ac97_write,
1235 .set_bias_level = wm9713_set_bias_level, 1243 .set_bias_level = wm9713_set_bias_level,
1236 .reg_cache_size = ARRAY_SIZE(wm9713_reg),
1237 .reg_word_size = sizeof(u16),
1238 .reg_cache_step = 2,
1239 .reg_cache_default = wm9713_reg,
1240 1244
1241 .controls = wm9713_snd_ac97_controls, 1245 .controls = wm9713_snd_ac97_controls,
1242 .num_controls = ARRAY_SIZE(wm9713_snd_ac97_controls), 1246 .num_controls = ARRAY_SIZE(wm9713_snd_ac97_controls),
diff --git a/sound/soc/codecs/wm_adsp.c b/sound/soc/codecs/wm_adsp.c
index 0bb415a28723..33806d487b8a 100644
--- a/sound/soc/codecs/wm_adsp.c
+++ b/sound/soc/codecs/wm_adsp.c
@@ -201,27 +201,194 @@ static void wm_adsp_buf_free(struct list_head *list)
201 } 201 }
202} 202}
203 203
204#define WM_ADSP_NUM_FW 4 204#define WM_ADSP_FW_MBC_VSS 0
205 205#define WM_ADSP_FW_HIFI 1
206#define WM_ADSP_FW_MBC_VSS 0 206#define WM_ADSP_FW_TX 2
207#define WM_ADSP_FW_TX 1 207#define WM_ADSP_FW_TX_SPK 3
208#define WM_ADSP_FW_TX_SPK 2 208#define WM_ADSP_FW_RX 4
209#define WM_ADSP_FW_RX_ANC 3 209#define WM_ADSP_FW_RX_ANC 5
210#define WM_ADSP_FW_CTRL 6
211#define WM_ADSP_FW_ASR 7
212#define WM_ADSP_FW_TRACE 8
213#define WM_ADSP_FW_SPK_PROT 9
214#define WM_ADSP_FW_MISC 10
215
216#define WM_ADSP_NUM_FW 11
210 217
211static const char *wm_adsp_fw_text[WM_ADSP_NUM_FW] = { 218static const char *wm_adsp_fw_text[WM_ADSP_NUM_FW] = {
212 [WM_ADSP_FW_MBC_VSS] = "MBC/VSS", 219 [WM_ADSP_FW_MBC_VSS] = "MBC/VSS",
213 [WM_ADSP_FW_TX] = "Tx", 220 [WM_ADSP_FW_HIFI] = "MasterHiFi",
214 [WM_ADSP_FW_TX_SPK] = "Tx Speaker", 221 [WM_ADSP_FW_TX] = "Tx",
215 [WM_ADSP_FW_RX_ANC] = "Rx ANC", 222 [WM_ADSP_FW_TX_SPK] = "Tx Speaker",
223 [WM_ADSP_FW_RX] = "Rx",
224 [WM_ADSP_FW_RX_ANC] = "Rx ANC",
225 [WM_ADSP_FW_CTRL] = "Voice Ctrl",
226 [WM_ADSP_FW_ASR] = "ASR Assist",
227 [WM_ADSP_FW_TRACE] = "Dbg Trace",
228 [WM_ADSP_FW_SPK_PROT] = "Protection",
229 [WM_ADSP_FW_MISC] = "Misc",
230};
231
232struct wm_adsp_system_config_xm_hdr {
233 __be32 sys_enable;
234 __be32 fw_id;
235 __be32 fw_rev;
236 __be32 boot_status;
237 __be32 watchdog;
238 __be32 dma_buffer_size;
239 __be32 rdma[6];
240 __be32 wdma[8];
241 __be32 build_job_name[3];
242 __be32 build_job_number;
243};
244
245struct wm_adsp_alg_xm_struct {
246 __be32 magic;
247 __be32 smoothing;
248 __be32 threshold;
249 __be32 host_buf_ptr;
250 __be32 start_seq;
251 __be32 high_water_mark;
252 __be32 low_water_mark;
253 __be64 smoothed_power;
254};
255
256struct wm_adsp_buffer {
257 __be32 X_buf_base; /* XM base addr of first X area */
258 __be32 X_buf_size; /* Size of 1st X area in words */
259 __be32 X_buf_base2; /* XM base addr of 2nd X area */
260 __be32 X_buf_brk; /* Total X size in words */
261 __be32 Y_buf_base; /* YM base addr of Y area */
262 __be32 wrap; /* Total size X and Y in words */
263 __be32 high_water_mark; /* Point at which IRQ is asserted */
264 __be32 irq_count; /* bits 1-31 count IRQ assertions */
265 __be32 irq_ack; /* acked IRQ count, bit 0 enables IRQ */
266 __be32 next_write_index; /* word index of next write */
267 __be32 next_read_index; /* word index of next read */
268 __be32 error; /* error if any */
269 __be32 oldest_block_index; /* word index of oldest surviving */
270 __be32 requested_rewind; /* how many blocks rewind was done */
271 __be32 reserved_space; /* internal */
272 __be32 min_free; /* min free space since stream start */
273 __be32 blocks_written[2]; /* total blocks written (64 bit) */
274 __be32 words_written[2]; /* total words written (64 bit) */
275};
276
277struct wm_adsp_compr_buf {
278 struct wm_adsp *dsp;
279
280 struct wm_adsp_buffer_region *regions;
281 u32 host_buf_ptr;
282
283 u32 error;
284 u32 irq_count;
285 int read_index;
286 int avail;
287};
288
289struct wm_adsp_compr {
290 struct wm_adsp *dsp;
291 struct wm_adsp_compr_buf *buf;
292
293 struct snd_compr_stream *stream;
294 struct snd_compressed_buffer size;
295
296 u32 *raw_buf;
297 unsigned int copied_total;
298};
299
300#define WM_ADSP_DATA_WORD_SIZE 3
301
302#define WM_ADSP_MIN_FRAGMENTS 1
303#define WM_ADSP_MAX_FRAGMENTS 256
304#define WM_ADSP_MIN_FRAGMENT_SIZE (64 * WM_ADSP_DATA_WORD_SIZE)
305#define WM_ADSP_MAX_FRAGMENT_SIZE (4096 * WM_ADSP_DATA_WORD_SIZE)
306
307#define WM_ADSP_ALG_XM_STRUCT_MAGIC 0x49aec7
308
309#define HOST_BUFFER_FIELD(field) \
310 (offsetof(struct wm_adsp_buffer, field) / sizeof(__be32))
311
312#define ALG_XM_FIELD(field) \
313 (offsetof(struct wm_adsp_alg_xm_struct, field) / sizeof(__be32))
314
315static int wm_adsp_buffer_init(struct wm_adsp *dsp);
316static int wm_adsp_buffer_free(struct wm_adsp *dsp);
317
318struct wm_adsp_buffer_region {
319 unsigned int offset;
320 unsigned int cumulative_size;
321 unsigned int mem_type;
322 unsigned int base_addr;
323};
324
325struct wm_adsp_buffer_region_def {
326 unsigned int mem_type;
327 unsigned int base_offset;
328 unsigned int size_offset;
216}; 329};
217 330
218static struct { 331static struct wm_adsp_buffer_region_def ez2control_regions[] = {
332 {
333 .mem_type = WMFW_ADSP2_XM,
334 .base_offset = HOST_BUFFER_FIELD(X_buf_base),
335 .size_offset = HOST_BUFFER_FIELD(X_buf_size),
336 },
337 {
338 .mem_type = WMFW_ADSP2_XM,
339 .base_offset = HOST_BUFFER_FIELD(X_buf_base2),
340 .size_offset = HOST_BUFFER_FIELD(X_buf_brk),
341 },
342 {
343 .mem_type = WMFW_ADSP2_YM,
344 .base_offset = HOST_BUFFER_FIELD(Y_buf_base),
345 .size_offset = HOST_BUFFER_FIELD(wrap),
346 },
347};
348
349struct wm_adsp_fw_caps {
350 u32 id;
351 struct snd_codec_desc desc;
352 int num_regions;
353 struct wm_adsp_buffer_region_def *region_defs;
354};
355
356static const struct wm_adsp_fw_caps ez2control_caps[] = {
357 {
358 .id = SND_AUDIOCODEC_BESPOKE,
359 .desc = {
360 .max_ch = 1,
361 .sample_rates = { 16000 },
362 .num_sample_rates = 1,
363 .formats = SNDRV_PCM_FMTBIT_S16_LE,
364 },
365 .num_regions = ARRAY_SIZE(ez2control_regions),
366 .region_defs = ez2control_regions,
367 },
368};
369
370static const struct {
219 const char *file; 371 const char *file;
372 int compr_direction;
373 int num_caps;
374 const struct wm_adsp_fw_caps *caps;
220} wm_adsp_fw[WM_ADSP_NUM_FW] = { 375} wm_adsp_fw[WM_ADSP_NUM_FW] = {
221 [WM_ADSP_FW_MBC_VSS] = { .file = "mbc-vss" }, 376 [WM_ADSP_FW_MBC_VSS] = { .file = "mbc-vss" },
222 [WM_ADSP_FW_TX] = { .file = "tx" }, 377 [WM_ADSP_FW_HIFI] = { .file = "hifi" },
223 [WM_ADSP_FW_TX_SPK] = { .file = "tx-spk" }, 378 [WM_ADSP_FW_TX] = { .file = "tx" },
224 [WM_ADSP_FW_RX_ANC] = { .file = "rx-anc" }, 379 [WM_ADSP_FW_TX_SPK] = { .file = "tx-spk" },
380 [WM_ADSP_FW_RX] = { .file = "rx" },
381 [WM_ADSP_FW_RX_ANC] = { .file = "rx-anc" },
382 [WM_ADSP_FW_CTRL] = {
383 .file = "ctrl",
384 .compr_direction = SND_COMPRESS_CAPTURE,
385 .num_caps = ARRAY_SIZE(ez2control_caps),
386 .caps = ez2control_caps,
387 },
388 [WM_ADSP_FW_ASR] = { .file = "asr" },
389 [WM_ADSP_FW_TRACE] = { .file = "trace" },
390 [WM_ADSP_FW_SPK_PROT] = { .file = "spk-prot" },
391 [WM_ADSP_FW_MISC] = { .file = "misc" },
225}; 392};
226 393
227struct wm_coeff_ctl_ops { 394struct wm_coeff_ctl_ops {
@@ -254,30 +421,24 @@ static void wm_adsp_debugfs_save_wmfwname(struct wm_adsp *dsp, const char *s)
254{ 421{
255 char *tmp = kasprintf(GFP_KERNEL, "%s\n", s); 422 char *tmp = kasprintf(GFP_KERNEL, "%s\n", s);
256 423
257 mutex_lock(&dsp->debugfs_lock);
258 kfree(dsp->wmfw_file_name); 424 kfree(dsp->wmfw_file_name);
259 dsp->wmfw_file_name = tmp; 425 dsp->wmfw_file_name = tmp;
260 mutex_unlock(&dsp->debugfs_lock);
261} 426}
262 427
263static void wm_adsp_debugfs_save_binname(struct wm_adsp *dsp, const char *s) 428static void wm_adsp_debugfs_save_binname(struct wm_adsp *dsp, const char *s)
264{ 429{
265 char *tmp = kasprintf(GFP_KERNEL, "%s\n", s); 430 char *tmp = kasprintf(GFP_KERNEL, "%s\n", s);
266 431
267 mutex_lock(&dsp->debugfs_lock);
268 kfree(dsp->bin_file_name); 432 kfree(dsp->bin_file_name);
269 dsp->bin_file_name = tmp; 433 dsp->bin_file_name = tmp;
270 mutex_unlock(&dsp->debugfs_lock);
271} 434}
272 435
273static void wm_adsp_debugfs_clear(struct wm_adsp *dsp) 436static void wm_adsp_debugfs_clear(struct wm_adsp *dsp)
274{ 437{
275 mutex_lock(&dsp->debugfs_lock);
276 kfree(dsp->wmfw_file_name); 438 kfree(dsp->wmfw_file_name);
277 kfree(dsp->bin_file_name); 439 kfree(dsp->bin_file_name);
278 dsp->wmfw_file_name = NULL; 440 dsp->wmfw_file_name = NULL;
279 dsp->bin_file_name = NULL; 441 dsp->bin_file_name = NULL;
280 mutex_unlock(&dsp->debugfs_lock);
281} 442}
282 443
283static ssize_t wm_adsp_debugfs_wmfw_read(struct file *file, 444static ssize_t wm_adsp_debugfs_wmfw_read(struct file *file,
@@ -287,7 +448,7 @@ static ssize_t wm_adsp_debugfs_wmfw_read(struct file *file,
287 struct wm_adsp *dsp = file->private_data; 448 struct wm_adsp *dsp = file->private_data;
288 ssize_t ret; 449 ssize_t ret;
289 450
290 mutex_lock(&dsp->debugfs_lock); 451 mutex_lock(&dsp->pwr_lock);
291 452
292 if (!dsp->wmfw_file_name || !dsp->running) 453 if (!dsp->wmfw_file_name || !dsp->running)
293 ret = 0; 454 ret = 0;
@@ -296,7 +457,7 @@ static ssize_t wm_adsp_debugfs_wmfw_read(struct file *file,
296 dsp->wmfw_file_name, 457 dsp->wmfw_file_name,
297 strlen(dsp->wmfw_file_name)); 458 strlen(dsp->wmfw_file_name));
298 459
299 mutex_unlock(&dsp->debugfs_lock); 460 mutex_unlock(&dsp->pwr_lock);
300 return ret; 461 return ret;
301} 462}
302 463
@@ -307,7 +468,7 @@ static ssize_t wm_adsp_debugfs_bin_read(struct file *file,
307 struct wm_adsp *dsp = file->private_data; 468 struct wm_adsp *dsp = file->private_data;
308 ssize_t ret; 469 ssize_t ret;
309 470
310 mutex_lock(&dsp->debugfs_lock); 471 mutex_lock(&dsp->pwr_lock);
311 472
312 if (!dsp->bin_file_name || !dsp->running) 473 if (!dsp->bin_file_name || !dsp->running)
313 ret = 0; 474 ret = 0;
@@ -316,7 +477,7 @@ static ssize_t wm_adsp_debugfs_bin_read(struct file *file,
316 dsp->bin_file_name, 477 dsp->bin_file_name,
317 strlen(dsp->bin_file_name)); 478 strlen(dsp->bin_file_name));
318 479
319 mutex_unlock(&dsp->debugfs_lock); 480 mutex_unlock(&dsp->pwr_lock);
320 return ret; 481 return ret;
321} 482}
322 483
@@ -436,6 +597,7 @@ static int wm_adsp_fw_put(struct snd_kcontrol *kcontrol,
436 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); 597 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
437 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; 598 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
438 struct wm_adsp *dsp = snd_soc_codec_get_drvdata(codec); 599 struct wm_adsp *dsp = snd_soc_codec_get_drvdata(codec);
600 int ret = 0;
439 601
440 if (ucontrol->value.integer.value[0] == dsp[e->shift_l].fw) 602 if (ucontrol->value.integer.value[0] == dsp[e->shift_l].fw)
441 return 0; 603 return 0;
@@ -443,12 +605,16 @@ static int wm_adsp_fw_put(struct snd_kcontrol *kcontrol,
443 if (ucontrol->value.integer.value[0] >= WM_ADSP_NUM_FW) 605 if (ucontrol->value.integer.value[0] >= WM_ADSP_NUM_FW)
444 return -EINVAL; 606 return -EINVAL;
445 607
446 if (dsp[e->shift_l].running) 608 mutex_lock(&dsp[e->shift_l].pwr_lock);
447 return -EBUSY;
448 609
449 dsp[e->shift_l].fw = ucontrol->value.integer.value[0]; 610 if (dsp[e->shift_l].running || dsp[e->shift_l].compr)
611 ret = -EBUSY;
612 else
613 dsp[e->shift_l].fw = ucontrol->value.integer.value[0];
450 614
451 return 0; 615 mutex_unlock(&dsp[e->shift_l].pwr_lock);
616
617 return ret;
452} 618}
453 619
454static const struct soc_enum wm_adsp_fw_enum[] = { 620static const struct soc_enum wm_adsp_fw_enum[] = {
@@ -523,10 +689,10 @@ static void wm_adsp2_show_fw_status(struct wm_adsp *dsp)
523 be16_to_cpu(scratch[3])); 689 be16_to_cpu(scratch[3]));
524} 690}
525 691
526static int wm_coeff_info(struct snd_kcontrol *kcontrol, 692static int wm_coeff_info(struct snd_kcontrol *kctl,
527 struct snd_ctl_elem_info *uinfo) 693 struct snd_ctl_elem_info *uinfo)
528{ 694{
529 struct wm_coeff_ctl *ctl = (struct wm_coeff_ctl *)kcontrol->private_value; 695 struct wm_coeff_ctl *ctl = (struct wm_coeff_ctl *)kctl->private_value;
530 696
531 uinfo->type = SNDRV_CTL_ELEM_TYPE_BYTES; 697 uinfo->type = SNDRV_CTL_ELEM_TYPE_BYTES;
532 uinfo->count = ctl->len; 698 uinfo->count = ctl->len;
@@ -572,19 +738,24 @@ static int wm_coeff_write_control(struct wm_coeff_ctl *ctl,
572 return 0; 738 return 0;
573} 739}
574 740
575static int wm_coeff_put(struct snd_kcontrol *kcontrol, 741static int wm_coeff_put(struct snd_kcontrol *kctl,
576 struct snd_ctl_elem_value *ucontrol) 742 struct snd_ctl_elem_value *ucontrol)
577{ 743{
578 struct wm_coeff_ctl *ctl = (struct wm_coeff_ctl *)kcontrol->private_value; 744 struct wm_coeff_ctl *ctl = (struct wm_coeff_ctl *)kctl->private_value;
579 char *p = ucontrol->value.bytes.data; 745 char *p = ucontrol->value.bytes.data;
746 int ret = 0;
747
748 mutex_lock(&ctl->dsp->pwr_lock);
580 749
581 memcpy(ctl->cache, p, ctl->len); 750 memcpy(ctl->cache, p, ctl->len);
582 751
583 ctl->set = 1; 752 ctl->set = 1;
584 if (!ctl->enabled) 753 if (ctl->enabled)
585 return 0; 754 ret = wm_coeff_write_control(ctl, p, ctl->len);
755
756 mutex_unlock(&ctl->dsp->pwr_lock);
586 757
587 return wm_coeff_write_control(ctl, p, ctl->len); 758 return ret;
588} 759}
589 760
590static int wm_coeff_read_control(struct wm_coeff_ctl *ctl, 761static int wm_coeff_read_control(struct wm_coeff_ctl *ctl,
@@ -626,22 +797,30 @@ static int wm_coeff_read_control(struct wm_coeff_ctl *ctl,
626 return 0; 797 return 0;
627} 798}
628 799
629static int wm_coeff_get(struct snd_kcontrol *kcontrol, 800static int wm_coeff_get(struct snd_kcontrol *kctl,
630 struct snd_ctl_elem_value *ucontrol) 801 struct snd_ctl_elem_value *ucontrol)
631{ 802{
632 struct wm_coeff_ctl *ctl = (struct wm_coeff_ctl *)kcontrol->private_value; 803 struct wm_coeff_ctl *ctl = (struct wm_coeff_ctl *)kctl->private_value;
633 char *p = ucontrol->value.bytes.data; 804 char *p = ucontrol->value.bytes.data;
805 int ret = 0;
806
807 mutex_lock(&ctl->dsp->pwr_lock);
634 808
635 if (ctl->flags & WMFW_CTL_FLAG_VOLATILE) { 809 if (ctl->flags & WMFW_CTL_FLAG_VOLATILE) {
636 if (ctl->enabled) 810 if (ctl->enabled)
637 return wm_coeff_read_control(ctl, p, ctl->len); 811 ret = wm_coeff_read_control(ctl, p, ctl->len);
638 else 812 else
639 return -EPERM; 813 ret = -EPERM;
814 } else {
815 if (!ctl->flags && ctl->enabled)
816 ret = wm_coeff_read_control(ctl, ctl->cache, ctl->len);
817
818 memcpy(p, ctl->cache, ctl->len);
640 } 819 }
641 820
642 memcpy(p, ctl->cache, ctl->len); 821 mutex_unlock(&ctl->dsp->pwr_lock);
643 822
644 return 0; 823 return ret;
645} 824}
646 825
647struct wmfw_ctl_work { 826struct wmfw_ctl_work {
@@ -808,8 +987,7 @@ static int wm_adsp_create_control(struct wm_adsp *dsp,
808 break; 987 break;
809 } 988 }
810 989
811 list_for_each_entry(ctl, &dsp->ctl_list, 990 list_for_each_entry(ctl, &dsp->ctl_list, list) {
812 list) {
813 if (!strcmp(ctl->name, name)) { 991 if (!strcmp(ctl->name, name)) {
814 if (!ctl->enabled) 992 if (!ctl->enabled)
815 ctl->enabled = 1; 993 ctl->enabled = 1;
@@ -1088,7 +1266,7 @@ static int wm_adsp_load(struct wm_adsp *dsp)
1088 goto out_fw; 1266 goto out_fw;
1089 } 1267 }
1090 1268
1091 header = (void*)&firmware->data[0]; 1269 header = (void *)&firmware->data[0];
1092 1270
1093 if (memcmp(&header->magic[0], "WMFW", 4) != 0) { 1271 if (memcmp(&header->magic[0], "WMFW", 4) != 0) {
1094 adsp_err(dsp, "%s: invalid magic\n", file); 1272 adsp_err(dsp, "%s: invalid magic\n", file);
@@ -1168,7 +1346,7 @@ static int wm_adsp_load(struct wm_adsp *dsp)
1168 offset = le32_to_cpu(region->offset) & 0xffffff; 1346 offset = le32_to_cpu(region->offset) & 0xffffff;
1169 type = be32_to_cpu(region->type) & 0xff; 1347 type = be32_to_cpu(region->type) & 0xff;
1170 mem = wm_adsp_find_region(dsp, type); 1348 mem = wm_adsp_find_region(dsp, type);
1171 1349
1172 switch (type) { 1350 switch (type) {
1173 case WMFW_NAME_TEXT: 1351 case WMFW_NAME_TEXT:
1174 region_name = "Firmware name"; 1352 region_name = "Firmware name";
@@ -1333,6 +1511,19 @@ static void *wm_adsp_read_algs(struct wm_adsp *dsp, size_t n_algs,
1333 return alg; 1511 return alg;
1334} 1512}
1335 1513
1514static struct wm_adsp_alg_region *
1515 wm_adsp_find_alg_region(struct wm_adsp *dsp, int type, unsigned int id)
1516{
1517 struct wm_adsp_alg_region *alg_region;
1518
1519 list_for_each_entry(alg_region, &dsp->alg_regions, list) {
1520 if (id == alg_region->alg && type == alg_region->type)
1521 return alg_region;
1522 }
1523
1524 return NULL;
1525}
1526
1336static struct wm_adsp_alg_region *wm_adsp_create_region(struct wm_adsp *dsp, 1527static struct wm_adsp_alg_region *wm_adsp_create_region(struct wm_adsp *dsp,
1337 int type, __be32 id, 1528 int type, __be32 id,
1338 __be32 base) 1529 __be32 base)
@@ -1625,7 +1816,7 @@ static int wm_adsp_load_coeff(struct wm_adsp *dsp)
1625 goto out_fw; 1816 goto out_fw;
1626 } 1817 }
1627 1818
1628 hdr = (void*)&firmware->data[0]; 1819 hdr = (void *)&firmware->data[0];
1629 if (memcmp(hdr->magic, "WMDR", 4) != 0) { 1820 if (memcmp(hdr->magic, "WMDR", 4) != 0) {
1630 adsp_err(dsp, "%s: invalid magic\n", file); 1821 adsp_err(dsp, "%s: invalid magic\n", file);
1631 goto out_fw; 1822 goto out_fw;
@@ -1651,7 +1842,7 @@ static int wm_adsp_load_coeff(struct wm_adsp *dsp)
1651 blocks = 0; 1842 blocks = 0;
1652 while (pos < firmware->size && 1843 while (pos < firmware->size &&
1653 pos - firmware->size > sizeof(*blk)) { 1844 pos - firmware->size > sizeof(*blk)) {
1654 blk = (void*)(&firmware->data[pos]); 1845 blk = (void *)(&firmware->data[pos]);
1655 1846
1656 type = le16_to_cpu(blk->type); 1847 type = le16_to_cpu(blk->type);
1657 offset = le16_to_cpu(blk->offset); 1848 offset = le16_to_cpu(blk->offset);
@@ -1705,22 +1896,16 @@ static int wm_adsp_load_coeff(struct wm_adsp *dsp)
1705 break; 1896 break;
1706 } 1897 }
1707 1898
1708 reg = 0; 1899 alg_region = wm_adsp_find_alg_region(dsp, type,
1709 list_for_each_entry(alg_region, 1900 le32_to_cpu(blk->id));
1710 &dsp->alg_regions, list) { 1901 if (alg_region) {
1711 if (le32_to_cpu(blk->id) == alg_region->alg && 1902 reg = alg_region->base;
1712 type == alg_region->type) { 1903 reg = wm_adsp_region_to_reg(mem, reg);
1713 reg = alg_region->base; 1904 reg += offset;
1714 reg = wm_adsp_region_to_reg(mem, 1905 } else {
1715 reg);
1716 reg += offset;
1717 break;
1718 }
1719 }
1720
1721 if (reg == 0)
1722 adsp_err(dsp, "No %x for algorithm %x\n", 1906 adsp_err(dsp, "No %x for algorithm %x\n",
1723 type, le32_to_cpu(blk->id)); 1907 type, le32_to_cpu(blk->id));
1908 }
1724 break; 1909 break;
1725 1910
1726 default: 1911 default:
@@ -1778,9 +1963,8 @@ int wm_adsp1_init(struct wm_adsp *dsp)
1778{ 1963{
1779 INIT_LIST_HEAD(&dsp->alg_regions); 1964 INIT_LIST_HEAD(&dsp->alg_regions);
1780 1965
1781#ifdef CONFIG_DEBUG_FS 1966 mutex_init(&dsp->pwr_lock);
1782 mutex_init(&dsp->debugfs_lock); 1967
1783#endif
1784 return 0; 1968 return 0;
1785} 1969}
1786EXPORT_SYMBOL_GPL(wm_adsp1_init); 1970EXPORT_SYMBOL_GPL(wm_adsp1_init);
@@ -1795,10 +1979,12 @@ int wm_adsp1_event(struct snd_soc_dapm_widget *w,
1795 struct wm_adsp_alg_region *alg_region; 1979 struct wm_adsp_alg_region *alg_region;
1796 struct wm_coeff_ctl *ctl; 1980 struct wm_coeff_ctl *ctl;
1797 int ret; 1981 int ret;
1798 int val; 1982 unsigned int val;
1799 1983
1800 dsp->card = codec->component.card; 1984 dsp->card = codec->component.card;
1801 1985
1986 mutex_lock(&dsp->pwr_lock);
1987
1802 switch (event) { 1988 switch (event) {
1803 case SND_SOC_DAPM_POST_PMU: 1989 case SND_SOC_DAPM_POST_PMU:
1804 regmap_update_bits(dsp->regmap, dsp->base + ADSP1_CONTROL_30, 1990 regmap_update_bits(dsp->regmap, dsp->base + ADSP1_CONTROL_30,
@@ -1808,12 +1994,12 @@ int wm_adsp1_event(struct snd_soc_dapm_widget *w,
1808 * For simplicity set the DSP clock rate to be the 1994 * For simplicity set the DSP clock rate to be the
1809 * SYSCLK rate rather than making it configurable. 1995 * SYSCLK rate rather than making it configurable.
1810 */ 1996 */
1811 if(dsp->sysclk_reg) { 1997 if (dsp->sysclk_reg) {
1812 ret = regmap_read(dsp->regmap, dsp->sysclk_reg, &val); 1998 ret = regmap_read(dsp->regmap, dsp->sysclk_reg, &val);
1813 if (ret != 0) { 1999 if (ret != 0) {
1814 adsp_err(dsp, "Failed to read SYSCLK state: %d\n", 2000 adsp_err(dsp, "Failed to read SYSCLK state: %d\n",
1815 ret); 2001 ret);
1816 return ret; 2002 goto err_mutex;
1817 } 2003 }
1818 2004
1819 val = (val & dsp->sysclk_mask) 2005 val = (val & dsp->sysclk_mask)
@@ -1825,31 +2011,31 @@ int wm_adsp1_event(struct snd_soc_dapm_widget *w,
1825 if (ret != 0) { 2011 if (ret != 0) {
1826 adsp_err(dsp, "Failed to set clock rate: %d\n", 2012 adsp_err(dsp, "Failed to set clock rate: %d\n",
1827 ret); 2013 ret);
1828 return ret; 2014 goto err_mutex;
1829 } 2015 }
1830 } 2016 }
1831 2017
1832 ret = wm_adsp_load(dsp); 2018 ret = wm_adsp_load(dsp);
1833 if (ret != 0) 2019 if (ret != 0)
1834 goto err; 2020 goto err_ena;
1835 2021
1836 ret = wm_adsp1_setup_algs(dsp); 2022 ret = wm_adsp1_setup_algs(dsp);
1837 if (ret != 0) 2023 if (ret != 0)
1838 goto err; 2024 goto err_ena;
1839 2025
1840 ret = wm_adsp_load_coeff(dsp); 2026 ret = wm_adsp_load_coeff(dsp);
1841 if (ret != 0) 2027 if (ret != 0)
1842 goto err; 2028 goto err_ena;
1843 2029
1844 /* Initialize caches for enabled and unset controls */ 2030 /* Initialize caches for enabled and unset controls */
1845 ret = wm_coeff_init_control_caches(dsp); 2031 ret = wm_coeff_init_control_caches(dsp);
1846 if (ret != 0) 2032 if (ret != 0)
1847 goto err; 2033 goto err_ena;
1848 2034
1849 /* Sync set controls */ 2035 /* Sync set controls */
1850 ret = wm_coeff_sync_controls(dsp); 2036 ret = wm_coeff_sync_controls(dsp);
1851 if (ret != 0) 2037 if (ret != 0)
1852 goto err; 2038 goto err_ena;
1853 2039
1854 /* Start the core running */ 2040 /* Start the core running */
1855 regmap_update_bits(dsp->regmap, dsp->base + ADSP1_CONTROL_30, 2041 regmap_update_bits(dsp->regmap, dsp->base + ADSP1_CONTROL_30,
@@ -1884,11 +2070,16 @@ int wm_adsp1_event(struct snd_soc_dapm_widget *w,
1884 break; 2070 break;
1885 } 2071 }
1886 2072
2073 mutex_unlock(&dsp->pwr_lock);
2074
1887 return 0; 2075 return 0;
1888 2076
1889err: 2077err_ena:
1890 regmap_update_bits(dsp->regmap, dsp->base + ADSP1_CONTROL_30, 2078 regmap_update_bits(dsp->regmap, dsp->base + ADSP1_CONTROL_30,
1891 ADSP1_SYS_ENA, 0); 2079 ADSP1_SYS_ENA, 0);
2080err_mutex:
2081 mutex_unlock(&dsp->pwr_lock);
2082
1892 return ret; 2083 return ret;
1893} 2084}
1894EXPORT_SYMBOL_GPL(wm_adsp1_event); 2085EXPORT_SYMBOL_GPL(wm_adsp1_event);
@@ -1934,6 +2125,8 @@ static void wm_adsp2_boot_work(struct work_struct *work)
1934 int ret; 2125 int ret;
1935 unsigned int val; 2126 unsigned int val;
1936 2127
2128 mutex_lock(&dsp->pwr_lock);
2129
1937 /* 2130 /*
1938 * For simplicity set the DSP clock rate to be the 2131 * For simplicity set the DSP clock rate to be the
1939 * SYSCLK rate rather than making it configurable. 2132 * SYSCLK rate rather than making it configurable.
@@ -1941,7 +2134,7 @@ static void wm_adsp2_boot_work(struct work_struct *work)
1941 ret = regmap_read(dsp->regmap, ARIZONA_SYSTEM_CLOCK_1, &val); 2134 ret = regmap_read(dsp->regmap, ARIZONA_SYSTEM_CLOCK_1, &val);
1942 if (ret != 0) { 2135 if (ret != 0) {
1943 adsp_err(dsp, "Failed to read SYSCLK state: %d\n", ret); 2136 adsp_err(dsp, "Failed to read SYSCLK state: %d\n", ret);
1944 return; 2137 goto err_mutex;
1945 } 2138 }
1946 val = (val & ARIZONA_SYSCLK_FREQ_MASK) 2139 val = (val & ARIZONA_SYSCLK_FREQ_MASK)
1947 >> ARIZONA_SYSCLK_FREQ_SHIFT; 2140 >> ARIZONA_SYSCLK_FREQ_SHIFT;
@@ -1951,42 +2144,46 @@ static void wm_adsp2_boot_work(struct work_struct *work)
1951 ADSP2_CLK_SEL_MASK, val); 2144 ADSP2_CLK_SEL_MASK, val);
1952 if (ret != 0) { 2145 if (ret != 0) {
1953 adsp_err(dsp, "Failed to set clock rate: %d\n", ret); 2146 adsp_err(dsp, "Failed to set clock rate: %d\n", ret);
1954 return; 2147 goto err_mutex;
1955 } 2148 }
1956 2149
1957 ret = wm_adsp2_ena(dsp); 2150 ret = wm_adsp2_ena(dsp);
1958 if (ret != 0) 2151 if (ret != 0)
1959 return; 2152 goto err_mutex;
1960 2153
1961 ret = wm_adsp_load(dsp); 2154 ret = wm_adsp_load(dsp);
1962 if (ret != 0) 2155 if (ret != 0)
1963 goto err; 2156 goto err_ena;
1964 2157
1965 ret = wm_adsp2_setup_algs(dsp); 2158 ret = wm_adsp2_setup_algs(dsp);
1966 if (ret != 0) 2159 if (ret != 0)
1967 goto err; 2160 goto err_ena;
1968 2161
1969 ret = wm_adsp_load_coeff(dsp); 2162 ret = wm_adsp_load_coeff(dsp);
1970 if (ret != 0) 2163 if (ret != 0)
1971 goto err; 2164 goto err_ena;
1972 2165
1973 /* Initialize caches for enabled and unset controls */ 2166 /* Initialize caches for enabled and unset controls */
1974 ret = wm_coeff_init_control_caches(dsp); 2167 ret = wm_coeff_init_control_caches(dsp);
1975 if (ret != 0) 2168 if (ret != 0)
1976 goto err; 2169 goto err_ena;
1977 2170
1978 /* Sync set controls */ 2171 /* Sync set controls */
1979 ret = wm_coeff_sync_controls(dsp); 2172 ret = wm_coeff_sync_controls(dsp);
1980 if (ret != 0) 2173 if (ret != 0)
1981 goto err; 2174 goto err_ena;
1982 2175
1983 dsp->running = true; 2176 dsp->running = true;
1984 2177
2178 mutex_unlock(&dsp->pwr_lock);
2179
1985 return; 2180 return;
1986 2181
1987err: 2182err_ena:
1988 regmap_update_bits(dsp->regmap, dsp->base + ADSP2_CONTROL, 2183 regmap_update_bits(dsp->regmap, dsp->base + ADSP2_CONTROL,
1989 ADSP2_SYS_ENA | ADSP2_CORE_ENA | ADSP2_START, 0); 2184 ADSP2_SYS_ENA | ADSP2_CORE_ENA | ADSP2_START, 0);
2185err_mutex:
2186 mutex_unlock(&dsp->pwr_lock);
1990} 2187}
1991 2188
1992int wm_adsp2_early_event(struct snd_soc_dapm_widget *w, 2189int wm_adsp2_early_event(struct snd_soc_dapm_widget *w,
@@ -2033,12 +2230,18 @@ int wm_adsp2_event(struct snd_soc_dapm_widget *w,
2033 ADSP2_CORE_ENA | ADSP2_START); 2230 ADSP2_CORE_ENA | ADSP2_START);
2034 if (ret != 0) 2231 if (ret != 0)
2035 goto err; 2232 goto err;
2233
2234 if (wm_adsp_fw[dsp->fw].num_caps != 0)
2235 ret = wm_adsp_buffer_init(dsp);
2236
2036 break; 2237 break;
2037 2238
2038 case SND_SOC_DAPM_PRE_PMD: 2239 case SND_SOC_DAPM_PRE_PMD:
2039 /* Log firmware state, it can be useful for analysis */ 2240 /* Log firmware state, it can be useful for analysis */
2040 wm_adsp2_show_fw_status(dsp); 2241 wm_adsp2_show_fw_status(dsp);
2041 2242
2243 mutex_lock(&dsp->pwr_lock);
2244
2042 wm_adsp_debugfs_clear(dsp); 2245 wm_adsp_debugfs_clear(dsp);
2043 2246
2044 dsp->fw_id = 0; 2247 dsp->fw_id = 0;
@@ -2065,6 +2268,11 @@ int wm_adsp2_event(struct snd_soc_dapm_widget *w,
2065 kfree(alg_region); 2268 kfree(alg_region);
2066 } 2269 }
2067 2270
2271 if (wm_adsp_fw[dsp->fw].num_caps != 0)
2272 wm_adsp_buffer_free(dsp);
2273
2274 mutex_unlock(&dsp->pwr_lock);
2275
2068 adsp_dbg(dsp, "Shutdown complete\n"); 2276 adsp_dbg(dsp, "Shutdown complete\n");
2069 break; 2277 break;
2070 2278
@@ -2117,11 +2325,724 @@ int wm_adsp2_init(struct wm_adsp *dsp)
2117 INIT_LIST_HEAD(&dsp->ctl_list); 2325 INIT_LIST_HEAD(&dsp->ctl_list);
2118 INIT_WORK(&dsp->boot_work, wm_adsp2_boot_work); 2326 INIT_WORK(&dsp->boot_work, wm_adsp2_boot_work);
2119 2327
2120#ifdef CONFIG_DEBUG_FS 2328 mutex_init(&dsp->pwr_lock);
2121 mutex_init(&dsp->debugfs_lock); 2329
2122#endif
2123 return 0; 2330 return 0;
2124} 2331}
2125EXPORT_SYMBOL_GPL(wm_adsp2_init); 2332EXPORT_SYMBOL_GPL(wm_adsp2_init);
2126 2333
2334int wm_adsp_compr_open(struct wm_adsp *dsp, struct snd_compr_stream *stream)
2335{
2336 struct wm_adsp_compr *compr;
2337 int ret = 0;
2338
2339 mutex_lock(&dsp->pwr_lock);
2340
2341 if (wm_adsp_fw[dsp->fw].num_caps == 0) {
2342 adsp_err(dsp, "Firmware does not support compressed API\n");
2343 ret = -ENXIO;
2344 goto out;
2345 }
2346
2347 if (wm_adsp_fw[dsp->fw].compr_direction != stream->direction) {
2348 adsp_err(dsp, "Firmware does not support stream direction\n");
2349 ret = -EINVAL;
2350 goto out;
2351 }
2352
2353 if (dsp->compr) {
2354 /* It is expect this limitation will be removed in future */
2355 adsp_err(dsp, "Only a single stream supported per DSP\n");
2356 ret = -EBUSY;
2357 goto out;
2358 }
2359
2360 compr = kzalloc(sizeof(*compr), GFP_KERNEL);
2361 if (!compr) {
2362 ret = -ENOMEM;
2363 goto out;
2364 }
2365
2366 compr->dsp = dsp;
2367 compr->stream = stream;
2368
2369 dsp->compr = compr;
2370
2371 stream->runtime->private_data = compr;
2372
2373out:
2374 mutex_unlock(&dsp->pwr_lock);
2375
2376 return ret;
2377}
2378EXPORT_SYMBOL_GPL(wm_adsp_compr_open);
2379
2380int wm_adsp_compr_free(struct snd_compr_stream *stream)
2381{
2382 struct wm_adsp_compr *compr = stream->runtime->private_data;
2383 struct wm_adsp *dsp = compr->dsp;
2384
2385 mutex_lock(&dsp->pwr_lock);
2386
2387 dsp->compr = NULL;
2388
2389 kfree(compr->raw_buf);
2390 kfree(compr);
2391
2392 mutex_unlock(&dsp->pwr_lock);
2393
2394 return 0;
2395}
2396EXPORT_SYMBOL_GPL(wm_adsp_compr_free);
2397
2398static int wm_adsp_compr_check_params(struct snd_compr_stream *stream,
2399 struct snd_compr_params *params)
2400{
2401 struct wm_adsp_compr *compr = stream->runtime->private_data;
2402 struct wm_adsp *dsp = compr->dsp;
2403 const struct wm_adsp_fw_caps *caps;
2404 const struct snd_codec_desc *desc;
2405 int i, j;
2406
2407 if (params->buffer.fragment_size < WM_ADSP_MIN_FRAGMENT_SIZE ||
2408 params->buffer.fragment_size > WM_ADSP_MAX_FRAGMENT_SIZE ||
2409 params->buffer.fragments < WM_ADSP_MIN_FRAGMENTS ||
2410 params->buffer.fragments > WM_ADSP_MAX_FRAGMENTS ||
2411 params->buffer.fragment_size % WM_ADSP_DATA_WORD_SIZE) {
2412 adsp_err(dsp, "Invalid buffer fragsize=%d fragments=%d\n",
2413 params->buffer.fragment_size,
2414 params->buffer.fragments);
2415
2416 return -EINVAL;
2417 }
2418
2419 for (i = 0; i < wm_adsp_fw[dsp->fw].num_caps; i++) {
2420 caps = &wm_adsp_fw[dsp->fw].caps[i];
2421 desc = &caps->desc;
2422
2423 if (caps->id != params->codec.id)
2424 continue;
2425
2426 if (stream->direction == SND_COMPRESS_PLAYBACK) {
2427 if (desc->max_ch < params->codec.ch_out)
2428 continue;
2429 } else {
2430 if (desc->max_ch < params->codec.ch_in)
2431 continue;
2432 }
2433
2434 if (!(desc->formats & (1 << params->codec.format)))
2435 continue;
2436
2437 for (j = 0; j < desc->num_sample_rates; ++j)
2438 if (desc->sample_rates[j] == params->codec.sample_rate)
2439 return 0;
2440 }
2441
2442 adsp_err(dsp, "Invalid params id=%u ch=%u,%u rate=%u fmt=%u\n",
2443 params->codec.id, params->codec.ch_in, params->codec.ch_out,
2444 params->codec.sample_rate, params->codec.format);
2445 return -EINVAL;
2446}
2447
2448static inline unsigned int wm_adsp_compr_frag_words(struct wm_adsp_compr *compr)
2449{
2450 return compr->size.fragment_size / WM_ADSP_DATA_WORD_SIZE;
2451}
2452
2453int wm_adsp_compr_set_params(struct snd_compr_stream *stream,
2454 struct snd_compr_params *params)
2455{
2456 struct wm_adsp_compr *compr = stream->runtime->private_data;
2457 unsigned int size;
2458 int ret;
2459
2460 ret = wm_adsp_compr_check_params(stream, params);
2461 if (ret)
2462 return ret;
2463
2464 compr->size = params->buffer;
2465
2466 adsp_dbg(compr->dsp, "fragment_size=%d fragments=%d\n",
2467 compr->size.fragment_size, compr->size.fragments);
2468
2469 size = wm_adsp_compr_frag_words(compr) * sizeof(*compr->raw_buf);
2470 compr->raw_buf = kmalloc(size, GFP_DMA | GFP_KERNEL);
2471 if (!compr->raw_buf)
2472 return -ENOMEM;
2473
2474 return 0;
2475}
2476EXPORT_SYMBOL_GPL(wm_adsp_compr_set_params);
2477
2478int wm_adsp_compr_get_caps(struct snd_compr_stream *stream,
2479 struct snd_compr_caps *caps)
2480{
2481 struct wm_adsp_compr *compr = stream->runtime->private_data;
2482 int fw = compr->dsp->fw;
2483 int i;
2484
2485 if (wm_adsp_fw[fw].caps) {
2486 for (i = 0; i < wm_adsp_fw[fw].num_caps; i++)
2487 caps->codecs[i] = wm_adsp_fw[fw].caps[i].id;
2488
2489 caps->num_codecs = i;
2490 caps->direction = wm_adsp_fw[fw].compr_direction;
2491
2492 caps->min_fragment_size = WM_ADSP_MIN_FRAGMENT_SIZE;
2493 caps->max_fragment_size = WM_ADSP_MAX_FRAGMENT_SIZE;
2494 caps->min_fragments = WM_ADSP_MIN_FRAGMENTS;
2495 caps->max_fragments = WM_ADSP_MAX_FRAGMENTS;
2496 }
2497
2498 return 0;
2499}
2500EXPORT_SYMBOL_GPL(wm_adsp_compr_get_caps);
2501
2502static int wm_adsp_read_data_block(struct wm_adsp *dsp, int mem_type,
2503 unsigned int mem_addr,
2504 unsigned int num_words, u32 *data)
2505{
2506 struct wm_adsp_region const *mem = wm_adsp_find_region(dsp, mem_type);
2507 unsigned int i, reg;
2508 int ret;
2509
2510 if (!mem)
2511 return -EINVAL;
2512
2513 reg = wm_adsp_region_to_reg(mem, mem_addr);
2514
2515 ret = regmap_raw_read(dsp->regmap, reg, data,
2516 sizeof(*data) * num_words);
2517 if (ret < 0)
2518 return ret;
2519
2520 for (i = 0; i < num_words; ++i)
2521 data[i] = be32_to_cpu(data[i]) & 0x00ffffffu;
2522
2523 return 0;
2524}
2525
2526static inline int wm_adsp_read_data_word(struct wm_adsp *dsp, int mem_type,
2527 unsigned int mem_addr, u32 *data)
2528{
2529 return wm_adsp_read_data_block(dsp, mem_type, mem_addr, 1, data);
2530}
2531
2532static int wm_adsp_write_data_word(struct wm_adsp *dsp, int mem_type,
2533 unsigned int mem_addr, u32 data)
2534{
2535 struct wm_adsp_region const *mem = wm_adsp_find_region(dsp, mem_type);
2536 unsigned int reg;
2537
2538 if (!mem)
2539 return -EINVAL;
2540
2541 reg = wm_adsp_region_to_reg(mem, mem_addr);
2542
2543 data = cpu_to_be32(data & 0x00ffffffu);
2544
2545 return regmap_raw_write(dsp->regmap, reg, &data, sizeof(data));
2546}
2547
2548static inline int wm_adsp_buffer_read(struct wm_adsp_compr_buf *buf,
2549 unsigned int field_offset, u32 *data)
2550{
2551 return wm_adsp_read_data_word(buf->dsp, WMFW_ADSP2_XM,
2552 buf->host_buf_ptr + field_offset, data);
2553}
2554
2555static inline int wm_adsp_buffer_write(struct wm_adsp_compr_buf *buf,
2556 unsigned int field_offset, u32 data)
2557{
2558 return wm_adsp_write_data_word(buf->dsp, WMFW_ADSP2_XM,
2559 buf->host_buf_ptr + field_offset, data);
2560}
2561
2562static int wm_adsp_buffer_locate(struct wm_adsp_compr_buf *buf)
2563{
2564 struct wm_adsp_alg_region *alg_region;
2565 struct wm_adsp *dsp = buf->dsp;
2566 u32 xmalg, addr, magic;
2567 int i, ret;
2568
2569 alg_region = wm_adsp_find_alg_region(dsp, WMFW_ADSP2_XM, dsp->fw_id);
2570 xmalg = sizeof(struct wm_adsp_system_config_xm_hdr) / sizeof(__be32);
2571
2572 addr = alg_region->base + xmalg + ALG_XM_FIELD(magic);
2573 ret = wm_adsp_read_data_word(dsp, WMFW_ADSP2_XM, addr, &magic);
2574 if (ret < 0)
2575 return ret;
2576
2577 if (magic != WM_ADSP_ALG_XM_STRUCT_MAGIC)
2578 return -EINVAL;
2579
2580 addr = alg_region->base + xmalg + ALG_XM_FIELD(host_buf_ptr);
2581 for (i = 0; i < 5; ++i) {
2582 ret = wm_adsp_read_data_word(dsp, WMFW_ADSP2_XM, addr,
2583 &buf->host_buf_ptr);
2584 if (ret < 0)
2585 return ret;
2586
2587 if (buf->host_buf_ptr)
2588 break;
2589
2590 usleep_range(1000, 2000);
2591 }
2592
2593 if (!buf->host_buf_ptr)
2594 return -EIO;
2595
2596 adsp_dbg(dsp, "host_buf_ptr=%x\n", buf->host_buf_ptr);
2597
2598 return 0;
2599}
2600
2601static int wm_adsp_buffer_populate(struct wm_adsp_compr_buf *buf)
2602{
2603 const struct wm_adsp_fw_caps *caps = wm_adsp_fw[buf->dsp->fw].caps;
2604 struct wm_adsp_buffer_region *region;
2605 u32 offset = 0;
2606 int i, ret;
2607
2608 for (i = 0; i < caps->num_regions; ++i) {
2609 region = &buf->regions[i];
2610
2611 region->offset = offset;
2612 region->mem_type = caps->region_defs[i].mem_type;
2613
2614 ret = wm_adsp_buffer_read(buf, caps->region_defs[i].base_offset,
2615 &region->base_addr);
2616 if (ret < 0)
2617 return ret;
2618
2619 ret = wm_adsp_buffer_read(buf, caps->region_defs[i].size_offset,
2620 &offset);
2621 if (ret < 0)
2622 return ret;
2623
2624 region->cumulative_size = offset;
2625
2626 adsp_dbg(buf->dsp,
2627 "region=%d type=%d base=%04x off=%04x size=%04x\n",
2628 i, region->mem_type, region->base_addr,
2629 region->offset, region->cumulative_size);
2630 }
2631
2632 return 0;
2633}
2634
2635static int wm_adsp_buffer_init(struct wm_adsp *dsp)
2636{
2637 struct wm_adsp_compr_buf *buf;
2638 int ret;
2639
2640 buf = kzalloc(sizeof(*buf), GFP_KERNEL);
2641 if (!buf)
2642 return -ENOMEM;
2643
2644 buf->dsp = dsp;
2645 buf->read_index = -1;
2646 buf->irq_count = 0xFFFFFFFF;
2647
2648 ret = wm_adsp_buffer_locate(buf);
2649 if (ret < 0) {
2650 adsp_err(dsp, "Failed to acquire host buffer: %d\n", ret);
2651 goto err_buffer;
2652 }
2653
2654 buf->regions = kcalloc(wm_adsp_fw[dsp->fw].caps->num_regions,
2655 sizeof(*buf->regions), GFP_KERNEL);
2656 if (!buf->regions) {
2657 ret = -ENOMEM;
2658 goto err_buffer;
2659 }
2660
2661 ret = wm_adsp_buffer_populate(buf);
2662 if (ret < 0) {
2663 adsp_err(dsp, "Failed to populate host buffer: %d\n", ret);
2664 goto err_regions;
2665 }
2666
2667 dsp->buffer = buf;
2668
2669 return 0;
2670
2671err_regions:
2672 kfree(buf->regions);
2673err_buffer:
2674 kfree(buf);
2675 return ret;
2676}
2677
2678static int wm_adsp_buffer_free(struct wm_adsp *dsp)
2679{
2680 if (dsp->buffer) {
2681 kfree(dsp->buffer->regions);
2682 kfree(dsp->buffer);
2683
2684 dsp->buffer = NULL;
2685 }
2686
2687 return 0;
2688}
2689
2690static inline int wm_adsp_compr_attached(struct wm_adsp_compr *compr)
2691{
2692 return compr->buf != NULL;
2693}
2694
2695static int wm_adsp_compr_attach(struct wm_adsp_compr *compr)
2696{
2697 /*
2698 * Note this will be more complex once each DSP can support multiple
2699 * streams
2700 */
2701 if (!compr->dsp->buffer)
2702 return -EINVAL;
2703
2704 compr->buf = compr->dsp->buffer;
2705
2706 return 0;
2707}
2708
2709int wm_adsp_compr_trigger(struct snd_compr_stream *stream, int cmd)
2710{
2711 struct wm_adsp_compr *compr = stream->runtime->private_data;
2712 struct wm_adsp *dsp = compr->dsp;
2713 int ret = 0;
2714
2715 adsp_dbg(dsp, "Trigger: %d\n", cmd);
2716
2717 mutex_lock(&dsp->pwr_lock);
2718
2719 switch (cmd) {
2720 case SNDRV_PCM_TRIGGER_START:
2721 if (wm_adsp_compr_attached(compr))
2722 break;
2723
2724 ret = wm_adsp_compr_attach(compr);
2725 if (ret < 0) {
2726 adsp_err(dsp, "Failed to link buffer and stream: %d\n",
2727 ret);
2728 break;
2729 }
2730
2731 /* Trigger the IRQ at one fragment of data */
2732 ret = wm_adsp_buffer_write(compr->buf,
2733 HOST_BUFFER_FIELD(high_water_mark),
2734 wm_adsp_compr_frag_words(compr));
2735 if (ret < 0) {
2736 adsp_err(dsp, "Failed to set high water mark: %d\n",
2737 ret);
2738 break;
2739 }
2740 break;
2741 case SNDRV_PCM_TRIGGER_STOP:
2742 break;
2743 default:
2744 ret = -EINVAL;
2745 break;
2746 }
2747
2748 mutex_unlock(&dsp->pwr_lock);
2749
2750 return ret;
2751}
2752EXPORT_SYMBOL_GPL(wm_adsp_compr_trigger);
2753
2754static inline int wm_adsp_buffer_size(struct wm_adsp_compr_buf *buf)
2755{
2756 int last_region = wm_adsp_fw[buf->dsp->fw].caps->num_regions - 1;
2757
2758 return buf->regions[last_region].cumulative_size;
2759}
2760
2761static int wm_adsp_buffer_update_avail(struct wm_adsp_compr_buf *buf)
2762{
2763 u32 next_read_index, next_write_index;
2764 int write_index, read_index, avail;
2765 int ret;
2766
2767 /* Only sync read index if we haven't already read a valid index */
2768 if (buf->read_index < 0) {
2769 ret = wm_adsp_buffer_read(buf,
2770 HOST_BUFFER_FIELD(next_read_index),
2771 &next_read_index);
2772 if (ret < 0)
2773 return ret;
2774
2775 read_index = sign_extend32(next_read_index, 23);
2776
2777 if (read_index < 0) {
2778 adsp_dbg(buf->dsp, "Avail check on unstarted stream\n");
2779 return 0;
2780 }
2781
2782 buf->read_index = read_index;
2783 }
2784
2785 ret = wm_adsp_buffer_read(buf, HOST_BUFFER_FIELD(next_write_index),
2786 &next_write_index);
2787 if (ret < 0)
2788 return ret;
2789
2790 write_index = sign_extend32(next_write_index, 23);
2791
2792 avail = write_index - buf->read_index;
2793 if (avail < 0)
2794 avail += wm_adsp_buffer_size(buf);
2795
2796 adsp_dbg(buf->dsp, "readindex=0x%x, writeindex=0x%x, avail=%d\n",
2797 buf->read_index, write_index, avail);
2798
2799 buf->avail = avail;
2800
2801 return 0;
2802}
2803
2804int wm_adsp_compr_handle_irq(struct wm_adsp *dsp)
2805{
2806 struct wm_adsp_compr_buf *buf = dsp->buffer;
2807 struct wm_adsp_compr *compr = dsp->compr;
2808 int ret = 0;
2809
2810 mutex_lock(&dsp->pwr_lock);
2811
2812 if (!buf) {
2813 adsp_err(dsp, "Spurious buffer IRQ\n");
2814 ret = -ENODEV;
2815 goto out;
2816 }
2817
2818 adsp_dbg(dsp, "Handling buffer IRQ\n");
2819
2820 ret = wm_adsp_buffer_read(buf, HOST_BUFFER_FIELD(error), &buf->error);
2821 if (ret < 0) {
2822 adsp_err(dsp, "Failed to check buffer error: %d\n", ret);
2823 goto out;
2824 }
2825 if (buf->error != 0) {
2826 adsp_err(dsp, "Buffer error occurred: %d\n", buf->error);
2827 ret = -EIO;
2828 goto out;
2829 }
2830
2831 ret = wm_adsp_buffer_read(buf, HOST_BUFFER_FIELD(irq_count),
2832 &buf->irq_count);
2833 if (ret < 0) {
2834 adsp_err(dsp, "Failed to get irq_count: %d\n", ret);
2835 goto out;
2836 }
2837
2838 ret = wm_adsp_buffer_update_avail(buf);
2839 if (ret < 0) {
2840 adsp_err(dsp, "Error reading avail: %d\n", ret);
2841 goto out;
2842 }
2843
2844 if (compr->stream)
2845 snd_compr_fragment_elapsed(compr->stream);
2846
2847out:
2848 mutex_unlock(&dsp->pwr_lock);
2849
2850 return ret;
2851}
2852EXPORT_SYMBOL_GPL(wm_adsp_compr_handle_irq);
2853
2854static int wm_adsp_buffer_reenable_irq(struct wm_adsp_compr_buf *buf)
2855{
2856 if (buf->irq_count & 0x01)
2857 return 0;
2858
2859 adsp_dbg(buf->dsp, "Enable IRQ(0x%x) for next fragment\n",
2860 buf->irq_count);
2861
2862 buf->irq_count |= 0x01;
2863
2864 return wm_adsp_buffer_write(buf, HOST_BUFFER_FIELD(irq_ack),
2865 buf->irq_count);
2866}
2867
2868int wm_adsp_compr_pointer(struct snd_compr_stream *stream,
2869 struct snd_compr_tstamp *tstamp)
2870{
2871 struct wm_adsp_compr *compr = stream->runtime->private_data;
2872 struct wm_adsp_compr_buf *buf = compr->buf;
2873 struct wm_adsp *dsp = compr->dsp;
2874 int ret = 0;
2875
2876 adsp_dbg(dsp, "Pointer request\n");
2877
2878 mutex_lock(&dsp->pwr_lock);
2879
2880 if (!compr->buf) {
2881 ret = -ENXIO;
2882 goto out;
2883 }
2884
2885 if (compr->buf->error) {
2886 ret = -EIO;
2887 goto out;
2888 }
2889
2890 if (buf->avail < wm_adsp_compr_frag_words(compr)) {
2891 ret = wm_adsp_buffer_update_avail(buf);
2892 if (ret < 0) {
2893 adsp_err(dsp, "Error reading avail: %d\n", ret);
2894 goto out;
2895 }
2896
2897 /*
2898 * If we really have less than 1 fragment available tell the
2899 * DSP to inform us once a whole fragment is available.
2900 */
2901 if (buf->avail < wm_adsp_compr_frag_words(compr)) {
2902 ret = wm_adsp_buffer_reenable_irq(buf);
2903 if (ret < 0) {
2904 adsp_err(dsp,
2905 "Failed to re-enable buffer IRQ: %d\n",
2906 ret);
2907 goto out;
2908 }
2909 }
2910 }
2911
2912 tstamp->copied_total = compr->copied_total;
2913 tstamp->copied_total += buf->avail * WM_ADSP_DATA_WORD_SIZE;
2914
2915out:
2916 mutex_unlock(&dsp->pwr_lock);
2917
2918 return ret;
2919}
2920EXPORT_SYMBOL_GPL(wm_adsp_compr_pointer);
2921
2922static int wm_adsp_buffer_capture_block(struct wm_adsp_compr *compr, int target)
2923{
2924 struct wm_adsp_compr_buf *buf = compr->buf;
2925 u8 *pack_in = (u8 *)compr->raw_buf;
2926 u8 *pack_out = (u8 *)compr->raw_buf;
2927 unsigned int adsp_addr;
2928 int mem_type, nwords, max_read;
2929 int i, j, ret;
2930
2931 /* Calculate read parameters */
2932 for (i = 0; i < wm_adsp_fw[buf->dsp->fw].caps->num_regions; ++i)
2933 if (buf->read_index < buf->regions[i].cumulative_size)
2934 break;
2935
2936 if (i == wm_adsp_fw[buf->dsp->fw].caps->num_regions)
2937 return -EINVAL;
2938
2939 mem_type = buf->regions[i].mem_type;
2940 adsp_addr = buf->regions[i].base_addr +
2941 (buf->read_index - buf->regions[i].offset);
2942
2943 max_read = wm_adsp_compr_frag_words(compr);
2944 nwords = buf->regions[i].cumulative_size - buf->read_index;
2945
2946 if (nwords > target)
2947 nwords = target;
2948 if (nwords > buf->avail)
2949 nwords = buf->avail;
2950 if (nwords > max_read)
2951 nwords = max_read;
2952 if (!nwords)
2953 return 0;
2954
2955 /* Read data from DSP */
2956 ret = wm_adsp_read_data_block(buf->dsp, mem_type, adsp_addr,
2957 nwords, compr->raw_buf);
2958 if (ret < 0)
2959 return ret;
2960
2961 /* Remove the padding bytes from the data read from the DSP */
2962 for (i = 0; i < nwords; i++) {
2963 for (j = 0; j < WM_ADSP_DATA_WORD_SIZE; j++)
2964 *pack_out++ = *pack_in++;
2965
2966 pack_in += sizeof(*(compr->raw_buf)) - WM_ADSP_DATA_WORD_SIZE;
2967 }
2968
2969 /* update read index to account for words read */
2970 buf->read_index += nwords;
2971 if (buf->read_index == wm_adsp_buffer_size(buf))
2972 buf->read_index = 0;
2973
2974 ret = wm_adsp_buffer_write(buf, HOST_BUFFER_FIELD(next_read_index),
2975 buf->read_index);
2976 if (ret < 0)
2977 return ret;
2978
2979 /* update avail to account for words read */
2980 buf->avail -= nwords;
2981
2982 return nwords;
2983}
2984
2985static int wm_adsp_compr_read(struct wm_adsp_compr *compr,
2986 char __user *buf, size_t count)
2987{
2988 struct wm_adsp *dsp = compr->dsp;
2989 int ntotal = 0;
2990 int nwords, nbytes;
2991
2992 adsp_dbg(dsp, "Requested read of %zu bytes\n", count);
2993
2994 if (!compr->buf)
2995 return -ENXIO;
2996
2997 if (compr->buf->error)
2998 return -EIO;
2999
3000 count /= WM_ADSP_DATA_WORD_SIZE;
3001
3002 do {
3003 nwords = wm_adsp_buffer_capture_block(compr, count);
3004 if (nwords < 0) {
3005 adsp_err(dsp, "Failed to capture block: %d\n", nwords);
3006 return nwords;
3007 }
3008
3009 nbytes = nwords * WM_ADSP_DATA_WORD_SIZE;
3010
3011 adsp_dbg(dsp, "Read %d bytes\n", nbytes);
3012
3013 if (copy_to_user(buf + ntotal, compr->raw_buf, nbytes)) {
3014 adsp_err(dsp, "Failed to copy data to user: %d, %d\n",
3015 ntotal, nbytes);
3016 return -EFAULT;
3017 }
3018
3019 count -= nwords;
3020 ntotal += nbytes;
3021 } while (nwords > 0 && count > 0);
3022
3023 compr->copied_total += ntotal;
3024
3025 return ntotal;
3026}
3027
3028int wm_adsp_compr_copy(struct snd_compr_stream *stream, char __user *buf,
3029 size_t count)
3030{
3031 struct wm_adsp_compr *compr = stream->runtime->private_data;
3032 struct wm_adsp *dsp = compr->dsp;
3033 int ret;
3034
3035 mutex_lock(&dsp->pwr_lock);
3036
3037 if (stream->direction == SND_COMPRESS_CAPTURE)
3038 ret = wm_adsp_compr_read(compr, buf, count);
3039 else
3040 ret = -ENOTSUPP;
3041
3042 mutex_unlock(&dsp->pwr_lock);
3043
3044 return ret;
3045}
3046EXPORT_SYMBOL_GPL(wm_adsp_compr_copy);
3047
2127MODULE_LICENSE("GPL v2"); 3048MODULE_LICENSE("GPL v2");
diff --git a/sound/soc/codecs/wm_adsp.h b/sound/soc/codecs/wm_adsp.h
index 2d117cf0e953..1a928ec54741 100644
--- a/sound/soc/codecs/wm_adsp.h
+++ b/sound/soc/codecs/wm_adsp.h
@@ -15,6 +15,7 @@
15 15
16#include <sound/soc.h> 16#include <sound/soc.h>
17#include <sound/soc-dapm.h> 17#include <sound/soc-dapm.h>
18#include <sound/compress_driver.h>
18 19
19#include "wmfw.h" 20#include "wmfw.h"
20 21
@@ -30,6 +31,9 @@ struct wm_adsp_alg_region {
30 unsigned int base; 31 unsigned int base;
31}; 32};
32 33
34struct wm_adsp_compr;
35struct wm_adsp_compr_buf;
36
33struct wm_adsp { 37struct wm_adsp {
34 const char *part; 38 const char *part;
35 int num; 39 int num;
@@ -45,8 +49,8 @@ struct wm_adsp {
45 49
46 struct list_head alg_regions; 50 struct list_head alg_regions;
47 51
48 int fw_id; 52 unsigned int fw_id;
49 int fw_id_version; 53 unsigned int fw_id_version;
50 54
51 const struct wm_adsp_region *mem; 55 const struct wm_adsp_region *mem;
52 int num_mems; 56 int num_mems;
@@ -59,9 +63,13 @@ struct wm_adsp {
59 63
60 struct work_struct boot_work; 64 struct work_struct boot_work;
61 65
66 struct wm_adsp_compr *compr;
67 struct wm_adsp_compr_buf *buffer;
68
69 struct mutex pwr_lock;
70
62#ifdef CONFIG_DEBUG_FS 71#ifdef CONFIG_DEBUG_FS
63 struct dentry *debugfs_root; 72 struct dentry *debugfs_root;
64 struct mutex debugfs_lock;
65 char *wmfw_file_name; 73 char *wmfw_file_name;
66 char *bin_file_name; 74 char *bin_file_name;
67#endif 75#endif
@@ -96,4 +104,18 @@ int wm_adsp2_early_event(struct snd_soc_dapm_widget *w,
96int wm_adsp2_event(struct snd_soc_dapm_widget *w, 104int wm_adsp2_event(struct snd_soc_dapm_widget *w,
97 struct snd_kcontrol *kcontrol, int event); 105 struct snd_kcontrol *kcontrol, int event);
98 106
107extern int wm_adsp_compr_open(struct wm_adsp *dsp,
108 struct snd_compr_stream *stream);
109extern int wm_adsp_compr_free(struct snd_compr_stream *stream);
110extern int wm_adsp_compr_set_params(struct snd_compr_stream *stream,
111 struct snd_compr_params *params);
112extern int wm_adsp_compr_get_caps(struct snd_compr_stream *stream,
113 struct snd_compr_caps *caps);
114extern int wm_adsp_compr_trigger(struct snd_compr_stream *stream, int cmd);
115extern int wm_adsp_compr_handle_irq(struct wm_adsp *dsp);
116extern int wm_adsp_compr_pointer(struct snd_compr_stream *stream,
117 struct snd_compr_tstamp *tstamp);
118extern int wm_adsp_compr_copy(struct snd_compr_stream *stream,
119 char __user *buf, size_t count);
120
99#endif 121#endif
diff --git a/sound/soc/dwc/designware_i2s.c b/sound/soc/dwc/designware_i2s.c
index 6e6a70c5c2bd..ce664c239be3 100644
--- a/sound/soc/dwc/designware_i2s.c
+++ b/sound/soc/dwc/designware_i2s.c
@@ -18,6 +18,7 @@
18#include <linux/interrupt.h> 18#include <linux/interrupt.h>
19#include <linux/module.h> 19#include <linux/module.h>
20#include <linux/slab.h> 20#include <linux/slab.h>
21#include <linux/pm_runtime.h>
21#include <sound/designware_i2s.h> 22#include <sound/designware_i2s.h>
22#include <sound/pcm.h> 23#include <sound/pcm.h>
23#include <sound/pcm_params.h> 24#include <sound/pcm_params.h>
@@ -93,7 +94,12 @@ struct dw_i2s_dev {
93 struct clk *clk; 94 struct clk *clk;
94 int active; 95 int active;
95 unsigned int capability; 96 unsigned int capability;
97 unsigned int quirks;
98 unsigned int i2s_reg_comp1;
99 unsigned int i2s_reg_comp2;
96 struct device *dev; 100 struct device *dev;
101 u32 ccr;
102 u32 xfer_resolution;
97 103
98 /* data related to DMA transfers b/w i2s and DMAC */ 104 /* data related to DMA transfers b/w i2s and DMAC */
99 union dw_i2s_snd_dma_data play_dma_data; 105 union dw_i2s_snd_dma_data play_dma_data;
@@ -213,31 +219,58 @@ static int dw_i2s_startup(struct snd_pcm_substream *substream,
213 return 0; 219 return 0;
214} 220}
215 221
222static void dw_i2s_config(struct dw_i2s_dev *dev, int stream)
223{
224 u32 ch_reg, irq;
225 struct i2s_clk_config_data *config = &dev->config;
226
227
228 i2s_disable_channels(dev, stream);
229
230 for (ch_reg = 0; ch_reg < (config->chan_nr / 2); ch_reg++) {
231 if (stream == SNDRV_PCM_STREAM_PLAYBACK) {
232 i2s_write_reg(dev->i2s_base, TCR(ch_reg),
233 dev->xfer_resolution);
234 i2s_write_reg(dev->i2s_base, TFCR(ch_reg), 0x02);
235 irq = i2s_read_reg(dev->i2s_base, IMR(ch_reg));
236 i2s_write_reg(dev->i2s_base, IMR(ch_reg), irq & ~0x30);
237 i2s_write_reg(dev->i2s_base, TER(ch_reg), 1);
238 } else {
239 i2s_write_reg(dev->i2s_base, RCR(ch_reg),
240 dev->xfer_resolution);
241 i2s_write_reg(dev->i2s_base, RFCR(ch_reg), 0x07);
242 irq = i2s_read_reg(dev->i2s_base, IMR(ch_reg));
243 i2s_write_reg(dev->i2s_base, IMR(ch_reg), irq & ~0x03);
244 i2s_write_reg(dev->i2s_base, RER(ch_reg), 1);
245 }
246
247 }
248}
249
216static int dw_i2s_hw_params(struct snd_pcm_substream *substream, 250static int dw_i2s_hw_params(struct snd_pcm_substream *substream,
217 struct snd_pcm_hw_params *params, struct snd_soc_dai *dai) 251 struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
218{ 252{
219 struct dw_i2s_dev *dev = snd_soc_dai_get_drvdata(dai); 253 struct dw_i2s_dev *dev = snd_soc_dai_get_drvdata(dai);
220 struct i2s_clk_config_data *config = &dev->config; 254 struct i2s_clk_config_data *config = &dev->config;
221 u32 ccr, xfer_resolution, ch_reg, irq;
222 int ret; 255 int ret;
223 256
224 switch (params_format(params)) { 257 switch (params_format(params)) {
225 case SNDRV_PCM_FORMAT_S16_LE: 258 case SNDRV_PCM_FORMAT_S16_LE:
226 config->data_width = 16; 259 config->data_width = 16;
227 ccr = 0x00; 260 dev->ccr = 0x00;
228 xfer_resolution = 0x02; 261 dev->xfer_resolution = 0x02;
229 break; 262 break;
230 263
231 case SNDRV_PCM_FORMAT_S24_LE: 264 case SNDRV_PCM_FORMAT_S24_LE:
232 config->data_width = 24; 265 config->data_width = 24;
233 ccr = 0x08; 266 dev->ccr = 0x08;
234 xfer_resolution = 0x04; 267 dev->xfer_resolution = 0x04;
235 break; 268 break;
236 269
237 case SNDRV_PCM_FORMAT_S32_LE: 270 case SNDRV_PCM_FORMAT_S32_LE:
238 config->data_width = 32; 271 config->data_width = 32;
239 ccr = 0x10; 272 dev->ccr = 0x10;
240 xfer_resolution = 0x05; 273 dev->xfer_resolution = 0x05;
241 break; 274 break;
242 275
243 default: 276 default:
@@ -258,27 +291,9 @@ static int dw_i2s_hw_params(struct snd_pcm_substream *substream,
258 return -EINVAL; 291 return -EINVAL;
259 } 292 }
260 293
261 i2s_disable_channels(dev, substream->stream); 294 dw_i2s_config(dev, substream->stream);
262
263 for (ch_reg = 0; ch_reg < (config->chan_nr / 2); ch_reg++) {
264 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
265 i2s_write_reg(dev->i2s_base, TCR(ch_reg),
266 xfer_resolution);
267 i2s_write_reg(dev->i2s_base, TFCR(ch_reg), 0x02);
268 irq = i2s_read_reg(dev->i2s_base, IMR(ch_reg));
269 i2s_write_reg(dev->i2s_base, IMR(ch_reg), irq & ~0x30);
270 i2s_write_reg(dev->i2s_base, TER(ch_reg), 1);
271 } else {
272 i2s_write_reg(dev->i2s_base, RCR(ch_reg),
273 xfer_resolution);
274 i2s_write_reg(dev->i2s_base, RFCR(ch_reg), 0x07);
275 irq = i2s_read_reg(dev->i2s_base, IMR(ch_reg));
276 i2s_write_reg(dev->i2s_base, IMR(ch_reg), irq & ~0x03);
277 i2s_write_reg(dev->i2s_base, RER(ch_reg), 1);
278 }
279 }
280 295
281 i2s_write_reg(dev->i2s_base, CCR, ccr); 296 i2s_write_reg(dev->i2s_base, CCR, dev->ccr);
282 297
283 config->sample_rate = params_rate(params); 298 config->sample_rate = params_rate(params);
284 299
@@ -394,6 +409,23 @@ static const struct snd_soc_component_driver dw_i2s_component = {
394}; 409};
395 410
396#ifdef CONFIG_PM 411#ifdef CONFIG_PM
412static int dw_i2s_runtime_suspend(struct device *dev)
413{
414 struct dw_i2s_dev *dw_dev = dev_get_drvdata(dev);
415
416 if (dw_dev->capability & DW_I2S_MASTER)
417 clk_disable(dw_dev->clk);
418 return 0;
419}
420
421static int dw_i2s_runtime_resume(struct device *dev)
422{
423 struct dw_i2s_dev *dw_dev = dev_get_drvdata(dev);
424
425 if (dw_dev->capability & DW_I2S_MASTER)
426 clk_enable(dw_dev->clk);
427 return 0;
428}
397 429
398static int dw_i2s_suspend(struct snd_soc_dai *dai) 430static int dw_i2s_suspend(struct snd_soc_dai *dai)
399{ 431{
@@ -410,6 +442,11 @@ static int dw_i2s_resume(struct snd_soc_dai *dai)
410 442
411 if (dev->capability & DW_I2S_MASTER) 443 if (dev->capability & DW_I2S_MASTER)
412 clk_enable(dev->clk); 444 clk_enable(dev->clk);
445
446 if (dai->playback_active)
447 dw_i2s_config(dev, SNDRV_PCM_STREAM_PLAYBACK);
448 if (dai->capture_active)
449 dw_i2s_config(dev, SNDRV_PCM_STREAM_CAPTURE);
413 return 0; 450 return 0;
414} 451}
415 452
@@ -459,10 +496,14 @@ static int dw_configure_dai(struct dw_i2s_dev *dev,
459 * Read component parameter registers to extract 496 * Read component parameter registers to extract
460 * the I2S block's configuration. 497 * the I2S block's configuration.
461 */ 498 */
462 u32 comp1 = i2s_read_reg(dev->i2s_base, I2S_COMP_PARAM_1); 499 u32 comp1 = i2s_read_reg(dev->i2s_base, dev->i2s_reg_comp1);
463 u32 comp2 = i2s_read_reg(dev->i2s_base, I2S_COMP_PARAM_2); 500 u32 comp2 = i2s_read_reg(dev->i2s_base, dev->i2s_reg_comp2);
464 u32 idx; 501 u32 idx;
465 502
503 if (dev->capability & DWC_I2S_RECORD &&
504 dev->quirks & DW_I2S_QUIRK_COMP_PARAM1)
505 comp1 = comp1 & ~BIT(5);
506
466 if (COMP1_TX_ENABLED(comp1)) { 507 if (COMP1_TX_ENABLED(comp1)) {
467 dev_dbg(dev->dev, " designware: play supported\n"); 508 dev_dbg(dev->dev, " designware: play supported\n");
468 idx = COMP1_TX_WORDSIZE_0(comp1); 509 idx = COMP1_TX_WORDSIZE_0(comp1);
@@ -503,7 +544,7 @@ static int dw_configure_dai_by_pd(struct dw_i2s_dev *dev,
503 struct resource *res, 544 struct resource *res,
504 const struct i2s_platform_data *pdata) 545 const struct i2s_platform_data *pdata)
505{ 546{
506 u32 comp1 = i2s_read_reg(dev->i2s_base, I2S_COMP_PARAM_1); 547 u32 comp1 = i2s_read_reg(dev->i2s_base, dev->i2s_reg_comp1);
507 u32 idx = COMP1_APB_DATA_WIDTH(comp1); 548 u32 idx = COMP1_APB_DATA_WIDTH(comp1);
508 int ret; 549 int ret;
509 550
@@ -607,6 +648,14 @@ static int dw_i2s_probe(struct platform_device *pdev)
607 if (pdata) { 648 if (pdata) {
608 dev->capability = pdata->cap; 649 dev->capability = pdata->cap;
609 clk_id = NULL; 650 clk_id = NULL;
651 dev->quirks = pdata->quirks;
652 if (dev->quirks & DW_I2S_QUIRK_COMP_REG_OFFSET) {
653 dev->i2s_reg_comp1 = pdata->i2s_reg_comp1;
654 dev->i2s_reg_comp2 = pdata->i2s_reg_comp2;
655 } else {
656 dev->i2s_reg_comp1 = I2S_COMP_PARAM_1;
657 dev->i2s_reg_comp2 = I2S_COMP_PARAM_2;
658 }
610 ret = dw_configure_dai_by_pd(dev, dw_i2s_dai, res, pdata); 659 ret = dw_configure_dai_by_pd(dev, dw_i2s_dai, res, pdata);
611 } else { 660 } else {
612 clk_id = "i2sclk"; 661 clk_id = "i2sclk";
@@ -649,7 +698,7 @@ static int dw_i2s_probe(struct platform_device *pdev)
649 goto err_clk_disable; 698 goto err_clk_disable;
650 } 699 }
651 } 700 }
652 701 pm_runtime_enable(&pdev->dev);
653 return 0; 702 return 0;
654 703
655err_clk_disable: 704err_clk_disable:
@@ -665,6 +714,7 @@ static int dw_i2s_remove(struct platform_device *pdev)
665 if (dev->capability & DW_I2S_MASTER) 714 if (dev->capability & DW_I2S_MASTER)
666 clk_disable_unprepare(dev->clk); 715 clk_disable_unprepare(dev->clk);
667 716
717 pm_runtime_disable(&pdev->dev);
668 return 0; 718 return 0;
669} 719}
670 720
@@ -677,12 +727,17 @@ static const struct of_device_id dw_i2s_of_match[] = {
677MODULE_DEVICE_TABLE(of, dw_i2s_of_match); 727MODULE_DEVICE_TABLE(of, dw_i2s_of_match);
678#endif 728#endif
679 729
730static const struct dev_pm_ops dwc_pm_ops = {
731 SET_RUNTIME_PM_OPS(dw_i2s_runtime_suspend, dw_i2s_runtime_resume, NULL)
732};
733
680static struct platform_driver dw_i2s_driver = { 734static struct platform_driver dw_i2s_driver = {
681 .probe = dw_i2s_probe, 735 .probe = dw_i2s_probe,
682 .remove = dw_i2s_remove, 736 .remove = dw_i2s_remove,
683 .driver = { 737 .driver = {
684 .name = "designware-i2s", 738 .name = "designware-i2s",
685 .of_match_table = of_match_ptr(dw_i2s_of_match), 739 .of_match_table = of_match_ptr(dw_i2s_of_match),
740 .pm = &dwc_pm_ops,
686 }, 741 },
687}; 742};
688 743
diff --git a/sound/soc/fsl/fsl-asoc-card.c b/sound/soc/fsl/fsl-asoc-card.c
index 1b05d1c5d9fd..562b3bd22d9a 100644
--- a/sound/soc/fsl/fsl-asoc-card.c
+++ b/sound/soc/fsl/fsl-asoc-card.c
@@ -107,6 +107,13 @@ static const struct snd_soc_dapm_route audio_map[] = {
107 {"CPU-Capture", NULL, "Capture"}, 107 {"CPU-Capture", NULL, "Capture"},
108}; 108};
109 109
110static const struct snd_soc_dapm_route audio_map_ac97[] = {
111 {"AC97 Playback", NULL, "ASRC-Playback"},
112 {"Playback", NULL, "AC97 Playback"},
113 {"ASRC-Capture", NULL, "AC97 Capture"},
114 {"AC97 Capture", NULL, "Capture"},
115};
116
110/* Add all possible widgets into here without being redundant */ 117/* Add all possible widgets into here without being redundant */
111static const struct snd_soc_dapm_widget fsl_asoc_card_dapm_widgets[] = { 118static const struct snd_soc_dapm_widget fsl_asoc_card_dapm_widgets[] = {
112 SND_SOC_DAPM_LINE("Line Out Jack", NULL), 119 SND_SOC_DAPM_LINE("Line Out Jack", NULL),
@@ -222,12 +229,15 @@ static int fsl_asoc_card_set_bias_level(struct snd_soc_card *card,
222 enum snd_soc_bias_level level) 229 enum snd_soc_bias_level level)
223{ 230{
224 struct fsl_asoc_card_priv *priv = snd_soc_card_get_drvdata(card); 231 struct fsl_asoc_card_priv *priv = snd_soc_card_get_drvdata(card);
225 struct snd_soc_dai *codec_dai = card->rtd[0].codec_dai; 232 struct snd_soc_pcm_runtime *rtd;
233 struct snd_soc_dai *codec_dai;
226 struct codec_priv *codec_priv = &priv->codec_priv; 234 struct codec_priv *codec_priv = &priv->codec_priv;
227 struct device *dev = card->dev; 235 struct device *dev = card->dev;
228 unsigned int pll_out; 236 unsigned int pll_out;
229 int ret; 237 int ret;
230 238
239 rtd = snd_soc_get_pcm_runtime(card, card->dai_link[0].name);
240 codec_dai = rtd->codec_dai;
231 if (dapm->dev != codec_dai->dev) 241 if (dapm->dev != codec_dai->dev)
232 return 0; 242 return 0;
233 243
@@ -414,14 +424,16 @@ static int fsl_asoc_card_audmux_init(struct device_node *np,
414static int fsl_asoc_card_late_probe(struct snd_soc_card *card) 424static int fsl_asoc_card_late_probe(struct snd_soc_card *card)
415{ 425{
416 struct fsl_asoc_card_priv *priv = snd_soc_card_get_drvdata(card); 426 struct fsl_asoc_card_priv *priv = snd_soc_card_get_drvdata(card);
417 struct snd_soc_dai *codec_dai = card->rtd[0].codec_dai; 427 struct snd_soc_pcm_runtime *rtd = list_first_entry(
428 &card->rtd_list, struct snd_soc_pcm_runtime, list);
429 struct snd_soc_dai *codec_dai = rtd->codec_dai;
418 struct codec_priv *codec_priv = &priv->codec_priv; 430 struct codec_priv *codec_priv = &priv->codec_priv;
419 struct device *dev = card->dev; 431 struct device *dev = card->dev;
420 int ret; 432 int ret;
421 433
422 if (fsl_asoc_card_is_ac97(priv)) { 434 if (fsl_asoc_card_is_ac97(priv)) {
423#if IS_ENABLED(CONFIG_SND_AC97_CODEC) 435#if IS_ENABLED(CONFIG_SND_AC97_CODEC)
424 struct snd_soc_codec *codec = card->rtd[0].codec; 436 struct snd_soc_codec *codec = rtd->codec;
425 struct snd_ac97 *ac97 = snd_soc_codec_get_drvdata(codec); 437 struct snd_ac97 *ac97 = snd_soc_codec_get_drvdata(codec);
426 438
427 /* 439 /*
@@ -574,7 +586,8 @@ static int fsl_asoc_card_probe(struct platform_device *pdev)
574 priv->card.dev = &pdev->dev; 586 priv->card.dev = &pdev->dev;
575 priv->card.name = priv->name; 587 priv->card.name = priv->name;
576 priv->card.dai_link = priv->dai_link; 588 priv->card.dai_link = priv->dai_link;
577 priv->card.dapm_routes = audio_map; 589 priv->card.dapm_routes = fsl_asoc_card_is_ac97(priv) ?
590 audio_map_ac97 : audio_map;
578 priv->card.late_probe = fsl_asoc_card_late_probe; 591 priv->card.late_probe = fsl_asoc_card_late_probe;
579 priv->card.num_dapm_routes = ARRAY_SIZE(audio_map); 592 priv->card.num_dapm_routes = ARRAY_SIZE(audio_map);
580 priv->card.dapm_widgets = fsl_asoc_card_dapm_widgets; 593 priv->card.dapm_widgets = fsl_asoc_card_dapm_widgets;
diff --git a/sound/soc/fsl/fsl_asrc.c b/sound/soc/fsl/fsl_asrc.c
index 9f087d4f73ed..c1a0e01cb8e7 100644
--- a/sound/soc/fsl/fsl_asrc.c
+++ b/sound/soc/fsl/fsl_asrc.c
@@ -31,21 +31,21 @@
31 dev_dbg(&asrc_priv->pdev->dev, "Pair %c: " fmt, 'A' + index, ##__VA_ARGS__) 31 dev_dbg(&asrc_priv->pdev->dev, "Pair %c: " fmt, 'A' + index, ##__VA_ARGS__)
32 32
33/* Sample rates are aligned with that defined in pcm.h file */ 33/* Sample rates are aligned with that defined in pcm.h file */
34static const u8 process_option[][8][2] = { 34static const u8 process_option[][12][2] = {
35 /* 32kHz 44.1kHz 48kHz 64kHz 88.2kHz 96kHz 176kHz 192kHz */ 35 /* 8kHz 11.025kHz 16kHz 22.05kHz 32kHz 44.1kHz 48kHz 64kHz 88.2kHz 96kHz 176kHz 192kHz */
36 {{0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0},}, /* 5512Hz */ 36 {{0, 1}, {0, 1}, {0, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0},}, /* 5512Hz */
37 {{0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0},}, /* 8kHz */ 37 {{0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0},}, /* 8kHz */
38 {{0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0},}, /* 11025Hz */ 38 {{0, 2}, {0, 1}, {0, 1}, {0, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0},}, /* 11025Hz */
39 {{0, 1}, {0, 1}, {0, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0},}, /* 16kHz */ 39 {{1, 2}, {0, 2}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0},}, /* 16kHz */
40 {{0, 1}, {0, 1}, {0, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0},}, /* 22050Hz */ 40 {{1, 2}, {1, 2}, {0, 2}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0},}, /* 22050Hz */
41 {{0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 0}, {0, 0}, {0, 0},}, /* 32kHz */ 41 {{1, 2}, {2, 1}, {2, 1}, {0, 2}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 0}, {0, 0}, {0, 0},}, /* 32kHz */
42 {{0, 2}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 0}, {0, 0},}, /* 44.1kHz */ 42 {{2, 2}, {2, 2}, {2, 1}, {2, 1}, {0, 2}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 0}, {0, 0},}, /* 44.1kHz */
43 {{0, 2}, {0, 2}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 0}, {0, 0},}, /* 48kHz */ 43 {{2, 2}, {2, 2}, {2, 1}, {2, 1}, {0, 2}, {0, 2}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 0}, {0, 0},}, /* 48kHz */
44 {{1, 2}, {0, 2}, {0, 2}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 0},}, /* 64kHz */ 44 {{2, 2}, {2, 2}, {2, 2}, {2, 1}, {1, 2}, {0, 2}, {0, 2}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 0},}, /* 64kHz */
45 {{1, 2}, {1, 2}, {1, 2}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1},}, /* 88.2kHz */ 45 {{2, 2}, {2, 2}, {2, 2}, {2, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1},}, /* 88.2kHz */
46 {{1, 2}, {1, 2}, {1, 2}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1},}, /* 96kHz */ 46 {{2, 2}, {2, 2}, {2, 2}, {2, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1},}, /* 96kHz */
47 {{2, 2}, {2, 2}, {2, 2}, {2, 1}, {2, 1}, {2, 1}, {2, 1}, {2, 1},}, /* 176kHz */ 47 {{2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 1}, {2, 1}, {2, 1}, {2, 1}, {2, 1},}, /* 176kHz */
48 {{2, 2}, {2, 2}, {2, 2}, {2, 1}, {2, 1}, {2, 1}, {2, 1}, {2, 1},}, /* 192kHz */ 48 {{2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 1}, {2, 1}, {2, 1}, {2, 1}, {2, 1},}, /* 192kHz */
49}; 49};
50 50
51/* Corresponding to process_option */ 51/* Corresponding to process_option */
@@ -55,7 +55,7 @@ static int supported_input_rate[] = {
55}; 55};
56 56
57static int supported_asrc_rate[] = { 57static int supported_asrc_rate[] = {
58 32000, 44100, 48000, 64000, 88200, 96000, 176400, 192000, 58 8000, 11025, 16000, 22050, 32000, 44100, 48000, 64000, 88200, 96000, 176400, 192000,
59}; 59};
60 60
61/** 61/**
@@ -286,6 +286,13 @@ static int fsl_asrc_config_pair(struct fsl_asrc_pair *pair)
286 return -EINVAL; 286 return -EINVAL;
287 } 287 }
288 288
289 if ((outrate > 8000 && outrate < 30000) &&
290 (outrate/inrate > 24 || inrate/outrate > 8)) {
291 pair_err("exceed supported ratio range [1/24, 8] for \
292 inrate/outrate: %d/%d\n", inrate, outrate);
293 return -EINVAL;
294 }
295
289 /* Validate input and output clock sources */ 296 /* Validate input and output clock sources */
290 clk_index[IN] = clk_map[IN][config->inclk]; 297 clk_index[IN] = clk_map[IN][config->inclk];
291 clk_index[OUT] = clk_map[OUT][config->outclk]; 298 clk_index[OUT] = clk_map[OUT][config->outclk];
@@ -447,7 +454,7 @@ static int fsl_asrc_dai_hw_params(struct snd_pcm_substream *substream,
447 struct snd_soc_dai *dai) 454 struct snd_soc_dai *dai)
448{ 455{
449 struct fsl_asrc *asrc_priv = snd_soc_dai_get_drvdata(dai); 456 struct fsl_asrc *asrc_priv = snd_soc_dai_get_drvdata(dai);
450 int width = snd_pcm_format_width(params_format(params)); 457 int width = params_width(params);
451 struct snd_pcm_runtime *runtime = substream->runtime; 458 struct snd_pcm_runtime *runtime = substream->runtime;
452 struct fsl_asrc_pair *pair = runtime->private_data; 459 struct fsl_asrc_pair *pair = runtime->private_data;
453 unsigned int channels = params_channels(params); 460 unsigned int channels = params_channels(params);
@@ -859,6 +866,10 @@ static int fsl_asrc_probe(struct platform_device *pdev)
859 return PTR_ERR(asrc_priv->ipg_clk); 866 return PTR_ERR(asrc_priv->ipg_clk);
860 } 867 }
861 868
869 asrc_priv->spba_clk = devm_clk_get(&pdev->dev, "spba");
870 if (IS_ERR(asrc_priv->spba_clk))
871 dev_warn(&pdev->dev, "failed to get spba clock\n");
872
862 for (i = 0; i < ASRC_CLK_MAX_NUM; i++) { 873 for (i = 0; i < ASRC_CLK_MAX_NUM; i++) {
863 sprintf(tmp, "asrck_%x", i); 874 sprintf(tmp, "asrck_%x", i);
864 asrc_priv->asrck_clk[i] = devm_clk_get(&pdev->dev, tmp); 875 asrc_priv->asrck_clk[i] = devm_clk_get(&pdev->dev, tmp);
@@ -939,6 +950,11 @@ static int fsl_asrc_runtime_resume(struct device *dev)
939 ret = clk_prepare_enable(asrc_priv->ipg_clk); 950 ret = clk_prepare_enable(asrc_priv->ipg_clk);
940 if (ret) 951 if (ret)
941 goto disable_mem_clk; 952 goto disable_mem_clk;
953 if (!IS_ERR(asrc_priv->spba_clk)) {
954 ret = clk_prepare_enable(asrc_priv->spba_clk);
955 if (ret)
956 goto disable_ipg_clk;
957 }
942 for (i = 0; i < ASRC_CLK_MAX_NUM; i++) { 958 for (i = 0; i < ASRC_CLK_MAX_NUM; i++) {
943 ret = clk_prepare_enable(asrc_priv->asrck_clk[i]); 959 ret = clk_prepare_enable(asrc_priv->asrck_clk[i]);
944 if (ret) 960 if (ret)
@@ -950,6 +966,9 @@ static int fsl_asrc_runtime_resume(struct device *dev)
950disable_asrck_clk: 966disable_asrck_clk:
951 for (i--; i >= 0; i--) 967 for (i--; i >= 0; i--)
952 clk_disable_unprepare(asrc_priv->asrck_clk[i]); 968 clk_disable_unprepare(asrc_priv->asrck_clk[i]);
969 if (!IS_ERR(asrc_priv->spba_clk))
970 clk_disable_unprepare(asrc_priv->spba_clk);
971disable_ipg_clk:
953 clk_disable_unprepare(asrc_priv->ipg_clk); 972 clk_disable_unprepare(asrc_priv->ipg_clk);
954disable_mem_clk: 973disable_mem_clk:
955 clk_disable_unprepare(asrc_priv->mem_clk); 974 clk_disable_unprepare(asrc_priv->mem_clk);
@@ -963,6 +982,8 @@ static int fsl_asrc_runtime_suspend(struct device *dev)
963 982
964 for (i = 0; i < ASRC_CLK_MAX_NUM; i++) 983 for (i = 0; i < ASRC_CLK_MAX_NUM; i++)
965 clk_disable_unprepare(asrc_priv->asrck_clk[i]); 984 clk_disable_unprepare(asrc_priv->asrck_clk[i]);
985 if (!IS_ERR(asrc_priv->spba_clk))
986 clk_disable_unprepare(asrc_priv->spba_clk);
966 clk_disable_unprepare(asrc_priv->ipg_clk); 987 clk_disable_unprepare(asrc_priv->ipg_clk);
967 clk_disable_unprepare(asrc_priv->mem_clk); 988 clk_disable_unprepare(asrc_priv->mem_clk);
968 989
@@ -975,6 +996,9 @@ static int fsl_asrc_suspend(struct device *dev)
975{ 996{
976 struct fsl_asrc *asrc_priv = dev_get_drvdata(dev); 997 struct fsl_asrc *asrc_priv = dev_get_drvdata(dev);
977 998
999 regmap_read(asrc_priv->regmap, REG_ASRCFG,
1000 &asrc_priv->regcache_cfg);
1001
978 regcache_cache_only(asrc_priv->regmap, true); 1002 regcache_cache_only(asrc_priv->regmap, true);
979 regcache_mark_dirty(asrc_priv->regmap); 1003 regcache_mark_dirty(asrc_priv->regmap);
980 1004
@@ -995,6 +1019,10 @@ static int fsl_asrc_resume(struct device *dev)
995 regcache_cache_only(asrc_priv->regmap, false); 1019 regcache_cache_only(asrc_priv->regmap, false);
996 regcache_sync(asrc_priv->regmap); 1020 regcache_sync(asrc_priv->regmap);
997 1021
1022 regmap_update_bits(asrc_priv->regmap, REG_ASRCFG,
1023 ASRCFG_NDPRi_ALL_MASK | ASRCFG_POSTMODi_ALL_MASK |
1024 ASRCFG_PREMODi_ALL_MASK, asrc_priv->regcache_cfg);
1025
998 /* Restart enabled pairs */ 1026 /* Restart enabled pairs */
999 regmap_update_bits(asrc_priv->regmap, REG_ASRCTR, 1027 regmap_update_bits(asrc_priv->regmap, REG_ASRCTR,
1000 ASRCTR_ASRCEi_ALL_MASK, asrctr); 1028 ASRCTR_ASRCEi_ALL_MASK, asrctr);
diff --git a/sound/soc/fsl/fsl_asrc.h b/sound/soc/fsl/fsl_asrc.h
index 4aed63c4b431..0f163abe4ba3 100644
--- a/sound/soc/fsl/fsl_asrc.h
+++ b/sound/soc/fsl/fsl_asrc.h
@@ -132,10 +132,13 @@
132#define ASRCFG_INIRQi (1 << ASRCFG_INIRQi_SHIFT(i)) 132#define ASRCFG_INIRQi (1 << ASRCFG_INIRQi_SHIFT(i))
133#define ASRCFG_NDPRi_SHIFT(i) (18 + i) 133#define ASRCFG_NDPRi_SHIFT(i) (18 + i)
134#define ASRCFG_NDPRi_MASK(i) (1 << ASRCFG_NDPRi_SHIFT(i)) 134#define ASRCFG_NDPRi_MASK(i) (1 << ASRCFG_NDPRi_SHIFT(i))
135#define ASRCFG_NDPRi_ALL_SHIFT 18
136#define ASRCFG_NDPRi_ALL_MASK (7 << ASRCFG_NDPRi_ALL_SHIFT)
135#define ASRCFG_NDPRi (1 << ASRCFG_NDPRi_SHIFT(i)) 137#define ASRCFG_NDPRi (1 << ASRCFG_NDPRi_SHIFT(i))
136#define ASRCFG_POSTMODi_SHIFT(i) (8 + (i << 2)) 138#define ASRCFG_POSTMODi_SHIFT(i) (8 + (i << 2))
137#define ASRCFG_POSTMODi_WIDTH 2 139#define ASRCFG_POSTMODi_WIDTH 2
138#define ASRCFG_POSTMODi_MASK(i) (((1 << ASRCFG_POSTMODi_WIDTH) - 1) << ASRCFG_POSTMODi_SHIFT(i)) 140#define ASRCFG_POSTMODi_MASK(i) (((1 << ASRCFG_POSTMODi_WIDTH) - 1) << ASRCFG_POSTMODi_SHIFT(i))
141#define ASRCFG_POSTMODi_ALL_MASK (ASRCFG_POSTMODi_MASK(0) | ASRCFG_POSTMODi_MASK(1) | ASRCFG_POSTMODi_MASK(2))
139#define ASRCFG_POSTMOD(i, v) ((v) << ASRCFG_POSTMODi_SHIFT(i)) 142#define ASRCFG_POSTMOD(i, v) ((v) << ASRCFG_POSTMODi_SHIFT(i))
140#define ASRCFG_POSTMODi_UP(i) (0 << ASRCFG_POSTMODi_SHIFT(i)) 143#define ASRCFG_POSTMODi_UP(i) (0 << ASRCFG_POSTMODi_SHIFT(i))
141#define ASRCFG_POSTMODi_DCON(i) (1 << ASRCFG_POSTMODi_SHIFT(i)) 144#define ASRCFG_POSTMODi_DCON(i) (1 << ASRCFG_POSTMODi_SHIFT(i))
@@ -143,6 +146,7 @@
143#define ASRCFG_PREMODi_SHIFT(i) (6 + (i << 2)) 146#define ASRCFG_PREMODi_SHIFT(i) (6 + (i << 2))
144#define ASRCFG_PREMODi_WIDTH 2 147#define ASRCFG_PREMODi_WIDTH 2
145#define ASRCFG_PREMODi_MASK(i) (((1 << ASRCFG_PREMODi_WIDTH) - 1) << ASRCFG_PREMODi_SHIFT(i)) 148#define ASRCFG_PREMODi_MASK(i) (((1 << ASRCFG_PREMODi_WIDTH) - 1) << ASRCFG_PREMODi_SHIFT(i))
149#define ASRCFG_PREMODi_ALL_MASK (ASRCFG_PREMODi_MASK(0) | ASRCFG_PREMODi_MASK(1) | ASRCFG_PREMODi_MASK(2))
146#define ASRCFG_PREMOD(i, v) ((v) << ASRCFG_PREMODi_SHIFT(i)) 150#define ASRCFG_PREMOD(i, v) ((v) << ASRCFG_PREMODi_SHIFT(i))
147#define ASRCFG_PREMODi_UP(i) (0 << ASRCFG_PREMODi_SHIFT(i)) 151#define ASRCFG_PREMODi_UP(i) (0 << ASRCFG_PREMODi_SHIFT(i))
148#define ASRCFG_PREMODi_DCON(i) (1 << ASRCFG_PREMODi_SHIFT(i)) 152#define ASRCFG_PREMODi_DCON(i) (1 << ASRCFG_PREMODi_SHIFT(i))
@@ -426,6 +430,7 @@ struct fsl_asrc_pair {
426 * @paddr: physical address to the base address of registers 430 * @paddr: physical address to the base address of registers
427 * @mem_clk: clock source to access register 431 * @mem_clk: clock source to access register
428 * @ipg_clk: clock source to drive peripheral 432 * @ipg_clk: clock source to drive peripheral
433 * @spba_clk: SPBA clock (optional, depending on SoC design)
429 * @asrck_clk: clock sources to driver ASRC internal logic 434 * @asrck_clk: clock sources to driver ASRC internal logic
430 * @lock: spin lock for resource protection 435 * @lock: spin lock for resource protection
431 * @pair: pair pointers 436 * @pair: pair pointers
@@ -433,6 +438,7 @@ struct fsl_asrc_pair {
433 * @channel_avail: non-occupied channel numbers 438 * @channel_avail: non-occupied channel numbers
434 * @asrc_rate: default sample rate for ASoC Back-Ends 439 * @asrc_rate: default sample rate for ASoC Back-Ends
435 * @asrc_width: default sample width for ASoC Back-Ends 440 * @asrc_width: default sample width for ASoC Back-Ends
441 * @regcache_cfg: store register value of REG_ASRCFG
436 */ 442 */
437struct fsl_asrc { 443struct fsl_asrc {
438 struct snd_dmaengine_dai_dma_data dma_params_rx; 444 struct snd_dmaengine_dai_dma_data dma_params_rx;
@@ -442,6 +448,7 @@ struct fsl_asrc {
442 unsigned long paddr; 448 unsigned long paddr;
443 struct clk *mem_clk; 449 struct clk *mem_clk;
444 struct clk *ipg_clk; 450 struct clk *ipg_clk;
451 struct clk *spba_clk;
445 struct clk *asrck_clk[ASRC_CLK_MAX_NUM]; 452 struct clk *asrck_clk[ASRC_CLK_MAX_NUM];
446 spinlock_t lock; 453 spinlock_t lock;
447 454
@@ -451,6 +458,8 @@ struct fsl_asrc {
451 458
452 int asrc_rate; 459 int asrc_rate;
453 int asrc_width; 460 int asrc_width;
461
462 u32 regcache_cfg;
454}; 463};
455 464
456extern struct snd_soc_platform_driver fsl_asrc_platform; 465extern struct snd_soc_platform_driver fsl_asrc_platform;
diff --git a/sound/soc/fsl/fsl_esai.c b/sound/soc/fsl/fsl_esai.c
index 59f234e51971..26a90e12ede4 100644
--- a/sound/soc/fsl/fsl_esai.c
+++ b/sound/soc/fsl/fsl_esai.c
@@ -35,6 +35,7 @@
35 * @coreclk: clock source to access register 35 * @coreclk: clock source to access register
36 * @extalclk: esai clock source to derive HCK, SCK and FS 36 * @extalclk: esai clock source to derive HCK, SCK and FS
37 * @fsysclk: system clock source to derive HCK, SCK and FS 37 * @fsysclk: system clock source to derive HCK, SCK and FS
38 * @spbaclk: SPBA clock (optional, depending on SoC design)
38 * @fifo_depth: depth of tx/rx FIFO 39 * @fifo_depth: depth of tx/rx FIFO
39 * @slot_width: width of each DAI slot 40 * @slot_width: width of each DAI slot
40 * @slots: number of slots 41 * @slots: number of slots
@@ -54,6 +55,7 @@ struct fsl_esai {
54 struct clk *coreclk; 55 struct clk *coreclk;
55 struct clk *extalclk; 56 struct clk *extalclk;
56 struct clk *fsysclk; 57 struct clk *fsysclk;
58 struct clk *spbaclk;
57 u32 fifo_depth; 59 u32 fifo_depth;
58 u32 slot_width; 60 u32 slot_width;
59 u32 slots; 61 u32 slots;
@@ -469,6 +471,11 @@ static int fsl_esai_startup(struct snd_pcm_substream *substream,
469 ret = clk_prepare_enable(esai_priv->coreclk); 471 ret = clk_prepare_enable(esai_priv->coreclk);
470 if (ret) 472 if (ret)
471 return ret; 473 return ret;
474 if (!IS_ERR(esai_priv->spbaclk)) {
475 ret = clk_prepare_enable(esai_priv->spbaclk);
476 if (ret)
477 goto err_spbaclk;
478 }
472 if (!IS_ERR(esai_priv->extalclk)) { 479 if (!IS_ERR(esai_priv->extalclk)) {
473 ret = clk_prepare_enable(esai_priv->extalclk); 480 ret = clk_prepare_enable(esai_priv->extalclk);
474 if (ret) 481 if (ret)
@@ -499,6 +506,9 @@ err_fsysclk:
499 if (!IS_ERR(esai_priv->extalclk)) 506 if (!IS_ERR(esai_priv->extalclk))
500 clk_disable_unprepare(esai_priv->extalclk); 507 clk_disable_unprepare(esai_priv->extalclk);
501err_extalck: 508err_extalck:
509 if (!IS_ERR(esai_priv->spbaclk))
510 clk_disable_unprepare(esai_priv->spbaclk);
511err_spbaclk:
502 clk_disable_unprepare(esai_priv->coreclk); 512 clk_disable_unprepare(esai_priv->coreclk);
503 513
504 return ret; 514 return ret;
@@ -510,7 +520,7 @@ static int fsl_esai_hw_params(struct snd_pcm_substream *substream,
510{ 520{
511 struct fsl_esai *esai_priv = snd_soc_dai_get_drvdata(dai); 521 struct fsl_esai *esai_priv = snd_soc_dai_get_drvdata(dai);
512 bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK; 522 bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
513 u32 width = snd_pcm_format_width(params_format(params)); 523 u32 width = params_width(params);
514 u32 channels = params_channels(params); 524 u32 channels = params_channels(params);
515 u32 pins = DIV_ROUND_UP(channels, esai_priv->slots); 525 u32 pins = DIV_ROUND_UP(channels, esai_priv->slots);
516 u32 slot_width = width; 526 u32 slot_width = width;
@@ -564,6 +574,8 @@ static void fsl_esai_shutdown(struct snd_pcm_substream *substream,
564 clk_disable_unprepare(esai_priv->fsysclk); 574 clk_disable_unprepare(esai_priv->fsysclk);
565 if (!IS_ERR(esai_priv->extalclk)) 575 if (!IS_ERR(esai_priv->extalclk))
566 clk_disable_unprepare(esai_priv->extalclk); 576 clk_disable_unprepare(esai_priv->extalclk);
577 if (!IS_ERR(esai_priv->spbaclk))
578 clk_disable_unprepare(esai_priv->spbaclk);
567 clk_disable_unprepare(esai_priv->coreclk); 579 clk_disable_unprepare(esai_priv->coreclk);
568} 580}
569 581
@@ -653,21 +665,28 @@ static const struct snd_soc_component_driver fsl_esai_component = {
653}; 665};
654 666
655static const struct reg_default fsl_esai_reg_defaults[] = { 667static const struct reg_default fsl_esai_reg_defaults[] = {
656 {0x8, 0x00000000}, 668 {REG_ESAI_ETDR, 0x00000000},
657 {0x10, 0x00000000}, 669 {REG_ESAI_ECR, 0x00000000},
658 {0x18, 0x00000000}, 670 {REG_ESAI_TFCR, 0x00000000},
659 {0x98, 0x00000000}, 671 {REG_ESAI_RFCR, 0x00000000},
660 {0xd0, 0x00000000}, 672 {REG_ESAI_TX0, 0x00000000},
661 {0xd4, 0x00000000}, 673 {REG_ESAI_TX1, 0x00000000},
662 {0xd8, 0x00000000}, 674 {REG_ESAI_TX2, 0x00000000},
663 {0xdc, 0x00000000}, 675 {REG_ESAI_TX3, 0x00000000},
664 {0xe0, 0x00000000}, 676 {REG_ESAI_TX4, 0x00000000},
665 {0xe4, 0x0000ffff}, 677 {REG_ESAI_TX5, 0x00000000},
666 {0xe8, 0x0000ffff}, 678 {REG_ESAI_TSR, 0x00000000},
667 {0xec, 0x0000ffff}, 679 {REG_ESAI_SAICR, 0x00000000},
668 {0xf0, 0x0000ffff}, 680 {REG_ESAI_TCR, 0x00000000},
669 {0xf8, 0x00000000}, 681 {REG_ESAI_TCCR, 0x00000000},
670 {0xfc, 0x00000000}, 682 {REG_ESAI_RCR, 0x00000000},
683 {REG_ESAI_RCCR, 0x00000000},
684 {REG_ESAI_TSMA, 0x0000ffff},
685 {REG_ESAI_TSMB, 0x0000ffff},
686 {REG_ESAI_RSMA, 0x0000ffff},
687 {REG_ESAI_RSMB, 0x0000ffff},
688 {REG_ESAI_PRRC, 0x00000000},
689 {REG_ESAI_PCRC, 0x00000000},
671}; 690};
672 691
673static bool fsl_esai_readable_reg(struct device *dev, unsigned int reg) 692static bool fsl_esai_readable_reg(struct device *dev, unsigned int reg)
@@ -705,17 +724,10 @@ static bool fsl_esai_readable_reg(struct device *dev, unsigned int reg)
705static bool fsl_esai_volatile_reg(struct device *dev, unsigned int reg) 724static bool fsl_esai_volatile_reg(struct device *dev, unsigned int reg)
706{ 725{
707 switch (reg) { 726 switch (reg) {
708 case REG_ESAI_ETDR:
709 case REG_ESAI_ERDR: 727 case REG_ESAI_ERDR:
710 case REG_ESAI_ESR: 728 case REG_ESAI_ESR:
711 case REG_ESAI_TFSR: 729 case REG_ESAI_TFSR:
712 case REG_ESAI_RFSR: 730 case REG_ESAI_RFSR:
713 case REG_ESAI_TX0:
714 case REG_ESAI_TX1:
715 case REG_ESAI_TX2:
716 case REG_ESAI_TX3:
717 case REG_ESAI_TX4:
718 case REG_ESAI_TX5:
719 case REG_ESAI_RX0: 731 case REG_ESAI_RX0:
720 case REG_ESAI_RX1: 732 case REG_ESAI_RX1:
721 case REG_ESAI_RX2: 733 case REG_ESAI_RX2:
@@ -819,6 +831,11 @@ static int fsl_esai_probe(struct platform_device *pdev)
819 dev_warn(&pdev->dev, "failed to get fsys clock: %ld\n", 831 dev_warn(&pdev->dev, "failed to get fsys clock: %ld\n",
820 PTR_ERR(esai_priv->fsysclk)); 832 PTR_ERR(esai_priv->fsysclk));
821 833
834 esai_priv->spbaclk = devm_clk_get(&pdev->dev, "spba");
835 if (IS_ERR(esai_priv->spbaclk))
836 dev_warn(&pdev->dev, "failed to get spba clock: %ld\n",
837 PTR_ERR(esai_priv->spbaclk));
838
822 irq = platform_get_irq(pdev, 0); 839 irq = platform_get_irq(pdev, 0);
823 if (irq < 0) { 840 if (irq < 0) {
824 dev_err(&pdev->dev, "no irq for node %s\n", pdev->name); 841 dev_err(&pdev->dev, "no irq for node %s\n", pdev->name);
diff --git a/sound/soc/fsl/fsl_sai.c b/sound/soc/fsl/fsl_sai.c
index 08b460ba06ef..fef264d27fd3 100644
--- a/sound/soc/fsl/fsl_sai.c
+++ b/sound/soc/fsl/fsl_sai.c
@@ -126,6 +126,17 @@ out:
126 return IRQ_HANDLED; 126 return IRQ_HANDLED;
127} 127}
128 128
129static int fsl_sai_set_dai_tdm_slot(struct snd_soc_dai *cpu_dai, u32 tx_mask,
130 u32 rx_mask, int slots, int slot_width)
131{
132 struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai);
133
134 sai->slots = slots;
135 sai->slot_width = slot_width;
136
137 return 0;
138}
139
129static int fsl_sai_set_dai_sysclk_tr(struct snd_soc_dai *cpu_dai, 140static int fsl_sai_set_dai_sysclk_tr(struct snd_soc_dai *cpu_dai,
130 int clk_id, unsigned int freq, int fsl_dir) 141 int clk_id, unsigned int freq, int fsl_dir)
131{ 142{
@@ -354,13 +365,25 @@ static int fsl_sai_set_bclk(struct snd_soc_dai *dai, bool tx, u32 freq)
354 return -EINVAL; 365 return -EINVAL;
355 } 366 }
356 367
357 if ((tx && sai->synchronous[TX]) || (!tx && !sai->synchronous[RX])) { 368 /*
369 * 1) For Asynchronous mode, we must set RCR2 register for capture, and
370 * set TCR2 register for playback.
371 * 2) For Tx sync with Rx clock, we must set RCR2 register for playback
372 * and capture.
373 * 3) For Rx sync with Tx clock, we must set TCR2 register for playback
374 * and capture.
375 * 4) For Tx and Rx are both Synchronous with another SAI, we just
376 * ignore it.
377 */
378 if ((sai->synchronous[TX] && !sai->synchronous[RX]) ||
379 (!tx && !sai->synchronous[RX])) {
358 regmap_update_bits(sai->regmap, FSL_SAI_RCR2, 380 regmap_update_bits(sai->regmap, FSL_SAI_RCR2,
359 FSL_SAI_CR2_MSEL_MASK, 381 FSL_SAI_CR2_MSEL_MASK,
360 FSL_SAI_CR2_MSEL(sai->mclk_id[tx])); 382 FSL_SAI_CR2_MSEL(sai->mclk_id[tx]));
361 regmap_update_bits(sai->regmap, FSL_SAI_RCR2, 383 regmap_update_bits(sai->regmap, FSL_SAI_RCR2,
362 FSL_SAI_CR2_DIV_MASK, savediv - 1); 384 FSL_SAI_CR2_DIV_MASK, savediv - 1);
363 } else { 385 } else if ((sai->synchronous[RX] && !sai->synchronous[TX]) ||
386 (tx && !sai->synchronous[TX])) {
364 regmap_update_bits(sai->regmap, FSL_SAI_TCR2, 387 regmap_update_bits(sai->regmap, FSL_SAI_TCR2,
365 FSL_SAI_CR2_MSEL_MASK, 388 FSL_SAI_CR2_MSEL_MASK,
366 FSL_SAI_CR2_MSEL(sai->mclk_id[tx])); 389 FSL_SAI_CR2_MSEL(sai->mclk_id[tx]));
@@ -381,13 +404,21 @@ static int fsl_sai_hw_params(struct snd_pcm_substream *substream,
381 struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai); 404 struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai);
382 bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK; 405 bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
383 unsigned int channels = params_channels(params); 406 unsigned int channels = params_channels(params);
384 u32 word_width = snd_pcm_format_width(params_format(params)); 407 u32 word_width = params_width(params);
385 u32 val_cr4 = 0, val_cr5 = 0; 408 u32 val_cr4 = 0, val_cr5 = 0;
409 u32 slots = (channels == 1) ? 2 : channels;
410 u32 slot_width = word_width;
386 int ret; 411 int ret;
387 412
413 if (sai->slots)
414 slots = sai->slots;
415
416 if (sai->slot_width)
417 slot_width = sai->slot_width;
418
388 if (!sai->is_slave_mode) { 419 if (!sai->is_slave_mode) {
389 ret = fsl_sai_set_bclk(cpu_dai, tx, 420 ret = fsl_sai_set_bclk(cpu_dai, tx,
390 2 * word_width * params_rate(params)); 421 slots * slot_width * params_rate(params));
391 if (ret) 422 if (ret)
392 return ret; 423 return ret;
393 424
@@ -399,21 +430,49 @@ static int fsl_sai_hw_params(struct snd_pcm_substream *substream,
399 430
400 sai->mclk_streams |= BIT(substream->stream); 431 sai->mclk_streams |= BIT(substream->stream);
401 } 432 }
402
403 } 433 }
404 434
405 if (!sai->is_dsp_mode) 435 if (!sai->is_dsp_mode)
406 val_cr4 |= FSL_SAI_CR4_SYWD(word_width); 436 val_cr4 |= FSL_SAI_CR4_SYWD(slot_width);
407 437
408 val_cr5 |= FSL_SAI_CR5_WNW(word_width); 438 val_cr5 |= FSL_SAI_CR5_WNW(slot_width);
409 val_cr5 |= FSL_SAI_CR5_W0W(word_width); 439 val_cr5 |= FSL_SAI_CR5_W0W(slot_width);
410 440
411 if (sai->is_lsb_first) 441 if (sai->is_lsb_first)
412 val_cr5 |= FSL_SAI_CR5_FBT(0); 442 val_cr5 |= FSL_SAI_CR5_FBT(0);
413 else 443 else
414 val_cr5 |= FSL_SAI_CR5_FBT(word_width - 1); 444 val_cr5 |= FSL_SAI_CR5_FBT(word_width - 1);
415 445
416 val_cr4 |= FSL_SAI_CR4_FRSZ(channels); 446 val_cr4 |= FSL_SAI_CR4_FRSZ(slots);
447
448 /*
449 * For SAI master mode, when Tx(Rx) sync with Rx(Tx) clock, Rx(Tx) will
450 * generate bclk and frame clock for Tx(Rx), we should set RCR4(TCR4),
451 * RCR5(TCR5) and RMR(TMR) for playback(capture), or there will be sync
452 * error.
453 */
454
455 if (!sai->is_slave_mode) {
456 if (!sai->synchronous[TX] && sai->synchronous[RX] && !tx) {
457 regmap_update_bits(sai->regmap, FSL_SAI_TCR4,
458 FSL_SAI_CR4_SYWD_MASK | FSL_SAI_CR4_FRSZ_MASK,
459 val_cr4);
460 regmap_update_bits(sai->regmap, FSL_SAI_TCR5,
461 FSL_SAI_CR5_WNW_MASK | FSL_SAI_CR5_W0W_MASK |
462 FSL_SAI_CR5_FBT_MASK, val_cr5);
463 regmap_write(sai->regmap, FSL_SAI_TMR,
464 ~0UL - ((1 << channels) - 1));
465 } else if (!sai->synchronous[RX] && sai->synchronous[TX] && tx) {
466 regmap_update_bits(sai->regmap, FSL_SAI_RCR4,
467 FSL_SAI_CR4_SYWD_MASK | FSL_SAI_CR4_FRSZ_MASK,
468 val_cr4);
469 regmap_update_bits(sai->regmap, FSL_SAI_RCR5,
470 FSL_SAI_CR5_WNW_MASK | FSL_SAI_CR5_W0W_MASK |
471 FSL_SAI_CR5_FBT_MASK, val_cr5);
472 regmap_write(sai->regmap, FSL_SAI_RMR,
473 ~0UL - ((1 << channels) - 1));
474 }
475 }
417 476
418 regmap_update_bits(sai->regmap, FSL_SAI_xCR4(tx), 477 regmap_update_bits(sai->regmap, FSL_SAI_xCR4(tx),
419 FSL_SAI_CR4_SYWD_MASK | FSL_SAI_CR4_FRSZ_MASK, 478 FSL_SAI_CR4_SYWD_MASK | FSL_SAI_CR4_FRSZ_MASK,
@@ -569,6 +628,7 @@ static void fsl_sai_shutdown(struct snd_pcm_substream *substream,
569static const struct snd_soc_dai_ops fsl_sai_pcm_dai_ops = { 628static const struct snd_soc_dai_ops fsl_sai_pcm_dai_ops = {
570 .set_sysclk = fsl_sai_set_dai_sysclk, 629 .set_sysclk = fsl_sai_set_dai_sysclk,
571 .set_fmt = fsl_sai_set_dai_fmt, 630 .set_fmt = fsl_sai_set_dai_fmt,
631 .set_tdm_slot = fsl_sai_set_dai_tdm_slot,
572 .hw_params = fsl_sai_hw_params, 632 .hw_params = fsl_sai_hw_params,
573 .hw_free = fsl_sai_hw_free, 633 .hw_free = fsl_sai_hw_free,
574 .trigger = fsl_sai_trigger, 634 .trigger = fsl_sai_trigger,
@@ -627,6 +687,22 @@ static const struct snd_soc_component_driver fsl_component = {
627 .name = "fsl-sai", 687 .name = "fsl-sai",
628}; 688};
629 689
690static struct reg_default fsl_sai_reg_defaults[] = {
691 {FSL_SAI_TCR1, 0},
692 {FSL_SAI_TCR2, 0},
693 {FSL_SAI_TCR3, 0},
694 {FSL_SAI_TCR4, 0},
695 {FSL_SAI_TCR5, 0},
696 {FSL_SAI_TDR, 0},
697 {FSL_SAI_TMR, 0},
698 {FSL_SAI_RCR1, 0},
699 {FSL_SAI_RCR2, 0},
700 {FSL_SAI_RCR3, 0},
701 {FSL_SAI_RCR4, 0},
702 {FSL_SAI_RCR5, 0},
703 {FSL_SAI_RMR, 0},
704};
705
630static bool fsl_sai_readable_reg(struct device *dev, unsigned int reg) 706static bool fsl_sai_readable_reg(struct device *dev, unsigned int reg)
631{ 707{
632 switch (reg) { 708 switch (reg) {
@@ -660,13 +736,11 @@ static bool fsl_sai_volatile_reg(struct device *dev, unsigned int reg)
660 case FSL_SAI_RCSR: 736 case FSL_SAI_RCSR:
661 case FSL_SAI_TFR: 737 case FSL_SAI_TFR:
662 case FSL_SAI_RFR: 738 case FSL_SAI_RFR:
663 case FSL_SAI_TDR:
664 case FSL_SAI_RDR: 739 case FSL_SAI_RDR:
665 return true; 740 return true;
666 default: 741 default:
667 return false; 742 return false;
668 } 743 }
669
670} 744}
671 745
672static bool fsl_sai_writeable_reg(struct device *dev, unsigned int reg) 746static bool fsl_sai_writeable_reg(struct device *dev, unsigned int reg)
@@ -699,6 +773,8 @@ static const struct regmap_config fsl_sai_regmap_config = {
699 .val_bits = 32, 773 .val_bits = 32,
700 774
701 .max_register = FSL_SAI_RMR, 775 .max_register = FSL_SAI_RMR,
776 .reg_defaults = fsl_sai_reg_defaults,
777 .num_reg_defaults = ARRAY_SIZE(fsl_sai_reg_defaults),
702 .readable_reg = fsl_sai_readable_reg, 778 .readable_reg = fsl_sai_readable_reg,
703 .volatile_reg = fsl_sai_volatile_reg, 779 .volatile_reg = fsl_sai_volatile_reg,
704 .writeable_reg = fsl_sai_writeable_reg, 780 .writeable_reg = fsl_sai_writeable_reg,
diff --git a/sound/soc/fsl/fsl_sai.h b/sound/soc/fsl/fsl_sai.h
index b95fbc3f68eb..d9ed7be8cb34 100644
--- a/sound/soc/fsl/fsl_sai.h
+++ b/sound/soc/fsl/fsl_sai.h
@@ -143,6 +143,9 @@ struct fsl_sai {
143 143
144 unsigned int mclk_id[2]; 144 unsigned int mclk_id[2];
145 unsigned int mclk_streams; 145 unsigned int mclk_streams;
146 unsigned int slots;
147 unsigned int slot_width;
148
146 struct snd_dmaengine_dai_dma_data dma_params_rx; 149 struct snd_dmaengine_dai_dma_data dma_params_rx;
147 struct snd_dmaengine_dai_dma_data dma_params_tx; 150 struct snd_dmaengine_dai_dma_data dma_params_tx;
148}; 151};
diff --git a/sound/soc/fsl/fsl_spdif.c b/sound/soc/fsl/fsl_spdif.c
index 3d59bb6719f2..151849f79863 100644
--- a/sound/soc/fsl/fsl_spdif.c
+++ b/sound/soc/fsl/fsl_spdif.c
@@ -88,6 +88,7 @@ struct spdif_mixer_control {
88 * @rxclk: rx clock sources for capture 88 * @rxclk: rx clock sources for capture
89 * @coreclk: core clock for register access via DMA 89 * @coreclk: core clock for register access via DMA
90 * @sysclk: system clock for rx clock rate measurement 90 * @sysclk: system clock for rx clock rate measurement
91 * @spbaclk: SPBA clock (optional, depending on SoC design)
91 * @dma_params_tx: DMA parameters for transmit channel 92 * @dma_params_tx: DMA parameters for transmit channel
92 * @dma_params_rx: DMA parameters for receive channel 93 * @dma_params_rx: DMA parameters for receive channel
93 */ 94 */
@@ -106,6 +107,7 @@ struct fsl_spdif_priv {
106 struct clk *rxclk; 107 struct clk *rxclk;
107 struct clk *coreclk; 108 struct clk *coreclk;
108 struct clk *sysclk; 109 struct clk *sysclk;
110 struct clk *spbaclk;
109 struct snd_dmaengine_dai_dma_data dma_params_tx; 111 struct snd_dmaengine_dai_dma_data dma_params_tx;
110 struct snd_dmaengine_dai_dma_data dma_params_rx; 112 struct snd_dmaengine_dai_dma_data dma_params_rx;
111 /* regcache for SRPC */ 113 /* regcache for SRPC */
@@ -474,6 +476,14 @@ static int fsl_spdif_startup(struct snd_pcm_substream *substream,
474 return ret; 476 return ret;
475 } 477 }
476 478
479 if (!IS_ERR(spdif_priv->spbaclk)) {
480 ret = clk_prepare_enable(spdif_priv->spbaclk);
481 if (ret) {
482 dev_err(&pdev->dev, "failed to enable spba clock\n");
483 goto err_spbaclk;
484 }
485 }
486
477 ret = spdif_softreset(spdif_priv); 487 ret = spdif_softreset(spdif_priv);
478 if (ret) { 488 if (ret) {
479 dev_err(&pdev->dev, "failed to soft reset\n"); 489 dev_err(&pdev->dev, "failed to soft reset\n");
@@ -515,6 +525,9 @@ disable_txclk:
515 for (i--; i >= 0; i--) 525 for (i--; i >= 0; i--)
516 clk_disable_unprepare(spdif_priv->txclk[i]); 526 clk_disable_unprepare(spdif_priv->txclk[i]);
517err: 527err:
528 if (!IS_ERR(spdif_priv->spbaclk))
529 clk_disable_unprepare(spdif_priv->spbaclk);
530err_spbaclk:
518 clk_disable_unprepare(spdif_priv->coreclk); 531 clk_disable_unprepare(spdif_priv->coreclk);
519 532
520 return ret; 533 return ret;
@@ -548,6 +561,8 @@ static void fsl_spdif_shutdown(struct snd_pcm_substream *substream,
548 spdif_intr_status_clear(spdif_priv); 561 spdif_intr_status_clear(spdif_priv);
549 regmap_update_bits(regmap, REG_SPDIF_SCR, 562 regmap_update_bits(regmap, REG_SPDIF_SCR,
550 SCR_LOW_POWER, SCR_LOW_POWER); 563 SCR_LOW_POWER, SCR_LOW_POWER);
564 if (!IS_ERR(spdif_priv->spbaclk))
565 clk_disable_unprepare(spdif_priv->spbaclk);
551 clk_disable_unprepare(spdif_priv->coreclk); 566 clk_disable_unprepare(spdif_priv->coreclk);
552 } 567 }
553} 568}
@@ -1006,12 +1021,14 @@ static const struct snd_soc_component_driver fsl_spdif_component = {
1006 1021
1007/* FSL SPDIF REGMAP */ 1022/* FSL SPDIF REGMAP */
1008static const struct reg_default fsl_spdif_reg_defaults[] = { 1023static const struct reg_default fsl_spdif_reg_defaults[] = {
1009 {0x0, 0x00000400}, 1024 {REG_SPDIF_SCR, 0x00000400},
1010 {0x4, 0x00000000}, 1025 {REG_SPDIF_SRCD, 0x00000000},
1011 {0xc, 0x00000000}, 1026 {REG_SPDIF_SIE, 0x00000000},
1012 {0x34, 0x00000000}, 1027 {REG_SPDIF_STL, 0x00000000},
1013 {0x38, 0x00000000}, 1028 {REG_SPDIF_STR, 0x00000000},
1014 {0x50, 0x00020f00}, 1029 {REG_SPDIF_STCSCH, 0x00000000},
1030 {REG_SPDIF_STCSCL, 0x00000000},
1031 {REG_SPDIF_STC, 0x00020f00},
1015}; 1032};
1016 1033
1017static bool fsl_spdif_readable_reg(struct device *dev, unsigned int reg) 1034static bool fsl_spdif_readable_reg(struct device *dev, unsigned int reg)
@@ -1049,8 +1066,6 @@ static bool fsl_spdif_volatile_reg(struct device *dev, unsigned int reg)
1049 case REG_SPDIF_SRCSL: 1066 case REG_SPDIF_SRCSL:
1050 case REG_SPDIF_SRU: 1067 case REG_SPDIF_SRU:
1051 case REG_SPDIF_SRQ: 1068 case REG_SPDIF_SRQ:
1052 case REG_SPDIF_STL:
1053 case REG_SPDIF_STR:
1054 case REG_SPDIF_SRFM: 1069 case REG_SPDIF_SRFM:
1055 return true; 1070 return true;
1056 default: 1071 default:
@@ -1261,6 +1276,10 @@ static int fsl_spdif_probe(struct platform_device *pdev)
1261 return PTR_ERR(spdif_priv->coreclk); 1276 return PTR_ERR(spdif_priv->coreclk);
1262 } 1277 }
1263 1278
1279 spdif_priv->spbaclk = devm_clk_get(&pdev->dev, "spba");
1280 if (IS_ERR(spdif_priv->spbaclk))
1281 dev_warn(&pdev->dev, "no spba clock in devicetree\n");
1282
1264 /* Select clock source for rx/tx clock */ 1283 /* Select clock source for rx/tx clock */
1265 spdif_priv->rxclk = devm_clk_get(&pdev->dev, "rxtx1"); 1284 spdif_priv->rxclk = devm_clk_get(&pdev->dev, "rxtx1");
1266 if (IS_ERR(spdif_priv->rxclk)) { 1285 if (IS_ERR(spdif_priv->rxclk)) {
diff --git a/sound/soc/fsl/fsl_ssi.c b/sound/soc/fsl/fsl_ssi.c
index 95d2392303eb..40dfd8a36484 100644
--- a/sound/soc/fsl/fsl_ssi.c
+++ b/sound/soc/fsl/fsl_ssi.c
@@ -113,17 +113,17 @@ struct fsl_ssi_rxtx_reg_val {
113}; 113};
114 114
115static const struct reg_default fsl_ssi_reg_defaults[] = { 115static const struct reg_default fsl_ssi_reg_defaults[] = {
116 {0x10, 0x00000000}, 116 {CCSR_SSI_SCR, 0x00000000},
117 {0x18, 0x00003003}, 117 {CCSR_SSI_SIER, 0x00003003},
118 {0x1c, 0x00000200}, 118 {CCSR_SSI_STCR, 0x00000200},
119 {0x20, 0x00000200}, 119 {CCSR_SSI_SRCR, 0x00000200},
120 {0x24, 0x00040000}, 120 {CCSR_SSI_STCCR, 0x00040000},
121 {0x28, 0x00040000}, 121 {CCSR_SSI_SRCCR, 0x00040000},
122 {0x38, 0x00000000}, 122 {CCSR_SSI_SACNT, 0x00000000},
123 {0x48, 0x00000000}, 123 {CCSR_SSI_STMSK, 0x00000000},
124 {0x4c, 0x00000000}, 124 {CCSR_SSI_SRMSK, 0x00000000},
125 {0x54, 0x00000000}, 125 {CCSR_SSI_SACCEN, 0x00000000},
126 {0x58, 0x00000000}, 126 {CCSR_SSI_SACCDIS, 0x00000000},
127}; 127};
128 128
129static bool fsl_ssi_readable_reg(struct device *dev, unsigned int reg) 129static bool fsl_ssi_readable_reg(struct device *dev, unsigned int reg)
@@ -146,6 +146,7 @@ static bool fsl_ssi_volatile_reg(struct device *dev, unsigned int reg)
146 case CCSR_SSI_SRX1: 146 case CCSR_SSI_SRX1:
147 case CCSR_SSI_SISR: 147 case CCSR_SSI_SISR:
148 case CCSR_SSI_SFCSR: 148 case CCSR_SSI_SFCSR:
149 case CCSR_SSI_SACNT:
149 case CCSR_SSI_SACADD: 150 case CCSR_SSI_SACADD:
150 case CCSR_SSI_SACDAT: 151 case CCSR_SSI_SACDAT:
151 case CCSR_SSI_SATAG: 152 case CCSR_SSI_SATAG:
@@ -156,6 +157,21 @@ static bool fsl_ssi_volatile_reg(struct device *dev, unsigned int reg)
156 } 157 }
157} 158}
158 159
160static bool fsl_ssi_precious_reg(struct device *dev, unsigned int reg)
161{
162 switch (reg) {
163 case CCSR_SSI_SRX0:
164 case CCSR_SSI_SRX1:
165 case CCSR_SSI_SISR:
166 case CCSR_SSI_SACADD:
167 case CCSR_SSI_SACDAT:
168 case CCSR_SSI_SATAG:
169 return true;
170 default:
171 return false;
172 }
173}
174
159static bool fsl_ssi_writeable_reg(struct device *dev, unsigned int reg) 175static bool fsl_ssi_writeable_reg(struct device *dev, unsigned int reg)
160{ 176{
161 switch (reg) { 177 switch (reg) {
@@ -178,6 +194,7 @@ static const struct regmap_config fsl_ssi_regconfig = {
178 .num_reg_defaults = ARRAY_SIZE(fsl_ssi_reg_defaults), 194 .num_reg_defaults = ARRAY_SIZE(fsl_ssi_reg_defaults),
179 .readable_reg = fsl_ssi_readable_reg, 195 .readable_reg = fsl_ssi_readable_reg,
180 .volatile_reg = fsl_ssi_volatile_reg, 196 .volatile_reg = fsl_ssi_volatile_reg,
197 .precious_reg = fsl_ssi_precious_reg,
181 .writeable_reg = fsl_ssi_writeable_reg, 198 .writeable_reg = fsl_ssi_writeable_reg,
182 .cache_type = REGCACHE_RBTREE, 199 .cache_type = REGCACHE_RBTREE,
183}; 200};
@@ -239,8 +256,9 @@ struct fsl_ssi_private {
239 unsigned int baudclk_streams; 256 unsigned int baudclk_streams;
240 unsigned int bitclk_freq; 257 unsigned int bitclk_freq;
241 258
242 /*regcache for SFCSR*/ 259 /* regcache for volatile regs */
243 u32 regcache_sfcsr; 260 u32 regcache_sfcsr;
261 u32 regcache_sacnt;
244 262
245 /* DMA params */ 263 /* DMA params */
246 struct snd_dmaengine_dai_dma_data dma_params_tx; 264 struct snd_dmaengine_dai_dma_data dma_params_tx;
@@ -767,8 +785,7 @@ static int fsl_ssi_hw_params(struct snd_pcm_substream *substream,
767 struct fsl_ssi_private *ssi_private = snd_soc_dai_get_drvdata(cpu_dai); 785 struct fsl_ssi_private *ssi_private = snd_soc_dai_get_drvdata(cpu_dai);
768 struct regmap *regs = ssi_private->regs; 786 struct regmap *regs = ssi_private->regs;
769 unsigned int channels = params_channels(hw_params); 787 unsigned int channels = params_channels(hw_params);
770 unsigned int sample_size = 788 unsigned int sample_size = params_width(hw_params);
771 snd_pcm_format_width(params_format(hw_params));
772 u32 wl = CCSR_SSI_SxCCR_WL(sample_size); 789 u32 wl = CCSR_SSI_SxCCR_WL(sample_size);
773 int ret; 790 int ret;
774 u32 scr_val; 791 u32 scr_val;
@@ -1588,6 +1605,8 @@ static int fsl_ssi_suspend(struct device *dev)
1588 1605
1589 regmap_read(regs, CCSR_SSI_SFCSR, 1606 regmap_read(regs, CCSR_SSI_SFCSR,
1590 &ssi_private->regcache_sfcsr); 1607 &ssi_private->regcache_sfcsr);
1608 regmap_read(regs, CCSR_SSI_SACNT,
1609 &ssi_private->regcache_sacnt);
1591 1610
1592 regcache_cache_only(regs, true); 1611 regcache_cache_only(regs, true);
1593 regcache_mark_dirty(regs); 1612 regcache_mark_dirty(regs);
@@ -1606,6 +1625,8 @@ static int fsl_ssi_resume(struct device *dev)
1606 CCSR_SSI_SFCSR_RFWM1_MASK | CCSR_SSI_SFCSR_TFWM1_MASK | 1625 CCSR_SSI_SFCSR_RFWM1_MASK | CCSR_SSI_SFCSR_TFWM1_MASK |
1607 CCSR_SSI_SFCSR_RFWM0_MASK | CCSR_SSI_SFCSR_TFWM0_MASK, 1626 CCSR_SSI_SFCSR_RFWM0_MASK | CCSR_SSI_SFCSR_TFWM0_MASK,
1608 ssi_private->regcache_sfcsr); 1627 ssi_private->regcache_sfcsr);
1628 regmap_write(regs, CCSR_SSI_SACNT,
1629 ssi_private->regcache_sacnt);
1609 1630
1610 return regcache_sync(regs); 1631 return regcache_sync(regs);
1611} 1632}
diff --git a/sound/soc/fsl/imx-pcm-dma.c b/sound/soc/fsl/imx-pcm-dma.c
index 1fc01ed3279d..f3d3d1ffa84e 100644
--- a/sound/soc/fsl/imx-pcm-dma.c
+++ b/sound/soc/fsl/imx-pcm-dma.c
@@ -62,6 +62,8 @@ int imx_pcm_dma_init(struct platform_device *pdev, size_t size)
62 62
63 config = devm_kzalloc(&pdev->dev, 63 config = devm_kzalloc(&pdev->dev,
64 sizeof(struct snd_dmaengine_pcm_config), GFP_KERNEL); 64 sizeof(struct snd_dmaengine_pcm_config), GFP_KERNEL);
65 if (!config)
66 return -ENOMEM;
65 *config = imx_dmaengine_pcm_config; 67 *config = imx_dmaengine_pcm_config;
66 if (size) 68 if (size)
67 config->prealloc_buffer_size = size; 69 config->prealloc_buffer_size = size;
diff --git a/sound/soc/fsl/imx-pcm-fiq.c b/sound/soc/fsl/imx-pcm-fiq.c
index 7abf6a079574..49d7513f429e 100644
--- a/sound/soc/fsl/imx-pcm-fiq.c
+++ b/sound/soc/fsl/imx-pcm-fiq.c
@@ -220,9 +220,9 @@ static int snd_imx_pcm_mmap(struct snd_pcm_substream *substream,
220 ret = dma_mmap_writecombine(substream->pcm->card->dev, vma, 220 ret = dma_mmap_writecombine(substream->pcm->card->dev, vma,
221 runtime->dma_area, runtime->dma_addr, runtime->dma_bytes); 221 runtime->dma_area, runtime->dma_addr, runtime->dma_bytes);
222 222
223 pr_debug("%s: ret: %d %p 0x%08x 0x%08x\n", __func__, ret, 223 pr_debug("%s: ret: %d %p %pad 0x%08x\n", __func__, ret,
224 runtime->dma_area, 224 runtime->dma_area,
225 runtime->dma_addr, 225 &runtime->dma_addr,
226 runtime->dma_bytes); 226 runtime->dma_bytes);
227 return ret; 227 return ret;
228} 228}
diff --git a/sound/soc/fsl/imx-wm8962.c b/sound/soc/fsl/imx-wm8962.c
index b38b98cae855..201a70d1027a 100644
--- a/sound/soc/fsl/imx-wm8962.c
+++ b/sound/soc/fsl/imx-wm8962.c
@@ -69,13 +69,16 @@ static int imx_wm8962_set_bias_level(struct snd_soc_card *card,
69 struct snd_soc_dapm_context *dapm, 69 struct snd_soc_dapm_context *dapm,
70 enum snd_soc_bias_level level) 70 enum snd_soc_bias_level level)
71{ 71{
72 struct snd_soc_dai *codec_dai = card->rtd[0].codec_dai; 72 struct snd_soc_pcm_runtime *rtd;
73 struct snd_soc_dai *codec_dai;
73 struct imx_priv *priv = &card_priv; 74 struct imx_priv *priv = &card_priv;
74 struct imx_wm8962_data *data = snd_soc_card_get_drvdata(card); 75 struct imx_wm8962_data *data = snd_soc_card_get_drvdata(card);
75 struct device *dev = &priv->pdev->dev; 76 struct device *dev = &priv->pdev->dev;
76 unsigned int pll_out; 77 unsigned int pll_out;
77 int ret; 78 int ret;
78 79
80 rtd = snd_soc_get_pcm_runtime(card, card->dai_link[0].name);
81 codec_dai = rtd->codec_dai;
79 if (dapm->dev != codec_dai->dev) 82 if (dapm->dev != codec_dai->dev)
80 return 0; 83 return 0;
81 84
@@ -135,12 +138,15 @@ static int imx_wm8962_set_bias_level(struct snd_soc_card *card,
135 138
136static int imx_wm8962_late_probe(struct snd_soc_card *card) 139static int imx_wm8962_late_probe(struct snd_soc_card *card)
137{ 140{
138 struct snd_soc_dai *codec_dai = card->rtd[0].codec_dai; 141 struct snd_soc_pcm_runtime *rtd;
142 struct snd_soc_dai *codec_dai;
139 struct imx_priv *priv = &card_priv; 143 struct imx_priv *priv = &card_priv;
140 struct imx_wm8962_data *data = snd_soc_card_get_drvdata(card); 144 struct imx_wm8962_data *data = snd_soc_card_get_drvdata(card);
141 struct device *dev = &priv->pdev->dev; 145 struct device *dev = &priv->pdev->dev;
142 int ret; 146 int ret;
143 147
148 rtd = snd_soc_get_pcm_runtime(card, card->dai_link[0].name);
149 codec_dai = rtd->codec_dai;
144 ret = snd_soc_dai_set_sysclk(codec_dai, WM8962_SYSCLK_MCLK, 150 ret = snd_soc_dai_set_sysclk(codec_dai, WM8962_SYSCLK_MCLK,
145 data->clk_frequency, SND_SOC_CLOCK_IN); 151 data->clk_frequency, SND_SOC_CLOCK_IN);
146 if (ret < 0) 152 if (ret < 0)
diff --git a/sound/soc/fsl/mpc8610_hpcd.c b/sound/soc/fsl/mpc8610_hpcd.c
index 6f236f170cf5..ddf49f30b23f 100644
--- a/sound/soc/fsl/mpc8610_hpcd.c
+++ b/sound/soc/fsl/mpc8610_hpcd.c
@@ -189,8 +189,7 @@ static int mpc8610_hpcd_probe(struct platform_device *pdev)
189{ 189{
190 struct device *dev = pdev->dev.parent; 190 struct device *dev = pdev->dev.parent;
191 /* ssi_pdev is the platform device for the SSI node that probed us */ 191 /* ssi_pdev is the platform device for the SSI node that probed us */
192 struct platform_device *ssi_pdev = 192 struct platform_device *ssi_pdev = to_platform_device(dev);
193 container_of(dev, struct platform_device, dev);
194 struct device_node *np = ssi_pdev->dev.of_node; 193 struct device_node *np = ssi_pdev->dev.of_node;
195 struct device_node *codec_np = NULL; 194 struct device_node *codec_np = NULL;
196 struct mpc8610_hpcd_data *machine_data; 195 struct mpc8610_hpcd_data *machine_data;
diff --git a/sound/soc/fsl/p1022_ds.c b/sound/soc/fsl/p1022_ds.c
index 747aab0602bd..a1f780ecadf5 100644
--- a/sound/soc/fsl/p1022_ds.c
+++ b/sound/soc/fsl/p1022_ds.c
@@ -199,8 +199,7 @@ static int p1022_ds_probe(struct platform_device *pdev)
199{ 199{
200 struct device *dev = pdev->dev.parent; 200 struct device *dev = pdev->dev.parent;
201 /* ssi_pdev is the platform device for the SSI node that probed us */ 201 /* ssi_pdev is the platform device for the SSI node that probed us */
202 struct platform_device *ssi_pdev = 202 struct platform_device *ssi_pdev = to_platform_device(dev);
203 container_of(dev, struct platform_device, dev);
204 struct device_node *np = ssi_pdev->dev.of_node; 203 struct device_node *np = ssi_pdev->dev.of_node;
205 struct device_node *codec_np = NULL; 204 struct device_node *codec_np = NULL;
206 struct machine_data *mdata; 205 struct machine_data *mdata;
diff --git a/sound/soc/fsl/p1022_rdk.c b/sound/soc/fsl/p1022_rdk.c
index 1dd49e5f9675..d4d88a8cb9c0 100644
--- a/sound/soc/fsl/p1022_rdk.c
+++ b/sound/soc/fsl/p1022_rdk.c
@@ -203,8 +203,7 @@ static int p1022_rdk_probe(struct platform_device *pdev)
203{ 203{
204 struct device *dev = pdev->dev.parent; 204 struct device *dev = pdev->dev.parent;
205 /* ssi_pdev is the platform device for the SSI node that probed us */ 205 /* ssi_pdev is the platform device for the SSI node that probed us */
206 struct platform_device *ssi_pdev = 206 struct platform_device *ssi_pdev = to_platform_device(dev);
207 container_of(dev, struct platform_device, dev);
208 struct device_node *np = ssi_pdev->dev.of_node; 207 struct device_node *np = ssi_pdev->dev.of_node;
209 struct device_node *codec_np = NULL; 208 struct device_node *codec_np = NULL;
210 struct machine_data *mdata; 209 struct machine_data *mdata;
diff --git a/sound/soc/generic/simple-card.c b/sound/soc/generic/simple-card.c
index 54c33204541f..1ded8811598e 100644
--- a/sound/soc/generic/simple-card.c
+++ b/sound/soc/generic/simple-card.c
@@ -45,7 +45,7 @@ static int asoc_simple_card_startup(struct snd_pcm_substream *substream)
45 struct snd_soc_pcm_runtime *rtd = substream->private_data; 45 struct snd_soc_pcm_runtime *rtd = substream->private_data;
46 struct simple_card_data *priv = snd_soc_card_get_drvdata(rtd->card); 46 struct simple_card_data *priv = snd_soc_card_get_drvdata(rtd->card);
47 struct simple_dai_props *dai_props = 47 struct simple_dai_props *dai_props =
48 &priv->dai_props[rtd - rtd->card->rtd]; 48 &priv->dai_props[rtd->num];
49 int ret; 49 int ret;
50 50
51 ret = clk_prepare_enable(dai_props->cpu_dai.clk); 51 ret = clk_prepare_enable(dai_props->cpu_dai.clk);
@@ -64,7 +64,7 @@ static void asoc_simple_card_shutdown(struct snd_pcm_substream *substream)
64 struct snd_soc_pcm_runtime *rtd = substream->private_data; 64 struct snd_soc_pcm_runtime *rtd = substream->private_data;
65 struct simple_card_data *priv = snd_soc_card_get_drvdata(rtd->card); 65 struct simple_card_data *priv = snd_soc_card_get_drvdata(rtd->card);
66 struct simple_dai_props *dai_props = 66 struct simple_dai_props *dai_props =
67 &priv->dai_props[rtd - rtd->card->rtd]; 67 &priv->dai_props[rtd->num];
68 68
69 clk_disable_unprepare(dai_props->cpu_dai.clk); 69 clk_disable_unprepare(dai_props->cpu_dai.clk);
70 70
@@ -78,8 +78,7 @@ static int asoc_simple_card_hw_params(struct snd_pcm_substream *substream,
78 struct snd_soc_dai *codec_dai = rtd->codec_dai; 78 struct snd_soc_dai *codec_dai = rtd->codec_dai;
79 struct snd_soc_dai *cpu_dai = rtd->cpu_dai; 79 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
80 struct simple_card_data *priv = snd_soc_card_get_drvdata(rtd->card); 80 struct simple_card_data *priv = snd_soc_card_get_drvdata(rtd->card);
81 struct simple_dai_props *dai_props = 81 struct simple_dai_props *dai_props = &priv->dai_props[rtd->num];
82 &priv->dai_props[rtd - rtd->card->rtd];
83 unsigned int mclk, mclk_fs = 0; 82 unsigned int mclk, mclk_fs = 0;
84 int ret = 0; 83 int ret = 0;
85 84
@@ -174,10 +173,9 @@ static int asoc_simple_card_dai_init(struct snd_soc_pcm_runtime *rtd)
174 struct snd_soc_dai *codec = rtd->codec_dai; 173 struct snd_soc_dai *codec = rtd->codec_dai;
175 struct snd_soc_dai *cpu = rtd->cpu_dai; 174 struct snd_soc_dai *cpu = rtd->cpu_dai;
176 struct simple_dai_props *dai_props; 175 struct simple_dai_props *dai_props;
177 int num, ret; 176 int ret;
178 177
179 num = rtd - rtd->card->rtd; 178 dai_props = &priv->dai_props[rtd->num];
180 dai_props = &priv->dai_props[num];
181 ret = __asoc_simple_card_dai_init(codec, &dai_props->codec_dai); 179 ret = __asoc_simple_card_dai_init(codec, &dai_props->codec_dai);
182 if (ret < 0) 180 if (ret < 0)
183 return ret; 181 return ret;
diff --git a/sound/soc/img/Kconfig b/sound/soc/img/Kconfig
new file mode 100644
index 000000000000..857a9510ee1c
--- /dev/null
+++ b/sound/soc/img/Kconfig
@@ -0,0 +1,52 @@
1config SND_SOC_IMG
2 bool "Audio support for Imagination Technologies designs"
3 help
4 Audio support for Imagination Technologies audio hardware
5
6config SND_SOC_IMG_I2S_IN
7 tristate "Imagination I2S Input Device Driver"
8 depends on SND_SOC_IMG
9 select SND_SOC_GENERIC_DMAENGINE_PCM
10 help
11 Say Y or M if you want to add support for I2S in driver for
12 Imagination Technologies I2S in device.
13
14config SND_SOC_IMG_I2S_OUT
15 tristate "Imagination I2S Output Device Driver"
16 depends on SND_SOC_IMG
17 select SND_SOC_GENERIC_DMAENGINE_PCM
18 help
19 Say Y or M if you want to add support for I2S out driver for
20 Imagination Technologies I2S out device.
21
22config SND_SOC_IMG_PARALLEL_OUT
23 tristate "Imagination Parallel Output Device Driver"
24 depends on SND_SOC_IMG
25 select SND_SOC_GENERIC_DMAENGINE_PCM
26 help
27 Say Y or M if you want to add support for parallel out driver for
28 Imagination Technologies parallel out device.
29
30config SND_SOC_IMG_SPDIF_IN
31 tristate "Imagination SPDIF Input Device Driver"
32 depends on SND_SOC_IMG
33 select SND_SOC_GENERIC_DMAENGINE_PCM
34 help
35 Say Y or M if you want to add support for SPDIF input driver for
36 Imagination Technologies SPDIF input device.
37
38config SND_SOC_IMG_SPDIF_OUT
39 tristate "Imagination SPDIF Output Device Driver"
40 depends on SND_SOC_IMG
41 select SND_SOC_GENERIC_DMAENGINE_PCM
42 help
43 Say Y or M if you want to add support for SPDIF out driver for
44 Imagination Technologies SPDIF out device.
45
46
47config SND_SOC_IMG_PISTACHIO_INTERNAL_DAC
48 tristate "Support for Pistachio SoC Internal DAC Driver"
49 depends on SND_SOC_IMG
50 help
51 Say Y or M if you want to add support for Pistachio internal DAC
52 driver for Imagination Technologies Pistachio internal DAC device.
diff --git a/sound/soc/img/Makefile b/sound/soc/img/Makefile
new file mode 100644
index 000000000000..0508c1ced636
--- /dev/null
+++ b/sound/soc/img/Makefile
@@ -0,0 +1,7 @@
1obj-$(CONFIG_SND_SOC_IMG_I2S_IN) += img-i2s-in.o
2obj-$(CONFIG_SND_SOC_IMG_I2S_OUT) += img-i2s-out.o
3obj-$(CONFIG_SND_SOC_IMG_PARALLEL_OUT) += img-parallel-out.o
4obj-$(CONFIG_SND_SOC_IMG_SPDIF_IN) += img-spdif-in.o
5obj-$(CONFIG_SND_SOC_IMG_SPDIF_OUT) += img-spdif-out.o
6
7obj-$(CONFIG_SND_SOC_IMG_PISTACHIO_INTERNAL_DAC) += pistachio-internal-dac.o
diff --git a/sound/soc/img/img-i2s-in.c b/sound/soc/img/img-i2s-in.c
new file mode 100644
index 000000000000..0389203f8560
--- /dev/null
+++ b/sound/soc/img/img-i2s-in.c
@@ -0,0 +1,516 @@
1/*
2 * IMG I2S input controller driver
3 *
4 * Copyright (C) 2015 Imagination Technologies Ltd.
5 *
6 * Author: Damien Horsley <Damien.Horsley@imgtec.com>
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms and conditions of the GNU General Public License,
10 * version 2, as published by the Free Software Foundation.
11 */
12
13#include <linux/clk.h>
14#include <linux/init.h>
15#include <linux/kernel.h>
16#include <linux/module.h>
17#include <linux/of.h>
18#include <linux/platform_device.h>
19#include <linux/reset.h>
20
21#include <sound/core.h>
22#include <sound/dmaengine_pcm.h>
23#include <sound/initval.h>
24#include <sound/pcm.h>
25#include <sound/pcm_params.h>
26#include <sound/soc.h>
27
28#define IMG_I2S_IN_RX_FIFO 0x0
29
30#define IMG_I2S_IN_CTL 0x4
31#define IMG_I2S_IN_CTL_ACTIVE_CHAN_MASK 0xfffffffc
32#define IMG_I2S_IN_CTL_ACTIVE_CH_SHIFT 2
33#define IMG_I2S_IN_CTL_16PACK_MASK BIT(1)
34#define IMG_I2S_IN_CTL_ME_MASK BIT(0)
35
36#define IMG_I2S_IN_CH_CTL 0x4
37#define IMG_I2S_IN_CH_CTL_CCDEL_MASK 0x38000
38#define IMG_I2S_IN_CH_CTL_CCDEL_SHIFT 15
39#define IMG_I2S_IN_CH_CTL_FEN_MASK BIT(14)
40#define IMG_I2S_IN_CH_CTL_FMODE_MASK BIT(13)
41#define IMG_I2S_IN_CH_CTL_16PACK_MASK BIT(12)
42#define IMG_I2S_IN_CH_CTL_JUST_MASK BIT(10)
43#define IMG_I2S_IN_CH_CTL_PACKH_MASK BIT(9)
44#define IMG_I2S_IN_CH_CTL_CLK_TRANS_MASK BIT(8)
45#define IMG_I2S_IN_CH_CTL_BLKP_MASK BIT(7)
46#define IMG_I2S_IN_CH_CTL_FIFO_FLUSH_MASK BIT(6)
47#define IMG_I2S_IN_CH_CTL_LRD_MASK BIT(3)
48#define IMG_I2S_IN_CH_CTL_FW_MASK BIT(2)
49#define IMG_I2S_IN_CH_CTL_SW_MASK BIT(1)
50#define IMG_I2S_IN_CH_CTL_ME_MASK BIT(0)
51
52#define IMG_I2S_IN_CH_STRIDE 0x20
53
54struct img_i2s_in {
55 void __iomem *base;
56 struct clk *clk_sys;
57 struct snd_dmaengine_dai_dma_data dma_data;
58 struct device *dev;
59 unsigned int max_i2s_chan;
60 void __iomem *channel_base;
61 unsigned int active_channels;
62 struct snd_soc_dai_driver dai_driver;
63};
64
65static inline void img_i2s_in_writel(struct img_i2s_in *i2s, u32 val, u32 reg)
66{
67 writel(val, i2s->base + reg);
68}
69
70static inline u32 img_i2s_in_readl(struct img_i2s_in *i2s, u32 reg)
71{
72 return readl(i2s->base + reg);
73}
74
75static inline void img_i2s_in_ch_writel(struct img_i2s_in *i2s, u32 chan,
76 u32 val, u32 reg)
77{
78 writel(val, i2s->channel_base + (chan * IMG_I2S_IN_CH_STRIDE) + reg);
79}
80
81static inline u32 img_i2s_in_ch_readl(struct img_i2s_in *i2s, u32 chan,
82 u32 reg)
83{
84 return readl(i2s->channel_base + (chan * IMG_I2S_IN_CH_STRIDE) + reg);
85}
86
87static inline void img_i2s_in_ch_disable(struct img_i2s_in *i2s, u32 chan)
88{
89 u32 reg;
90
91 reg = img_i2s_in_ch_readl(i2s, chan, IMG_I2S_IN_CH_CTL);
92 reg &= ~IMG_I2S_IN_CH_CTL_ME_MASK;
93 img_i2s_in_ch_writel(i2s, chan, reg, IMG_I2S_IN_CH_CTL);
94}
95
96static inline void img_i2s_in_ch_enable(struct img_i2s_in *i2s, u32 chan)
97{
98 u32 reg;
99
100 reg = img_i2s_in_ch_readl(i2s, chan, IMG_I2S_IN_CH_CTL);
101 reg |= IMG_I2S_IN_CH_CTL_ME_MASK;
102 img_i2s_in_ch_writel(i2s, chan, reg, IMG_I2S_IN_CH_CTL);
103}
104
105static inline void img_i2s_in_disable(struct img_i2s_in *i2s)
106{
107 u32 reg;
108
109 reg = img_i2s_in_readl(i2s, IMG_I2S_IN_CTL);
110 reg &= ~IMG_I2S_IN_CTL_ME_MASK;
111 img_i2s_in_writel(i2s, reg, IMG_I2S_IN_CTL);
112}
113
114static inline void img_i2s_in_enable(struct img_i2s_in *i2s)
115{
116 u32 reg;
117
118 reg = img_i2s_in_readl(i2s, IMG_I2S_IN_CTL);
119 reg |= IMG_I2S_IN_CTL_ME_MASK;
120 img_i2s_in_writel(i2s, reg, IMG_I2S_IN_CTL);
121}
122
123static inline void img_i2s_in_flush(struct img_i2s_in *i2s)
124{
125 int i;
126 u32 reg;
127
128 for (i = 0; i < i2s->active_channels; i++) {
129 reg = img_i2s_in_ch_readl(i2s, i, IMG_I2S_IN_CH_CTL);
130 reg |= IMG_I2S_IN_CH_CTL_FIFO_FLUSH_MASK;
131 img_i2s_in_ch_writel(i2s, i, reg, IMG_I2S_IN_CH_CTL);
132 reg &= ~IMG_I2S_IN_CH_CTL_FIFO_FLUSH_MASK;
133 img_i2s_in_ch_writel(i2s, i, reg, IMG_I2S_IN_CH_CTL);
134 }
135}
136
137static int img_i2s_in_trigger(struct snd_pcm_substream *substream, int cmd,
138 struct snd_soc_dai *dai)
139{
140 struct img_i2s_in *i2s = snd_soc_dai_get_drvdata(dai);
141
142 switch (cmd) {
143 case SNDRV_PCM_TRIGGER_START:
144 case SNDRV_PCM_TRIGGER_RESUME:
145 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
146 img_i2s_in_enable(i2s);
147 break;
148
149 case SNDRV_PCM_TRIGGER_STOP:
150 case SNDRV_PCM_TRIGGER_SUSPEND:
151 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
152 img_i2s_in_disable(i2s);
153 break;
154 default:
155 return -EINVAL;
156 }
157
158 return 0;
159}
160
161static int img_i2s_in_check_rate(struct img_i2s_in *i2s,
162 unsigned int sample_rate, unsigned int frame_size,
163 unsigned int *bclk_filter_enable,
164 unsigned int *bclk_filter_value)
165{
166 unsigned int bclk_freq, cur_freq;
167
168 bclk_freq = sample_rate * frame_size;
169
170 cur_freq = clk_get_rate(i2s->clk_sys);
171
172 if (cur_freq >= bclk_freq * 8) {
173 *bclk_filter_enable = 1;
174 *bclk_filter_value = 0;
175 } else if (cur_freq >= bclk_freq * 7) {
176 *bclk_filter_enable = 1;
177 *bclk_filter_value = 1;
178 } else if (cur_freq >= bclk_freq * 6) {
179 *bclk_filter_enable = 0;
180 *bclk_filter_value = 0;
181 } else {
182 dev_err(i2s->dev,
183 "Sys clock rate %u insufficient for sample rate %u\n",
184 cur_freq, sample_rate);
185 return -EINVAL;
186 }
187
188 return 0;
189}
190
191static int img_i2s_in_hw_params(struct snd_pcm_substream *substream,
192 struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
193{
194 struct img_i2s_in *i2s = snd_soc_dai_get_drvdata(dai);
195 unsigned int rate, channels, i2s_channels, frame_size;
196 unsigned int bclk_filter_enable, bclk_filter_value;
197 int i, ret = 0;
198 u32 reg, control_mask, chan_control_mask;
199 u32 control_set = 0, chan_control_set = 0;
200 snd_pcm_format_t format;
201
202 rate = params_rate(params);
203 format = params_format(params);
204 channels = params_channels(params);
205 i2s_channels = channels / 2;
206
207 switch (format) {
208 case SNDRV_PCM_FORMAT_S32_LE:
209 frame_size = 64;
210 chan_control_set |= IMG_I2S_IN_CH_CTL_SW_MASK;
211 chan_control_set |= IMG_I2S_IN_CH_CTL_FW_MASK;
212 chan_control_set |= IMG_I2S_IN_CH_CTL_PACKH_MASK;
213 break;
214 case SNDRV_PCM_FORMAT_S24_LE:
215 frame_size = 64;
216 chan_control_set |= IMG_I2S_IN_CH_CTL_SW_MASK;
217 chan_control_set |= IMG_I2S_IN_CH_CTL_FW_MASK;
218 break;
219 case SNDRV_PCM_FORMAT_S16_LE:
220 frame_size = 32;
221 control_set |= IMG_I2S_IN_CTL_16PACK_MASK;
222 chan_control_set |= IMG_I2S_IN_CH_CTL_16PACK_MASK;
223 break;
224 default:
225 return -EINVAL;
226 }
227
228 if ((channels < 2) ||
229 (channels > (i2s->max_i2s_chan * 2)) ||
230 (channels % 2))
231 return -EINVAL;
232
233 control_set |= ((i2s_channels - 1) << IMG_I2S_IN_CTL_ACTIVE_CH_SHIFT);
234
235 ret = img_i2s_in_check_rate(i2s, rate, frame_size,
236 &bclk_filter_enable, &bclk_filter_value);
237 if (ret < 0)
238 return ret;
239
240 if (bclk_filter_enable)
241 chan_control_set |= IMG_I2S_IN_CH_CTL_FEN_MASK;
242
243 if (bclk_filter_value)
244 chan_control_set |= IMG_I2S_IN_CH_CTL_FMODE_MASK;
245
246 control_mask = IMG_I2S_IN_CTL_16PACK_MASK |
247 IMG_I2S_IN_CTL_ACTIVE_CHAN_MASK;
248
249 chan_control_mask = IMG_I2S_IN_CH_CTL_16PACK_MASK |
250 IMG_I2S_IN_CH_CTL_FEN_MASK |
251 IMG_I2S_IN_CH_CTL_FMODE_MASK |
252 IMG_I2S_IN_CH_CTL_SW_MASK |
253 IMG_I2S_IN_CH_CTL_FW_MASK |
254 IMG_I2S_IN_CH_CTL_PACKH_MASK;
255
256 reg = img_i2s_in_readl(i2s, IMG_I2S_IN_CTL);
257 reg = (reg & ~control_mask) | control_set;
258 img_i2s_in_writel(i2s, reg, IMG_I2S_IN_CTL);
259
260 for (i = 0; i < i2s->active_channels; i++)
261 img_i2s_in_ch_disable(i2s, i);
262
263 for (i = 0; i < i2s->max_i2s_chan; i++) {
264 reg = img_i2s_in_ch_readl(i2s, i, IMG_I2S_IN_CH_CTL);
265 reg = (reg & ~chan_control_mask) | chan_control_set;
266 img_i2s_in_ch_writel(i2s, i, reg, IMG_I2S_IN_CH_CTL);
267 }
268
269 i2s->active_channels = i2s_channels;
270
271 img_i2s_in_flush(i2s);
272
273 for (i = 0; i < i2s->active_channels; i++)
274 img_i2s_in_ch_enable(i2s, i);
275
276 return 0;
277}
278
279static int img_i2s_in_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
280{
281 struct img_i2s_in *i2s = snd_soc_dai_get_drvdata(dai);
282 int i;
283 u32 chan_control_mask, lrd_set = 0, blkp_set = 0, chan_control_set = 0;
284 u32 reg;
285
286 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
287 case SND_SOC_DAIFMT_NB_NF:
288 lrd_set |= IMG_I2S_IN_CH_CTL_LRD_MASK;
289 break;
290 case SND_SOC_DAIFMT_NB_IF:
291 break;
292 case SND_SOC_DAIFMT_IB_NF:
293 lrd_set |= IMG_I2S_IN_CH_CTL_LRD_MASK;
294 blkp_set |= IMG_I2S_IN_CH_CTL_BLKP_MASK;
295 break;
296 case SND_SOC_DAIFMT_IB_IF:
297 blkp_set |= IMG_I2S_IN_CH_CTL_BLKP_MASK;
298 break;
299 default:
300 return -EINVAL;
301 }
302
303 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
304 case SND_SOC_DAIFMT_I2S:
305 chan_control_set |= IMG_I2S_IN_CH_CTL_CLK_TRANS_MASK;
306 break;
307 case SND_SOC_DAIFMT_LEFT_J:
308 break;
309 default:
310 return -EINVAL;
311 }
312
313 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
314 case SND_SOC_DAIFMT_CBM_CFM:
315 break;
316 default:
317 return -EINVAL;
318 }
319
320 chan_control_mask = IMG_I2S_IN_CH_CTL_CLK_TRANS_MASK;
321
322 for (i = 0; i < i2s->active_channels; i++)
323 img_i2s_in_ch_disable(i2s, i);
324
325 /*
326 * BLKP and LRD must be set during separate register writes
327 */
328 for (i = 0; i < i2s->max_i2s_chan; i++) {
329 reg = img_i2s_in_ch_readl(i2s, i, IMG_I2S_IN_CH_CTL);
330 reg = (reg & ~chan_control_mask) | chan_control_set;
331 img_i2s_in_ch_writel(i2s, i, reg, IMG_I2S_IN_CH_CTL);
332 reg = (reg & ~IMG_I2S_IN_CH_CTL_BLKP_MASK) | blkp_set;
333 img_i2s_in_ch_writel(i2s, i, reg, IMG_I2S_IN_CH_CTL);
334 reg = (reg & ~IMG_I2S_IN_CH_CTL_LRD_MASK) | lrd_set;
335 img_i2s_in_ch_writel(i2s, i, reg, IMG_I2S_IN_CH_CTL);
336 }
337
338 for (i = 0; i < i2s->active_channels; i++)
339 img_i2s_in_ch_enable(i2s, i);
340
341 return 0;
342}
343
344static const struct snd_soc_dai_ops img_i2s_in_dai_ops = {
345 .trigger = img_i2s_in_trigger,
346 .hw_params = img_i2s_in_hw_params,
347 .set_fmt = img_i2s_in_set_fmt
348};
349
350static int img_i2s_in_dai_probe(struct snd_soc_dai *dai)
351{
352 struct img_i2s_in *i2s = snd_soc_dai_get_drvdata(dai);
353
354 snd_soc_dai_init_dma_data(dai, NULL, &i2s->dma_data);
355
356 return 0;
357}
358
359static const struct snd_soc_component_driver img_i2s_in_component = {
360 .name = "img-i2s-in"
361};
362
363static int img_i2s_in_dma_prepare_slave_config(struct snd_pcm_substream *st,
364 struct snd_pcm_hw_params *params, struct dma_slave_config *sc)
365{
366 unsigned int i2s_channels = params_channels(params) / 2;
367 struct snd_soc_pcm_runtime *rtd = st->private_data;
368 struct snd_dmaengine_dai_dma_data *dma_data;
369 int ret;
370
371 dma_data = snd_soc_dai_get_dma_data(rtd->cpu_dai, st);
372
373 ret = snd_hwparams_to_dma_slave_config(st, params, sc);
374 if (ret)
375 return ret;
376
377 sc->src_addr = dma_data->addr;
378 sc->src_addr_width = dma_data->addr_width;
379 sc->src_maxburst = 4 * i2s_channels;
380
381 return 0;
382}
383
384static const struct snd_dmaengine_pcm_config img_i2s_in_dma_config = {
385 .prepare_slave_config = img_i2s_in_dma_prepare_slave_config
386};
387
388static int img_i2s_in_probe(struct platform_device *pdev)
389{
390 struct img_i2s_in *i2s;
391 struct resource *res;
392 void __iomem *base;
393 int ret, i;
394 struct reset_control *rst;
395 unsigned int max_i2s_chan_pow_2;
396 struct device *dev = &pdev->dev;
397
398 i2s = devm_kzalloc(dev, sizeof(*i2s), GFP_KERNEL);
399 if (!i2s)
400 return -ENOMEM;
401
402 platform_set_drvdata(pdev, i2s);
403
404 i2s->dev = dev;
405
406 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
407 base = devm_ioremap_resource(dev, res);
408 if (IS_ERR(base))
409 return PTR_ERR(base);
410
411 i2s->base = base;
412
413 if (of_property_read_u32(pdev->dev.of_node, "img,i2s-channels",
414 &i2s->max_i2s_chan)) {
415 dev_err(dev, "No img,i2s-channels property\n");
416 return -EINVAL;
417 }
418
419 max_i2s_chan_pow_2 = 1 << get_count_order(i2s->max_i2s_chan);
420
421 i2s->channel_base = base + (max_i2s_chan_pow_2 * 0x20);
422
423 i2s->clk_sys = devm_clk_get(dev, "sys");
424 if (IS_ERR(i2s->clk_sys)) {
425 if (PTR_ERR(i2s->clk_sys) != -EPROBE_DEFER)
426 dev_err(dev, "Failed to acquire clock 'sys'\n");
427 return PTR_ERR(i2s->clk_sys);
428 }
429
430 ret = clk_prepare_enable(i2s->clk_sys);
431 if (ret)
432 return ret;
433
434 i2s->active_channels = 1;
435 i2s->dma_data.addr = res->start + IMG_I2S_IN_RX_FIFO;
436 i2s->dma_data.addr_width = 4;
437
438 i2s->dai_driver.probe = img_i2s_in_dai_probe;
439 i2s->dai_driver.capture.channels_min = 2;
440 i2s->dai_driver.capture.channels_max = i2s->max_i2s_chan * 2;
441 i2s->dai_driver.capture.rates = SNDRV_PCM_RATE_8000_192000;
442 i2s->dai_driver.capture.formats = SNDRV_PCM_FMTBIT_S32_LE |
443 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S16_LE;
444 i2s->dai_driver.ops = &img_i2s_in_dai_ops;
445
446 rst = devm_reset_control_get(dev, "rst");
447 if (IS_ERR(rst)) {
448 if (PTR_ERR(rst) == -EPROBE_DEFER) {
449 ret = -EPROBE_DEFER;
450 goto err_clk_disable;
451 }
452
453 dev_dbg(dev, "No top level reset found\n");
454
455 img_i2s_in_disable(i2s);
456
457 for (i = 0; i < i2s->max_i2s_chan; i++)
458 img_i2s_in_ch_disable(i2s, i);
459 } else {
460 reset_control_assert(rst);
461 reset_control_deassert(rst);
462 }
463
464 img_i2s_in_writel(i2s, 0, IMG_I2S_IN_CTL);
465
466 for (i = 0; i < i2s->max_i2s_chan; i++)
467 img_i2s_in_ch_writel(i2s, i,
468 (4 << IMG_I2S_IN_CH_CTL_CCDEL_SHIFT) |
469 IMG_I2S_IN_CH_CTL_JUST_MASK |
470 IMG_I2S_IN_CH_CTL_FW_MASK, IMG_I2S_IN_CH_CTL);
471
472 ret = devm_snd_soc_register_component(dev, &img_i2s_in_component,
473 &i2s->dai_driver, 1);
474 if (ret)
475 goto err_clk_disable;
476
477 ret = devm_snd_dmaengine_pcm_register(dev, &img_i2s_in_dma_config, 0);
478 if (ret)
479 goto err_clk_disable;
480
481 return 0;
482
483err_clk_disable:
484 clk_disable_unprepare(i2s->clk_sys);
485
486 return ret;
487}
488
489static int img_i2s_in_dev_remove(struct platform_device *pdev)
490{
491 struct img_i2s_in *i2s = platform_get_drvdata(pdev);
492
493 clk_disable_unprepare(i2s->clk_sys);
494
495 return 0;
496}
497
498static const struct of_device_id img_i2s_in_of_match[] = {
499 { .compatible = "img,i2s-in" },
500 {}
501};
502MODULE_DEVICE_TABLE(of, img_i2s_in_of_match);
503
504static struct platform_driver img_i2s_in_driver = {
505 .driver = {
506 .name = "img-i2s-in",
507 .of_match_table = img_i2s_in_of_match
508 },
509 .probe = img_i2s_in_probe,
510 .remove = img_i2s_in_dev_remove
511};
512module_platform_driver(img_i2s_in_driver);
513
514MODULE_AUTHOR("Damien Horsley <Damien.Horsley@imgtec.com>");
515MODULE_DESCRIPTION("IMG I2S Input Driver");
516MODULE_LICENSE("GPL v2");
diff --git a/sound/soc/img/img-i2s-out.c b/sound/soc/img/img-i2s-out.c
new file mode 100644
index 000000000000..5f997135a8ae
--- /dev/null
+++ b/sound/soc/img/img-i2s-out.c
@@ -0,0 +1,565 @@
1/*
2 * IMG I2S output controller driver
3 *
4 * Copyright (C) 2015 Imagination Technologies Ltd.
5 *
6 * Author: Damien Horsley <Damien.Horsley@imgtec.com>
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms and conditions of the GNU General Public License,
10 * version 2, as published by the Free Software Foundation.
11 */
12
13#include <linux/clk.h>
14#include <linux/init.h>
15#include <linux/kernel.h>
16#include <linux/module.h>
17#include <linux/of.h>
18#include <linux/platform_device.h>
19#include <linux/pm_runtime.h>
20#include <linux/reset.h>
21
22#include <sound/core.h>
23#include <sound/dmaengine_pcm.h>
24#include <sound/initval.h>
25#include <sound/pcm.h>
26#include <sound/pcm_params.h>
27#include <sound/soc.h>
28
29#define IMG_I2S_OUT_TX_FIFO 0x0
30
31#define IMG_I2S_OUT_CTL 0x4
32#define IMG_I2S_OUT_CTL_DATA_EN_MASK BIT(24)
33#define IMG_I2S_OUT_CTL_ACTIVE_CHAN_MASK 0xffe000
34#define IMG_I2S_OUT_CTL_ACTIVE_CHAN_SHIFT 13
35#define IMG_I2S_OUT_CTL_FRM_SIZE_MASK BIT(8)
36#define IMG_I2S_OUT_CTL_MASTER_MASK BIT(6)
37#define IMG_I2S_OUT_CTL_CLK_MASK BIT(5)
38#define IMG_I2S_OUT_CTL_CLK_EN_MASK BIT(4)
39#define IMG_I2S_OUT_CTL_FRM_CLK_POL_MASK BIT(3)
40#define IMG_I2S_OUT_CTL_BCLK_POL_MASK BIT(2)
41#define IMG_I2S_OUT_CTL_ME_MASK BIT(0)
42
43#define IMG_I2S_OUT_CH_CTL 0x4
44#define IMG_I2S_OUT_CHAN_CTL_CH_MASK BIT(11)
45#define IMG_I2S_OUT_CHAN_CTL_LT_MASK BIT(10)
46#define IMG_I2S_OUT_CHAN_CTL_FMT_MASK 0xf0
47#define IMG_I2S_OUT_CHAN_CTL_FMT_SHIFT 4
48#define IMG_I2S_OUT_CHAN_CTL_JUST_MASK BIT(3)
49#define IMG_I2S_OUT_CHAN_CTL_CLKT_MASK BIT(1)
50#define IMG_I2S_OUT_CHAN_CTL_ME_MASK BIT(0)
51
52#define IMG_I2S_OUT_CH_STRIDE 0x20
53
54struct img_i2s_out {
55 void __iomem *base;
56 struct clk *clk_sys;
57 struct clk *clk_ref;
58 struct snd_dmaengine_dai_dma_data dma_data;
59 struct device *dev;
60 unsigned int max_i2s_chan;
61 void __iomem *channel_base;
62 bool force_clk_active;
63 unsigned int active_channels;
64 struct reset_control *rst;
65 struct snd_soc_dai_driver dai_driver;
66};
67
68static int img_i2s_out_suspend(struct device *dev)
69{
70 struct img_i2s_out *i2s = dev_get_drvdata(dev);
71
72 if (!i2s->force_clk_active)
73 clk_disable_unprepare(i2s->clk_ref);
74
75 return 0;
76}
77
78static int img_i2s_out_resume(struct device *dev)
79{
80 struct img_i2s_out *i2s = dev_get_drvdata(dev);
81 int ret;
82
83 if (!i2s->force_clk_active) {
84 ret = clk_prepare_enable(i2s->clk_ref);
85 if (ret) {
86 dev_err(dev, "clk_enable failed: %d\n", ret);
87 return ret;
88 }
89 }
90
91 return 0;
92}
93
94static inline void img_i2s_out_writel(struct img_i2s_out *i2s, u32 val,
95 u32 reg)
96{
97 writel(val, i2s->base + reg);
98}
99
100static inline u32 img_i2s_out_readl(struct img_i2s_out *i2s, u32 reg)
101{
102 return readl(i2s->base + reg);
103}
104
105static inline void img_i2s_out_ch_writel(struct img_i2s_out *i2s,
106 u32 chan, u32 val, u32 reg)
107{
108 writel(val, i2s->channel_base + (chan * IMG_I2S_OUT_CH_STRIDE) + reg);
109}
110
111static inline u32 img_i2s_out_ch_readl(struct img_i2s_out *i2s, u32 chan,
112 u32 reg)
113{
114 return readl(i2s->channel_base + (chan * IMG_I2S_OUT_CH_STRIDE) + reg);
115}
116
117static inline void img_i2s_out_ch_disable(struct img_i2s_out *i2s, u32 chan)
118{
119 u32 reg;
120
121 reg = img_i2s_out_ch_readl(i2s, chan, IMG_I2S_OUT_CH_CTL);
122 reg &= ~IMG_I2S_OUT_CHAN_CTL_ME_MASK;
123 img_i2s_out_ch_writel(i2s, chan, reg, IMG_I2S_OUT_CH_CTL);
124}
125
126static inline void img_i2s_out_ch_enable(struct img_i2s_out *i2s, u32 chan)
127{
128 u32 reg;
129
130 reg = img_i2s_out_ch_readl(i2s, chan, IMG_I2S_OUT_CH_CTL);
131 reg |= IMG_I2S_OUT_CHAN_CTL_ME_MASK;
132 img_i2s_out_ch_writel(i2s, chan, reg, IMG_I2S_OUT_CH_CTL);
133}
134
135static inline void img_i2s_out_disable(struct img_i2s_out *i2s)
136{
137 u32 reg;
138
139 reg = img_i2s_out_readl(i2s, IMG_I2S_OUT_CTL);
140 reg &= ~IMG_I2S_OUT_CTL_ME_MASK;
141 img_i2s_out_writel(i2s, reg, IMG_I2S_OUT_CTL);
142}
143
144static inline void img_i2s_out_enable(struct img_i2s_out *i2s)
145{
146 u32 reg;
147
148 reg = img_i2s_out_readl(i2s, IMG_I2S_OUT_CTL);
149 reg |= IMG_I2S_OUT_CTL_ME_MASK;
150 img_i2s_out_writel(i2s, reg, IMG_I2S_OUT_CTL);
151}
152
153static void img_i2s_out_reset(struct img_i2s_out *i2s)
154{
155 int i;
156 u32 core_ctl, chan_ctl;
157
158 core_ctl = img_i2s_out_readl(i2s, IMG_I2S_OUT_CTL) &
159 ~IMG_I2S_OUT_CTL_ME_MASK &
160 ~IMG_I2S_OUT_CTL_DATA_EN_MASK;
161
162 if (!i2s->force_clk_active)
163 core_ctl &= ~IMG_I2S_OUT_CTL_CLK_EN_MASK;
164
165 chan_ctl = img_i2s_out_ch_readl(i2s, 0, IMG_I2S_OUT_CH_CTL) &
166 ~IMG_I2S_OUT_CHAN_CTL_ME_MASK;
167
168 reset_control_assert(i2s->rst);
169 reset_control_deassert(i2s->rst);
170
171 for (i = 0; i < i2s->max_i2s_chan; i++)
172 img_i2s_out_ch_writel(i2s, i, chan_ctl, IMG_I2S_OUT_CH_CTL);
173
174 for (i = 0; i < i2s->active_channels; i++)
175 img_i2s_out_ch_enable(i2s, i);
176
177 img_i2s_out_writel(i2s, core_ctl, IMG_I2S_OUT_CTL);
178 img_i2s_out_enable(i2s);
179}
180
181static int img_i2s_out_trigger(struct snd_pcm_substream *substream, int cmd,
182 struct snd_soc_dai *dai)
183{
184 struct img_i2s_out *i2s = snd_soc_dai_get_drvdata(dai);
185 u32 reg;
186
187 switch (cmd) {
188 case SNDRV_PCM_TRIGGER_START:
189 case SNDRV_PCM_TRIGGER_RESUME:
190 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
191 reg = img_i2s_out_readl(i2s, IMG_I2S_OUT_CTL);
192 if (!i2s->force_clk_active)
193 reg |= IMG_I2S_OUT_CTL_CLK_EN_MASK;
194 reg |= IMG_I2S_OUT_CTL_DATA_EN_MASK;
195 img_i2s_out_writel(i2s, reg, IMG_I2S_OUT_CTL);
196 break;
197 case SNDRV_PCM_TRIGGER_STOP:
198 case SNDRV_PCM_TRIGGER_SUSPEND:
199 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
200 img_i2s_out_reset(i2s);
201 break;
202 default:
203 return -EINVAL;
204 }
205
206 return 0;
207}
208
209static int img_i2s_out_hw_params(struct snd_pcm_substream *substream,
210 struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
211{
212 struct img_i2s_out *i2s = snd_soc_dai_get_drvdata(dai);
213 unsigned int channels, i2s_channels;
214 long pre_div_a, pre_div_b, diff_a, diff_b, rate, clk_rate;
215 int i;
216 u32 reg, control_mask, control_set = 0;
217 snd_pcm_format_t format;
218
219 rate = params_rate(params);
220 format = params_format(params);
221 channels = params_channels(params);
222 i2s_channels = channels / 2;
223
224 if (format != SNDRV_PCM_FORMAT_S32_LE)
225 return -EINVAL;
226
227 if ((channels < 2) ||
228 (channels > (i2s->max_i2s_chan * 2)) ||
229 (channels % 2))
230 return -EINVAL;
231
232 pre_div_a = clk_round_rate(i2s->clk_ref, rate * 256);
233 if (pre_div_a < 0)
234 return pre_div_a;
235 pre_div_b = clk_round_rate(i2s->clk_ref, rate * 384);
236 if (pre_div_b < 0)
237 return pre_div_b;
238
239 diff_a = abs((pre_div_a / 256) - rate);
240 diff_b = abs((pre_div_b / 384) - rate);
241
242 /* If diffs are equal, use lower clock rate */
243 if (diff_a > diff_b)
244 clk_set_rate(i2s->clk_ref, pre_div_b);
245 else
246 clk_set_rate(i2s->clk_ref, pre_div_a);
247
248 /*
249 * Another driver (eg alsa machine driver) may have rejected the above
250 * change. Get the current rate and set the register bit according to
251 * the new minimum diff
252 */
253 clk_rate = clk_get_rate(i2s->clk_ref);
254
255 diff_a = abs((clk_rate / 256) - rate);
256 diff_b = abs((clk_rate / 384) - rate);
257
258 if (diff_a > diff_b)
259 control_set |= IMG_I2S_OUT_CTL_CLK_MASK;
260
261 control_set |= ((i2s_channels - 1) <<
262 IMG_I2S_OUT_CTL_ACTIVE_CHAN_SHIFT) &
263 IMG_I2S_OUT_CTL_ACTIVE_CHAN_MASK;
264
265 control_mask = IMG_I2S_OUT_CTL_CLK_MASK |
266 IMG_I2S_OUT_CTL_ACTIVE_CHAN_MASK;
267
268 img_i2s_out_disable(i2s);
269
270 reg = img_i2s_out_readl(i2s, IMG_I2S_OUT_CTL);
271 reg = (reg & ~control_mask) | control_set;
272 img_i2s_out_writel(i2s, reg, IMG_I2S_OUT_CTL);
273
274 for (i = 0; i < i2s_channels; i++)
275 img_i2s_out_ch_enable(i2s, i);
276
277 for (; i < i2s->max_i2s_chan; i++)
278 img_i2s_out_ch_disable(i2s, i);
279
280 img_i2s_out_enable(i2s);
281
282 i2s->active_channels = i2s_channels;
283
284 return 0;
285}
286
287static int img_i2s_out_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
288{
289 struct img_i2s_out *i2s = snd_soc_dai_get_drvdata(dai);
290 int i;
291 bool force_clk_active;
292 u32 chan_control_mask, control_mask, chan_control_set = 0;
293 u32 reg, control_set = 0;
294
295 force_clk_active = ((fmt & SND_SOC_DAIFMT_CLOCK_MASK) ==
296 SND_SOC_DAIFMT_CONT);
297
298 if (force_clk_active)
299 control_set |= IMG_I2S_OUT_CTL_CLK_EN_MASK;
300
301 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
302 case SND_SOC_DAIFMT_CBM_CFM:
303 break;
304 case SND_SOC_DAIFMT_CBS_CFS:
305 control_set |= IMG_I2S_OUT_CTL_MASTER_MASK;
306 break;
307 default:
308 return -EINVAL;
309 }
310
311 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
312 case SND_SOC_DAIFMT_NB_NF:
313 control_set |= IMG_I2S_OUT_CTL_BCLK_POL_MASK;
314 break;
315 case SND_SOC_DAIFMT_NB_IF:
316 control_set |= IMG_I2S_OUT_CTL_BCLK_POL_MASK;
317 control_set |= IMG_I2S_OUT_CTL_FRM_CLK_POL_MASK;
318 break;
319 case SND_SOC_DAIFMT_IB_NF:
320 break;
321 case SND_SOC_DAIFMT_IB_IF:
322 control_set |= IMG_I2S_OUT_CTL_FRM_CLK_POL_MASK;
323 break;
324 default:
325 return -EINVAL;
326 }
327
328 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
329 case SND_SOC_DAIFMT_I2S:
330 chan_control_set |= IMG_I2S_OUT_CHAN_CTL_CLKT_MASK;
331 break;
332 case SND_SOC_DAIFMT_LEFT_J:
333 break;
334 default:
335 return -EINVAL;
336 }
337
338 control_mask = IMG_I2S_OUT_CTL_CLK_EN_MASK |
339 IMG_I2S_OUT_CTL_MASTER_MASK |
340 IMG_I2S_OUT_CTL_BCLK_POL_MASK |
341 IMG_I2S_OUT_CTL_FRM_CLK_POL_MASK;
342
343 chan_control_mask = IMG_I2S_OUT_CHAN_CTL_CLKT_MASK;
344
345 img_i2s_out_disable(i2s);
346
347 reg = img_i2s_out_readl(i2s, IMG_I2S_OUT_CTL);
348 reg = (reg & ~control_mask) | control_set;
349 img_i2s_out_writel(i2s, reg, IMG_I2S_OUT_CTL);
350
351 for (i = 0; i < i2s->active_channels; i++)
352 img_i2s_out_ch_disable(i2s, i);
353
354 for (i = 0; i < i2s->max_i2s_chan; i++) {
355 reg = img_i2s_out_ch_readl(i2s, i, IMG_I2S_OUT_CH_CTL);
356 reg = (reg & ~chan_control_mask) | chan_control_set;
357 img_i2s_out_ch_writel(i2s, i, reg, IMG_I2S_OUT_CH_CTL);
358 }
359
360 for (i = 0; i < i2s->active_channels; i++)
361 img_i2s_out_ch_enable(i2s, i);
362
363 img_i2s_out_enable(i2s);
364
365 i2s->force_clk_active = force_clk_active;
366
367 return 0;
368}
369
370static const struct snd_soc_dai_ops img_i2s_out_dai_ops = {
371 .trigger = img_i2s_out_trigger,
372 .hw_params = img_i2s_out_hw_params,
373 .set_fmt = img_i2s_out_set_fmt
374};
375
376static int img_i2s_out_dai_probe(struct snd_soc_dai *dai)
377{
378 struct img_i2s_out *i2s = snd_soc_dai_get_drvdata(dai);
379
380 snd_soc_dai_init_dma_data(dai, &i2s->dma_data, NULL);
381
382 return 0;
383}
384
385static const struct snd_soc_component_driver img_i2s_out_component = {
386 .name = "img-i2s-out"
387};
388
389static int img_i2s_out_dma_prepare_slave_config(struct snd_pcm_substream *st,
390 struct snd_pcm_hw_params *params, struct dma_slave_config *sc)
391{
392 unsigned int i2s_channels = params_channels(params) / 2;
393 struct snd_soc_pcm_runtime *rtd = st->private_data;
394 struct snd_dmaengine_dai_dma_data *dma_data;
395 int ret;
396
397 dma_data = snd_soc_dai_get_dma_data(rtd->cpu_dai, st);
398
399 ret = snd_hwparams_to_dma_slave_config(st, params, sc);
400 if (ret)
401 return ret;
402
403 sc->dst_addr = dma_data->addr;
404 sc->dst_addr_width = dma_data->addr_width;
405 sc->dst_maxburst = 4 * i2s_channels;
406
407 return 0;
408}
409
410static const struct snd_dmaengine_pcm_config img_i2s_out_dma_config = {
411 .prepare_slave_config = img_i2s_out_dma_prepare_slave_config
412};
413
414static int img_i2s_out_probe(struct platform_device *pdev)
415{
416 struct img_i2s_out *i2s;
417 struct resource *res;
418 void __iomem *base;
419 int i, ret;
420 unsigned int max_i2s_chan_pow_2;
421 u32 reg;
422 struct device *dev = &pdev->dev;
423
424 i2s = devm_kzalloc(&pdev->dev, sizeof(*i2s), GFP_KERNEL);
425 if (!i2s)
426 return -ENOMEM;
427
428 platform_set_drvdata(pdev, i2s);
429
430 i2s->dev = &pdev->dev;
431
432 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
433 base = devm_ioremap_resource(&pdev->dev, res);
434 if (IS_ERR(base))
435 return PTR_ERR(base);
436
437 i2s->base = base;
438
439 if (of_property_read_u32(pdev->dev.of_node, "img,i2s-channels",
440 &i2s->max_i2s_chan)) {
441 dev_err(&pdev->dev, "No img,i2s-channels property\n");
442 return -EINVAL;
443 }
444
445 max_i2s_chan_pow_2 = 1 << get_count_order(i2s->max_i2s_chan);
446
447 i2s->channel_base = base + (max_i2s_chan_pow_2 * 0x20);
448
449 i2s->rst = devm_reset_control_get(&pdev->dev, "rst");
450 if (IS_ERR(i2s->rst)) {
451 if (PTR_ERR(i2s->rst) != -EPROBE_DEFER)
452 dev_err(&pdev->dev, "No top level reset found\n");
453 return PTR_ERR(i2s->rst);
454 }
455
456 i2s->clk_sys = devm_clk_get(&pdev->dev, "sys");
457 if (IS_ERR(i2s->clk_sys)) {
458 if (PTR_ERR(i2s->clk_sys) != -EPROBE_DEFER)
459 dev_err(dev, "Failed to acquire clock 'sys'\n");
460 return PTR_ERR(i2s->clk_sys);
461 }
462
463 i2s->clk_ref = devm_clk_get(&pdev->dev, "ref");
464 if (IS_ERR(i2s->clk_ref)) {
465 if (PTR_ERR(i2s->clk_ref) != -EPROBE_DEFER)
466 dev_err(dev, "Failed to acquire clock 'ref'\n");
467 return PTR_ERR(i2s->clk_ref);
468 }
469
470 ret = clk_prepare_enable(i2s->clk_sys);
471 if (ret)
472 return ret;
473
474 reg = IMG_I2S_OUT_CTL_FRM_SIZE_MASK;
475 img_i2s_out_writel(i2s, reg, IMG_I2S_OUT_CTL);
476
477 reg = IMG_I2S_OUT_CHAN_CTL_JUST_MASK |
478 IMG_I2S_OUT_CHAN_CTL_LT_MASK |
479 IMG_I2S_OUT_CHAN_CTL_CH_MASK |
480 (8 << IMG_I2S_OUT_CHAN_CTL_FMT_SHIFT);
481
482 for (i = 0; i < i2s->max_i2s_chan; i++)
483 img_i2s_out_ch_writel(i2s, i, reg, IMG_I2S_OUT_CH_CTL);
484
485 img_i2s_out_reset(i2s);
486
487 pm_runtime_enable(&pdev->dev);
488 if (!pm_runtime_enabled(&pdev->dev)) {
489 ret = img_i2s_out_resume(&pdev->dev);
490 if (ret)
491 goto err_pm_disable;
492 }
493
494 i2s->active_channels = 1;
495 i2s->dma_data.addr = res->start + IMG_I2S_OUT_TX_FIFO;
496 i2s->dma_data.addr_width = 4;
497 i2s->dma_data.maxburst = 4;
498
499 i2s->dai_driver.probe = img_i2s_out_dai_probe;
500 i2s->dai_driver.playback.channels_min = 2;
501 i2s->dai_driver.playback.channels_max = i2s->max_i2s_chan * 2;
502 i2s->dai_driver.playback.rates = SNDRV_PCM_RATE_8000_192000;
503 i2s->dai_driver.playback.formats = SNDRV_PCM_FMTBIT_S32_LE;
504 i2s->dai_driver.ops = &img_i2s_out_dai_ops;
505
506 ret = devm_snd_soc_register_component(&pdev->dev,
507 &img_i2s_out_component, &i2s->dai_driver, 1);
508 if (ret)
509 goto err_suspend;
510
511 ret = devm_snd_dmaengine_pcm_register(&pdev->dev,
512 &img_i2s_out_dma_config, 0);
513 if (ret)
514 goto err_suspend;
515
516 return 0;
517
518err_suspend:
519 if (!pm_runtime_status_suspended(&pdev->dev))
520 img_i2s_out_suspend(&pdev->dev);
521err_pm_disable:
522 pm_runtime_disable(&pdev->dev);
523 clk_disable_unprepare(i2s->clk_sys);
524
525 return ret;
526}
527
528static int img_i2s_out_dev_remove(struct platform_device *pdev)
529{
530 struct img_i2s_out *i2s = platform_get_drvdata(pdev);
531
532 pm_runtime_disable(&pdev->dev);
533 if (!pm_runtime_status_suspended(&pdev->dev))
534 img_i2s_out_suspend(&pdev->dev);
535
536 clk_disable_unprepare(i2s->clk_sys);
537
538 return 0;
539}
540
541static const struct of_device_id img_i2s_out_of_match[] = {
542 { .compatible = "img,i2s-out" },
543 {}
544};
545MODULE_DEVICE_TABLE(of, img_i2s_out_of_match);
546
547static const struct dev_pm_ops img_i2s_out_pm_ops = {
548 SET_RUNTIME_PM_OPS(img_i2s_out_suspend,
549 img_i2s_out_resume, NULL)
550};
551
552static struct platform_driver img_i2s_out_driver = {
553 .driver = {
554 .name = "img-i2s-out",
555 .of_match_table = img_i2s_out_of_match,
556 .pm = &img_i2s_out_pm_ops
557 },
558 .probe = img_i2s_out_probe,
559 .remove = img_i2s_out_dev_remove
560};
561module_platform_driver(img_i2s_out_driver);
562
563MODULE_AUTHOR("Damien Horsley <Damien.Horsley@imgtec.com>");
564MODULE_DESCRIPTION("IMG I2S Output Driver");
565MODULE_LICENSE("GPL v2");
diff --git a/sound/soc/img/img-parallel-out.c b/sound/soc/img/img-parallel-out.c
new file mode 100644
index 000000000000..c1610a054d65
--- /dev/null
+++ b/sound/soc/img/img-parallel-out.c
@@ -0,0 +1,327 @@
1/*
2 * IMG parallel output controller driver
3 *
4 * Copyright (C) 2015 Imagination Technologies Ltd.
5 *
6 * Author: Damien Horsley <Damien.Horsley@imgtec.com>
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms and conditions of the GNU General Public License,
10 * version 2, as published by the Free Software Foundation.
11 */
12
13#include <linux/clk.h>
14#include <linux/init.h>
15#include <linux/kernel.h>
16#include <linux/module.h>
17#include <linux/of.h>
18#include <linux/platform_device.h>
19#include <linux/pm_runtime.h>
20#include <linux/reset.h>
21
22#include <sound/core.h>
23#include <sound/dmaengine_pcm.h>
24#include <sound/initval.h>
25#include <sound/pcm.h>
26#include <sound/pcm_params.h>
27#include <sound/soc.h>
28
29#define IMG_PRL_OUT_TX_FIFO 0
30
31#define IMG_PRL_OUT_CTL 0x4
32#define IMG_PRL_OUT_CTL_CH_MASK BIT(4)
33#define IMG_PRL_OUT_CTL_PACKH_MASK BIT(3)
34#define IMG_PRL_OUT_CTL_EDGE_MASK BIT(2)
35#define IMG_PRL_OUT_CTL_ME_MASK BIT(1)
36#define IMG_PRL_OUT_CTL_SRST_MASK BIT(0)
37
38struct img_prl_out {
39 void __iomem *base;
40 struct clk *clk_sys;
41 struct clk *clk_ref;
42 struct snd_dmaengine_dai_dma_data dma_data;
43 struct device *dev;
44 struct reset_control *rst;
45};
46
47static int img_prl_out_suspend(struct device *dev)
48{
49 struct img_prl_out *prl = dev_get_drvdata(dev);
50
51 clk_disable_unprepare(prl->clk_ref);
52
53 return 0;
54}
55
56static int img_prl_out_resume(struct device *dev)
57{
58 struct img_prl_out *prl = dev_get_drvdata(dev);
59 int ret;
60
61 ret = clk_prepare_enable(prl->clk_ref);
62 if (ret) {
63 dev_err(dev, "clk_enable failed: %d\n", ret);
64 return ret;
65 }
66
67 return 0;
68}
69
70static inline void img_prl_out_writel(struct img_prl_out *prl,
71 u32 val, u32 reg)
72{
73 writel(val, prl->base + reg);
74}
75
76static inline u32 img_prl_out_readl(struct img_prl_out *prl, u32 reg)
77{
78 return readl(prl->base + reg);
79}
80
81static void img_prl_out_reset(struct img_prl_out *prl)
82{
83 u32 ctl;
84
85 ctl = img_prl_out_readl(prl, IMG_PRL_OUT_CTL) &
86 ~IMG_PRL_OUT_CTL_ME_MASK;
87
88 reset_control_assert(prl->rst);
89 reset_control_deassert(prl->rst);
90
91 img_prl_out_writel(prl, ctl, IMG_PRL_OUT_CTL);
92}
93
94static int img_prl_out_trigger(struct snd_pcm_substream *substream, int cmd,
95 struct snd_soc_dai *dai)
96{
97 struct img_prl_out *prl = snd_soc_dai_get_drvdata(dai);
98 u32 reg;
99
100 switch (cmd) {
101 case SNDRV_PCM_TRIGGER_START:
102 case SNDRV_PCM_TRIGGER_RESUME:
103 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
104 reg = img_prl_out_readl(prl, IMG_PRL_OUT_CTL);
105 reg |= IMG_PRL_OUT_CTL_ME_MASK;
106 img_prl_out_writel(prl, reg, IMG_PRL_OUT_CTL);
107 break;
108 case SNDRV_PCM_TRIGGER_STOP:
109 case SNDRV_PCM_TRIGGER_SUSPEND:
110 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
111 img_prl_out_reset(prl);
112 break;
113 default:
114 return -EINVAL;
115 }
116
117 return 0;
118}
119
120static int img_prl_out_hw_params(struct snd_pcm_substream *substream,
121 struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
122{
123 struct img_prl_out *prl = snd_soc_dai_get_drvdata(dai);
124 unsigned int rate, channels;
125 u32 reg, control_set = 0;
126 snd_pcm_format_t format;
127
128 rate = params_rate(params);
129 format = params_format(params);
130 channels = params_channels(params);
131
132 switch (params_format(params)) {
133 case SNDRV_PCM_FORMAT_S32_LE:
134 control_set |= IMG_PRL_OUT_CTL_PACKH_MASK;
135 break;
136 case SNDRV_PCM_FORMAT_S24_LE:
137 break;
138 default:
139 return -EINVAL;
140 }
141
142 if (channels != 2)
143 return -EINVAL;
144
145 clk_set_rate(prl->clk_ref, rate * 256);
146
147 reg = img_prl_out_readl(prl, IMG_PRL_OUT_CTL);
148 reg = (reg & ~IMG_PRL_OUT_CTL_PACKH_MASK) | control_set;
149 img_prl_out_writel(prl, reg, IMG_PRL_OUT_CTL);
150
151 return 0;
152}
153
154static int img_prl_out_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
155{
156 struct img_prl_out *prl = snd_soc_dai_get_drvdata(dai);
157 u32 reg, control_set = 0;
158
159 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
160 case SND_SOC_DAIFMT_NB_NF:
161 break;
162 case SND_SOC_DAIFMT_NB_IF:
163 control_set |= IMG_PRL_OUT_CTL_EDGE_MASK;
164 break;
165 default:
166 return -EINVAL;
167 }
168
169 reg = img_prl_out_readl(prl, IMG_PRL_OUT_CTL);
170 reg = (reg & ~IMG_PRL_OUT_CTL_EDGE_MASK) | control_set;
171 img_prl_out_writel(prl, reg, IMG_PRL_OUT_CTL);
172
173 return 0;
174}
175
176static const struct snd_soc_dai_ops img_prl_out_dai_ops = {
177 .trigger = img_prl_out_trigger,
178 .hw_params = img_prl_out_hw_params,
179 .set_fmt = img_prl_out_set_fmt
180};
181
182static int img_prl_out_dai_probe(struct snd_soc_dai *dai)
183{
184 struct img_prl_out *prl = snd_soc_dai_get_drvdata(dai);
185
186 snd_soc_dai_init_dma_data(dai, &prl->dma_data, NULL);
187
188 return 0;
189}
190
191static struct snd_soc_dai_driver img_prl_out_dai = {
192 .probe = img_prl_out_dai_probe,
193 .playback = {
194 .channels_min = 2,
195 .channels_max = 2,
196 .rates = SNDRV_PCM_RATE_8000_192000,
197 .formats = SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_S24_LE
198 },
199 .ops = &img_prl_out_dai_ops
200};
201
202static const struct snd_soc_component_driver img_prl_out_component = {
203 .name = "img-prl-out"
204};
205
206static int img_prl_out_probe(struct platform_device *pdev)
207{
208 struct img_prl_out *prl;
209 struct resource *res;
210 void __iomem *base;
211 int ret;
212 struct device *dev = &pdev->dev;
213
214 prl = devm_kzalloc(&pdev->dev, sizeof(*prl), GFP_KERNEL);
215 if (!prl)
216 return -ENOMEM;
217
218 platform_set_drvdata(pdev, prl);
219
220 prl->dev = &pdev->dev;
221
222 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
223 base = devm_ioremap_resource(&pdev->dev, res);
224 if (IS_ERR(base))
225 return PTR_ERR(base);
226
227 prl->base = base;
228
229 prl->rst = devm_reset_control_get(&pdev->dev, "rst");
230 if (IS_ERR(prl->rst)) {
231 if (PTR_ERR(prl->rst) != -EPROBE_DEFER)
232 dev_err(&pdev->dev, "No top level reset found\n");
233 return PTR_ERR(prl->rst);
234 }
235
236 prl->clk_sys = devm_clk_get(&pdev->dev, "sys");
237 if (IS_ERR(prl->clk_sys)) {
238 if (PTR_ERR(prl->clk_sys) != -EPROBE_DEFER)
239 dev_err(dev, "Failed to acquire clock 'sys'\n");
240 return PTR_ERR(prl->clk_sys);
241 }
242
243 prl->clk_ref = devm_clk_get(&pdev->dev, "ref");
244 if (IS_ERR(prl->clk_ref)) {
245 if (PTR_ERR(prl->clk_ref) != -EPROBE_DEFER)
246 dev_err(dev, "Failed to acquire clock 'ref'\n");
247 return PTR_ERR(prl->clk_ref);
248 }
249
250 ret = clk_prepare_enable(prl->clk_sys);
251 if (ret)
252 return ret;
253
254 img_prl_out_writel(prl, IMG_PRL_OUT_CTL_EDGE_MASK, IMG_PRL_OUT_CTL);
255 img_prl_out_reset(prl);
256
257 pm_runtime_enable(&pdev->dev);
258 if (!pm_runtime_enabled(&pdev->dev)) {
259 ret = img_prl_out_resume(&pdev->dev);
260 if (ret)
261 goto err_pm_disable;
262 }
263
264 prl->dma_data.addr = res->start + IMG_PRL_OUT_TX_FIFO;
265 prl->dma_data.addr_width = 4;
266 prl->dma_data.maxburst = 4;
267
268 ret = devm_snd_soc_register_component(&pdev->dev,
269 &img_prl_out_component,
270 &img_prl_out_dai, 1);
271 if (ret)
272 goto err_suspend;
273
274 ret = devm_snd_dmaengine_pcm_register(&pdev->dev, NULL, 0);
275 if (ret)
276 goto err_suspend;
277
278 return 0;
279
280err_suspend:
281 if (!pm_runtime_status_suspended(&pdev->dev))
282 img_prl_out_suspend(&pdev->dev);
283err_pm_disable:
284 pm_runtime_disable(&pdev->dev);
285 clk_disable_unprepare(prl->clk_sys);
286
287 return ret;
288}
289
290static int img_prl_out_dev_remove(struct platform_device *pdev)
291{
292 struct img_prl_out *prl = platform_get_drvdata(pdev);
293
294 pm_runtime_disable(&pdev->dev);
295 if (!pm_runtime_status_suspended(&pdev->dev))
296 img_prl_out_suspend(&pdev->dev);
297
298 clk_disable_unprepare(prl->clk_sys);
299
300 return 0;
301}
302
303static const struct of_device_id img_prl_out_of_match[] = {
304 { .compatible = "img,parallel-out" },
305 {}
306};
307MODULE_DEVICE_TABLE(of, img_prl_out_of_match);
308
309static const struct dev_pm_ops img_prl_out_pm_ops = {
310 SET_RUNTIME_PM_OPS(img_prl_out_suspend,
311 img_prl_out_resume, NULL)
312};
313
314static struct platform_driver img_prl_out_driver = {
315 .driver = {
316 .name = "img-parallel-out",
317 .of_match_table = img_prl_out_of_match,
318 .pm = &img_prl_out_pm_ops
319 },
320 .probe = img_prl_out_probe,
321 .remove = img_prl_out_dev_remove
322};
323module_platform_driver(img_prl_out_driver);
324
325MODULE_AUTHOR("Damien Horsley <Damien.Horsley@imgtec.com>");
326MODULE_DESCRIPTION("IMG Parallel Output Driver");
327MODULE_LICENSE("GPL v2");
diff --git a/sound/soc/img/img-spdif-in.c b/sound/soc/img/img-spdif-in.c
new file mode 100644
index 000000000000..4d9953d318af
--- /dev/null
+++ b/sound/soc/img/img-spdif-in.c
@@ -0,0 +1,806 @@
1/*
2 * IMG SPDIF input controller driver
3 *
4 * Copyright (C) 2015 Imagination Technologies Ltd.
5 *
6 * Author: Damien Horsley <Damien.Horsley@imgtec.com>
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms and conditions of the GNU General Public License,
10 * version 2, as published by the Free Software Foundation.
11 */
12
13#include <linux/clk.h>
14#include <linux/init.h>
15#include <linux/kernel.h>
16#include <linux/module.h>
17#include <linux/of.h>
18#include <linux/platform_device.h>
19#include <linux/reset.h>
20
21#include <sound/core.h>
22#include <sound/dmaengine_pcm.h>
23#include <sound/initval.h>
24#include <sound/pcm.h>
25#include <sound/pcm_params.h>
26#include <sound/soc.h>
27
28#define IMG_SPDIF_IN_RX_FIFO_OFFSET 0
29
30#define IMG_SPDIF_IN_CTL 0x4
31#define IMG_SPDIF_IN_CTL_LOCKLO_MASK 0xff
32#define IMG_SPDIF_IN_CTL_LOCKLO_SHIFT 0
33#define IMG_SPDIF_IN_CTL_LOCKHI_MASK 0xff00
34#define IMG_SPDIF_IN_CTL_LOCKHI_SHIFT 8
35#define IMG_SPDIF_IN_CTL_TRK_MASK 0xff0000
36#define IMG_SPDIF_IN_CTL_TRK_SHIFT 16
37#define IMG_SPDIF_IN_CTL_SRD_MASK 0x70000000
38#define IMG_SPDIF_IN_CTL_SRD_SHIFT 28
39#define IMG_SPDIF_IN_CTL_SRT_MASK BIT(31)
40
41#define IMG_SPDIF_IN_STATUS 0x8
42#define IMG_SPDIF_IN_STATUS_SAM_MASK 0x7000
43#define IMG_SPDIF_IN_STATUS_SAM_SHIFT 12
44#define IMG_SPDIF_IN_STATUS_LOCK_MASK BIT(15)
45#define IMG_SPDIF_IN_STATUS_LOCK_SHIFT 15
46
47#define IMG_SPDIF_IN_CLKGEN 0x1c
48#define IMG_SPDIF_IN_CLKGEN_NOM_MASK 0x3ff
49#define IMG_SPDIF_IN_CLKGEN_NOM_SHIFT 0
50#define IMG_SPDIF_IN_CLKGEN_HLD_MASK 0x3ff0000
51#define IMG_SPDIF_IN_CLKGEN_HLD_SHIFT 16
52
53#define IMG_SPDIF_IN_CSL 0x20
54
55#define IMG_SPDIF_IN_CSH 0x24
56#define IMG_SPDIF_IN_CSH_MASK 0xff
57#define IMG_SPDIF_IN_CSH_SHIFT 0
58
59#define IMG_SPDIF_IN_SOFT_RESET 0x28
60#define IMG_SPDIF_IN_SOFT_RESET_MASK BIT(0)
61
62#define IMG_SPDIF_IN_ACLKGEN_START 0x2c
63#define IMG_SPDIF_IN_ACLKGEN_NOM_MASK 0x3ff
64#define IMG_SPDIF_IN_ACLKGEN_NOM_SHIFT 0
65#define IMG_SPDIF_IN_ACLKGEN_HLD_MASK 0xffc00
66#define IMG_SPDIF_IN_ACLKGEN_HLD_SHIFT 10
67#define IMG_SPDIF_IN_ACLKGEN_TRK_MASK 0xff00000
68#define IMG_SPDIF_IN_ACLKGEN_TRK_SHIFT 20
69
70#define IMG_SPDIF_IN_NUM_ACLKGEN 4
71
72struct img_spdif_in {
73 spinlock_t lock;
74 void __iomem *base;
75 struct clk *clk_sys;
76 struct snd_dmaengine_dai_dma_data dma_data;
77 struct device *dev;
78 unsigned int trk;
79 bool multi_freq;
80 int lock_acquire;
81 int lock_release;
82 unsigned int single_freq;
83 unsigned int multi_freqs[IMG_SPDIF_IN_NUM_ACLKGEN];
84 bool active;
85
86 /* Write-only registers */
87 unsigned int aclkgen_regs[IMG_SPDIF_IN_NUM_ACLKGEN];
88};
89
90static inline void img_spdif_in_writel(struct img_spdif_in *spdif,
91 u32 val, u32 reg)
92{
93 writel(val, spdif->base + reg);
94}
95
96static inline u32 img_spdif_in_readl(struct img_spdif_in *spdif, u32 reg)
97{
98 return readl(spdif->base + reg);
99}
100
101static inline void img_spdif_in_aclkgen_writel(struct img_spdif_in *spdif,
102 u32 index)
103{
104 img_spdif_in_writel(spdif, spdif->aclkgen_regs[index],
105 IMG_SPDIF_IN_ACLKGEN_START + (index * 0x4));
106}
107
108static int img_spdif_in_check_max_rate(struct img_spdif_in *spdif,
109 unsigned int sample_rate, unsigned long *actual_freq)
110{
111 unsigned long min_freq, freq_t;
112
113 /* Clock rate must be at least 24x the bit rate */
114 min_freq = sample_rate * 2 * 32 * 24;
115
116 freq_t = clk_get_rate(spdif->clk_sys);
117
118 if (freq_t < min_freq)
119 return -EINVAL;
120
121 *actual_freq = freq_t;
122
123 return 0;
124}
125
126static int img_spdif_in_do_clkgen_calc(unsigned int rate, unsigned int *pnom,
127 unsigned int *phld, unsigned long clk_rate)
128{
129 unsigned int ori, nom, hld;
130
131 /*
132 * Calculate oversampling ratio, nominal phase increment and hold
133 * increment for the given rate / frequency
134 */
135
136 if (!rate)
137 return -EINVAL;
138
139 ori = clk_rate / (rate * 64);
140
141 if (!ori)
142 return -EINVAL;
143
144 nom = (4096 / ori) + 1;
145 do
146 hld = 4096 - (--nom * (ori - 1));
147 while (hld < 120);
148
149 *pnom = nom;
150 *phld = hld;
151
152 return 0;
153}
154
155static int img_spdif_in_do_clkgen_single(struct img_spdif_in *spdif,
156 unsigned int rate)
157{
158 unsigned int nom, hld;
159 unsigned long flags, clk_rate;
160 int ret = 0;
161 u32 reg;
162
163 ret = img_spdif_in_check_max_rate(spdif, rate, &clk_rate);
164 if (ret)
165 return ret;
166
167 ret = img_spdif_in_do_clkgen_calc(rate, &nom, &hld, clk_rate);
168 if (ret)
169 return ret;
170
171 reg = (nom << IMG_SPDIF_IN_CLKGEN_NOM_SHIFT) &
172 IMG_SPDIF_IN_CLKGEN_NOM_MASK;
173 reg |= (hld << IMG_SPDIF_IN_CLKGEN_HLD_SHIFT) &
174 IMG_SPDIF_IN_CLKGEN_HLD_MASK;
175
176 spin_lock_irqsave(&spdif->lock, flags);
177
178 if (spdif->active) {
179 spin_unlock_irqrestore(&spdif->lock, flags);
180 return -EBUSY;
181 }
182
183 img_spdif_in_writel(spdif, reg, IMG_SPDIF_IN_CLKGEN);
184
185 spdif->single_freq = rate;
186
187 spin_unlock_irqrestore(&spdif->lock, flags);
188
189 return 0;
190}
191
192static int img_spdif_in_do_clkgen_multi(struct img_spdif_in *spdif,
193 unsigned int multi_freqs[])
194{
195 unsigned int nom, hld, rate, max_rate = 0;
196 unsigned long flags, clk_rate;
197 int i, ret = 0;
198 u32 reg, trk_reg, temp_regs[IMG_SPDIF_IN_NUM_ACLKGEN];
199
200 for (i = 0; i < IMG_SPDIF_IN_NUM_ACLKGEN; i++)
201 if (multi_freqs[i] > max_rate)
202 max_rate = multi_freqs[i];
203
204 ret = img_spdif_in_check_max_rate(spdif, max_rate, &clk_rate);
205 if (ret)
206 return ret;
207
208 for (i = 0; i < IMG_SPDIF_IN_NUM_ACLKGEN; i++) {
209 rate = multi_freqs[i];
210
211 ret = img_spdif_in_do_clkgen_calc(rate, &nom, &hld, clk_rate);
212 if (ret)
213 return ret;
214
215 reg = (nom << IMG_SPDIF_IN_ACLKGEN_NOM_SHIFT) &
216 IMG_SPDIF_IN_ACLKGEN_NOM_MASK;
217 reg |= (hld << IMG_SPDIF_IN_ACLKGEN_HLD_SHIFT) &
218 IMG_SPDIF_IN_ACLKGEN_HLD_MASK;
219 temp_regs[i] = reg;
220 }
221
222 spin_lock_irqsave(&spdif->lock, flags);
223
224 if (spdif->active) {
225 spin_unlock_irqrestore(&spdif->lock, flags);
226 return -EBUSY;
227 }
228
229 trk_reg = spdif->trk << IMG_SPDIF_IN_ACLKGEN_TRK_SHIFT;
230
231 for (i = 0; i < IMG_SPDIF_IN_NUM_ACLKGEN; i++) {
232 spdif->aclkgen_regs[i] = temp_regs[i] | trk_reg;
233 img_spdif_in_aclkgen_writel(spdif, i);
234 }
235
236 spdif->multi_freq = true;
237 spdif->multi_freqs[0] = multi_freqs[0];
238 spdif->multi_freqs[1] = multi_freqs[1];
239 spdif->multi_freqs[2] = multi_freqs[2];
240 spdif->multi_freqs[3] = multi_freqs[3];
241
242 spin_unlock_irqrestore(&spdif->lock, flags);
243
244 return 0;
245}
246
247static int img_spdif_in_iec958_info(struct snd_kcontrol *kcontrol,
248 struct snd_ctl_elem_info *uinfo)
249{
250 uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
251 uinfo->count = 1;
252
253 return 0;
254}
255
256static int img_spdif_in_get_status_mask(struct snd_kcontrol *kcontrol,
257 struct snd_ctl_elem_value *ucontrol)
258{
259 ucontrol->value.iec958.status[0] = 0xff;
260 ucontrol->value.iec958.status[1] = 0xff;
261 ucontrol->value.iec958.status[2] = 0xff;
262 ucontrol->value.iec958.status[3] = 0xff;
263 ucontrol->value.iec958.status[4] = 0xff;
264
265 return 0;
266}
267
268static int img_spdif_in_get_status(struct snd_kcontrol *kcontrol,
269 struct snd_ctl_elem_value *ucontrol)
270{
271 struct snd_soc_dai *cpu_dai = snd_kcontrol_chip(kcontrol);
272 struct img_spdif_in *spdif = snd_soc_dai_get_drvdata(cpu_dai);
273 u32 reg;
274
275 reg = img_spdif_in_readl(spdif, IMG_SPDIF_IN_CSL);
276 ucontrol->value.iec958.status[0] = reg & 0xff;
277 ucontrol->value.iec958.status[1] = (reg >> 8) & 0xff;
278 ucontrol->value.iec958.status[2] = (reg >> 16) & 0xff;
279 ucontrol->value.iec958.status[3] = (reg >> 24) & 0xff;
280 reg = img_spdif_in_readl(spdif, IMG_SPDIF_IN_CSH);
281 ucontrol->value.iec958.status[4] = (reg & IMG_SPDIF_IN_CSH_MASK)
282 >> IMG_SPDIF_IN_CSH_SHIFT;
283
284 return 0;
285}
286
287static int img_spdif_in_info_multi_freq(struct snd_kcontrol *kcontrol,
288 struct snd_ctl_elem_info *uinfo)
289{
290 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
291 uinfo->count = IMG_SPDIF_IN_NUM_ACLKGEN;
292 uinfo->value.integer.min = 0;
293 uinfo->value.integer.max = LONG_MAX;
294
295 return 0;
296}
297
298static int img_spdif_in_get_multi_freq(struct snd_kcontrol *kcontrol,
299 struct snd_ctl_elem_value *ucontrol)
300{
301 struct snd_soc_dai *cpu_dai = snd_kcontrol_chip(kcontrol);
302 struct img_spdif_in *spdif = snd_soc_dai_get_drvdata(cpu_dai);
303 unsigned long flags;
304
305 spin_lock_irqsave(&spdif->lock, flags);
306 if (spdif->multi_freq) {
307 ucontrol->value.integer.value[0] = spdif->multi_freqs[0];
308 ucontrol->value.integer.value[1] = spdif->multi_freqs[1];
309 ucontrol->value.integer.value[2] = spdif->multi_freqs[2];
310 ucontrol->value.integer.value[3] = spdif->multi_freqs[3];
311 } else {
312 ucontrol->value.integer.value[0] = 0;
313 ucontrol->value.integer.value[1] = 0;
314 ucontrol->value.integer.value[2] = 0;
315 ucontrol->value.integer.value[3] = 0;
316 }
317 spin_unlock_irqrestore(&spdif->lock, flags);
318
319 return 0;
320}
321
322static int img_spdif_in_set_multi_freq(struct snd_kcontrol *kcontrol,
323 struct snd_ctl_elem_value *ucontrol)
324{
325 struct snd_soc_dai *cpu_dai = snd_kcontrol_chip(kcontrol);
326 struct img_spdif_in *spdif = snd_soc_dai_get_drvdata(cpu_dai);
327 unsigned int multi_freqs[IMG_SPDIF_IN_NUM_ACLKGEN];
328 bool multi_freq;
329 unsigned long flags;
330
331 if ((ucontrol->value.integer.value[0] == 0) &&
332 (ucontrol->value.integer.value[1] == 0) &&
333 (ucontrol->value.integer.value[2] == 0) &&
334 (ucontrol->value.integer.value[3] == 0)) {
335 multi_freq = false;
336 } else {
337 multi_freqs[0] = ucontrol->value.integer.value[0];
338 multi_freqs[1] = ucontrol->value.integer.value[1];
339 multi_freqs[2] = ucontrol->value.integer.value[2];
340 multi_freqs[3] = ucontrol->value.integer.value[3];
341 multi_freq = true;
342 }
343
344 if (multi_freq)
345 return img_spdif_in_do_clkgen_multi(spdif, multi_freqs);
346
347 spin_lock_irqsave(&spdif->lock, flags);
348
349 if (spdif->active) {
350 spin_unlock_irqrestore(&spdif->lock, flags);
351 return -EBUSY;
352 }
353
354 spdif->multi_freq = false;
355
356 spin_unlock_irqrestore(&spdif->lock, flags);
357
358 return 0;
359}
360
361static int img_spdif_in_info_lock_freq(struct snd_kcontrol *kcontrol,
362 struct snd_ctl_elem_info *uinfo)
363{
364 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
365 uinfo->count = 1;
366 uinfo->value.integer.min = 0;
367 uinfo->value.integer.max = LONG_MAX;
368
369 return 0;
370}
371
372static int img_spdif_in_get_lock_freq(struct snd_kcontrol *kcontrol,
373 struct snd_ctl_elem_value *uc)
374{
375 struct snd_soc_dai *cpu_dai = snd_kcontrol_chip(kcontrol);
376 struct img_spdif_in *spdif = snd_soc_dai_get_drvdata(cpu_dai);
377 u32 reg;
378 int i;
379 unsigned long flags;
380
381 spin_lock_irqsave(&spdif->lock, flags);
382
383 reg = img_spdif_in_readl(spdif, IMG_SPDIF_IN_STATUS);
384 if (reg & IMG_SPDIF_IN_STATUS_LOCK_MASK) {
385 if (spdif->multi_freq) {
386 i = ((reg & IMG_SPDIF_IN_STATUS_SAM_MASK) >>
387 IMG_SPDIF_IN_STATUS_SAM_SHIFT) - 1;
388 uc->value.integer.value[0] = spdif->multi_freqs[i];
389 } else {
390 uc->value.integer.value[0] = spdif->single_freq;
391 }
392 } else {
393 uc->value.integer.value[0] = 0;
394 }
395
396 spin_unlock_irqrestore(&spdif->lock, flags);
397
398 return 0;
399}
400
401static int img_spdif_in_info_trk(struct snd_kcontrol *kcontrol,
402 struct snd_ctl_elem_info *uinfo)
403{
404 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
405 uinfo->count = 1;
406 uinfo->value.integer.min = 0;
407 uinfo->value.integer.max = 255;
408
409 return 0;
410}
411
412static int img_spdif_in_get_trk(struct snd_kcontrol *kcontrol,
413 struct snd_ctl_elem_value *ucontrol)
414{
415 struct snd_soc_dai *cpu_dai = snd_kcontrol_chip(kcontrol);
416 struct img_spdif_in *spdif = snd_soc_dai_get_drvdata(cpu_dai);
417
418 ucontrol->value.integer.value[0] = spdif->trk;
419
420 return 0;
421}
422
423static int img_spdif_in_set_trk(struct snd_kcontrol *kcontrol,
424 struct snd_ctl_elem_value *ucontrol)
425{
426 struct snd_soc_dai *cpu_dai = snd_kcontrol_chip(kcontrol);
427 struct img_spdif_in *spdif = snd_soc_dai_get_drvdata(cpu_dai);
428 unsigned long flags;
429 int i;
430 u32 reg;
431
432 spin_lock_irqsave(&spdif->lock, flags);
433
434 if (spdif->active) {
435 spin_unlock_irqrestore(&spdif->lock, flags);
436 return -EBUSY;
437 }
438
439 spdif->trk = ucontrol->value.integer.value[0];
440
441 reg = img_spdif_in_readl(spdif, IMG_SPDIF_IN_CTL);
442 reg &= ~IMG_SPDIF_IN_CTL_TRK_MASK;
443 reg |= spdif->trk << IMG_SPDIF_IN_CTL_TRK_SHIFT;
444 img_spdif_in_writel(spdif, reg, IMG_SPDIF_IN_CTL);
445
446 for (i = 0; i < IMG_SPDIF_IN_NUM_ACLKGEN; i++) {
447 spdif->aclkgen_regs[i] = (spdif->aclkgen_regs[i] &
448 ~IMG_SPDIF_IN_ACLKGEN_TRK_MASK) |
449 (spdif->trk << IMG_SPDIF_IN_ACLKGEN_TRK_SHIFT);
450
451 img_spdif_in_aclkgen_writel(spdif, i);
452 }
453
454 spin_unlock_irqrestore(&spdif->lock, flags);
455
456 return 0;
457}
458
459static int img_spdif_in_info_lock(struct snd_kcontrol *kcontrol,
460 struct snd_ctl_elem_info *uinfo)
461{
462 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
463 uinfo->count = 1;
464 uinfo->value.integer.min = -128;
465 uinfo->value.integer.max = 127;
466
467 return 0;
468}
469
470static int img_spdif_in_get_lock_acquire(struct snd_kcontrol *kcontrol,
471 struct snd_ctl_elem_value *ucontrol)
472{
473 struct snd_soc_dai *cpu_dai = snd_kcontrol_chip(kcontrol);
474 struct img_spdif_in *spdif = snd_soc_dai_get_drvdata(cpu_dai);
475
476 ucontrol->value.integer.value[0] = spdif->lock_acquire;
477
478 return 0;
479}
480
481static int img_spdif_in_set_lock_acquire(struct snd_kcontrol *kcontrol,
482 struct snd_ctl_elem_value *ucontrol)
483{
484 struct snd_soc_dai *cpu_dai = snd_kcontrol_chip(kcontrol);
485 struct img_spdif_in *spdif = snd_soc_dai_get_drvdata(cpu_dai);
486 unsigned long flags;
487 u32 reg;
488
489 spin_lock_irqsave(&spdif->lock, flags);
490
491 if (spdif->active) {
492 spin_unlock_irqrestore(&spdif->lock, flags);
493 return -EBUSY;
494 }
495
496 spdif->lock_acquire = ucontrol->value.integer.value[0];
497
498 reg = img_spdif_in_readl(spdif, IMG_SPDIF_IN_CTL);
499 reg &= ~IMG_SPDIF_IN_CTL_LOCKHI_MASK;
500 reg |= (spdif->lock_acquire << IMG_SPDIF_IN_CTL_LOCKHI_SHIFT) &
501 IMG_SPDIF_IN_CTL_LOCKHI_MASK;
502 img_spdif_in_writel(spdif, reg, IMG_SPDIF_IN_CTL);
503
504 spin_unlock_irqrestore(&spdif->lock, flags);
505
506 return 0;
507}
508
509static int img_spdif_in_get_lock_release(struct snd_kcontrol *kcontrol,
510 struct snd_ctl_elem_value *ucontrol)
511{
512 struct snd_soc_dai *cpu_dai = snd_kcontrol_chip(kcontrol);
513 struct img_spdif_in *spdif = snd_soc_dai_get_drvdata(cpu_dai);
514
515 ucontrol->value.integer.value[0] = spdif->lock_release;
516
517 return 0;
518}
519
520static int img_spdif_in_set_lock_release(struct snd_kcontrol *kcontrol,
521 struct snd_ctl_elem_value *ucontrol)
522{
523 struct snd_soc_dai *cpu_dai = snd_kcontrol_chip(kcontrol);
524 struct img_spdif_in *spdif = snd_soc_dai_get_drvdata(cpu_dai);
525 unsigned long flags;
526 u32 reg;
527
528 spin_lock_irqsave(&spdif->lock, flags);
529
530 if (spdif->active) {
531 spin_unlock_irqrestore(&spdif->lock, flags);
532 return -EBUSY;
533 }
534
535 spdif->lock_release = ucontrol->value.integer.value[0];
536
537 reg = img_spdif_in_readl(spdif, IMG_SPDIF_IN_CTL);
538 reg &= ~IMG_SPDIF_IN_CTL_LOCKLO_MASK;
539 reg |= (spdif->lock_release << IMG_SPDIF_IN_CTL_LOCKLO_SHIFT) &
540 IMG_SPDIF_IN_CTL_LOCKLO_MASK;
541 img_spdif_in_writel(spdif, reg, IMG_SPDIF_IN_CTL);
542
543 spin_unlock_irqrestore(&spdif->lock, flags);
544
545 return 0;
546}
547
548static struct snd_kcontrol_new img_spdif_in_controls[] = {
549 {
550 .access = SNDRV_CTL_ELEM_ACCESS_READ,
551 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
552 .name = SNDRV_CTL_NAME_IEC958("", CAPTURE, MASK),
553 .info = img_spdif_in_iec958_info,
554 .get = img_spdif_in_get_status_mask
555 },
556 {
557 .access = SNDRV_CTL_ELEM_ACCESS_READ |
558 SNDRV_CTL_ELEM_ACCESS_VOLATILE,
559 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
560 .name = SNDRV_CTL_NAME_IEC958("", CAPTURE, DEFAULT),
561 .info = img_spdif_in_iec958_info,
562 .get = img_spdif_in_get_status
563 },
564 {
565 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
566 .name = "SPDIF In Multi Frequency Acquire",
567 .info = img_spdif_in_info_multi_freq,
568 .get = img_spdif_in_get_multi_freq,
569 .put = img_spdif_in_set_multi_freq
570 },
571 {
572 .access = SNDRV_CTL_ELEM_ACCESS_READ |
573 SNDRV_CTL_ELEM_ACCESS_VOLATILE,
574 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
575 .name = "SPDIF In Lock Frequency",
576 .info = img_spdif_in_info_lock_freq,
577 .get = img_spdif_in_get_lock_freq
578 },
579 {
580 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
581 .name = "SPDIF In Lock TRK",
582 .info = img_spdif_in_info_trk,
583 .get = img_spdif_in_get_trk,
584 .put = img_spdif_in_set_trk
585 },
586 {
587 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
588 .name = "SPDIF In Lock Acquire Threshold",
589 .info = img_spdif_in_info_lock,
590 .get = img_spdif_in_get_lock_acquire,
591 .put = img_spdif_in_set_lock_acquire
592 },
593 {
594 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
595 .name = "SPDIF In Lock Release Threshold",
596 .info = img_spdif_in_info_lock,
597 .get = img_spdif_in_get_lock_release,
598 .put = img_spdif_in_set_lock_release
599 }
600};
601
602static int img_spdif_in_trigger(struct snd_pcm_substream *substream, int cmd,
603 struct snd_soc_dai *dai)
604{
605 unsigned long flags;
606 struct img_spdif_in *spdif = snd_soc_dai_get_drvdata(dai);
607 int ret = 0;
608 u32 reg;
609
610 spin_lock_irqsave(&spdif->lock, flags);
611
612 switch (cmd) {
613 case SNDRV_PCM_TRIGGER_START:
614 case SNDRV_PCM_TRIGGER_RESUME:
615 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
616 reg = img_spdif_in_readl(spdif, IMG_SPDIF_IN_CTL);
617 if (spdif->multi_freq)
618 reg &= ~IMG_SPDIF_IN_CTL_SRD_MASK;
619 else
620 reg |= (1UL << IMG_SPDIF_IN_CTL_SRD_SHIFT);
621 reg |= IMG_SPDIF_IN_CTL_SRT_MASK;
622 img_spdif_in_writel(spdif, reg, IMG_SPDIF_IN_CTL);
623 spdif->active = true;
624 break;
625 case SNDRV_PCM_TRIGGER_STOP:
626 case SNDRV_PCM_TRIGGER_SUSPEND:
627 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
628 reg = img_spdif_in_readl(spdif, IMG_SPDIF_IN_CTL);
629 reg &= ~IMG_SPDIF_IN_CTL_SRT_MASK;
630 img_spdif_in_writel(spdif, reg, IMG_SPDIF_IN_CTL);
631 spdif->active = false;
632 break;
633 default:
634 ret = -EINVAL;
635 }
636
637 spin_unlock_irqrestore(&spdif->lock, flags);
638
639 return ret;
640}
641
642static int img_spdif_in_hw_params(struct snd_pcm_substream *substream,
643 struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
644{
645 struct img_spdif_in *spdif = snd_soc_dai_get_drvdata(dai);
646 unsigned int rate, channels;
647 snd_pcm_format_t format;
648
649 rate = params_rate(params);
650 channels = params_channels(params);
651 format = params_format(params);
652
653 if (format != SNDRV_PCM_FORMAT_S32_LE)
654 return -EINVAL;
655
656 if (channels != 2)
657 return -EINVAL;
658
659 return img_spdif_in_do_clkgen_single(spdif, rate);
660}
661
662static const struct snd_soc_dai_ops img_spdif_in_dai_ops = {
663 .trigger = img_spdif_in_trigger,
664 .hw_params = img_spdif_in_hw_params
665};
666
667static int img_spdif_in_dai_probe(struct snd_soc_dai *dai)
668{
669 struct img_spdif_in *spdif = snd_soc_dai_get_drvdata(dai);
670
671 snd_soc_dai_init_dma_data(dai, NULL, &spdif->dma_data);
672
673 snd_soc_add_dai_controls(dai, img_spdif_in_controls,
674 ARRAY_SIZE(img_spdif_in_controls));
675
676 return 0;
677}
678
679static struct snd_soc_dai_driver img_spdif_in_dai = {
680 .probe = img_spdif_in_dai_probe,
681 .capture = {
682 .channels_min = 2,
683 .channels_max = 2,
684 .rates = SNDRV_PCM_RATE_8000_192000,
685 .formats = SNDRV_PCM_FMTBIT_S32_LE
686 },
687 .ops = &img_spdif_in_dai_ops
688};
689
690static const struct snd_soc_component_driver img_spdif_in_component = {
691 .name = "img-spdif-in"
692};
693
694static int img_spdif_in_probe(struct platform_device *pdev)
695{
696 struct img_spdif_in *spdif;
697 struct resource *res;
698 void __iomem *base;
699 int ret;
700 struct reset_control *rst;
701 u32 reg;
702 struct device *dev = &pdev->dev;
703
704 spdif = devm_kzalloc(&pdev->dev, sizeof(*spdif), GFP_KERNEL);
705 if (!spdif)
706 return -ENOMEM;
707
708 platform_set_drvdata(pdev, spdif);
709
710 spdif->dev = &pdev->dev;
711
712 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
713 base = devm_ioremap_resource(&pdev->dev, res);
714 if (IS_ERR(base))
715 return PTR_ERR(base);
716
717 spdif->base = base;
718
719 spdif->clk_sys = devm_clk_get(dev, "sys");
720 if (IS_ERR(spdif->clk_sys)) {
721 if (PTR_ERR(spdif->clk_sys) != -EPROBE_DEFER)
722 dev_err(dev, "Failed to acquire clock 'sys'\n");
723 return PTR_ERR(spdif->clk_sys);
724 }
725
726 ret = clk_prepare_enable(spdif->clk_sys);
727 if (ret)
728 return ret;
729
730 rst = devm_reset_control_get(&pdev->dev, "rst");
731 if (IS_ERR(rst)) {
732 if (PTR_ERR(rst) == -EPROBE_DEFER) {
733 ret = -EPROBE_DEFER;
734 goto err_clk_disable;
735 }
736 dev_dbg(dev, "No top level reset found\n");
737 img_spdif_in_writel(spdif, IMG_SPDIF_IN_SOFT_RESET_MASK,
738 IMG_SPDIF_IN_SOFT_RESET);
739 img_spdif_in_writel(spdif, 0, IMG_SPDIF_IN_SOFT_RESET);
740 } else {
741 reset_control_assert(rst);
742 reset_control_deassert(rst);
743 }
744
745 spin_lock_init(&spdif->lock);
746
747 spdif->dma_data.addr = res->start + IMG_SPDIF_IN_RX_FIFO_OFFSET;
748 spdif->dma_data.addr_width = 4;
749 spdif->dma_data.maxburst = 4;
750 spdif->trk = 0x80;
751 spdif->lock_acquire = 4;
752 spdif->lock_release = -128;
753
754 reg = (spdif->lock_acquire << IMG_SPDIF_IN_CTL_LOCKHI_SHIFT) &
755 IMG_SPDIF_IN_CTL_LOCKHI_MASK;
756 reg |= (spdif->lock_release << IMG_SPDIF_IN_CTL_LOCKLO_SHIFT) &
757 IMG_SPDIF_IN_CTL_LOCKLO_MASK;
758 reg |= (spdif->trk << IMG_SPDIF_IN_CTL_TRK_SHIFT) &
759 IMG_SPDIF_IN_CTL_TRK_MASK;
760 img_spdif_in_writel(spdif, reg, IMG_SPDIF_IN_CTL);
761
762 ret = devm_snd_soc_register_component(&pdev->dev,
763 &img_spdif_in_component, &img_spdif_in_dai, 1);
764 if (ret)
765 goto err_clk_disable;
766
767 ret = devm_snd_dmaengine_pcm_register(&pdev->dev, NULL, 0);
768 if (ret)
769 goto err_clk_disable;
770
771 return 0;
772
773err_clk_disable:
774 clk_disable_unprepare(spdif->clk_sys);
775
776 return ret;
777}
778
779static int img_spdif_in_dev_remove(struct platform_device *pdev)
780{
781 struct img_spdif_in *spdif = platform_get_drvdata(pdev);
782
783 clk_disable_unprepare(spdif->clk_sys);
784
785 return 0;
786}
787
788static const struct of_device_id img_spdif_in_of_match[] = {
789 { .compatible = "img,spdif-in" },
790 {}
791};
792MODULE_DEVICE_TABLE(of, img_spdif_in_of_match);
793
794static struct platform_driver img_spdif_in_driver = {
795 .driver = {
796 .name = "img-spdif-in",
797 .of_match_table = img_spdif_in_of_match
798 },
799 .probe = img_spdif_in_probe,
800 .remove = img_spdif_in_dev_remove
801};
802module_platform_driver(img_spdif_in_driver);
803
804MODULE_AUTHOR("Damien Horsley <Damien.Horsley@imgtec.com>");
805MODULE_DESCRIPTION("IMG SPDIF Input driver");
806MODULE_LICENSE("GPL v2");
diff --git a/sound/soc/img/img-spdif-out.c b/sound/soc/img/img-spdif-out.c
new file mode 100644
index 000000000000..08f93a5dadfe
--- /dev/null
+++ b/sound/soc/img/img-spdif-out.c
@@ -0,0 +1,441 @@
1/*
2 * IMG SPDIF output controller driver
3 *
4 * Copyright (C) 2015 Imagination Technologies Ltd.
5 *
6 * Author: Damien Horsley <Damien.Horsley@imgtec.com>
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms and conditions of the GNU General Public License,
10 * version 2, as published by the Free Software Foundation.
11 */
12
13#include <linux/clk.h>
14#include <linux/init.h>
15#include <linux/kernel.h>
16#include <linux/module.h>
17#include <linux/of.h>
18#include <linux/platform_device.h>
19#include <linux/pm_runtime.h>
20#include <linux/reset.h>
21
22#include <sound/core.h>
23#include <sound/dmaengine_pcm.h>
24#include <sound/initval.h>
25#include <sound/pcm.h>
26#include <sound/pcm_params.h>
27#include <sound/soc.h>
28
29#define IMG_SPDIF_OUT_TX_FIFO 0x0
30
31#define IMG_SPDIF_OUT_CTL 0x4
32#define IMG_SPDIF_OUT_CTL_FS_MASK BIT(4)
33#define IMG_SPDIF_OUT_CTL_CLK_MASK BIT(2)
34#define IMG_SPDIF_OUT_CTL_SRT_MASK BIT(0)
35
36#define IMG_SPDIF_OUT_CSL 0x14
37
38#define IMG_SPDIF_OUT_CSH_UV 0x18
39#define IMG_SPDIF_OUT_CSH_UV_CSH_SHIFT 0
40#define IMG_SPDIF_OUT_CSH_UV_CSH_MASK 0xff
41
42struct img_spdif_out {
43 spinlock_t lock;
44 void __iomem *base;
45 struct clk *clk_sys;
46 struct clk *clk_ref;
47 struct snd_dmaengine_dai_dma_data dma_data;
48 struct device *dev;
49 struct reset_control *rst;
50};
51
52static int img_spdif_out_suspend(struct device *dev)
53{
54 struct img_spdif_out *spdif = dev_get_drvdata(dev);
55
56 clk_disable_unprepare(spdif->clk_ref);
57
58 return 0;
59}
60
61static int img_spdif_out_resume(struct device *dev)
62{
63 struct img_spdif_out *spdif = dev_get_drvdata(dev);
64 int ret;
65
66 ret = clk_prepare_enable(spdif->clk_ref);
67 if (ret) {
68 dev_err(dev, "clk_enable failed: %d\n", ret);
69 return ret;
70 }
71
72 return 0;
73}
74
75static inline void img_spdif_out_writel(struct img_spdif_out *spdif, u32 val,
76 u32 reg)
77{
78 writel(val, spdif->base + reg);
79}
80
81static inline u32 img_spdif_out_readl(struct img_spdif_out *spdif, u32 reg)
82{
83 return readl(spdif->base + reg);
84}
85
86static void img_spdif_out_reset(struct img_spdif_out *spdif)
87{
88 u32 ctl, status_low, status_high;
89
90 ctl = img_spdif_out_readl(spdif, IMG_SPDIF_OUT_CTL) &
91 ~IMG_SPDIF_OUT_CTL_SRT_MASK;
92 status_low = img_spdif_out_readl(spdif, IMG_SPDIF_OUT_CSL);
93 status_high = img_spdif_out_readl(spdif, IMG_SPDIF_OUT_CSH_UV);
94
95 reset_control_assert(spdif->rst);
96 reset_control_deassert(spdif->rst);
97
98 img_spdif_out_writel(spdif, ctl, IMG_SPDIF_OUT_CTL);
99 img_spdif_out_writel(spdif, status_low, IMG_SPDIF_OUT_CSL);
100 img_spdif_out_writel(spdif, status_high, IMG_SPDIF_OUT_CSH_UV);
101}
102
103static int img_spdif_out_info(struct snd_kcontrol *kcontrol,
104 struct snd_ctl_elem_info *uinfo)
105{
106 uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
107 uinfo->count = 1;
108
109 return 0;
110}
111
112static int img_spdif_out_get_status_mask(struct snd_kcontrol *kcontrol,
113 struct snd_ctl_elem_value *ucontrol)
114{
115 ucontrol->value.iec958.status[0] = 0xff;
116 ucontrol->value.iec958.status[1] = 0xff;
117 ucontrol->value.iec958.status[2] = 0xff;
118 ucontrol->value.iec958.status[3] = 0xff;
119 ucontrol->value.iec958.status[4] = 0xff;
120
121 return 0;
122}
123
124static int img_spdif_out_get_status(struct snd_kcontrol *kcontrol,
125 struct snd_ctl_elem_value *ucontrol)
126{
127 struct snd_soc_dai *cpu_dai = snd_kcontrol_chip(kcontrol);
128 struct img_spdif_out *spdif = snd_soc_dai_get_drvdata(cpu_dai);
129 u32 reg;
130 unsigned long flags;
131
132 spin_lock_irqsave(&spdif->lock, flags);
133
134 reg = img_spdif_out_readl(spdif, IMG_SPDIF_OUT_CSL);
135 ucontrol->value.iec958.status[0] = reg & 0xff;
136 ucontrol->value.iec958.status[1] = (reg >> 8) & 0xff;
137 ucontrol->value.iec958.status[2] = (reg >> 16) & 0xff;
138 ucontrol->value.iec958.status[3] = (reg >> 24) & 0xff;
139
140 reg = img_spdif_out_readl(spdif, IMG_SPDIF_OUT_CSH_UV);
141 ucontrol->value.iec958.status[4] =
142 (reg & IMG_SPDIF_OUT_CSH_UV_CSH_MASK) >>
143 IMG_SPDIF_OUT_CSH_UV_CSH_SHIFT;
144
145 spin_unlock_irqrestore(&spdif->lock, flags);
146
147 return 0;
148}
149
150static int img_spdif_out_set_status(struct snd_kcontrol *kcontrol,
151 struct snd_ctl_elem_value *ucontrol)
152{
153 struct snd_soc_dai *cpu_dai = snd_kcontrol_chip(kcontrol);
154 struct img_spdif_out *spdif = snd_soc_dai_get_drvdata(cpu_dai);
155 u32 reg;
156 unsigned long flags;
157
158 reg = ((u32)ucontrol->value.iec958.status[3] << 24);
159 reg |= ((u32)ucontrol->value.iec958.status[2] << 16);
160 reg |= ((u32)ucontrol->value.iec958.status[1] << 8);
161 reg |= (u32)ucontrol->value.iec958.status[0];
162
163 spin_lock_irqsave(&spdif->lock, flags);
164
165 img_spdif_out_writel(spdif, reg, IMG_SPDIF_OUT_CSL);
166
167 reg = img_spdif_out_readl(spdif, IMG_SPDIF_OUT_CSH_UV);
168 reg &= ~IMG_SPDIF_OUT_CSH_UV_CSH_MASK;
169 reg |= (u32)ucontrol->value.iec958.status[4] <<
170 IMG_SPDIF_OUT_CSH_UV_CSH_SHIFT;
171 img_spdif_out_writel(spdif, reg, IMG_SPDIF_OUT_CSH_UV);
172
173 spin_unlock_irqrestore(&spdif->lock, flags);
174
175 return 0;
176}
177
178static struct snd_kcontrol_new img_spdif_out_controls[] = {
179 {
180 .access = SNDRV_CTL_ELEM_ACCESS_READ,
181 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
182 .name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, MASK),
183 .info = img_spdif_out_info,
184 .get = img_spdif_out_get_status_mask
185 },
186 {
187 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
188 .name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, DEFAULT),
189 .info = img_spdif_out_info,
190 .get = img_spdif_out_get_status,
191 .put = img_spdif_out_set_status
192 }
193};
194
195static int img_spdif_out_trigger(struct snd_pcm_substream *substream, int cmd,
196 struct snd_soc_dai *dai)
197{
198 struct img_spdif_out *spdif = snd_soc_dai_get_drvdata(dai);
199 u32 reg;
200 unsigned long flags;
201
202 switch (cmd) {
203 case SNDRV_PCM_TRIGGER_START:
204 case SNDRV_PCM_TRIGGER_RESUME:
205 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
206 reg = img_spdif_out_readl(spdif, IMG_SPDIF_OUT_CTL);
207 reg |= IMG_SPDIF_OUT_CTL_SRT_MASK;
208 img_spdif_out_writel(spdif, reg, IMG_SPDIF_OUT_CTL);
209 break;
210 case SNDRV_PCM_TRIGGER_STOP:
211 case SNDRV_PCM_TRIGGER_SUSPEND:
212 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
213 spin_lock_irqsave(&spdif->lock, flags);
214 img_spdif_out_reset(spdif);
215 spin_unlock_irqrestore(&spdif->lock, flags);
216 break;
217 default:
218 return -EINVAL;
219 }
220
221 return 0;
222}
223
224static int img_spdif_out_hw_params(struct snd_pcm_substream *substream,
225 struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
226{
227 struct img_spdif_out *spdif = snd_soc_dai_get_drvdata(dai);
228 unsigned int channels;
229 long pre_div_a, pre_div_b, diff_a, diff_b, rate, clk_rate;
230 u32 reg;
231 snd_pcm_format_t format;
232
233 rate = params_rate(params);
234 format = params_format(params);
235 channels = params_channels(params);
236
237 dev_dbg(spdif->dev, "hw_params rate %ld channels %u format %u\n",
238 rate, channels, format);
239
240 if (format != SNDRV_PCM_FORMAT_S32_LE)
241 return -EINVAL;
242
243 if (channels != 2)
244 return -EINVAL;
245
246 pre_div_a = clk_round_rate(spdif->clk_ref, rate * 256);
247 if (pre_div_a < 0)
248 return pre_div_a;
249 pre_div_b = clk_round_rate(spdif->clk_ref, rate * 384);
250 if (pre_div_b < 0)
251 return pre_div_b;
252
253 diff_a = abs((pre_div_a / 256) - rate);
254 diff_b = abs((pre_div_b / 384) - rate);
255
256 /* If diffs are equal, use lower clock rate */
257 if (diff_a > diff_b)
258 clk_set_rate(spdif->clk_ref, pre_div_b);
259 else
260 clk_set_rate(spdif->clk_ref, pre_div_a);
261
262 /*
263 * Another driver (eg machine driver) may have rejected the above
264 * change. Get the current rate and set the register bit according to
265 * the new min diff
266 */
267 clk_rate = clk_get_rate(spdif->clk_ref);
268
269 diff_a = abs((clk_rate / 256) - rate);
270 diff_b = abs((clk_rate / 384) - rate);
271
272 reg = img_spdif_out_readl(spdif, IMG_SPDIF_OUT_CTL);
273 if (diff_a <= diff_b)
274 reg &= ~IMG_SPDIF_OUT_CTL_CLK_MASK;
275 else
276 reg |= IMG_SPDIF_OUT_CTL_CLK_MASK;
277 img_spdif_out_writel(spdif, reg, IMG_SPDIF_OUT_CTL);
278
279 return 0;
280}
281
282static const struct snd_soc_dai_ops img_spdif_out_dai_ops = {
283 .trigger = img_spdif_out_trigger,
284 .hw_params = img_spdif_out_hw_params
285};
286
287static int img_spdif_out_dai_probe(struct snd_soc_dai *dai)
288{
289 struct img_spdif_out *spdif = snd_soc_dai_get_drvdata(dai);
290
291 snd_soc_dai_init_dma_data(dai, &spdif->dma_data, NULL);
292
293 snd_soc_add_dai_controls(dai, img_spdif_out_controls,
294 ARRAY_SIZE(img_spdif_out_controls));
295
296 return 0;
297}
298
299static struct snd_soc_dai_driver img_spdif_out_dai = {
300 .probe = img_spdif_out_dai_probe,
301 .playback = {
302 .channels_min = 2,
303 .channels_max = 2,
304 .rates = SNDRV_PCM_RATE_8000_192000,
305 .formats = SNDRV_PCM_FMTBIT_S32_LE
306 },
307 .ops = &img_spdif_out_dai_ops
308};
309
310static const struct snd_soc_component_driver img_spdif_out_component = {
311 .name = "img-spdif-out"
312};
313
314static int img_spdif_out_probe(struct platform_device *pdev)
315{
316 struct img_spdif_out *spdif;
317 struct resource *res;
318 void __iomem *base;
319 int ret;
320 struct device *dev = &pdev->dev;
321
322 spdif = devm_kzalloc(&pdev->dev, sizeof(*spdif), GFP_KERNEL);
323 if (!spdif)
324 return -ENOMEM;
325
326 platform_set_drvdata(pdev, spdif);
327
328 spdif->dev = &pdev->dev;
329
330 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
331 base = devm_ioremap_resource(&pdev->dev, res);
332 if (IS_ERR(base))
333 return PTR_ERR(base);
334
335 spdif->base = base;
336
337 spdif->rst = devm_reset_control_get(&pdev->dev, "rst");
338 if (IS_ERR(spdif->rst)) {
339 if (PTR_ERR(spdif->rst) != -EPROBE_DEFER)
340 dev_err(&pdev->dev, "No top level reset found\n");
341 return PTR_ERR(spdif->rst);
342 }
343
344 spdif->clk_sys = devm_clk_get(&pdev->dev, "sys");
345 if (IS_ERR(spdif->clk_sys)) {
346 if (PTR_ERR(spdif->clk_sys) != -EPROBE_DEFER)
347 dev_err(dev, "Failed to acquire clock 'sys'\n");
348 return PTR_ERR(spdif->clk_sys);
349 }
350
351 spdif->clk_ref = devm_clk_get(&pdev->dev, "ref");
352 if (IS_ERR(spdif->clk_ref)) {
353 if (PTR_ERR(spdif->clk_ref) != -EPROBE_DEFER)
354 dev_err(dev, "Failed to acquire clock 'ref'\n");
355 return PTR_ERR(spdif->clk_ref);
356 }
357
358 ret = clk_prepare_enable(spdif->clk_sys);
359 if (ret)
360 return ret;
361
362 img_spdif_out_writel(spdif, IMG_SPDIF_OUT_CTL_FS_MASK,
363 IMG_SPDIF_OUT_CTL);
364
365 img_spdif_out_reset(spdif);
366
367 pm_runtime_enable(&pdev->dev);
368 if (!pm_runtime_enabled(&pdev->dev)) {
369 ret = img_spdif_out_resume(&pdev->dev);
370 if (ret)
371 goto err_pm_disable;
372 }
373
374 spin_lock_init(&spdif->lock);
375
376 spdif->dma_data.addr = res->start + IMG_SPDIF_OUT_TX_FIFO;
377 spdif->dma_data.addr_width = 4;
378 spdif->dma_data.maxburst = 4;
379
380 ret = devm_snd_soc_register_component(&pdev->dev,
381 &img_spdif_out_component,
382 &img_spdif_out_dai, 1);
383 if (ret)
384 goto err_suspend;
385
386 ret = devm_snd_dmaengine_pcm_register(&pdev->dev, NULL, 0);
387 if (ret)
388 goto err_suspend;
389
390 dev_dbg(&pdev->dev, "Probe successful\n");
391
392 return 0;
393
394err_suspend:
395 if (!pm_runtime_status_suspended(&pdev->dev))
396 img_spdif_out_suspend(&pdev->dev);
397err_pm_disable:
398 pm_runtime_disable(&pdev->dev);
399 clk_disable_unprepare(spdif->clk_sys);
400
401 return ret;
402}
403
404static int img_spdif_out_dev_remove(struct platform_device *pdev)
405{
406 struct img_spdif_out *spdif = platform_get_drvdata(pdev);
407
408 pm_runtime_disable(&pdev->dev);
409 if (!pm_runtime_status_suspended(&pdev->dev))
410 img_spdif_out_suspend(&pdev->dev);
411
412 clk_disable_unprepare(spdif->clk_sys);
413
414 return 0;
415}
416
417static const struct of_device_id img_spdif_out_of_match[] = {
418 { .compatible = "img,spdif-out" },
419 {}
420};
421MODULE_DEVICE_TABLE(of, img_spdif_out_of_match);
422
423static const struct dev_pm_ops img_spdif_out_pm_ops = {
424 SET_RUNTIME_PM_OPS(img_spdif_out_suspend,
425 img_spdif_out_resume, NULL)
426};
427
428static struct platform_driver img_spdif_out_driver = {
429 .driver = {
430 .name = "img-spdif-out",
431 .of_match_table = img_spdif_out_of_match,
432 .pm = &img_spdif_out_pm_ops
433 },
434 .probe = img_spdif_out_probe,
435 .remove = img_spdif_out_dev_remove
436};
437module_platform_driver(img_spdif_out_driver);
438
439MODULE_AUTHOR("Damien Horsley <Damien.Horsley@imgtec.com>");
440MODULE_DESCRIPTION("IMG SPDIF Output driver");
441MODULE_LICENSE("GPL v2");
diff --git a/sound/soc/img/pistachio-internal-dac.c b/sound/soc/img/pistachio-internal-dac.c
new file mode 100644
index 000000000000..162a0fd68c7b
--- /dev/null
+++ b/sound/soc/img/pistachio-internal-dac.c
@@ -0,0 +1,287 @@
1/*
2 * Pistachio internal dac driver
3 *
4 * Copyright (C) 2015 Imagination Technologies Ltd.
5 *
6 * Author: Damien Horsley <Damien.Horsley@imgtec.com>
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms and conditions of the GNU General Public License,
10 * version 2, as published by the Free Software Foundation.
11 */
12
13#include <linux/clk.h>
14#include <linux/delay.h>
15#include <linux/mfd/syscon.h>
16#include <linux/module.h>
17#include <linux/pm_runtime.h>
18#include <linux/regmap.h>
19#include <linux/regulator/consumer.h>
20
21#include <sound/pcm_params.h>
22#include <sound/soc.h>
23
24#define PISTACHIO_INTERNAL_DAC_CTRL 0x40
25#define PISTACHIO_INTERNAL_DAC_CTRL_PWR_SEL_MASK 0x2
26#define PISTACHIO_INTERNAL_DAC_CTRL_PWRDN_MASK 0x1
27
28#define PISTACHIO_INTERNAL_DAC_SRST 0x44
29#define PISTACHIO_INTERNAL_DAC_SRST_MASK 0x1
30
31#define PISTACHIO_INTERNAL_DAC_GTI_CTRL 0x48
32#define PISTACHIO_INTERNAL_DAC_GTI_CTRL_ADDR_SHIFT 0
33#define PISTACHIO_INTERNAL_DAC_GTI_CTRL_ADDR_MASK 0xFFF
34#define PISTACHIO_INTERNAL_DAC_GTI_CTRL_WE_MASK 0x1000
35#define PISTACHIO_INTERNAL_DAC_GTI_CTRL_WDATA_SHIFT 13
36#define PISTACHIO_INTERNAL_DAC_GTI_CTRL_WDATA_MASK 0x1FE000
37
38#define PISTACHIO_INTERNAL_DAC_PWR 0x1
39#define PISTACHIO_INTERNAL_DAC_PWR_MASK 0x1
40
41#define PISTACHIO_INTERNAL_DAC_FORMATS (SNDRV_PCM_FMTBIT_S24_LE | \
42 SNDRV_PCM_FMTBIT_S32_LE)
43
44/* codec private data */
45struct pistachio_internal_dac {
46 struct regmap *regmap;
47 struct regulator *supply;
48 bool mute;
49};
50
51static const struct snd_kcontrol_new pistachio_internal_dac_snd_controls[] = {
52 SOC_SINGLE("Playback Switch", PISTACHIO_INTERNAL_DAC_CTRL, 2, 1, 1)
53};
54
55static const struct snd_soc_dapm_widget pistachio_internal_dac_widgets[] = {
56 SND_SOC_DAPM_DAC("DAC", "Playback", SND_SOC_NOPM, 0, 0),
57 SND_SOC_DAPM_OUTPUT("AOUTL"),
58 SND_SOC_DAPM_OUTPUT("AOUTR"),
59};
60
61static const struct snd_soc_dapm_route pistachio_internal_dac_routes[] = {
62 { "AOUTL", NULL, "DAC" },
63 { "AOUTR", NULL, "DAC" },
64};
65
66static void pistachio_internal_dac_reg_writel(struct regmap *top_regs,
67 u32 val, u32 reg)
68{
69 regmap_update_bits(top_regs, PISTACHIO_INTERNAL_DAC_GTI_CTRL,
70 PISTACHIO_INTERNAL_DAC_GTI_CTRL_ADDR_MASK,
71 reg << PISTACHIO_INTERNAL_DAC_GTI_CTRL_ADDR_SHIFT);
72
73 regmap_update_bits(top_regs, PISTACHIO_INTERNAL_DAC_GTI_CTRL,
74 PISTACHIO_INTERNAL_DAC_GTI_CTRL_WDATA_MASK,
75 val << PISTACHIO_INTERNAL_DAC_GTI_CTRL_WDATA_SHIFT);
76
77 regmap_update_bits(top_regs, PISTACHIO_INTERNAL_DAC_GTI_CTRL,
78 PISTACHIO_INTERNAL_DAC_GTI_CTRL_WE_MASK,
79 PISTACHIO_INTERNAL_DAC_GTI_CTRL_WE_MASK);
80
81 regmap_update_bits(top_regs, PISTACHIO_INTERNAL_DAC_GTI_CTRL,
82 PISTACHIO_INTERNAL_DAC_GTI_CTRL_WE_MASK, 0);
83}
84
85static void pistachio_internal_dac_pwr_off(struct pistachio_internal_dac *dac)
86{
87 regmap_update_bits(dac->regmap, PISTACHIO_INTERNAL_DAC_CTRL,
88 PISTACHIO_INTERNAL_DAC_CTRL_PWRDN_MASK,
89 PISTACHIO_INTERNAL_DAC_CTRL_PWRDN_MASK);
90
91 pistachio_internal_dac_reg_writel(dac->regmap, 0,
92 PISTACHIO_INTERNAL_DAC_PWR);
93}
94
95static void pistachio_internal_dac_pwr_on(struct pistachio_internal_dac *dac)
96{
97 regmap_update_bits(dac->regmap, PISTACHIO_INTERNAL_DAC_SRST,
98 PISTACHIO_INTERNAL_DAC_SRST_MASK,
99 PISTACHIO_INTERNAL_DAC_SRST_MASK);
100
101 regmap_update_bits(dac->regmap, PISTACHIO_INTERNAL_DAC_SRST,
102 PISTACHIO_INTERNAL_DAC_SRST_MASK, 0);
103
104 pistachio_internal_dac_reg_writel(dac->regmap,
105 PISTACHIO_INTERNAL_DAC_PWR_MASK,
106 PISTACHIO_INTERNAL_DAC_PWR);
107
108 regmap_update_bits(dac->regmap, PISTACHIO_INTERNAL_DAC_CTRL,
109 PISTACHIO_INTERNAL_DAC_CTRL_PWRDN_MASK, 0);
110}
111
112static struct snd_soc_dai_driver pistachio_internal_dac_dais[] = {
113 {
114 .name = "pistachio_internal_dac",
115 .playback = {
116 .stream_name = "Playback",
117 .channels_min = 2,
118 .channels_max = 2,
119 .rates = SNDRV_PCM_RATE_8000_48000,
120 .formats = PISTACHIO_INTERNAL_DAC_FORMATS,
121 }
122 },
123};
124
125static int pistachio_internal_dac_codec_probe(struct snd_soc_codec *codec)
126{
127 struct pistachio_internal_dac *dac = snd_soc_codec_get_drvdata(codec);
128
129 snd_soc_codec_init_regmap(codec, dac->regmap);
130
131 return 0;
132}
133
134static const struct snd_soc_codec_driver pistachio_internal_dac_driver = {
135 .probe = pistachio_internal_dac_codec_probe,
136 .idle_bias_off = true,
137 .controls = pistachio_internal_dac_snd_controls,
138 .num_controls = ARRAY_SIZE(pistachio_internal_dac_snd_controls),
139 .dapm_widgets = pistachio_internal_dac_widgets,
140 .num_dapm_widgets = ARRAY_SIZE(pistachio_internal_dac_widgets),
141 .dapm_routes = pistachio_internal_dac_routes,
142 .num_dapm_routes = ARRAY_SIZE(pistachio_internal_dac_routes),
143};
144
145static int pistachio_internal_dac_probe(struct platform_device *pdev)
146{
147 struct pistachio_internal_dac *dac;
148 int ret, voltage;
149 struct device *dev = &pdev->dev;
150 u32 reg;
151
152 dac = devm_kzalloc(dev, sizeof(*dac), GFP_KERNEL);
153
154 if (!dac)
155 return -ENOMEM;
156
157 platform_set_drvdata(pdev, dac);
158
159 dac->regmap = syscon_regmap_lookup_by_phandle(pdev->dev.of_node,
160 "img,cr-top");
161 if (IS_ERR(dac->regmap))
162 return PTR_ERR(dac->regmap);
163
164 dac->supply = devm_regulator_get(dev, "VDD");
165 if (IS_ERR(dac->supply)) {
166 ret = PTR_ERR(dac->supply);
167 if (ret != -EPROBE_DEFER)
168 dev_err(dev, "failed to acquire supply 'VDD-supply': %d\n", ret);
169 return ret;
170 }
171
172 ret = regulator_enable(dac->supply);
173 if (ret) {
174 dev_err(dev, "failed to enable supply: %d\n", ret);
175 return ret;
176 }
177
178 voltage = regulator_get_voltage(dac->supply);
179
180 switch (voltage) {
181 case 1800000:
182 reg = 0;
183 break;
184 case 3300000:
185 reg = PISTACHIO_INTERNAL_DAC_CTRL_PWR_SEL_MASK;
186 break;
187 default:
188 dev_err(dev, "invalid voltage: %d\n", voltage);
189 ret = -EINVAL;
190 goto err_regulator;
191 }
192
193 regmap_update_bits(dac->regmap, PISTACHIO_INTERNAL_DAC_CTRL,
194 PISTACHIO_INTERNAL_DAC_CTRL_PWR_SEL_MASK, reg);
195
196 pistachio_internal_dac_pwr_off(dac);
197 pistachio_internal_dac_pwr_on(dac);
198
199 pm_runtime_set_active(dev);
200 pm_runtime_enable(dev);
201 pm_runtime_idle(dev);
202
203 ret = snd_soc_register_codec(dev, &pistachio_internal_dac_driver,
204 pistachio_internal_dac_dais,
205 ARRAY_SIZE(pistachio_internal_dac_dais));
206 if (ret) {
207 dev_err(dev, "failed to register codec: %d\n", ret);
208 goto err_pwr;
209 }
210
211 return 0;
212
213err_pwr:
214 pm_runtime_disable(&pdev->dev);
215 pistachio_internal_dac_pwr_off(dac);
216err_regulator:
217 regulator_disable(dac->supply);
218
219 return ret;
220}
221
222static int pistachio_internal_dac_remove(struct platform_device *pdev)
223{
224 struct pistachio_internal_dac *dac = dev_get_drvdata(&pdev->dev);
225
226 snd_soc_unregister_codec(&pdev->dev);
227 pm_runtime_disable(&pdev->dev);
228 pistachio_internal_dac_pwr_off(dac);
229 regulator_disable(dac->supply);
230
231 return 0;
232}
233
234#ifdef CONFIG_PM
235static int pistachio_internal_dac_rt_resume(struct device *dev)
236{
237 struct pistachio_internal_dac *dac = dev_get_drvdata(dev);
238 int ret;
239
240 ret = regulator_enable(dac->supply);
241 if (ret) {
242 dev_err(dev, "failed to enable supply: %d\n", ret);
243 return ret;
244 }
245
246 pistachio_internal_dac_pwr_on(dac);
247
248 return 0;
249}
250
251static int pistachio_internal_dac_rt_suspend(struct device *dev)
252{
253 struct pistachio_internal_dac *dac = dev_get_drvdata(dev);
254
255 pistachio_internal_dac_pwr_off(dac);
256
257 regulator_disable(dac->supply);
258
259 return 0;
260}
261#endif
262
263static const struct dev_pm_ops pistachio_internal_dac_pm_ops = {
264 SET_RUNTIME_PM_OPS(pistachio_internal_dac_rt_suspend,
265 pistachio_internal_dac_rt_resume, NULL)
266};
267
268static const struct of_device_id pistachio_internal_dac_of_match[] = {
269 { .compatible = "img,pistachio-internal-dac" },
270 {}
271};
272MODULE_DEVICE_TABLE(of, pistachio_internal_dac_of_match);
273
274static struct platform_driver pistachio_internal_dac_plat_driver = {
275 .driver = {
276 .name = "img-pistachio-internal-dac",
277 .of_match_table = pistachio_internal_dac_of_match,
278 .pm = &pistachio_internal_dac_pm_ops
279 },
280 .probe = pistachio_internal_dac_probe,
281 .remove = pistachio_internal_dac_remove
282};
283module_platform_driver(pistachio_internal_dac_plat_driver);
284
285MODULE_DESCRIPTION("Pistachio Internal DAC driver");
286MODULE_AUTHOR("Damien Horsley <Damien.Horsley@imgtec.com>");
287MODULE_LICENSE("GPL v2");
diff --git a/sound/soc/intel/Kconfig b/sound/soc/intel/Kconfig
index d430ef5a4f38..803f95e40679 100644
--- a/sound/soc/intel/Kconfig
+++ b/sound/soc/intel/Kconfig
@@ -24,6 +24,7 @@ config SND_SST_IPC_PCI
24config SND_SST_IPC_ACPI 24config 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 depends on ACPI 28 depends on ACPI
28 29
29config SND_SOC_INTEL_SST 30config SND_SOC_INTEL_SST
@@ -43,7 +44,7 @@ config SND_SOC_INTEL_BAYTRAIL
43config SND_SOC_INTEL_HASWELL_MACH 44config SND_SOC_INTEL_HASWELL_MACH
44 tristate "ASoC Audio DSP support for Intel Haswell Lynxpoint" 45 tristate "ASoC Audio DSP support for Intel Haswell Lynxpoint"
45 depends on X86_INTEL_LPSS && I2C && I2C_DESIGNWARE_PLATFORM 46 depends on X86_INTEL_LPSS && I2C && I2C_DESIGNWARE_PLATFORM
46 depends on DW_DMAC_CORE 47 depends on DW_DMAC_CORE=y
47 select SND_SOC_INTEL_SST 48 select SND_SOC_INTEL_SST
48 select SND_SOC_INTEL_HASWELL 49 select SND_SOC_INTEL_HASWELL
49 select SND_SOC_RT5640 50 select SND_SOC_RT5640
@@ -56,18 +57,19 @@ config SND_SOC_INTEL_HASWELL_MACH
56config SND_SOC_INTEL_BYT_RT5640_MACH 57config SND_SOC_INTEL_BYT_RT5640_MACH
57 tristate "ASoC Audio driver for Intel Baytrail with RT5640 codec" 58 tristate "ASoC Audio driver for Intel Baytrail with RT5640 codec"
58 depends on X86_INTEL_LPSS && I2C 59 depends on X86_INTEL_LPSS && I2C
59 depends on DW_DMAC_CORE 60 depends on DW_DMAC_CORE=y && (SND_SOC_INTEL_BYTCR_RT5640_MACH = n)
60 select SND_SOC_INTEL_SST 61 select SND_SOC_INTEL_SST
61 select SND_SOC_INTEL_BAYTRAIL 62 select SND_SOC_INTEL_BAYTRAIL
62 select SND_SOC_RT5640 63 select SND_SOC_RT5640
63 help 64 help
64 This adds audio driver for Intel Baytrail platform based boards 65 This adds audio driver for Intel Baytrail platform based boards
65 with the RT5640 audio codec. 66 with the RT5640 audio codec. This driver is deprecated, use
67 SND_SOC_INTEL_BYTCR_RT5640_MACH instead for better functionality
66 68
67config SND_SOC_INTEL_BYT_MAX98090_MACH 69config SND_SOC_INTEL_BYT_MAX98090_MACH
68 tristate "ASoC Audio driver for Intel Baytrail with MAX98090 codec" 70 tristate "ASoC Audio driver for Intel Baytrail with MAX98090 codec"
69 depends on X86_INTEL_LPSS && I2C 71 depends on X86_INTEL_LPSS && I2C
70 depends on DW_DMAC_CORE 72 depends on DW_DMAC_CORE=y
71 select SND_SOC_INTEL_SST 73 select SND_SOC_INTEL_SST
72 select SND_SOC_INTEL_BAYTRAIL 74 select SND_SOC_INTEL_BAYTRAIL
73 select SND_SOC_MAX98090 75 select SND_SOC_MAX98090
@@ -79,7 +81,7 @@ config SND_SOC_INTEL_BROADWELL_MACH
79 tristate "ASoC Audio DSP support for Intel Broadwell Wildcatpoint" 81 tristate "ASoC Audio DSP support for Intel Broadwell Wildcatpoint"
80 depends on X86_INTEL_LPSS && I2C && DW_DMAC && \ 82 depends on X86_INTEL_LPSS && I2C && DW_DMAC && \
81 I2C_DESIGNWARE_PLATFORM 83 I2C_DESIGNWARE_PLATFORM
82 depends on DW_DMAC_CORE 84 depends on DW_DMAC_CORE=y
83 select SND_SOC_INTEL_SST 85 select SND_SOC_INTEL_SST
84 select SND_SOC_INTEL_HASWELL 86 select SND_SOC_INTEL_HASWELL
85 select SND_SOC_RT286 87 select SND_SOC_RT286
@@ -90,14 +92,26 @@ config SND_SOC_INTEL_BROADWELL_MACH
90 If unsure select "N". 92 If unsure select "N".
91 93
92config SND_SOC_INTEL_BYTCR_RT5640_MACH 94config SND_SOC_INTEL_BYTCR_RT5640_MACH
93 tristate "ASoC Audio DSP Support for MID BYT Platform" 95 tristate "ASoC Audio driver for Intel Baytrail and Baytrail-CR with RT5640 codec"
94 depends on X86 && I2C 96 depends on X86 && I2C
95 select SND_SOC_RT5640 97 select SND_SOC_RT5640
96 select SND_SST_MFLD_PLATFORM 98 select SND_SST_MFLD_PLATFORM
97 select SND_SST_IPC_ACPI 99 select SND_SST_IPC_ACPI
98 help 100 help
99 This adds support for ASoC machine driver for Intel(R) MID Baytrail platform 101 This adds support for ASoC machine driver for Intel(R) Baytrail and Baytrail-CR
100 used as alsa device in audio substem in Intel(R) MID devices 102 platforms with RT5640 audio codec.
103 Say Y if you have such a device
104 If unsure select "N".
105
106config SND_SOC_INTEL_BYTCR_RT5651_MACH
107 tristate "ASoC Audio driver for Intel Baytrail and Baytrail-CR with RT5651 codec"
108 depends on X86 && I2C
109 select SND_SOC_RT5651
110 select SND_SST_MFLD_PLATFORM
111 select SND_SST_IPC_ACPI
112 help
113 This adds support for ASoC machine driver for Intel(R) Baytrail and Baytrail-CR
114 platforms with RT5651 audio codec.
101 Say Y if you have such a device 115 Say Y if you have such a device
102 If unsure select "N". 116 If unsure select "N".
103 117
@@ -154,3 +168,31 @@ config SND_SOC_INTEL_SKL_RT286_MACH
154 with RT286 I2S audio codec. 168 with RT286 I2S audio codec.
155 Say Y if you have such a device 169 Say Y if you have such a device
156 If unsure select "N". 170 If unsure select "N".
171
172config SND_SOC_INTEL_SKL_NAU88L25_SSM4567_MACH
173 tristate "ASoC Audio driver for SKL with NAU88L25 and SSM4567 in I2S Mode"
174 depends on X86_INTEL_LPSS && I2C
175 select SND_SOC_INTEL_SST
176 select SND_SOC_INTEL_SKYLAKE
177 select SND_SOC_NAU8825
178 select SND_SOC_SSM4567
179 select SND_SOC_DMIC
180 help
181 This adds support for ASoC Onboard Codec I2S machine driver. This will
182 create an alsa sound card for NAU88L25 + SSM4567.
183 Say Y if you have such a device
184 If unsure select "N".
185
186config SND_SOC_INTEL_SKL_NAU88L25_MAX98357A_MACH
187 tristate "ASoC Audio driver for SKL with NAU88L25 and MAX98357A in I2S Mode"
188 depends on X86_INTEL_LPSS && I2C
189 select SND_SOC_INTEL_SST
190 select SND_SOC_INTEL_SKYLAKE
191 select SND_SOC_NAU8825
192 select SND_SOC_MAX98357A
193 select SND_SOC_DMIC
194 help
195 This adds support for ASoC Onboard Codec I2S machine driver. This will
196 create an alsa sound card for NAU88L25 + MAX98357A.
197 Say Y if you have such a device
198 If unsure select "N".
diff --git a/sound/soc/intel/atom/sst-atom-controls.c b/sound/soc/intel/atom/sst-atom-controls.c
index d55388e082e1..b97e6adcf1b2 100644
--- a/sound/soc/intel/atom/sst-atom-controls.c
+++ b/sound/soc/intel/atom/sst-atom-controls.c
@@ -443,7 +443,7 @@ static int sst_gain_get(struct snd_kcontrol *kcontrol,
443 break; 443 break;
444 444
445 case SST_GAIN_MUTE: 445 case SST_GAIN_MUTE:
446 ucontrol->value.integer.value[0] = gv->mute ? 1 : 0; 446 ucontrol->value.integer.value[0] = gv->mute ? 0 : 1;
447 break; 447 break;
448 448
449 case SST_GAIN_RAMP_DURATION: 449 case SST_GAIN_RAMP_DURATION:
@@ -479,7 +479,7 @@ static int sst_gain_put(struct snd_kcontrol *kcontrol,
479 break; 479 break;
480 480
481 case SST_GAIN_MUTE: 481 case SST_GAIN_MUTE:
482 gv->mute = !!ucontrol->value.integer.value[0]; 482 gv->mute = !ucontrol->value.integer.value[0];
483 dev_dbg(cmpnt->dev, "%s: Mute %d\n", mc->pname, gv->mute); 483 dev_dbg(cmpnt->dev, "%s: Mute %d\n", mc->pname, gv->mute);
484 break; 484 break;
485 485
@@ -1109,6 +1109,7 @@ static const struct snd_soc_dapm_route intercon[] = {
1109 {"media0_in", NULL, "Compress Playback"}, 1109 {"media0_in", NULL, "Compress Playback"},
1110 {"media1_in", NULL, "Headset Playback"}, 1110 {"media1_in", NULL, "Headset Playback"},
1111 {"media2_in", NULL, "pcm0_out"}, 1111 {"media2_in", NULL, "pcm0_out"},
1112 {"media3_in", NULL, "Deepbuffer Playback"},
1112 1113
1113 {"media0_out mix 0", "media0_in Switch", "media0_in"}, 1114 {"media0_out mix 0", "media0_in Switch", "media0_in"},
1114 {"media0_out mix 0", "media1_in Switch", "media1_in"}, 1115 {"media0_out mix 0", "media1_in Switch", "media1_in"},
diff --git a/sound/soc/intel/atom/sst-atom-controls.h b/sound/soc/intel/atom/sst-atom-controls.h
index 93de8045d4e1..e0113112f668 100644
--- a/sound/soc/intel/atom/sst-atom-controls.h
+++ b/sound/soc/intel/atom/sst-atom-controls.h
@@ -28,6 +28,7 @@
28 28
29enum { 29enum {
30 MERR_DPCM_AUDIO = 0, 30 MERR_DPCM_AUDIO = 0,
31 MERR_DPCM_DEEP_BUFFER,
31 MERR_DPCM_COMPR, 32 MERR_DPCM_COMPR,
32}; 33};
33 34
diff --git a/sound/soc/intel/atom/sst-mfld-platform-pcm.c b/sound/soc/intel/atom/sst-mfld-platform-pcm.c
index 0487cfaac538..55c33dc76ce4 100644
--- a/sound/soc/intel/atom/sst-mfld-platform-pcm.c
+++ b/sound/soc/intel/atom/sst-mfld-platform-pcm.c
@@ -98,6 +98,7 @@ static struct sst_dev_stream_map dpcm_strm_map[] = {
98 {MERR_DPCM_AUDIO, 0, SNDRV_PCM_STREAM_PLAYBACK, PIPE_MEDIA1_IN, SST_TASK_ID_MEDIA, 0}, 98 {MERR_DPCM_AUDIO, 0, SNDRV_PCM_STREAM_PLAYBACK, PIPE_MEDIA1_IN, SST_TASK_ID_MEDIA, 0},
99 {MERR_DPCM_COMPR, 0, SNDRV_PCM_STREAM_PLAYBACK, PIPE_MEDIA0_IN, SST_TASK_ID_MEDIA, 0}, 99 {MERR_DPCM_COMPR, 0, SNDRV_PCM_STREAM_PLAYBACK, PIPE_MEDIA0_IN, SST_TASK_ID_MEDIA, 0},
100 {MERR_DPCM_AUDIO, 0, SNDRV_PCM_STREAM_CAPTURE, PIPE_PCM1_OUT, SST_TASK_ID_MEDIA, 0}, 100 {MERR_DPCM_AUDIO, 0, SNDRV_PCM_STREAM_CAPTURE, PIPE_PCM1_OUT, SST_TASK_ID_MEDIA, 0},
101 {MERR_DPCM_DEEP_BUFFER, 0, SNDRV_PCM_STREAM_PLAYBACK, PIPE_MEDIA3_IN, SST_TASK_ID_MEDIA, 0},
101}; 102};
102 103
103static int sst_media_digital_mute(struct snd_soc_dai *dai, int mute, int stream) 104static int sst_media_digital_mute(struct snd_soc_dai *dai, int mute, int stream)
@@ -500,14 +501,25 @@ static struct snd_soc_dai_driver sst_platform_dai[] = {
500 .channels_min = SST_STEREO, 501 .channels_min = SST_STEREO,
501 .channels_max = SST_STEREO, 502 .channels_max = SST_STEREO,
502 .rates = SNDRV_PCM_RATE_44100|SNDRV_PCM_RATE_48000, 503 .rates = SNDRV_PCM_RATE_44100|SNDRV_PCM_RATE_48000,
503 .formats = SNDRV_PCM_FMTBIT_S16_LE, 504 .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE,
504 }, 505 },
505 .capture = { 506 .capture = {
506 .stream_name = "Headset Capture", 507 .stream_name = "Headset Capture",
507 .channels_min = 1, 508 .channels_min = 1,
508 .channels_max = 2, 509 .channels_max = 2,
509 .rates = SNDRV_PCM_RATE_44100|SNDRV_PCM_RATE_48000, 510 .rates = SNDRV_PCM_RATE_44100|SNDRV_PCM_RATE_48000,
510 .formats = SNDRV_PCM_FMTBIT_S16_LE, 511 .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE,
512 },
513},
514{
515 .name = "deepbuffer-cpu-dai",
516 .ops = &sst_media_dai_ops,
517 .playback = {
518 .stream_name = "Deepbuffer Playback",
519 .channels_min = SST_STEREO,
520 .channels_max = SST_STEREO,
521 .rates = SNDRV_PCM_RATE_44100|SNDRV_PCM_RATE_48000,
522 .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE,
511 }, 523 },
512}, 524},
513{ 525{
@@ -516,10 +528,6 @@ static struct snd_soc_dai_driver sst_platform_dai[] = {
516 .ops = &sst_compr_dai_ops, 528 .ops = &sst_compr_dai_ops,
517 .playback = { 529 .playback = {
518 .stream_name = "Compress Playback", 530 .stream_name = "Compress Playback",
519 .channels_min = SST_STEREO,
520 .channels_max = SST_STEREO,
521 .rates = SNDRV_PCM_RATE_48000,
522 .formats = SNDRV_PCM_FMTBIT_S16_LE,
523 }, 531 },
524}, 532},
525/* BE CPU Dais */ 533/* BE CPU Dais */
@@ -760,15 +768,15 @@ static int sst_platform_remove(struct platform_device *pdev)
760static int sst_soc_prepare(struct device *dev) 768static int sst_soc_prepare(struct device *dev)
761{ 769{
762 struct sst_data *drv = dev_get_drvdata(dev); 770 struct sst_data *drv = dev_get_drvdata(dev);
763 int i; 771 struct snd_soc_pcm_runtime *rtd;
764 772
765 /* suspend all pcms first */ 773 /* suspend all pcms first */
766 snd_soc_suspend(drv->soc_card->dev); 774 snd_soc_suspend(drv->soc_card->dev);
767 snd_soc_poweroff(drv->soc_card->dev); 775 snd_soc_poweroff(drv->soc_card->dev);
768 776
769 /* set the SSPs to idle */ 777 /* set the SSPs to idle */
770 for (i = 0; i < drv->soc_card->num_rtd; i++) { 778 list_for_each_entry(rtd, &drv->soc_card->rtd_list, list) {
771 struct snd_soc_dai *dai = drv->soc_card->rtd[i].cpu_dai; 779 struct snd_soc_dai *dai = rtd->cpu_dai;
772 780
773 if (dai->active) { 781 if (dai->active) {
774 send_ssp_cmd(dai, dai->name, 0); 782 send_ssp_cmd(dai, dai->name, 0);
@@ -782,11 +790,11 @@ static int sst_soc_prepare(struct device *dev)
782static void sst_soc_complete(struct device *dev) 790static void sst_soc_complete(struct device *dev)
783{ 791{
784 struct sst_data *drv = dev_get_drvdata(dev); 792 struct sst_data *drv = dev_get_drvdata(dev);
785 int i; 793 struct snd_soc_pcm_runtime *rtd;
786 794
787 /* restart SSPs */ 795 /* restart SSPs */
788 for (i = 0; i < drv->soc_card->num_rtd; i++) { 796 list_for_each_entry(rtd, &drv->soc_card->rtd_list, list) {
789 struct snd_soc_dai *dai = drv->soc_card->rtd[i].cpu_dai; 797 struct snd_soc_dai *dai = rtd->cpu_dai;
790 798
791 if (dai->active) { 799 if (dai->active) {
792 sst_handle_vb_timer(dai, true); 800 sst_handle_vb_timer(dai, true);
diff --git a/sound/soc/intel/atom/sst/sst_acpi.c b/sound/soc/intel/atom/sst/sst_acpi.c
index bb19b5801466..4fce03fc1870 100644
--- a/sound/soc/intel/atom/sst/sst_acpi.c
+++ b/sound/soc/intel/atom/sst/sst_acpi.c
@@ -40,18 +40,9 @@
40#include <acpi/acpi_bus.h> 40#include <acpi/acpi_bus.h>
41#include "../sst-mfld-platform.h" 41#include "../sst-mfld-platform.h"
42#include "../../common/sst-dsp.h" 42#include "../../common/sst-dsp.h"
43#include "../../common/sst-acpi.h"
43#include "sst.h" 44#include "sst.h"
44 45
45struct sst_machines {
46 char *codec_id;
47 char board[32];
48 char machine[32];
49 void (*machine_quirk)(void);
50 char firmware[FW_NAME_SIZE];
51 struct sst_platform_info *pdata;
52
53};
54
55/* LPE viewpoint addresses */ 46/* LPE viewpoint addresses */
56#define SST_BYT_IRAM_PHY_START 0xff2c0000 47#define SST_BYT_IRAM_PHY_START 0xff2c0000
57#define SST_BYT_IRAM_PHY_END 0xff2d4000 48#define SST_BYT_IRAM_PHY_END 0xff2d4000
@@ -223,37 +214,16 @@ static int sst_platform_get_resources(struct intel_sst_drv *ctx)
223 return 0; 214 return 0;
224} 215}
225 216
226static acpi_status sst_acpi_mach_match(acpi_handle handle, u32 level,
227 void *context, void **ret)
228{
229 *(bool *)context = true;
230 return AE_OK;
231}
232
233static struct sst_machines *sst_acpi_find_machine(
234 struct sst_machines *machines)
235{
236 struct sst_machines *mach;
237 bool found = false;
238
239 for (mach = machines; mach->codec_id; mach++)
240 if (ACPI_SUCCESS(acpi_get_devices(mach->codec_id,
241 sst_acpi_mach_match,
242 &found, NULL)) && found)
243 return mach;
244
245 return NULL;
246}
247
248static int sst_acpi_probe(struct platform_device *pdev) 217static int sst_acpi_probe(struct platform_device *pdev)
249{ 218{
250 struct device *dev = &pdev->dev; 219 struct device *dev = &pdev->dev;
251 int ret = 0; 220 int ret = 0;
252 struct intel_sst_drv *ctx; 221 struct intel_sst_drv *ctx;
253 const struct acpi_device_id *id; 222 const struct acpi_device_id *id;
254 struct sst_machines *mach; 223 struct sst_acpi_mach *mach;
255 struct platform_device *mdev; 224 struct platform_device *mdev;
256 struct platform_device *plat_dev; 225 struct platform_device *plat_dev;
226 struct sst_platform_info *pdata;
257 unsigned int dev_id; 227 unsigned int dev_id;
258 228
259 id = acpi_match_device(dev->driver->acpi_match_table, dev); 229 id = acpi_match_device(dev->driver->acpi_match_table, dev);
@@ -261,12 +231,13 @@ static int sst_acpi_probe(struct platform_device *pdev)
261 return -ENODEV; 231 return -ENODEV;
262 dev_dbg(dev, "for %s", id->id); 232 dev_dbg(dev, "for %s", id->id);
263 233
264 mach = (struct sst_machines *)id->driver_data; 234 mach = (struct sst_acpi_mach *)id->driver_data;
265 mach = sst_acpi_find_machine(mach); 235 mach = sst_acpi_find_machine(mach);
266 if (mach == NULL) { 236 if (mach == NULL) {
267 dev_err(dev, "No matching machine driver found\n"); 237 dev_err(dev, "No matching machine driver found\n");
268 return -ENODEV; 238 return -ENODEV;
269 } 239 }
240 pdata = mach->pdata;
270 241
271 ret = kstrtouint(id->id, 16, &dev_id); 242 ret = kstrtouint(id->id, 16, &dev_id);
272 if (ret < 0) { 243 if (ret < 0) {
@@ -276,16 +247,23 @@ static int sst_acpi_probe(struct platform_device *pdev)
276 247
277 dev_dbg(dev, "ACPI device id: %x\n", dev_id); 248 dev_dbg(dev, "ACPI device id: %x\n", dev_id);
278 249
279 plat_dev = platform_device_register_data(dev, mach->pdata->platform, -1, NULL, 0); 250 plat_dev = platform_device_register_data(dev, pdata->platform, -1,
251 NULL, 0);
280 if (IS_ERR(plat_dev)) { 252 if (IS_ERR(plat_dev)) {
281 dev_err(dev, "Failed to create machine device: %s\n", mach->pdata->platform); 253 dev_err(dev, "Failed to create machine device: %s\n",
254 pdata->platform);
282 return PTR_ERR(plat_dev); 255 return PTR_ERR(plat_dev);
283 } 256 }
284 257
285 /* Create platform device for sst machine driver */ 258 /*
286 mdev = platform_device_register_data(dev, mach->machine, -1, NULL, 0); 259 * Create platform device for sst machine driver,
260 * pass machine info as pdata
261 */
262 mdev = platform_device_register_data(dev, mach->drv_name, -1,
263 (const void *)mach, sizeof(*mach));
287 if (IS_ERR(mdev)) { 264 if (IS_ERR(mdev)) {
288 dev_err(dev, "Failed to create machine device: %s\n", mach->machine); 265 dev_err(dev, "Failed to create machine device: %s\n",
266 mach->drv_name);
289 return PTR_ERR(mdev); 267 return PTR_ERR(mdev);
290 } 268 }
291 269
@@ -294,8 +272,8 @@ static int sst_acpi_probe(struct platform_device *pdev)
294 return ret; 272 return ret;
295 273
296 /* Fill sst platform data */ 274 /* Fill sst platform data */
297 ctx->pdata = mach->pdata; 275 ctx->pdata = pdata;
298 strcpy(ctx->firmware_name, mach->firmware); 276 strcpy(ctx->firmware_name, mach->fw_filename);
299 277
300 ret = sst_platform_get_resources(ctx); 278 ret = sst_platform_get_resources(ctx);
301 if (ret) 279 if (ret)
@@ -342,22 +320,28 @@ static int sst_acpi_remove(struct platform_device *pdev)
342 return 0; 320 return 0;
343} 321}
344 322
345static struct sst_machines sst_acpi_bytcr[] = { 323static struct sst_acpi_mach sst_acpi_bytcr[] = {
346 {"10EC5640", "T100", "bytt100_rt5640", NULL, "intel/fw_sst_0f28.bin", 324 {"10EC5640", "bytcr_rt5640", "intel/fw_sst_0f28.bin", "bytcr_rt5640", NULL,
325 &byt_rvp_platform_data },
326 {"10EC5642", "bytcr_rt5640", "intel/fw_sst_0f28.bin", "bytcr_rt5640", NULL,
327 &byt_rvp_platform_data },
328 {"INTCCFFD", "bytcr_rt5640", "intel/fw_sst_0f28.bin", "bytcr_rt5640", NULL,
329 &byt_rvp_platform_data },
330 {"10EC5651", "bytcr_rt5651", "intel/fw_sst_0f28.bin", "bytcr_rt5651", NULL,
347 &byt_rvp_platform_data }, 331 &byt_rvp_platform_data },
348 {}, 332 {},
349}; 333};
350 334
351/* Cherryview-based platforms: CherryTrail and Braswell */ 335/* Cherryview-based platforms: CherryTrail and Braswell */
352static struct sst_machines sst_acpi_chv[] = { 336static struct sst_acpi_mach sst_acpi_chv[] = {
353 {"10EC5670", "cht-bsw", "cht-bsw-rt5672", NULL, "intel/fw_sst_22a8.bin", 337 {"10EC5670", "cht-bsw-rt5672", "intel/fw_sst_22a8.bin", "cht-bsw", NULL,
338 &chv_platform_data },
339 {"10EC5645", "cht-bsw-rt5645", "intel/fw_sst_22a8.bin", "cht-bsw", NULL,
354 &chv_platform_data }, 340 &chv_platform_data },
355 {"10EC5645", "cht-bsw", "cht-bsw-rt5645", NULL, "intel/fw_sst_22a8.bin", 341 {"10EC5650", "cht-bsw-rt5645", "intel/fw_sst_22a8.bin", "cht-bsw", NULL,
356 &chv_platform_data }, 342 &chv_platform_data },
357 {"10EC5650", "cht-bsw", "cht-bsw-rt5645", NULL, "intel/fw_sst_22a8.bin", 343 {"193C9890", "cht-bsw-max98090", "intel/fw_sst_22a8.bin", "cht-bsw", NULL,
358 &chv_platform_data }, 344 &chv_platform_data },
359 {"193C9890", "cht-bsw", "cht-bsw-max98090", NULL,
360 "intel/fw_sst_22a8.bin", &chv_platform_data },
361 {}, 345 {},
362}; 346};
363 347
diff --git a/sound/soc/intel/atom/sst/sst_stream.c b/sound/soc/intel/atom/sst/sst_stream.c
index a74c64c7053c..4ccc80e5e8cc 100644
--- a/sound/soc/intel/atom/sst/sst_stream.c
+++ b/sound/soc/intel/atom/sst/sst_stream.c
@@ -108,7 +108,7 @@ int sst_alloc_stream_mrfld(struct intel_sst_drv *sst_drv_ctx, void *params)
108 str_id, pipe_id); 108 str_id, pipe_id);
109 ret = sst_prepare_and_post_msg(sst_drv_ctx, task_id, IPC_CMD, 109 ret = sst_prepare_and_post_msg(sst_drv_ctx, task_id, IPC_CMD,
110 IPC_IA_ALLOC_STREAM_MRFLD, pipe_id, sizeof(alloc_param), 110 IPC_IA_ALLOC_STREAM_MRFLD, pipe_id, sizeof(alloc_param),
111 &alloc_param, data, true, true, false, true); 111 &alloc_param, &data, true, true, false, true);
112 112
113 if (ret < 0) { 113 if (ret < 0) {
114 dev_err(sst_drv_ctx->dev, "FW alloc failed ret %d\n", ret); 114 dev_err(sst_drv_ctx->dev, "FW alloc failed ret %d\n", ret);
diff --git a/sound/soc/intel/baytrail/sst-baytrail-pcm.c b/sound/soc/intel/baytrail/sst-baytrail-pcm.c
index 79547bec558b..4765ad474544 100644
--- a/sound/soc/intel/baytrail/sst-baytrail-pcm.c
+++ b/sound/soc/intel/baytrail/sst-baytrail-pcm.c
@@ -377,6 +377,8 @@ static int sst_byt_pcm_probe(struct snd_soc_platform *platform)
377 377
378 priv_data = devm_kzalloc(platform->dev, sizeof(*priv_data), 378 priv_data = devm_kzalloc(platform->dev, sizeof(*priv_data),
379 GFP_KERNEL); 379 GFP_KERNEL);
380 if (!priv_data)
381 return -ENOMEM;
380 priv_data->byt = plat_data->dsp; 382 priv_data->byt = plat_data->dsp;
381 snd_soc_platform_set_drvdata(platform, priv_data); 383 snd_soc_platform_set_drvdata(platform, priv_data);
382 384
diff --git a/sound/soc/intel/boards/Makefile b/sound/soc/intel/boards/Makefile
index 371c4565cad8..3310c0f9c356 100644
--- a/sound/soc/intel/boards/Makefile
+++ b/sound/soc/intel/boards/Makefile
@@ -3,17 +3,23 @@ snd-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-broadwell-objs := broadwell.o 4snd-soc-sst-broadwell-objs := broadwell.o
5snd-soc-sst-bytcr-rt5640-objs := bytcr_rt5640.o 5snd-soc-sst-bytcr-rt5640-objs := bytcr_rt5640.o
6snd-soc-sst-bytcr-rt5651-objs := bytcr_rt5651.o
6snd-soc-sst-cht-bsw-rt5672-objs := cht_bsw_rt5672.o 7snd-soc-sst-cht-bsw-rt5672-objs := cht_bsw_rt5672.o
7snd-soc-sst-cht-bsw-rt5645-objs := cht_bsw_rt5645.o 8snd-soc-sst-cht-bsw-rt5645-objs := cht_bsw_rt5645.o
8snd-soc-sst-cht-bsw-max98090_ti-objs := cht_bsw_max98090_ti.o 9snd-soc-sst-cht-bsw-max98090_ti-objs := cht_bsw_max98090_ti.o
9snd-soc-skl_rt286-objs := skl_rt286.o 10snd-soc-skl_rt286-objs := skl_rt286.o
11snd-skl_nau88l25_max98357a-objs := skl_nau88l25_max98357a.o
12snd-soc-skl_nau88l25_ssm4567-objs := skl_nau88l25_ssm4567.o
10 13
11obj-$(CONFIG_SND_SOC_INTEL_HASWELL_MACH) += snd-soc-sst-haswell.o 14obj-$(CONFIG_SND_SOC_INTEL_HASWELL_MACH) += snd-soc-sst-haswell.o
12obj-$(CONFIG_SND_SOC_INTEL_BYT_RT5640_MACH) += snd-soc-sst-byt-rt5640-mach.o 15obj-$(CONFIG_SND_SOC_INTEL_BYT_RT5640_MACH) += snd-soc-sst-byt-rt5640-mach.o
13obj-$(CONFIG_SND_SOC_INTEL_BYT_MAX98090_MACH) += snd-soc-sst-byt-max98090-mach.o 16obj-$(CONFIG_SND_SOC_INTEL_BYT_MAX98090_MACH) += snd-soc-sst-byt-max98090-mach.o
14obj-$(CONFIG_SND_SOC_INTEL_BROADWELL_MACH) += snd-soc-sst-broadwell.o 17obj-$(CONFIG_SND_SOC_INTEL_BROADWELL_MACH) += snd-soc-sst-broadwell.o
15obj-$(CONFIG_SND_SOC_INTEL_BYTCR_RT5640_MACH) += snd-soc-sst-bytcr-rt5640.o 18obj-$(CONFIG_SND_SOC_INTEL_BYTCR_RT5640_MACH) += snd-soc-sst-bytcr-rt5640.o
19obj-$(CONFIG_SND_SOC_INTEL_BYTCR_RT5651_MACH) += snd-soc-sst-bytcr-rt5651.o
16obj-$(CONFIG_SND_SOC_INTEL_CHT_BSW_RT5672_MACH) += snd-soc-sst-cht-bsw-rt5672.o 20obj-$(CONFIG_SND_SOC_INTEL_CHT_BSW_RT5672_MACH) += snd-soc-sst-cht-bsw-rt5672.o
17obj-$(CONFIG_SND_SOC_INTEL_CHT_BSW_RT5645_MACH) += snd-soc-sst-cht-bsw-rt5645.o 21obj-$(CONFIG_SND_SOC_INTEL_CHT_BSW_RT5645_MACH) += snd-soc-sst-cht-bsw-rt5645.o
18obj-$(CONFIG_SND_SOC_INTEL_CHT_BSW_MAX98090_TI_MACH) += snd-soc-sst-cht-bsw-max98090_ti.o 22obj-$(CONFIG_SND_SOC_INTEL_CHT_BSW_MAX98090_TI_MACH) += snd-soc-sst-cht-bsw-max98090_ti.o
19obj-$(CONFIG_SND_SOC_INTEL_SKL_RT286_MACH) += snd-soc-skl_rt286.o 23obj-$(CONFIG_SND_SOC_INTEL_SKL_RT286_MACH) += snd-soc-skl_rt286.o
24obj-$(CONFIG_SND_SOC_INTEL_SKL_NAU88L25_MAX98357A_MACH) += snd-skl_nau88l25_max98357a.o
25obj-$(CONFIG_SND_SOC_INTEL_SKL_NAU88L25_SSM4567_MACH) += snd-soc-skl_nau88l25_ssm4567.o
diff --git a/sound/soc/intel/boards/bytcr_rt5640.c b/sound/soc/intel/boards/bytcr_rt5640.c
index 7a5c9a36c1db..9a1752df45a9 100644
--- a/sound/soc/intel/boards/bytcr_rt5640.c
+++ b/sound/soc/intel/boards/bytcr_rt5640.c
@@ -20,51 +20,76 @@
20#include <linux/init.h> 20#include <linux/init.h>
21#include <linux/module.h> 21#include <linux/module.h>
22#include <linux/platform_device.h> 22#include <linux/platform_device.h>
23#include <linux/acpi.h>
23#include <linux/device.h> 24#include <linux/device.h>
25#include <linux/dmi.h>
24#include <linux/slab.h> 26#include <linux/slab.h>
25#include <linux/input.h>
26#include <sound/pcm.h> 27#include <sound/pcm.h>
27#include <sound/pcm_params.h> 28#include <sound/pcm_params.h>
28#include <sound/soc.h> 29#include <sound/soc.h>
30#include <sound/jack.h>
29#include "../../codecs/rt5640.h" 31#include "../../codecs/rt5640.h"
30#include "../atom/sst-atom-controls.h" 32#include "../atom/sst-atom-controls.h"
33#include "../common/sst-acpi.h"
31 34
32static const struct snd_soc_dapm_widget byt_dapm_widgets[] = { 35static const struct snd_soc_dapm_widget byt_rt5640_widgets[] = {
33 SND_SOC_DAPM_HP("Headphone", NULL), 36 SND_SOC_DAPM_HP("Headphone", NULL),
34 SND_SOC_DAPM_MIC("Headset Mic", NULL), 37 SND_SOC_DAPM_MIC("Headset Mic", NULL),
35 SND_SOC_DAPM_MIC("Int Mic", NULL), 38 SND_SOC_DAPM_MIC("Internal Mic", NULL),
36 SND_SOC_DAPM_SPK("Ext Spk", NULL), 39 SND_SOC_DAPM_SPK("Speaker", NULL),
37}; 40};
38 41
39static const struct snd_soc_dapm_route byt_audio_map[] = { 42static const struct snd_soc_dapm_route byt_rt5640_audio_map[] = {
40 {"IN2P", NULL, "Headset Mic"},
41 {"IN2N", NULL, "Headset Mic"},
42 {"Headset Mic", NULL, "MICBIAS1"},
43 {"IN1P", NULL, "MICBIAS1"},
44 {"LDO2", NULL, "Int Mic"},
45 {"Headphone", NULL, "HPOL"},
46 {"Headphone", NULL, "HPOR"},
47 {"Ext Spk", NULL, "SPOLP"},
48 {"Ext Spk", NULL, "SPOLN"},
49 {"Ext Spk", NULL, "SPORP"},
50 {"Ext Spk", NULL, "SPORN"},
51
52 {"AIF1 Playback", NULL, "ssp2 Tx"}, 43 {"AIF1 Playback", NULL, "ssp2 Tx"},
53 {"ssp2 Tx", NULL, "codec_out0"}, 44 {"ssp2 Tx", NULL, "codec_out0"},
54 {"ssp2 Tx", NULL, "codec_out1"}, 45 {"ssp2 Tx", NULL, "codec_out1"},
55 {"codec_in0", NULL, "ssp2 Rx"}, 46 {"codec_in0", NULL, "ssp2 Rx"},
56 {"codec_in1", NULL, "ssp2 Rx"}, 47 {"codec_in1", NULL, "ssp2 Rx"},
57 {"ssp2 Rx", NULL, "AIF1 Capture"}, 48 {"ssp2 Rx", NULL, "AIF1 Capture"},
49
50 {"Headset Mic", NULL, "MICBIAS1"},
51 {"IN2P", NULL, "Headset Mic"},
52 {"Headphone", NULL, "HPOL"},
53 {"Headphone", NULL, "HPOR"},
54 {"Speaker", NULL, "SPOLP"},
55 {"Speaker", NULL, "SPOLN"},
56 {"Speaker", NULL, "SPORP"},
57 {"Speaker", NULL, "SPORN"},
58};
59
60static const struct snd_soc_dapm_route byt_rt5640_intmic_dmic1_map[] = {
61 {"DMIC1", NULL, "Internal Mic"},
62};
63
64static const struct snd_soc_dapm_route byt_rt5640_intmic_dmic2_map[] = {
65 {"DMIC2", NULL, "Internal Mic"},
66};
67
68static const struct snd_soc_dapm_route byt_rt5640_intmic_in1_map[] = {
69 {"Internal Mic", NULL, "MICBIAS1"},
70 {"IN1P", NULL, "Internal Mic"},
71};
72
73enum {
74 BYT_RT5640_DMIC1_MAP,
75 BYT_RT5640_DMIC2_MAP,
76 BYT_RT5640_IN1_MAP,
58}; 77};
59 78
60static const struct snd_kcontrol_new byt_mc_controls[] = { 79#define BYT_RT5640_MAP(quirk) ((quirk) & 0xff)
80#define BYT_RT5640_DMIC_EN BIT(16)
81
82static unsigned long byt_rt5640_quirk = BYT_RT5640_DMIC1_MAP |
83 BYT_RT5640_DMIC_EN;
84
85static const struct snd_kcontrol_new byt_rt5640_controls[] = {
61 SOC_DAPM_PIN_SWITCH("Headphone"), 86 SOC_DAPM_PIN_SWITCH("Headphone"),
62 SOC_DAPM_PIN_SWITCH("Headset Mic"), 87 SOC_DAPM_PIN_SWITCH("Headset Mic"),
63 SOC_DAPM_PIN_SWITCH("Int Mic"), 88 SOC_DAPM_PIN_SWITCH("Internal Mic"),
64 SOC_DAPM_PIN_SWITCH("Ext Spk"), 89 SOC_DAPM_PIN_SWITCH("Speaker"),
65}; 90};
66 91
67static int byt_aif1_hw_params(struct snd_pcm_substream *substream, 92static int byt_rt5640_aif1_hw_params(struct snd_pcm_substream *substream,
68 struct snd_pcm_hw_params *params) 93 struct snd_pcm_hw_params *params)
69{ 94{
70 struct snd_soc_pcm_runtime *rtd = substream->private_data; 95 struct snd_soc_pcm_runtime *rtd = substream->private_data;
@@ -92,7 +117,95 @@ static int byt_aif1_hw_params(struct snd_pcm_substream *substream,
92 return 0; 117 return 0;
93} 118}
94 119
95static const struct snd_soc_pcm_stream byt_dai_params = { 120static int byt_rt5640_quirk_cb(const struct dmi_system_id *id)
121{
122 byt_rt5640_quirk = (unsigned long)id->driver_data;
123 return 1;
124}
125
126static const struct dmi_system_id byt_rt5640_quirk_table[] = {
127 {
128 .callback = byt_rt5640_quirk_cb,
129 .matches = {
130 DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
131 DMI_MATCH(DMI_PRODUCT_NAME, "T100TA"),
132 },
133 .driver_data = (unsigned long *)BYT_RT5640_IN1_MAP,
134 },
135 {
136 .callback = byt_rt5640_quirk_cb,
137 .matches = {
138 DMI_MATCH(DMI_SYS_VENDOR, "DellInc."),
139 DMI_MATCH(DMI_PRODUCT_NAME, "Venue 8 Pro 5830"),
140 },
141 .driver_data = (unsigned long *)(BYT_RT5640_DMIC2_MAP |
142 BYT_RT5640_DMIC_EN),
143 },
144 {
145 .callback = byt_rt5640_quirk_cb,
146 .matches = {
147 DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
148 DMI_MATCH(DMI_PRODUCT_NAME, "HP ElitePad 1000 G2"),
149 },
150 .driver_data = (unsigned long *)BYT_RT5640_IN1_MAP,
151 },
152 {}
153};
154
155static int byt_rt5640_init(struct snd_soc_pcm_runtime *runtime)
156{
157 int ret;
158 struct snd_soc_codec *codec = runtime->codec;
159 struct snd_soc_card *card = runtime->card;
160 const struct snd_soc_dapm_route *custom_map;
161 int num_routes;
162
163 card->dapm.idle_bias_off = true;
164
165 rt5640_sel_asrc_clk_src(codec,
166 RT5640_DA_STEREO_FILTER |
167 RT5640_AD_STEREO_FILTER,
168 RT5640_CLK_SEL_ASRC);
169
170 ret = snd_soc_add_card_controls(card, byt_rt5640_controls,
171 ARRAY_SIZE(byt_rt5640_controls));
172 if (ret) {
173 dev_err(card->dev, "unable to add card controls\n");
174 return ret;
175 }
176
177 dmi_check_system(byt_rt5640_quirk_table);
178 switch (BYT_RT5640_MAP(byt_rt5640_quirk)) {
179 case BYT_RT5640_IN1_MAP:
180 custom_map = byt_rt5640_intmic_in1_map;
181 num_routes = ARRAY_SIZE(byt_rt5640_intmic_in1_map);
182 break;
183 case BYT_RT5640_DMIC2_MAP:
184 custom_map = byt_rt5640_intmic_dmic2_map;
185 num_routes = ARRAY_SIZE(byt_rt5640_intmic_dmic2_map);
186 break;
187 default:
188 custom_map = byt_rt5640_intmic_dmic1_map;
189 num_routes = ARRAY_SIZE(byt_rt5640_intmic_dmic1_map);
190 }
191
192 ret = snd_soc_dapm_add_routes(&card->dapm, custom_map, num_routes);
193 if (ret)
194 return ret;
195
196 if (byt_rt5640_quirk & BYT_RT5640_DMIC_EN) {
197 ret = rt5640_dmic_enable(codec, 0, 0);
198 if (ret)
199 return ret;
200 }
201
202 snd_soc_dapm_ignore_suspend(&card->dapm, "Headphone");
203 snd_soc_dapm_ignore_suspend(&card->dapm, "Speaker");
204
205 return ret;
206}
207
208static const struct snd_soc_pcm_stream byt_rt5640_dai_params = {
96 .formats = SNDRV_PCM_FMTBIT_S24_LE, 209 .formats = SNDRV_PCM_FMTBIT_S24_LE,
97 .rate_min = 48000, 210 .rate_min = 48000,
98 .rate_max = 48000, 211 .rate_max = 48000,
@@ -100,13 +213,14 @@ static const struct snd_soc_pcm_stream byt_dai_params = {
100 .channels_max = 2, 213 .channels_max = 2,
101}; 214};
102 215
103static int byt_codec_fixup(struct snd_soc_pcm_runtime *rtd, 216static int byt_rt5640_codec_fixup(struct snd_soc_pcm_runtime *rtd,
104 struct snd_pcm_hw_params *params) 217 struct snd_pcm_hw_params *params)
105{ 218{
106 struct snd_interval *rate = hw_param_interval(params, 219 struct snd_interval *rate = hw_param_interval(params,
107 SNDRV_PCM_HW_PARAM_RATE); 220 SNDRV_PCM_HW_PARAM_RATE);
108 struct snd_interval *channels = hw_param_interval(params, 221 struct snd_interval *channels = hw_param_interval(params,
109 SNDRV_PCM_HW_PARAM_CHANNELS); 222 SNDRV_PCM_HW_PARAM_CHANNELS);
223 int ret;
110 224
111 /* The DSP will covert the FE rate to 48k, stereo, 24bits */ 225 /* The DSP will covert the FE rate to 48k, stereo, 24bits */
112 rate->min = rate->max = 48000; 226 rate->min = rate->max = 48000;
@@ -114,24 +228,46 @@ static int byt_codec_fixup(struct snd_soc_pcm_runtime *rtd,
114 228
115 /* set SSP2 to 24-bit */ 229 /* set SSP2 to 24-bit */
116 params_set_format(params, SNDRV_PCM_FORMAT_S24_LE); 230 params_set_format(params, SNDRV_PCM_FORMAT_S24_LE);
231
232 /*
233 * Default mode for SSP configuration is TDM 4 slot, override config
234 * with explicit setting to I2S 2ch 24-bit. The word length is set with
235 * dai_set_tdm_slot() since there is no other API exposed
236 */
237 ret = snd_soc_dai_set_fmt(rtd->cpu_dai,
238 SND_SOC_DAIFMT_I2S |
239 SND_SOC_DAIFMT_NB_IF |
240 SND_SOC_DAIFMT_CBS_CFS
241 );
242 if (ret < 0) {
243 dev_err(rtd->dev, "can't set format to I2S, err %d\n", ret);
244 return ret;
245 }
246
247 ret = snd_soc_dai_set_tdm_slot(rtd->cpu_dai, 0x3, 0x3, 2, 24);
248 if (ret < 0) {
249 dev_err(rtd->dev, "can't set I2S config, err %d\n", ret);
250 return ret;
251 }
252
117 return 0; 253 return 0;
118} 254}
119 255
120static int byt_aif1_startup(struct snd_pcm_substream *substream) 256static int byt_rt5640_aif1_startup(struct snd_pcm_substream *substream)
121{ 257{
122 return snd_pcm_hw_constraint_single(substream->runtime, 258 return snd_pcm_hw_constraint_single(substream->runtime,
123 SNDRV_PCM_HW_PARAM_RATE, 48000); 259 SNDRV_PCM_HW_PARAM_RATE, 48000);
124} 260}
125 261
126static struct snd_soc_ops byt_aif1_ops = { 262static struct snd_soc_ops byt_rt5640_aif1_ops = {
127 .startup = byt_aif1_startup, 263 .startup = byt_rt5640_aif1_startup,
128}; 264};
129 265
130static struct snd_soc_ops byt_be_ssp2_ops = { 266static struct snd_soc_ops byt_rt5640_be_ssp2_ops = {
131 .hw_params = byt_aif1_hw_params, 267 .hw_params = byt_rt5640_aif1_hw_params,
132}; 268};
133 269
134static struct snd_soc_dai_link byt_dailink[] = { 270static struct snd_soc_dai_link byt_rt5640_dais[] = {
135 [MERR_DPCM_AUDIO] = { 271 [MERR_DPCM_AUDIO] = {
136 .name = "Baytrail Audio Port", 272 .name = "Baytrail Audio Port",
137 .stream_name = "Baytrail Audio", 273 .stream_name = "Baytrail Audio",
@@ -143,7 +279,20 @@ static struct snd_soc_dai_link byt_dailink[] = {
143 .dynamic = 1, 279 .dynamic = 1,
144 .dpcm_playback = 1, 280 .dpcm_playback = 1,
145 .dpcm_capture = 1, 281 .dpcm_capture = 1,
146 .ops = &byt_aif1_ops, 282 .ops = &byt_rt5640_aif1_ops,
283 },
284 [MERR_DPCM_DEEP_BUFFER] = {
285 .name = "Deep-Buffer Audio Port",
286 .stream_name = "Deep-Buffer Audio",
287 .cpu_dai_name = "deepbuffer-cpu-dai",
288 .codec_dai_name = "snd-soc-dummy-dai",
289 .codec_name = "snd-soc-dummy",
290 .platform_name = "sst-mfld-platform",
291 .ignore_suspend = 1,
292 .nonatomic = true,
293 .dynamic = 1,
294 .dpcm_playback = 1,
295 .ops = &byt_rt5640_aif1_ops,
147 }, 296 },
148 [MERR_DPCM_COMPR] = { 297 [MERR_DPCM_COMPR] = {
149 .name = "Baytrail Compressed Port", 298 .name = "Baytrail Compressed Port",
@@ -161,58 +310,69 @@ static struct snd_soc_dai_link byt_dailink[] = {
161 .platform_name = "sst-mfld-platform", 310 .platform_name = "sst-mfld-platform",
162 .no_pcm = 1, 311 .no_pcm = 1,
163 .codec_dai_name = "rt5640-aif1", 312 .codec_dai_name = "rt5640-aif1",
164 .codec_name = "i2c-10EC5640:00", 313 .codec_name = "i2c-10EC5640:00", /* overwritten with HID */
165 .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF 314 .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF
166 | SND_SOC_DAIFMT_CBS_CFS, 315 | SND_SOC_DAIFMT_CBS_CFS,
167 .be_hw_params_fixup = byt_codec_fixup, 316 .be_hw_params_fixup = byt_rt5640_codec_fixup,
168 .ignore_suspend = 1, 317 .ignore_suspend = 1,
169 .dpcm_playback = 1, 318 .dpcm_playback = 1,
170 .dpcm_capture = 1, 319 .dpcm_capture = 1,
171 .ops = &byt_be_ssp2_ops, 320 .init = byt_rt5640_init,
321 .ops = &byt_rt5640_be_ssp2_ops,
172 }, 322 },
173}; 323};
174 324
175/* SoC card */ 325/* SoC card */
176static struct snd_soc_card snd_soc_card_byt = { 326static struct snd_soc_card byt_rt5640_card = {
177 .name = "baytrailcraudio", 327 .name = "bytcr-rt5640",
178 .owner = THIS_MODULE, 328 .owner = THIS_MODULE,
179 .dai_link = byt_dailink, 329 .dai_link = byt_rt5640_dais,
180 .num_links = ARRAY_SIZE(byt_dailink), 330 .num_links = ARRAY_SIZE(byt_rt5640_dais),
181 .dapm_widgets = byt_dapm_widgets, 331 .dapm_widgets = byt_rt5640_widgets,
182 .num_dapm_widgets = ARRAY_SIZE(byt_dapm_widgets), 332 .num_dapm_widgets = ARRAY_SIZE(byt_rt5640_widgets),
183 .dapm_routes = byt_audio_map, 333 .dapm_routes = byt_rt5640_audio_map,
184 .num_dapm_routes = ARRAY_SIZE(byt_audio_map), 334 .num_dapm_routes = ARRAY_SIZE(byt_rt5640_audio_map),
185 .controls = byt_mc_controls, 335 .fully_routed = true,
186 .num_controls = ARRAY_SIZE(byt_mc_controls),
187}; 336};
188 337
189static int snd_byt_mc_probe(struct platform_device *pdev) 338static char byt_rt5640_codec_name[16]; /* i2c-<HID>:00 with HID being 8 chars */
339
340static int snd_byt_rt5640_mc_probe(struct platform_device *pdev)
190{ 341{
191 int ret_val = 0; 342 int ret_val = 0;
343 struct sst_acpi_mach *mach;
192 344
193 /* register the soc card */ 345 /* register the soc card */
194 snd_soc_card_byt.dev = &pdev->dev; 346 byt_rt5640_card.dev = &pdev->dev;
347 mach = byt_rt5640_card.dev->platform_data;
348
349 /* fixup codec name based on HID */
350 snprintf(byt_rt5640_codec_name, sizeof(byt_rt5640_codec_name),
351 "%s%s%s", "i2c-", mach->id, ":00");
352 byt_rt5640_dais[MERR_DPCM_COMPR+1].codec_name = byt_rt5640_codec_name;
353
354 ret_val = devm_snd_soc_register_card(&pdev->dev, &byt_rt5640_card);
195 355
196 ret_val = devm_snd_soc_register_card(&pdev->dev, &snd_soc_card_byt);
197 if (ret_val) { 356 if (ret_val) {
198 dev_err(&pdev->dev, "devm_snd_soc_register_card failed %d\n", ret_val); 357 dev_err(&pdev->dev, "devm_snd_soc_register_card failed %d\n",
358 ret_val);
199 return ret_val; 359 return ret_val;
200 } 360 }
201 platform_set_drvdata(pdev, &snd_soc_card_byt); 361 platform_set_drvdata(pdev, &byt_rt5640_card);
202 return ret_val; 362 return ret_val;
203} 363}
204 364
205static struct platform_driver snd_byt_mc_driver = { 365static struct platform_driver snd_byt_rt5640_mc_driver = {
206 .driver = { 366 .driver = {
207 .name = "bytt100_rt5640", 367 .name = "bytcr_rt5640",
208 .pm = &snd_soc_pm_ops, 368 .pm = &snd_soc_pm_ops,
209 }, 369 },
210 .probe = snd_byt_mc_probe, 370 .probe = snd_byt_rt5640_mc_probe,
211}; 371};
212 372
213module_platform_driver(snd_byt_mc_driver); 373module_platform_driver(snd_byt_rt5640_mc_driver);
214 374
215MODULE_DESCRIPTION("ASoC Intel(R) Baytrail CR Machine driver"); 375MODULE_DESCRIPTION("ASoC Intel(R) Baytrail CR Machine driver");
216MODULE_AUTHOR("Subhransu S. Prusty <subhransu.s.prusty@intel.com>"); 376MODULE_AUTHOR("Subhransu S. Prusty <subhransu.s.prusty@intel.com>");
217MODULE_LICENSE("GPL v2"); 377MODULE_LICENSE("GPL v2");
218MODULE_ALIAS("platform:bytt100_rt5640"); 378MODULE_ALIAS("platform:bytcr_rt5640");
diff --git a/sound/soc/intel/boards/bytcr_rt5651.c b/sound/soc/intel/boards/bytcr_rt5651.c
new file mode 100644
index 000000000000..1c95ccc886c4
--- /dev/null
+++ b/sound/soc/intel/boards/bytcr_rt5651.c
@@ -0,0 +1,332 @@
1/*
2 * bytcr_rt5651.c - ASoc Machine driver for Intel Byt CR platform
3 * (derived from bytcr_rt5640.c)
4 *
5 * Copyright (C) 2015 Intel Corp
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 published by
10 * the Free Software Foundation; version 2 of the License.
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 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
18 */
19
20#include <linux/init.h>
21#include <linux/module.h>
22#include <linux/platform_device.h>
23#include <linux/acpi.h>
24#include <linux/device.h>
25#include <linux/dmi.h>
26#include <linux/slab.h>
27#include <sound/pcm.h>
28#include <sound/pcm_params.h>
29#include <sound/soc.h>
30#include <sound/jack.h>
31#include "../../codecs/rt5651.h"
32#include "../atom/sst-atom-controls.h"
33
34static const struct snd_soc_dapm_widget byt_rt5651_widgets[] = {
35 SND_SOC_DAPM_HP("Headphone", NULL),
36 SND_SOC_DAPM_MIC("Headset Mic", NULL),
37 SND_SOC_DAPM_MIC("Internal Mic", NULL),
38 SND_SOC_DAPM_SPK("Speaker", NULL),
39};
40
41static const struct snd_soc_dapm_route byt_rt5651_audio_map[] = {
42 {"AIF1 Playback", NULL, "ssp2 Tx"},
43 {"ssp2 Tx", NULL, "codec_out0"},
44 {"ssp2 Tx", NULL, "codec_out1"},
45 {"codec_in0", NULL, "ssp2 Rx"},
46 {"codec_in1", NULL, "ssp2 Rx"},
47 {"ssp2 Rx", NULL, "AIF1 Capture"},
48
49 {"Headset Mic", NULL, "micbias1"}, /* lowercase for rt5651 */
50 {"IN2P", NULL, "Headset Mic"},
51 {"Headphone", NULL, "HPOL"},
52 {"Headphone", NULL, "HPOR"},
53 {"Speaker", NULL, "LOUTL"},
54 {"Speaker", NULL, "LOUTR"},
55};
56
57static const struct snd_soc_dapm_route byt_rt5651_intmic_dmic1_map[] = {
58 {"DMIC1", NULL, "Internal Mic"},
59};
60
61static const struct snd_soc_dapm_route byt_rt5651_intmic_dmic2_map[] = {
62 {"DMIC2", NULL, "Internal Mic"},
63};
64
65static const struct snd_soc_dapm_route byt_rt5651_intmic_in1_map[] = {
66 {"Internal Mic", NULL, "micbias1"},
67 {"IN1P", NULL, "Internal Mic"},
68};
69
70enum {
71 BYT_RT5651_DMIC1_MAP,
72 BYT_RT5651_DMIC2_MAP,
73 BYT_RT5651_IN1_MAP,
74};
75
76#define BYT_RT5651_MAP(quirk) ((quirk) & 0xff)
77#define BYT_RT5651_DMIC_EN BIT(16)
78
79static unsigned long byt_rt5651_quirk = BYT_RT5651_DMIC1_MAP |
80 BYT_RT5651_DMIC_EN;
81
82static const struct snd_kcontrol_new byt_rt5651_controls[] = {
83 SOC_DAPM_PIN_SWITCH("Headphone"),
84 SOC_DAPM_PIN_SWITCH("Headset Mic"),
85 SOC_DAPM_PIN_SWITCH("Internal Mic"),
86 SOC_DAPM_PIN_SWITCH("Speaker"),
87};
88
89static int byt_rt5651_aif1_hw_params(struct snd_pcm_substream *substream,
90 struct snd_pcm_hw_params *params)
91{
92 struct snd_soc_pcm_runtime *rtd = substream->private_data;
93 struct snd_soc_dai *codec_dai = rtd->codec_dai;
94 int ret;
95
96 snd_soc_dai_set_bclk_ratio(codec_dai, 50);
97
98 ret = snd_soc_dai_set_sysclk(codec_dai, RT5651_SCLK_S_PLL1,
99 params_rate(params) * 512,
100 SND_SOC_CLOCK_IN);
101 if (ret < 0) {
102 dev_err(rtd->dev, "can't set codec clock %d\n", ret);
103 return ret;
104 }
105
106 ret = snd_soc_dai_set_pll(codec_dai, 0, RT5651_PLL1_S_BCLK1,
107 params_rate(params) * 50,
108 params_rate(params) * 512);
109 if (ret < 0) {
110 dev_err(rtd->dev, "can't set codec pll: %d\n", ret);
111 return ret;
112 }
113
114 return 0;
115}
116
117static const struct dmi_system_id byt_rt5651_quirk_table[] = {
118 {}
119};
120
121static int byt_rt5651_init(struct snd_soc_pcm_runtime *runtime)
122{
123 int ret;
124 struct snd_soc_card *card = runtime->card;
125 const struct snd_soc_dapm_route *custom_map;
126 int num_routes;
127
128 card->dapm.idle_bias_off = true;
129
130 dmi_check_system(byt_rt5651_quirk_table);
131 switch (BYT_RT5651_MAP(byt_rt5651_quirk)) {
132 case BYT_RT5651_IN1_MAP:
133 custom_map = byt_rt5651_intmic_in1_map;
134 num_routes = ARRAY_SIZE(byt_rt5651_intmic_in1_map);
135 break;
136 case BYT_RT5651_DMIC2_MAP:
137 custom_map = byt_rt5651_intmic_dmic2_map;
138 num_routes = ARRAY_SIZE(byt_rt5651_intmic_dmic2_map);
139 break;
140 default:
141 custom_map = byt_rt5651_intmic_dmic1_map;
142 num_routes = ARRAY_SIZE(byt_rt5651_intmic_dmic1_map);
143 }
144
145 ret = snd_soc_add_card_controls(card, byt_rt5651_controls,
146 ARRAY_SIZE(byt_rt5651_controls));
147 if (ret) {
148 dev_err(card->dev, "unable to add card controls\n");
149 return ret;
150 }
151 snd_soc_dapm_ignore_suspend(&card->dapm, "Headphone");
152 snd_soc_dapm_ignore_suspend(&card->dapm, "Speaker");
153
154 return ret;
155}
156
157static const struct snd_soc_pcm_stream byt_rt5651_dai_params = {
158 .formats = SNDRV_PCM_FMTBIT_S24_LE,
159 .rate_min = 48000,
160 .rate_max = 48000,
161 .channels_min = 2,
162 .channels_max = 2,
163};
164
165static int byt_rt5651_codec_fixup(struct snd_soc_pcm_runtime *rtd,
166 struct snd_pcm_hw_params *params)
167{
168 struct snd_interval *rate = hw_param_interval(params,
169 SNDRV_PCM_HW_PARAM_RATE);
170 struct snd_interval *channels = hw_param_interval(params,
171 SNDRV_PCM_HW_PARAM_CHANNELS);
172 int ret;
173
174 /* The DSP will covert the FE rate to 48k, stereo, 24bits */
175 rate->min = rate->max = 48000;
176 channels->min = channels->max = 2;
177
178 /* set SSP2 to 24-bit */
179 params_set_format(params, SNDRV_PCM_FORMAT_S24_LE);
180
181 /*
182 * Default mode for SSP configuration is TDM 4 slot, override config
183 * with explicit setting to I2S 2ch 24-bit. The word length is set with
184 * dai_set_tdm_slot() since there is no other API exposed
185 */
186 ret = snd_soc_dai_set_fmt(rtd->cpu_dai,
187 SND_SOC_DAIFMT_I2S |
188 SND_SOC_DAIFMT_NB_IF |
189 SND_SOC_DAIFMT_CBS_CFS
190 );
191
192 if (ret < 0) {
193 dev_err(rtd->dev, "can't set format to I2S, err %d\n", ret);
194 return ret;
195 }
196
197 ret = snd_soc_dai_set_tdm_slot(rtd->cpu_dai, 0x3, 0x3, 2, 24);
198 if (ret < 0) {
199 dev_err(rtd->dev, "can't set I2S config, err %d\n", ret);
200 return ret;
201 }
202
203 return 0;
204}
205
206static unsigned int rates_48000[] = {
207 48000,
208};
209
210static struct snd_pcm_hw_constraint_list constraints_48000 = {
211 .count = ARRAY_SIZE(rates_48000),
212 .list = rates_48000,
213};
214
215static int byt_rt5651_aif1_startup(struct snd_pcm_substream *substream)
216{
217 return snd_pcm_hw_constraint_list(substream->runtime, 0,
218 SNDRV_PCM_HW_PARAM_RATE,
219 &constraints_48000);
220}
221
222static struct snd_soc_ops byt_rt5651_aif1_ops = {
223 .startup = byt_rt5651_aif1_startup,
224};
225
226static struct snd_soc_ops byt_rt5651_be_ssp2_ops = {
227 .hw_params = byt_rt5651_aif1_hw_params,
228};
229
230static struct snd_soc_dai_link byt_rt5651_dais[] = {
231 [MERR_DPCM_AUDIO] = {
232 .name = "Audio Port",
233 .stream_name = "Audio",
234 .cpu_dai_name = "media-cpu-dai",
235 .codec_dai_name = "snd-soc-dummy-dai",
236 .codec_name = "snd-soc-dummy",
237 .platform_name = "sst-mfld-platform",
238 .ignore_suspend = 1,
239 .nonatomic = true,
240 .dynamic = 1,
241 .dpcm_playback = 1,
242 .dpcm_capture = 1,
243 .ops = &byt_rt5651_aif1_ops,
244 },
245 [MERR_DPCM_DEEP_BUFFER] = {
246 .name = "Deep-Buffer Audio Port",
247 .stream_name = "Deep-Buffer Audio",
248 .cpu_dai_name = "deepbuffer-cpu-dai",
249 .codec_dai_name = "snd-soc-dummy-dai",
250 .codec_name = "snd-soc-dummy",
251 .platform_name = "sst-mfld-platform",
252 .ignore_suspend = 1,
253 .nonatomic = true,
254 .dynamic = 1,
255 .dpcm_playback = 1,
256 .ops = &byt_rt5651_aif1_ops,
257 },
258 [MERR_DPCM_COMPR] = {
259 .name = "Compressed Port",
260 .stream_name = "Compress",
261 .cpu_dai_name = "compress-cpu-dai",
262 .codec_dai_name = "snd-soc-dummy-dai",
263 .codec_name = "snd-soc-dummy",
264 .platform_name = "sst-mfld-platform",
265 },
266 /* CODEC<->CODEC link */
267 /* back ends */
268 {
269 .name = "SSP2-Codec",
270 .be_id = 1,
271 .cpu_dai_name = "ssp2-port",
272 .platform_name = "sst-mfld-platform",
273 .no_pcm = 1,
274 .codec_dai_name = "rt5651-aif1",
275 .codec_name = "i2c-10EC5651:00",
276 .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF
277 | SND_SOC_DAIFMT_CBS_CFS,
278 .be_hw_params_fixup = byt_rt5651_codec_fixup,
279 .ignore_suspend = 1,
280 .nonatomic = true,
281 .dpcm_playback = 1,
282 .dpcm_capture = 1,
283 .init = byt_rt5651_init,
284 .ops = &byt_rt5651_be_ssp2_ops,
285 },
286};
287
288/* SoC card */
289static struct snd_soc_card byt_rt5651_card = {
290 .name = "bytcr-rt5651",
291 .owner = THIS_MODULE,
292 .dai_link = byt_rt5651_dais,
293 .num_links = ARRAY_SIZE(byt_rt5651_dais),
294 .dapm_widgets = byt_rt5651_widgets,
295 .num_dapm_widgets = ARRAY_SIZE(byt_rt5651_widgets),
296 .dapm_routes = byt_rt5651_audio_map,
297 .num_dapm_routes = ARRAY_SIZE(byt_rt5651_audio_map),
298 .fully_routed = true,
299};
300
301static int snd_byt_rt5651_mc_probe(struct platform_device *pdev)
302{
303 int ret_val = 0;
304
305 /* register the soc card */
306 byt_rt5651_card.dev = &pdev->dev;
307
308 ret_val = devm_snd_soc_register_card(&pdev->dev, &byt_rt5651_card);
309
310 if (ret_val) {
311 dev_err(&pdev->dev, "devm_snd_soc_register_card failed %d\n",
312 ret_val);
313 return ret_val;
314 }
315 platform_set_drvdata(pdev, &byt_rt5651_card);
316 return ret_val;
317}
318
319static struct platform_driver snd_byt_rt5651_mc_driver = {
320 .driver = {
321 .name = "bytcr_rt5651",
322 .pm = &snd_soc_pm_ops,
323 },
324 .probe = snd_byt_rt5651_mc_probe,
325};
326
327module_platform_driver(snd_byt_rt5651_mc_driver);
328
329MODULE_DESCRIPTION("ASoC Intel(R) Baytrail CR Machine driver for RT5651");
330MODULE_AUTHOR("Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>");
331MODULE_LICENSE("GPL v2");
332MODULE_ALIAS("platform:bytcr_rt5651");
diff --git a/sound/soc/intel/boards/cht_bsw_max98090_ti.c b/sound/soc/intel/boards/cht_bsw_max98090_ti.c
index 4e2fcf188dd1..90588d6e64fc 100644
--- a/sound/soc/intel/boards/cht_bsw_max98090_ti.c
+++ b/sound/soc/intel/boards/cht_bsw_max98090_ti.c
@@ -41,12 +41,9 @@ struct cht_mc_private {
41 41
42static inline struct snd_soc_dai *cht_get_codec_dai(struct snd_soc_card *card) 42static inline struct snd_soc_dai *cht_get_codec_dai(struct snd_soc_card *card)
43{ 43{
44 int i; 44 struct snd_soc_pcm_runtime *rtd;
45 45
46 for (i = 0; i < card->num_rtd; i++) { 46 list_for_each_entry(rtd, &card->rtd_list, list) {
47 struct snd_soc_pcm_runtime *rtd;
48
49 rtd = card->rtd + i;
50 if (!strncmp(rtd->codec_dai->name, CHT_CODEC_DAI, 47 if (!strncmp(rtd->codec_dai->name, CHT_CODEC_DAI,
51 strlen(CHT_CODEC_DAI))) 48 strlen(CHT_CODEC_DAI)))
52 return rtd->codec_dai; 49 return rtd->codec_dai;
@@ -235,6 +232,18 @@ static struct snd_soc_dai_link cht_dailink[] = {
235 .dpcm_capture = 1, 232 .dpcm_capture = 1,
236 .ops = &cht_aif1_ops, 233 .ops = &cht_aif1_ops,
237 }, 234 },
235 [MERR_DPCM_DEEP_BUFFER] = {
236 .name = "Deep-Buffer Audio Port",
237 .stream_name = "Deep-Buffer Audio",
238 .cpu_dai_name = "deepbuffer-cpu-dai",
239 .codec_dai_name = "snd-soc-dummy-dai",
240 .codec_name = "snd-soc-dummy",
241 .platform_name = "sst-mfld-platform",
242 .nonatomic = true,
243 .dynamic = 1,
244 .dpcm_playback = 1,
245 .ops = &cht_aif1_ops,
246 },
238 [MERR_DPCM_COMPR] = { 247 [MERR_DPCM_COMPR] = {
239 .name = "Compressed Port", 248 .name = "Compressed Port",
240 .stream_name = "Compress", 249 .stream_name = "Compress",
diff --git a/sound/soc/intel/boards/cht_bsw_rt5645.c b/sound/soc/intel/boards/cht_bsw_rt5645.c
index 38d65a3529c4..2d3afddb0a2e 100644
--- a/sound/soc/intel/boards/cht_bsw_rt5645.c
+++ b/sound/soc/intel/boards/cht_bsw_rt5645.c
@@ -47,12 +47,9 @@ struct cht_mc_private {
47 47
48static inline struct snd_soc_dai *cht_get_codec_dai(struct snd_soc_card *card) 48static inline struct snd_soc_dai *cht_get_codec_dai(struct snd_soc_card *card)
49{ 49{
50 int i; 50 struct snd_soc_pcm_runtime *rtd;
51
52 for (i = 0; i < card->num_rtd; i++) {
53 struct snd_soc_pcm_runtime *rtd;
54 51
55 rtd = card->rtd + i; 52 list_for_each_entry(rtd, &card->rtd_list, list) {
56 if (!strncmp(rtd->codec_dai->name, CHT_CODEC_DAI, 53 if (!strncmp(rtd->codec_dai->name, CHT_CODEC_DAI,
57 strlen(CHT_CODEC_DAI))) 54 strlen(CHT_CODEC_DAI)))
58 return rtd->codec_dai; 55 return rtd->codec_dai;
@@ -263,6 +260,18 @@ static struct snd_soc_dai_link cht_dailink[] = {
263 .dpcm_capture = 1, 260 .dpcm_capture = 1,
264 .ops = &cht_aif1_ops, 261 .ops = &cht_aif1_ops,
265 }, 262 },
263 [MERR_DPCM_DEEP_BUFFER] = {
264 .name = "Deep-Buffer Audio Port",
265 .stream_name = "Deep-Buffer Audio",
266 .cpu_dai_name = "deepbuffer-cpu-dai",
267 .codec_dai_name = "snd-soc-dummy-dai",
268 .codec_name = "snd-soc-dummy",
269 .platform_name = "sst-mfld-platform",
270 .nonatomic = true,
271 .dynamic = 1,
272 .dpcm_playback = 1,
273 .ops = &cht_aif1_ops,
274 },
266 [MERR_DPCM_COMPR] = { 275 [MERR_DPCM_COMPR] = {
267 .name = "Compressed Port", 276 .name = "Compressed Port",
268 .stream_name = "Compress", 277 .stream_name = "Compress",
diff --git a/sound/soc/intel/boards/cht_bsw_rt5672.c b/sound/soc/intel/boards/cht_bsw_rt5672.c
index 5621ccd92992..2e5347f8f96c 100644
--- a/sound/soc/intel/boards/cht_bsw_rt5672.c
+++ b/sound/soc/intel/boards/cht_bsw_rt5672.c
@@ -46,12 +46,9 @@ static struct snd_soc_jack_pin cht_bsw_headset_pins[] = {
46 46
47static inline struct snd_soc_dai *cht_get_codec_dai(struct snd_soc_card *card) 47static inline struct snd_soc_dai *cht_get_codec_dai(struct snd_soc_card *card)
48{ 48{
49 int i; 49 struct snd_soc_pcm_runtime *rtd;
50 50
51 for (i = 0; i < card->num_rtd; i++) { 51 list_for_each_entry(rtd, &card->rtd_list, list) {
52 struct snd_soc_pcm_runtime *rtd;
53
54 rtd = card->rtd + i;
55 if (!strncmp(rtd->codec_dai->name, CHT_CODEC_DAI, 52 if (!strncmp(rtd->codec_dai->name, CHT_CODEC_DAI,
56 strlen(CHT_CODEC_DAI))) 53 strlen(CHT_CODEC_DAI)))
57 return rtd->codec_dai; 54 return rtd->codec_dai;
@@ -251,6 +248,18 @@ static struct snd_soc_dai_link cht_dailink[] = {
251 .dpcm_capture = 1, 248 .dpcm_capture = 1,
252 .ops = &cht_aif1_ops, 249 .ops = &cht_aif1_ops,
253 }, 250 },
251 [MERR_DPCM_DEEP_BUFFER] = {
252 .name = "Deep-Buffer Audio Port",
253 .stream_name = "Deep-Buffer Audio",
254 .cpu_dai_name = "deepbuffer-cpu-dai",
255 .codec_dai_name = "snd-soc-dummy-dai",
256 .codec_name = "snd-soc-dummy",
257 .platform_name = "sst-mfld-platform",
258 .nonatomic = true,
259 .dynamic = 1,
260 .dpcm_playback = 1,
261 .ops = &cht_aif1_ops,
262 },
254 [MERR_DPCM_COMPR] = { 263 [MERR_DPCM_COMPR] = {
255 .name = "Compressed Port", 264 .name = "Compressed Port",
256 .stream_name = "Compress", 265 .stream_name = "Compress",
diff --git a/sound/soc/intel/boards/skl_nau88l25_max98357a.c b/sound/soc/intel/boards/skl_nau88l25_max98357a.c
new file mode 100644
index 000000000000..ab7da9c304b2
--- /dev/null
+++ b/sound/soc/intel/boards/skl_nau88l25_max98357a.c
@@ -0,0 +1,485 @@
1/*
2 * Intel Skylake I2S Machine Driver with MAXIM98357A
3 * and NAU88L25
4 *
5 * Copyright (C) 2015, Intel Corporation. All rights reserved.
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License version
9 * 2 as published by the Free Software Foundation.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 */
16
17#include <linux/module.h>
18#include <linux/platform_device.h>
19#include <sound/core.h>
20#include <sound/jack.h>
21#include <sound/pcm.h>
22#include <sound/pcm_params.h>
23#include <sound/soc.h>
24#include "../../codecs/nau8825.h"
25
26#define SKL_NUVOTON_CODEC_DAI "nau8825-hifi"
27#define SKL_MAXIM_CODEC_DAI "HiFi"
28
29static struct snd_soc_jack skylake_headset;
30static struct snd_soc_card skylake_audio_card;
31
32static inline struct snd_soc_dai *skl_get_codec_dai(struct snd_soc_card *card)
33{
34 struct snd_soc_pcm_runtime *rtd;
35
36 list_for_each_entry(rtd, &card->rtd_list, list) {
37
38 if (!strncmp(rtd->codec_dai->name, SKL_NUVOTON_CODEC_DAI,
39 strlen(SKL_NUVOTON_CODEC_DAI)))
40 return rtd->codec_dai;
41 }
42
43 return NULL;
44}
45
46static int platform_clock_control(struct snd_soc_dapm_widget *w,
47 struct snd_kcontrol *k, int event)
48{
49 struct snd_soc_dapm_context *dapm = w->dapm;
50 struct snd_soc_card *card = dapm->card;
51 struct snd_soc_dai *codec_dai;
52 int ret;
53
54 codec_dai = skl_get_codec_dai(card);
55 if (!codec_dai) {
56 dev_err(card->dev, "Codec dai not found; Unable to set platform clock\n");
57 return -EIO;
58 }
59
60 if (SND_SOC_DAPM_EVENT_ON(event)) {
61 ret = snd_soc_dai_set_sysclk(codec_dai,
62 NAU8825_CLK_MCLK, 24000000, SND_SOC_CLOCK_IN);
63 if (ret < 0) {
64 dev_err(card->dev, "set sysclk err = %d\n", ret);
65 return -EIO;
66 }
67 } else {
68 ret = snd_soc_dai_set_sysclk(codec_dai,
69 NAU8825_CLK_INTERNAL, 0, SND_SOC_CLOCK_IN);
70 if (ret < 0) {
71 dev_err(card->dev, "set sysclk err = %d\n", ret);
72 return -EIO;
73 }
74 }
75
76 return ret;
77}
78
79static const struct snd_kcontrol_new skylake_controls[] = {
80 SOC_DAPM_PIN_SWITCH("Headphone Jack"),
81 SOC_DAPM_PIN_SWITCH("Headset Mic"),
82 SOC_DAPM_PIN_SWITCH("Spk"),
83};
84
85static const struct snd_soc_dapm_widget skylake_widgets[] = {
86 SND_SOC_DAPM_HP("Headphone Jack", NULL),
87 SND_SOC_DAPM_MIC("Headset Mic", NULL),
88 SND_SOC_DAPM_SPK("Spk", NULL),
89 SND_SOC_DAPM_MIC("SoC DMIC", NULL),
90 SND_SOC_DAPM_SINK("WoV Sink"),
91 SND_SOC_DAPM_SPK("DP", NULL),
92 SND_SOC_DAPM_SPK("HDMI", NULL),
93 SND_SOC_DAPM_SUPPLY("Platform Clock", SND_SOC_NOPM, 0, 0,
94 platform_clock_control, SND_SOC_DAPM_PRE_PMU |
95 SND_SOC_DAPM_POST_PMD),
96};
97
98static const struct snd_soc_dapm_route skylake_map[] = {
99 /* HP jack connectors - unknown if we have jack detection */
100 { "Headphone Jack", NULL, "HPOL" },
101 { "Headphone Jack", NULL, "HPOR" },
102
103 /* speaker */
104 { "Spk", NULL, "Speaker" },
105
106 /* other jacks */
107 { "MIC", NULL, "Headset Mic" },
108 { "DMic", NULL, "SoC DMIC" },
109
110 {"WoV Sink", NULL, "hwd_in sink"},
111 {"HDMI", NULL, "hif5 Output"},
112 {"DP", NULL, "hif6 Output"},
113
114 /* CODEC BE connections */
115 { "HiFi Playback", NULL, "ssp0 Tx" },
116 { "ssp0 Tx", NULL, "codec0_out" },
117
118 { "Playback", NULL, "ssp1 Tx" },
119 { "ssp1 Tx", NULL, "codec1_out" },
120
121 { "codec0_in", NULL, "ssp1 Rx" },
122 { "ssp1 Rx", NULL, "Capture" },
123
124 /* DMIC */
125 { "dmic01_hifi", NULL, "DMIC01 Rx" },
126 { "DMIC01 Rx", NULL, "DMIC AIF" },
127 { "hifi1", NULL, "iDisp Tx"},
128 { "iDisp Tx", NULL, "iDisp_out"},
129 { "Headphone Jack", NULL, "Platform Clock" },
130 { "Headset Mic", NULL, "Platform Clock" },
131};
132
133static int skylake_ssp_fixup(struct snd_soc_pcm_runtime *rtd,
134 struct snd_pcm_hw_params *params)
135{
136 struct snd_interval *rate = hw_param_interval(params,
137 SNDRV_PCM_HW_PARAM_RATE);
138 struct snd_interval *channels = hw_param_interval(params,
139 SNDRV_PCM_HW_PARAM_CHANNELS);
140 struct snd_mask *fmt = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT);
141
142 /* The ADSP will covert the FE rate to 48k, stereo */
143 rate->min = rate->max = 48000;
144 channels->min = channels->max = 2;
145
146 /* set SSP0 to 24 bit */
147 snd_mask_none(fmt);
148 snd_mask_set(fmt, SNDRV_PCM_FORMAT_S24_LE);
149
150 return 0;
151}
152
153static int skylake_nau8825_codec_init(struct snd_soc_pcm_runtime *rtd)
154{
155 int ret;
156 struct snd_soc_codec *codec = rtd->codec;
157
158 /*
159 * Headset buttons map to the google Reference headset.
160 * These can be configured by userspace.
161 */
162 ret = snd_soc_card_jack_new(&skylake_audio_card, "Headset Jack",
163 SND_JACK_HEADSET | SND_JACK_BTN_0 | SND_JACK_BTN_1 |
164 SND_JACK_BTN_2 | SND_JACK_BTN_3, &skylake_headset,
165 NULL, 0);
166 if (ret) {
167 dev_err(rtd->dev, "Headset Jack creation failed %d\n", ret);
168 return ret;
169 }
170
171 nau8825_enable_jack_detect(codec, &skylake_headset);
172
173 snd_soc_dapm_ignore_suspend(&rtd->card->dapm, "SoC DMIC");
174 snd_soc_dapm_ignore_suspend(&rtd->card->dapm, "WoV Sink");
175
176 return ret;
177}
178
179static int skylake_nau8825_fe_init(struct snd_soc_pcm_runtime *rtd)
180{
181 struct snd_soc_dapm_context *dapm;
182 struct snd_soc_component *component = rtd->cpu_dai->component;
183
184 dapm = snd_soc_component_get_dapm(component);
185 snd_soc_dapm_ignore_suspend(dapm, "Reference Capture");
186
187 return 0;
188}
189
190static unsigned int rates[] = {
191 48000,
192};
193
194static struct snd_pcm_hw_constraint_list constraints_rates = {
195 .count = ARRAY_SIZE(rates),
196 .list = rates,
197 .mask = 0,
198};
199
200static unsigned int channels[] = {
201 2,
202};
203
204static struct snd_pcm_hw_constraint_list constraints_channels = {
205 .count = ARRAY_SIZE(channels),
206 .list = channels,
207 .mask = 0,
208};
209
210static int skl_fe_startup(struct snd_pcm_substream *substream)
211{
212 struct snd_pcm_runtime *runtime = substream->runtime;
213
214 /*
215 * On this platform for PCM device we support,
216 * 48Khz
217 * stereo
218 * 16 bit audio
219 */
220
221 runtime->hw.channels_max = 2;
222 snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
223 &constraints_channels);
224
225 runtime->hw.formats = SNDRV_PCM_FMTBIT_S16_LE;
226 snd_pcm_hw_constraint_msbits(runtime, 0, 16, 16);
227
228 snd_pcm_hw_constraint_list(runtime, 0,
229 SNDRV_PCM_HW_PARAM_RATE, &constraints_rates);
230
231 return 0;
232}
233
234static const struct snd_soc_ops skylake_nau8825_fe_ops = {
235 .startup = skl_fe_startup,
236};
237
238static int skylake_nau8825_hw_params(struct snd_pcm_substream *substream,
239 struct snd_pcm_hw_params *params)
240{
241 struct snd_soc_pcm_runtime *rtd = substream->private_data;
242 struct snd_soc_dai *codec_dai = rtd->codec_dai;
243 int ret;
244
245 ret = snd_soc_dai_set_sysclk(codec_dai,
246 NAU8825_CLK_MCLK, 24000000, SND_SOC_CLOCK_IN);
247
248 if (ret < 0)
249 dev_err(rtd->dev, "snd_soc_dai_set_sysclk err = %d\n", ret);
250
251 return ret;
252}
253
254static struct snd_soc_ops skylake_nau8825_ops = {
255 .hw_params = skylake_nau8825_hw_params,
256};
257
258static int skylake_dmic_fixup(struct snd_soc_pcm_runtime *rtd,
259 struct snd_pcm_hw_params *params)
260{
261 struct snd_interval *channels = hw_param_interval(params,
262 SNDRV_PCM_HW_PARAM_CHANNELS);
263
264 if (params_channels(params) == 2)
265 channels->min = channels->max = 2;
266 else
267 channels->min = channels->max = 4;
268
269 return 0;
270}
271
272static unsigned int channels_dmic[] = {
273 2, 4,
274};
275
276static struct snd_pcm_hw_constraint_list constraints_dmic_channels = {
277 .count = ARRAY_SIZE(channels_dmic),
278 .list = channels_dmic,
279 .mask = 0,
280};
281
282static int skylake_dmic_startup(struct snd_pcm_substream *substream)
283{
284 struct snd_pcm_runtime *runtime = substream->runtime;
285
286 runtime->hw.channels_max = 4;
287 snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
288 &constraints_dmic_channels);
289
290 return snd_pcm_hw_constraint_list(substream->runtime, 0,
291 SNDRV_PCM_HW_PARAM_RATE, &constraints_rates);
292}
293
294static struct snd_soc_ops skylake_dmic_ops = {
295 .startup = skylake_dmic_startup,
296};
297
298static unsigned int rates_16000[] = {
299 16000,
300};
301
302static struct snd_pcm_hw_constraint_list constraints_16000 = {
303 .count = ARRAY_SIZE(rates_16000),
304 .list = rates_16000,
305};
306
307static int skylake_refcap_startup(struct snd_pcm_substream *substream)
308{
309 return snd_pcm_hw_constraint_list(substream->runtime, 0,
310 SNDRV_PCM_HW_PARAM_RATE,
311 &constraints_16000);
312}
313
314static struct snd_soc_ops skylaye_refcap_ops = {
315 .startup = skylake_refcap_startup,
316};
317
318/* skylake digital audio interface glue - connects codec <--> CPU */
319static struct snd_soc_dai_link skylake_dais[] = {
320 /* Front End DAI links */
321 {
322 .name = "Skl Audio Port",
323 .stream_name = "Audio",
324 .cpu_dai_name = "System Pin",
325 .platform_name = "0000:00:1f.3",
326 .dynamic = 1,
327 .codec_name = "snd-soc-dummy",
328 .codec_dai_name = "snd-soc-dummy-dai",
329 .nonatomic = 1,
330 .init = skylake_nau8825_fe_init,
331 .trigger = {
332 SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST},
333 .dpcm_playback = 1,
334 .ops = &skylake_nau8825_fe_ops,
335 },
336 {
337 .name = "Skl Audio Capture Port",
338 .stream_name = "Audio Record",
339 .cpu_dai_name = "System Pin",
340 .platform_name = "0000:00:1f.3",
341 .dynamic = 1,
342 .codec_name = "snd-soc-dummy",
343 .codec_dai_name = "snd-soc-dummy-dai",
344 .nonatomic = 1,
345 .trigger = {
346 SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST},
347 .dpcm_capture = 1,
348 .ops = &skylake_nau8825_fe_ops,
349 },
350 {
351 .name = "Skl Audio Reference cap",
352 .stream_name = "Wake on Voice",
353 .cpu_dai_name = "Reference Pin",
354 .codec_name = "snd-soc-dummy",
355 .codec_dai_name = "snd-soc-dummy-dai",
356 .platform_name = "0000:00:1f.3",
357 .init = NULL,
358 .dpcm_capture = 1,
359 .ignore_suspend = 1,
360 .nonatomic = 1,
361 .dynamic = 1,
362 .ops = &skylaye_refcap_ops,
363 },
364 {
365 .name = "Skl Audio DMIC cap",
366 .stream_name = "dmiccap",
367 .cpu_dai_name = "DMIC Pin",
368 .codec_name = "snd-soc-dummy",
369 .codec_dai_name = "snd-soc-dummy-dai",
370 .platform_name = "0000:00:1f.3",
371 .init = NULL,
372 .dpcm_capture = 1,
373 .nonatomic = 1,
374 .dynamic = 1,
375 .ops = &skylake_dmic_ops,
376 },
377 {
378 .name = "Skl HDMI Port",
379 .stream_name = "Hdmi",
380 .cpu_dai_name = "HDMI Pin",
381 .codec_name = "snd-soc-dummy",
382 .codec_dai_name = "snd-soc-dummy-dai",
383 .platform_name = "0000:00:1f.3",
384 .dpcm_playback = 1,
385 .init = NULL,
386 .nonatomic = 1,
387 .dynamic = 1,
388 },
389
390 /* Back End DAI links */
391 {
392 /* SSP0 - Codec */
393 .name = "SSP0-Codec",
394 .be_id = 0,
395 .cpu_dai_name = "SSP0 Pin",
396 .platform_name = "0000:00:1f.3",
397 .no_pcm = 1,
398 .codec_name = "MX98357A:00",
399 .codec_dai_name = SKL_MAXIM_CODEC_DAI,
400 .dai_fmt = SND_SOC_DAIFMT_I2S |
401 SND_SOC_DAIFMT_NB_NF |
402 SND_SOC_DAIFMT_CBS_CFS,
403 .ignore_pmdown_time = 1,
404 .be_hw_params_fixup = skylake_ssp_fixup,
405 .dpcm_playback = 1,
406 },
407 {
408 /* SSP1 - Codec */
409 .name = "SSP1-Codec",
410 .be_id = 0,
411 .cpu_dai_name = "SSP1 Pin",
412 .platform_name = "0000:00:1f.3",
413 .no_pcm = 1,
414 .codec_name = "i2c-10508825:00",
415 .codec_dai_name = SKL_NUVOTON_CODEC_DAI,
416 .init = skylake_nau8825_codec_init,
417 .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
418 SND_SOC_DAIFMT_CBS_CFS,
419 .ignore_pmdown_time = 1,
420 .be_hw_params_fixup = skylake_ssp_fixup,
421 .ops = &skylake_nau8825_ops,
422 .dpcm_playback = 1,
423 .dpcm_capture = 1,
424 },
425 {
426 .name = "dmic01",
427 .be_id = 1,
428 .cpu_dai_name = "DMIC01 Pin",
429 .codec_name = "dmic-codec",
430 .codec_dai_name = "dmic-hifi",
431 .platform_name = "0000:00:1f.3",
432 .be_hw_params_fixup = skylake_dmic_fixup,
433 .ignore_suspend = 1,
434 .dpcm_capture = 1,
435 .no_pcm = 1,
436 },
437 {
438 .name = "iDisp",
439 .be_id = 3,
440 .cpu_dai_name = "iDisp Pin",
441 .codec_name = "ehdaudio0D2",
442 .codec_dai_name = "intel-hdmi-hifi1",
443 .platform_name = "0000:00:1f.3",
444 .dpcm_playback = 1,
445 .no_pcm = 1,
446 },
447};
448
449/* skylake audio machine driver for SPT + NAU88L25 */
450static struct snd_soc_card skylake_audio_card = {
451 .name = "sklnau8825max",
452 .owner = THIS_MODULE,
453 .dai_link = skylake_dais,
454 .num_links = ARRAY_SIZE(skylake_dais),
455 .controls = skylake_controls,
456 .num_controls = ARRAY_SIZE(skylake_controls),
457 .dapm_widgets = skylake_widgets,
458 .num_dapm_widgets = ARRAY_SIZE(skylake_widgets),
459 .dapm_routes = skylake_map,
460 .num_dapm_routes = ARRAY_SIZE(skylake_map),
461 .fully_routed = true,
462};
463
464static int skylake_audio_probe(struct platform_device *pdev)
465{
466 skylake_audio_card.dev = &pdev->dev;
467
468 return devm_snd_soc_register_card(&pdev->dev, &skylake_audio_card);
469}
470
471static struct platform_driver skylake_audio = {
472 .probe = skylake_audio_probe,
473 .driver = {
474 .name = "skl_nau88l25_max98357a_i2s",
475 .pm = &snd_soc_pm_ops,
476 },
477};
478
479module_platform_driver(skylake_audio)
480
481/* Module information */
482MODULE_DESCRIPTION("Audio Machine driver-NAU88L25 & MAX98357A in I2S mode");
483MODULE_AUTHOR("Rohit Ainapure <rohit.m.ainapure@intel.com");
484MODULE_LICENSE("GPL v2");
485MODULE_ALIAS("platform:skl_nau88l25_max98357a_i2s");
diff --git a/sound/soc/intel/boards/skl_nau88l25_ssm4567.c b/sound/soc/intel/boards/skl_nau88l25_ssm4567.c
new file mode 100644
index 000000000000..c071812f31e5
--- /dev/null
+++ b/sound/soc/intel/boards/skl_nau88l25_ssm4567.c
@@ -0,0 +1,536 @@
1/*
2 * Intel Skylake I2S Machine Driver for NAU88L25+SSM4567
3 *
4 * Copyright (C) 2015, Intel Corporation. All rights reserved.
5 *
6 * Modified from:
7 * Intel Skylake I2S Machine Driver for NAU88L25 and SSM4567
8 *
9 * Copyright (C) 2015, Intel Corporation. All rights reserved.
10 *
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License version
13 * 2 as published by the Free Software Foundation.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 */
20
21#include <linux/module.h>
22#include <linux/platform_device.h>
23#include <sound/core.h>
24#include <sound/pcm.h>
25#include <sound/soc.h>
26#include <sound/jack.h>
27#include <sound/pcm_params.h>
28#include "../../codecs/nau8825.h"
29
30#define SKL_NUVOTON_CODEC_DAI "nau8825-hifi"
31#define SKL_SSM_CODEC_DAI "ssm4567-hifi"
32
33static struct snd_soc_jack skylake_headset;
34static struct snd_soc_card skylake_audio_card;
35
36static inline struct snd_soc_dai *skl_get_codec_dai(struct snd_soc_card *card)
37{
38 struct snd_soc_pcm_runtime *rtd;
39
40 list_for_each_entry(rtd, &card->rtd_list, list) {
41
42 if (!strncmp(rtd->codec_dai->name, SKL_NUVOTON_CODEC_DAI,
43 strlen(SKL_NUVOTON_CODEC_DAI)))
44 return rtd->codec_dai;
45 }
46
47 return NULL;
48}
49
50static const struct snd_kcontrol_new skylake_controls[] = {
51 SOC_DAPM_PIN_SWITCH("Headphone Jack"),
52 SOC_DAPM_PIN_SWITCH("Headset Mic"),
53 SOC_DAPM_PIN_SWITCH("Left Speaker"),
54 SOC_DAPM_PIN_SWITCH("Right Speaker"),
55};
56
57static int platform_clock_control(struct snd_soc_dapm_widget *w,
58 struct snd_kcontrol *k, int event)
59{
60 struct snd_soc_dapm_context *dapm = w->dapm;
61 struct snd_soc_card *card = dapm->card;
62 struct snd_soc_dai *codec_dai;
63 int ret;
64
65 codec_dai = skl_get_codec_dai(card);
66 if (!codec_dai) {
67 dev_err(card->dev, "Codec dai not found\n");
68 return -EIO;
69 }
70
71 if (SND_SOC_DAPM_EVENT_ON(event)) {
72 ret = snd_soc_dai_set_sysclk(codec_dai,
73 NAU8825_CLK_MCLK, 24000000, SND_SOC_CLOCK_IN);
74 if (ret < 0) {
75 dev_err(card->dev, "set sysclk err = %d\n", ret);
76 return -EIO;
77 }
78 } else {
79 ret = snd_soc_dai_set_sysclk(codec_dai,
80 NAU8825_CLK_INTERNAL, 0, SND_SOC_CLOCK_IN);
81 if (ret < 0) {
82 dev_err(card->dev, "set sysclk err = %d\n", ret);
83 return -EIO;
84 }
85 }
86 return ret;
87}
88
89static const struct snd_soc_dapm_widget skylake_widgets[] = {
90 SND_SOC_DAPM_HP("Headphone Jack", NULL),
91 SND_SOC_DAPM_MIC("Headset Mic", NULL),
92 SND_SOC_DAPM_SPK("Left Speaker", NULL),
93 SND_SOC_DAPM_SPK("Right Speaker", NULL),
94 SND_SOC_DAPM_MIC("SoC DMIC", NULL),
95 SND_SOC_DAPM_SINK("WoV Sink"),
96 SND_SOC_DAPM_SPK("DP", NULL),
97 SND_SOC_DAPM_SPK("HDMI", NULL),
98 SND_SOC_DAPM_SUPPLY("Platform Clock", SND_SOC_NOPM, 0, 0,
99 platform_clock_control, SND_SOC_DAPM_PRE_PMU |
100 SND_SOC_DAPM_POST_PMD),
101};
102
103static const struct snd_soc_dapm_route skylake_map[] = {
104 /* HP jack connectors - unknown if we have jack detection */
105 {"Headphone Jack", NULL, "HPOL"},
106 {"Headphone Jack", NULL, "HPOR"},
107
108 /* speaker */
109 {"Left Speaker", NULL, "Left OUT"},
110 {"Right Speaker", NULL, "Right OUT"},
111
112 /* other jacks */
113 {"MIC", NULL, "Headset Mic"},
114 {"DMic", NULL, "SoC DMIC"},
115
116 {"WoV Sink", NULL, "hwd_in sink"},
117
118 {"HDMI", NULL, "hif5 Output"},
119 {"DP", NULL, "hif6 Output"},
120 /* CODEC BE connections */
121 { "Left Playback", NULL, "ssp0 Tx"},
122 { "Right Playback", NULL, "ssp0 Tx"},
123 { "ssp0 Tx", NULL, "codec0_out"},
124
125 { "Playback", NULL, "ssp1 Tx"},
126 { "ssp1 Tx", NULL, "codec1_out"},
127
128 { "codec0_in", NULL, "ssp1 Rx" },
129 { "ssp1 Rx", NULL, "Capture" },
130
131 /* DMIC */
132 { "dmic01_hifi", NULL, "DMIC01 Rx" },
133 { "DMIC01 Rx", NULL, "DMIC AIF" },
134 { "hifi1", NULL, "iDisp Tx"},
135 { "iDisp Tx", NULL, "iDisp_out"},
136 { "Headphone Jack", NULL, "Platform Clock" },
137 { "Headset Mic", NULL, "Platform Clock" },
138};
139
140static struct snd_soc_codec_conf ssm4567_codec_conf[] = {
141 {
142 .dev_name = "i2c-INT343B:00",
143 .name_prefix = "Left",
144 },
145 {
146 .dev_name = "i2c-INT343B:01",
147 .name_prefix = "Right",
148 },
149};
150
151static struct snd_soc_dai_link_component ssm4567_codec_components[] = {
152 { /* Left */
153 .name = "i2c-INT343B:00",
154 .dai_name = SKL_SSM_CODEC_DAI,
155 },
156 { /* Right */
157 .name = "i2c-INT343B:01",
158 .dai_name = SKL_SSM_CODEC_DAI,
159 },
160};
161
162static int skylake_ssm4567_codec_init(struct snd_soc_pcm_runtime *rtd)
163{
164 int ret;
165
166 /* Slot 1 for left */
167 ret = snd_soc_dai_set_tdm_slot(rtd->codec_dais[0], 0x01, 0x01, 2, 48);
168 if (ret < 0)
169 return ret;
170
171 /* Slot 2 for right */
172 ret = snd_soc_dai_set_tdm_slot(rtd->codec_dais[1], 0x02, 0x02, 2, 48);
173 if (ret < 0)
174 return ret;
175
176 return ret;
177}
178
179static int skylake_nau8825_codec_init(struct snd_soc_pcm_runtime *rtd)
180{
181 int ret;
182 struct snd_soc_codec *codec = rtd->codec;
183
184 /*
185 * 4 buttons here map to the google Reference headset
186 * The use of these buttons can be decided by the user space.
187 */
188 ret = snd_soc_card_jack_new(&skylake_audio_card, "Headset Jack",
189 SND_JACK_HEADSET | SND_JACK_BTN_0 | SND_JACK_BTN_1 |
190 SND_JACK_BTN_2 | SND_JACK_BTN_3, &skylake_headset,
191 NULL, 0);
192 if (ret) {
193 dev_err(rtd->dev, "Headset Jack creation failed %d\n", ret);
194 return ret;
195 }
196
197 nau8825_enable_jack_detect(codec, &skylake_headset);
198
199 snd_soc_dapm_ignore_suspend(&rtd->card->dapm, "SoC DMIC");
200 snd_soc_dapm_ignore_suspend(&rtd->card->dapm, "WoV Sink");
201
202 return ret;
203}
204
205static int skylake_nau8825_fe_init(struct snd_soc_pcm_runtime *rtd)
206{
207 struct snd_soc_dapm_context *dapm;
208 struct snd_soc_component *component = rtd->cpu_dai->component;
209
210 dapm = snd_soc_component_get_dapm(component);
211 snd_soc_dapm_ignore_suspend(dapm, "Reference Capture");
212
213 return 0;
214}
215
216static unsigned int rates[] = {
217 48000,
218};
219
220static struct snd_pcm_hw_constraint_list constraints_rates = {
221 .count = ARRAY_SIZE(rates),
222 .list = rates,
223 .mask = 0,
224};
225
226static unsigned int channels[] = {
227 2,
228};
229
230static struct snd_pcm_hw_constraint_list constraints_channels = {
231 .count = ARRAY_SIZE(channels),
232 .list = channels,
233 .mask = 0,
234};
235
236static int skl_fe_startup(struct snd_pcm_substream *substream)
237{
238 struct snd_pcm_runtime *runtime = substream->runtime;
239
240 /*
241 * on this platform for PCM device we support,
242 * 48Khz
243 * stereo
244 * 16 bit audio
245 */
246
247 runtime->hw.channels_max = 2;
248 snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
249 &constraints_channels);
250
251 runtime->hw.formats = SNDRV_PCM_FMTBIT_S16_LE;
252 snd_pcm_hw_constraint_msbits(runtime, 0, 16, 16);
253
254 snd_pcm_hw_constraint_list(runtime, 0,
255 SNDRV_PCM_HW_PARAM_RATE, &constraints_rates);
256
257 return 0;
258}
259
260static const struct snd_soc_ops skylake_nau8825_fe_ops = {
261 .startup = skl_fe_startup,
262};
263
264static int skylake_ssp_fixup(struct snd_soc_pcm_runtime *rtd,
265 struct snd_pcm_hw_params *params)
266{
267 struct snd_interval *rate = hw_param_interval(params,
268 SNDRV_PCM_HW_PARAM_RATE);
269 struct snd_interval *channels = hw_param_interval(params,
270 SNDRV_PCM_HW_PARAM_CHANNELS);
271 struct snd_mask *fmt = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT);
272
273 /* The ADSP will covert the FE rate to 48k, stereo */
274 rate->min = rate->max = 48000;
275 channels->min = channels->max = 2;
276
277 /* set SSP0 to 24 bit */
278 snd_mask_none(fmt);
279 snd_mask_set(fmt, SNDRV_PCM_FORMAT_S24_LE);
280 return 0;
281}
282
283static int skylake_dmic_fixup(struct snd_soc_pcm_runtime *rtd,
284 struct snd_pcm_hw_params *params)
285{
286 struct snd_interval *channels = hw_param_interval(params,
287 SNDRV_PCM_HW_PARAM_CHANNELS);
288 if (params_channels(params) == 2)
289 channels->min = channels->max = 2;
290 else
291 channels->min = channels->max = 4;
292
293 return 0;
294}
295
296static int skylake_nau8825_hw_params(struct snd_pcm_substream *substream,
297 struct snd_pcm_hw_params *params)
298{
299 struct snd_soc_pcm_runtime *rtd = substream->private_data;
300 struct snd_soc_dai *codec_dai = rtd->codec_dai;
301 int ret;
302
303 ret = snd_soc_dai_set_sysclk(codec_dai,
304 NAU8825_CLK_MCLK, 24000000, SND_SOC_CLOCK_IN);
305
306 if (ret < 0)
307 dev_err(rtd->dev, "snd_soc_dai_set_sysclk err = %d\n", ret);
308
309 return ret;
310}
311
312static struct snd_soc_ops skylake_nau8825_ops = {
313 .hw_params = skylake_nau8825_hw_params,
314};
315
316static unsigned int channels_dmic[] = {
317 2, 4,
318};
319
320static struct snd_pcm_hw_constraint_list constraints_dmic_channels = {
321 .count = ARRAY_SIZE(channels_dmic),
322 .list = channels_dmic,
323 .mask = 0,
324};
325
326static int skylake_dmic_startup(struct snd_pcm_substream *substream)
327{
328 struct snd_pcm_runtime *runtime = substream->runtime;
329
330 runtime->hw.channels_max = 4;
331 snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
332 &constraints_dmic_channels);
333
334 return snd_pcm_hw_constraint_list(substream->runtime, 0,
335 SNDRV_PCM_HW_PARAM_RATE, &constraints_rates);
336}
337
338static struct snd_soc_ops skylake_dmic_ops = {
339 .startup = skylake_dmic_startup,
340};
341
342static unsigned int rates_16000[] = {
343 16000,
344};
345
346static struct snd_pcm_hw_constraint_list constraints_16000 = {
347 .count = ARRAY_SIZE(rates_16000),
348 .list = rates_16000,
349};
350
351static int skylake_refcap_startup(struct snd_pcm_substream *substream)
352{
353 return snd_pcm_hw_constraint_list(substream->runtime, 0,
354 SNDRV_PCM_HW_PARAM_RATE,
355 &constraints_16000);
356}
357
358static struct snd_soc_ops skylaye_refcap_ops = {
359 .startup = skylake_refcap_startup,
360};
361
362/* skylake digital audio interface glue - connects codec <--> CPU */
363static struct snd_soc_dai_link skylake_dais[] = {
364 /* Front End DAI links */
365 {
366 .name = "Skl Audio Port",
367 .stream_name = "Audio",
368 .cpu_dai_name = "System Pin",
369 .platform_name = "0000:00:1f.3",
370 .dynamic = 1,
371 .codec_name = "snd-soc-dummy",
372 .codec_dai_name = "snd-soc-dummy-dai",
373 .nonatomic = 1,
374 .init = skylake_nau8825_fe_init,
375 .trigger = {
376 SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST},
377 .dpcm_playback = 1,
378 .ops = &skylake_nau8825_fe_ops,
379 },
380 {
381 .name = "Skl Audio Capture Port",
382 .stream_name = "Audio Record",
383 .cpu_dai_name = "System Pin",
384 .platform_name = "0000:00:1f.3",
385 .dynamic = 1,
386 .codec_name = "snd-soc-dummy",
387 .codec_dai_name = "snd-soc-dummy-dai",
388 .nonatomic = 1,
389 .trigger = {
390 SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST},
391 .dpcm_capture = 1,
392 .ops = &skylake_nau8825_fe_ops,
393 },
394 {
395 .name = "Skl Audio Reference cap",
396 .stream_name = "Wake on Voice",
397 .cpu_dai_name = "Reference Pin",
398 .codec_name = "snd-soc-dummy",
399 .codec_dai_name = "snd-soc-dummy-dai",
400 .platform_name = "0000:00:1f.3",
401 .init = NULL,
402 .dpcm_capture = 1,
403 .ignore_suspend = 1,
404 .nonatomic = 1,
405 .dynamic = 1,
406 .ops = &skylaye_refcap_ops,
407 },
408 {
409 .name = "Skl Audio DMIC cap",
410 .stream_name = "dmiccap",
411 .cpu_dai_name = "DMIC Pin",
412 .codec_name = "snd-soc-dummy",
413 .codec_dai_name = "snd-soc-dummy-dai",
414 .platform_name = "0000:00:1f.3",
415 .init = NULL,
416 .dpcm_capture = 1,
417 .nonatomic = 1,
418 .dynamic = 1,
419 .ops = &skylake_dmic_ops,
420 },
421 {
422 .name = "Skl HDMI Port",
423 .stream_name = "Hdmi",
424 .cpu_dai_name = "HDMI Pin",
425 .codec_name = "snd-soc-dummy",
426 .codec_dai_name = "snd-soc-dummy-dai",
427 .platform_name = "0000:00:1f.3",
428 .dpcm_playback = 1,
429 .init = NULL,
430 .nonatomic = 1,
431 .dynamic = 1,
432 },
433
434 /* Back End DAI links */
435 {
436 /* SSP0 - Codec */
437 .name = "SSP0-Codec",
438 .be_id = 0,
439 .cpu_dai_name = "SSP0 Pin",
440 .platform_name = "0000:00:1f.3",
441 .no_pcm = 1,
442 .codecs = ssm4567_codec_components,
443 .num_codecs = ARRAY_SIZE(ssm4567_codec_components),
444 .dai_fmt = SND_SOC_DAIFMT_DSP_A |
445 SND_SOC_DAIFMT_IB_NF |
446 SND_SOC_DAIFMT_CBS_CFS,
447 .init = skylake_ssm4567_codec_init,
448 .ignore_pmdown_time = 1,
449 .be_hw_params_fixup = skylake_ssp_fixup,
450 .dpcm_playback = 1,
451 },
452 {
453 /* SSP1 - Codec */
454 .name = "SSP1-Codec",
455 .be_id = 0,
456 .cpu_dai_name = "SSP1 Pin",
457 .platform_name = "0000:00:1f.3",
458 .no_pcm = 1,
459 .codec_name = "i2c-10508825:00",
460 .codec_dai_name = SKL_NUVOTON_CODEC_DAI,
461 .init = skylake_nau8825_codec_init,
462 .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
463 SND_SOC_DAIFMT_CBS_CFS,
464 .ignore_pmdown_time = 1,
465 .be_hw_params_fixup = skylake_ssp_fixup,
466 .ops = &skylake_nau8825_ops,
467 .dpcm_playback = 1,
468 .dpcm_capture = 1,
469 },
470 {
471 .name = "dmic01",
472 .be_id = 1,
473 .cpu_dai_name = "DMIC01 Pin",
474 .codec_name = "dmic-codec",
475 .codec_dai_name = "dmic-hifi",
476 .platform_name = "0000:00:1f.3",
477 .ignore_suspend = 1,
478 .be_hw_params_fixup = skylake_dmic_fixup,
479 .dpcm_capture = 1,
480 .no_pcm = 1,
481 },
482 {
483 .name = "iDisp",
484 .be_id = 3,
485 .cpu_dai_name = "iDisp Pin",
486 .codec_name = "ehdaudio0D2",
487 .codec_dai_name = "intel-hdmi-hifi1",
488 .platform_name = "0000:00:1f.3",
489 .dpcm_playback = 1,
490 .no_pcm = 1,
491 },
492};
493
494/* skylake audio machine driver for SPT + NAU88L25 */
495static struct snd_soc_card skylake_audio_card = {
496 .name = "sklnau8825adi",
497 .owner = THIS_MODULE,
498 .dai_link = skylake_dais,
499 .num_links = ARRAY_SIZE(skylake_dais),
500 .controls = skylake_controls,
501 .num_controls = ARRAY_SIZE(skylake_controls),
502 .dapm_widgets = skylake_widgets,
503 .num_dapm_widgets = ARRAY_SIZE(skylake_widgets),
504 .dapm_routes = skylake_map,
505 .num_dapm_routes = ARRAY_SIZE(skylake_map),
506 .codec_conf = ssm4567_codec_conf,
507 .num_configs = ARRAY_SIZE(ssm4567_codec_conf),
508 .fully_routed = true,
509};
510
511static int skylake_audio_probe(struct platform_device *pdev)
512{
513 skylake_audio_card.dev = &pdev->dev;
514
515 return devm_snd_soc_register_card(&pdev->dev, &skylake_audio_card);
516}
517
518static struct platform_driver skylake_audio = {
519 .probe = skylake_audio_probe,
520 .driver = {
521 .name = "skl_nau88l25_ssm4567_i2s",
522 .pm = &snd_soc_pm_ops,
523 },
524};
525
526module_platform_driver(skylake_audio)
527
528/* Module information */
529MODULE_AUTHOR("Conrad Cooke <conrad.cooke@intel.com>");
530MODULE_AUTHOR("Harsha Priya <harshapriya.n@intel.com>");
531MODULE_AUTHOR("Naveen M <naveen.m@intel.com>");
532MODULE_AUTHOR("Sathya Prakash M R <sathya.prakash.m.r@intel.com>");
533MODULE_AUTHOR("Yong Zhi <yong.zhi@intel.com>");
534MODULE_DESCRIPTION("Intel Audio Machine driver for SKL with NAU88L25 and SSM4567 in I2S Mode");
535MODULE_LICENSE("GPL v2");
536MODULE_ALIAS("platform:skl_nau88l25_ssm4567_i2s");
diff --git a/sound/soc/intel/boards/skl_rt286.c b/sound/soc/intel/boards/skl_rt286.c
index a73a431bd8b7..7396ddb427d8 100644
--- a/sound/soc/intel/boards/skl_rt286.c
+++ b/sound/soc/intel/boards/skl_rt286.c
@@ -52,6 +52,7 @@ static const struct snd_soc_dapm_widget skylake_widgets[] = {
52 SND_SOC_DAPM_MIC("Mic Jack", NULL), 52 SND_SOC_DAPM_MIC("Mic Jack", NULL),
53 SND_SOC_DAPM_MIC("DMIC2", NULL), 53 SND_SOC_DAPM_MIC("DMIC2", NULL),
54 SND_SOC_DAPM_MIC("SoC DMIC", NULL), 54 SND_SOC_DAPM_MIC("SoC DMIC", NULL),
55 SND_SOC_DAPM_SINK("WoV Sink"),
55}; 56};
56 57
57static const struct snd_soc_dapm_route skylake_rt286_map[] = { 58static const struct snd_soc_dapm_route skylake_rt286_map[] = {
@@ -67,7 +68,9 @@ static const struct snd_soc_dapm_route skylake_rt286_map[] = {
67 68
68 /* digital mics */ 69 /* digital mics */
69 {"DMIC1 Pin", NULL, "DMIC2"}, 70 {"DMIC1 Pin", NULL, "DMIC2"},
70 {"DMIC AIF", NULL, "SoC DMIC"}, 71 {"DMic", NULL, "SoC DMIC"},
72
73 {"WoV Sink", NULL, "hwd_in sink"},
71 74
72 /* CODEC BE connections */ 75 /* CODEC BE connections */
73 { "AIF1 Playback", NULL, "ssp0 Tx"}, 76 { "AIF1 Playback", NULL, "ssp0 Tx"},
@@ -79,13 +82,24 @@ static const struct snd_soc_dapm_route skylake_rt286_map[] = {
79 { "ssp0 Rx", NULL, "AIF1 Capture" }, 82 { "ssp0 Rx", NULL, "AIF1 Capture" },
80 83
81 { "dmic01_hifi", NULL, "DMIC01 Rx" }, 84 { "dmic01_hifi", NULL, "DMIC01 Rx" },
82 { "DMIC01 Rx", NULL, "Capture" }, 85 { "DMIC01 Rx", NULL, "DMIC AIF" },
83 86
84 { "hif1", NULL, "iDisp Tx"}, 87 { "hif1", NULL, "iDisp Tx"},
85 { "iDisp Tx", NULL, "iDisp_out"}, 88 { "iDisp Tx", NULL, "iDisp_out"},
86 89
87}; 90};
88 91
92static int skylake_rt286_fe_init(struct snd_soc_pcm_runtime *rtd)
93{
94 struct snd_soc_dapm_context *dapm;
95 struct snd_soc_component *component = rtd->cpu_dai->component;
96
97 dapm = snd_soc_component_get_dapm(component);
98 snd_soc_dapm_ignore_suspend(dapm, "Reference Capture");
99
100 return 0;
101}
102
89static int skylake_rt286_codec_init(struct snd_soc_pcm_runtime *rtd) 103static int skylake_rt286_codec_init(struct snd_soc_pcm_runtime *rtd)
90{ 104{
91 struct snd_soc_codec *codec = rtd->codec; 105 struct snd_soc_codec *codec = rtd->codec;
@@ -101,9 +115,59 @@ static int skylake_rt286_codec_init(struct snd_soc_pcm_runtime *rtd)
101 115
102 rt286_mic_detect(codec, &skylake_headset); 116 rt286_mic_detect(codec, &skylake_headset);
103 117
118 snd_soc_dapm_ignore_suspend(&rtd->card->dapm, "SoC DMIC");
119 snd_soc_dapm_ignore_suspend(&rtd->card->dapm, "WoV Sink");
120
104 return 0; 121 return 0;
105} 122}
106 123
124static unsigned int rates[] = {
125 48000,
126};
127
128static struct snd_pcm_hw_constraint_list constraints_rates = {
129 .count = ARRAY_SIZE(rates),
130 .list = rates,
131 .mask = 0,
132};
133
134static unsigned int channels[] = {
135 2,
136};
137
138static struct snd_pcm_hw_constraint_list constraints_channels = {
139 .count = ARRAY_SIZE(channels),
140 .list = channels,
141 .mask = 0,
142};
143
144static int skl_fe_startup(struct snd_pcm_substream *substream)
145{
146 struct snd_pcm_runtime *runtime = substream->runtime;
147
148 /*
149 * on this platform for PCM device we support,
150 * 48Khz
151 * stereo
152 * 16 bit audio
153 */
154
155 runtime->hw.channels_max = 2;
156 snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
157 &constraints_channels);
158
159 runtime->hw.formats = SNDRV_PCM_FMTBIT_S16_LE;
160 snd_pcm_hw_constraint_msbits(runtime, 0, 16, 16);
161
162 snd_pcm_hw_constraint_list(runtime, 0,
163 SNDRV_PCM_HW_PARAM_RATE, &constraints_rates);
164
165 return 0;
166}
167
168static const struct snd_soc_ops skylake_rt286_fe_ops = {
169 .startup = skl_fe_startup,
170};
107 171
108static int skylake_ssp0_fixup(struct snd_soc_pcm_runtime *rtd, 172static int skylake_ssp0_fixup(struct snd_soc_pcm_runtime *rtd,
109 struct snd_pcm_hw_params *params) 173 struct snd_pcm_hw_params *params)
@@ -112,12 +176,15 @@ static int skylake_ssp0_fixup(struct snd_soc_pcm_runtime *rtd,
112 SNDRV_PCM_HW_PARAM_RATE); 176 SNDRV_PCM_HW_PARAM_RATE);
113 struct snd_interval *channels = hw_param_interval(params, 177 struct snd_interval *channels = hw_param_interval(params,
114 SNDRV_PCM_HW_PARAM_CHANNELS); 178 SNDRV_PCM_HW_PARAM_CHANNELS);
179 struct snd_mask *fmt = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT);
115 180
116 /* The output is 48KHz, stereo, 16bits */ 181 /* The output is 48KHz, stereo, 16bits */
117 rate->min = rate->max = 48000; 182 rate->min = rate->max = 48000;
118 channels->min = channels->max = 2; 183 channels->min = channels->max = 2;
119 params_set_format(params, SNDRV_PCM_FORMAT_S16_LE);
120 184
185 /* set SSP0 to 24 bit */
186 snd_mask_none(fmt);
187 snd_mask_set(fmt, SNDRV_PCM_FORMAT_S24_LE);
121 return 0; 188 return 0;
122} 189}
123 190
@@ -140,6 +207,42 @@ static struct snd_soc_ops skylake_rt286_ops = {
140 .hw_params = skylake_rt286_hw_params, 207 .hw_params = skylake_rt286_hw_params,
141}; 208};
142 209
210static int skylake_dmic_fixup(struct snd_soc_pcm_runtime *rtd,
211 struct snd_pcm_hw_params *params)
212{
213 struct snd_interval *channels = hw_param_interval(params,
214 SNDRV_PCM_HW_PARAM_CHANNELS);
215 channels->min = channels->max = 4;
216
217 return 0;
218}
219
220static unsigned int channels_dmic[] = {
221 2, 4,
222};
223
224static struct snd_pcm_hw_constraint_list constraints_dmic_channels = {
225 .count = ARRAY_SIZE(channels_dmic),
226 .list = channels_dmic,
227 .mask = 0,
228};
229
230static int skylake_dmic_startup(struct snd_pcm_substream *substream)
231{
232 struct snd_pcm_runtime *runtime = substream->runtime;
233
234 runtime->hw.channels_max = 4;
235 snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
236 &constraints_dmic_channels);
237
238 return snd_pcm_hw_constraint_list(substream->runtime, 0,
239 SNDRV_PCM_HW_PARAM_RATE, &constraints_rates);
240}
241
242static struct snd_soc_ops skylake_dmic_ops = {
243 .startup = skylake_dmic_startup,
244};
245
143/* skylake digital audio interface glue - connects codec <--> CPU */ 246/* skylake digital audio interface glue - connects codec <--> CPU */
144static struct snd_soc_dai_link skylake_rt286_dais[] = { 247static struct snd_soc_dai_link skylake_rt286_dais[] = {
145 /* Front End DAI links */ 248 /* Front End DAI links */
@@ -152,11 +255,13 @@ static struct snd_soc_dai_link skylake_rt286_dais[] = {
152 .dynamic = 1, 255 .dynamic = 1,
153 .codec_name = "snd-soc-dummy", 256 .codec_name = "snd-soc-dummy",
154 .codec_dai_name = "snd-soc-dummy-dai", 257 .codec_dai_name = "snd-soc-dummy-dai",
258 .init = skylake_rt286_fe_init,
155 .trigger = { 259 .trigger = {
156 SND_SOC_DPCM_TRIGGER_POST, 260 SND_SOC_DPCM_TRIGGER_POST,
157 SND_SOC_DPCM_TRIGGER_POST 261 SND_SOC_DPCM_TRIGGER_POST
158 }, 262 },
159 .dpcm_playback = 1, 263 .dpcm_playback = 1,
264 .ops = &skylake_rt286_fe_ops,
160 }, 265 },
161 { 266 {
162 .name = "Skl Audio Capture Port", 267 .name = "Skl Audio Capture Port",
@@ -172,6 +277,7 @@ static struct snd_soc_dai_link skylake_rt286_dais[] = {
172 SND_SOC_DPCM_TRIGGER_POST 277 SND_SOC_DPCM_TRIGGER_POST
173 }, 278 },
174 .dpcm_capture = 1, 279 .dpcm_capture = 1,
280 .ops = &skylake_rt286_fe_ops,
175 }, 281 },
176 { 282 {
177 .name = "Skl Audio Reference cap", 283 .name = "Skl Audio Reference cap",
@@ -186,6 +292,19 @@ static struct snd_soc_dai_link skylake_rt286_dais[] = {
186 .nonatomic = 1, 292 .nonatomic = 1,
187 .dynamic = 1, 293 .dynamic = 1,
188 }, 294 },
295 {
296 .name = "Skl Audio DMIC cap",
297 .stream_name = "dmiccap",
298 .cpu_dai_name = "DMIC Pin",
299 .codec_name = "snd-soc-dummy",
300 .codec_dai_name = "snd-soc-dummy-dai",
301 .platform_name = "0000:00:1f.3",
302 .init = NULL,
303 .dpcm_capture = 1,
304 .nonatomic = 1,
305 .dynamic = 1,
306 .ops = &skylake_dmic_ops,
307 },
189 308
190 /* Back End DAI links */ 309 /* Back End DAI links */
191 { 310 {
@@ -201,7 +320,6 @@ static struct snd_soc_dai_link skylake_rt286_dais[] = {
201 .dai_fmt = SND_SOC_DAIFMT_I2S | 320 .dai_fmt = SND_SOC_DAIFMT_I2S |
202 SND_SOC_DAIFMT_NB_NF | 321 SND_SOC_DAIFMT_NB_NF |
203 SND_SOC_DAIFMT_CBS_CFS, 322 SND_SOC_DAIFMT_CBS_CFS,
204 .ignore_suspend = 1,
205 .ignore_pmdown_time = 1, 323 .ignore_pmdown_time = 1,
206 .be_hw_params_fixup = skylake_ssp0_fixup, 324 .be_hw_params_fixup = skylake_ssp0_fixup,
207 .ops = &skylake_rt286_ops, 325 .ops = &skylake_rt286_ops,
@@ -215,6 +333,7 @@ static struct snd_soc_dai_link skylake_rt286_dais[] = {
215 .codec_name = "dmic-codec", 333 .codec_name = "dmic-codec",
216 .codec_dai_name = "dmic-hifi", 334 .codec_dai_name = "dmic-hifi",
217 .platform_name = "0000:00:1f.3", 335 .platform_name = "0000:00:1f.3",
336 .be_hw_params_fixup = skylake_dmic_fixup,
218 .ignore_suspend = 1, 337 .ignore_suspend = 1,
219 .dpcm_capture = 1, 338 .dpcm_capture = 1,
220 .no_pcm = 1, 339 .no_pcm = 1,
@@ -247,6 +366,7 @@ static struct platform_driver skylake_audio = {
247 .probe = skylake_audio_probe, 366 .probe = skylake_audio_probe,
248 .driver = { 367 .driver = {
249 .name = "skl_alc286s_i2s", 368 .name = "skl_alc286s_i2s",
369 .pm = &snd_soc_pm_ops,
250 }, 370 },
251}; 371};
252 372
diff --git a/sound/soc/intel/common/Makefile b/sound/soc/intel/common/Makefile
index d9105584c51f..668fdeee195e 100644
--- a/sound/soc/intel/common/Makefile
+++ b/sound/soc/intel/common/Makefile
@@ -1,11 +1,13 @@
1snd-soc-sst-dsp-objs := sst-dsp.o 1snd-soc-sst-dsp-objs := sst-dsp.o
2snd-soc-sst-acpi-objs := sst-acpi.o 2ifneq ($(CONFIG_SND_SST_IPC_ACPI),)
3snd-soc-sst-acpi-objs := sst-match-acpi.o
4else
5snd-soc-sst-acpi-objs := sst-acpi.o sst-match-acpi.o
6endif
7
3snd-soc-sst-ipc-objs := sst-ipc.o 8snd-soc-sst-ipc-objs := sst-ipc.o
4 9
5ifneq ($(CONFIG_DW_DMAC_CORE),) 10snd-soc-sst-dsp-$(CONFIG_DW_DMAC_CORE) += sst-firmware.o
6snd-soc-sst-dsp-objs += sst-firmware.o
7endif
8 11
9obj-$(CONFIG_SND_SOC_INTEL_SST) += snd-soc-sst-dsp.o snd-soc-sst-ipc.o 12obj-$(CONFIG_SND_SOC_INTEL_SST) += snd-soc-sst-dsp.o snd-soc-sst-ipc.o
10obj-$(CONFIG_SND_SOC_INTEL_SST_ACPI) += snd-soc-sst-acpi.o 13obj-$(CONFIG_SND_SOC_INTEL_SST_ACPI) += snd-soc-sst-acpi.o
11
diff --git a/sound/soc/intel/common/sst-acpi.c b/sound/soc/intel/common/sst-acpi.c
index 67b6d3d52f57..7a85c576dad3 100644
--- a/sound/soc/intel/common/sst-acpi.c
+++ b/sound/soc/intel/common/sst-acpi.c
@@ -21,21 +21,12 @@
21#include <linux/platform_device.h> 21#include <linux/platform_device.h>
22 22
23#include "sst-dsp.h" 23#include "sst-dsp.h"
24#include "sst-acpi.h"
24 25
25#define SST_LPT_DSP_DMA_ADDR_OFFSET 0x0F0000 26#define SST_LPT_DSP_DMA_ADDR_OFFSET 0x0F0000
26#define SST_WPT_DSP_DMA_ADDR_OFFSET 0x0FE000 27#define SST_WPT_DSP_DMA_ADDR_OFFSET 0x0FE000
27#define SST_LPT_DSP_DMA_SIZE (1024 - 1) 28#define SST_LPT_DSP_DMA_SIZE (1024 - 1)
28 29
29/* Descriptor for SST ASoC machine driver */
30struct sst_acpi_mach {
31 /* ACPI ID for the matching machine driver. Audio codec for instance */
32 const u8 id[ACPI_ID_LEN];
33 /* machine driver name */
34 const char *drv_name;
35 /* firmware file name */
36 const char *fw_filename;
37};
38
39/* Descriptor for setting up SST platform data */ 30/* Descriptor for setting up SST platform data */
40struct sst_acpi_desc { 31struct sst_acpi_desc {
41 const char *drv_name; 32 const char *drv_name;
@@ -88,28 +79,6 @@ static void sst_acpi_fw_cb(const struct firmware *fw, void *context)
88 return; 79 return;
89} 80}
90 81
91static acpi_status sst_acpi_mach_match(acpi_handle handle, u32 level,
92 void *context, void **ret)
93{
94 *(bool *)context = true;
95 return AE_OK;
96}
97
98static struct sst_acpi_mach *sst_acpi_find_machine(
99 struct sst_acpi_mach *machines)
100{
101 struct sst_acpi_mach *mach;
102 bool found = false;
103
104 for (mach = machines; mach->id[0]; mach++)
105 if (ACPI_SUCCESS(acpi_get_devices(mach->id,
106 sst_acpi_mach_match,
107 &found, NULL)) && found)
108 return mach;
109
110 return NULL;
111}
112
113static int sst_acpi_probe(struct platform_device *pdev) 82static int sst_acpi_probe(struct platform_device *pdev)
114{ 83{
115 const struct acpi_device_id *id; 84 const struct acpi_device_id *id;
@@ -211,7 +180,7 @@ static int sst_acpi_remove(struct platform_device *pdev)
211} 180}
212 181
213static struct sst_acpi_mach haswell_machines[] = { 182static struct sst_acpi_mach haswell_machines[] = {
214 { "INT33CA", "haswell-audio", "intel/IntcSST1.bin" }, 183 { "INT33CA", "haswell-audio", "intel/IntcSST1.bin", NULL, NULL, NULL },
215 {} 184 {}
216}; 185};
217 186
@@ -229,7 +198,7 @@ static struct sst_acpi_desc sst_acpi_haswell_desc = {
229}; 198};
230 199
231static struct sst_acpi_mach broadwell_machines[] = { 200static struct sst_acpi_mach broadwell_machines[] = {
232 { "INT343A", "broadwell-audio", "intel/IntcSST2.bin" }, 201 { "INT343A", "broadwell-audio", "intel/IntcSST2.bin", NULL, NULL, NULL },
233 {} 202 {}
234}; 203};
235 204
@@ -247,8 +216,8 @@ static struct sst_acpi_desc sst_acpi_broadwell_desc = {
247}; 216};
248 217
249static struct sst_acpi_mach baytrail_machines[] = { 218static struct sst_acpi_mach baytrail_machines[] = {
250 { "10EC5640", "byt-rt5640", "intel/fw_sst_0f28.bin-48kHz_i2s_master" }, 219 { "10EC5640", "byt-rt5640", "intel/fw_sst_0f28.bin-48kHz_i2s_master", NULL, NULL, NULL },
251 { "193C9890", "byt-max98090", "intel/fw_sst_0f28.bin-48kHz_i2s_master" }, 220 { "193C9890", "byt-max98090", "intel/fw_sst_0f28.bin-48kHz_i2s_master", NULL, NULL, NULL },
252 {} 221 {}
253}; 222};
254 223
diff --git a/sound/soc/intel/common/sst-acpi.h b/sound/soc/intel/common/sst-acpi.h
new file mode 100644
index 000000000000..3ee3b7ab5d03
--- /dev/null
+++ b/sound/soc/intel/common/sst-acpi.h
@@ -0,0 +1,33 @@
1/*
2 * Copyright (C) 2013-15, Intel Corporation. All rights reserved.
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License version
6 * 2 as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 */
14
15#include <linux/acpi.h>
16
17/* acpi match */
18struct sst_acpi_mach *sst_acpi_find_machine(struct sst_acpi_mach *machines);
19
20/* Descriptor for SST ASoC machine driver */
21struct sst_acpi_mach {
22 /* ACPI ID for the matching machine driver. Audio codec for instance */
23 const u8 id[ACPI_ID_LEN];
24 /* machine driver name */
25 const char *drv_name;
26 /* firmware file name */
27 const char *fw_filename;
28
29 /* board name */
30 const char *board;
31 void (*machine_quirk)(void);
32 void *pdata;
33};
diff --git a/sound/soc/intel/common/sst-dsp-priv.h b/sound/soc/intel/common/sst-dsp-priv.h
index 2151652d37b7..81aa1ed64201 100644
--- a/sound/soc/intel/common/sst-dsp-priv.h
+++ b/sound/soc/intel/common/sst-dsp-priv.h
@@ -243,7 +243,7 @@ struct sst_mem_block {
243 u32 size; /* block size */ 243 u32 size; /* block size */
244 u32 index; /* block index 0..N */ 244 u32 index; /* block index 0..N */
245 enum sst_mem_type type; /* block memory type IRAM/DRAM */ 245 enum sst_mem_type type; /* block memory type IRAM/DRAM */
246 struct sst_block_ops *ops; /* block operations, if any */ 246 const struct sst_block_ops *ops;/* block operations, if any */
247 247
248 /* block status */ 248 /* block status */
249 u32 bytes_used; /* bytes in use by modules */ 249 u32 bytes_used; /* bytes in use by modules */
@@ -308,6 +308,8 @@ struct sst_dsp {
308 308
309 /* SKL data */ 309 /* SKL data */
310 310
311 const char *fw_name;
312
311 /* To allocate CL dma buffers */ 313 /* To allocate CL dma buffers */
312 struct skl_dsp_loader_ops dsp_ops; 314 struct skl_dsp_loader_ops dsp_ops;
313 struct skl_dsp_fw_ops fw_ops; 315 struct skl_dsp_fw_ops fw_ops;
@@ -376,8 +378,8 @@ void sst_block_free_scratch(struct sst_dsp *dsp);
376 378
377/* Register the DSPs memory blocks - would be nice to read from ACPI */ 379/* Register the DSPs memory blocks - would be nice to read from ACPI */
378struct sst_mem_block *sst_mem_block_register(struct sst_dsp *dsp, u32 offset, 380struct sst_mem_block *sst_mem_block_register(struct sst_dsp *dsp, u32 offset,
379 u32 size, enum sst_mem_type type, struct sst_block_ops *ops, u32 index, 381 u32 size, enum sst_mem_type type, const struct sst_block_ops *ops,
380 void *private); 382 u32 index, void *private);
381void sst_mem_block_unregister_all(struct sst_dsp *dsp); 383void sst_mem_block_unregister_all(struct sst_dsp *dsp);
382 384
383/* Create/Free DMA resources */ 385/* Create/Free DMA resources */
diff --git a/sound/soc/intel/common/sst-dsp.c b/sound/soc/intel/common/sst-dsp.c
index c9452e02e0dd..b5bbdf4fe93a 100644
--- a/sound/soc/intel/common/sst-dsp.c
+++ b/sound/soc/intel/common/sst-dsp.c
@@ -420,7 +420,7 @@ void sst_dsp_inbox_read(struct sst_dsp *sst, void *message, size_t bytes)
420} 420}
421EXPORT_SYMBOL_GPL(sst_dsp_inbox_read); 421EXPORT_SYMBOL_GPL(sst_dsp_inbox_read);
422 422
423#if IS_ENABLED(CONFIG_DW_DMAC_CORE) 423#ifdef CONFIG_DW_DMAC_CORE
424struct sst_dsp *sst_dsp_new(struct device *dev, 424struct sst_dsp *sst_dsp_new(struct device *dev,
425 struct sst_dsp_device *sst_dev, struct sst_pdata *pdata) 425 struct sst_dsp_device *sst_dev, struct sst_pdata *pdata)
426{ 426{
diff --git a/sound/soc/intel/common/sst-dsp.h b/sound/soc/intel/common/sst-dsp.h
index 859f0de00339..0b84c719ec48 100644
--- a/sound/soc/intel/common/sst-dsp.h
+++ b/sound/soc/intel/common/sst-dsp.h
@@ -216,7 +216,7 @@ struct sst_pdata {
216 void *dsp; 216 void *dsp;
217}; 217};
218 218
219#if IS_ENABLED(CONFIG_DW_DMAC_CORE) 219#ifdef CONFIG_DW_DMAC_CORE
220/* Initialization */ 220/* Initialization */
221struct sst_dsp *sst_dsp_new(struct device *dev, 221struct sst_dsp *sst_dsp_new(struct device *dev,
222 struct sst_dsp_device *sst_dev, struct sst_pdata *pdata); 222 struct sst_dsp_device *sst_dev, struct sst_pdata *pdata);
diff --git a/sound/soc/intel/common/sst-firmware.c b/sound/soc/intel/common/sst-firmware.c
index 1636a1eeb002..ef4881e7753a 100644
--- a/sound/soc/intel/common/sst-firmware.c
+++ b/sound/soc/intel/common/sst-firmware.c
@@ -51,8 +51,22 @@ struct sst_dma {
51 51
52static inline void sst_memcpy32(volatile void __iomem *dest, void *src, u32 bytes) 52static inline void sst_memcpy32(volatile void __iomem *dest, void *src, u32 bytes)
53{ 53{
54 u32 tmp = 0;
55 int i, m, n;
56 const u8 *src_byte = src;
57
58 m = bytes / 4;
59 n = bytes % 4;
60
54 /* __iowrite32_copy use 32bit size values so divide by 4 */ 61 /* __iowrite32_copy use 32bit size values so divide by 4 */
55 __iowrite32_copy((void *)dest, src, bytes/4); 62 __iowrite32_copy((void *)dest, src, m);
63
64 if (n) {
65 for (i = 0; i < n; i++)
66 tmp |= (u32)*(src_byte + m * 4 + i) << (i * 8);
67 __iowrite32_copy((void *)(dest + m * 4), &tmp, 1);
68 }
69
56} 70}
57 71
58static void sst_dma_transfer_complete(void *arg) 72static void sst_dma_transfer_complete(void *arg)
@@ -1014,8 +1028,8 @@ EXPORT_SYMBOL_GPL(sst_module_runtime_restore);
1014 1028
1015/* register a DSP memory block for use with FW based modules */ 1029/* register a DSP memory block for use with FW based modules */
1016struct sst_mem_block *sst_mem_block_register(struct sst_dsp *dsp, u32 offset, 1030struct sst_mem_block *sst_mem_block_register(struct sst_dsp *dsp, u32 offset,
1017 u32 size, enum sst_mem_type type, struct sst_block_ops *ops, u32 index, 1031 u32 size, enum sst_mem_type type, const struct sst_block_ops *ops,
1018 void *private) 1032 u32 index, void *private)
1019{ 1033{
1020 struct sst_mem_block *block; 1034 struct sst_mem_block *block;
1021 1035
diff --git a/sound/soc/intel/common/sst-match-acpi.c b/sound/soc/intel/common/sst-match-acpi.c
new file mode 100644
index 000000000000..dd077e116d25
--- /dev/null
+++ b/sound/soc/intel/common/sst-match-acpi.c
@@ -0,0 +1,43 @@
1/*
2 * sst_match_apci.c - SST (LPE) match for ACPI enumeration.
3 *
4 * Copyright (c) 2013-15, Intel Corporation.
5 *
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms and conditions of the GNU General Public License,
9 * version 2, as published by the Free Software Foundation.
10 *
11 * This program is distributed in the hope it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14 * more details.
15 */
16#include <linux/acpi.h>
17#include <linux/device.h>
18#include <linux/module.h>
19#include <linux/platform_device.h>
20
21#include "sst-acpi.h"
22
23static acpi_status sst_acpi_mach_match(acpi_handle handle, u32 level,
24 void *context, void **ret)
25{
26 *(bool *)context = true;
27 return AE_OK;
28}
29
30struct sst_acpi_mach *sst_acpi_find_machine(struct sst_acpi_mach *machines)
31{
32 struct sst_acpi_mach *mach;
33 bool found = false;
34
35 for (mach = machines; mach->id[0]; mach++)
36 if (ACPI_SUCCESS(acpi_get_devices(mach->id,
37 sst_acpi_mach_match,
38 &found, NULL)) && found)
39 return mach;
40
41 return NULL;
42}
43EXPORT_SYMBOL_GPL(sst_acpi_find_machine);
diff --git a/sound/soc/intel/haswell/sst-haswell-dsp.c b/sound/soc/intel/haswell/sst-haswell-dsp.c
index 7f94920c8a4d..b2bec36d074c 100644
--- a/sound/soc/intel/haswell/sst-haswell-dsp.c
+++ b/sound/soc/intel/haswell/sst-haswell-dsp.c
@@ -607,7 +607,7 @@ static int hsw_block_disable(struct sst_mem_block *block)
607 return 0; 607 return 0;
608} 608}
609 609
610static struct sst_block_ops sst_hsw_ops = { 610static const struct sst_block_ops sst_hsw_ops = {
611 .enable = hsw_block_enable, 611 .enable = hsw_block_enable,
612 .disable = hsw_block_disable, 612 .disable = hsw_block_disable,
613}; 613};
diff --git a/sound/soc/intel/haswell/sst-haswell-ipc.c b/sound/soc/intel/haswell/sst-haswell-ipc.c
index b27f25f70730..ac60f1301e21 100644
--- a/sound/soc/intel/haswell/sst-haswell-ipc.c
+++ b/sound/soc/intel/haswell/sst-haswell-ipc.c
@@ -778,7 +778,6 @@ static irqreturn_t hsw_irq_thread(int irq, void *context)
778 struct sst_hsw *hsw = sst_dsp_get_thread_context(sst); 778 struct sst_hsw *hsw = sst_dsp_get_thread_context(sst);
779 struct sst_generic_ipc *ipc = &hsw->ipc; 779 struct sst_generic_ipc *ipc = &hsw->ipc;
780 u32 ipcx, ipcd; 780 u32 ipcx, ipcd;
781 int handled;
782 unsigned long flags; 781 unsigned long flags;
783 782
784 spin_lock_irqsave(&sst->spinlock, flags); 783 spin_lock_irqsave(&sst->spinlock, flags);
@@ -790,34 +789,30 @@ static irqreturn_t hsw_irq_thread(int irq, void *context)
790 if (ipcx & SST_IPCX_DONE) { 789 if (ipcx & SST_IPCX_DONE) {
791 790
792 /* Handle Immediate reply from DSP Core */ 791 /* Handle Immediate reply from DSP Core */
793 handled = hsw_process_reply(hsw, ipcx); 792 hsw_process_reply(hsw, ipcx);
794 793
795 if (handled > 0) { 794 /* clear DONE bit - tell DSP we have completed */
796 /* clear DONE bit - tell DSP we have completed */ 795 sst_dsp_shim_update_bits_unlocked(sst, SST_IPCX,
797 sst_dsp_shim_update_bits_unlocked(sst, SST_IPCX, 796 SST_IPCX_DONE, 0);
798 SST_IPCX_DONE, 0);
799 797
800 /* unmask Done interrupt */ 798 /* unmask Done interrupt */
801 sst_dsp_shim_update_bits_unlocked(sst, SST_IMRX, 799 sst_dsp_shim_update_bits_unlocked(sst, SST_IMRX,
802 SST_IMRX_DONE, 0); 800 SST_IMRX_DONE, 0);
803 }
804 } 801 }
805 802
806 /* new message from DSP */ 803 /* new message from DSP */
807 if (ipcd & SST_IPCD_BUSY) { 804 if (ipcd & SST_IPCD_BUSY) {
808 805
809 /* Handle Notification and Delayed reply from DSP Core */ 806 /* Handle Notification and Delayed reply from DSP Core */
810 handled = hsw_process_notification(hsw); 807 hsw_process_notification(hsw);
811 808
812 /* clear BUSY bit and set DONE bit - accept new messages */ 809 /* clear BUSY bit and set DONE bit - accept new messages */
813 if (handled > 0) { 810 sst_dsp_shim_update_bits_unlocked(sst, SST_IPCD,
814 sst_dsp_shim_update_bits_unlocked(sst, SST_IPCD, 811 SST_IPCD_BUSY | SST_IPCD_DONE, SST_IPCD_DONE);
815 SST_IPCD_BUSY | SST_IPCD_DONE, SST_IPCD_DONE);
816 812
817 /* unmask busy interrupt */ 813 /* unmask busy interrupt */
818 sst_dsp_shim_update_bits_unlocked(sst, SST_IMRX, 814 sst_dsp_shim_update_bits_unlocked(sst, SST_IMRX,
819 SST_IMRX_BUSY, 0); 815 SST_IMRX_BUSY, 0);
820 }
821 } 816 }
822 817
823 spin_unlock_irqrestore(&sst->spinlock, flags); 818 spin_unlock_irqrestore(&sst->spinlock, flags);
diff --git a/sound/soc/intel/skylake/skl-messages.c b/sound/soc/intel/skylake/skl-messages.c
index 50a109503a3f..de6dac496a0d 100644
--- a/sound/soc/intel/skylake/skl-messages.c
+++ b/sound/soc/intel/skylake/skl-messages.c
@@ -96,7 +96,7 @@ int skl_init_dsp(struct skl *skl)
96 } 96 }
97 97
98 ret = skl_sst_dsp_init(bus->dev, mmio_base, irq, 98 ret = skl_sst_dsp_init(bus->dev, mmio_base, irq,
99 loader_ops, &skl->skl_sst); 99 skl->fw_name, loader_ops, &skl->skl_sst);
100 if (ret < 0) 100 if (ret < 0)
101 return ret; 101 return ret;
102 102
@@ -182,94 +182,6 @@ enum skl_bitdepth skl_get_bit_depth(int params)
182 } 182 }
183} 183}
184 184
185static u32 skl_create_channel_map(enum skl_ch_cfg ch_cfg)
186{
187 u32 config;
188
189 switch (ch_cfg) {
190 case SKL_CH_CFG_MONO:
191 config = (0xFFFFFFF0 | SKL_CHANNEL_LEFT);
192 break;
193
194 case SKL_CH_CFG_STEREO:
195 config = (0xFFFFFF00 | SKL_CHANNEL_LEFT
196 | (SKL_CHANNEL_RIGHT << 4));
197 break;
198
199 case SKL_CH_CFG_2_1:
200 config = (0xFFFFF000 | SKL_CHANNEL_LEFT
201 | (SKL_CHANNEL_RIGHT << 4)
202 | (SKL_CHANNEL_LFE << 8));
203 break;
204
205 case SKL_CH_CFG_3_0:
206 config = (0xFFFFF000 | SKL_CHANNEL_LEFT
207 | (SKL_CHANNEL_CENTER << 4)
208 | (SKL_CHANNEL_RIGHT << 8));
209 break;
210
211 case SKL_CH_CFG_3_1:
212 config = (0xFFFF0000 | SKL_CHANNEL_LEFT
213 | (SKL_CHANNEL_CENTER << 4)
214 | (SKL_CHANNEL_RIGHT << 8)
215 | (SKL_CHANNEL_LFE << 12));
216 break;
217
218 case SKL_CH_CFG_QUATRO:
219 config = (0xFFFF0000 | SKL_CHANNEL_LEFT
220 | (SKL_CHANNEL_RIGHT << 4)
221 | (SKL_CHANNEL_LEFT_SURROUND << 8)
222 | (SKL_CHANNEL_RIGHT_SURROUND << 12));
223 break;
224
225 case SKL_CH_CFG_4_0:
226 config = (0xFFFF0000 | SKL_CHANNEL_LEFT
227 | (SKL_CHANNEL_CENTER << 4)
228 | (SKL_CHANNEL_RIGHT << 8)
229 | (SKL_CHANNEL_CENTER_SURROUND << 12));
230 break;
231
232 case SKL_CH_CFG_5_0:
233 config = (0xFFF00000 | SKL_CHANNEL_LEFT
234 | (SKL_CHANNEL_CENTER << 4)
235 | (SKL_CHANNEL_RIGHT << 8)
236 | (SKL_CHANNEL_LEFT_SURROUND << 12)
237 | (SKL_CHANNEL_RIGHT_SURROUND << 16));
238 break;
239
240 case SKL_CH_CFG_5_1:
241 config = (0xFF000000 | SKL_CHANNEL_CENTER
242 | (SKL_CHANNEL_LEFT << 4)
243 | (SKL_CHANNEL_RIGHT << 8)
244 | (SKL_CHANNEL_LEFT_SURROUND << 12)
245 | (SKL_CHANNEL_RIGHT_SURROUND << 16)
246 | (SKL_CHANNEL_LFE << 20));
247 break;
248
249 case SKL_CH_CFG_DUAL_MONO:
250 config = (0xFFFFFF00 | SKL_CHANNEL_LEFT
251 | (SKL_CHANNEL_LEFT << 4));
252 break;
253
254 case SKL_CH_CFG_I2S_DUAL_STEREO_0:
255 config = (0xFFFFFF00 | SKL_CHANNEL_LEFT
256 | (SKL_CHANNEL_RIGHT << 4));
257 break;
258
259 case SKL_CH_CFG_I2S_DUAL_STEREO_1:
260 config = (0xFFFF00FF | (SKL_CHANNEL_LEFT << 8)
261 | (SKL_CHANNEL_RIGHT << 12));
262 break;
263
264 default:
265 config = 0xFFFFFFFF;
266 break;
267
268 }
269
270 return config;
271}
272
273/* 185/*
274 * Each module in DSP expects a base module configuration, which consists of 186 * Each module in DSP expects a base module configuration, which consists of
275 * PCM format information, which we calculate in driver and resource values 187 * PCM format information, which we calculate in driver and resource values
@@ -280,7 +192,7 @@ static void skl_set_base_module_format(struct skl_sst *ctx,
280 struct skl_module_cfg *mconfig, 192 struct skl_module_cfg *mconfig,
281 struct skl_base_cfg *base_cfg) 193 struct skl_base_cfg *base_cfg)
282{ 194{
283 struct skl_module_fmt *format = &mconfig->in_fmt; 195 struct skl_module_fmt *format = &mconfig->in_fmt[0];
284 196
285 base_cfg->audio_fmt.number_of_channels = (u8)format->channels; 197 base_cfg->audio_fmt.number_of_channels = (u8)format->channels;
286 198
@@ -293,14 +205,14 @@ static void skl_set_base_module_format(struct skl_sst *ctx,
293 format->bit_depth, format->valid_bit_depth, 205 format->bit_depth, format->valid_bit_depth,
294 format->ch_cfg); 206 format->ch_cfg);
295 207
296 base_cfg->audio_fmt.channel_map = skl_create_channel_map( 208 base_cfg->audio_fmt.channel_map = format->ch_map;
297 base_cfg->audio_fmt.ch_cfg);
298 209
299 base_cfg->audio_fmt.interleaving = SKL_INTERLEAVING_PER_CHANNEL; 210 base_cfg->audio_fmt.interleaving = format->interleaving_style;
300 211
301 base_cfg->cps = mconfig->mcps; 212 base_cfg->cps = mconfig->mcps;
302 base_cfg->ibs = mconfig->ibs; 213 base_cfg->ibs = mconfig->ibs;
303 base_cfg->obs = mconfig->obs; 214 base_cfg->obs = mconfig->obs;
215 base_cfg->is_pages = mconfig->mem_pages;
304} 216}
305 217
306/* 218/*
@@ -399,7 +311,7 @@ static void skl_setup_out_format(struct skl_sst *ctx,
399 struct skl_module_cfg *mconfig, 311 struct skl_module_cfg *mconfig,
400 struct skl_audio_data_format *out_fmt) 312 struct skl_audio_data_format *out_fmt)
401{ 313{
402 struct skl_module_fmt *format = &mconfig->out_fmt; 314 struct skl_module_fmt *format = &mconfig->out_fmt[0];
403 315
404 out_fmt->number_of_channels = (u8)format->channels; 316 out_fmt->number_of_channels = (u8)format->channels;
405 out_fmt->s_freq = format->s_freq; 317 out_fmt->s_freq = format->s_freq;
@@ -407,8 +319,9 @@ static void skl_setup_out_format(struct skl_sst *ctx,
407 out_fmt->valid_bit_depth = format->valid_bit_depth; 319 out_fmt->valid_bit_depth = format->valid_bit_depth;
408 out_fmt->ch_cfg = format->ch_cfg; 320 out_fmt->ch_cfg = format->ch_cfg;
409 321
410 out_fmt->channel_map = skl_create_channel_map(out_fmt->ch_cfg); 322 out_fmt->channel_map = format->ch_map;
411 out_fmt->interleaving = SKL_INTERLEAVING_PER_CHANNEL; 323 out_fmt->interleaving = format->interleaving_style;
324 out_fmt->sample_type = format->sample_type;
412 325
413 dev_dbg(ctx->dev, "copier out format chan=%d fre=%d bitdepth=%d\n", 326 dev_dbg(ctx->dev, "copier out format chan=%d fre=%d bitdepth=%d\n",
414 out_fmt->number_of_channels, format->s_freq, format->bit_depth); 327 out_fmt->number_of_channels, format->s_freq, format->bit_depth);
@@ -423,7 +336,7 @@ static void skl_set_src_format(struct skl_sst *ctx,
423 struct skl_module_cfg *mconfig, 336 struct skl_module_cfg *mconfig,
424 struct skl_src_module_cfg *src_mconfig) 337 struct skl_src_module_cfg *src_mconfig)
425{ 338{
426 struct skl_module_fmt *fmt = &mconfig->out_fmt; 339 struct skl_module_fmt *fmt = &mconfig->out_fmt[0];
427 340
428 skl_set_base_module_format(ctx, mconfig, 341 skl_set_base_module_format(ctx, mconfig,
429 (struct skl_base_cfg *)src_mconfig); 342 (struct skl_base_cfg *)src_mconfig);
@@ -440,7 +353,7 @@ static void skl_set_updown_mixer_format(struct skl_sst *ctx,
440 struct skl_module_cfg *mconfig, 353 struct skl_module_cfg *mconfig,
441 struct skl_up_down_mixer_cfg *mixer_mconfig) 354 struct skl_up_down_mixer_cfg *mixer_mconfig)
442{ 355{
443 struct skl_module_fmt *fmt = &mconfig->out_fmt; 356 struct skl_module_fmt *fmt = &mconfig->out_fmt[0];
444 int i = 0; 357 int i = 0;
445 358
446 skl_set_base_module_format(ctx, mconfig, 359 skl_set_base_module_format(ctx, mconfig,
@@ -475,6 +388,47 @@ static void skl_set_copier_format(struct skl_sst *ctx,
475 skl_setup_cpr_gateway_cfg(ctx, mconfig, cpr_mconfig); 388 skl_setup_cpr_gateway_cfg(ctx, mconfig, cpr_mconfig);
476} 389}
477 390
391/*
392 * Algo module are DSP pre processing modules. Algo module take base module
393 * configuration and params
394 */
395
396static void skl_set_algo_format(struct skl_sst *ctx,
397 struct skl_module_cfg *mconfig,
398 struct skl_algo_cfg *algo_mcfg)
399{
400 struct skl_base_cfg *base_cfg = (struct skl_base_cfg *)algo_mcfg;
401
402 skl_set_base_module_format(ctx, mconfig, base_cfg);
403
404 if (mconfig->formats_config.caps_size == 0)
405 return;
406
407 memcpy(algo_mcfg->params,
408 mconfig->formats_config.caps,
409 mconfig->formats_config.caps_size);
410
411}
412
413/*
414 * Mic select module allows selecting one or many input channels, thus
415 * acting as a demux.
416 *
417 * Mic select module take base module configuration and out-format
418 * configuration
419 */
420static void skl_set_base_outfmt_format(struct skl_sst *ctx,
421 struct skl_module_cfg *mconfig,
422 struct skl_base_outfmt_cfg *base_outfmt_mcfg)
423{
424 struct skl_audio_data_format *out_fmt = &base_outfmt_mcfg->out_fmt;
425 struct skl_base_cfg *base_cfg =
426 (struct skl_base_cfg *)base_outfmt_mcfg;
427
428 skl_set_base_module_format(ctx, mconfig, base_cfg);
429 skl_setup_out_format(ctx, mconfig, out_fmt);
430}
431
478static u16 skl_get_module_param_size(struct skl_sst *ctx, 432static u16 skl_get_module_param_size(struct skl_sst *ctx,
479 struct skl_module_cfg *mconfig) 433 struct skl_module_cfg *mconfig)
480{ 434{
@@ -492,6 +446,14 @@ static u16 skl_get_module_param_size(struct skl_sst *ctx,
492 case SKL_MODULE_TYPE_UPDWMIX: 446 case SKL_MODULE_TYPE_UPDWMIX:
493 return sizeof(struct skl_up_down_mixer_cfg); 447 return sizeof(struct skl_up_down_mixer_cfg);
494 448
449 case SKL_MODULE_TYPE_ALGO:
450 param_size = sizeof(struct skl_base_cfg);
451 param_size += mconfig->formats_config.caps_size;
452 return param_size;
453
454 case SKL_MODULE_TYPE_BASE_OUTFMT:
455 return sizeof(struct skl_base_outfmt_cfg);
456
495 default: 457 default:
496 /* 458 /*
497 * return only base cfg when no specific module type is 459 * return only base cfg when no specific module type is
@@ -538,6 +500,14 @@ static int skl_set_module_format(struct skl_sst *ctx,
538 skl_set_updown_mixer_format(ctx, module_config, *param_data); 500 skl_set_updown_mixer_format(ctx, module_config, *param_data);
539 break; 501 break;
540 502
503 case SKL_MODULE_TYPE_ALGO:
504 skl_set_algo_format(ctx, module_config, *param_data);
505 break;
506
507 case SKL_MODULE_TYPE_BASE_OUTFMT:
508 skl_set_base_outfmt_format(ctx, module_config, *param_data);
509 break;
510
541 default: 511 default:
542 skl_set_base_module_format(ctx, module_config, *param_data); 512 skl_set_base_module_format(ctx, module_config, *param_data);
543 break; 513 break;
@@ -571,10 +541,10 @@ static int skl_get_queue_index(struct skl_module_pin *mpin,
571 * In static, the pin_index is fixed based on module_id and instance id 541 * In static, the pin_index is fixed based on module_id and instance id
572 */ 542 */
573static int skl_alloc_queue(struct skl_module_pin *mpin, 543static int skl_alloc_queue(struct skl_module_pin *mpin,
574 struct skl_module_inst_id id, int max) 544 struct skl_module_cfg *tgt_cfg, int max)
575{ 545{
576 int i; 546 int i;
577 547 struct skl_module_inst_id id = tgt_cfg->id;
578 /* 548 /*
579 * if pin in dynamic, find first free pin 549 * if pin in dynamic, find first free pin
580 * otherwise find match module and instance id pin as topology will 550 * otherwise find match module and instance id pin as topology will
@@ -583,16 +553,23 @@ static int skl_alloc_queue(struct skl_module_pin *mpin,
583 */ 553 */
584 for (i = 0; i < max; i++) { 554 for (i = 0; i < max; i++) {
585 if (mpin[i].is_dynamic) { 555 if (mpin[i].is_dynamic) {
586 if (!mpin[i].in_use) { 556 if (!mpin[i].in_use &&
557 mpin[i].pin_state == SKL_PIN_UNBIND) {
558
587 mpin[i].in_use = true; 559 mpin[i].in_use = true;
588 mpin[i].id.module_id = id.module_id; 560 mpin[i].id.module_id = id.module_id;
589 mpin[i].id.instance_id = id.instance_id; 561 mpin[i].id.instance_id = id.instance_id;
562 mpin[i].tgt_mcfg = tgt_cfg;
590 return i; 563 return i;
591 } 564 }
592 } else { 565 } else {
593 if (mpin[i].id.module_id == id.module_id && 566 if (mpin[i].id.module_id == id.module_id &&
594 mpin[i].id.instance_id == id.instance_id) 567 mpin[i].id.instance_id == id.instance_id &&
568 mpin[i].pin_state == SKL_PIN_UNBIND) {
569
570 mpin[i].tgt_mcfg = tgt_cfg;
595 return i; 571 return i;
572 }
596 } 573 }
597 } 574 }
598 575
@@ -606,6 +583,28 @@ static void skl_free_queue(struct skl_module_pin *mpin, int q_index)
606 mpin[q_index].id.module_id = 0; 583 mpin[q_index].id.module_id = 0;
607 mpin[q_index].id.instance_id = 0; 584 mpin[q_index].id.instance_id = 0;
608 } 585 }
586 mpin[q_index].pin_state = SKL_PIN_UNBIND;
587 mpin[q_index].tgt_mcfg = NULL;
588}
589
590/* Module state will be set to unint, if all the out pin state is UNBIND */
591
592static void skl_clear_module_state(struct skl_module_pin *mpin, int max,
593 struct skl_module_cfg *mcfg)
594{
595 int i;
596 bool found = false;
597
598 for (i = 0; i < max; i++) {
599 if (mpin[i].pin_state == SKL_PIN_UNBIND)
600 continue;
601 found = true;
602 break;
603 }
604
605 if (!found)
606 mcfg->m_state = SKL_MODULE_UNINIT;
607 return;
609} 608}
610 609
611/* 610/*
@@ -615,7 +614,7 @@ static void skl_free_queue(struct skl_module_pin *mpin, int q_index)
615 * invoke the DSP by sending IPC INIT_INSTANCE using ipc helper 614 * invoke the DSP by sending IPC INIT_INSTANCE using ipc helper
616 */ 615 */
617int skl_init_module(struct skl_sst *ctx, 616int skl_init_module(struct skl_sst *ctx,
618 struct skl_module_cfg *mconfig, char *param) 617 struct skl_module_cfg *mconfig)
619{ 618{
620 u16 module_config_size = 0; 619 u16 module_config_size = 0;
621 void *param_data = NULL; 620 void *param_data = NULL;
@@ -682,37 +681,30 @@ int skl_unbind_modules(struct skl_sst *ctx,
682 struct skl_module_inst_id dst_id = dst_mcfg->id; 681 struct skl_module_inst_id dst_id = dst_mcfg->id;
683 int in_max = dst_mcfg->max_in_queue; 682 int in_max = dst_mcfg->max_in_queue;
684 int out_max = src_mcfg->max_out_queue; 683 int out_max = src_mcfg->max_out_queue;
685 int src_index, dst_index; 684 int src_index, dst_index, src_pin_state, dst_pin_state;
686 685
687 skl_dump_bind_info(ctx, src_mcfg, dst_mcfg); 686 skl_dump_bind_info(ctx, src_mcfg, dst_mcfg);
688 687
689 if (src_mcfg->m_state != SKL_MODULE_BIND_DONE)
690 return 0;
691
692 /*
693 * if intra module unbind, check if both modules are BIND,
694 * then send unbind
695 */
696 if ((src_mcfg->pipe->ppl_id != dst_mcfg->pipe->ppl_id) &&
697 dst_mcfg->m_state != SKL_MODULE_BIND_DONE)
698 return 0;
699 else if (src_mcfg->m_state < SKL_MODULE_INIT_DONE &&
700 dst_mcfg->m_state < SKL_MODULE_INIT_DONE)
701 return 0;
702
703 /* get src queue index */ 688 /* get src queue index */
704 src_index = skl_get_queue_index(src_mcfg->m_out_pin, dst_id, out_max); 689 src_index = skl_get_queue_index(src_mcfg->m_out_pin, dst_id, out_max);
705 if (src_index < 0) 690 if (src_index < 0)
706 return -EINVAL; 691 return -EINVAL;
707 692
708 msg.src_queue = src_mcfg->m_out_pin[src_index].pin_index; 693 msg.src_queue = src_index;
709 694
710 /* get dst queue index */ 695 /* get dst queue index */
711 dst_index = skl_get_queue_index(dst_mcfg->m_in_pin, src_id, in_max); 696 dst_index = skl_get_queue_index(dst_mcfg->m_in_pin, src_id, in_max);
712 if (dst_index < 0) 697 if (dst_index < 0)
713 return -EINVAL; 698 return -EINVAL;
714 699
715 msg.dst_queue = dst_mcfg->m_in_pin[dst_index].pin_index; 700 msg.dst_queue = dst_index;
701
702 src_pin_state = src_mcfg->m_out_pin[src_index].pin_state;
703 dst_pin_state = dst_mcfg->m_in_pin[dst_index].pin_state;
704
705 if (src_pin_state != SKL_PIN_BIND_DONE ||
706 dst_pin_state != SKL_PIN_BIND_DONE)
707 return 0;
716 708
717 msg.module_id = src_mcfg->id.module_id; 709 msg.module_id = src_mcfg->id.module_id;
718 msg.instance_id = src_mcfg->id.instance_id; 710 msg.instance_id = src_mcfg->id.instance_id;
@@ -722,10 +714,15 @@ int skl_unbind_modules(struct skl_sst *ctx,
722 714
723 ret = skl_ipc_bind_unbind(&ctx->ipc, &msg); 715 ret = skl_ipc_bind_unbind(&ctx->ipc, &msg);
724 if (!ret) { 716 if (!ret) {
725 src_mcfg->m_state = SKL_MODULE_UNINIT;
726 /* free queue only if unbind is success */ 717 /* free queue only if unbind is success */
727 skl_free_queue(src_mcfg->m_out_pin, src_index); 718 skl_free_queue(src_mcfg->m_out_pin, src_index);
728 skl_free_queue(dst_mcfg->m_in_pin, dst_index); 719 skl_free_queue(dst_mcfg->m_in_pin, dst_index);
720
721 /*
722 * check only if src module bind state, bind is
723 * always from src -> sink
724 */
725 skl_clear_module_state(src_mcfg->m_out_pin, out_max, src_mcfg);
729 } 726 }
730 727
731 return ret; 728 return ret;
@@ -744,8 +741,6 @@ int skl_bind_modules(struct skl_sst *ctx,
744{ 741{
745 int ret; 742 int ret;
746 struct skl_ipc_bind_unbind_msg msg; 743 struct skl_ipc_bind_unbind_msg msg;
747 struct skl_module_inst_id src_id = src_mcfg->id;
748 struct skl_module_inst_id dst_id = dst_mcfg->id;
749 int in_max = dst_mcfg->max_in_queue; 744 int in_max = dst_mcfg->max_in_queue;
750 int out_max = src_mcfg->max_out_queue; 745 int out_max = src_mcfg->max_out_queue;
751 int src_index, dst_index; 746 int src_index, dst_index;
@@ -756,18 +751,18 @@ int skl_bind_modules(struct skl_sst *ctx,
756 dst_mcfg->m_state < SKL_MODULE_INIT_DONE) 751 dst_mcfg->m_state < SKL_MODULE_INIT_DONE)
757 return 0; 752 return 0;
758 753
759 src_index = skl_alloc_queue(src_mcfg->m_out_pin, dst_id, out_max); 754 src_index = skl_alloc_queue(src_mcfg->m_out_pin, dst_mcfg, out_max);
760 if (src_index < 0) 755 if (src_index < 0)
761 return -EINVAL; 756 return -EINVAL;
762 757
763 msg.src_queue = src_mcfg->m_out_pin[src_index].pin_index; 758 msg.src_queue = src_index;
764 dst_index = skl_alloc_queue(dst_mcfg->m_in_pin, src_id, in_max); 759 dst_index = skl_alloc_queue(dst_mcfg->m_in_pin, src_mcfg, in_max);
765 if (dst_index < 0) { 760 if (dst_index < 0) {
766 skl_free_queue(src_mcfg->m_out_pin, src_index); 761 skl_free_queue(src_mcfg->m_out_pin, src_index);
767 return -EINVAL; 762 return -EINVAL;
768 } 763 }
769 764
770 msg.dst_queue = dst_mcfg->m_in_pin[dst_index].pin_index; 765 msg.dst_queue = dst_index;
771 766
772 dev_dbg(ctx->dev, "src queue = %d dst queue =%d\n", 767 dev_dbg(ctx->dev, "src queue = %d dst queue =%d\n",
773 msg.src_queue, msg.dst_queue); 768 msg.src_queue, msg.dst_queue);
@@ -782,6 +777,8 @@ int skl_bind_modules(struct skl_sst *ctx,
782 777
783 if (!ret) { 778 if (!ret) {
784 src_mcfg->m_state = SKL_MODULE_BIND_DONE; 779 src_mcfg->m_state = SKL_MODULE_BIND_DONE;
780 src_mcfg->m_out_pin[src_index].pin_state = SKL_PIN_BIND_DONE;
781 dst_mcfg->m_in_pin[dst_index].pin_state = SKL_PIN_BIND_DONE;
785 } else { 782 } else {
786 /* error case , if IPC fails, clear the queue index */ 783 /* error case , if IPC fails, clear the queue index */
787 skl_free_queue(src_mcfg->m_out_pin, src_index); 784 skl_free_queue(src_mcfg->m_out_pin, src_index);
@@ -852,6 +849,8 @@ int skl_delete_pipe(struct skl_sst *ctx, struct skl_pipe *pipe)
852 ret = skl_ipc_delete_pipeline(&ctx->ipc, pipe->ppl_id); 849 ret = skl_ipc_delete_pipeline(&ctx->ipc, pipe->ppl_id);
853 if (ret < 0) 850 if (ret < 0)
854 dev_err(ctx->dev, "Failed to delete pipeline\n"); 851 dev_err(ctx->dev, "Failed to delete pipeline\n");
852
853 pipe->state = SKL_PIPE_INVALID;
855 } 854 }
856 855
857 return ret; 856 return ret;
@@ -916,3 +915,30 @@ int skl_stop_pipe(struct skl_sst *ctx, struct skl_pipe *pipe)
916 915
917 return 0; 916 return 0;
918} 917}
918
919/* Algo parameter set helper function */
920int skl_set_module_params(struct skl_sst *ctx, u32 *params, int size,
921 u32 param_id, struct skl_module_cfg *mcfg)
922{
923 struct skl_ipc_large_config_msg msg;
924
925 msg.module_id = mcfg->id.module_id;
926 msg.instance_id = mcfg->id.instance_id;
927 msg.param_data_size = size;
928 msg.large_param_id = param_id;
929
930 return skl_ipc_set_large_config(&ctx->ipc, &msg, params);
931}
932
933int skl_get_module_params(struct skl_sst *ctx, u32 *params, int size,
934 u32 param_id, struct skl_module_cfg *mcfg)
935{
936 struct skl_ipc_large_config_msg msg;
937
938 msg.module_id = mcfg->id.module_id;
939 msg.instance_id = mcfg->id.instance_id;
940 msg.param_data_size = size;
941 msg.large_param_id = param_id;
942
943 return skl_ipc_get_large_config(&ctx->ipc, &msg, params);
944}
diff --git a/sound/soc/intel/skylake/skl-nhlt.c b/sound/soc/intel/skylake/skl-nhlt.c
index b0c7bd113aac..6e4b21cdb1bd 100644
--- a/sound/soc/intel/skylake/skl-nhlt.c
+++ b/sound/soc/intel/skylake/skl-nhlt.c
@@ -55,7 +55,7 @@ void skl_nhlt_free(void *addr)
55 55
56static struct nhlt_specific_cfg *skl_get_specific_cfg( 56static struct nhlt_specific_cfg *skl_get_specific_cfg(
57 struct device *dev, struct nhlt_fmt *fmt, 57 struct device *dev, struct nhlt_fmt *fmt,
58 u8 no_ch, u32 rate, u16 bps) 58 u8 no_ch, u32 rate, u16 bps, u8 linktype)
59{ 59{
60 struct nhlt_specific_cfg *sp_config; 60 struct nhlt_specific_cfg *sp_config;
61 struct wav_fmt *wfmt; 61 struct wav_fmt *wfmt;
@@ -68,11 +68,17 @@ static struct nhlt_specific_cfg *skl_get_specific_cfg(
68 wfmt = &fmt_config->fmt_ext.fmt; 68 wfmt = &fmt_config->fmt_ext.fmt;
69 dev_dbg(dev, "ch=%d fmt=%d s_rate=%d\n", wfmt->channels, 69 dev_dbg(dev, "ch=%d fmt=%d s_rate=%d\n", wfmt->channels,
70 wfmt->bits_per_sample, wfmt->samples_per_sec); 70 wfmt->bits_per_sample, wfmt->samples_per_sec);
71 if (wfmt->channels == no_ch && wfmt->samples_per_sec == rate && 71 if (wfmt->channels == no_ch && wfmt->bits_per_sample == bps) {
72 wfmt->bits_per_sample == bps) { 72 /*
73 * if link type is dmic ignore rate check as the blob is
74 * generic for all rates
75 */
73 sp_config = &fmt_config->config; 76 sp_config = &fmt_config->config;
77 if (linktype == NHLT_LINK_DMIC)
78 return sp_config;
74 79
75 return sp_config; 80 if (wfmt->samples_per_sec == rate)
81 return sp_config;
76 } 82 }
77 83
78 fmt_config = (struct nhlt_fmt_cfg *)(fmt_config->config.caps + 84 fmt_config = (struct nhlt_fmt_cfg *)(fmt_config->config.caps +
@@ -115,7 +121,7 @@ struct nhlt_specific_cfg
115 struct device *dev = bus->dev; 121 struct device *dev = bus->dev;
116 struct nhlt_specific_cfg *sp_config; 122 struct nhlt_specific_cfg *sp_config;
117 struct nhlt_acpi_table *nhlt = (struct nhlt_acpi_table *)skl->nhlt; 123 struct nhlt_acpi_table *nhlt = (struct nhlt_acpi_table *)skl->nhlt;
118 u16 bps = num_ch * s_fmt; 124 u16 bps = (s_fmt == 16) ? 16 : 32;
119 u8 j; 125 u8 j;
120 126
121 dump_config(dev, instance, link_type, s_fmt, num_ch, s_rate, dirn, bps); 127 dump_config(dev, instance, link_type, s_fmt, num_ch, s_rate, dirn, bps);
@@ -128,7 +134,8 @@ struct nhlt_specific_cfg
128 if (skl_check_ep_match(dev, epnt, instance, link_type, dirn)) { 134 if (skl_check_ep_match(dev, epnt, instance, link_type, dirn)) {
129 fmt = (struct nhlt_fmt *)(epnt->config.caps + 135 fmt = (struct nhlt_fmt *)(epnt->config.caps +
130 epnt->config.size); 136 epnt->config.size);
131 sp_config = skl_get_specific_cfg(dev, fmt, num_ch, s_rate, bps); 137 sp_config = skl_get_specific_cfg(dev, fmt, num_ch,
138 s_rate, bps, link_type);
132 if (sp_config) 139 if (sp_config)
133 return sp_config; 140 return sp_config;
134 } 141 }
diff --git a/sound/soc/intel/skylake/skl-pcm.c b/sound/soc/intel/skylake/skl-pcm.c
index a2f94ce1679d..f3553258091a 100644
--- a/sound/soc/intel/skylake/skl-pcm.c
+++ b/sound/soc/intel/skylake/skl-pcm.c
@@ -25,9 +25,12 @@
25#include <sound/soc.h> 25#include <sound/soc.h>
26#include "skl.h" 26#include "skl.h"
27#include "skl-topology.h" 27#include "skl-topology.h"
28#include "skl-sst-dsp.h"
29#include "skl-sst-ipc.h"
28 30
29#define HDA_MONO 1 31#define HDA_MONO 1
30#define HDA_STEREO 2 32#define HDA_STEREO 2
33#define HDA_QUAD 4
31 34
32static struct snd_pcm_hardware azx_pcm_hw = { 35static struct snd_pcm_hardware azx_pcm_hw = {
33 .info = (SNDRV_PCM_INFO_MMAP | 36 .info = (SNDRV_PCM_INFO_MMAP |
@@ -35,16 +38,20 @@ static struct snd_pcm_hardware azx_pcm_hw = {
35 SNDRV_PCM_INFO_BLOCK_TRANSFER | 38 SNDRV_PCM_INFO_BLOCK_TRANSFER |
36 SNDRV_PCM_INFO_MMAP_VALID | 39 SNDRV_PCM_INFO_MMAP_VALID |
37 SNDRV_PCM_INFO_PAUSE | 40 SNDRV_PCM_INFO_PAUSE |
41 SNDRV_PCM_INFO_RESUME |
38 SNDRV_PCM_INFO_SYNC_START | 42 SNDRV_PCM_INFO_SYNC_START |
39 SNDRV_PCM_INFO_HAS_WALL_CLOCK | /* legacy */ 43 SNDRV_PCM_INFO_HAS_WALL_CLOCK | /* legacy */
40 SNDRV_PCM_INFO_HAS_LINK_ATIME | 44 SNDRV_PCM_INFO_HAS_LINK_ATIME |
41 SNDRV_PCM_INFO_NO_PERIOD_WAKEUP), 45 SNDRV_PCM_INFO_NO_PERIOD_WAKEUP),
42 .formats = SNDRV_PCM_FMTBIT_S16_LE, 46 .formats = SNDRV_PCM_FMTBIT_S16_LE |
43 .rates = SNDRV_PCM_RATE_48000, 47 SNDRV_PCM_FMTBIT_S32_LE |
44 .rate_min = 48000, 48 SNDRV_PCM_FMTBIT_S24_LE,
49 .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_16000 |
50 SNDRV_PCM_RATE_8000,
51 .rate_min = 8000,
45 .rate_max = 48000, 52 .rate_max = 48000,
46 .channels_min = 2, 53 .channels_min = 1,
47 .channels_max = 2, 54 .channels_max = HDA_QUAD,
48 .buffer_bytes_max = AZX_MAX_BUF_SIZE, 55 .buffer_bytes_max = AZX_MAX_BUF_SIZE,
49 .period_bytes_min = 128, 56 .period_bytes_min = 128,
50 .period_bytes_max = AZX_MAX_BUF_SIZE / 2, 57 .period_bytes_max = AZX_MAX_BUF_SIZE / 2,
@@ -105,6 +112,31 @@ static enum hdac_ext_stream_type skl_get_host_stream_type(struct hdac_ext_bus *e
105 return HDAC_EXT_STREAM_TYPE_COUPLED; 112 return HDAC_EXT_STREAM_TYPE_COUPLED;
106} 113}
107 114
115/*
116 * check if the stream opened is marked as ignore_suspend by machine, if so
117 * then enable suspend_active refcount
118 *
119 * The count supend_active does not need lock as it is used in open/close
120 * and suspend context
121 */
122static void skl_set_suspend_active(struct snd_pcm_substream *substream,
123 struct snd_soc_dai *dai, bool enable)
124{
125 struct hdac_ext_bus *ebus = dev_get_drvdata(dai->dev);
126 struct snd_soc_dapm_widget *w;
127 struct skl *skl = ebus_to_skl(ebus);
128
129 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
130 w = dai->playback_widget;
131 else
132 w = dai->capture_widget;
133
134 if (w->ignore_suspend && enable)
135 skl->supend_active++;
136 else if (w->ignore_suspend && !enable)
137 skl->supend_active--;
138}
139
108static int skl_pcm_open(struct snd_pcm_substream *substream, 140static int skl_pcm_open(struct snd_pcm_substream *substream,
109 struct snd_soc_dai *dai) 141 struct snd_soc_dai *dai)
110{ 142{
@@ -112,12 +144,8 @@ static int skl_pcm_open(struct snd_pcm_substream *substream,
112 struct hdac_ext_stream *stream; 144 struct hdac_ext_stream *stream;
113 struct snd_pcm_runtime *runtime = substream->runtime; 145 struct snd_pcm_runtime *runtime = substream->runtime;
114 struct skl_dma_params *dma_params; 146 struct skl_dma_params *dma_params;
115 int ret;
116 147
117 dev_dbg(dai->dev, "%s: %s\n", __func__, dai->name); 148 dev_dbg(dai->dev, "%s: %s\n", __func__, dai->name);
118 ret = pm_runtime_get_sync(dai->dev);
119 if (ret < 0)
120 return ret;
121 149
122 stream = snd_hdac_ext_stream_assign(ebus, substream, 150 stream = snd_hdac_ext_stream_assign(ebus, substream,
123 skl_get_host_stream_type(ebus)); 151 skl_get_host_stream_type(ebus));
@@ -146,6 +174,7 @@ static int skl_pcm_open(struct snd_pcm_substream *substream,
146 174
147 dev_dbg(dai->dev, "stream tag set in dma params=%d\n", 175 dev_dbg(dai->dev, "stream tag set in dma params=%d\n",
148 dma_params->stream_tag); 176 dma_params->stream_tag);
177 skl_set_suspend_active(substream, dai, true);
149 snd_pcm_set_sync(substream); 178 snd_pcm_set_sync(substream);
150 179
151 return 0; 180 return 0;
@@ -185,10 +214,6 @@ static int skl_pcm_prepare(struct snd_pcm_substream *substream,
185 int err; 214 int err;
186 215
187 dev_dbg(dai->dev, "%s: %s\n", __func__, dai->name); 216 dev_dbg(dai->dev, "%s: %s\n", __func__, dai->name);
188 if (hdac_stream(stream)->prepared) {
189 dev_dbg(dai->dev, "already stream is prepared - returning\n");
190 return 0;
191 }
192 217
193 format_val = skl_get_format(substream, dai); 218 format_val = skl_get_format(substream, dai);
194 dev_dbg(dai->dev, "stream_tag=%d formatvalue=%d\n", 219 dev_dbg(dai->dev, "stream_tag=%d formatvalue=%d\n",
@@ -250,6 +275,7 @@ static void skl_pcm_close(struct snd_pcm_substream *substream,
250 struct hdac_ext_stream *stream = get_hdac_ext_stream(substream); 275 struct hdac_ext_stream *stream = get_hdac_ext_stream(substream);
251 struct hdac_ext_bus *ebus = dev_get_drvdata(dai->dev); 276 struct hdac_ext_bus *ebus = dev_get_drvdata(dai->dev);
252 struct skl_dma_params *dma_params = NULL; 277 struct skl_dma_params *dma_params = NULL;
278 struct skl *skl = ebus_to_skl(ebus);
253 279
254 dev_dbg(dai->dev, "%s: %s\n", __func__, dai->name); 280 dev_dbg(dai->dev, "%s: %s\n", __func__, dai->name);
255 281
@@ -261,9 +287,18 @@ static void skl_pcm_close(struct snd_pcm_substream *substream,
261 * dma_params 287 * dma_params
262 */ 288 */
263 snd_soc_dai_set_dma_data(dai, substream, NULL); 289 snd_soc_dai_set_dma_data(dai, substream, NULL);
290 skl_set_suspend_active(substream, dai, false);
291
292 /*
293 * check if close is for "Reference Pin" and set back the
294 * CGCTL.MISCBDCGE if disabled by driver
295 */
296 if (!strncmp(dai->name, "Reference Pin", 13) &&
297 skl->skl_sst->miscbdcg_disabled) {
298 skl->skl_sst->enable_miscbdcge(dai->dev, true);
299 skl->skl_sst->miscbdcg_disabled = false;
300 }
264 301
265 pm_runtime_mark_last_busy(dai->dev);
266 pm_runtime_put_autosuspend(dai->dev);
267 kfree(dma_params); 302 kfree(dma_params);
268} 303}
269 304
@@ -291,7 +326,53 @@ static int skl_be_hw_params(struct snd_pcm_substream *substream,
291 p_params.ch = params_channels(params); 326 p_params.ch = params_channels(params);
292 p_params.s_freq = params_rate(params); 327 p_params.s_freq = params_rate(params);
293 p_params.stream = substream->stream; 328 p_params.stream = substream->stream;
294 skl_tplg_be_update_params(dai, &p_params); 329
330 return skl_tplg_be_update_params(dai, &p_params);
331}
332
333static int skl_decoupled_trigger(struct snd_pcm_substream *substream,
334 int cmd)
335{
336 struct hdac_ext_bus *ebus = get_bus_ctx(substream);
337 struct hdac_bus *bus = ebus_to_hbus(ebus);
338 struct hdac_ext_stream *stream;
339 int start;
340 unsigned long cookie;
341 struct hdac_stream *hstr;
342
343 stream = get_hdac_ext_stream(substream);
344 hstr = hdac_stream(stream);
345
346 if (!hstr->prepared)
347 return -EPIPE;
348
349 switch (cmd) {
350 case SNDRV_PCM_TRIGGER_START:
351 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
352 case SNDRV_PCM_TRIGGER_RESUME:
353 start = 1;
354 break;
355
356 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
357 case SNDRV_PCM_TRIGGER_SUSPEND:
358 case SNDRV_PCM_TRIGGER_STOP:
359 start = 0;
360 break;
361
362 default:
363 return -EINVAL;
364 }
365
366 spin_lock_irqsave(&bus->reg_lock, cookie);
367
368 if (start) {
369 snd_hdac_stream_start(hdac_stream(stream), true);
370 snd_hdac_stream_timecounter_init(hstr, 0);
371 } else {
372 snd_hdac_stream_stop(hdac_stream(stream));
373 }
374
375 spin_unlock_irqrestore(&bus->reg_lock, cookie);
295 376
296 return 0; 377 return 0;
297} 378}
@@ -302,23 +383,72 @@ static int skl_pcm_trigger(struct snd_pcm_substream *substream, int cmd,
302 struct skl *skl = get_skl_ctx(dai->dev); 383 struct skl *skl = get_skl_ctx(dai->dev);
303 struct skl_sst *ctx = skl->skl_sst; 384 struct skl_sst *ctx = skl->skl_sst;
304 struct skl_module_cfg *mconfig; 385 struct skl_module_cfg *mconfig;
386 struct hdac_ext_bus *ebus = get_bus_ctx(substream);
387 struct hdac_ext_stream *stream = get_hdac_ext_stream(substream);
388 int ret;
305 389
306 mconfig = skl_tplg_fe_get_cpr_module(dai, substream->stream); 390 mconfig = skl_tplg_fe_get_cpr_module(dai, substream->stream);
307 if (!mconfig) 391 if (!mconfig)
308 return -EIO; 392 return -EIO;
309 393
310 switch (cmd) { 394 switch (cmd) {
311 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
312 case SNDRV_PCM_TRIGGER_RESUME: 395 case SNDRV_PCM_TRIGGER_RESUME:
396 skl_pcm_prepare(substream, dai);
397 /*
398 * enable DMA Resume enable bit for the stream, set the dpib
399 * & lpib position to resune before starting the DMA
400 */
401 snd_hdac_ext_stream_drsm_enable(ebus, true,
402 hdac_stream(stream)->index);
403 snd_hdac_ext_stream_set_dpibr(ebus, stream, stream->dpib);
404 snd_hdac_ext_stream_set_lpib(stream, stream->lpib);
405
406 case SNDRV_PCM_TRIGGER_START:
407 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
408 /*
409 * Start HOST DMA and Start FE Pipe.This is to make sure that
410 * there are no underrun/overrun in the case when the FE
411 * pipeline is started but there is a delay in starting the
412 * DMA channel on the host.
413 */
414 snd_hdac_ext_stream_decouple(ebus, stream, true);
415 ret = skl_decoupled_trigger(substream, cmd);
416 if (ret < 0)
417 return ret;
313 return skl_run_pipe(ctx, mconfig->pipe); 418 return skl_run_pipe(ctx, mconfig->pipe);
419 break;
314 420
315 case SNDRV_PCM_TRIGGER_PAUSE_PUSH: 421 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
316 case SNDRV_PCM_TRIGGER_SUSPEND: 422 case SNDRV_PCM_TRIGGER_SUSPEND:
317 return skl_stop_pipe(ctx, mconfig->pipe); 423 case SNDRV_PCM_TRIGGER_STOP:
424 /*
425 * Stop FE Pipe first and stop DMA. This is to make sure that
426 * there are no underrun/overrun in the case if there is a delay
427 * between the two operations.
428 */
429 ret = skl_stop_pipe(ctx, mconfig->pipe);
430 if (ret < 0)
431 return ret;
432
433 ret = skl_decoupled_trigger(substream, cmd);
434 if (cmd == SNDRV_PCM_TRIGGER_SUSPEND) {
435 /* save the dpib and lpib positions */
436 stream->dpib = readl(ebus->bus.remap_addr +
437 AZX_REG_VS_SDXDPIB_XBASE +
438 (AZX_REG_VS_SDXDPIB_XINTERVAL *
439 hdac_stream(stream)->index));
440
441 stream->lpib = snd_hdac_stream_get_pos_lpib(
442 hdac_stream(stream));
443 snd_hdac_ext_stream_decouple(ebus, stream, false);
444 }
445 break;
318 446
319 default: 447 default:
320 return 0; 448 return -EINVAL;
321 } 449 }
450
451 return 0;
322} 452}
323 453
324static int skl_link_hw_params(struct snd_pcm_substream *substream, 454static int skl_link_hw_params(struct snd_pcm_substream *substream,
@@ -352,9 +482,7 @@ static int skl_link_hw_params(struct snd_pcm_substream *substream,
352 p_params.stream = substream->stream; 482 p_params.stream = substream->stream;
353 p_params.link_dma_id = hdac_stream(link_dev)->stream_tag - 1; 483 p_params.link_dma_id = hdac_stream(link_dev)->stream_tag - 1;
354 484
355 skl_tplg_be_update_params(dai, &p_params); 485 return skl_tplg_be_update_params(dai, &p_params);
356
357 return 0;
358} 486}
359 487
360static int skl_link_pcm_prepare(struct snd_pcm_substream *substream, 488static int skl_link_pcm_prepare(struct snd_pcm_substream *substream,
@@ -369,11 +497,6 @@ static int skl_link_pcm_prepare(struct snd_pcm_substream *substream,
369 struct snd_soc_dai *codec_dai = rtd->codec_dai; 497 struct snd_soc_dai *codec_dai = rtd->codec_dai;
370 struct hdac_ext_link *link; 498 struct hdac_ext_link *link;
371 499
372 if (link_dev->link_prepared) {
373 dev_dbg(dai->dev, "already stream is prepared - returning\n");
374 return 0;
375 }
376
377 dma_params = (struct skl_dma_params *) 500 dma_params = (struct skl_dma_params *)
378 snd_soc_dai_get_dma_data(codec_dai, substream); 501 snd_soc_dai_get_dma_data(codec_dai, substream);
379 if (dma_params) 502 if (dma_params)
@@ -381,14 +504,15 @@ static int skl_link_pcm_prepare(struct snd_pcm_substream *substream,
381 dev_dbg(dai->dev, "stream_tag=%d formatvalue=%d codec_dai_name=%s\n", 504 dev_dbg(dai->dev, "stream_tag=%d formatvalue=%d codec_dai_name=%s\n",
382 hdac_stream(link_dev)->stream_tag, format_val, codec_dai->name); 505 hdac_stream(link_dev)->stream_tag, format_val, codec_dai->name);
383 506
384 snd_hdac_ext_link_stream_reset(link_dev);
385
386 snd_hdac_ext_link_stream_setup(link_dev, format_val);
387
388 link = snd_hdac_ext_bus_get_link(ebus, rtd->codec->component.name); 507 link = snd_hdac_ext_bus_get_link(ebus, rtd->codec->component.name);
389 if (!link) 508 if (!link)
390 return -EINVAL; 509 return -EINVAL;
391 510
511 snd_hdac_ext_bus_link_power_up(link);
512 snd_hdac_ext_link_stream_reset(link_dev);
513
514 snd_hdac_ext_link_stream_setup(link_dev, format_val);
515
392 snd_hdac_ext_link_set_stream_id(link, hdac_stream(link_dev)->stream_tag); 516 snd_hdac_ext_link_set_stream_id(link, hdac_stream(link_dev)->stream_tag);
393 link_dev->link_prepared = 1; 517 link_dev->link_prepared = 1;
394 518
@@ -400,12 +524,16 @@ static int skl_link_pcm_trigger(struct snd_pcm_substream *substream,
400{ 524{
401 struct hdac_ext_stream *link_dev = 525 struct hdac_ext_stream *link_dev =
402 snd_soc_dai_get_dma_data(dai, substream); 526 snd_soc_dai_get_dma_data(dai, substream);
527 struct hdac_ext_bus *ebus = get_bus_ctx(substream);
528 struct hdac_ext_stream *stream = get_hdac_ext_stream(substream);
403 529
404 dev_dbg(dai->dev, "In %s cmd=%d\n", __func__, cmd); 530 dev_dbg(dai->dev, "In %s cmd=%d\n", __func__, cmd);
405 switch (cmd) { 531 switch (cmd) {
532 case SNDRV_PCM_TRIGGER_RESUME:
533 skl_link_pcm_prepare(substream, dai);
406 case SNDRV_PCM_TRIGGER_START: 534 case SNDRV_PCM_TRIGGER_START:
407 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: 535 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
408 case SNDRV_PCM_TRIGGER_RESUME: 536 snd_hdac_ext_stream_decouple(ebus, stream, true);
409 snd_hdac_ext_link_stream_start(link_dev); 537 snd_hdac_ext_link_stream_start(link_dev);
410 break; 538 break;
411 539
@@ -413,6 +541,8 @@ static int skl_link_pcm_trigger(struct snd_pcm_substream *substream,
413 case SNDRV_PCM_TRIGGER_SUSPEND: 541 case SNDRV_PCM_TRIGGER_SUSPEND:
414 case SNDRV_PCM_TRIGGER_STOP: 542 case SNDRV_PCM_TRIGGER_STOP:
415 snd_hdac_ext_link_stream_clear(link_dev); 543 snd_hdac_ext_link_stream_clear(link_dev);
544 if (cmd == SNDRV_PCM_TRIGGER_SUSPEND)
545 snd_hdac_ext_stream_decouple(ebus, stream, false);
416 break; 546 break;
417 547
418 default: 548 default:
@@ -443,19 +573,6 @@ static int skl_link_hw_free(struct snd_pcm_substream *substream,
443 return 0; 573 return 0;
444} 574}
445 575
446static int skl_be_startup(struct snd_pcm_substream *substream,
447 struct snd_soc_dai *dai)
448{
449 return pm_runtime_get_sync(dai->dev);
450}
451
452static void skl_be_shutdown(struct snd_pcm_substream *substream,
453 struct snd_soc_dai *dai)
454{
455 pm_runtime_mark_last_busy(dai->dev);
456 pm_runtime_put_autosuspend(dai->dev);
457}
458
459static struct snd_soc_dai_ops skl_pcm_dai_ops = { 576static struct snd_soc_dai_ops skl_pcm_dai_ops = {
460 .startup = skl_pcm_open, 577 .startup = skl_pcm_open,
461 .shutdown = skl_pcm_close, 578 .shutdown = skl_pcm_close,
@@ -466,24 +583,18 @@ static struct snd_soc_dai_ops skl_pcm_dai_ops = {
466}; 583};
467 584
468static struct snd_soc_dai_ops skl_dmic_dai_ops = { 585static struct snd_soc_dai_ops skl_dmic_dai_ops = {
469 .startup = skl_be_startup,
470 .hw_params = skl_be_hw_params, 586 .hw_params = skl_be_hw_params,
471 .shutdown = skl_be_shutdown,
472}; 587};
473 588
474static struct snd_soc_dai_ops skl_be_ssp_dai_ops = { 589static struct snd_soc_dai_ops skl_be_ssp_dai_ops = {
475 .startup = skl_be_startup,
476 .hw_params = skl_be_hw_params, 590 .hw_params = skl_be_hw_params,
477 .shutdown = skl_be_shutdown,
478}; 591};
479 592
480static struct snd_soc_dai_ops skl_link_dai_ops = { 593static struct snd_soc_dai_ops skl_link_dai_ops = {
481 .startup = skl_be_startup,
482 .prepare = skl_link_pcm_prepare, 594 .prepare = skl_link_pcm_prepare,
483 .hw_params = skl_link_hw_params, 595 .hw_params = skl_link_hw_params,
484 .hw_free = skl_link_hw_free, 596 .hw_free = skl_link_hw_free,
485 .trigger = skl_link_pcm_trigger, 597 .trigger = skl_link_pcm_trigger,
486 .shutdown = skl_be_shutdown,
487}; 598};
488 599
489static struct snd_soc_dai_driver skl_platform_dai[] = { 600static struct snd_soc_dai_driver skl_platform_dai[] = {
@@ -511,7 +622,7 @@ static struct snd_soc_dai_driver skl_platform_dai[] = {
511 .capture = { 622 .capture = {
512 .stream_name = "Reference Capture", 623 .stream_name = "Reference Capture",
513 .channels_min = HDA_MONO, 624 .channels_min = HDA_MONO,
514 .channels_max = HDA_STEREO, 625 .channels_max = HDA_QUAD,
515 .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_16000, 626 .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_16000,
516 .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE, 627 .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE,
517 }, 628 },
@@ -538,6 +649,18 @@ static struct snd_soc_dai_driver skl_platform_dai[] = {
538 .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE, 649 .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE,
539 }, 650 },
540}, 651},
652{
653 .name = "DMIC Pin",
654 .ops = &skl_pcm_dai_ops,
655 .capture = {
656 .stream_name = "DMIC Capture",
657 .channels_min = HDA_MONO,
658 .channels_max = HDA_QUAD,
659 .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_16000,
660 .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE,
661 },
662},
663
541/* BE CPU Dais */ 664/* BE CPU Dais */
542{ 665{
543 .name = "SSP0 Pin", 666 .name = "SSP0 Pin",
@@ -558,6 +681,24 @@ static struct snd_soc_dai_driver skl_platform_dai[] = {
558 }, 681 },
559}, 682},
560{ 683{
684 .name = "SSP1 Pin",
685 .ops = &skl_be_ssp_dai_ops,
686 .playback = {
687 .stream_name = "ssp1 Tx",
688 .channels_min = HDA_STEREO,
689 .channels_max = HDA_STEREO,
690 .rates = SNDRV_PCM_RATE_48000,
691 .formats = SNDRV_PCM_FMTBIT_S16_LE,
692 },
693 .capture = {
694 .stream_name = "ssp1 Rx",
695 .channels_min = HDA_STEREO,
696 .channels_max = HDA_STEREO,
697 .rates = SNDRV_PCM_RATE_48000,
698 .formats = SNDRV_PCM_FMTBIT_S16_LE,
699 },
700},
701{
561 .name = "iDisp Pin", 702 .name = "iDisp Pin",
562 .ops = &skl_link_dai_ops, 703 .ops = &skl_link_dai_ops,
563 .playback = { 704 .playback = {
@@ -573,8 +714,8 @@ static struct snd_soc_dai_driver skl_platform_dai[] = {
573 .ops = &skl_dmic_dai_ops, 714 .ops = &skl_dmic_dai_ops,
574 .capture = { 715 .capture = {
575 .stream_name = "DMIC01 Rx", 716 .stream_name = "DMIC01 Rx",
576 .channels_min = HDA_STEREO, 717 .channels_min = HDA_MONO,
577 .channels_max = HDA_STEREO, 718 .channels_max = HDA_QUAD,
578 .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_16000, 719 .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_16000,
579 .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE, 720 .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE,
580 }, 721 },
@@ -688,66 +829,15 @@ static int skl_coupled_trigger(struct snd_pcm_substream *substream,
688 return 0; 829 return 0;
689} 830}
690 831
691static int skl_decoupled_trigger(struct snd_pcm_substream *substream,
692 int cmd)
693{
694 struct hdac_ext_bus *ebus = get_bus_ctx(substream);
695 struct hdac_bus *bus = ebus_to_hbus(ebus);
696 struct snd_soc_pcm_runtime *rtd = snd_pcm_substream_chip(substream);
697 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
698 struct hdac_ext_stream *stream;
699 int start;
700 unsigned long cookie;
701 struct hdac_stream *hstr;
702
703 dev_dbg(bus->dev, "In %s cmd=%d streamname=%s\n", __func__, cmd, cpu_dai->name);
704
705 stream = get_hdac_ext_stream(substream);
706 hstr = hdac_stream(stream);
707
708 if (!hstr->prepared)
709 return -EPIPE;
710
711 switch (cmd) {
712 case SNDRV_PCM_TRIGGER_START:
713 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
714 case SNDRV_PCM_TRIGGER_RESUME:
715 start = 1;
716 break;
717
718 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
719 case SNDRV_PCM_TRIGGER_SUSPEND:
720 case SNDRV_PCM_TRIGGER_STOP:
721 start = 0;
722 break;
723
724 default:
725 return -EINVAL;
726 }
727
728 spin_lock_irqsave(&bus->reg_lock, cookie);
729
730 if (start)
731 snd_hdac_stream_start(hdac_stream(stream), true);
732 else
733 snd_hdac_stream_stop(hdac_stream(stream));
734
735 if (start)
736 snd_hdac_stream_timecounter_init(hstr, 0);
737
738 spin_unlock_irqrestore(&bus->reg_lock, cookie);
739
740 return 0;
741}
742static int skl_platform_pcm_trigger(struct snd_pcm_substream *substream, 832static int skl_platform_pcm_trigger(struct snd_pcm_substream *substream,
743 int cmd) 833 int cmd)
744{ 834{
745 struct hdac_ext_bus *ebus = get_bus_ctx(substream); 835 struct hdac_ext_bus *ebus = get_bus_ctx(substream);
746 836
747 if (ebus->ppcap) 837 if (!ebus->ppcap)
748 return skl_decoupled_trigger(substream, cmd);
749 else
750 return skl_coupled_trigger(substream, cmd); 838 return skl_coupled_trigger(substream, cmd);
839
840 return 0;
751} 841}
752 842
753/* calculate runtime delay from LPIB */ 843/* calculate runtime delay from LPIB */
@@ -789,7 +879,7 @@ static unsigned int skl_get_position(struct hdac_ext_stream *hstream,
789{ 879{
790 struct hdac_stream *hstr = hdac_stream(hstream); 880 struct hdac_stream *hstr = hdac_stream(hstream);
791 struct snd_pcm_substream *substream = hstr->substream; 881 struct snd_pcm_substream *substream = hstr->substream;
792 struct hdac_ext_bus *ebus = get_bus_ctx(substream); 882 struct hdac_ext_bus *ebus;
793 unsigned int pos; 883 unsigned int pos;
794 int delay; 884 int delay;
795 885
@@ -800,6 +890,7 @@ static unsigned int skl_get_position(struct hdac_ext_stream *hstream,
800 pos = 0; 890 pos = 0;
801 891
802 if (substream->runtime) { 892 if (substream->runtime) {
893 ebus = get_bus_ctx(substream);
803 delay = skl_get_delay_from_lpib(ebus, hstream, pos) 894 delay = skl_get_delay_from_lpib(ebus, hstream, pos)
804 + codec_delay; 895 + codec_delay;
805 substream->runtime->delay += delay; 896 substream->runtime->delay += delay;
@@ -941,7 +1032,6 @@ int skl_platform_register(struct device *dev)
941 struct skl *skl = ebus_to_skl(ebus); 1032 struct skl *skl = ebus_to_skl(ebus);
942 1033
943 INIT_LIST_HEAD(&skl->ppl_list); 1034 INIT_LIST_HEAD(&skl->ppl_list);
944 INIT_LIST_HEAD(&skl->dapm_path_list);
945 1035
946 ret = snd_soc_register_platform(dev, &skl_platform_drv); 1036 ret = snd_soc_register_platform(dev, &skl_platform_drv);
947 if (ret) { 1037 if (ret) {
diff --git a/sound/soc/intel/skylake/skl-sst-cldma.c b/sound/soc/intel/skylake/skl-sst-cldma.c
index 44748ba98da2..da2329d17f4d 100644
--- a/sound/soc/intel/skylake/skl-sst-cldma.c
+++ b/sound/soc/intel/skylake/skl-sst-cldma.c
@@ -18,6 +18,7 @@
18#include <linux/device.h> 18#include <linux/device.h>
19#include <linux/mm.h> 19#include <linux/mm.h>
20#include <linux/kthread.h> 20#include <linux/kthread.h>
21#include <linux/delay.h>
21#include "../common/sst-dsp.h" 22#include "../common/sst-dsp.h"
22#include "../common/sst-dsp-priv.h" 23#include "../common/sst-dsp-priv.h"
23 24
@@ -33,6 +34,53 @@ void skl_cldma_int_disable(struct sst_dsp *ctx)
33 SKL_ADSP_REG_ADSPIC, SKL_ADSPIC_CL_DMA, 0); 34 SKL_ADSP_REG_ADSPIC, SKL_ADSPIC_CL_DMA, 0);
34} 35}
35 36
37static void skl_cldma_stream_run(struct sst_dsp *ctx, bool enable)
38{
39 unsigned char val;
40 int timeout;
41
42 sst_dsp_shim_update_bits_unlocked(ctx,
43 SKL_ADSP_REG_CL_SD_CTL,
44 CL_SD_CTL_RUN_MASK, CL_SD_CTL_RUN(enable));
45
46 udelay(3);
47 timeout = 300;
48 do {
49 /* waiting for hardware to report that the stream Run bit set */
50 val = sst_dsp_shim_read(ctx, SKL_ADSP_REG_CL_SD_CTL) &
51 CL_SD_CTL_RUN_MASK;
52 if (enable && val)
53 break;
54 else if (!enable && !val)
55 break;
56 udelay(3);
57 } while (--timeout);
58
59 if (timeout == 0)
60 dev_err(ctx->dev, "Failed to set Run bit=%d enable=%d\n", val, enable);
61}
62
63static void skl_cldma_stream_clear(struct sst_dsp *ctx)
64{
65 /* make sure Run bit is cleared before setting stream register */
66 skl_cldma_stream_run(ctx, 0);
67
68 sst_dsp_shim_update_bits(ctx, SKL_ADSP_REG_CL_SD_CTL,
69 CL_SD_CTL_IOCE_MASK, CL_SD_CTL_IOCE(0));
70 sst_dsp_shim_update_bits(ctx, SKL_ADSP_REG_CL_SD_CTL,
71 CL_SD_CTL_FEIE_MASK, CL_SD_CTL_FEIE(0));
72 sst_dsp_shim_update_bits(ctx, SKL_ADSP_REG_CL_SD_CTL,
73 CL_SD_CTL_DEIE_MASK, CL_SD_CTL_DEIE(0));
74 sst_dsp_shim_update_bits(ctx, SKL_ADSP_REG_CL_SD_CTL,
75 CL_SD_CTL_STRM_MASK, CL_SD_CTL_STRM(0));
76
77 sst_dsp_shim_write(ctx, SKL_ADSP_REG_CL_SD_BDLPL, CL_SD_BDLPLBA(0));
78 sst_dsp_shim_write(ctx, SKL_ADSP_REG_CL_SD_BDLPU, 0);
79
80 sst_dsp_shim_write(ctx, SKL_ADSP_REG_CL_SD_CBL, 0);
81 sst_dsp_shim_write(ctx, SKL_ADSP_REG_CL_SD_LVI, 0);
82}
83
36/* Code loader helper APIs */ 84/* Code loader helper APIs */
37static void skl_cldma_setup_bdle(struct sst_dsp *ctx, 85static void skl_cldma_setup_bdle(struct sst_dsp *ctx,
38 struct snd_dma_buffer *dmab_data, 86 struct snd_dma_buffer *dmab_data,
@@ -68,6 +116,7 @@ static void skl_cldma_setup_controller(struct sst_dsp *ctx,
68 struct snd_dma_buffer *dmab_bdl, unsigned int max_size, 116 struct snd_dma_buffer *dmab_bdl, unsigned int max_size,
69 u32 count) 117 u32 count)
70{ 118{
119 skl_cldma_stream_clear(ctx);
71 sst_dsp_shim_write(ctx, SKL_ADSP_REG_CL_SD_BDLPL, 120 sst_dsp_shim_write(ctx, SKL_ADSP_REG_CL_SD_BDLPL,
72 CL_SD_BDLPLBA(dmab_bdl->addr)); 121 CL_SD_BDLPLBA(dmab_bdl->addr));
73 sst_dsp_shim_write(ctx, SKL_ADSP_REG_CL_SD_BDLPU, 122 sst_dsp_shim_write(ctx, SKL_ADSP_REG_CL_SD_BDLPU,
@@ -107,36 +156,13 @@ static void skl_cldma_cleanup_spb(struct sst_dsp *ctx)
107 sst_dsp_shim_write_unlocked(ctx, SKL_ADSP_REG_CL_SPBFIFO_SPIB, 0); 156 sst_dsp_shim_write_unlocked(ctx, SKL_ADSP_REG_CL_SPBFIFO_SPIB, 0);
108} 157}
109 158
110static void skl_cldma_trigger(struct sst_dsp *ctx, bool enable)
111{
112 if (enable)
113 sst_dsp_shim_update_bits_unlocked(ctx,
114 SKL_ADSP_REG_CL_SD_CTL,
115 CL_SD_CTL_RUN_MASK, CL_SD_CTL_RUN(1));
116 else
117 sst_dsp_shim_update_bits_unlocked(ctx,
118 SKL_ADSP_REG_CL_SD_CTL,
119 CL_SD_CTL_RUN_MASK, CL_SD_CTL_RUN(0));
120}
121
122static void skl_cldma_cleanup(struct sst_dsp *ctx) 159static void skl_cldma_cleanup(struct sst_dsp *ctx)
123{ 160{
124 skl_cldma_cleanup_spb(ctx); 161 skl_cldma_cleanup_spb(ctx);
162 skl_cldma_stream_clear(ctx);
125 163
126 sst_dsp_shim_update_bits(ctx, SKL_ADSP_REG_CL_SD_CTL, 164 ctx->dsp_ops.free_dma_buf(ctx->dev, &ctx->cl_dev.dmab_data);
127 CL_SD_CTL_IOCE_MASK, CL_SD_CTL_IOCE(0)); 165 ctx->dsp_ops.free_dma_buf(ctx->dev, &ctx->cl_dev.dmab_bdl);
128 sst_dsp_shim_update_bits(ctx, SKL_ADSP_REG_CL_SD_CTL,
129 CL_SD_CTL_FEIE_MASK, CL_SD_CTL_FEIE(0));
130 sst_dsp_shim_update_bits(ctx, SKL_ADSP_REG_CL_SD_CTL,
131 CL_SD_CTL_DEIE_MASK, CL_SD_CTL_DEIE(0));
132 sst_dsp_shim_update_bits(ctx, SKL_ADSP_REG_CL_SD_CTL,
133 CL_SD_CTL_STRM_MASK, CL_SD_CTL_STRM(0));
134
135 sst_dsp_shim_write(ctx, SKL_ADSP_REG_CL_SD_BDLPL, CL_SD_BDLPLBA(0));
136 sst_dsp_shim_write(ctx, SKL_ADSP_REG_CL_SD_BDLPU, 0);
137
138 sst_dsp_shim_write(ctx, SKL_ADSP_REG_CL_SD_CBL, 0);
139 sst_dsp_shim_write(ctx, SKL_ADSP_REG_CL_SD_LVI, 0);
140} 166}
141 167
142static int skl_cldma_wait_interruptible(struct sst_dsp *ctx) 168static int skl_cldma_wait_interruptible(struct sst_dsp *ctx)
@@ -164,7 +190,7 @@ cleanup:
164 190
165static void skl_cldma_stop(struct sst_dsp *ctx) 191static void skl_cldma_stop(struct sst_dsp *ctx)
166{ 192{
167 ctx->cl_dev.ops.cl_trigger(ctx, false); 193 skl_cldma_stream_run(ctx, false);
168} 194}
169 195
170static void skl_cldma_fill_buffer(struct sst_dsp *ctx, unsigned int size, 196static void skl_cldma_fill_buffer(struct sst_dsp *ctx, unsigned int size,
@@ -175,6 +201,21 @@ static void skl_cldma_fill_buffer(struct sst_dsp *ctx, unsigned int size,
175 ctx->cl_dev.dma_buffer_offset, trigger); 201 ctx->cl_dev.dma_buffer_offset, trigger);
176 dev_dbg(ctx->dev, "spib position: %d\n", ctx->cl_dev.curr_spib_pos); 202 dev_dbg(ctx->dev, "spib position: %d\n", ctx->cl_dev.curr_spib_pos);
177 203
204 /*
205 * Check if the size exceeds buffer boundary. If it exceeds
206 * max_buffer size, then copy till buffer size and then copy
207 * remaining buffer from the start of ring buffer.
208 */
209 if (ctx->cl_dev.dma_buffer_offset + size > ctx->cl_dev.bufsize) {
210 unsigned int size_b = ctx->cl_dev.bufsize -
211 ctx->cl_dev.dma_buffer_offset;
212 memcpy(ctx->cl_dev.dmab_data.area + ctx->cl_dev.dma_buffer_offset,
213 curr_pos, size_b);
214 size -= size_b;
215 curr_pos += size_b;
216 ctx->cl_dev.dma_buffer_offset = 0;
217 }
218
178 memcpy(ctx->cl_dev.dmab_data.area + ctx->cl_dev.dma_buffer_offset, 219 memcpy(ctx->cl_dev.dmab_data.area + ctx->cl_dev.dma_buffer_offset,
179 curr_pos, size); 220 curr_pos, size);
180 221
@@ -291,7 +332,7 @@ int skl_cldma_prepare(struct sst_dsp *ctx)
291 ctx->cl_dev.ops.cl_setup_controller = skl_cldma_setup_controller; 332 ctx->cl_dev.ops.cl_setup_controller = skl_cldma_setup_controller;
292 ctx->cl_dev.ops.cl_setup_spb = skl_cldma_setup_spb; 333 ctx->cl_dev.ops.cl_setup_spb = skl_cldma_setup_spb;
293 ctx->cl_dev.ops.cl_cleanup_spb = skl_cldma_cleanup_spb; 334 ctx->cl_dev.ops.cl_cleanup_spb = skl_cldma_cleanup_spb;
294 ctx->cl_dev.ops.cl_trigger = skl_cldma_trigger; 335 ctx->cl_dev.ops.cl_trigger = skl_cldma_stream_run;
295 ctx->cl_dev.ops.cl_cleanup_controller = skl_cldma_cleanup; 336 ctx->cl_dev.ops.cl_cleanup_controller = skl_cldma_cleanup;
296 ctx->cl_dev.ops.cl_copy_to_dmabuf = skl_cldma_copy_to_buf; 337 ctx->cl_dev.ops.cl_copy_to_dmabuf = skl_cldma_copy_to_buf;
297 ctx->cl_dev.ops.cl_stop_dma = skl_cldma_stop; 338 ctx->cl_dev.ops.cl_stop_dma = skl_cldma_stop;
diff --git a/sound/soc/intel/skylake/skl-sst-dsp.h b/sound/soc/intel/skylake/skl-sst-dsp.h
index 6bfcef449bdc..cbb40751c37e 100644
--- a/sound/soc/intel/skylake/skl-sst-dsp.h
+++ b/sound/soc/intel/skylake/skl-sst-dsp.h
@@ -58,9 +58,9 @@ struct sst_dsp_device;
58 58
59#define SKL_ADSP_MMIO_LEN 0x10000 59#define SKL_ADSP_MMIO_LEN 0x10000
60 60
61#define SKL_ADSP_W0_STAT_SZ 0x800 61#define SKL_ADSP_W0_STAT_SZ 0x1000
62 62
63#define SKL_ADSP_W0_UP_SZ 0x800 63#define SKL_ADSP_W0_UP_SZ 0x1000
64 64
65#define SKL_ADSP_W1_SZ 0x1000 65#define SKL_ADSP_W1_SZ 0x1000
66 66
@@ -114,6 +114,9 @@ struct skl_dsp_fw_ops {
114 int (*set_state_D0)(struct sst_dsp *ctx); 114 int (*set_state_D0)(struct sst_dsp *ctx);
115 int (*set_state_D3)(struct sst_dsp *ctx); 115 int (*set_state_D3)(struct sst_dsp *ctx);
116 unsigned int (*get_fw_errcode)(struct sst_dsp *ctx); 116 unsigned int (*get_fw_errcode)(struct sst_dsp *ctx);
117 int (*load_mod)(struct sst_dsp *ctx, u16 mod_id, char *mod_name);
118 int (*unload_mod)(struct sst_dsp *ctx, u16 mod_id);
119
117}; 120};
118 121
119struct skl_dsp_loader_ops { 122struct skl_dsp_loader_ops {
@@ -123,6 +126,17 @@ struct skl_dsp_loader_ops {
123 struct snd_dma_buffer *dmab); 126 struct snd_dma_buffer *dmab);
124}; 127};
125 128
129struct skl_load_module_info {
130 u16 mod_id;
131 const struct firmware *fw;
132};
133
134struct skl_module_table {
135 struct skl_load_module_info *mod_info;
136 unsigned int usage_cnt;
137 struct list_head list;
138};
139
126void skl_cldma_process_intr(struct sst_dsp *ctx); 140void skl_cldma_process_intr(struct sst_dsp *ctx);
127void skl_cldma_int_disable(struct sst_dsp *ctx); 141void skl_cldma_int_disable(struct sst_dsp *ctx);
128int skl_cldma_prepare(struct sst_dsp *ctx); 142int skl_cldma_prepare(struct sst_dsp *ctx);
@@ -139,7 +153,8 @@ void skl_dsp_free(struct sst_dsp *dsp);
139 153
140int skl_dsp_boot(struct sst_dsp *ctx); 154int skl_dsp_boot(struct sst_dsp *ctx);
141int skl_sst_dsp_init(struct device *dev, void __iomem *mmio_base, int irq, 155int skl_sst_dsp_init(struct device *dev, void __iomem *mmio_base, int irq,
142 struct skl_dsp_loader_ops dsp_ops, struct skl_sst **dsp); 156 const char *fw_name, struct skl_dsp_loader_ops dsp_ops,
157 struct skl_sst **dsp);
143void skl_sst_dsp_cleanup(struct device *dev, struct skl_sst *ctx); 158void skl_sst_dsp_cleanup(struct device *dev, struct skl_sst *ctx);
144 159
145#endif /*__SKL_SST_DSP_H__*/ 160#endif /*__SKL_SST_DSP_H__*/
diff --git a/sound/soc/intel/skylake/skl-sst-ipc.c b/sound/soc/intel/skylake/skl-sst-ipc.c
index 3345ea0d4414..543460293b00 100644
--- a/sound/soc/intel/skylake/skl-sst-ipc.c
+++ b/sound/soc/intel/skylake/skl-sst-ipc.c
@@ -16,8 +16,10 @@
16 16
17#include "../common/sst-dsp.h" 17#include "../common/sst-dsp.h"
18#include "../common/sst-dsp-priv.h" 18#include "../common/sst-dsp-priv.h"
19#include "skl.h"
19#include "skl-sst-dsp.h" 20#include "skl-sst-dsp.h"
20#include "skl-sst-ipc.h" 21#include "skl-sst-ipc.h"
22#include "sound/hdaudio_ext.h"
21 23
22 24
23#define IPC_IXC_STATUS_BITS 24 25#define IPC_IXC_STATUS_BITS 24
@@ -130,6 +132,11 @@
130#define IPC_SRC_QUEUE_MASK 0x7 132#define IPC_SRC_QUEUE_MASK 0x7
131#define IPC_SRC_QUEUE(x) (((x) & IPC_SRC_QUEUE_MASK) \ 133#define IPC_SRC_QUEUE(x) (((x) & IPC_SRC_QUEUE_MASK) \
132 << IPC_SRC_QUEUE_SHIFT) 134 << IPC_SRC_QUEUE_SHIFT)
135/* Load Module count */
136#define IPC_LOAD_MODULE_SHIFT 0
137#define IPC_LOAD_MODULE_MASK 0xFF
138#define IPC_LOAD_MODULE_CNT(x) (((x) & IPC_LOAD_MODULE_MASK) \
139 << IPC_LOAD_MODULE_SHIFT)
133 140
134/* Save pipeline messgae extension register */ 141/* Save pipeline messgae extension register */
135#define IPC_DMA_ID_SHIFT 0 142#define IPC_DMA_ID_SHIFT 0
@@ -317,6 +324,19 @@ static int skl_ipc_process_notification(struct sst_generic_ipc *ipc,
317 wake_up(&skl->boot_wait); 324 wake_up(&skl->boot_wait);
318 break; 325 break;
319 326
327 case IPC_GLB_NOTIFY_PHRASE_DETECTED:
328 dev_dbg(ipc->dev, "***** Phrase Detected **********\n");
329
330 /*
331 * Per HW recomendation, After phrase detection,
332 * clear the CGCTL.MISCBDCGE.
333 *
334 * This will be set back on stream closure
335 */
336 skl->enable_miscbdcge(ipc->dev, false);
337 skl->miscbdcg_disabled = true;
338 break;
339
320 default: 340 default:
321 dev_err(ipc->dev, "ipc: Unhandled error msg=%x", 341 dev_err(ipc->dev, "ipc: Unhandled error msg=%x",
322 header.primary); 342 header.primary);
@@ -344,6 +364,8 @@ static void skl_ipc_process_reply(struct sst_generic_ipc *ipc,
344 switch (reply) { 364 switch (reply) {
345 case IPC_GLB_REPLY_SUCCESS: 365 case IPC_GLB_REPLY_SUCCESS:
346 dev_info(ipc->dev, "ipc FW reply %x: success\n", header.primary); 366 dev_info(ipc->dev, "ipc FW reply %x: success\n", header.primary);
367 /* copy the rx data from the mailbox */
368 sst_dsp_inbox_read(ipc->dsp, msg->rx_data, msg->rx_size);
347 break; 369 break;
348 370
349 case IPC_GLB_REPLY_OUT_OF_MEMORY: 371 case IPC_GLB_REPLY_OUT_OF_MEMORY:
@@ -650,7 +672,7 @@ int skl_ipc_set_dx(struct sst_generic_ipc *ipc, u8 instance_id,
650 dev_dbg(ipc->dev, "In %s primary =%x ext=%x\n", __func__, 672 dev_dbg(ipc->dev, "In %s primary =%x ext=%x\n", __func__,
651 header.primary, header.extension); 673 header.primary, header.extension);
652 ret = sst_ipc_tx_message_wait(ipc, *ipc_header, 674 ret = sst_ipc_tx_message_wait(ipc, *ipc_header,
653 dx, sizeof(dx), NULL, 0); 675 dx, sizeof(*dx), NULL, 0);
654 if (ret < 0) { 676 if (ret < 0) {
655 dev_err(ipc->dev, "ipc: set dx failed, err %d\n", ret); 677 dev_err(ipc->dev, "ipc: set dx failed, err %d\n", ret);
656 return ret; 678 return ret;
@@ -728,6 +750,54 @@ int skl_ipc_bind_unbind(struct sst_generic_ipc *ipc,
728} 750}
729EXPORT_SYMBOL_GPL(skl_ipc_bind_unbind); 751EXPORT_SYMBOL_GPL(skl_ipc_bind_unbind);
730 752
753/*
754 * In order to load a module we need to send IPC to initiate that. DMA will
755 * performed to load the module memory. The FW supports multiple module load
756 * at single shot, so we can send IPC with N modules represented by
757 * module_cnt
758 */
759int skl_ipc_load_modules(struct sst_generic_ipc *ipc,
760 u8 module_cnt, void *data)
761{
762 struct skl_ipc_header header = {0};
763 u64 *ipc_header = (u64 *)(&header);
764 int ret;
765
766 header.primary = IPC_MSG_TARGET(IPC_FW_GEN_MSG);
767 header.primary |= IPC_MSG_DIR(IPC_MSG_REQUEST);
768 header.primary |= IPC_GLB_TYPE(IPC_GLB_LOAD_MULTIPLE_MODS);
769 header.primary |= IPC_LOAD_MODULE_CNT(module_cnt);
770
771 ret = sst_ipc_tx_message_wait(ipc, *ipc_header, data,
772 (sizeof(u16) * module_cnt), NULL, 0);
773 if (ret < 0)
774 dev_err(ipc->dev, "ipc: load modules failed :%d\n", ret);
775
776 return ret;
777}
778EXPORT_SYMBOL_GPL(skl_ipc_load_modules);
779
780int skl_ipc_unload_modules(struct sst_generic_ipc *ipc, u8 module_cnt,
781 void *data)
782{
783 struct skl_ipc_header header = {0};
784 u64 *ipc_header = (u64 *)(&header);
785 int ret;
786
787 header.primary = IPC_MSG_TARGET(IPC_FW_GEN_MSG);
788 header.primary |= IPC_MSG_DIR(IPC_MSG_REQUEST);
789 header.primary |= IPC_GLB_TYPE(IPC_GLB_UNLOAD_MULTIPLE_MODS);
790 header.primary |= IPC_LOAD_MODULE_CNT(module_cnt);
791
792 ret = sst_ipc_tx_message_wait(ipc, *ipc_header, data,
793 (sizeof(u16) * module_cnt), NULL, 0);
794 if (ret < 0)
795 dev_err(ipc->dev, "ipc: unload modules failed :%d\n", ret);
796
797 return ret;
798}
799EXPORT_SYMBOL_GPL(skl_ipc_unload_modules);
800
731int skl_ipc_set_large_config(struct sst_generic_ipc *ipc, 801int skl_ipc_set_large_config(struct sst_generic_ipc *ipc,
732 struct skl_ipc_large_config_msg *msg, u32 *param) 802 struct skl_ipc_large_config_msg *msg, u32 *param)
733{ 803{
@@ -781,3 +851,54 @@ int skl_ipc_set_large_config(struct sst_generic_ipc *ipc,
781 return ret; 851 return ret;
782} 852}
783EXPORT_SYMBOL_GPL(skl_ipc_set_large_config); 853EXPORT_SYMBOL_GPL(skl_ipc_set_large_config);
854
855int skl_ipc_get_large_config(struct sst_generic_ipc *ipc,
856 struct skl_ipc_large_config_msg *msg, u32 *param)
857{
858 struct skl_ipc_header header = {0};
859 u64 *ipc_header = (u64 *)(&header);
860 int ret = 0;
861 size_t sz_remaining, rx_size, data_offset;
862
863 header.primary = IPC_MSG_TARGET(IPC_MOD_MSG);
864 header.primary |= IPC_MSG_DIR(IPC_MSG_REQUEST);
865 header.primary |= IPC_GLB_TYPE(IPC_MOD_LARGE_CONFIG_GET);
866 header.primary |= IPC_MOD_INSTANCE_ID(msg->instance_id);
867 header.primary |= IPC_MOD_ID(msg->module_id);
868
869 header.extension = IPC_DATA_OFFSET_SZ(msg->param_data_size);
870 header.extension |= IPC_LARGE_PARAM_ID(msg->large_param_id);
871 header.extension |= IPC_FINAL_BLOCK(1);
872 header.extension |= IPC_INITIAL_BLOCK(1);
873
874 sz_remaining = msg->param_data_size;
875 data_offset = 0;
876
877 while (sz_remaining != 0) {
878 rx_size = sz_remaining > SKL_ADSP_W1_SZ
879 ? SKL_ADSP_W1_SZ : sz_remaining;
880 if (rx_size == sz_remaining)
881 header.extension |= IPC_FINAL_BLOCK(1);
882
883 ret = sst_ipc_tx_message_wait(ipc, *ipc_header, NULL, 0,
884 ((char *)param) + data_offset,
885 msg->param_data_size);
886 if (ret < 0) {
887 dev_err(ipc->dev,
888 "ipc: get large config fail, err: %d\n", ret);
889 return ret;
890 }
891 sz_remaining -= rx_size;
892 data_offset = msg->param_data_size - sz_remaining;
893
894 /* clear the fields */
895 header.extension &= IPC_INITIAL_BLOCK_CLEAR;
896 header.extension &= IPC_DATA_OFFSET_SZ_CLEAR;
897 /* fill the fields */
898 header.extension |= IPC_INITIAL_BLOCK(1);
899 header.extension |= IPC_DATA_OFFSET_SZ(data_offset);
900 }
901
902 return ret;
903}
904EXPORT_SYMBOL_GPL(skl_ipc_get_large_config);
diff --git a/sound/soc/intel/skylake/skl-sst-ipc.h b/sound/soc/intel/skylake/skl-sst-ipc.h
index f1a154e45dc3..d59d1ba62a43 100644
--- a/sound/soc/intel/skylake/skl-sst-ipc.h
+++ b/sound/soc/intel/skylake/skl-sst-ipc.h
@@ -55,6 +55,11 @@ struct skl_sst {
55 55
56 /* IPC messaging */ 56 /* IPC messaging */
57 struct sst_generic_ipc ipc; 57 struct sst_generic_ipc ipc;
58
59 /* callback for miscbdge */
60 void (*enable_miscbdcge)(struct device *dev, bool enable);
61 /*Is CGCTL.MISCBDCGE disabled*/
62 bool miscbdcg_disabled;
58}; 63};
59 64
60struct skl_ipc_init_instance_msg { 65struct skl_ipc_init_instance_msg {
@@ -108,12 +113,21 @@ int skl_ipc_init_instance(struct sst_generic_ipc *sst_ipc,
108int skl_ipc_bind_unbind(struct sst_generic_ipc *sst_ipc, 113int skl_ipc_bind_unbind(struct sst_generic_ipc *sst_ipc,
109 struct skl_ipc_bind_unbind_msg *msg); 114 struct skl_ipc_bind_unbind_msg *msg);
110 115
116int skl_ipc_load_modules(struct sst_generic_ipc *ipc,
117 u8 module_cnt, void *data);
118
119int skl_ipc_unload_modules(struct sst_generic_ipc *ipc,
120 u8 module_cnt, void *data);
121
111int skl_ipc_set_dx(struct sst_generic_ipc *ipc, 122int skl_ipc_set_dx(struct sst_generic_ipc *ipc,
112 u8 instance_id, u16 module_id, struct skl_ipc_dxstate_info *dx); 123 u8 instance_id, u16 module_id, struct skl_ipc_dxstate_info *dx);
113 124
114int skl_ipc_set_large_config(struct sst_generic_ipc *ipc, 125int skl_ipc_set_large_config(struct sst_generic_ipc *ipc,
115 struct skl_ipc_large_config_msg *msg, u32 *param); 126 struct skl_ipc_large_config_msg *msg, u32 *param);
116 127
128int skl_ipc_get_large_config(struct sst_generic_ipc *ipc,
129 struct skl_ipc_large_config_msg *msg, u32 *param);
130
117void skl_ipc_int_enable(struct sst_dsp *dsp); 131void skl_ipc_int_enable(struct sst_dsp *dsp);
118void skl_ipc_op_int_enable(struct sst_dsp *ctx); 132void skl_ipc_op_int_enable(struct sst_dsp *ctx);
119void skl_ipc_op_int_disable(struct sst_dsp *ctx); 133void skl_ipc_op_int_disable(struct sst_dsp *ctx);
diff --git a/sound/soc/intel/skylake/skl-sst.c b/sound/soc/intel/skylake/skl-sst.c
index 3b83dc99f1d4..e26f4746afb7 100644
--- a/sound/soc/intel/skylake/skl-sst.c
+++ b/sound/soc/intel/skylake/skl-sst.c
@@ -19,6 +19,7 @@
19#include <linux/module.h> 19#include <linux/module.h>
20#include <linux/delay.h> 20#include <linux/delay.h>
21#include <linux/device.h> 21#include <linux/device.h>
22#include <linux/err.h>
22#include "../common/sst-dsp.h" 23#include "../common/sst-dsp.h"
23#include "../common/sst-dsp-priv.h" 24#include "../common/sst-dsp-priv.h"
24#include "../common/sst-ipc.h" 25#include "../common/sst-ipc.h"
@@ -37,6 +38,8 @@
37#define SKL_INSTANCE_ID 0 38#define SKL_INSTANCE_ID 0
38#define SKL_BASE_FW_MODULE_ID 0 39#define SKL_BASE_FW_MODULE_ID 0
39 40
41#define SKL_NUM_MODULES 1
42
40static bool skl_check_fw_status(struct sst_dsp *ctx, u32 status) 43static bool skl_check_fw_status(struct sst_dsp *ctx, u32 status)
41{ 44{
42 u32 cur_sts; 45 u32 cur_sts;
@@ -77,7 +80,7 @@ static int skl_load_base_firmware(struct sst_dsp *ctx)
77 init_waitqueue_head(&skl->boot_wait); 80 init_waitqueue_head(&skl->boot_wait);
78 81
79 if (ctx->fw == NULL) { 82 if (ctx->fw == NULL) {
80 ret = request_firmware(&ctx->fw, "dsp_fw_release.bin", ctx->dev); 83 ret = request_firmware(&ctx->fw, ctx->fw_name, ctx->dev);
81 if (ret < 0) { 84 if (ret < 0) {
82 dev_err(ctx->dev, "Request firmware failed %d\n", ret); 85 dev_err(ctx->dev, "Request firmware failed %d\n", ret);
83 skl_dsp_disable_core(ctx); 86 skl_dsp_disable_core(ctx);
@@ -115,27 +118,28 @@ static int skl_load_base_firmware(struct sst_dsp *ctx)
115 dev_err(ctx->dev, 118 dev_err(ctx->dev,
116 "Timeout waiting for ROM init done, reg:0x%x\n", reg); 119 "Timeout waiting for ROM init done, reg:0x%x\n", reg);
117 ret = -EIO; 120 ret = -EIO;
118 goto skl_load_base_firmware_failed; 121 goto transfer_firmware_failed;
119 } 122 }
120 123
121 ret = skl_transfer_firmware(ctx, ctx->fw->data, ctx->fw->size); 124 ret = skl_transfer_firmware(ctx, ctx->fw->data, ctx->fw->size);
122 if (ret < 0) { 125 if (ret < 0) {
123 dev_err(ctx->dev, "Transfer firmware failed%d\n", ret); 126 dev_err(ctx->dev, "Transfer firmware failed%d\n", ret);
124 goto skl_load_base_firmware_failed; 127 goto transfer_firmware_failed;
125 } else { 128 } else {
126 ret = wait_event_timeout(skl->boot_wait, skl->boot_complete, 129 ret = wait_event_timeout(skl->boot_wait, skl->boot_complete,
127 msecs_to_jiffies(SKL_IPC_BOOT_MSECS)); 130 msecs_to_jiffies(SKL_IPC_BOOT_MSECS));
128 if (ret == 0) { 131 if (ret == 0) {
129 dev_err(ctx->dev, "DSP boot failed, FW Ready timed-out\n"); 132 dev_err(ctx->dev, "DSP boot failed, FW Ready timed-out\n");
130 ret = -EIO; 133 ret = -EIO;
131 goto skl_load_base_firmware_failed; 134 goto transfer_firmware_failed;
132 } 135 }
133 136
134 dev_dbg(ctx->dev, "Download firmware successful%d\n", ret); 137 dev_dbg(ctx->dev, "Download firmware successful%d\n", ret);
135 skl_dsp_set_state_locked(ctx, SKL_DSP_RUNNING); 138 skl_dsp_set_state_locked(ctx, SKL_DSP_RUNNING);
136 } 139 }
137 return 0; 140 return 0;
138 141transfer_firmware_failed:
142 ctx->cl_dev.ops.cl_cleanup_controller(ctx);
139skl_load_base_firmware_failed: 143skl_load_base_firmware_failed:
140 skl_dsp_disable_core(ctx); 144 skl_dsp_disable_core(ctx);
141 release_firmware(ctx->fw); 145 release_firmware(ctx->fw);
@@ -175,10 +179,15 @@ static int skl_set_dsp_D3(struct sst_dsp *ctx)
175 dx.core_mask = SKL_DSP_CORE0_MASK; 179 dx.core_mask = SKL_DSP_CORE0_MASK;
176 dx.dx_mask = SKL_IPC_D3_MASK; 180 dx.dx_mask = SKL_IPC_D3_MASK;
177 ret = skl_ipc_set_dx(&skl->ipc, SKL_INSTANCE_ID, SKL_BASE_FW_MODULE_ID, &dx); 181 ret = skl_ipc_set_dx(&skl->ipc, SKL_INSTANCE_ID, SKL_BASE_FW_MODULE_ID, &dx);
178 if (ret < 0) { 182 if (ret < 0)
179 dev_err(ctx->dev, "Failed to set DSP to D3 state\n"); 183 dev_err(ctx->dev,
180 return ret; 184 "D3 request to FW failed, continuing reset: %d", ret);
181 } 185
186 /* disable Interrupt */
187 ctx->cl_dev.ops.cl_cleanup_controller(ctx);
188 skl_cldma_int_disable(ctx);
189 skl_ipc_op_int_disable(ctx);
190 skl_ipc_int_disable(ctx);
182 191
183 ret = skl_dsp_disable_core(ctx); 192 ret = skl_dsp_disable_core(ctx);
184 if (ret < 0) { 193 if (ret < 0) {
@@ -187,12 +196,6 @@ static int skl_set_dsp_D3(struct sst_dsp *ctx)
187 } 196 }
188 skl_dsp_set_state_locked(ctx, SKL_DSP_RESET); 197 skl_dsp_set_state_locked(ctx, SKL_DSP_RESET);
189 198
190 /* disable Interrupt */
191 ctx->cl_dev.ops.cl_cleanup_controller(ctx);
192 skl_cldma_int_disable(ctx);
193 skl_ipc_op_int_disable(ctx);
194 skl_ipc_int_disable(ctx);
195
196 return ret; 199 return ret;
197} 200}
198 201
@@ -201,11 +204,182 @@ static unsigned int skl_get_errorcode(struct sst_dsp *ctx)
201 return sst_dsp_shim_read(ctx, SKL_ADSP_ERROR_CODE); 204 return sst_dsp_shim_read(ctx, SKL_ADSP_ERROR_CODE);
202} 205}
203 206
207/*
208 * since get/set_module are called from DAPM context,
209 * we don't need lock for usage count
210 */
211static int skl_get_module(struct sst_dsp *ctx, u16 mod_id)
212{
213 struct skl_module_table *module;
214
215 list_for_each_entry(module, &ctx->module_list, list) {
216 if (module->mod_info->mod_id == mod_id)
217 return ++module->usage_cnt;
218 }
219
220 return -EINVAL;
221}
222
223static int skl_put_module(struct sst_dsp *ctx, u16 mod_id)
224{
225 struct skl_module_table *module;
226
227 list_for_each_entry(module, &ctx->module_list, list) {
228 if (module->mod_info->mod_id == mod_id)
229 return --module->usage_cnt;
230 }
231
232 return -EINVAL;
233}
234
235static struct skl_module_table *skl_fill_module_table(struct sst_dsp *ctx,
236 char *mod_name, int mod_id)
237{
238 const struct firmware *fw;
239 struct skl_module_table *skl_module;
240 unsigned int size;
241 int ret;
242
243 ret = request_firmware(&fw, mod_name, ctx->dev);
244 if (ret < 0) {
245 dev_err(ctx->dev, "Request Module %s failed :%d\n",
246 mod_name, ret);
247 return NULL;
248 }
249
250 skl_module = devm_kzalloc(ctx->dev, sizeof(*skl_module), GFP_KERNEL);
251 if (skl_module == NULL) {
252 release_firmware(fw);
253 return NULL;
254 }
255
256 size = sizeof(*skl_module->mod_info);
257 skl_module->mod_info = devm_kzalloc(ctx->dev, size, GFP_KERNEL);
258 if (skl_module->mod_info == NULL) {
259 release_firmware(fw);
260 return NULL;
261 }
262
263 skl_module->mod_info->mod_id = mod_id;
264 skl_module->mod_info->fw = fw;
265 list_add(&skl_module->list, &ctx->module_list);
266
267 return skl_module;
268}
269
270/* get a module from it's unique ID */
271static struct skl_module_table *skl_module_get_from_id(
272 struct sst_dsp *ctx, u16 mod_id)
273{
274 struct skl_module_table *module;
275
276 if (list_empty(&ctx->module_list)) {
277 dev_err(ctx->dev, "Module list is empty\n");
278 return NULL;
279 }
280
281 list_for_each_entry(module, &ctx->module_list, list) {
282 if (module->mod_info->mod_id == mod_id)
283 return module;
284 }
285
286 return NULL;
287}
288
289static int skl_transfer_module(struct sst_dsp *ctx,
290 struct skl_load_module_info *module)
291{
292 int ret;
293 struct skl_sst *skl = ctx->thread_context;
294
295 ret = ctx->cl_dev.ops.cl_copy_to_dmabuf(ctx, module->fw->data,
296 module->fw->size);
297 if (ret < 0)
298 return ret;
299
300 ret = skl_ipc_load_modules(&skl->ipc, SKL_NUM_MODULES,
301 (void *)&module->mod_id);
302 if (ret < 0)
303 dev_err(ctx->dev, "Failed to Load module: %d\n", ret);
304
305 ctx->cl_dev.ops.cl_stop_dma(ctx);
306
307 return ret;
308}
309
310static int skl_load_module(struct sst_dsp *ctx, u16 mod_id, char *guid)
311{
312 struct skl_module_table *module_entry = NULL;
313 int ret = 0;
314 char mod_name[64]; /* guid str = 32 chars + 4 hyphens */
315
316 snprintf(mod_name, sizeof(mod_name), "%s%s%s",
317 "intel/dsp_fw_", guid, ".bin");
318
319 module_entry = skl_module_get_from_id(ctx, mod_id);
320 if (module_entry == NULL) {
321 module_entry = skl_fill_module_table(ctx, mod_name, mod_id);
322 if (module_entry == NULL) {
323 dev_err(ctx->dev, "Failed to Load module\n");
324 return -EINVAL;
325 }
326 }
327
328 if (!module_entry->usage_cnt) {
329 ret = skl_transfer_module(ctx, module_entry->mod_info);
330 if (ret < 0) {
331 dev_err(ctx->dev, "Failed to Load module\n");
332 return ret;
333 }
334 }
335
336 ret = skl_get_module(ctx, mod_id);
337
338 return ret;
339}
340
341static int skl_unload_module(struct sst_dsp *ctx, u16 mod_id)
342{
343 int usage_cnt;
344 struct skl_sst *skl = ctx->thread_context;
345 int ret = 0;
346
347 usage_cnt = skl_put_module(ctx, mod_id);
348 if (usage_cnt < 0) {
349 dev_err(ctx->dev, "Module bad usage cnt!:%d\n", usage_cnt);
350 return -EIO;
351 }
352 ret = skl_ipc_unload_modules(&skl->ipc,
353 SKL_NUM_MODULES, &mod_id);
354 if (ret < 0) {
355 dev_err(ctx->dev, "Failed to UnLoad module\n");
356 skl_get_module(ctx, mod_id);
357 return ret;
358 }
359
360 return ret;
361}
362
363static void skl_clear_module_table(struct sst_dsp *ctx)
364{
365 struct skl_module_table *module, *tmp;
366
367 if (list_empty(&ctx->module_list))
368 return;
369
370 list_for_each_entry_safe(module, tmp, &ctx->module_list, list) {
371 list_del(&module->list);
372 release_firmware(module->mod_info->fw);
373 }
374}
375
204static struct skl_dsp_fw_ops skl_fw_ops = { 376static struct skl_dsp_fw_ops skl_fw_ops = {
205 .set_state_D0 = skl_set_dsp_D0, 377 .set_state_D0 = skl_set_dsp_D0,
206 .set_state_D3 = skl_set_dsp_D3, 378 .set_state_D3 = skl_set_dsp_D3,
207 .load_fw = skl_load_base_firmware, 379 .load_fw = skl_load_base_firmware,
208 .get_fw_errcode = skl_get_errorcode, 380 .get_fw_errcode = skl_get_errorcode,
381 .load_mod = skl_load_module,
382 .unload_mod = skl_unload_module,
209}; 383};
210 384
211static struct sst_ops skl_ops = { 385static struct sst_ops skl_ops = {
@@ -223,7 +397,7 @@ static struct sst_dsp_device skl_dev = {
223}; 397};
224 398
225int skl_sst_dsp_init(struct device *dev, void __iomem *mmio_base, int irq, 399int skl_sst_dsp_init(struct device *dev, void __iomem *mmio_base, int irq,
226 struct skl_dsp_loader_ops dsp_ops, struct skl_sst **dsp) 400 const char *fw_name, struct skl_dsp_loader_ops dsp_ops, struct skl_sst **dsp)
227{ 401{
228 struct skl_sst *skl; 402 struct skl_sst *skl;
229 struct sst_dsp *sst; 403 struct sst_dsp *sst;
@@ -244,11 +418,13 @@ int skl_sst_dsp_init(struct device *dev, void __iomem *mmio_base, int irq,
244 418
245 sst = skl->dsp; 419 sst = skl->dsp;
246 420
421 sst->fw_name = fw_name;
247 sst->addr.lpe = mmio_base; 422 sst->addr.lpe = mmio_base;
248 sst->addr.shim = mmio_base; 423 sst->addr.shim = mmio_base;
249 sst_dsp_mailbox_init(sst, (SKL_ADSP_SRAM0_BASE + SKL_ADSP_W0_STAT_SZ), 424 sst_dsp_mailbox_init(sst, (SKL_ADSP_SRAM0_BASE + SKL_ADSP_W0_STAT_SZ),
250 SKL_ADSP_W0_UP_SZ, SKL_ADSP_SRAM1_BASE, SKL_ADSP_W1_SZ); 425 SKL_ADSP_W0_UP_SZ, SKL_ADSP_SRAM1_BASE, SKL_ADSP_W1_SZ);
251 426
427 INIT_LIST_HEAD(&sst->module_list);
252 sst->dsp_ops = dsp_ops; 428 sst->dsp_ops = dsp_ops;
253 sst->fw_ops = skl_fw_ops; 429 sst->fw_ops = skl_fw_ops;
254 430
@@ -259,23 +435,24 @@ int skl_sst_dsp_init(struct device *dev, void __iomem *mmio_base, int irq,
259 ret = sst->fw_ops.load_fw(sst); 435 ret = sst->fw_ops.load_fw(sst);
260 if (ret < 0) { 436 if (ret < 0) {
261 dev_err(dev, "Load base fw failed : %d", ret); 437 dev_err(dev, "Load base fw failed : %d", ret);
262 return ret; 438 goto cleanup;
263 } 439 }
264 440
265 if (dsp) 441 if (dsp)
266 *dsp = skl; 442 *dsp = skl;
267 443
268 return 0; 444 return ret;
269 445
270 skl_ipc_free(&skl->ipc); 446cleanup:
447 skl_sst_dsp_cleanup(dev, skl);
271 return ret; 448 return ret;
272} 449}
273EXPORT_SYMBOL_GPL(skl_sst_dsp_init); 450EXPORT_SYMBOL_GPL(skl_sst_dsp_init);
274 451
275void skl_sst_dsp_cleanup(struct device *dev, struct skl_sst *ctx) 452void skl_sst_dsp_cleanup(struct device *dev, struct skl_sst *ctx)
276{ 453{
454 skl_clear_module_table(ctx->dsp);
277 skl_ipc_free(&ctx->ipc); 455 skl_ipc_free(&ctx->ipc);
278 ctx->dsp->cl_dev.ops.cl_cleanup_controller(ctx->dsp);
279 ctx->dsp->ops->free(ctx->dsp); 456 ctx->dsp->ops->free(ctx->dsp);
280} 457}
281EXPORT_SYMBOL_GPL(skl_sst_dsp_cleanup); 458EXPORT_SYMBOL_GPL(skl_sst_dsp_cleanup);
diff --git a/sound/soc/intel/skylake/skl-topology.c b/sound/soc/intel/skylake/skl-topology.c
index ad4d0f82603e..4624556f486d 100644
--- a/sound/soc/intel/skylake/skl-topology.c
+++ b/sound/soc/intel/skylake/skl-topology.c
@@ -26,6 +26,8 @@
26#include "skl-topology.h" 26#include "skl-topology.h"
27#include "skl.h" 27#include "skl.h"
28#include "skl-tplg-interface.h" 28#include "skl-tplg-interface.h"
29#include "../common/sst-dsp.h"
30#include "../common/sst-dsp-priv.h"
29 31
30#define SKL_CH_FIXUP_MASK (1 << 0) 32#define SKL_CH_FIXUP_MASK (1 << 0)
31#define SKL_RATE_FIXUP_MASK (1 << 1) 33#define SKL_RATE_FIXUP_MASK (1 << 1)
@@ -129,17 +131,15 @@ static void skl_dump_mconfig(struct skl_sst *ctx,
129{ 131{
130 dev_dbg(ctx->dev, "Dumping config\n"); 132 dev_dbg(ctx->dev, "Dumping config\n");
131 dev_dbg(ctx->dev, "Input Format:\n"); 133 dev_dbg(ctx->dev, "Input Format:\n");
132 dev_dbg(ctx->dev, "channels = %d\n", mcfg->in_fmt.channels); 134 dev_dbg(ctx->dev, "channels = %d\n", mcfg->in_fmt[0].channels);
133 dev_dbg(ctx->dev, "s_freq = %d\n", mcfg->in_fmt.s_freq); 135 dev_dbg(ctx->dev, "s_freq = %d\n", mcfg->in_fmt[0].s_freq);
134 dev_dbg(ctx->dev, "ch_cfg = %d\n", mcfg->in_fmt.ch_cfg); 136 dev_dbg(ctx->dev, "ch_cfg = %d\n", mcfg->in_fmt[0].ch_cfg);
135 dev_dbg(ctx->dev, "valid bit depth = %d\n", 137 dev_dbg(ctx->dev, "valid bit depth = %d\n", mcfg->in_fmt[0].valid_bit_depth);
136 mcfg->in_fmt.valid_bit_depth);
137 dev_dbg(ctx->dev, "Output Format:\n"); 138 dev_dbg(ctx->dev, "Output Format:\n");
138 dev_dbg(ctx->dev, "channels = %d\n", mcfg->out_fmt.channels); 139 dev_dbg(ctx->dev, "channels = %d\n", mcfg->out_fmt[0].channels);
139 dev_dbg(ctx->dev, "s_freq = %d\n", mcfg->out_fmt.s_freq); 140 dev_dbg(ctx->dev, "s_freq = %d\n", mcfg->out_fmt[0].s_freq);
140 dev_dbg(ctx->dev, "valid bit depth = %d\n", 141 dev_dbg(ctx->dev, "valid bit depth = %d\n", mcfg->out_fmt[0].valid_bit_depth);
141 mcfg->out_fmt.valid_bit_depth); 142 dev_dbg(ctx->dev, "ch_cfg = %d\n", mcfg->out_fmt[0].ch_cfg);
142 dev_dbg(ctx->dev, "ch_cfg = %d\n", mcfg->out_fmt.ch_cfg);
143} 143}
144 144
145static void skl_tplg_update_params(struct skl_module_fmt *fmt, 145static void skl_tplg_update_params(struct skl_module_fmt *fmt,
@@ -149,8 +149,24 @@ static void skl_tplg_update_params(struct skl_module_fmt *fmt,
149 fmt->s_freq = params->s_freq; 149 fmt->s_freq = params->s_freq;
150 if (fixup & SKL_CH_FIXUP_MASK) 150 if (fixup & SKL_CH_FIXUP_MASK)
151 fmt->channels = params->ch; 151 fmt->channels = params->ch;
152 if (fixup & SKL_FMT_FIXUP_MASK) 152 if (fixup & SKL_FMT_FIXUP_MASK) {
153 fmt->valid_bit_depth = params->s_fmt; 153 fmt->valid_bit_depth = skl_get_bit_depth(params->s_fmt);
154
155 /*
156 * 16 bit is 16 bit container whereas 24 bit is in 32 bit
157 * container so update bit depth accordingly
158 */
159 switch (fmt->valid_bit_depth) {
160 case SKL_DEPTH_16BIT:
161 fmt->bit_depth = fmt->valid_bit_depth;
162 break;
163
164 default:
165 fmt->bit_depth = SKL_DEPTH_32BIT;
166 break;
167 }
168 }
169
154} 170}
155 171
156/* 172/*
@@ -171,8 +187,9 @@ static void skl_tplg_update_params_fixup(struct skl_module_cfg *m_cfg,
171 int in_fixup, out_fixup; 187 int in_fixup, out_fixup;
172 struct skl_module_fmt *in_fmt, *out_fmt; 188 struct skl_module_fmt *in_fmt, *out_fmt;
173 189
174 in_fmt = &m_cfg->in_fmt; 190 /* Fixups will be applied to pin 0 only */
175 out_fmt = &m_cfg->out_fmt; 191 in_fmt = &m_cfg->in_fmt[0];
192 out_fmt = &m_cfg->out_fmt[0];
176 193
177 if (params->stream == SNDRV_PCM_STREAM_PLAYBACK) { 194 if (params->stream == SNDRV_PCM_STREAM_PLAYBACK) {
178 if (is_fe) { 195 if (is_fe) {
@@ -209,18 +226,25 @@ static void skl_tplg_update_buffer_size(struct skl_sst *ctx,
209 struct skl_module_cfg *mcfg) 226 struct skl_module_cfg *mcfg)
210{ 227{
211 int multiplier = 1; 228 int multiplier = 1;
229 struct skl_module_fmt *in_fmt, *out_fmt;
230
231
232 /* Since fixups is applied to pin 0 only, ibs, obs needs
233 * change for pin 0 only
234 */
235 in_fmt = &mcfg->in_fmt[0];
236 out_fmt = &mcfg->out_fmt[0];
212 237
213 if (mcfg->m_type == SKL_MODULE_TYPE_SRCINT) 238 if (mcfg->m_type == SKL_MODULE_TYPE_SRCINT)
214 multiplier = 5; 239 multiplier = 5;
215 240 mcfg->ibs = (in_fmt->s_freq / 1000) *
216 mcfg->ibs = (mcfg->in_fmt.s_freq / 1000) * 241 (mcfg->in_fmt->channels) *
217 (mcfg->in_fmt.channels) * 242 (mcfg->in_fmt->bit_depth >> 3) *
218 (mcfg->in_fmt.bit_depth >> 3) *
219 multiplier; 243 multiplier;
220 244
221 mcfg->obs = (mcfg->out_fmt.s_freq / 1000) * 245 mcfg->obs = (mcfg->out_fmt->s_freq / 1000) *
222 (mcfg->out_fmt.channels) * 246 (mcfg->out_fmt->channels) *
223 (mcfg->out_fmt.bit_depth >> 3) * 247 (mcfg->out_fmt->bit_depth >> 3) *
224 multiplier; 248 multiplier;
225} 249}
226 250
@@ -292,6 +316,83 @@ static int skl_tplg_alloc_pipe_widget(struct device *dev,
292} 316}
293 317
294/* 318/*
319 * some modules can have multiple params set from user control and
320 * need to be set after module is initialized. If set_param flag is
321 * set module params will be done after module is initialised.
322 */
323static int skl_tplg_set_module_params(struct snd_soc_dapm_widget *w,
324 struct skl_sst *ctx)
325{
326 int i, ret;
327 struct skl_module_cfg *mconfig = w->priv;
328 const struct snd_kcontrol_new *k;
329 struct soc_bytes_ext *sb;
330 struct skl_algo_data *bc;
331 struct skl_specific_cfg *sp_cfg;
332
333 if (mconfig->formats_config.caps_size > 0 &&
334 mconfig->formats_config.set_params == SKL_PARAM_SET) {
335 sp_cfg = &mconfig->formats_config;
336 ret = skl_set_module_params(ctx, sp_cfg->caps,
337 sp_cfg->caps_size,
338 sp_cfg->param_id, mconfig);
339 if (ret < 0)
340 return ret;
341 }
342
343 for (i = 0; i < w->num_kcontrols; i++) {
344 k = &w->kcontrol_news[i];
345 if (k->access & SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK) {
346 sb = (void *) k->private_value;
347 bc = (struct skl_algo_data *)sb->dobj.private;
348
349 if (bc->set_params == SKL_PARAM_SET) {
350 ret = skl_set_module_params(ctx,
351 (u32 *)bc->params, bc->max,
352 bc->param_id, mconfig);
353 if (ret < 0)
354 return ret;
355 }
356 }
357 }
358
359 return 0;
360}
361
362/*
363 * some module param can set from user control and this is required as
364 * when module is initailzed. if module param is required in init it is
365 * identifed by set_param flag. if set_param flag is not set, then this
366 * parameter needs to set as part of module init.
367 */
368static int skl_tplg_set_module_init_data(struct snd_soc_dapm_widget *w)
369{
370 const struct snd_kcontrol_new *k;
371 struct soc_bytes_ext *sb;
372 struct skl_algo_data *bc;
373 struct skl_module_cfg *mconfig = w->priv;
374 int i;
375
376 for (i = 0; i < w->num_kcontrols; i++) {
377 k = &w->kcontrol_news[i];
378 if (k->access & SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK) {
379 sb = (struct soc_bytes_ext *)k->private_value;
380 bc = (struct skl_algo_data *)sb->dobj.private;
381
382 if (bc->set_params != SKL_PARAM_INIT)
383 continue;
384
385 mconfig->formats_config.caps = (u32 *)&bc->params;
386 mconfig->formats_config.caps_size = bc->max;
387
388 break;
389 }
390 }
391
392 return 0;
393}
394
395/*
295 * Inside a pipe instance, we can have various modules. These modules need 396 * Inside a pipe instance, we can have various modules. These modules need
296 * to instantiated in DSP by invoking INIT_MODULE IPC, which is achieved by 397 * to instantiated in DSP by invoking INIT_MODULE IPC, which is achieved by
297 * skl_init_module() routine, so invoke that for all modules in a pipeline 398 * skl_init_module() routine, so invoke that for all modules in a pipeline
@@ -313,12 +414,25 @@ skl_tplg_init_pipe_modules(struct skl *skl, struct skl_pipe *pipe)
313 if (!skl_tplg_alloc_pipe_mcps(skl, mconfig)) 414 if (!skl_tplg_alloc_pipe_mcps(skl, mconfig))
314 return -ENOMEM; 415 return -ENOMEM;
315 416
417 if (mconfig->is_loadable && ctx->dsp->fw_ops.load_mod) {
418 ret = ctx->dsp->fw_ops.load_mod(ctx->dsp,
419 mconfig->id.module_id, mconfig->guid);
420 if (ret < 0)
421 return ret;
422 }
423
316 /* 424 /*
317 * apply fix/conversion to module params based on 425 * apply fix/conversion to module params based on
318 * FE/BE params 426 * FE/BE params
319 */ 427 */
320 skl_tplg_update_module_params(w, ctx); 428 skl_tplg_update_module_params(w, ctx);
321 ret = skl_init_module(ctx, mconfig, NULL); 429
430 skl_tplg_set_module_init_data(w);
431 ret = skl_init_module(ctx, mconfig);
432 if (ret < 0)
433 return ret;
434
435 ret = skl_tplg_set_module_params(w, ctx);
322 if (ret < 0) 436 if (ret < 0)
323 return ret; 437 return ret;
324 } 438 }
@@ -326,6 +440,24 @@ skl_tplg_init_pipe_modules(struct skl *skl, struct skl_pipe *pipe)
326 return 0; 440 return 0;
327} 441}
328 442
443static int skl_tplg_unload_pipe_modules(struct skl_sst *ctx,
444 struct skl_pipe *pipe)
445{
446 struct skl_pipe_module *w_module = NULL;
447 struct skl_module_cfg *mconfig = NULL;
448
449 list_for_each_entry(w_module, &pipe->w_list, node) {
450 mconfig = w_module->w->priv;
451
452 if (mconfig->is_loadable && ctx->dsp->fw_ops.unload_mod)
453 return ctx->dsp->fw_ops.unload_mod(ctx->dsp,
454 mconfig->id.module_id);
455 }
456
457 /* no modules to unload in this path, so return */
458 return 0;
459}
460
329/* 461/*
330 * Mixer module represents a pipeline. So in the Pre-PMU event of mixer we 462 * Mixer module represents a pipeline. So in the Pre-PMU event of mixer we
331 * need create the pipeline. So we do following: 463 * need create the pipeline. So we do following:
@@ -397,41 +529,24 @@ static int skl_tplg_mixer_dapm_pre_pmu_event(struct snd_soc_dapm_widget *w,
397 return 0; 529 return 0;
398} 530}
399 531
400/* 532static int skl_tplg_bind_sinks(struct snd_soc_dapm_widget *w,
401 * A PGA represents a module in a pipeline. So in the Pre-PMU event of PGA 533 struct skl *skl,
402 * we need to do following: 534 struct skl_module_cfg *src_mconfig)
403 * - Bind to sink pipeline
404 * Since the sink pipes can be running and we don't get mixer event on
405 * connect for already running mixer, we need to find the sink pipes
406 * here and bind to them. This way dynamic connect works.
407 * - Start sink pipeline, if not running
408 * - Then run current pipe
409 */
410static int skl_tplg_pga_dapm_pre_pmu_event(struct snd_soc_dapm_widget *w,
411 struct skl *skl)
412{ 535{
413 struct snd_soc_dapm_path *p; 536 struct snd_soc_dapm_path *p;
414 struct skl_dapm_path_list *path_list; 537 struct snd_soc_dapm_widget *sink = NULL, *next_sink = NULL;
415 struct snd_soc_dapm_widget *source, *sink; 538 struct skl_module_cfg *sink_mconfig;
416 struct skl_module_cfg *src_mconfig, *sink_mconfig;
417 struct skl_sst *ctx = skl->skl_sst; 539 struct skl_sst *ctx = skl->skl_sst;
418 int ret = 0; 540 int ret;
419
420 source = w;
421 src_mconfig = source->priv;
422 541
423 /* 542 snd_soc_dapm_widget_for_each_sink_path(w, p) {
424 * find which sink it is connected to, bind with the sink,
425 * if sink is not started, start sink pipe first, then start
426 * this pipe
427 */
428 snd_soc_dapm_widget_for_each_source_path(w, p) {
429 if (!p->connect) 543 if (!p->connect)
430 continue; 544 continue;
431 545
432 dev_dbg(ctx->dev, "%s: src widget=%s\n", __func__, w->name); 546 dev_dbg(ctx->dev, "%s: src widget=%s\n", __func__, w->name);
433 dev_dbg(ctx->dev, "%s: sink widget=%s\n", __func__, p->sink->name); 547 dev_dbg(ctx->dev, "%s: sink widget=%s\n", __func__, p->sink->name);
434 548
549 next_sink = p->sink;
435 /* 550 /*
436 * here we will check widgets in sink pipelines, so that 551 * here we will check widgets in sink pipelines, so that
437 * can be any widgets type and we are only interested if 552 * can be any widgets type and we are only interested if
@@ -441,7 +556,6 @@ static int skl_tplg_pga_dapm_pre_pmu_event(struct snd_soc_dapm_widget *w,
441 is_skl_dsp_widget_type(p->sink)) { 556 is_skl_dsp_widget_type(p->sink)) {
442 557
443 sink = p->sink; 558 sink = p->sink;
444 src_mconfig = source->priv;
445 sink_mconfig = sink->priv; 559 sink_mconfig = sink->priv;
446 560
447 /* Bind source to sink, mixin is always source */ 561 /* Bind source to sink, mixin is always source */
@@ -451,32 +565,89 @@ static int skl_tplg_pga_dapm_pre_pmu_event(struct snd_soc_dapm_widget *w,
451 565
452 /* Start sinks pipe first */ 566 /* Start sinks pipe first */
453 if (sink_mconfig->pipe->state != SKL_PIPE_STARTED) { 567 if (sink_mconfig->pipe->state != SKL_PIPE_STARTED) {
454 ret = skl_run_pipe(ctx, sink_mconfig->pipe); 568 if (sink_mconfig->pipe->conn_type !=
569 SKL_PIPE_CONN_TYPE_FE)
570 ret = skl_run_pipe(ctx,
571 sink_mconfig->pipe);
455 if (ret) 572 if (ret)
456 return ret; 573 return ret;
457 } 574 }
458
459 path_list = kzalloc(
460 sizeof(struct skl_dapm_path_list),
461 GFP_KERNEL);
462 if (path_list == NULL)
463 return -ENOMEM;
464
465 /* Add connected path to one global list */
466 path_list->dapm_path = p;
467 list_add_tail(&path_list->node, &skl->dapm_path_list);
468 break;
469 } 575 }
470 } 576 }
471 577
472 /* Start source pipe last after starting all sinks */ 578 if (!sink)
473 ret = skl_run_pipe(ctx, src_mconfig->pipe); 579 return skl_tplg_bind_sinks(next_sink, skl, src_mconfig);
580
581 return 0;
582}
583
584/*
585 * A PGA represents a module in a pipeline. So in the Pre-PMU event of PGA
586 * we need to do following:
587 * - Bind to sink pipeline
588 * Since the sink pipes can be running and we don't get mixer event on
589 * connect for already running mixer, we need to find the sink pipes
590 * here and bind to them. This way dynamic connect works.
591 * - Start sink pipeline, if not running
592 * - Then run current pipe
593 */
594static int skl_tplg_pga_dapm_pre_pmu_event(struct snd_soc_dapm_widget *w,
595 struct skl *skl)
596{
597 struct skl_module_cfg *src_mconfig;
598 struct skl_sst *ctx = skl->skl_sst;
599 int ret = 0;
600
601 src_mconfig = w->priv;
602
603 /*
604 * find which sink it is connected to, bind with the sink,
605 * if sink is not started, start sink pipe first, then start
606 * this pipe
607 */
608 ret = skl_tplg_bind_sinks(w, skl, src_mconfig);
474 if (ret) 609 if (ret)
475 return ret; 610 return ret;
476 611
612 /* Start source pipe last after starting all sinks */
613 if (src_mconfig->pipe->conn_type != SKL_PIPE_CONN_TYPE_FE)
614 return skl_run_pipe(ctx, src_mconfig->pipe);
615
477 return 0; 616 return 0;
478} 617}
479 618
619static struct snd_soc_dapm_widget *skl_get_src_dsp_widget(
620 struct snd_soc_dapm_widget *w, struct skl *skl)
621{
622 struct snd_soc_dapm_path *p;
623 struct snd_soc_dapm_widget *src_w = NULL;
624 struct skl_sst *ctx = skl->skl_sst;
625
626 snd_soc_dapm_widget_for_each_source_path(w, p) {
627 src_w = p->source;
628 if (!p->connect)
629 continue;
630
631 dev_dbg(ctx->dev, "sink widget=%s\n", w->name);
632 dev_dbg(ctx->dev, "src widget=%s\n", p->source->name);
633
634 /*
635 * here we will check widgets in sink pipelines, so that can
636 * be any widgets type and we are only interested if they are
637 * ones used for SKL so check that first
638 */
639 if ((p->source->priv != NULL) &&
640 is_skl_dsp_widget_type(p->source)) {
641 return p->source;
642 }
643 }
644
645 if (src_w != NULL)
646 return skl_get_src_dsp_widget(src_w, skl);
647
648 return NULL;
649}
650
480/* 651/*
481 * in the Post-PMU event of mixer we need to do following: 652 * in the Post-PMU event of mixer we need to do following:
482 * - Check if this pipe is running 653 * - Check if this pipe is running
@@ -490,7 +661,6 @@ static int skl_tplg_mixer_dapm_post_pmu_event(struct snd_soc_dapm_widget *w,
490 struct skl *skl) 661 struct skl *skl)
491{ 662{
492 int ret = 0; 663 int ret = 0;
493 struct snd_soc_dapm_path *p;
494 struct snd_soc_dapm_widget *source, *sink; 664 struct snd_soc_dapm_widget *source, *sink;
495 struct skl_module_cfg *src_mconfig, *sink_mconfig; 665 struct skl_module_cfg *src_mconfig, *sink_mconfig;
496 struct skl_sst *ctx = skl->skl_sst; 666 struct skl_sst *ctx = skl->skl_sst;
@@ -504,32 +674,18 @@ static int skl_tplg_mixer_dapm_post_pmu_event(struct snd_soc_dapm_widget *w,
504 * one more sink before this sink got connected, Since source is 674 * one more sink before this sink got connected, Since source is
505 * started, bind this sink to source and start this pipe. 675 * started, bind this sink to source and start this pipe.
506 */ 676 */
507 snd_soc_dapm_widget_for_each_sink_path(w, p) { 677 source = skl_get_src_dsp_widget(w, skl);
508 if (!p->connect) 678 if (source != NULL) {
509 continue; 679 src_mconfig = source->priv;
510 680 sink_mconfig = sink->priv;
511 dev_dbg(ctx->dev, "sink widget=%s\n", w->name); 681 src_pipe_started = 1;
512 dev_dbg(ctx->dev, "src widget=%s\n", p->source->name);
513 682
514 /* 683 /*
515 * here we will check widgets in sink pipelines, so that 684 * check pipe state, then no need to bind or start the
516 * can be any widgets type and we are only interested if 685 * pipe
517 * they are ones used for SKL so check that first
518 */ 686 */
519 if ((p->source->priv != NULL) && 687 if (src_mconfig->pipe->state != SKL_PIPE_STARTED)
520 is_skl_dsp_widget_type(p->source)) { 688 src_pipe_started = 0;
521 source = p->source;
522 src_mconfig = source->priv;
523 sink_mconfig = sink->priv;
524 src_pipe_started = 1;
525
526 /*
527 * check pipe state, then no need to bind or start
528 * the pipe
529 */
530 if (src_mconfig->pipe->state != SKL_PIPE_STARTED)
531 src_pipe_started = 0;
532 }
533 } 689 }
534 690
535 if (src_pipe_started) { 691 if (src_pipe_started) {
@@ -537,7 +693,8 @@ static int skl_tplg_mixer_dapm_post_pmu_event(struct snd_soc_dapm_widget *w,
537 if (ret) 693 if (ret)
538 return ret; 694 return ret;
539 695
540 ret = skl_run_pipe(ctx, sink_mconfig->pipe); 696 if (sink_mconfig->pipe->conn_type != SKL_PIPE_CONN_TYPE_FE)
697 ret = skl_run_pipe(ctx, sink_mconfig->pipe);
541 } 698 }
542 699
543 return ret; 700 return ret;
@@ -552,52 +709,35 @@ static int skl_tplg_mixer_dapm_post_pmu_event(struct snd_soc_dapm_widget *w,
552static int skl_tplg_mixer_dapm_pre_pmd_event(struct snd_soc_dapm_widget *w, 709static int skl_tplg_mixer_dapm_pre_pmd_event(struct snd_soc_dapm_widget *w,
553 struct skl *skl) 710 struct skl *skl)
554{ 711{
555 struct snd_soc_dapm_widget *source, *sink;
556 struct skl_module_cfg *src_mconfig, *sink_mconfig; 712 struct skl_module_cfg *src_mconfig, *sink_mconfig;
557 int ret = 0, path_found = 0; 713 int ret = 0, i;
558 struct skl_dapm_path_list *path_list, *tmp_list;
559 struct skl_sst *ctx = skl->skl_sst; 714 struct skl_sst *ctx = skl->skl_sst;
560 715
561 sink = w; 716 sink_mconfig = w->priv;
562 sink_mconfig = sink->priv;
563 717
564 /* Stop the pipe */ 718 /* Stop the pipe */
565 ret = skl_stop_pipe(ctx, sink_mconfig->pipe); 719 ret = skl_stop_pipe(ctx, sink_mconfig->pipe);
566 if (ret) 720 if (ret)
567 return ret; 721 return ret;
568 722
569 /* 723 for (i = 0; i < sink_mconfig->max_in_queue; i++) {
570 * This list, dapm_path_list handling here does not need any locks 724 if (sink_mconfig->m_in_pin[i].pin_state == SKL_PIN_BIND_DONE) {
571 * as we are under dapm lock while handling widget events. 725 src_mconfig = sink_mconfig->m_in_pin[i].tgt_mcfg;
572 * List can be manipulated safely only under dapm widgets handler 726 if (!src_mconfig)
573 * routines 727 continue;
574 */ 728 /*
575 list_for_each_entry_safe(path_list, tmp_list, 729 * If path_found == 1, that means pmd for source
576 &skl->dapm_path_list, node) { 730 * pipe has not occurred, source is connected to
577 if (path_list->dapm_path->sink == sink) { 731 * some other sink. so its responsibility of sink
578 dev_dbg(ctx->dev, "Path found = %s\n", 732 * to unbind itself from source.
579 path_list->dapm_path->name); 733 */
580 source = path_list->dapm_path->source; 734 ret = skl_stop_pipe(ctx, src_mconfig->pipe);
581 src_mconfig = source->priv; 735 if (ret < 0)
582 path_found = 1; 736 return ret;
583
584 list_del(&path_list->node);
585 kfree(path_list);
586 break;
587 }
588 }
589
590 /*
591 * If path_found == 1, that means pmd for source pipe has
592 * not occurred, source is connected to some other sink.
593 * so its responsibility of sink to unbind itself from source.
594 */
595 if (path_found) {
596 ret = skl_stop_pipe(ctx, src_mconfig->pipe);
597 if (ret < 0)
598 return ret;
599 737
600 ret = skl_unbind_modules(ctx, src_mconfig, sink_mconfig); 738 ret = skl_unbind_modules(ctx,
739 src_mconfig, sink_mconfig);
740 }
601 } 741 }
602 742
603 return ret; 743 return ret;
@@ -622,10 +762,12 @@ static int skl_tplg_mixer_dapm_post_pmd_event(struct snd_soc_dapm_widget *w,
622 int ret = 0; 762 int ret = 0;
623 763
624 skl_tplg_free_pipe_mcps(skl, mconfig); 764 skl_tplg_free_pipe_mcps(skl, mconfig);
765 skl_tplg_free_pipe_mem(skl, mconfig);
625 766
626 list_for_each_entry(w_module, &s_pipe->w_list, node) { 767 list_for_each_entry(w_module, &s_pipe->w_list, node) {
627 dst_module = w_module->w->priv; 768 dst_module = w_module->w->priv;
628 769
770 skl_tplg_free_pipe_mcps(skl, dst_module);
629 if (src_module == NULL) { 771 if (src_module == NULL) {
630 src_module = dst_module; 772 src_module = dst_module;
631 continue; 773 continue;
@@ -639,9 +781,8 @@ static int skl_tplg_mixer_dapm_post_pmd_event(struct snd_soc_dapm_widget *w,
639 } 781 }
640 782
641 ret = skl_delete_pipe(ctx, mconfig->pipe); 783 ret = skl_delete_pipe(ctx, mconfig->pipe);
642 skl_tplg_free_pipe_mem(skl, mconfig);
643 784
644 return ret; 785 return skl_tplg_unload_pipe_modules(ctx, s_pipe);
645} 786}
646 787
647/* 788/*
@@ -653,47 +794,34 @@ static int skl_tplg_mixer_dapm_post_pmd_event(struct snd_soc_dapm_widget *w,
653static int skl_tplg_pga_dapm_post_pmd_event(struct snd_soc_dapm_widget *w, 794static int skl_tplg_pga_dapm_post_pmd_event(struct snd_soc_dapm_widget *w,
654 struct skl *skl) 795 struct skl *skl)
655{ 796{
656 struct snd_soc_dapm_widget *source, *sink;
657 struct skl_module_cfg *src_mconfig, *sink_mconfig; 797 struct skl_module_cfg *src_mconfig, *sink_mconfig;
658 int ret = 0, path_found = 0; 798 int ret = 0, i;
659 struct skl_dapm_path_list *path_list, *tmp_path_list;
660 struct skl_sst *ctx = skl->skl_sst; 799 struct skl_sst *ctx = skl->skl_sst;
661 800
662 source = w; 801 src_mconfig = w->priv;
663 src_mconfig = source->priv;
664 802
665 skl_tplg_free_pipe_mcps(skl, src_mconfig);
666 /* Stop the pipe since this is a mixin module */ 803 /* Stop the pipe since this is a mixin module */
667 ret = skl_stop_pipe(ctx, src_mconfig->pipe); 804 ret = skl_stop_pipe(ctx, src_mconfig->pipe);
668 if (ret) 805 if (ret)
669 return ret; 806 return ret;
670 807
671 list_for_each_entry_safe(path_list, tmp_path_list, &skl->dapm_path_list, node) { 808 for (i = 0; i < src_mconfig->max_out_queue; i++) {
672 if (path_list->dapm_path->source == source) { 809 if (src_mconfig->m_out_pin[i].pin_state == SKL_PIN_BIND_DONE) {
673 dev_dbg(ctx->dev, "Path found = %s\n", 810 sink_mconfig = src_mconfig->m_out_pin[i].tgt_mcfg;
674 path_list->dapm_path->name); 811 if (!sink_mconfig)
675 sink = path_list->dapm_path->sink; 812 continue;
676 sink_mconfig = sink->priv; 813 /*
677 path_found = 1; 814 * This is a connecter and if path is found that means
678 815 * unbind between source and sink has not happened yet
679 list_del(&path_list->node); 816 */
680 kfree(path_list); 817 ret = skl_stop_pipe(ctx, sink_mconfig->pipe);
681 break; 818 if (ret < 0)
819 return ret;
820 ret = skl_unbind_modules(ctx, src_mconfig,
821 sink_mconfig);
682 } 822 }
683 } 823 }
684 824
685 /*
686 * This is a connector and if path is found that means
687 * unbind between source and sink has not happened yet
688 */
689 if (path_found) {
690 ret = skl_stop_pipe(ctx, src_mconfig->pipe);
691 if (ret < 0)
692 return ret;
693
694 ret = skl_unbind_modules(ctx, src_mconfig, sink_mconfig);
695 }
696
697 return ret; 825 return ret;
698} 826}
699 827
@@ -774,6 +902,67 @@ static int skl_tplg_pga_event(struct snd_soc_dapm_widget *w,
774 return 0; 902 return 0;
775} 903}
776 904
905static int skl_tplg_tlv_control_get(struct snd_kcontrol *kcontrol,
906 unsigned int __user *data, unsigned int size)
907{
908 struct soc_bytes_ext *sb =
909 (struct soc_bytes_ext *)kcontrol->private_value;
910 struct skl_algo_data *bc = (struct skl_algo_data *)sb->dobj.private;
911 struct snd_soc_dapm_widget *w = snd_soc_dapm_kcontrol_widget(kcontrol);
912 struct skl_module_cfg *mconfig = w->priv;
913 struct skl *skl = get_skl_ctx(w->dapm->dev);
914
915 if (w->power)
916 skl_get_module_params(skl->skl_sst, (u32 *)bc->params,
917 bc->max, bc->param_id, mconfig);
918
919 if (bc->params) {
920 if (copy_to_user(data, &bc->param_id, sizeof(u32)))
921 return -EFAULT;
922 if (copy_to_user(data + 1, &size, sizeof(u32)))
923 return -EFAULT;
924 if (copy_to_user(data + 2, bc->params, size))
925 return -EFAULT;
926 }
927
928 return 0;
929}
930
931#define SKL_PARAM_VENDOR_ID 0xff
932
933static int skl_tplg_tlv_control_set(struct snd_kcontrol *kcontrol,
934 const unsigned int __user *data, unsigned int size)
935{
936 struct snd_soc_dapm_widget *w = snd_soc_dapm_kcontrol_widget(kcontrol);
937 struct skl_module_cfg *mconfig = w->priv;
938 struct soc_bytes_ext *sb =
939 (struct soc_bytes_ext *)kcontrol->private_value;
940 struct skl_algo_data *ac = (struct skl_algo_data *)sb->dobj.private;
941 struct skl *skl = get_skl_ctx(w->dapm->dev);
942
943 if (ac->params) {
944 /*
945 * if the param_is is of type Vendor, firmware expects actual
946 * parameter id and size from the control.
947 */
948 if (ac->param_id == SKL_PARAM_VENDOR_ID) {
949 if (copy_from_user(ac->params, data, size))
950 return -EFAULT;
951 } else {
952 if (copy_from_user(ac->params,
953 data + 2 * sizeof(u32), size))
954 return -EFAULT;
955 }
956
957 if (w->power)
958 return skl_set_module_params(skl->skl_sst,
959 (u32 *)ac->params, ac->max,
960 ac->param_id, mconfig);
961 }
962
963 return 0;
964}
965
777/* 966/*
778 * The FE params are passed by hw_params of the DAI. 967 * The FE params are passed by hw_params of the DAI.
779 * On hw_params, the params are stored in Gateway module of the FE and we 968 * On hw_params, the params are stored in Gateway module of the FE and we
@@ -790,9 +979,9 @@ int skl_tplg_update_pipe_params(struct device *dev,
790 memcpy(pipe->p_params, params, sizeof(*params)); 979 memcpy(pipe->p_params, params, sizeof(*params));
791 980
792 if (params->stream == SNDRV_PCM_STREAM_PLAYBACK) 981 if (params->stream == SNDRV_PCM_STREAM_PLAYBACK)
793 format = &mconfig->in_fmt; 982 format = &mconfig->in_fmt[0];
794 else 983 else
795 format = &mconfig->out_fmt; 984 format = &mconfig->out_fmt[0];
796 985
797 /* set the hw_params */ 986 /* set the hw_params */
798 format->s_freq = params->s_freq; 987 format->s_freq = params->s_freq;
@@ -809,6 +998,7 @@ int skl_tplg_update_pipe_params(struct device *dev,
809 break; 998 break;
810 999
811 case SKL_DEPTH_24BIT: 1000 case SKL_DEPTH_24BIT:
1001 case SKL_DEPTH_32BIT:
812 format->bit_depth = SKL_DEPTH_32BIT; 1002 format->bit_depth = SKL_DEPTH_32BIT;
813 break; 1003 break;
814 1004
@@ -846,7 +1036,7 @@ skl_tplg_fe_get_cpr_module(struct snd_soc_dai *dai, int stream)
846 w = dai->playback_widget; 1036 w = dai->playback_widget;
847 snd_soc_dapm_widget_for_each_sink_path(w, p) { 1037 snd_soc_dapm_widget_for_each_sink_path(w, p) {
848 if (p->connect && p->sink->power && 1038 if (p->connect && p->sink->power &&
849 is_skl_dsp_widget_type(p->sink)) 1039 !is_skl_dsp_widget_type(p->sink))
850 continue; 1040 continue;
851 1041
852 if (p->sink->priv) { 1042 if (p->sink->priv) {
@@ -859,7 +1049,7 @@ skl_tplg_fe_get_cpr_module(struct snd_soc_dai *dai, int stream)
859 w = dai->capture_widget; 1049 w = dai->capture_widget;
860 snd_soc_dapm_widget_for_each_source_path(w, p) { 1050 snd_soc_dapm_widget_for_each_source_path(w, p) {
861 if (p->connect && p->source->power && 1051 if (p->connect && p->source->power &&
862 is_skl_dsp_widget_type(p->source)) 1052 !is_skl_dsp_widget_type(p->source))
863 continue; 1053 continue;
864 1054
865 if (p->source->priv) { 1055 if (p->source->priv) {
@@ -920,6 +1110,9 @@ static int skl_tplg_be_fill_pipe_params(struct snd_soc_dai *dai,
920 1110
921 memcpy(pipe->p_params, params, sizeof(*params)); 1111 memcpy(pipe->p_params, params, sizeof(*params));
922 1112
1113 if (link_type == NHLT_LINK_HDA)
1114 return 0;
1115
923 /* update the blob based on virtual bus_id*/ 1116 /* update the blob based on virtual bus_id*/
924 cfg = skl_get_ep_blob(skl, mconfig->vbus_id, link_type, 1117 cfg = skl_get_ep_blob(skl, mconfig->vbus_id, link_type,
925 params->s_fmt, params->ch, 1118 params->s_fmt, params->ch,
@@ -950,18 +1143,13 @@ static int skl_tplg_be_set_src_pipe_params(struct snd_soc_dai *dai,
950 if (p->connect && is_skl_dsp_widget_type(p->source) && 1143 if (p->connect && is_skl_dsp_widget_type(p->source) &&
951 p->source->priv) { 1144 p->source->priv) {
952 1145
953 if (!p->source->power) { 1146 ret = skl_tplg_be_fill_pipe_params(dai,
954 ret = skl_tplg_be_fill_pipe_params( 1147 p->source->priv, params);
955 dai, p->source->priv, 1148 if (ret < 0)
956 params); 1149 return ret;
957 if (ret < 0)
958 return ret;
959 } else {
960 return -EBUSY;
961 }
962 } else { 1150 } else {
963 ret = skl_tplg_be_set_src_pipe_params( 1151 ret = skl_tplg_be_set_src_pipe_params(dai,
964 dai, p->source, params); 1152 p->source, params);
965 if (ret < 0) 1153 if (ret < 0)
966 return ret; 1154 return ret;
967 } 1155 }
@@ -980,15 +1168,10 @@ static int skl_tplg_be_set_sink_pipe_params(struct snd_soc_dai *dai,
980 if (p->connect && is_skl_dsp_widget_type(p->sink) && 1168 if (p->connect && is_skl_dsp_widget_type(p->sink) &&
981 p->sink->priv) { 1169 p->sink->priv) {
982 1170
983 if (!p->sink->power) { 1171 ret = skl_tplg_be_fill_pipe_params(dai,
984 ret = skl_tplg_be_fill_pipe_params( 1172 p->sink->priv, params);
985 dai, p->sink->priv, params); 1173 if (ret < 0)
986 if (ret < 0) 1174 return ret;
987 return ret;
988 } else {
989 return -EBUSY;
990 }
991
992 } else { 1175 } else {
993 ret = skl_tplg_be_set_sink_pipe_params( 1176 ret = skl_tplg_be_set_sink_pipe_params(
994 dai, p->sink, params); 1177 dai, p->sink, params);
@@ -1030,6 +1213,11 @@ static const struct snd_soc_tplg_widget_events skl_tplg_widget_ops[] = {
1030 {SKL_PGA_EVENT, skl_tplg_pga_event}, 1213 {SKL_PGA_EVENT, skl_tplg_pga_event},
1031}; 1214};
1032 1215
1216static const struct snd_soc_tplg_bytes_ext_ops skl_tlv_ops[] = {
1217 {SKL_CONTROL_TYPE_BYTE_TLV, skl_tplg_tlv_control_get,
1218 skl_tplg_tlv_control_set},
1219};
1220
1033/* 1221/*
1034 * The topology binary passes the pin info for a module so initialize the pin 1222 * The topology binary passes the pin info for a module so initialize the pin
1035 * info passed into module instance 1223 * info passed into module instance
@@ -1045,6 +1233,7 @@ static void skl_fill_module_pin_info(struct skl_dfw_module_pin *dfw_pin,
1045 m_pin[i].id.instance_id = dfw_pin[i].instance_id; 1233 m_pin[i].id.instance_id = dfw_pin[i].instance_id;
1046 m_pin[i].in_use = false; 1234 m_pin[i].in_use = false;
1047 m_pin[i].is_dynamic = is_dynamic; 1235 m_pin[i].is_dynamic = is_dynamic;
1236 m_pin[i].pin_state = SKL_PIN_UNBIND;
1048 } 1237 }
1049} 1238}
1050 1239
@@ -1092,6 +1281,24 @@ static struct skl_pipe *skl_tplg_add_pipe(struct device *dev,
1092 return ppl->pipe; 1281 return ppl->pipe;
1093} 1282}
1094 1283
1284static void skl_tplg_fill_fmt(struct skl_module_fmt *dst_fmt,
1285 struct skl_dfw_module_fmt *src_fmt,
1286 int pins)
1287{
1288 int i;
1289
1290 for (i = 0; i < pins; i++) {
1291 dst_fmt[i].channels = src_fmt[i].channels;
1292 dst_fmt[i].s_freq = src_fmt[i].freq;
1293 dst_fmt[i].bit_depth = src_fmt[i].bit_depth;
1294 dst_fmt[i].valid_bit_depth = src_fmt[i].valid_bit_depth;
1295 dst_fmt[i].ch_cfg = src_fmt[i].ch_cfg;
1296 dst_fmt[i].ch_map = src_fmt[i].ch_map;
1297 dst_fmt[i].interleaving_style = src_fmt[i].interleaving_style;
1298 dst_fmt[i].sample_type = src_fmt[i].sample_type;
1299 }
1300}
1301
1095/* 1302/*
1096 * Topology core widget load callback 1303 * Topology core widget load callback
1097 * 1304 *
@@ -1130,22 +1337,16 @@ static int skl_tplg_widget_load(struct snd_soc_component *cmpnt,
1130 mconfig->max_in_queue = dfw_config->max_in_queue; 1337 mconfig->max_in_queue = dfw_config->max_in_queue;
1131 mconfig->max_out_queue = dfw_config->max_out_queue; 1338 mconfig->max_out_queue = dfw_config->max_out_queue;
1132 mconfig->is_loadable = dfw_config->is_loadable; 1339 mconfig->is_loadable = dfw_config->is_loadable;
1133 mconfig->in_fmt.channels = dfw_config->in_fmt.channels; 1340 skl_tplg_fill_fmt(mconfig->in_fmt, dfw_config->in_fmt,
1134 mconfig->in_fmt.s_freq = dfw_config->in_fmt.freq; 1341 MODULE_MAX_IN_PINS);
1135 mconfig->in_fmt.bit_depth = dfw_config->in_fmt.bit_depth; 1342 skl_tplg_fill_fmt(mconfig->out_fmt, dfw_config->out_fmt,
1136 mconfig->in_fmt.valid_bit_depth = 1343 MODULE_MAX_OUT_PINS);
1137 dfw_config->in_fmt.valid_bit_depth; 1344
1138 mconfig->in_fmt.ch_cfg = dfw_config->in_fmt.ch_cfg;
1139 mconfig->out_fmt.channels = dfw_config->out_fmt.channels;
1140 mconfig->out_fmt.s_freq = dfw_config->out_fmt.freq;
1141 mconfig->out_fmt.bit_depth = dfw_config->out_fmt.bit_depth;
1142 mconfig->out_fmt.valid_bit_depth =
1143 dfw_config->out_fmt.valid_bit_depth;
1144 mconfig->out_fmt.ch_cfg = dfw_config->out_fmt.ch_cfg;
1145 mconfig->params_fixup = dfw_config->params_fixup; 1345 mconfig->params_fixup = dfw_config->params_fixup;
1146 mconfig->converter = dfw_config->converter; 1346 mconfig->converter = dfw_config->converter;
1147 mconfig->m_type = dfw_config->module_type; 1347 mconfig->m_type = dfw_config->module_type;
1148 mconfig->vbus_id = dfw_config->vbus_id; 1348 mconfig->vbus_id = dfw_config->vbus_id;
1349 mconfig->mem_pages = dfw_config->mem_pages;
1149 1350
1150 pipe = skl_tplg_add_pipe(bus->dev, skl, &dfw_config->pipe); 1351 pipe = skl_tplg_add_pipe(bus->dev, skl, &dfw_config->pipe);
1151 if (pipe) 1352 if (pipe)
@@ -1156,10 +1357,13 @@ static int skl_tplg_widget_load(struct snd_soc_component *cmpnt,
1156 mconfig->time_slot = dfw_config->time_slot; 1357 mconfig->time_slot = dfw_config->time_slot;
1157 mconfig->formats_config.caps_size = dfw_config->caps.caps_size; 1358 mconfig->formats_config.caps_size = dfw_config->caps.caps_size;
1158 1359
1159 mconfig->m_in_pin = devm_kzalloc(bus->dev, 1360 if (dfw_config->is_loadable)
1160 (mconfig->max_in_queue) * 1361 memcpy(mconfig->guid, dfw_config->uuid,
1161 sizeof(*mconfig->m_in_pin), 1362 ARRAY_SIZE(dfw_config->uuid));
1162 GFP_KERNEL); 1363
1364 mconfig->m_in_pin = devm_kzalloc(bus->dev, (mconfig->max_in_queue) *
1365 sizeof(*mconfig->m_in_pin),
1366 GFP_KERNEL);
1163 if (!mconfig->m_in_pin) 1367 if (!mconfig->m_in_pin)
1164 return -ENOMEM; 1368 return -ENOMEM;
1165 1369
@@ -1188,7 +1392,9 @@ static int skl_tplg_widget_load(struct snd_soc_component *cmpnt,
1188 return -ENOMEM; 1392 return -ENOMEM;
1189 1393
1190 memcpy(mconfig->formats_config.caps, dfw_config->caps.caps, 1394 memcpy(mconfig->formats_config.caps, dfw_config->caps.caps,
1191 dfw_config->caps.caps_size); 1395 dfw_config->caps.caps_size);
1396 mconfig->formats_config.param_id = dfw_config->caps.param_id;
1397 mconfig->formats_config.set_params = dfw_config->caps.set_params;
1192 1398
1193bind_event: 1399bind_event:
1194 if (tplg_w->event_type == 0) { 1400 if (tplg_w->event_type == 0) {
@@ -1209,8 +1415,70 @@ bind_event:
1209 return 0; 1415 return 0;
1210} 1416}
1211 1417
1418static int skl_init_algo_data(struct device *dev, struct soc_bytes_ext *be,
1419 struct snd_soc_tplg_bytes_control *bc)
1420{
1421 struct skl_algo_data *ac;
1422 struct skl_dfw_algo_data *dfw_ac =
1423 (struct skl_dfw_algo_data *)bc->priv.data;
1424
1425 ac = devm_kzalloc(dev, sizeof(*ac), GFP_KERNEL);
1426 if (!ac)
1427 return -ENOMEM;
1428
1429 /* Fill private data */
1430 ac->max = dfw_ac->max;
1431 ac->param_id = dfw_ac->param_id;
1432 ac->set_params = dfw_ac->set_params;
1433
1434 if (ac->max) {
1435 ac->params = (char *) devm_kzalloc(dev, ac->max, GFP_KERNEL);
1436 if (!ac->params)
1437 return -ENOMEM;
1438
1439 if (dfw_ac->params)
1440 memcpy(ac->params, dfw_ac->params, ac->max);
1441 }
1442
1443 be->dobj.private = ac;
1444 return 0;
1445}
1446
1447static int skl_tplg_control_load(struct snd_soc_component *cmpnt,
1448 struct snd_kcontrol_new *kctl,
1449 struct snd_soc_tplg_ctl_hdr *hdr)
1450{
1451 struct soc_bytes_ext *sb;
1452 struct snd_soc_tplg_bytes_control *tplg_bc;
1453 struct hdac_ext_bus *ebus = snd_soc_component_get_drvdata(cmpnt);
1454 struct hdac_bus *bus = ebus_to_hbus(ebus);
1455
1456 switch (hdr->ops.info) {
1457 case SND_SOC_TPLG_CTL_BYTES:
1458 tplg_bc = container_of(hdr,
1459 struct snd_soc_tplg_bytes_control, hdr);
1460 if (kctl->access & SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK) {
1461 sb = (struct soc_bytes_ext *)kctl->private_value;
1462 if (tplg_bc->priv.size)
1463 return skl_init_algo_data(
1464 bus->dev, sb, tplg_bc);
1465 }
1466 break;
1467
1468 default:
1469 dev_warn(bus->dev, "Control load not supported %d:%d:%d\n",
1470 hdr->ops.get, hdr->ops.put, hdr->ops.info);
1471 break;
1472 }
1473
1474 return 0;
1475}
1476
1212static struct snd_soc_tplg_ops skl_tplg_ops = { 1477static struct snd_soc_tplg_ops skl_tplg_ops = {
1213 .widget_load = skl_tplg_widget_load, 1478 .widget_load = skl_tplg_widget_load,
1479 .control_load = skl_tplg_control_load,
1480 .bytes_ext_ops = skl_tlv_ops,
1481 .bytes_ext_ops_count = ARRAY_SIZE(skl_tlv_ops),
1214}; 1482};
1215 1483
1216/* This will be read from topology manifest, currently defined here */ 1484/* This will be read from topology manifest, currently defined here */
diff --git a/sound/soc/intel/skylake/skl-topology.h b/sound/soc/intel/skylake/skl-topology.h
index 76053a8de41c..9aa2a2b6598a 100644
--- a/sound/soc/intel/skylake/skl-topology.h
+++ b/sound/soc/intel/skylake/skl-topology.h
@@ -36,6 +36,9 @@
36/* Maximum number of coefficients up down mixer module */ 36/* Maximum number of coefficients up down mixer module */
37#define UP_DOWN_MIXER_MAX_COEFF 6 37#define UP_DOWN_MIXER_MAX_COEFF 6
38 38
39#define MODULE_MAX_IN_PINS 8
40#define MODULE_MAX_OUT_PINS 8
41
39enum skl_channel_index { 42enum skl_channel_index {
40 SKL_CHANNEL_LEFT = 0, 43 SKL_CHANNEL_LEFT = 0,
41 SKL_CHANNEL_RIGHT = 1, 44 SKL_CHANNEL_RIGHT = 1,
@@ -55,12 +58,6 @@ enum skl_bitdepth {
55 SKL_DEPTH_INVALID 58 SKL_DEPTH_INVALID
56}; 59};
57 60
58enum skl_interleaving {
59 /* [s1_ch1...s1_chN,...,sM_ch1...sM_chN] */
60 SKL_INTERLEAVING_PER_CHANNEL = 0,
61 /* [s1_ch1...sM_ch1,...,s1_chN...sM_chN] */
62 SKL_INTERLEAVING_PER_SAMPLE = 1,
63};
64 61
65enum skl_s_freq { 62enum skl_s_freq {
66 SKL_FS_8000 = 8000, 63 SKL_FS_8000 = 8000,
@@ -143,6 +140,16 @@ struct skl_up_down_mixer_cfg {
143 s32 coeff[UP_DOWN_MIXER_MAX_COEFF]; 140 s32 coeff[UP_DOWN_MIXER_MAX_COEFF];
144} __packed; 141} __packed;
145 142
143struct skl_algo_cfg {
144 struct skl_base_cfg base_cfg;
145 char params[0];
146} __packed;
147
148struct skl_base_outfmt_cfg {
149 struct skl_base_cfg base_cfg;
150 struct skl_audio_data_format out_fmt;
151} __packed;
152
146enum skl_dma_type { 153enum skl_dma_type {
147 SKL_DMA_HDA_HOST_OUTPUT_CLASS = 0, 154 SKL_DMA_HDA_HOST_OUTPUT_CLASS = 0,
148 SKL_DMA_HDA_HOST_INPUT_CLASS = 1, 155 SKL_DMA_HDA_HOST_INPUT_CLASS = 1,
@@ -178,21 +185,34 @@ struct skl_module_fmt {
178 u32 bit_depth; 185 u32 bit_depth;
179 u32 valid_bit_depth; 186 u32 valid_bit_depth;
180 u32 ch_cfg; 187 u32 ch_cfg;
188 u32 interleaving_style;
189 u32 sample_type;
190 u32 ch_map;
181}; 191};
182 192
193struct skl_module_cfg;
194
183struct skl_module_inst_id { 195struct skl_module_inst_id {
184 u32 module_id; 196 u32 module_id;
185 u32 instance_id; 197 u32 instance_id;
186}; 198};
187 199
200enum skl_module_pin_state {
201 SKL_PIN_UNBIND = 0,
202 SKL_PIN_BIND_DONE = 1,
203};
204
188struct skl_module_pin { 205struct skl_module_pin {
189 struct skl_module_inst_id id; 206 struct skl_module_inst_id id;
190 u8 pin_index;
191 bool is_dynamic; 207 bool is_dynamic;
192 bool in_use; 208 bool in_use;
209 enum skl_module_pin_state pin_state;
210 struct skl_module_cfg *tgt_mcfg;
193}; 211};
194 212
195struct skl_specific_cfg { 213struct skl_specific_cfg {
214 u32 set_params;
215 u32 param_id;
196 u32 caps_size; 216 u32 caps_size;
197 u32 *caps; 217 u32 *caps;
198}; 218};
@@ -238,9 +258,13 @@ enum skl_module_state {
238}; 258};
239 259
240struct skl_module_cfg { 260struct skl_module_cfg {
261 char guid[SKL_UUID_STR_SZ];
241 struct skl_module_inst_id id; 262 struct skl_module_inst_id id;
242 struct skl_module_fmt in_fmt; 263 u8 domain;
243 struct skl_module_fmt out_fmt; 264 bool homogenous_inputs;
265 bool homogenous_outputs;
266 struct skl_module_fmt in_fmt[MODULE_MAX_IN_PINS];
267 struct skl_module_fmt out_fmt[MODULE_MAX_OUT_PINS];
244 u8 max_in_queue; 268 u8 max_in_queue;
245 u8 max_out_queue; 269 u8 max_out_queue;
246 u8 in_queue_mask; 270 u8 in_queue_mask;
@@ -258,6 +282,7 @@ struct skl_module_cfg {
258 u32 params_fixup; 282 u32 params_fixup;
259 u32 converter; 283 u32 converter;
260 u32 vbus_id; 284 u32 vbus_id;
285 u32 mem_pages;
261 struct skl_module_pin *m_in_pin; 286 struct skl_module_pin *m_in_pin;
262 struct skl_module_pin *m_out_pin; 287 struct skl_module_pin *m_out_pin;
263 enum skl_module_type m_type; 288 enum skl_module_type m_type;
@@ -267,13 +292,15 @@ struct skl_module_cfg {
267 struct skl_specific_cfg formats_config; 292 struct skl_specific_cfg formats_config;
268}; 293};
269 294
270struct skl_pipeline { 295struct skl_algo_data {
271 struct skl_pipe *pipe; 296 u32 param_id;
272 struct list_head node; 297 u32 set_params;
298 u32 max;
299 char *params;
273}; 300};
274 301
275struct skl_dapm_path_list { 302struct skl_pipeline {
276 struct snd_soc_dapm_path *dapm_path; 303 struct skl_pipe *pipe;
277 struct list_head node; 304 struct list_head node;
278}; 305};
279 306
@@ -305,8 +332,7 @@ int skl_delete_pipe(struct skl_sst *ctx, struct skl_pipe *pipe);
305 332
306int skl_stop_pipe(struct skl_sst *ctx, struct skl_pipe *pipe); 333int skl_stop_pipe(struct skl_sst *ctx, struct skl_pipe *pipe);
307 334
308int skl_init_module(struct skl_sst *ctx, struct skl_module_cfg *module_config, 335int skl_init_module(struct skl_sst *ctx, struct skl_module_cfg *module_config);
309 char *param);
310 336
311int skl_bind_modules(struct skl_sst *ctx, struct skl_module_cfg 337int skl_bind_modules(struct skl_sst *ctx, struct skl_module_cfg
312 *src_module, struct skl_module_cfg *dst_module); 338 *src_module, struct skl_module_cfg *dst_module);
@@ -314,5 +340,10 @@ int skl_bind_modules(struct skl_sst *ctx, struct skl_module_cfg
314int skl_unbind_modules(struct skl_sst *ctx, struct skl_module_cfg 340int skl_unbind_modules(struct skl_sst *ctx, struct skl_module_cfg
315 *src_module, struct skl_module_cfg *dst_module); 341 *src_module, struct skl_module_cfg *dst_module);
316 342
343int skl_set_module_params(struct skl_sst *ctx, u32 *params, int size,
344 u32 param_id, struct skl_module_cfg *mcfg);
345int skl_get_module_params(struct skl_sst *ctx, u32 *params, int size,
346 u32 param_id, struct skl_module_cfg *mcfg);
347
317enum skl_bitdepth skl_get_bit_depth(int params); 348enum skl_bitdepth skl_get_bit_depth(int params);
318#endif 349#endif
diff --git a/sound/soc/intel/skylake/skl-tplg-interface.h b/sound/soc/intel/skylake/skl-tplg-interface.h
index 2bc396d54cbe..c9ae010b3cc8 100644
--- a/sound/soc/intel/skylake/skl-tplg-interface.h
+++ b/sound/soc/intel/skylake/skl-tplg-interface.h
@@ -23,15 +23,13 @@
23 * Default types range from 0~12. type can range from 0 to 0xff 23 * Default types range from 0~12. type can range from 0 to 0xff
24 * SST types start at higher to avoid any overlapping in future 24 * SST types start at higher to avoid any overlapping in future
25 */ 25 */
26#define SOC_CONTROL_TYPE_HDA_SST_ALGO_PARAMS 0x100 26#define SKL_CONTROL_TYPE_BYTE_TLV 0x100
27#define SOC_CONTROL_TYPE_HDA_SST_MUX 0x101
28#define SOC_CONTROL_TYPE_HDA_SST_MIX 0x101
29#define SOC_CONTROL_TYPE_HDA_SST_BYTE 0x103
30 27
31#define HDA_SST_CFG_MAX 900 /* size of copier cfg*/ 28#define HDA_SST_CFG_MAX 900 /* size of copier cfg*/
32#define MAX_IN_QUEUE 8 29#define MAX_IN_QUEUE 8
33#define MAX_OUT_QUEUE 8 30#define MAX_OUT_QUEUE 8
34 31
32#define SKL_UUID_STR_SZ 40
35/* Event types goes here */ 33/* Event types goes here */
36/* Reserve event type 0 for no event handlers */ 34/* Reserve event type 0 for no event handlers */
37enum skl_event_types { 35enum skl_event_types {
@@ -72,6 +70,7 @@ enum skl_ch_cfg {
72 SKL_CH_CFG_DUAL_MONO = 9, 70 SKL_CH_CFG_DUAL_MONO = 9,
73 SKL_CH_CFG_I2S_DUAL_STEREO_0 = 10, 71 SKL_CH_CFG_I2S_DUAL_STEREO_0 = 10,
74 SKL_CH_CFG_I2S_DUAL_STEREO_1 = 11, 72 SKL_CH_CFG_I2S_DUAL_STEREO_1 = 11,
73 SKL_CH_CFG_4_CHANNEL = 12,
75 SKL_CH_CFG_INVALID 74 SKL_CH_CFG_INVALID
76}; 75};
77 76
@@ -79,7 +78,9 @@ enum skl_module_type {
79 SKL_MODULE_TYPE_MIXER = 0, 78 SKL_MODULE_TYPE_MIXER = 0,
80 SKL_MODULE_TYPE_COPIER, 79 SKL_MODULE_TYPE_COPIER,
81 SKL_MODULE_TYPE_UPDWMIX, 80 SKL_MODULE_TYPE_UPDWMIX,
82 SKL_MODULE_TYPE_SRCINT 81 SKL_MODULE_TYPE_SRCINT,
82 SKL_MODULE_TYPE_ALGO,
83 SKL_MODULE_TYPE_BASE_OUTFMT
83}; 84};
84 85
85enum skl_core_affinity { 86enum skl_core_affinity {
@@ -110,6 +111,42 @@ enum skl_dev_type {
110 SKL_DEVICE_NONE 111 SKL_DEVICE_NONE
111}; 112};
112 113
114/**
115 * enum skl_interleaving - interleaving style
116 *
117 * @SKL_INTERLEAVING_PER_CHANNEL: [s1_ch1...s1_chN,...,sM_ch1...sM_chN]
118 * @SKL_INTERLEAVING_PER_SAMPLE: [s1_ch1...sM_ch1,...,s1_chN...sM_chN]
119 */
120enum skl_interleaving {
121 SKL_INTERLEAVING_PER_CHANNEL = 0,
122 SKL_INTERLEAVING_PER_SAMPLE = 1,
123};
124
125enum skl_sample_type {
126 SKL_SAMPLE_TYPE_INT_MSB = 0,
127 SKL_SAMPLE_TYPE_INT_LSB = 1,
128 SKL_SAMPLE_TYPE_INT_SIGNED = 2,
129 SKL_SAMPLE_TYPE_INT_UNSIGNED = 3,
130 SKL_SAMPLE_TYPE_FLOAT = 4
131};
132
133enum module_pin_type {
134 /* All pins of the module takes same PCM inputs or outputs
135 * e.g. mixout
136 */
137 SKL_PIN_TYPE_HOMOGENEOUS,
138 /* All pins of the module takes different PCM inputs or outputs
139 * e.g mux
140 */
141 SKL_PIN_TYPE_HETEROGENEOUS,
142};
143
144enum skl_module_param_type {
145 SKL_PARAM_DEFAULT = 0,
146 SKL_PARAM_INIT,
147 SKL_PARAM_SET
148};
149
113struct skl_dfw_module_pin { 150struct skl_dfw_module_pin {
114 u16 module_id; 151 u16 module_id;
115 u16 instance_id; 152 u16 instance_id;
@@ -121,9 +158,15 @@ struct skl_dfw_module_fmt {
121 u32 bit_depth; 158 u32 bit_depth;
122 u32 valid_bit_depth; 159 u32 valid_bit_depth;
123 u32 ch_cfg; 160 u32 ch_cfg;
161 u32 interleaving_style;
162 u32 sample_type;
163 u32 ch_map;
124} __packed; 164} __packed;
125 165
126struct skl_dfw_module_caps { 166struct skl_dfw_module_caps {
167 u32 set_params:2;
168 u32 rsvd:30;
169 u32 param_id;
127 u32 caps_size; 170 u32 caps_size;
128 u32 caps[HDA_SST_CFG_MAX]; 171 u32 caps[HDA_SST_CFG_MAX];
129}; 172};
@@ -131,41 +174,57 @@ struct skl_dfw_module_caps {
131struct skl_dfw_pipe { 174struct skl_dfw_pipe {
132 u8 pipe_id; 175 u8 pipe_id;
133 u8 pipe_priority; 176 u8 pipe_priority;
134 u16 conn_type; 177 u16 conn_type:4;
135 u32 memory_pages; 178 u16 rsvd:4;
179 u16 memory_pages:8;
136} __packed; 180} __packed;
137 181
138struct skl_dfw_module { 182struct skl_dfw_module {
183 char uuid[SKL_UUID_STR_SZ];
184
139 u16 module_id; 185 u16 module_id;
140 u16 instance_id; 186 u16 instance_id;
141 u32 max_mcps; 187 u32 max_mcps;
142 u8 core_id; 188 u32 mem_pages;
143 u8 max_in_queue;
144 u8 max_out_queue;
145 u8 is_loadable;
146 u8 conn_type;
147 u8 dev_type;
148 u8 hw_conn_type;
149 u8 time_slot;
150 u32 obs; 189 u32 obs;
151 u32 ibs; 190 u32 ibs;
152 u32 params_fixup;
153 u32 converter;
154 u32 module_type;
155 u32 vbus_id; 191 u32 vbus_id;
156 u8 is_dynamic_in_pin; 192
157 u8 is_dynamic_out_pin; 193 u32 max_in_queue:8;
194 u32 max_out_queue:8;
195 u32 time_slot:8;
196 u32 core_id:4;
197 u32 rsvd1:4;
198
199 u32 module_type:8;
200 u32 conn_type:4;
201 u32 dev_type:4;
202 u32 hw_conn_type:4;
203 u32 rsvd2:12;
204
205 u32 params_fixup:8;
206 u32 converter:8;
207 u32 input_pin_type:1;
208 u32 output_pin_type:1;
209 u32 is_dynamic_in_pin:1;
210 u32 is_dynamic_out_pin:1;
211 u32 is_loadable:1;
212 u32 rsvd3:11;
213
158 struct skl_dfw_pipe pipe; 214 struct skl_dfw_pipe pipe;
159 struct skl_dfw_module_fmt in_fmt; 215 struct skl_dfw_module_fmt in_fmt[MAX_IN_QUEUE];
160 struct skl_dfw_module_fmt out_fmt; 216 struct skl_dfw_module_fmt out_fmt[MAX_OUT_QUEUE];
161 struct skl_dfw_module_pin in_pin[MAX_IN_QUEUE]; 217 struct skl_dfw_module_pin in_pin[MAX_IN_QUEUE];
162 struct skl_dfw_module_pin out_pin[MAX_OUT_QUEUE]; 218 struct skl_dfw_module_pin out_pin[MAX_OUT_QUEUE];
163 struct skl_dfw_module_caps caps; 219 struct skl_dfw_module_caps caps;
164} __packed; 220} __packed;
165 221
166struct skl_dfw_algo_data { 222struct skl_dfw_algo_data {
223 u32 set_params:2;
224 u32 rsvd:30;
225 u32 param_id;
167 u32 max; 226 u32 max;
168 char *params; 227 char params[0];
169} __packed; 228} __packed;
170 229
171#endif 230#endif
diff --git a/sound/soc/intel/skylake/skl.c b/sound/soc/intel/skylake/skl.c
index caa69c4598a6..443a15de94b5 100644
--- a/sound/soc/intel/skylake/skl.c
+++ b/sound/soc/intel/skylake/skl.c
@@ -27,7 +27,10 @@
27#include <linux/platform_device.h> 27#include <linux/platform_device.h>
28#include <linux/firmware.h> 28#include <linux/firmware.h>
29#include <sound/pcm.h> 29#include <sound/pcm.h>
30#include "../common/sst-acpi.h"
30#include "skl.h" 31#include "skl.h"
32#include "skl-sst-dsp.h"
33#include "skl-sst-ipc.h"
31 34
32/* 35/*
33 * initialize the PCI registers 36 * initialize the PCI registers
@@ -58,6 +61,49 @@ static void skl_init_pci(struct skl *skl)
58 skl_update_pci_byte(skl->pci, AZX_PCIREG_TCSEL, 0x07, 0); 61 skl_update_pci_byte(skl->pci, AZX_PCIREG_TCSEL, 0x07, 0);
59} 62}
60 63
64static void update_pci_dword(struct pci_dev *pci,
65 unsigned int reg, u32 mask, u32 val)
66{
67 u32 data = 0;
68
69 pci_read_config_dword(pci, reg, &data);
70 data &= ~mask;
71 data |= (val & mask);
72 pci_write_config_dword(pci, reg, data);
73}
74
75/*
76 * skl_enable_miscbdcge - enable/dsiable CGCTL.MISCBDCGE bits
77 *
78 * @dev: device pointer
79 * @enable: enable/disable flag
80 */
81static void skl_enable_miscbdcge(struct device *dev, bool enable)
82{
83 struct pci_dev *pci = to_pci_dev(dev);
84 u32 val;
85
86 val = enable ? AZX_CGCTL_MISCBDCGE_MASK : 0;
87
88 update_pci_dword(pci, AZX_PCIREG_CGCTL, AZX_CGCTL_MISCBDCGE_MASK, val);
89}
90
91/*
92 * While performing reset, controller may not come back properly causing
93 * issues, so recommendation is to set CGCTL.MISCBDCGE to 0 then do reset
94 * (init chip) and then again set CGCTL.MISCBDCGE to 1
95 */
96static int skl_init_chip(struct hdac_bus *bus, bool full_reset)
97{
98 int ret;
99
100 skl_enable_miscbdcge(bus->dev, false);
101 ret = snd_hdac_bus_init_chip(bus, full_reset);
102 skl_enable_miscbdcge(bus->dev, true);
103
104 return ret;
105}
106
61/* called from IRQ */ 107/* called from IRQ */
62static void skl_stream_update(struct hdac_bus *bus, struct hdac_stream *hstr) 108static void skl_stream_update(struct hdac_bus *bus, struct hdac_stream *hstr)
63{ 109{
@@ -130,6 +176,39 @@ static int skl_acquire_irq(struct hdac_ext_bus *ebus, int do_disconnect)
130 return 0; 176 return 0;
131} 177}
132 178
179#ifdef CONFIG_PM
180static int _skl_suspend(struct hdac_ext_bus *ebus)
181{
182 struct skl *skl = ebus_to_skl(ebus);
183 struct hdac_bus *bus = ebus_to_hbus(ebus);
184 int ret;
185
186 snd_hdac_ext_bus_link_power_down_all(ebus);
187
188 ret = skl_suspend_dsp(skl);
189 if (ret < 0)
190 return ret;
191
192 snd_hdac_bus_stop_chip(bus);
193 skl_enable_miscbdcge(bus->dev, false);
194 snd_hdac_bus_enter_link_reset(bus);
195 skl_enable_miscbdcge(bus->dev, true);
196
197 return 0;
198}
199
200static int _skl_resume(struct hdac_ext_bus *ebus)
201{
202 struct skl *skl = ebus_to_skl(ebus);
203 struct hdac_bus *bus = ebus_to_hbus(ebus);
204
205 skl_init_pci(skl);
206 skl_init_chip(bus, true);
207
208 return skl_resume_dsp(skl);
209}
210#endif
211
133#ifdef CONFIG_PM_SLEEP 212#ifdef CONFIG_PM_SLEEP
134/* 213/*
135 * power management 214 * power management
@@ -138,26 +217,46 @@ static int skl_suspend(struct device *dev)
138{ 217{
139 struct pci_dev *pci = to_pci_dev(dev); 218 struct pci_dev *pci = to_pci_dev(dev);
140 struct hdac_ext_bus *ebus = pci_get_drvdata(pci); 219 struct hdac_ext_bus *ebus = pci_get_drvdata(pci);
220 struct skl *skl = ebus_to_skl(ebus);
141 struct hdac_bus *bus = ebus_to_hbus(ebus); 221 struct hdac_bus *bus = ebus_to_hbus(ebus);
142 222
143 snd_hdac_bus_stop_chip(bus); 223 /*
144 snd_hdac_bus_enter_link_reset(bus); 224 * Do not suspend if streams which are marked ignore suspend are
145 225 * running, we need to save the state for these and continue
146 return 0; 226 */
227 if (skl->supend_active) {
228 snd_hdac_ext_bus_link_power_down_all(ebus);
229 enable_irq_wake(bus->irq);
230 pci_save_state(pci);
231 pci_disable_device(pci);
232 return 0;
233 } else {
234 return _skl_suspend(ebus);
235 }
147} 236}
148 237
149static int skl_resume(struct device *dev) 238static int skl_resume(struct device *dev)
150{ 239{
151 struct pci_dev *pci = to_pci_dev(dev); 240 struct pci_dev *pci = to_pci_dev(dev);
152 struct hdac_ext_bus *ebus = pci_get_drvdata(pci); 241 struct hdac_ext_bus *ebus = pci_get_drvdata(pci);
242 struct skl *skl = ebus_to_skl(ebus);
153 struct hdac_bus *bus = ebus_to_hbus(ebus); 243 struct hdac_bus *bus = ebus_to_hbus(ebus);
154 struct skl *hda = ebus_to_skl(ebus); 244 int ret;
155
156 skl_init_pci(hda);
157 245
158 snd_hdac_bus_init_chip(bus, 1); 246 /*
247 * resume only when we are not in suspend active, otherwise need to
248 * restore the device
249 */
250 if (skl->supend_active) {
251 pci_restore_state(pci);
252 ret = pci_enable_device(pci);
253 snd_hdac_ext_bus_link_power_up_all(ebus);
254 disable_irq_wake(bus->irq);
255 } else {
256 ret = _skl_resume(ebus);
257 }
159 258
160 return 0; 259 return ret;
161} 260}
162#endif /* CONFIG_PM_SLEEP */ 261#endif /* CONFIG_PM_SLEEP */
163 262
@@ -167,24 +266,10 @@ static int skl_runtime_suspend(struct device *dev)
167 struct pci_dev *pci = to_pci_dev(dev); 266 struct pci_dev *pci = to_pci_dev(dev);
168 struct hdac_ext_bus *ebus = pci_get_drvdata(pci); 267 struct hdac_ext_bus *ebus = pci_get_drvdata(pci);
169 struct hdac_bus *bus = ebus_to_hbus(ebus); 268 struct hdac_bus *bus = ebus_to_hbus(ebus);
170 struct skl *skl = ebus_to_skl(ebus);
171 int ret;
172 269
173 dev_dbg(bus->dev, "in %s\n", __func__); 270 dev_dbg(bus->dev, "in %s\n", __func__);
174 271
175 /* enable controller wake up event */ 272 return _skl_suspend(ebus);
176 snd_hdac_chip_updatew(bus, WAKEEN, 0, STATESTS_INT_MASK);
177
178 snd_hdac_ext_bus_link_power_down_all(ebus);
179
180 ret = skl_suspend_dsp(skl);
181 if (ret < 0)
182 return ret;
183
184 snd_hdac_bus_stop_chip(bus);
185 snd_hdac_bus_enter_link_reset(bus);
186
187 return 0;
188} 273}
189 274
190static int skl_runtime_resume(struct device *dev) 275static int skl_runtime_resume(struct device *dev)
@@ -192,20 +277,10 @@ static int skl_runtime_resume(struct device *dev)
192 struct pci_dev *pci = to_pci_dev(dev); 277 struct pci_dev *pci = to_pci_dev(dev);
193 struct hdac_ext_bus *ebus = pci_get_drvdata(pci); 278 struct hdac_ext_bus *ebus = pci_get_drvdata(pci);
194 struct hdac_bus *bus = ebus_to_hbus(ebus); 279 struct hdac_bus *bus = ebus_to_hbus(ebus);
195 struct skl *skl = ebus_to_skl(ebus);
196 int status;
197 280
198 dev_dbg(bus->dev, "in %s\n", __func__); 281 dev_dbg(bus->dev, "in %s\n", __func__);
199 282
200 /* Read STATESTS before controller reset */ 283 return _skl_resume(ebus);
201 status = snd_hdac_chip_readw(bus, STATESTS);
202
203 skl_init_pci(skl);
204 snd_hdac_bus_init_chip(bus, true);
205 /* disable controller Wake Up event */
206 snd_hdac_chip_updatew(bus, WAKEEN, STATESTS_INT_MASK, 0);
207
208 return skl_resume_dsp(skl);
209} 284}
210#endif /* CONFIG_PM */ 285#endif /* CONFIG_PM */
211 286
@@ -242,6 +317,43 @@ static int skl_free(struct hdac_ext_bus *ebus)
242 return 0; 317 return 0;
243} 318}
244 319
320static int skl_machine_device_register(struct skl *skl, void *driver_data)
321{
322 struct hdac_bus *bus = ebus_to_hbus(&skl->ebus);
323 struct platform_device *pdev;
324 struct sst_acpi_mach *mach = driver_data;
325 int ret;
326
327 mach = sst_acpi_find_machine(mach);
328 if (mach == NULL) {
329 dev_err(bus->dev, "No matching machine driver found\n");
330 return -ENODEV;
331 }
332 skl->fw_name = mach->fw_filename;
333
334 pdev = platform_device_alloc(mach->drv_name, -1);
335 if (pdev == NULL) {
336 dev_err(bus->dev, "platform device alloc failed\n");
337 return -EIO;
338 }
339
340 ret = platform_device_add(pdev);
341 if (ret) {
342 dev_err(bus->dev, "failed to add machine device\n");
343 platform_device_put(pdev);
344 return -EIO;
345 }
346 skl->i2s_dev = pdev;
347
348 return 0;
349}
350
351static void skl_machine_device_unregister(struct skl *skl)
352{
353 if (skl->i2s_dev)
354 platform_device_unregister(skl->i2s_dev);
355}
356
245static int skl_dmic_device_register(struct skl *skl) 357static int skl_dmic_device_register(struct skl *skl)
246{ 358{
247 struct hdac_bus *bus = ebus_to_hbus(&skl->ebus); 359 struct hdac_bus *bus = ebus_to_hbus(&skl->ebus);
@@ -321,7 +433,7 @@ static int skl_codec_create(struct hdac_ext_bus *ebus)
321 * back to the sanity state. 433 * back to the sanity state.
322 */ 434 */
323 snd_hdac_bus_stop_chip(bus); 435 snd_hdac_bus_stop_chip(bus);
324 snd_hdac_bus_init_chip(bus, true); 436 skl_init_chip(bus, true);
325 } 437 }
326 } 438 }
327 } 439 }
@@ -431,12 +543,11 @@ static int skl_first_init(struct hdac_ext_bus *ebus)
431 /* initialize chip */ 543 /* initialize chip */
432 skl_init_pci(skl); 544 skl_init_pci(skl);
433 545
434 snd_hdac_bus_init_chip(bus, true); 546 skl_init_chip(bus, true);
435 547
436 /* codec detection */ 548 /* codec detection */
437 if (!bus->codec_mask) { 549 if (!bus->codec_mask) {
438 dev_err(bus->dev, "no codecs found!\n"); 550 dev_info(bus->dev, "no hda codecs found!\n");
439 return -ENODEV;
440 } 551 }
441 552
442 return 0; 553 return 0;
@@ -471,11 +582,18 @@ static int skl_probe(struct pci_dev *pci,
471 582
472 /* check if dsp is there */ 583 /* check if dsp is there */
473 if (ebus->ppcap) { 584 if (ebus->ppcap) {
585 err = skl_machine_device_register(skl,
586 (void *)pci_id->driver_data);
587 if (err < 0)
588 goto out_free;
589
474 err = skl_init_dsp(skl); 590 err = skl_init_dsp(skl);
475 if (err < 0) { 591 if (err < 0) {
476 dev_dbg(bus->dev, "error failed to register dsp\n"); 592 dev_dbg(bus->dev, "error failed to register dsp\n");
477 goto out_free; 593 goto out_mach_free;
478 } 594 }
595 skl->skl_sst->enable_miscbdcge = skl_enable_miscbdcge;
596
479 } 597 }
480 if (ebus->mlcap) 598 if (ebus->mlcap)
481 snd_hdac_ext_bus_get_ml_capabilities(ebus); 599 snd_hdac_ext_bus_get_ml_capabilities(ebus);
@@ -509,6 +627,8 @@ out_dmic_free:
509 skl_dmic_device_unregister(skl); 627 skl_dmic_device_unregister(skl);
510out_dsp_free: 628out_dsp_free:
511 skl_free_dsp(skl); 629 skl_free_dsp(skl);
630out_mach_free:
631 skl_machine_device_unregister(skl);
512out_free: 632out_free:
513 skl->init_failed = 1; 633 skl->init_failed = 1;
514 skl_free(ebus); 634 skl_free(ebus);
@@ -529,15 +649,26 @@ static void skl_remove(struct pci_dev *pci)
529 pci_dev_put(pci); 649 pci_dev_put(pci);
530 skl_platform_unregister(&pci->dev); 650 skl_platform_unregister(&pci->dev);
531 skl_free_dsp(skl); 651 skl_free_dsp(skl);
652 skl_machine_device_unregister(skl);
532 skl_dmic_device_unregister(skl); 653 skl_dmic_device_unregister(skl);
533 skl_free(ebus); 654 skl_free(ebus);
534 dev_set_drvdata(&pci->dev, NULL); 655 dev_set_drvdata(&pci->dev, NULL);
535} 656}
536 657
658static struct sst_acpi_mach sst_skl_devdata[] = {
659 { "INT343A", "skl_alc286s_i2s", "intel/dsp_fw_release.bin", NULL, NULL, NULL },
660 { "INT343B", "skl_nau88l25_ssm4567_i2s", "intel/dsp_fw_release.bin",
661 NULL, NULL, NULL },
662 { "MX98357A", "skl_nau88l25_max98357a_i2s", "intel/dsp_fw_release.bin",
663 NULL, NULL, NULL },
664 {}
665};
666
537/* PCI IDs */ 667/* PCI IDs */
538static const struct pci_device_id skl_ids[] = { 668static const struct pci_device_id skl_ids[] = {
539 /* Sunrise Point-LP */ 669 /* Sunrise Point-LP */
540 { PCI_DEVICE(0x8086, 0x9d70), 0}, 670 { PCI_DEVICE(0x8086, 0x9d70),
671 .driver_data = (unsigned long)&sst_skl_devdata},
541 { 0, } 672 { 0, }
542}; 673};
543MODULE_DEVICE_TABLE(pci, skl_ids); 674MODULE_DEVICE_TABLE(pci, skl_ids);
diff --git a/sound/soc/intel/skylake/skl.h b/sound/soc/intel/skylake/skl.h
index a0709e344d44..4d18293b5537 100644
--- a/sound/soc/intel/skylake/skl.h
+++ b/sound/soc/intel/skylake/skl.h
@@ -48,6 +48,9 @@
48#define AZX_REG_VS_SDXEFIFOS_XBASE 0x1094 48#define AZX_REG_VS_SDXEFIFOS_XBASE 0x1094
49#define AZX_REG_VS_SDXEFIFOS_XINTERVAL 0x20 49#define AZX_REG_VS_SDXEFIFOS_XINTERVAL 0x20
50 50
51#define AZX_PCIREG_CGCTL 0x48
52#define AZX_CGCTL_MISCBDCGE_MASK (1 << 6)
53
51struct skl_dsp_resource { 54struct skl_dsp_resource {
52 u32 max_mcps; 55 u32 max_mcps;
53 u32 max_mem; 56 u32 max_mem;
@@ -61,15 +64,18 @@ struct skl {
61 64
62 unsigned int init_failed:1; /* delayed init failed */ 65 unsigned int init_failed:1; /* delayed init failed */
63 struct platform_device *dmic_dev; 66 struct platform_device *dmic_dev;
67 struct platform_device *i2s_dev;
64 68
65 void *nhlt; /* nhlt ptr */ 69 void *nhlt; /* nhlt ptr */
66 struct skl_sst *skl_sst; /* sst skl ctx */ 70 struct skl_sst *skl_sst; /* sst skl ctx */
67 71
68 struct skl_dsp_resource resource; 72 struct skl_dsp_resource resource;
69 struct list_head ppl_list; 73 struct list_head ppl_list;
70 struct list_head dapm_path_list;
71 74
75 const char *fw_name;
72 const struct firmware *tplg; 76 const struct firmware *tplg;
77
78 int supend_active;
73}; 79};
74 80
75#define skl_to_ebus(s) (&(s)->ebus) 81#define skl_to_ebus(s) (&(s)->ebus)
diff --git a/sound/soc/mediatek/mtk-afe-common.h b/sound/soc/mediatek/mtk-afe-common.h
index cc4393cb1130..9b1af1a70874 100644
--- a/sound/soc/mediatek/mtk-afe-common.h
+++ b/sound/soc/mediatek/mtk-afe-common.h
@@ -92,7 +92,6 @@ struct mtk_afe_memif_data {
92struct mtk_afe_memif { 92struct mtk_afe_memif {
93 unsigned int phys_buf_addr; 93 unsigned int phys_buf_addr;
94 int buffer_size; 94 int buffer_size;
95 unsigned int hw_ptr; /* Previous IRQ's HW ptr */
96 struct snd_pcm_substream *substream; 95 struct snd_pcm_substream *substream;
97 const struct mtk_afe_memif_data *data; 96 const struct mtk_afe_memif_data *data;
98 const struct mtk_afe_irq_data *irqdata; 97 const struct mtk_afe_irq_data *irqdata;
diff --git a/sound/soc/mediatek/mtk-afe-pcm.c b/sound/soc/mediatek/mtk-afe-pcm.c
index f5baf3c38863..08af9f5dc4ab 100644
--- a/sound/soc/mediatek/mtk-afe-pcm.c
+++ b/sound/soc/mediatek/mtk-afe-pcm.c
@@ -175,8 +175,17 @@ static snd_pcm_uframes_t mtk_afe_pcm_pointer
175 struct snd_soc_pcm_runtime *rtd = substream->private_data; 175 struct snd_soc_pcm_runtime *rtd = substream->private_data;
176 struct mtk_afe *afe = snd_soc_platform_get_drvdata(rtd->platform); 176 struct mtk_afe *afe = snd_soc_platform_get_drvdata(rtd->platform);
177 struct mtk_afe_memif *memif = &afe->memif[rtd->cpu_dai->id]; 177 struct mtk_afe_memif *memif = &afe->memif[rtd->cpu_dai->id];
178 unsigned int hw_ptr;
179 int ret;
180
181 ret = regmap_read(afe->regmap, memif->data->reg_ofs_cur, &hw_ptr);
182 if (ret || hw_ptr == 0) {
183 dev_err(afe->dev, "%s hw_ptr err\n", __func__);
184 hw_ptr = memif->phys_buf_addr;
185 }
178 186
179 return bytes_to_frames(substream->runtime, memif->hw_ptr); 187 return bytes_to_frames(substream->runtime,
188 hw_ptr - memif->phys_buf_addr);
180} 189}
181 190
182static const struct snd_pcm_ops mtk_afe_pcm_ops = { 191static const struct snd_pcm_ops mtk_afe_pcm_ops = {
@@ -299,8 +308,6 @@ static int mtk_afe_dais_enable_clks(struct mtk_afe *afe,
299 dev_err(afe->dev, "Failed to enable m_ck\n"); 308 dev_err(afe->dev, "Failed to enable m_ck\n");
300 return ret; 309 return ret;
301 } 310 }
302 regmap_update_bits(afe->regmap, AUDIO_TOP_CON0,
303 AUD_TCON0_PDN_22M | AUD_TCON0_PDN_24M, 0);
304 } 311 }
305 312
306 if (b_ck) { 313 if (b_ck) {
@@ -340,12 +347,8 @@ static int mtk_afe_dais_set_clks(struct mtk_afe *afe,
340static void mtk_afe_dais_disable_clks(struct mtk_afe *afe, 347static void mtk_afe_dais_disable_clks(struct mtk_afe *afe,
341 struct clk *m_ck, struct clk *b_ck) 348 struct clk *m_ck, struct clk *b_ck)
342{ 349{
343 if (m_ck) { 350 if (m_ck)
344 regmap_update_bits(afe->regmap, AUDIO_TOP_CON0,
345 AUD_TCON0_PDN_22M | AUD_TCON0_PDN_24M,
346 AUD_TCON0_PDN_22M | AUD_TCON0_PDN_24M);
347 clk_disable_unprepare(m_ck); 351 clk_disable_unprepare(m_ck);
348 }
349 if (b_ck) 352 if (b_ck)
350 clk_disable_unprepare(b_ck); 353 clk_disable_unprepare(b_ck);
351} 354}
@@ -360,6 +363,8 @@ static int mtk_afe_i2s_startup(struct snd_pcm_substream *substream,
360 return 0; 363 return 0;
361 364
362 mtk_afe_dais_enable_clks(afe, afe->clocks[MTK_CLK_I2S1_M], NULL); 365 mtk_afe_dais_enable_clks(afe, afe->clocks[MTK_CLK_I2S1_M], NULL);
366 regmap_update_bits(afe->regmap, AUDIO_TOP_CON0,
367 AUD_TCON0_PDN_22M | AUD_TCON0_PDN_24M, 0);
363 return 0; 368 return 0;
364} 369}
365 370
@@ -373,10 +378,10 @@ static void mtk_afe_i2s_shutdown(struct snd_pcm_substream *substream,
373 return; 378 return;
374 379
375 mtk_afe_set_i2s_enable(afe, false); 380 mtk_afe_set_i2s_enable(afe, false);
381 regmap_update_bits(afe->regmap, AUDIO_TOP_CON0,
382 AUD_TCON0_PDN_22M | AUD_TCON0_PDN_24M,
383 AUD_TCON0_PDN_22M | AUD_TCON0_PDN_24M);
376 mtk_afe_dais_disable_clks(afe, afe->clocks[MTK_CLK_I2S1_M], NULL); 384 mtk_afe_dais_disable_clks(afe, afe->clocks[MTK_CLK_I2S1_M], NULL);
377
378 /* disable AFE */
379 regmap_update_bits(afe->regmap, AFE_DAC_CON0, 0x1, 0);
380} 385}
381 386
382static int mtk_afe_i2s_prepare(struct snd_pcm_substream *substream, 387static int mtk_afe_i2s_prepare(struct snd_pcm_substream *substream,
@@ -425,9 +430,6 @@ static void mtk_afe_hdmi_shutdown(struct snd_pcm_substream *substream,
425 430
426 mtk_afe_dais_disable_clks(afe, afe->clocks[MTK_CLK_I2S3_M], 431 mtk_afe_dais_disable_clks(afe, afe->clocks[MTK_CLK_I2S3_M],
427 afe->clocks[MTK_CLK_I2S3_B]); 432 afe->clocks[MTK_CLK_I2S3_B]);
428
429 /* disable AFE */
430 regmap_update_bits(afe->regmap, AFE_DAC_CON0, 0x1, 0);
431} 433}
432 434
433static int mtk_afe_hdmi_prepare(struct snd_pcm_substream *substream, 435static int mtk_afe_hdmi_prepare(struct snd_pcm_substream *substream,
@@ -603,7 +605,6 @@ static int mtk_afe_dais_hw_params(struct snd_pcm_substream *substream,
603 605
604 memif->phys_buf_addr = substream->runtime->dma_addr; 606 memif->phys_buf_addr = substream->runtime->dma_addr;
605 memif->buffer_size = substream->runtime->dma_bytes; 607 memif->buffer_size = substream->runtime->dma_bytes;
606 memif->hw_ptr = 0;
607 608
608 /* start */ 609 /* start */
609 regmap_write(afe->regmap, 610 regmap_write(afe->regmap,
@@ -672,17 +673,6 @@ static int mtk_afe_dais_hw_free(struct snd_pcm_substream *substream,
672 return snd_pcm_lib_free_pages(substream); 673 return snd_pcm_lib_free_pages(substream);
673} 674}
674 675
675static int mtk_afe_dais_prepare(struct snd_pcm_substream *substream,
676 struct snd_soc_dai *dai)
677{
678 struct snd_soc_pcm_runtime *rtd = substream->private_data;
679 struct mtk_afe *afe = snd_soc_platform_get_drvdata(rtd->platform);
680
681 /* enable AFE */
682 regmap_update_bits(afe->regmap, AFE_DAC_CON0, 0x1, 0x1);
683 return 0;
684}
685
686static int mtk_afe_dais_trigger(struct snd_pcm_substream *substream, int cmd, 676static int mtk_afe_dais_trigger(struct snd_pcm_substream *substream, int cmd,
687 struct snd_soc_dai *dai) 677 struct snd_soc_dai *dai)
688{ 678{
@@ -738,7 +728,6 @@ static int mtk_afe_dais_trigger(struct snd_pcm_substream *substream, int cmd,
738 /* and clear pending IRQ */ 728 /* and clear pending IRQ */
739 regmap_write(afe->regmap, AFE_IRQ_CLR, 729 regmap_write(afe->regmap, AFE_IRQ_CLR,
740 1 << memif->data->irq_clr_shift); 730 1 << memif->data->irq_clr_shift);
741 memif->hw_ptr = 0;
742 return 0; 731 return 0;
743 default: 732 default:
744 return -EINVAL; 733 return -EINVAL;
@@ -751,7 +740,6 @@ static const struct snd_soc_dai_ops mtk_afe_dai_ops = {
751 .shutdown = mtk_afe_dais_shutdown, 740 .shutdown = mtk_afe_dais_shutdown,
752 .hw_params = mtk_afe_dais_hw_params, 741 .hw_params = mtk_afe_dais_hw_params,
753 .hw_free = mtk_afe_dais_hw_free, 742 .hw_free = mtk_afe_dais_hw_free,
754 .prepare = mtk_afe_dais_prepare,
755 .trigger = mtk_afe_dais_trigger, 743 .trigger = mtk_afe_dais_trigger,
756}; 744};
757 745
@@ -1082,7 +1070,7 @@ static const struct regmap_config mtk_afe_regmap_config = {
1082static irqreturn_t mtk_afe_irq_handler(int irq, void *dev_id) 1070static irqreturn_t mtk_afe_irq_handler(int irq, void *dev_id)
1083{ 1071{
1084 struct mtk_afe *afe = dev_id; 1072 struct mtk_afe *afe = dev_id;
1085 unsigned int reg_value, hw_ptr; 1073 unsigned int reg_value;
1086 int i, ret; 1074 int i, ret;
1087 1075
1088 ret = regmap_read(afe->regmap, AFE_IRQ_STATUS, &reg_value); 1076 ret = regmap_read(afe->regmap, AFE_IRQ_STATUS, &reg_value);
@@ -1098,13 +1086,6 @@ static irqreturn_t mtk_afe_irq_handler(int irq, void *dev_id)
1098 if (!(reg_value & (1 << memif->data->irq_clr_shift))) 1086 if (!(reg_value & (1 << memif->data->irq_clr_shift)))
1099 continue; 1087 continue;
1100 1088
1101 ret = regmap_read(afe->regmap, memif->data->reg_ofs_cur,
1102 &hw_ptr);
1103 if (ret || hw_ptr == 0) {
1104 dev_err(afe->dev, "%s hw_ptr err\n", __func__);
1105 hw_ptr = memif->phys_buf_addr;
1106 }
1107 memif->hw_ptr = hw_ptr - memif->phys_buf_addr;
1108 snd_pcm_period_elapsed(memif->substream); 1089 snd_pcm_period_elapsed(memif->substream);
1109 } 1090 }
1110 1091
@@ -1119,6 +1100,9 @@ static int mtk_afe_runtime_suspend(struct device *dev)
1119{ 1100{
1120 struct mtk_afe *afe = dev_get_drvdata(dev); 1101 struct mtk_afe *afe = dev_get_drvdata(dev);
1121 1102
1103 /* disable AFE */
1104 regmap_update_bits(afe->regmap, AFE_DAC_CON0, 0x1, 0);
1105
1122 /* disable AFE clk */ 1106 /* disable AFE clk */
1123 regmap_update_bits(afe->regmap, AUDIO_TOP_CON0, 1107 regmap_update_bits(afe->regmap, AUDIO_TOP_CON0,
1124 AUD_TCON0_PDN_AFE, AUD_TCON0_PDN_AFE); 1108 AUD_TCON0_PDN_AFE, AUD_TCON0_PDN_AFE);
@@ -1165,6 +1149,9 @@ static int mtk_afe_runtime_resume(struct device *dev)
1165 1149
1166 /* unmask all IRQs */ 1150 /* unmask all IRQs */
1167 regmap_update_bits(afe->regmap, AFE_IRQ_MCU_EN, 0xff, 0xff); 1151 regmap_update_bits(afe->regmap, AFE_IRQ_MCU_EN, 0xff, 0xff);
1152
1153 /* enable AFE */
1154 regmap_update_bits(afe->regmap, AFE_DAC_CON0, 0x1, 0x1);
1168 return 0; 1155 return 0;
1169 1156
1170err_bck0: 1157err_bck0:
diff --git a/sound/soc/omap/omap-hdmi-audio.c b/sound/soc/omap/omap-hdmi-audio.c
index 584b2372339e..f83cc2bc0fc4 100644
--- a/sound/soc/omap/omap-hdmi-audio.c
+++ b/sound/soc/omap/omap-hdmi-audio.c
@@ -368,6 +368,8 @@ static int omap_hdmi_audio_probe(struct platform_device *pdev)
368 card->owner = THIS_MODULE; 368 card->owner = THIS_MODULE;
369 card->dai_link = 369 card->dai_link =
370 devm_kzalloc(dev, sizeof(*(card->dai_link)), GFP_KERNEL); 370 devm_kzalloc(dev, sizeof(*(card->dai_link)), GFP_KERNEL);
371 if (!card->dai_link)
372 return -ENOMEM;
371 card->dai_link->name = card->name; 373 card->dai_link->name = card->name;
372 card->dai_link->stream_name = card->name; 374 card->dai_link->stream_name = card->name;
373 card->dai_link->cpu_dai_name = dev_name(ad->dssdev); 375 card->dai_link->cpu_dai_name = dev_name(ad->dssdev);
diff --git a/sound/soc/pxa/brownstone.c b/sound/soc/pxa/brownstone.c
index 6147e86e9b0f..416ea646c3b1 100644
--- a/sound/soc/pxa/brownstone.c
+++ b/sound/soc/pxa/brownstone.c
@@ -63,8 +63,7 @@ static int brownstone_wm8994_hw_params(struct snd_pcm_substream *substream,
63 sysclk = params_rate(params) * 512; 63 sysclk = params_rate(params) * 512;
64 sspa_mclk = params_rate(params) * 64; 64 sspa_mclk = params_rate(params) * 64;
65 } 65 }
66 sspa_div = freq_out; 66 sspa_div = freq_out / sspa_mclk;
67 do_div(sspa_div, sspa_mclk);
68 67
69 snd_soc_dai_set_sysclk(cpu_dai, MMP_SSPA_CLK_AUDIO, freq_out, 0); 68 snd_soc_dai_set_sysclk(cpu_dai, MMP_SSPA_CLK_AUDIO, freq_out, 0);
70 snd_soc_dai_set_pll(cpu_dai, MMP_SYSCLK, 0, freq_out, sysclk); 69 snd_soc_dai_set_pll(cpu_dai, MMP_SYSCLK, 0, freq_out, sysclk);
diff --git a/sound/soc/pxa/mioa701_wm9713.c b/sound/soc/pxa/mioa701_wm9713.c
index 29bc60e85e92..5c8f9db50a47 100644
--- a/sound/soc/pxa/mioa701_wm9713.c
+++ b/sound/soc/pxa/mioa701_wm9713.c
@@ -81,8 +81,12 @@ static int rear_amp_power(struct snd_soc_codec *codec, int power)
81static int rear_amp_event(struct snd_soc_dapm_widget *widget, 81static int rear_amp_event(struct snd_soc_dapm_widget *widget,
82 struct snd_kcontrol *kctl, int event) 82 struct snd_kcontrol *kctl, int event)
83{ 83{
84 struct snd_soc_codec *codec = widget->dapm->card->rtd[0].codec; 84 struct snd_soc_card *card = widget->dapm->card;
85 struct snd_soc_pcm_runtime *rtd;
86 struct snd_soc_codec *codec;
85 87
88 rtd = snd_soc_get_pcm_runtime(card, card->dai_link[0].name);
89 codec = rtd->codec;
86 return rear_amp_power(codec, SND_SOC_DAPM_EVENT_ON(event)); 90 return rear_amp_power(codec, SND_SOC_DAPM_EVENT_ON(event));
87} 91}
88 92
diff --git a/sound/soc/qcom/lpass-cpu.c b/sound/soc/qcom/lpass-cpu.c
index e5101e0d2d37..00b6c9d039cf 100644
--- a/sound/soc/qcom/lpass-cpu.c
+++ b/sound/soc/qcom/lpass-cpu.c
@@ -355,6 +355,7 @@ static struct regmap_config lpass_cpu_regmap_config = {
355 .readable_reg = lpass_cpu_regmap_readable, 355 .readable_reg = lpass_cpu_regmap_readable,
356 .volatile_reg = lpass_cpu_regmap_volatile, 356 .volatile_reg = lpass_cpu_regmap_volatile,
357 .cache_type = REGCACHE_FLAT, 357 .cache_type = REGCACHE_FLAT,
358 .val_format_endian = REGMAP_ENDIAN_LITTLE,
358}; 359};
359 360
360int asoc_qcom_lpass_cpu_platform_probe(struct platform_device *pdev) 361int asoc_qcom_lpass_cpu_platform_probe(struct platform_device *pdev)
diff --git a/sound/soc/rockchip/rockchip_i2s.c b/sound/soc/rockchip/rockchip_i2s.c
index 58ee64594f07..6561c4cc2edd 100644
--- a/sound/soc/rockchip/rockchip_i2s.c
+++ b/sound/soc/rockchip/rockchip_i2s.c
@@ -34,13 +34,7 @@ struct rk_i2s_dev {
34 34
35 struct regmap *regmap; 35 struct regmap *regmap;
36 36
37/* 37 bool is_master_mode;
38 * Used to indicate the tx/rx status.
39 * I2S controller hopes to start the tx and rx together,
40 * also to stop them when they are both try to stop.
41*/
42 bool tx_start;
43 bool rx_start;
44}; 38};
45 39
46static int i2s_runtime_suspend(struct device *dev) 40static int i2s_runtime_suspend(struct device *dev)
@@ -81,37 +75,29 @@ static void rockchip_snd_txctrl(struct rk_i2s_dev *i2s, int on)
81 I2S_DMACR_TDE_ENABLE, I2S_DMACR_TDE_ENABLE); 75 I2S_DMACR_TDE_ENABLE, I2S_DMACR_TDE_ENABLE);
82 76
83 regmap_update_bits(i2s->regmap, I2S_XFER, 77 regmap_update_bits(i2s->regmap, I2S_XFER,
84 I2S_XFER_TXS_START | I2S_XFER_RXS_START, 78 I2S_XFER_TXS_START,
85 I2S_XFER_TXS_START | I2S_XFER_RXS_START); 79 I2S_XFER_TXS_START);
86
87 i2s->tx_start = true;
88 } else { 80 } else {
89 i2s->tx_start = false;
90
91 regmap_update_bits(i2s->regmap, I2S_DMACR, 81 regmap_update_bits(i2s->regmap, I2S_DMACR,
92 I2S_DMACR_TDE_ENABLE, I2S_DMACR_TDE_DISABLE); 82 I2S_DMACR_TDE_ENABLE, I2S_DMACR_TDE_DISABLE);
93 83
94 if (!i2s->rx_start) { 84 regmap_update_bits(i2s->regmap, I2S_XFER,
95 regmap_update_bits(i2s->regmap, I2S_XFER, 85 I2S_XFER_TXS_START,
96 I2S_XFER_TXS_START | 86 I2S_XFER_TXS_STOP);
97 I2S_XFER_RXS_START,
98 I2S_XFER_TXS_STOP |
99 I2S_XFER_RXS_STOP);
100 87
101 regmap_update_bits(i2s->regmap, I2S_CLR, 88 regmap_update_bits(i2s->regmap, I2S_CLR,
102 I2S_CLR_TXC | I2S_CLR_RXC, 89 I2S_CLR_TXC,
103 I2S_CLR_TXC | I2S_CLR_RXC); 90 I2S_CLR_TXC);
104 91
105 regmap_read(i2s->regmap, I2S_CLR, &val); 92 regmap_read(i2s->regmap, I2S_CLR, &val);
106 93
107 /* Should wait for clear operation to finish */ 94 /* Should wait for clear operation to finish */
108 while (val) { 95 while (val & I2S_CLR_TXC) {
109 regmap_read(i2s->regmap, I2S_CLR, &val); 96 regmap_read(i2s->regmap, I2S_CLR, &val);
110 retry--; 97 retry--;
111 if (!retry) { 98 if (!retry) {
112 dev_warn(i2s->dev, "fail to clear\n"); 99 dev_warn(i2s->dev, "fail to clear\n");
113 break; 100 break;
114 }
115 } 101 }
116 } 102 }
117 } 103 }
@@ -127,37 +113,29 @@ static void rockchip_snd_rxctrl(struct rk_i2s_dev *i2s, int on)
127 I2S_DMACR_RDE_ENABLE, I2S_DMACR_RDE_ENABLE); 113 I2S_DMACR_RDE_ENABLE, I2S_DMACR_RDE_ENABLE);
128 114
129 regmap_update_bits(i2s->regmap, I2S_XFER, 115 regmap_update_bits(i2s->regmap, I2S_XFER,
130 I2S_XFER_TXS_START | I2S_XFER_RXS_START, 116 I2S_XFER_RXS_START,
131 I2S_XFER_TXS_START | I2S_XFER_RXS_START); 117 I2S_XFER_RXS_START);
132
133 i2s->rx_start = true;
134 } else { 118 } else {
135 i2s->rx_start = false;
136
137 regmap_update_bits(i2s->regmap, I2S_DMACR, 119 regmap_update_bits(i2s->regmap, I2S_DMACR,
138 I2S_DMACR_RDE_ENABLE, I2S_DMACR_RDE_DISABLE); 120 I2S_DMACR_RDE_ENABLE, I2S_DMACR_RDE_DISABLE);
139 121
140 if (!i2s->tx_start) { 122 regmap_update_bits(i2s->regmap, I2S_XFER,
141 regmap_update_bits(i2s->regmap, I2S_XFER, 123 I2S_XFER_RXS_START,
142 I2S_XFER_TXS_START | 124 I2S_XFER_RXS_STOP);
143 I2S_XFER_RXS_START,
144 I2S_XFER_TXS_STOP |
145 I2S_XFER_RXS_STOP);
146 125
147 regmap_update_bits(i2s->regmap, I2S_CLR, 126 regmap_update_bits(i2s->regmap, I2S_CLR,
148 I2S_CLR_TXC | I2S_CLR_RXC, 127 I2S_CLR_RXC,
149 I2S_CLR_TXC | I2S_CLR_RXC); 128 I2S_CLR_RXC);
150 129
151 regmap_read(i2s->regmap, I2S_CLR, &val); 130 regmap_read(i2s->regmap, I2S_CLR, &val);
152 131
153 /* Should wait for clear operation to finish */ 132 /* Should wait for clear operation to finish */
154 while (val) { 133 while (val & I2S_CLR_RXC) {
155 regmap_read(i2s->regmap, I2S_CLR, &val); 134 regmap_read(i2s->regmap, I2S_CLR, &val);
156 retry--; 135 retry--;
157 if (!retry) { 136 if (!retry) {
158 dev_warn(i2s->dev, "fail to clear\n"); 137 dev_warn(i2s->dev, "fail to clear\n");
159 break; 138 break;
160 }
161 } 139 }
162 } 140 }
163 } 141 }
@@ -174,9 +152,11 @@ static int rockchip_i2s_set_fmt(struct snd_soc_dai *cpu_dai,
174 case SND_SOC_DAIFMT_CBS_CFS: 152 case SND_SOC_DAIFMT_CBS_CFS:
175 /* Set source clock in Master mode */ 153 /* Set source clock in Master mode */
176 val = I2S_CKR_MSS_MASTER; 154 val = I2S_CKR_MSS_MASTER;
155 i2s->is_master_mode = true;
177 break; 156 break;
178 case SND_SOC_DAIFMT_CBM_CFM: 157 case SND_SOC_DAIFMT_CBM_CFM:
179 val = I2S_CKR_MSS_SLAVE; 158 val = I2S_CKR_MSS_SLAVE;
159 i2s->is_master_mode = false;
180 break; 160 break;
181 default: 161 default:
182 return -EINVAL; 162 return -EINVAL;
@@ -228,6 +208,26 @@ static int rockchip_i2s_hw_params(struct snd_pcm_substream *substream,
228 struct rk_i2s_dev *i2s = to_info(dai); 208 struct rk_i2s_dev *i2s = to_info(dai);
229 struct snd_soc_pcm_runtime *rtd = substream->private_data; 209 struct snd_soc_pcm_runtime *rtd = substream->private_data;
230 unsigned int val = 0; 210 unsigned int val = 0;
211 unsigned int mclk_rate, bclk_rate, div_bclk, div_lrck;
212
213 if (i2s->is_master_mode) {
214 mclk_rate = clk_get_rate(i2s->mclk);
215 bclk_rate = 2 * 32 * params_rate(params);
216 if (bclk_rate && mclk_rate % bclk_rate)
217 return -EINVAL;
218
219 div_bclk = mclk_rate / bclk_rate;
220 div_lrck = bclk_rate / params_rate(params);
221 regmap_update_bits(i2s->regmap, I2S_CKR,
222 I2S_CKR_MDIV_MASK,
223 I2S_CKR_MDIV(div_bclk));
224
225 regmap_update_bits(i2s->regmap, I2S_CKR,
226 I2S_CKR_TSD_MASK |
227 I2S_CKR_RSD_MASK,
228 I2S_CKR_TSD(div_lrck) |
229 I2S_CKR_RSD(div_lrck));
230 }
231 231
232 switch (params_format(params)) { 232 switch (params_format(params)) {
233 case SNDRV_PCM_FORMAT_S8: 233 case SNDRV_PCM_FORMAT_S8:
@@ -242,6 +242,9 @@ static int rockchip_i2s_hw_params(struct snd_pcm_substream *substream,
242 case SNDRV_PCM_FORMAT_S24_LE: 242 case SNDRV_PCM_FORMAT_S24_LE:
243 val |= I2S_TXCR_VDW(24); 243 val |= I2S_TXCR_VDW(24);
244 break; 244 break;
245 case SNDRV_PCM_FORMAT_S32_LE:
246 val |= I2S_TXCR_VDW(32);
247 break;
245 default: 248 default:
246 return -EINVAL; 249 return -EINVAL;
247 } 250 }
@@ -360,7 +363,8 @@ static struct snd_soc_dai_driver rockchip_i2s_dai = {
360 .formats = (SNDRV_PCM_FMTBIT_S8 | 363 .formats = (SNDRV_PCM_FMTBIT_S8 |
361 SNDRV_PCM_FMTBIT_S16_LE | 364 SNDRV_PCM_FMTBIT_S16_LE |
362 SNDRV_PCM_FMTBIT_S20_3LE | 365 SNDRV_PCM_FMTBIT_S20_3LE |
363 SNDRV_PCM_FMTBIT_S24_LE), 366 SNDRV_PCM_FMTBIT_S24_LE |
367 SNDRV_PCM_FMTBIT_S32_LE),
364 }, 368 },
365 .capture = { 369 .capture = {
366 .stream_name = "Capture", 370 .stream_name = "Capture",
@@ -370,7 +374,8 @@ static struct snd_soc_dai_driver rockchip_i2s_dai = {
370 .formats = (SNDRV_PCM_FMTBIT_S8 | 374 .formats = (SNDRV_PCM_FMTBIT_S8 |
371 SNDRV_PCM_FMTBIT_S16_LE | 375 SNDRV_PCM_FMTBIT_S16_LE |
372 SNDRV_PCM_FMTBIT_S20_3LE | 376 SNDRV_PCM_FMTBIT_S20_3LE |
373 SNDRV_PCM_FMTBIT_S24_LE), 377 SNDRV_PCM_FMTBIT_S24_LE |
378 SNDRV_PCM_FMTBIT_S32_LE),
374 }, 379 },
375 .ops = &rockchip_i2s_dai_ops, 380 .ops = &rockchip_i2s_dai_ops,
376 .symmetric_rates = 1, 381 .symmetric_rates = 1,
@@ -451,6 +456,7 @@ static int rockchip_i2s_probe(struct platform_device *pdev)
451{ 456{
452 struct device_node *node = pdev->dev.of_node; 457 struct device_node *node = pdev->dev.of_node;
453 struct rk_i2s_dev *i2s; 458 struct rk_i2s_dev *i2s;
459 struct snd_soc_dai_driver *soc_dai;
454 struct resource *res; 460 struct resource *res;
455 void __iomem *regs; 461 void __iomem *regs;
456 int ret; 462 int ret;
@@ -511,17 +517,26 @@ static int rockchip_i2s_probe(struct platform_device *pdev)
511 goto err_pm_disable; 517 goto err_pm_disable;
512 } 518 }
513 519
514 /* refine capture channels */ 520 soc_dai = devm_kzalloc(&pdev->dev,
521 sizeof(*soc_dai), GFP_KERNEL);
522 if (!soc_dai)
523 return -ENOMEM;
524
525 memcpy(soc_dai, &rockchip_i2s_dai, sizeof(*soc_dai));
526 if (!of_property_read_u32(node, "rockchip,playback-channels", &val)) {
527 if (val >= 2 && val <= 8)
528 soc_dai->playback.channels_max = val;
529 }
530
515 if (!of_property_read_u32(node, "rockchip,capture-channels", &val)) { 531 if (!of_property_read_u32(node, "rockchip,capture-channels", &val)) {
516 if (val >= 2 && val <= 8) 532 if (val >= 2 && val <= 8)
517 rockchip_i2s_dai.capture.channels_max = val; 533 soc_dai->capture.channels_max = val;
518 else
519 rockchip_i2s_dai.capture.channels_max = 2;
520 } 534 }
521 535
522 ret = devm_snd_soc_register_component(&pdev->dev, 536 ret = devm_snd_soc_register_component(&pdev->dev,
523 &rockchip_i2s_component, 537 &rockchip_i2s_component,
524 &rockchip_i2s_dai, 1); 538 soc_dai, 1);
539
525 if (ret) { 540 if (ret) {
526 dev_err(&pdev->dev, "Could not register DAI\n"); 541 dev_err(&pdev->dev, "Could not register DAI\n");
527 goto err_suspend; 542 goto err_suspend;
diff --git a/sound/soc/rockchip/rockchip_max98090.c b/sound/soc/rockchip/rockchip_max98090.c
index 26567b10393a..543610282cdb 100644
--- a/sound/soc/rockchip/rockchip_max98090.c
+++ b/sound/soc/rockchip/rockchip_max98090.c
@@ -80,11 +80,17 @@ static int rk_aif1_hw_params(struct snd_pcm_substream *substream,
80 switch (params_rate(params)) { 80 switch (params_rate(params)) {
81 case 8000: 81 case 8000:
82 case 16000: 82 case 16000:
83 case 24000:
84 case 32000:
83 case 48000: 85 case 48000:
86 case 64000:
84 case 96000: 87 case 96000:
85 mclk = 12288000; 88 mclk = 12288000;
86 break; 89 break;
90 case 11025:
91 case 22050:
87 case 44100: 92 case 44100:
93 case 88200:
88 mclk = 11289600; 94 mclk = 11289600;
89 break; 95 break;
90 default: 96 default:
diff --git a/sound/soc/rockchip/rockchip_rt5645.c b/sound/soc/rockchip/rockchip_rt5645.c
index 68c62e4c2316..440a8026346a 100644
--- a/sound/soc/rockchip/rockchip_rt5645.c
+++ b/sound/soc/rockchip/rockchip_rt5645.c
@@ -79,11 +79,17 @@ static int rk_aif1_hw_params(struct snd_pcm_substream *substream,
79 switch (params_rate(params)) { 79 switch (params_rate(params)) {
80 case 8000: 80 case 8000:
81 case 16000: 81 case 16000:
82 case 24000:
83 case 32000:
82 case 48000: 84 case 48000:
85 case 64000:
83 case 96000: 86 case 96000:
84 mclk = 12288000; 87 mclk = 12288000;
85 break; 88 break;
89 case 11025:
90 case 22050:
86 case 44100: 91 case 44100:
92 case 88200:
87 mclk = 11289600; 93 mclk = 11289600;
88 break; 94 break;
89 default: 95 default:
diff --git a/sound/soc/samsung/Kconfig b/sound/soc/samsung/Kconfig
index 3744c9ed5370..78baa26e938b 100644
--- a/sound/soc/samsung/Kconfig
+++ b/sound/soc/samsung/Kconfig
@@ -1,8 +1,6 @@
1config SND_SOC_SAMSUNG 1config 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 depends on S3C64XX_PL080 || !ARCH_S3C64XX
5 depends on S3C24XX_DMAC || !ARCH_S3C24XX
6 select SND_SOC_GENERIC_DMAENGINE_PCM 4 select SND_SOC_GENERIC_DMAENGINE_PCM
7 help 5 help
8 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
diff --git a/sound/soc/samsung/ac97.c b/sound/soc/samsung/ac97.c
index e4145509d63c..4a7a503fe13c 100644
--- a/sound/soc/samsung/ac97.c
+++ b/sound/soc/samsung/ac97.c
@@ -324,7 +324,7 @@ static const struct snd_soc_component_driver s3c_ac97_component = {
324 324
325static int s3c_ac97_probe(struct platform_device *pdev) 325static int s3c_ac97_probe(struct platform_device *pdev)
326{ 326{
327 struct resource *mem_res, *dmatx_res, *dmarx_res, *dmamic_res, *irq_res; 327 struct resource *mem_res, *irq_res;
328 struct s3c_audio_pdata *ac97_pdata; 328 struct s3c_audio_pdata *ac97_pdata;
329 int ret; 329 int ret;
330 330
@@ -335,24 +335,6 @@ static int s3c_ac97_probe(struct platform_device *pdev)
335 } 335 }
336 336
337 /* Check for availability of necessary resource */ 337 /* Check for availability of necessary resource */
338 dmatx_res = platform_get_resource(pdev, IORESOURCE_DMA, 0);
339 if (!dmatx_res) {
340 dev_err(&pdev->dev, "Unable to get AC97-TX dma resource\n");
341 return -ENXIO;
342 }
343
344 dmarx_res = platform_get_resource(pdev, IORESOURCE_DMA, 1);
345 if (!dmarx_res) {
346 dev_err(&pdev->dev, "Unable to get AC97-RX dma resource\n");
347 return -ENXIO;
348 }
349
350 dmamic_res = platform_get_resource(pdev, IORESOURCE_DMA, 2);
351 if (!dmamic_res) {
352 dev_err(&pdev->dev, "Unable to get AC97-MIC dma resource\n");
353 return -ENXIO;
354 }
355
356 irq_res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); 338 irq_res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
357 if (!irq_res) { 339 if (!irq_res) {
358 dev_err(&pdev->dev, "AC97 IRQ not provided!\n"); 340 dev_err(&pdev->dev, "AC97 IRQ not provided!\n");
@@ -364,11 +346,11 @@ static int s3c_ac97_probe(struct platform_device *pdev)
364 if (IS_ERR(s3c_ac97.regs)) 346 if (IS_ERR(s3c_ac97.regs))
365 return PTR_ERR(s3c_ac97.regs); 347 return PTR_ERR(s3c_ac97.regs);
366 348
367 s3c_ac97_pcm_out.channel = dmatx_res->start; 349 s3c_ac97_pcm_out.slave = ac97_pdata->dma_playback;
368 s3c_ac97_pcm_out.dma_addr = mem_res->start + S3C_AC97_PCM_DATA; 350 s3c_ac97_pcm_out.dma_addr = mem_res->start + S3C_AC97_PCM_DATA;
369 s3c_ac97_pcm_in.channel = dmarx_res->start; 351 s3c_ac97_pcm_in.slave = ac97_pdata->dma_capture;
370 s3c_ac97_pcm_in.dma_addr = mem_res->start + S3C_AC97_PCM_DATA; 352 s3c_ac97_pcm_in.dma_addr = mem_res->start + S3C_AC97_PCM_DATA;
371 s3c_ac97_mic_in.channel = dmamic_res->start; 353 s3c_ac97_mic_in.slave = ac97_pdata->dma_capture_mic;
372 s3c_ac97_mic_in.dma_addr = mem_res->start + S3C_AC97_MIC_DATA; 354 s3c_ac97_mic_in.dma_addr = mem_res->start + S3C_AC97_MIC_DATA;
373 355
374 init_completion(&s3c_ac97.done); 356 init_completion(&s3c_ac97.done);
@@ -406,7 +388,8 @@ static int s3c_ac97_probe(struct platform_device *pdev)
406 if (ret) 388 if (ret)
407 goto err5; 389 goto err5;
408 390
409 ret = samsung_asoc_dma_platform_register(&pdev->dev); 391 ret = samsung_asoc_dma_platform_register(&pdev->dev,
392 ac97_pdata->dma_filter);
410 if (ret) { 393 if (ret) {
411 dev_err(&pdev->dev, "failed to get register DMA: %d\n", ret); 394 dev_err(&pdev->dev, "failed to get register DMA: %d\n", ret);
412 goto err5; 395 goto err5;
diff --git a/sound/soc/samsung/bells.c b/sound/soc/samsung/bells.c
index e5f05e62fa3c..3dd246fa0059 100644
--- a/sound/soc/samsung/bells.c
+++ b/sound/soc/samsung/bells.c
@@ -58,11 +58,16 @@ static int bells_set_bias_level(struct snd_soc_card *card,
58 struct snd_soc_dapm_context *dapm, 58 struct snd_soc_dapm_context *dapm,
59 enum snd_soc_bias_level level) 59 enum snd_soc_bias_level level)
60{ 60{
61 struct snd_soc_dai *codec_dai = card->rtd[DAI_DSP_CODEC].codec_dai; 61 struct snd_soc_pcm_runtime *rtd;
62 struct snd_soc_codec *codec = codec_dai->codec; 62 struct snd_soc_dai *codec_dai;
63 struct snd_soc_codec *codec;
63 struct bells_drvdata *bells = card->drvdata; 64 struct bells_drvdata *bells = card->drvdata;
64 int ret; 65 int ret;
65 66
67 rtd = snd_soc_get_pcm_runtime(card, card->dai_link[DAI_DSP_CODEC].name);
68 codec_dai = rtd->codec_dai;
69 codec = codec_dai->codec;
70
66 if (dapm->dev != codec_dai->dev) 71 if (dapm->dev != codec_dai->dev)
67 return 0; 72 return 0;
68 73
@@ -99,11 +104,16 @@ static int bells_set_bias_level_post(struct snd_soc_card *card,
99 struct snd_soc_dapm_context *dapm, 104 struct snd_soc_dapm_context *dapm,
100 enum snd_soc_bias_level level) 105 enum snd_soc_bias_level level)
101{ 106{
102 struct snd_soc_dai *codec_dai = card->rtd[DAI_DSP_CODEC].codec_dai; 107 struct snd_soc_pcm_runtime *rtd;
103 struct snd_soc_codec *codec = codec_dai->codec; 108 struct snd_soc_dai *codec_dai;
109 struct snd_soc_codec *codec;
104 struct bells_drvdata *bells = card->drvdata; 110 struct bells_drvdata *bells = card->drvdata;
105 int ret; 111 int ret;
106 112
113 rtd = snd_soc_get_pcm_runtime(card, card->dai_link[DAI_DSP_CODEC].name);
114 codec_dai = rtd->codec_dai;
115 codec = codec_dai->codec;
116
107 if (dapm->dev != codec_dai->dev) 117 if (dapm->dev != codec_dai->dev)
108 return 0; 118 return 0;
109 119
@@ -137,14 +147,22 @@ static int bells_set_bias_level_post(struct snd_soc_card *card,
137static int bells_late_probe(struct snd_soc_card *card) 147static int bells_late_probe(struct snd_soc_card *card)
138{ 148{
139 struct bells_drvdata *bells = card->drvdata; 149 struct bells_drvdata *bells = card->drvdata;
140 struct snd_soc_codec *wm0010 = card->rtd[DAI_AP_DSP].codec; 150 struct snd_soc_pcm_runtime *rtd;
141 struct snd_soc_codec *codec = card->rtd[DAI_DSP_CODEC].codec; 151 struct snd_soc_codec *wm0010;
142 struct snd_soc_dai *aif1_dai = card->rtd[DAI_DSP_CODEC].codec_dai; 152 struct snd_soc_codec *codec;
153 struct snd_soc_dai *aif1_dai;
143 struct snd_soc_dai *aif2_dai; 154 struct snd_soc_dai *aif2_dai;
144 struct snd_soc_dai *aif3_dai; 155 struct snd_soc_dai *aif3_dai;
145 struct snd_soc_dai *wm9081_dai; 156 struct snd_soc_dai *wm9081_dai;
146 int ret; 157 int ret;
147 158
159 rtd = snd_soc_get_pcm_runtime(card, card->dai_link[DAI_AP_DSP].name);
160 wm0010 = rtd->codec;
161
162 rtd = snd_soc_get_pcm_runtime(card, card->dai_link[DAI_DSP_CODEC].name);
163 codec = rtd->codec;
164 aif1_dai = rtd->codec_dai;
165
148 ret = snd_soc_codec_set_sysclk(codec, ARIZONA_CLK_SYSCLK, 166 ret = snd_soc_codec_set_sysclk(codec, ARIZONA_CLK_SYSCLK,
149 ARIZONA_CLK_SRC_FLL1, 167 ARIZONA_CLK_SRC_FLL1,
150 bells->sysclk_rate, 168 bells->sysclk_rate,
@@ -181,7 +199,8 @@ static int bells_late_probe(struct snd_soc_card *card)
181 return ret; 199 return ret;
182 } 200 }
183 201
184 aif2_dai = card->rtd[DAI_CODEC_CP].cpu_dai; 202 rtd = snd_soc_get_pcm_runtime(card, card->dai_link[DAI_CODEC_CP].name);
203 aif2_dai = rtd->cpu_dai;
185 204
186 ret = snd_soc_dai_set_sysclk(aif2_dai, ARIZONA_CLK_ASYNCCLK, 0, 0); 205 ret = snd_soc_dai_set_sysclk(aif2_dai, ARIZONA_CLK_ASYNCCLK, 0, 0);
187 if (ret != 0) { 206 if (ret != 0) {
@@ -192,8 +211,9 @@ static int bells_late_probe(struct snd_soc_card *card)
192 if (card->num_rtd == DAI_CODEC_SUB) 211 if (card->num_rtd == DAI_CODEC_SUB)
193 return 0; 212 return 0;
194 213
195 aif3_dai = card->rtd[DAI_CODEC_SUB].cpu_dai; 214 rtd = snd_soc_get_pcm_runtime(card, card->dai_link[DAI_CODEC_SUB].name);
196 wm9081_dai = card->rtd[DAI_CODEC_SUB].codec_dai; 215 aif3_dai = rtd->cpu_dai;
216 wm9081_dai = rtd->codec_dai;
197 217
198 ret = snd_soc_dai_set_sysclk(aif3_dai, ARIZONA_CLK_SYSCLK, 0, 0); 218 ret = snd_soc_dai_set_sysclk(aif3_dai, ARIZONA_CLK_SYSCLK, 0, 0);
199 if (ret != 0) { 219 if (ret != 0) {
diff --git a/sound/soc/samsung/dma.h b/sound/soc/samsung/dma.h
index 0e85dcfec023..a7616cc9b39e 100644
--- a/sound/soc/samsung/dma.h
+++ b/sound/soc/samsung/dma.h
@@ -13,9 +13,10 @@
13#define _S3C_AUDIO_H 13#define _S3C_AUDIO_H
14 14
15#include <sound/dmaengine_pcm.h> 15#include <sound/dmaengine_pcm.h>
16#include <linux/dmaengine.h>
16 17
17struct s3c_dma_params { 18struct s3c_dma_params {
18 int channel; /* Channel ID */ 19 void *slave; /* Channel ID */
19 dma_addr_t dma_addr; 20 dma_addr_t dma_addr;
20 int dma_size; /* Size of the DMA transfer */ 21 int dma_size; /* Size of the DMA transfer */
21 char *ch_name; 22 char *ch_name;
@@ -25,6 +26,7 @@ struct s3c_dma_params {
25void samsung_asoc_init_dma_data(struct snd_soc_dai *dai, 26void samsung_asoc_init_dma_data(struct snd_soc_dai *dai,
26 struct s3c_dma_params *playback, 27 struct s3c_dma_params *playback,
27 struct s3c_dma_params *capture); 28 struct s3c_dma_params *capture);
28int samsung_asoc_dma_platform_register(struct device *dev); 29int samsung_asoc_dma_platform_register(struct device *dev,
30 dma_filter_fn fn);
29 31
30#endif 32#endif
diff --git a/sound/soc/samsung/dmaengine.c b/sound/soc/samsung/dmaengine.c
index 506f5bf6d082..063125937311 100644
--- a/sound/soc/samsung/dmaengine.c
+++ b/sound/soc/samsung/dmaengine.c
@@ -28,17 +28,8 @@
28 28
29#include "dma.h" 29#include "dma.h"
30 30
31#ifdef CONFIG_ARCH_S3C64XX 31static struct snd_dmaengine_pcm_config samsung_dmaengine_pcm_config = {
32#define filter_fn pl08x_filter_id
33#elif defined(CONFIG_ARCH_S3C24XX)
34#define filter_fn s3c24xx_dma_filter
35#else
36#define filter_fn NULL
37#endif
38
39static const struct snd_dmaengine_pcm_config samsung_dmaengine_pcm_config = {
40 .prepare_slave_config = snd_dmaengine_pcm_prepare_slave_config, 32 .prepare_slave_config = snd_dmaengine_pcm_prepare_slave_config,
41 .compat_filter_fn = filter_fn,
42}; 33};
43 34
44void samsung_asoc_init_dma_data(struct snd_soc_dai *dai, 35void samsung_asoc_init_dma_data(struct snd_soc_dai *dai,
@@ -50,14 +41,14 @@ void samsung_asoc_init_dma_data(struct snd_soc_dai *dai,
50 41
51 if (playback) { 42 if (playback) {
52 playback_data = &playback->dma_data; 43 playback_data = &playback->dma_data;
53 playback_data->filter_data = (void *)playback->channel; 44 playback_data->filter_data = playback->slave;
54 playback_data->chan_name = playback->ch_name; 45 playback_data->chan_name = playback->ch_name;
55 playback_data->addr = playback->dma_addr; 46 playback_data->addr = playback->dma_addr;
56 playback_data->addr_width = playback->dma_size; 47 playback_data->addr_width = playback->dma_size;
57 } 48 }
58 if (capture) { 49 if (capture) {
59 capture_data = &capture->dma_data; 50 capture_data = &capture->dma_data;
60 capture_data->filter_data = (void *)capture->channel; 51 capture_data->filter_data = capture->slave;
61 capture_data->chan_name = capture->ch_name; 52 capture_data->chan_name = capture->ch_name;
62 capture_data->addr = capture->dma_addr; 53 capture_data->addr = capture->dma_addr;
63 capture_data->addr_width = capture->dma_size; 54 capture_data->addr_width = capture->dma_size;
@@ -67,8 +58,11 @@ void samsung_asoc_init_dma_data(struct snd_soc_dai *dai,
67} 58}
68EXPORT_SYMBOL_GPL(samsung_asoc_init_dma_data); 59EXPORT_SYMBOL_GPL(samsung_asoc_init_dma_data);
69 60
70int samsung_asoc_dma_platform_register(struct device *dev) 61int samsung_asoc_dma_platform_register(struct device *dev,
62 dma_filter_fn filter)
71{ 63{
64 samsung_dmaengine_pcm_config.compat_filter_fn = filter;
65
72 return devm_snd_dmaengine_pcm_register(dev, 66 return devm_snd_dmaengine_pcm_register(dev,
73 &samsung_dmaengine_pcm_config, 67 &samsung_dmaengine_pcm_config,
74 SND_DMAENGINE_PCM_FLAG_CUSTOM_CHANNEL_NAME | 68 SND_DMAENGINE_PCM_FLAG_CUSTOM_CHANNEL_NAME |
diff --git a/sound/soc/samsung/i2s.c b/sound/soc/samsung/i2s.c
index ea4ab374a223..84d9e77c0fbe 100644
--- a/sound/soc/samsung/i2s.c
+++ b/sound/soc/samsung/i2s.c
@@ -89,6 +89,7 @@ struct i2s_dai {
89 struct s3c_dma_params dma_playback; 89 struct s3c_dma_params dma_playback;
90 struct s3c_dma_params dma_capture; 90 struct s3c_dma_params dma_capture;
91 struct s3c_dma_params idma_playback; 91 struct s3c_dma_params idma_playback;
92 dma_filter_fn filter;
92 u32 quirks; 93 u32 quirks;
93 u32 suspend_i2smod; 94 u32 suspend_i2smod;
94 u32 suspend_i2scon; 95 u32 suspend_i2scon;
@@ -1244,7 +1245,8 @@ static int samsung_i2s_probe(struct platform_device *pdev)
1244 if (ret != 0) 1245 if (ret != 0)
1245 return ret; 1246 return ret;
1246 1247
1247 return samsung_asoc_dma_platform_register(&pdev->dev); 1248 return samsung_asoc_dma_platform_register(&pdev->dev,
1249 sec_dai->filter);
1248 } 1250 }
1249 1251
1250 pri_dai = i2s_alloc_dai(pdev, false); 1252 pri_dai = i2s_alloc_dai(pdev, false);
@@ -1257,27 +1259,15 @@ static int samsung_i2s_probe(struct platform_device *pdev)
1257 pri_dai->lock = &pri_dai->spinlock; 1259 pri_dai->lock = &pri_dai->spinlock;
1258 1260
1259 if (!np) { 1261 if (!np) {
1260 res = platform_get_resource(pdev, IORESOURCE_DMA, 0);
1261 if (!res) {
1262 dev_err(&pdev->dev,
1263 "Unable to get I2S-TX dma resource\n");
1264 return -ENXIO;
1265 }
1266 pri_dai->dma_playback.channel = res->start;
1267
1268 res = platform_get_resource(pdev, IORESOURCE_DMA, 1);
1269 if (!res) {
1270 dev_err(&pdev->dev,
1271 "Unable to get I2S-RX dma resource\n");
1272 return -ENXIO;
1273 }
1274 pri_dai->dma_capture.channel = res->start;
1275
1276 if (i2s_pdata == NULL) { 1262 if (i2s_pdata == NULL) {
1277 dev_err(&pdev->dev, "Can't work without s3c_audio_pdata\n"); 1263 dev_err(&pdev->dev, "Can't work without s3c_audio_pdata\n");
1278 return -EINVAL; 1264 return -EINVAL;
1279 } 1265 }
1280 1266
1267 pri_dai->dma_playback.slave = i2s_pdata->dma_playback;
1268 pri_dai->dma_capture.slave = i2s_pdata->dma_capture;
1269 pri_dai->filter = i2s_pdata->dma_filter;
1270
1281 if (&i2s_pdata->type) 1271 if (&i2s_pdata->type)
1282 i2s_cfg = &i2s_pdata->type.i2s; 1272 i2s_cfg = &i2s_pdata->type.i2s;
1283 1273
@@ -1339,9 +1329,8 @@ static int samsung_i2s_probe(struct platform_device *pdev)
1339 sec_dai->dma_playback.ch_name = "tx-sec"; 1329 sec_dai->dma_playback.ch_name = "tx-sec";
1340 1330
1341 if (!np) { 1331 if (!np) {
1342 res = platform_get_resource(pdev, IORESOURCE_DMA, 2); 1332 sec_dai->dma_playback.slave = i2s_pdata->dma_play_sec;
1343 if (res) 1333 sec_dai->filter = i2s_pdata->dma_filter;
1344 sec_dai->dma_playback.channel = res->start;
1345 } 1334 }
1346 1335
1347 sec_dai->dma_playback.dma_size = 4; 1336 sec_dai->dma_playback.dma_size = 4;
@@ -1364,7 +1353,7 @@ static int samsung_i2s_probe(struct platform_device *pdev)
1364 1353
1365 pm_runtime_enable(&pdev->dev); 1354 pm_runtime_enable(&pdev->dev);
1366 1355
1367 ret = samsung_asoc_dma_platform_register(&pdev->dev); 1356 ret = samsung_asoc_dma_platform_register(&pdev->dev, pri_dai->filter);
1368 if (ret != 0) 1357 if (ret != 0)
1369 return ret; 1358 return ret;
1370 1359
diff --git a/sound/soc/samsung/littlemill.c b/sound/soc/samsung/littlemill.c
index 31a820eb0ac3..7cb204e649ca 100644
--- a/sound/soc/samsung/littlemill.c
+++ b/sound/soc/samsung/littlemill.c
@@ -23,9 +23,13 @@ static int littlemill_set_bias_level(struct snd_soc_card *card,
23 struct snd_soc_dapm_context *dapm, 23 struct snd_soc_dapm_context *dapm,
24 enum snd_soc_bias_level level) 24 enum snd_soc_bias_level level)
25{ 25{
26 struct snd_soc_dai *aif1_dai = card->rtd[0].codec_dai; 26 struct snd_soc_pcm_runtime *rtd;
27 struct snd_soc_dai *aif1_dai;
27 int ret; 28 int ret;
28 29
30 rtd = snd_soc_get_pcm_runtime(card, card->dai_link[0].name);
31 aif1_dai = rtd->codec_dai;
32
29 if (dapm->dev != aif1_dai->dev) 33 if (dapm->dev != aif1_dai->dev)
30 return 0; 34 return 0;
31 35
@@ -66,9 +70,13 @@ static int littlemill_set_bias_level_post(struct snd_soc_card *card,
66 struct snd_soc_dapm_context *dapm, 70 struct snd_soc_dapm_context *dapm,
67 enum snd_soc_bias_level level) 71 enum snd_soc_bias_level level)
68{ 72{
69 struct snd_soc_dai *aif1_dai = card->rtd[0].codec_dai; 73 struct snd_soc_pcm_runtime *rtd;
74 struct snd_soc_dai *aif1_dai;
70 int ret; 75 int ret;
71 76
77 rtd = snd_soc_get_pcm_runtime(card, card->dai_link[0].name);
78 aif1_dai = rtd->codec_dai;
79
72 if (dapm->dev != aif1_dai->dev) 80 if (dapm->dev != aif1_dai->dev)
73 return 0; 81 return 0;
74 82
@@ -168,9 +176,13 @@ static int bbclk_ev(struct snd_soc_dapm_widget *w,
168 struct snd_kcontrol *kcontrol, int event) 176 struct snd_kcontrol *kcontrol, int event)
169{ 177{
170 struct snd_soc_card *card = w->dapm->card; 178 struct snd_soc_card *card = w->dapm->card;
171 struct snd_soc_dai *aif2_dai = card->rtd[1].cpu_dai; 179 struct snd_soc_pcm_runtime *rtd;
180 struct snd_soc_dai *aif2_dai;
172 int ret; 181 int ret;
173 182
183 rtd = snd_soc_get_pcm_runtime(card, card->dai_link[1].name);
184 aif2_dai = rtd->cpu_dai;
185
174 switch (event) { 186 switch (event) {
175 case SND_SOC_DAPM_PRE_PMU: 187 case SND_SOC_DAPM_PRE_PMU:
176 ret = snd_soc_dai_set_pll(aif2_dai, WM8994_FLL2, 188 ret = snd_soc_dai_set_pll(aif2_dai, WM8994_FLL2,
@@ -245,11 +257,19 @@ static struct snd_soc_jack littlemill_headset;
245 257
246static int littlemill_late_probe(struct snd_soc_card *card) 258static int littlemill_late_probe(struct snd_soc_card *card)
247{ 259{
248 struct snd_soc_codec *codec = card->rtd[0].codec; 260 struct snd_soc_pcm_runtime *rtd;
249 struct snd_soc_dai *aif1_dai = card->rtd[0].codec_dai; 261 struct snd_soc_codec *codec;
250 struct snd_soc_dai *aif2_dai = card->rtd[1].cpu_dai; 262 struct snd_soc_dai *aif1_dai;
263 struct snd_soc_dai *aif2_dai;
251 int ret; 264 int ret;
252 265
266 rtd = snd_soc_get_pcm_runtime(card, card->dai_link[0].name);
267 codec = rtd->codec;
268 aif1_dai = rtd->codec_dai;
269
270 rtd = snd_soc_get_pcm_runtime(card, card->dai_link[1].name);
271 aif2_dai = rtd->cpu_dai;
272
253 ret = snd_soc_dai_set_sysclk(aif1_dai, WM8994_SYSCLK_MCLK2, 273 ret = snd_soc_dai_set_sysclk(aif1_dai, WM8994_SYSCLK_MCLK2,
254 32768, SND_SOC_CLOCK_IN); 274 32768, SND_SOC_CLOCK_IN);
255 if (ret < 0) 275 if (ret < 0)
diff --git a/sound/soc/samsung/odroidx2_max98090.c b/sound/soc/samsung/odroidx2_max98090.c
index 596f1180a369..04217279fe25 100644
--- a/sound/soc/samsung/odroidx2_max98090.c
+++ b/sound/soc/samsung/odroidx2_max98090.c
@@ -25,10 +25,15 @@ static struct snd_soc_dai_link odroidx2_dai[];
25 25
26static int odroidx2_late_probe(struct snd_soc_card *card) 26static int odroidx2_late_probe(struct snd_soc_card *card)
27{ 27{
28 struct snd_soc_dai *codec_dai = card->rtd[0].codec_dai; 28 struct snd_soc_pcm_runtime *rtd;
29 struct snd_soc_dai *cpu_dai = card->rtd[0].cpu_dai; 29 struct snd_soc_dai *codec_dai;
30 struct snd_soc_dai *cpu_dai;
30 int ret; 31 int ret;
31 32
33 rtd = snd_soc_get_pcm_runtime(card, card->dai_link[0].name);
34 codec_dai = rtd->codec_dai;
35 cpu_dai = rtd->cpu_dai;
36
32 ret = snd_soc_dai_set_sysclk(codec_dai, 0, MAX98090_MCLK, 37 ret = snd_soc_dai_set_sysclk(codec_dai, 0, MAX98090_MCLK,
33 SND_SOC_CLOCK_IN); 38 SND_SOC_CLOCK_IN);
34 39
diff --git a/sound/soc/samsung/pcm.c b/sound/soc/samsung/pcm.c
index b320a9d3fbf8..498f563a4c9c 100644
--- a/sound/soc/samsung/pcm.c
+++ b/sound/soc/samsung/pcm.c
@@ -486,8 +486,9 @@ static const struct snd_soc_component_driver s3c_pcm_component = {
486static int s3c_pcm_dev_probe(struct platform_device *pdev) 486static int s3c_pcm_dev_probe(struct platform_device *pdev)
487{ 487{
488 struct s3c_pcm_info *pcm; 488 struct s3c_pcm_info *pcm;
489 struct resource *mem_res, *dmatx_res, *dmarx_res; 489 struct resource *mem_res;
490 struct s3c_audio_pdata *pcm_pdata; 490 struct s3c_audio_pdata *pcm_pdata;
491 dma_filter_fn filter;
491 int ret; 492 int ret;
492 493
493 /* Check for valid device index */ 494 /* Check for valid device index */
@@ -499,18 +500,6 @@ static int s3c_pcm_dev_probe(struct platform_device *pdev)
499 pcm_pdata = pdev->dev.platform_data; 500 pcm_pdata = pdev->dev.platform_data;
500 501
501 /* Check for availability of necessary resource */ 502 /* Check for availability of necessary resource */
502 dmatx_res = platform_get_resource(pdev, IORESOURCE_DMA, 0);
503 if (!dmatx_res) {
504 dev_err(&pdev->dev, "Unable to get PCM-TX dma resource\n");
505 return -ENXIO;
506 }
507
508 dmarx_res = platform_get_resource(pdev, IORESOURCE_DMA, 1);
509 if (!dmarx_res) {
510 dev_err(&pdev->dev, "Unable to get PCM-RX dma resource\n");
511 return -ENXIO;
512 }
513
514 mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 503 mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
515 if (!mem_res) { 504 if (!mem_res) {
516 dev_err(&pdev->dev, "Unable to get register resource\n"); 505 dev_err(&pdev->dev, "Unable to get register resource\n");
@@ -568,8 +557,12 @@ static int s3c_pcm_dev_probe(struct platform_device *pdev)
568 s3c_pcm_stereo_out[pdev->id].dma_addr = mem_res->start 557 s3c_pcm_stereo_out[pdev->id].dma_addr = mem_res->start
569 + S3C_PCM_TXFIFO; 558 + S3C_PCM_TXFIFO;
570 559
571 s3c_pcm_stereo_in[pdev->id].channel = dmarx_res->start; 560 filter = NULL;
572 s3c_pcm_stereo_out[pdev->id].channel = dmatx_res->start; 561 if (pcm_pdata) {
562 s3c_pcm_stereo_in[pdev->id].slave = pcm_pdata->dma_capture;
563 s3c_pcm_stereo_out[pdev->id].slave = pcm_pdata->dma_playback;
564 filter = pcm_pdata->dma_filter;
565 }
573 566
574 pcm->dma_capture = &s3c_pcm_stereo_in[pdev->id]; 567 pcm->dma_capture = &s3c_pcm_stereo_in[pdev->id];
575 pcm->dma_playback = &s3c_pcm_stereo_out[pdev->id]; 568 pcm->dma_playback = &s3c_pcm_stereo_out[pdev->id];
@@ -583,7 +576,7 @@ static int s3c_pcm_dev_probe(struct platform_device *pdev)
583 goto err5; 576 goto err5;
584 } 577 }
585 578
586 ret = samsung_asoc_dma_platform_register(&pdev->dev); 579 ret = samsung_asoc_dma_platform_register(&pdev->dev, filter);
587 if (ret) { 580 if (ret) {
588 dev_err(&pdev->dev, "failed to get register DMA: %d\n", ret); 581 dev_err(&pdev->dev, "failed to get register DMA: %d\n", ret);
589 goto err5; 582 goto err5;
diff --git a/sound/soc/samsung/s3c2412-i2s.c b/sound/soc/samsung/s3c2412-i2s.c
index 2b766d212ce0..204029d12f5b 100644
--- a/sound/soc/samsung/s3c2412-i2s.c
+++ b/sound/soc/samsung/s3c2412-i2s.c
@@ -25,7 +25,6 @@
25#include <sound/soc.h> 25#include <sound/soc.h>
26#include <sound/pcm_params.h> 26#include <sound/pcm_params.h>
27 27
28#include <mach/dma.h>
29#include <mach/gpio-samsung.h> 28#include <mach/gpio-samsung.h>
30#include <plat/gpio-cfg.h> 29#include <plat/gpio-cfg.h>
31 30
@@ -33,14 +32,14 @@
33#include "regs-i2s-v2.h" 32#include "regs-i2s-v2.h"
34#include "s3c2412-i2s.h" 33#include "s3c2412-i2s.h"
35 34
35#include <linux/platform_data/asoc-s3c.h>
36
36static struct s3c_dma_params s3c2412_i2s_pcm_stereo_out = { 37static struct s3c_dma_params s3c2412_i2s_pcm_stereo_out = {
37 .channel = DMACH_I2S_OUT,
38 .ch_name = "tx", 38 .ch_name = "tx",
39 .dma_size = 4, 39 .dma_size = 4,
40}; 40};
41 41
42static struct s3c_dma_params s3c2412_i2s_pcm_stereo_in = { 42static struct s3c_dma_params s3c2412_i2s_pcm_stereo_in = {
43 .channel = DMACH_I2S_IN,
44 .ch_name = "rx", 43 .ch_name = "rx",
45 .dma_size = 4, 44 .dma_size = 4,
46}; 45};
@@ -152,6 +151,12 @@ static int s3c2412_iis_dev_probe(struct platform_device *pdev)
152{ 151{
153 int ret = 0; 152 int ret = 0;
154 struct resource *res; 153 struct resource *res;
154 struct s3c_audio_pdata *pdata = dev_get_platdata(&pdev->dev);
155
156 if (!pdata) {
157 dev_err(&pdev->dev, "missing platform data");
158 return -ENXIO;
159 }
155 160
156 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 161 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
157 s3c2412_i2s.regs = devm_ioremap_resource(&pdev->dev, res); 162 s3c2412_i2s.regs = devm_ioremap_resource(&pdev->dev, res);
@@ -159,7 +164,9 @@ static int s3c2412_iis_dev_probe(struct platform_device *pdev)
159 return PTR_ERR(s3c2412_i2s.regs); 164 return PTR_ERR(s3c2412_i2s.regs);
160 165
161 s3c2412_i2s_pcm_stereo_out.dma_addr = res->start + S3C2412_IISTXD; 166 s3c2412_i2s_pcm_stereo_out.dma_addr = res->start + S3C2412_IISTXD;
167 s3c2412_i2s_pcm_stereo_out.slave = pdata->dma_playback;
162 s3c2412_i2s_pcm_stereo_in.dma_addr = res->start + S3C2412_IISRXD; 168 s3c2412_i2s_pcm_stereo_in.dma_addr = res->start + S3C2412_IISRXD;
169 s3c2412_i2s_pcm_stereo_in.slave = pdata->dma_capture;
163 170
164 ret = s3c_i2sv2_register_component(&pdev->dev, -1, 171 ret = s3c_i2sv2_register_component(&pdev->dev, -1,
165 &s3c2412_i2s_component, 172 &s3c2412_i2s_component,
@@ -169,7 +176,8 @@ static int s3c2412_iis_dev_probe(struct platform_device *pdev)
169 return ret; 176 return ret;
170 } 177 }
171 178
172 ret = samsung_asoc_dma_platform_register(&pdev->dev); 179 ret = samsung_asoc_dma_platform_register(&pdev->dev,
180 pdata->dma_filter);
173 if (ret) 181 if (ret)
174 pr_err("failed to register the DMA: %d\n", ret); 182 pr_err("failed to register the DMA: %d\n", ret);
175 183
diff --git a/sound/soc/samsung/s3c24xx-i2s.c b/sound/soc/samsung/s3c24xx-i2s.c
index 5bf723689692..b3a475d73ba7 100644
--- a/sound/soc/samsung/s3c24xx-i2s.c
+++ b/sound/soc/samsung/s3c24xx-i2s.c
@@ -23,7 +23,6 @@
23#include <sound/soc.h> 23#include <sound/soc.h>
24#include <sound/pcm_params.h> 24#include <sound/pcm_params.h>
25 25
26#include <mach/dma.h>
27#include <mach/gpio-samsung.h> 26#include <mach/gpio-samsung.h>
28#include <plat/gpio-cfg.h> 27#include <plat/gpio-cfg.h>
29#include "regs-iis.h" 28#include "regs-iis.h"
@@ -31,14 +30,14 @@
31#include "dma.h" 30#include "dma.h"
32#include "s3c24xx-i2s.h" 31#include "s3c24xx-i2s.h"
33 32
33#include <linux/platform_data/asoc-s3c.h>
34
34static struct s3c_dma_params s3c24xx_i2s_pcm_stereo_out = { 35static struct s3c_dma_params s3c24xx_i2s_pcm_stereo_out = {
35 .channel = DMACH_I2S_OUT,
36 .ch_name = "tx", 36 .ch_name = "tx",
37 .dma_size = 2, 37 .dma_size = 2,
38}; 38};
39 39
40static struct s3c_dma_params s3c24xx_i2s_pcm_stereo_in = { 40static struct s3c_dma_params s3c24xx_i2s_pcm_stereo_in = {
41 .channel = DMACH_I2S_IN,
42 .ch_name = "rx", 41 .ch_name = "rx",
43 .dma_size = 2, 42 .dma_size = 2,
44}; 43};
@@ -454,6 +453,12 @@ static int s3c24xx_iis_dev_probe(struct platform_device *pdev)
454{ 453{
455 int ret = 0; 454 int ret = 0;
456 struct resource *res; 455 struct resource *res;
456 struct s3c_audio_pdata *pdata = dev_get_platdata(&pdev->dev);
457
458 if (!pdata) {
459 dev_err(&pdev->dev, "missing platform data");
460 return -ENXIO;
461 }
457 462
458 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 463 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
459 if (!res) { 464 if (!res) {
@@ -465,7 +470,9 @@ static int s3c24xx_iis_dev_probe(struct platform_device *pdev)
465 return PTR_ERR(s3c24xx_i2s.regs); 470 return PTR_ERR(s3c24xx_i2s.regs);
466 471
467 s3c24xx_i2s_pcm_stereo_out.dma_addr = res->start + S3C2410_IISFIFO; 472 s3c24xx_i2s_pcm_stereo_out.dma_addr = res->start + S3C2410_IISFIFO;
473 s3c24xx_i2s_pcm_stereo_out.slave = pdata->dma_playback;
468 s3c24xx_i2s_pcm_stereo_in.dma_addr = res->start + S3C2410_IISFIFO; 474 s3c24xx_i2s_pcm_stereo_in.dma_addr = res->start + S3C2410_IISFIFO;
475 s3c24xx_i2s_pcm_stereo_in.slave = pdata->dma_capture;
469 476
470 ret = devm_snd_soc_register_component(&pdev->dev, 477 ret = devm_snd_soc_register_component(&pdev->dev,
471 &s3c24xx_i2s_component, &s3c24xx_i2s_dai, 1); 478 &s3c24xx_i2s_component, &s3c24xx_i2s_dai, 1);
@@ -474,7 +481,8 @@ static int s3c24xx_iis_dev_probe(struct platform_device *pdev)
474 return ret; 481 return ret;
475 } 482 }
476 483
477 ret = samsung_asoc_dma_platform_register(&pdev->dev); 484 ret = samsung_asoc_dma_platform_register(&pdev->dev,
485 pdata->dma_filter);
478 if (ret) 486 if (ret)
479 pr_err("failed to register the dma: %d\n", ret); 487 pr_err("failed to register the dma: %d\n", ret);
480 488
diff --git a/sound/soc/samsung/snow.c b/sound/soc/samsung/snow.c
index 07ce2cfa4845..d8ac907bbb0d 100644
--- a/sound/soc/samsung/snow.c
+++ b/sound/soc/samsung/snow.c
@@ -35,10 +35,15 @@ static struct snd_soc_dai_link snow_dai[] = {
35 35
36static int snow_late_probe(struct snd_soc_card *card) 36static int snow_late_probe(struct snd_soc_card *card)
37{ 37{
38 struct snd_soc_dai *codec_dai = card->rtd[0].codec_dai; 38 struct snd_soc_pcm_runtime *rtd;
39 struct snd_soc_dai *cpu_dai = card->rtd[0].cpu_dai; 39 struct snd_soc_dai *codec_dai;
40 struct snd_soc_dai *cpu_dai;
40 int ret; 41 int ret;
41 42
43 rtd = snd_soc_get_pcm_runtime(card, card->dai_link[0].name);
44 codec_dai = rtd->codec_dai;
45 cpu_dai = rtd->cpu_dai;
46
42 /* Set the MCLK rate for the codec */ 47 /* Set the MCLK rate for the codec */
43 ret = snd_soc_dai_set_sysclk(codec_dai, 0, 48 ret = snd_soc_dai_set_sysclk(codec_dai, 0,
44 FIN_PLL_RATE, SND_SOC_CLOCK_IN); 49 FIN_PLL_RATE, SND_SOC_CLOCK_IN);
diff --git a/sound/soc/samsung/spdif.c b/sound/soc/samsung/spdif.c
index 36dbc0e96004..4687f521197c 100644
--- a/sound/soc/samsung/spdif.c
+++ b/sound/soc/samsung/spdif.c
@@ -359,20 +359,15 @@ static const struct snd_soc_component_driver samsung_spdif_component = {
359static int spdif_probe(struct platform_device *pdev) 359static int spdif_probe(struct platform_device *pdev)
360{ 360{
361 struct s3c_audio_pdata *spdif_pdata; 361 struct s3c_audio_pdata *spdif_pdata;
362 struct resource *mem_res, *dma_res; 362 struct resource *mem_res;
363 struct samsung_spdif_info *spdif; 363 struct samsung_spdif_info *spdif;
364 dma_filter_fn filter;
364 int ret; 365 int ret;
365 366
366 spdif_pdata = pdev->dev.platform_data; 367 spdif_pdata = pdev->dev.platform_data;
367 368
368 dev_dbg(&pdev->dev, "Entered %s\n", __func__); 369 dev_dbg(&pdev->dev, "Entered %s\n", __func__);
369 370
370 dma_res = platform_get_resource(pdev, IORESOURCE_DMA, 0);
371 if (!dma_res) {
372 dev_err(&pdev->dev, "Unable to get dma resource.\n");
373 return -ENXIO;
374 }
375
376 mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 371 mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
377 if (!mem_res) { 372 if (!mem_res) {
378 dev_err(&pdev->dev, "Unable to get register resource.\n"); 373 dev_err(&pdev->dev, "Unable to get register resource.\n");
@@ -432,11 +427,15 @@ static int spdif_probe(struct platform_device *pdev)
432 427
433 spdif_stereo_out.dma_size = 2; 428 spdif_stereo_out.dma_size = 2;
434 spdif_stereo_out.dma_addr = mem_res->start + DATA_OUTBUF; 429 spdif_stereo_out.dma_addr = mem_res->start + DATA_OUTBUF;
435 spdif_stereo_out.channel = dma_res->start; 430 filter = NULL;
431 if (spdif_pdata) {
432 spdif_stereo_out.slave = spdif_pdata->dma_playback;
433 filter = spdif_pdata->dma_filter;
434 }
436 435
437 spdif->dma_playback = &spdif_stereo_out; 436 spdif->dma_playback = &spdif_stereo_out;
438 437
439 ret = samsung_asoc_dma_platform_register(&pdev->dev); 438 ret = samsung_asoc_dma_platform_register(&pdev->dev, filter);
440 if (ret) { 439 if (ret) {
441 dev_err(&pdev->dev, "failed to register DMA: %d\n", ret); 440 dev_err(&pdev->dev, "failed to register DMA: %d\n", ret);
442 goto err4; 441 goto err4;
diff --git a/sound/soc/samsung/speyside.c b/sound/soc/samsung/speyside.c
index d1ae21c5e253..083ef5e21b17 100644
--- a/sound/soc/samsung/speyside.c
+++ b/sound/soc/samsung/speyside.c
@@ -25,9 +25,13 @@ static int speyside_set_bias_level(struct snd_soc_card *card,
25 struct snd_soc_dapm_context *dapm, 25 struct snd_soc_dapm_context *dapm,
26 enum snd_soc_bias_level level) 26 enum snd_soc_bias_level level)
27{ 27{
28 struct snd_soc_dai *codec_dai = card->rtd[1].codec_dai; 28 struct snd_soc_pcm_runtime *rtd;
29 struct snd_soc_dai *codec_dai;
29 int ret; 30 int ret;
30 31
32 rtd = snd_soc_get_pcm_runtime(card, card->dai_link[1].name);
33 codec_dai = rtd->codec_dai;
34
31 if (dapm->dev != codec_dai->dev) 35 if (dapm->dev != codec_dai->dev)
32 return 0; 36 return 0;
33 37
@@ -57,9 +61,13 @@ static int speyside_set_bias_level_post(struct snd_soc_card *card,
57 struct snd_soc_dapm_context *dapm, 61 struct snd_soc_dapm_context *dapm,
58 enum snd_soc_bias_level level) 62 enum snd_soc_bias_level level)
59{ 63{
60 struct snd_soc_dai *codec_dai = card->rtd[1].codec_dai; 64 struct snd_soc_pcm_runtime *rtd;
65 struct snd_soc_dai *codec_dai;
61 int ret; 66 int ret;
62 67
68 rtd = snd_soc_get_pcm_runtime(card, card->dai_link[1].name);
69 codec_dai = rtd->codec_dai;
70
63 if (dapm->dev != codec_dai->dev) 71 if (dapm->dev != codec_dai->dev)
64 return 0; 72 return 0;
65 73
diff --git a/sound/soc/samsung/tobermory.c b/sound/soc/samsung/tobermory.c
index 85ccfb7188cb..3310eda7cf53 100644
--- a/sound/soc/samsung/tobermory.c
+++ b/sound/soc/samsung/tobermory.c
@@ -23,9 +23,13 @@ static int tobermory_set_bias_level(struct snd_soc_card *card,
23 struct snd_soc_dapm_context *dapm, 23 struct snd_soc_dapm_context *dapm,
24 enum snd_soc_bias_level level) 24 enum snd_soc_bias_level level)
25{ 25{
26 struct snd_soc_dai *codec_dai = card->rtd[0].codec_dai; 26 struct snd_soc_pcm_runtime *rtd;
27 struct snd_soc_dai *codec_dai;
27 int ret; 28 int ret;
28 29
30 rtd = snd_soc_get_pcm_runtime(card, card->dai_link[0].name);
31 codec_dai = rtd->codec_dai;
32
29 if (dapm->dev != codec_dai->dev) 33 if (dapm->dev != codec_dai->dev)
30 return 0; 34 return 0;
31 35
@@ -62,9 +66,13 @@ static int tobermory_set_bias_level_post(struct snd_soc_card *card,
62 struct snd_soc_dapm_context *dapm, 66 struct snd_soc_dapm_context *dapm,
63 enum snd_soc_bias_level level) 67 enum snd_soc_bias_level level)
64{ 68{
65 struct snd_soc_dai *codec_dai = card->rtd[0].codec_dai; 69 struct snd_soc_pcm_runtime *rtd;
70 struct snd_soc_dai *codec_dai;
66 int ret; 71 int ret;
67 72
73 rtd = snd_soc_get_pcm_runtime(card, card->dai_link[0].name);
74 codec_dai = rtd->codec_dai;
75
68 if (dapm->dev != codec_dai->dev) 76 if (dapm->dev != codec_dai->dev)
69 return 0; 77 return 0;
70 78
@@ -170,10 +178,15 @@ static struct snd_soc_jack_pin tobermory_headset_pins[] = {
170 178
171static int tobermory_late_probe(struct snd_soc_card *card) 179static int tobermory_late_probe(struct snd_soc_card *card)
172{ 180{
173 struct snd_soc_codec *codec = card->rtd[0].codec; 181 struct snd_soc_pcm_runtime *rtd;
174 struct snd_soc_dai *codec_dai = card->rtd[0].codec_dai; 182 struct snd_soc_codec *codec;
183 struct snd_soc_dai *codec_dai;
175 int ret; 184 int ret;
176 185
186 rtd = snd_soc_get_pcm_runtime(card, card->dai_link[0].name);
187 codec = rtd->codec;
188 codec_dai = rtd->codec_dai;
189
177 ret = snd_soc_dai_set_sysclk(codec_dai, WM8962_SYSCLK_MCLK, 190 ret = snd_soc_dai_set_sysclk(codec_dai, WM8962_SYSCLK_MCLK,
178 32768, SND_SOC_CLOCK_IN); 191 32768, SND_SOC_CLOCK_IN);
179 if (ret < 0) 192 if (ret < 0)
diff --git a/sound/soc/sh/Kconfig b/sound/soc/sh/Kconfig
index 206d1edab07c..c9902a6d6fa0 100644
--- a/sound/soc/sh/Kconfig
+++ b/sound/soc/sh/Kconfig
@@ -36,7 +36,6 @@ config SND_SOC_SH4_SIU
36 36
37config SND_SOC_RCAR 37config SND_SOC_RCAR
38 tristate "R-Car series SRU/SCU/SSIU/SSI support" 38 tristate "R-Car series SRU/SCU/SSIU/SSI support"
39 depends on DMA_OF
40 depends on COMMON_CLK 39 depends on COMMON_CLK
41 select SND_SIMPLE_CARD 40 select SND_SIMPLE_CARD
42 select REGMAP_MMIO 41 select REGMAP_MMIO
diff --git a/sound/soc/sh/fsi.c b/sound/soc/sh/fsi.c
index 0215c78cbddf..ead520182e26 100644
--- a/sound/soc/sh/fsi.c
+++ b/sound/soc/sh/fsi.c
@@ -1362,15 +1362,18 @@ static int fsi_dma_push_start_stop(struct fsi_priv *fsi, struct fsi_stream *io,
1362 1362
1363static int fsi_dma_probe(struct fsi_priv *fsi, struct fsi_stream *io, struct device *dev) 1363static int fsi_dma_probe(struct fsi_priv *fsi, struct fsi_stream *io, struct device *dev)
1364{ 1364{
1365 dma_cap_mask_t mask;
1366 int is_play = fsi_stream_is_play(fsi, io); 1365 int is_play = fsi_stream_is_play(fsi, io);
1367 1366
1367#ifdef CONFIG_SUPERH
1368 dma_cap_mask_t mask;
1368 dma_cap_zero(mask); 1369 dma_cap_zero(mask);
1369 dma_cap_set(DMA_SLAVE, mask); 1370 dma_cap_set(DMA_SLAVE, mask);
1370 1371
1371 io->chan = dma_request_slave_channel_compat(mask, 1372 io->chan = dma_request_channel(mask, shdma_chan_filter,
1372 shdma_chan_filter, (void *)io->dma_id, 1373 (void *)io->dma_id);
1373 dev, is_play ? "tx" : "rx"); 1374#else
1375 io->chan = dma_request_slave_channel(dev, is_play ? "tx" : "rx");
1376#endif
1374 if (io->chan) { 1377 if (io->chan) {
1375 struct dma_slave_config cfg = {}; 1378 struct dma_slave_config cfg = {};
1376 int ret; 1379 int ret;
diff --git a/sound/soc/sh/rcar/Makefile b/sound/soc/sh/rcar/Makefile
index 8b258501aa35..a89ddf758695 100644
--- a/sound/soc/sh/rcar/Makefile
+++ b/sound/soc/sh/rcar/Makefile
@@ -1,4 +1,4 @@
1snd-soc-rcar-objs := core.o gen.o dma.o adg.o ssi.o src.o ctu.o mix.o dvc.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 3
4snd-soc-rsrc-card-objs := rsrc-card.o 4snd-soc-rsrc-card-objs := rsrc-card.o
diff --git a/sound/soc/sh/rcar/adg.c b/sound/soc/sh/rcar/adg.c
index 2a5b3a293cd2..6d3ef366d536 100644
--- a/sound/soc/sh/rcar/adg.c
+++ b/sound/soc/sh/rcar/adg.c
@@ -68,8 +68,8 @@ static u32 rsnd_adg_calculate_rbgx(unsigned long div)
68 68
69static u32 rsnd_adg_ssi_ws_timing_gen2(struct rsnd_dai_stream *io) 69static u32 rsnd_adg_ssi_ws_timing_gen2(struct rsnd_dai_stream *io)
70{ 70{
71 struct rsnd_mod *mod = rsnd_io_to_mod_ssi(io); 71 struct rsnd_mod *ssi_mod = rsnd_io_to_mod_ssi(io);
72 int id = rsnd_mod_id(mod); 72 int id = rsnd_mod_id(ssi_mod);
73 int ws = id; 73 int ws = id;
74 74
75 if (rsnd_ssi_is_pin_sharing(io)) { 75 if (rsnd_ssi_is_pin_sharing(io)) {
@@ -90,13 +90,13 @@ static u32 rsnd_adg_ssi_ws_timing_gen2(struct rsnd_dai_stream *io)
90 return (0x6 + ws) << 8; 90 return (0x6 + ws) << 8;
91} 91}
92 92
93int rsnd_adg_set_cmd_timsel_gen2(struct rsnd_mod *mod, 93int rsnd_adg_set_cmd_timsel_gen2(struct rsnd_mod *cmd_mod,
94 struct rsnd_dai_stream *io) 94 struct rsnd_dai_stream *io)
95{ 95{
96 struct rsnd_priv *priv = rsnd_mod_to_priv(mod); 96 struct rsnd_priv *priv = rsnd_mod_to_priv(cmd_mod);
97 struct rsnd_adg *adg = rsnd_priv_to_adg(priv); 97 struct rsnd_adg *adg = rsnd_priv_to_adg(priv);
98 struct rsnd_mod *adg_mod = rsnd_mod_get(adg); 98 struct rsnd_mod *adg_mod = rsnd_mod_get(adg);
99 int id = rsnd_mod_id(mod); 99 int id = rsnd_mod_id(cmd_mod);
100 int shift = (id % 2) ? 16 : 0; 100 int shift = (id % 2) ? 16 : 0;
101 u32 mask, val; 101 u32 mask, val;
102 102
@@ -242,68 +242,6 @@ int rsnd_adg_set_convert_timing_gen2(struct rsnd_mod *src_mod,
242 return rsnd_adg_set_src_timsel_gen2(src_mod, io, val); 242 return rsnd_adg_set_src_timsel_gen2(src_mod, io, val);
243} 243}
244 244
245int rsnd_adg_set_convert_clk_gen1(struct rsnd_priv *priv,
246 struct rsnd_mod *mod,
247 unsigned int src_rate,
248 unsigned int dst_rate)
249{
250 struct rsnd_adg *adg = rsnd_priv_to_adg(priv);
251 struct rsnd_mod *adg_mod = rsnd_mod_get(adg);
252 struct device *dev = rsnd_priv_to_dev(priv);
253 int idx, sel, div, shift;
254 u32 mask, val;
255 int id = rsnd_mod_id(mod);
256 unsigned int sel_rate [] = {
257 clk_get_rate(adg->clk[CLKA]), /* 000: CLKA */
258 clk_get_rate(adg->clk[CLKB]), /* 001: CLKB */
259 clk_get_rate(adg->clk[CLKC]), /* 010: CLKC */
260 0, /* 011: MLBCLK (not used) */
261 adg->rbga_rate_for_441khz, /* 100: RBGA */
262 adg->rbgb_rate_for_48khz, /* 101: RBGB */
263 };
264
265 /* find div (= 1/128, 1/256, 1/512, 1/1024, 1/2048 */
266 for (sel = 0; sel < ARRAY_SIZE(sel_rate); sel++) {
267 for (div = 128, idx = 0;
268 div <= 2048;
269 div *= 2, idx++) {
270 if (src_rate == sel_rate[sel] / div) {
271 val = (idx << 4) | sel;
272 goto find_rate;
273 }
274 }
275 }
276 dev_err(dev, "can't find convert src clk\n");
277 return -EINVAL;
278
279find_rate:
280 shift = (id % 4) * 8;
281 mask = 0xFF << shift;
282 val = val << shift;
283
284 dev_dbg(dev, "adg convert src clk = %02x\n", val);
285
286 switch (id / 4) {
287 case 0:
288 rsnd_mod_bset(adg_mod, AUDIO_CLK_SEL3, mask, val);
289 break;
290 case 1:
291 rsnd_mod_bset(adg_mod, AUDIO_CLK_SEL4, mask, val);
292 break;
293 case 2:
294 rsnd_mod_bset(adg_mod, AUDIO_CLK_SEL5, mask, val);
295 break;
296 }
297
298 /*
299 * Gen1 doesn't need dst_rate settings,
300 * since it uses SSI WS pin.
301 * see also rsnd_src_set_route_if_gen1()
302 */
303
304 return 0;
305}
306
307static void rsnd_adg_set_ssi_clk(struct rsnd_mod *ssi_mod, u32 val) 245static void rsnd_adg_set_ssi_clk(struct rsnd_mod *ssi_mod, u32 val)
308{ 246{
309 struct rsnd_priv *priv = rsnd_mod_to_priv(ssi_mod); 247 struct rsnd_priv *priv = rsnd_mod_to_priv(ssi_mod);
@@ -337,20 +275,16 @@ static void rsnd_adg_set_ssi_clk(struct rsnd_mod *ssi_mod, u32 val)
337 } 275 }
338} 276}
339 277
340int rsnd_adg_ssi_clk_stop(struct rsnd_mod *mod) 278int rsnd_adg_ssi_clk_stop(struct rsnd_mod *ssi_mod)
341{ 279{
342 /* 280 rsnd_adg_set_ssi_clk(ssi_mod, 0);
343 * "mod" = "ssi" here.
344 * we can get "ssi id" from mod
345 */
346 rsnd_adg_set_ssi_clk(mod, 0);
347 281
348 return 0; 282 return 0;
349} 283}
350 284
351int rsnd_adg_ssi_clk_try_start(struct rsnd_mod *mod, unsigned int rate) 285int rsnd_adg_ssi_clk_try_start(struct rsnd_mod *ssi_mod, unsigned int rate)
352{ 286{
353 struct rsnd_priv *priv = rsnd_mod_to_priv(mod); 287 struct rsnd_priv *priv = rsnd_mod_to_priv(ssi_mod);
354 struct rsnd_adg *adg = rsnd_priv_to_adg(priv); 288 struct rsnd_adg *adg = rsnd_priv_to_adg(priv);
355 struct device *dev = rsnd_priv_to_dev(priv); 289 struct device *dev = rsnd_priv_to_dev(priv);
356 struct clk *clk; 290 struct clk *clk;
@@ -394,14 +328,10 @@ int rsnd_adg_ssi_clk_try_start(struct rsnd_mod *mod, unsigned int rate)
394 328
395found_clock: 329found_clock:
396 330
397 /* 331 rsnd_adg_set_ssi_clk(ssi_mod, data);
398 * This "mod" = "ssi" here.
399 * we can get "ssi id" from mod
400 */
401 rsnd_adg_set_ssi_clk(mod, data);
402 332
403 dev_dbg(dev, "ADG: %s[%d] selects 0x%x for %d\n", 333 dev_dbg(dev, "ADG: %s[%d] selects 0x%x for %d\n",
404 rsnd_mod_name(mod), rsnd_mod_id(mod), 334 rsnd_mod_name(ssi_mod), rsnd_mod_id(ssi_mod),
405 data, rate); 335 data, rate);
406 336
407 return 0; 337 return 0;
@@ -418,15 +348,20 @@ static void rsnd_adg_get_clkin(struct rsnd_priv *priv,
418 [CLKC] = "clk_c", 348 [CLKC] = "clk_c",
419 [CLKI] = "clk_i", 349 [CLKI] = "clk_i",
420 }; 350 };
421 int i; 351 int i, ret;
422 352
423 for (i = 0; i < CLKMAX; i++) { 353 for (i = 0; i < CLKMAX; i++) {
424 clk = devm_clk_get(dev, clk_name[i]); 354 clk = devm_clk_get(dev, clk_name[i]);
425 adg->clk[i] = IS_ERR(clk) ? NULL : clk; 355 adg->clk[i] = IS_ERR(clk) ? NULL : clk;
426 } 356 }
427 357
428 for_each_rsnd_clk(clk, adg, i) 358 for_each_rsnd_clk(clk, adg, i) {
359 ret = clk_prepare_enable(clk);
360 if (ret < 0)
361 dev_warn(dev, "can't use clk %d\n", i);
362
429 dev_dbg(dev, "clk %d : %p : %ld\n", i, clk, clk_get_rate(clk)); 363 dev_dbg(dev, "clk %d : %p : %ld\n", i, clk, clk_get_rate(clk));
364 }
430} 365}
431 366
432static void rsnd_adg_get_clkout(struct rsnd_priv *priv, 367static void rsnd_adg_get_clkout(struct rsnd_priv *priv,
@@ -437,7 +372,7 @@ static void rsnd_adg_get_clkout(struct rsnd_priv *priv,
437 struct device *dev = rsnd_priv_to_dev(priv); 372 struct device *dev = rsnd_priv_to_dev(priv);
438 struct device_node *np = dev->of_node; 373 struct device_node *np = dev->of_node;
439 u32 ckr, rbgx, rbga, rbgb; 374 u32 ckr, rbgx, rbga, rbgb;
440 u32 rate, req_rate, div; 375 u32 rate, req_rate = 0, div;
441 uint32_t count = 0; 376 uint32_t count = 0;
442 unsigned long req_48kHz_rate, req_441kHz_rate; 377 unsigned long req_48kHz_rate, req_441kHz_rate;
443 int i; 378 int i;
@@ -572,9 +507,7 @@ static void rsnd_adg_get_clkout(struct rsnd_priv *priv,
572 ckr, rbga, rbgb); 507 ckr, rbga, rbgb);
573} 508}
574 509
575int rsnd_adg_probe(struct platform_device *pdev, 510int rsnd_adg_probe(struct rsnd_priv *priv)
576 const struct rsnd_of_data *of_data,
577 struct rsnd_priv *priv)
578{ 511{
579 struct rsnd_adg *adg; 512 struct rsnd_adg *adg;
580 struct device *dev = rsnd_priv_to_dev(priv); 513 struct device *dev = rsnd_priv_to_dev(priv);
@@ -600,3 +533,14 @@ int rsnd_adg_probe(struct platform_device *pdev,
600 533
601 return 0; 534 return 0;
602} 535}
536
537void rsnd_adg_remove(struct rsnd_priv *priv)
538{
539 struct rsnd_adg *adg = rsnd_priv_to_adg(priv);
540 struct clk *clk;
541 int i;
542
543 for_each_rsnd_clk(clk, adg, i) {
544 clk_disable_unprepare(clk);
545 }
546}
diff --git a/sound/soc/sh/rcar/cmd.c b/sound/soc/sh/rcar/cmd.c
new file mode 100644
index 000000000000..cd1f064e63c4
--- /dev/null
+++ b/sound/soc/sh/rcar/cmd.c
@@ -0,0 +1,171 @@
1/*
2 * Renesas R-Car CMD support
3 *
4 * Copyright (C) 2015 Renesas Solutions Corp.
5 * Kuninori Morimoto <kuninori.morimoto.gx@renesas.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 "rsnd.h"
12
13struct rsnd_cmd {
14 struct rsnd_mod mod;
15};
16
17#define CMD_NAME "cmd"
18
19#define rsnd_cmd_nr(priv) ((priv)->cmd_nr)
20#define for_each_rsnd_cmd(pos, priv, i) \
21 for ((i) = 0; \
22 ((i) < rsnd_cmd_nr(priv)) && \
23 ((pos) = (struct rsnd_cmd *)(priv)->cmd + i); \
24 i++)
25
26static int rsnd_cmd_init(struct rsnd_mod *mod,
27 struct rsnd_dai_stream *io,
28 struct rsnd_priv *priv)
29{
30 struct rsnd_mod *dvc = rsnd_io_to_mod_dvc(io);
31 struct rsnd_mod *mix = rsnd_io_to_mod_mix(io);
32 struct rsnd_mod *src = rsnd_io_to_mod_src(io);
33 struct device *dev = rsnd_priv_to_dev(priv);
34 u32 data;
35
36 if (!mix && !dvc)
37 return 0;
38
39 if (mix) {
40 struct rsnd_dai *rdai;
41 int i;
42 u32 path[] = {
43 [0] = 0,
44 [1] = 1 << 0,
45 [2] = 0,
46 [3] = 0,
47 [4] = 0,
48 [5] = 1 << 8
49 };
50
51 /*
52 * it is assuming that integrater is well understanding about
53 * data path. Here doesn't check impossible connection,
54 * like src2 + src5
55 */
56 data = 0;
57 for_each_rsnd_dai(rdai, priv, i) {
58 io = &rdai->playback;
59 if (mix == rsnd_io_to_mod_mix(io))
60 data |= path[rsnd_mod_id(src)];
61
62 io = &rdai->capture;
63 if (mix == rsnd_io_to_mod_mix(io))
64 data |= path[rsnd_mod_id(src)];
65 }
66
67 } else {
68 u32 path[] = {
69 [0] = 0x30000,
70 [1] = 0x30001,
71 [2] = 0x40000,
72 [3] = 0x10000,
73 [4] = 0x20000,
74 [5] = 0x40100
75 };
76
77 data = path[rsnd_mod_id(src)];
78 }
79
80 dev_dbg(dev, "ctu/mix path = 0x%08x", data);
81
82 rsnd_mod_write(mod, CMD_ROUTE_SLCT, data);
83 rsnd_mod_write(mod, CMD_BUSIF_DALIGN, rsnd_get_dalign(mod, io));
84
85 rsnd_adg_set_cmd_timsel_gen2(mod, io);
86
87 return 0;
88}
89
90static int rsnd_cmd_start(struct rsnd_mod *mod,
91 struct rsnd_dai_stream *io,
92 struct rsnd_priv *priv)
93{
94 rsnd_mod_write(mod, CMD_CTRL, 0x10);
95
96 return 0;
97}
98
99static int rsnd_cmd_stop(struct rsnd_mod *mod,
100 struct rsnd_dai_stream *io,
101 struct rsnd_priv *priv)
102{
103 rsnd_mod_write(mod, CMD_CTRL, 0);
104
105 return 0;
106}
107
108static struct rsnd_mod_ops rsnd_cmd_ops = {
109 .name = CMD_NAME,
110 .init = rsnd_cmd_init,
111 .start = rsnd_cmd_start,
112 .stop = rsnd_cmd_stop,
113};
114
115int rsnd_cmd_attach(struct rsnd_dai_stream *io, int id)
116{
117 struct rsnd_priv *priv = rsnd_io_to_priv(io);
118 struct rsnd_mod *mod = rsnd_cmd_mod_get(priv, id);
119
120 return rsnd_dai_connect(mod, io, mod->type);
121}
122
123struct rsnd_mod *rsnd_cmd_mod_get(struct rsnd_priv *priv, int id)
124{
125 if (WARN_ON(id < 0 || id >= rsnd_cmd_nr(priv)))
126 id = 0;
127
128 return rsnd_mod_get((struct rsnd_cmd *)(priv->cmd) + id);
129}
130
131int rsnd_cmd_probe(struct rsnd_priv *priv)
132{
133 struct device *dev = rsnd_priv_to_dev(priv);
134 struct rsnd_cmd *cmd;
135 int i, nr, ret;
136
137 /* This driver doesn't support Gen1 at this point */
138 if (rsnd_is_gen1(priv))
139 return 0;
140
141 /* same number as DVC */
142 nr = priv->dvc_nr;
143 if (!nr)
144 return 0;
145
146 cmd = devm_kzalloc(dev, sizeof(*cmd) * nr, GFP_KERNEL);
147 if (!cmd)
148 return -ENOMEM;
149
150 priv->cmd_nr = nr;
151 priv->cmd = cmd;
152
153 for_each_rsnd_cmd(cmd, priv, i) {
154 ret = rsnd_mod_init(priv, rsnd_mod_get(cmd),
155 &rsnd_cmd_ops, NULL, RSND_MOD_CMD, i);
156 if (ret)
157 return ret;
158 }
159
160 return 0;
161}
162
163void rsnd_cmd_remove(struct rsnd_priv *priv)
164{
165 struct rsnd_cmd *cmd;
166 int i;
167
168 for_each_rsnd_cmd(cmd, priv, i) {
169 rsnd_mod_quit(rsnd_mod_get(cmd));
170 }
171}
diff --git a/sound/soc/sh/rcar/core.c b/sound/soc/sh/rcar/core.c
index deed48ef28b8..02b4b085b8d7 100644
--- a/sound/soc/sh/rcar/core.c
+++ b/sound/soc/sh/rcar/core.c
@@ -99,34 +99,17 @@
99#define RSND_RATES SNDRV_PCM_RATE_8000_96000 99#define RSND_RATES SNDRV_PCM_RATE_8000_96000
100#define RSND_FMTS (SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S16_LE) 100#define RSND_FMTS (SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S16_LE)
101 101
102static const struct rsnd_of_data rsnd_of_data_gen1 = {
103 .flags = RSND_GEN1,
104};
105
106static const struct rsnd_of_data rsnd_of_data_gen2 = {
107 .flags = RSND_GEN2,
108};
109
110static const struct of_device_id rsnd_of_match[] = { 102static const struct of_device_id rsnd_of_match[] = {
111 { .compatible = "renesas,rcar_sound-gen1", .data = &rsnd_of_data_gen1 }, 103 { .compatible = "renesas,rcar_sound-gen1", .data = (void *)RSND_GEN1 },
112 { .compatible = "renesas,rcar_sound-gen2", .data = &rsnd_of_data_gen2 }, 104 { .compatible = "renesas,rcar_sound-gen2", .data = (void *)RSND_GEN2 },
113 { .compatible = "renesas,rcar_sound-gen3", .data = &rsnd_of_data_gen2 }, /* gen2 compatible */ 105 { .compatible = "renesas,rcar_sound-gen3", .data = (void *)RSND_GEN2 }, /* gen2 compatible */
114 {}, 106 {},
115}; 107};
116MODULE_DEVICE_TABLE(of, rsnd_of_match); 108MODULE_DEVICE_TABLE(of, rsnd_of_match);
117 109
118/* 110/*
119 * rsnd_platform functions 111 * rsnd_mod functions
120 */ 112 */
121#define rsnd_platform_call(priv, dai, func, param...) \
122 (!(priv->info->func) ? 0 : \
123 priv->info->func(param))
124
125#define rsnd_is_enable_path(io, name) \
126 ((io)->info ? (io)->info->name : NULL)
127#define rsnd_info_id(priv, io, name) \
128 ((io)->info->name - priv->info->name##_info)
129
130void rsnd_mod_make_sure(struct rsnd_mod *mod, enum rsnd_mod_type type) 113void rsnd_mod_make_sure(struct rsnd_mod *mod, enum rsnd_mod_type type)
131{ 114{
132 if (mod->type != type) { 115 if (mod->type != type) {
@@ -138,9 +121,6 @@ void rsnd_mod_make_sure(struct rsnd_mod *mod, enum rsnd_mod_type type)
138 } 121 }
139} 122}
140 123
141/*
142 * rsnd_mod functions
143 */
144char *rsnd_mod_name(struct rsnd_mod *mod) 124char *rsnd_mod_name(struct rsnd_mod *mod)
145{ 125{
146 if (!mod || !mod->ops) 126 if (!mod || !mod->ops)
@@ -192,19 +172,16 @@ void rsnd_mod_interrupt(struct rsnd_mod *mod,
192 struct rsnd_priv *priv = rsnd_mod_to_priv(mod); 172 struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
193 struct rsnd_dai_stream *io; 173 struct rsnd_dai_stream *io;
194 struct rsnd_dai *rdai; 174 struct rsnd_dai *rdai;
195 int i, j; 175 int i;
196
197 for_each_rsnd_dai(rdai, priv, j) {
198 176
199 for (i = 0; i < RSND_MOD_MAX; i++) { 177 for_each_rsnd_dai(rdai, priv, i) {
200 io = &rdai->playback; 178 io = &rdai->playback;
201 if (mod == io->mod[i]) 179 if (mod == io->mod[mod->type])
202 callback(mod, io); 180 callback(mod, io);
203 181
204 io = &rdai->capture; 182 io = &rdai->capture;
205 if (mod == io->mod[i]) 183 if (mod == io->mod[mod->type])
206 callback(mod, io); 184 callback(mod, io);
207 }
208 } 185 }
209} 186}
210 187
@@ -214,6 +191,43 @@ int rsnd_io_is_working(struct rsnd_dai_stream *io)
214 return !!io->substream; 191 return !!io->substream;
215} 192}
216 193
194void rsnd_set_slot(struct rsnd_dai *rdai,
195 int slots, int num)
196{
197 rdai->slots = slots;
198 rdai->slots_num = num;
199}
200
201int rsnd_get_slot(struct rsnd_dai_stream *io)
202{
203 struct rsnd_dai *rdai = rsnd_io_to_rdai(io);
204
205 return rdai->slots;
206}
207
208int rsnd_get_slot_num(struct rsnd_dai_stream *io)
209{
210 struct rsnd_dai *rdai = rsnd_io_to_rdai(io);
211
212 return rdai->slots_num;
213}
214
215int rsnd_get_slot_width(struct rsnd_dai_stream *io)
216{
217 struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io);
218 int chan = runtime->channels;
219
220 /* Multi channel Mode */
221 if (rsnd_ssi_multi_slaves(io))
222 chan /= rsnd_get_slot_num(io);
223
224 /* TDM Extend Mode needs 8ch */
225 if (chan == 6)
226 chan = 8;
227
228 return chan;
229}
230
217/* 231/*
218 * ADINR function 232 * ADINR function
219 */ 233 */
@@ -222,21 +236,17 @@ u32 rsnd_get_adinr_bit(struct rsnd_mod *mod, struct rsnd_dai_stream *io)
222 struct rsnd_priv *priv = rsnd_mod_to_priv(mod); 236 struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
223 struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io); 237 struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io);
224 struct device *dev = rsnd_priv_to_dev(priv); 238 struct device *dev = rsnd_priv_to_dev(priv);
225 u32 adinr = runtime->channels;
226 239
227 switch (runtime->sample_bits) { 240 switch (runtime->sample_bits) {
228 case 16: 241 case 16:
229 adinr |= (8 << 16); 242 return 8 << 16;
230 break;
231 case 32: 243 case 32:
232 adinr |= (0 << 16); 244 return 0 << 16;
233 break;
234 default:
235 dev_warn(dev, "not supported sample bits\n");
236 return 0;
237 } 245 }
238 246
239 return adinr; 247 dev_warn(dev, "not supported sample bits\n");
248
249 return 0;
240} 250}
241 251
242u32 rsnd_get_adinr_chan(struct rsnd_mod *mod, struct rsnd_dai_stream *io) 252u32 rsnd_get_adinr_chan(struct rsnd_mod *mod, struct rsnd_dai_stream *io)
@@ -267,13 +277,22 @@ u32 rsnd_get_adinr_chan(struct rsnd_mod *mod, struct rsnd_dai_stream *io)
267 */ 277 */
268u32 rsnd_get_dalign(struct rsnd_mod *mod, struct rsnd_dai_stream *io) 278u32 rsnd_get_dalign(struct rsnd_mod *mod, struct rsnd_dai_stream *io)
269{ 279{
270 struct rsnd_mod *src = rsnd_io_to_mod_src(io);
271 struct rsnd_mod *ssi = rsnd_io_to_mod_ssi(io); 280 struct rsnd_mod *ssi = rsnd_io_to_mod_ssi(io);
272 struct rsnd_mod *target = src ? src : ssi; 281 struct rsnd_mod *target;
273 struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io); 282 struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io);
274 u32 val = 0x76543210; 283 u32 val = 0x76543210;
275 u32 mask = ~0; 284 u32 mask = ~0;
276 285
286 if (rsnd_io_is_play(io)) {
287 struct rsnd_mod *src = rsnd_io_to_mod_src(io);
288
289 target = src ? src : ssi;
290 } else {
291 struct rsnd_mod *cmd = rsnd_io_to_mod_cmd(io);
292
293 target = cmd ? cmd : ssi;
294 }
295
277 mask <<= runtime->channels * 4; 296 mask <<= runtime->channels * 4;
278 val = val & mask; 297 val = val & mask;
279 298
@@ -300,20 +319,22 @@ u32 rsnd_get_dalign(struct rsnd_mod *mod, struct rsnd_dai_stream *io)
300/* 319/*
301 * rsnd_dai functions 320 * rsnd_dai functions
302 */ 321 */
303#define rsnd_mod_call(mod, io, func, param...) \ 322#define rsnd_mod_call(idx, io, func, param...) \
304({ \ 323({ \
305 struct rsnd_priv *priv = rsnd_mod_to_priv(mod); \ 324 struct rsnd_priv *priv = rsnd_mod_to_priv(mod); \
325 struct rsnd_mod *mod = (io)->mod[idx]; \
306 struct device *dev = rsnd_priv_to_dev(priv); \ 326 struct device *dev = rsnd_priv_to_dev(priv); \
327 u32 *status = (io)->mod_status + idx; \
307 u32 mask = 0xF << __rsnd_mod_shift_##func; \ 328 u32 mask = 0xF << __rsnd_mod_shift_##func; \
308 u8 val = (mod->status >> __rsnd_mod_shift_##func) & 0xF; \ 329 u8 val = (*status >> __rsnd_mod_shift_##func) & 0xF; \
309 u8 add = ((val + __rsnd_mod_add_##func) & 0xF); \ 330 u8 add = ((val + __rsnd_mod_add_##func) & 0xF); \
310 int ret = 0; \ 331 int ret = 0; \
311 int call = (val == __rsnd_mod_call_##func) && (mod)->ops->func; \ 332 int call = (val == __rsnd_mod_call_##func) && (mod)->ops->func; \
312 mod->status = (mod->status & ~mask) + \ 333 *status = (*status & ~mask) + \
313 (add << __rsnd_mod_shift_##func); \ 334 (add << __rsnd_mod_shift_##func); \
314 dev_dbg(dev, "%s[%d]\t0x%08x %s\n", \ 335 dev_dbg(dev, "%s[%d]\t0x%08x %s\n", \
315 rsnd_mod_name(mod), rsnd_mod_id(mod), \ 336 rsnd_mod_name(mod), rsnd_mod_id(mod), \
316 mod->status, call ? #func : ""); \ 337 *status, call ? #func : ""); \
317 if (call) \ 338 if (call) \
318 ret = (mod)->ops->func(mod, io, param); \ 339 ret = (mod)->ops->func(mod, io, param); \
319 ret; \ 340 ret; \
@@ -327,13 +348,14 @@ u32 rsnd_get_dalign(struct rsnd_mod *mod, struct rsnd_dai_stream *io)
327 mod = (io)->mod[i]; \ 348 mod = (io)->mod[i]; \
328 if (!mod) \ 349 if (!mod) \
329 continue; \ 350 continue; \
330 ret |= rsnd_mod_call(mod, io, fn, param); \ 351 ret |= rsnd_mod_call(i, io, fn, param); \
331 } \ 352 } \
332 ret; \ 353 ret; \
333}) 354})
334 355
335static int rsnd_dai_connect(struct rsnd_mod *mod, 356int rsnd_dai_connect(struct rsnd_mod *mod,
336 struct rsnd_dai_stream *io) 357 struct rsnd_dai_stream *io,
358 enum rsnd_mod_type type)
337{ 359{
338 struct rsnd_priv *priv; 360 struct rsnd_priv *priv;
339 struct device *dev; 361 struct device *dev;
@@ -341,10 +363,13 @@ static int rsnd_dai_connect(struct rsnd_mod *mod,
341 if (!mod) 363 if (!mod)
342 return -EIO; 364 return -EIO;
343 365
366 if (io->mod[type])
367 return -EINVAL;
368
344 priv = rsnd_mod_to_priv(mod); 369 priv = rsnd_mod_to_priv(mod);
345 dev = rsnd_priv_to_dev(priv); 370 dev = rsnd_priv_to_dev(priv);
346 371
347 io->mod[mod->type] = mod; 372 io->mod[type] = mod;
348 373
349 dev_dbg(dev, "%s[%d] is connected to io (%s)\n", 374 dev_dbg(dev, "%s[%d] is connected to io (%s)\n",
350 rsnd_mod_name(mod), rsnd_mod_id(mod), 375 rsnd_mod_name(mod), rsnd_mod_id(mod),
@@ -354,9 +379,10 @@ static int rsnd_dai_connect(struct rsnd_mod *mod,
354} 379}
355 380
356static void rsnd_dai_disconnect(struct rsnd_mod *mod, 381static void rsnd_dai_disconnect(struct rsnd_mod *mod,
357 struct rsnd_dai_stream *io) 382 struct rsnd_dai_stream *io,
383 enum rsnd_mod_type type)
358{ 384{
359 io->mod[mod->type] = NULL; 385 io->mod[type] = NULL;
360} 386}
361 387
362struct rsnd_dai *rsnd_rdai_get(struct rsnd_priv *priv, int id) 388struct rsnd_dai *rsnd_rdai_get(struct rsnd_priv *priv, int id)
@@ -469,7 +495,6 @@ static int rsnd_soc_dai_trigger(struct snd_pcm_substream *substream, int cmd,
469 struct rsnd_priv *priv = rsnd_dai_to_priv(dai); 495 struct rsnd_priv *priv = rsnd_dai_to_priv(dai);
470 struct rsnd_dai *rdai = rsnd_dai_to_rdai(dai); 496 struct rsnd_dai *rdai = rsnd_dai_to_rdai(dai);
471 struct rsnd_dai_stream *io = rsnd_rdai_to_io(rdai, substream); 497 struct rsnd_dai_stream *io = rsnd_rdai_to_io(rdai, substream);
472 int ssi_id = rsnd_mod_id(rsnd_io_to_mod_ssi(io));
473 int ret; 498 int ret;
474 unsigned long flags; 499 unsigned long flags;
475 500
@@ -479,10 +504,6 @@ static int rsnd_soc_dai_trigger(struct snd_pcm_substream *substream, int cmd,
479 case SNDRV_PCM_TRIGGER_START: 504 case SNDRV_PCM_TRIGGER_START:
480 rsnd_dai_stream_init(io, substream); 505 rsnd_dai_stream_init(io, substream);
481 506
482 ret = rsnd_platform_call(priv, dai, start, ssi_id);
483 if (ret < 0)
484 goto dai_trigger_end;
485
486 ret = rsnd_dai_call(init, io, priv); 507 ret = rsnd_dai_call(init, io, priv);
487 if (ret < 0) 508 if (ret < 0)
488 goto dai_trigger_end; 509 goto dai_trigger_end;
@@ -496,8 +517,6 @@ static int rsnd_soc_dai_trigger(struct snd_pcm_substream *substream, int cmd,
496 517
497 ret |= rsnd_dai_call(quit, io, priv); 518 ret |= rsnd_dai_call(quit, io, priv);
498 519
499 ret |= rsnd_platform_call(priv, dai, stop, ssi_id);
500
501 rsnd_dai_stream_quit(io); 520 rsnd_dai_stream_quit(io);
502 break; 521 break;
503 default: 522 default:
@@ -567,332 +586,157 @@ static int rsnd_soc_dai_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
567 return 0; 586 return 0;
568} 587}
569 588
570static const struct snd_soc_dai_ops rsnd_soc_dai_ops = { 589static int rsnd_soc_set_dai_tdm_slot(struct snd_soc_dai *dai,
571 .trigger = rsnd_soc_dai_trigger, 590 u32 tx_mask, u32 rx_mask,
572 .set_fmt = rsnd_soc_dai_set_fmt, 591 int slots, int slot_width)
573};
574
575#define rsnd_path_add(priv, io, type) \
576({ \
577 struct rsnd_mod *mod; \
578 int ret = 0; \
579 int id = -1; \
580 \
581 if (rsnd_is_enable_path(io, type)) { \
582 id = rsnd_info_id(priv, io, type); \
583 if (id >= 0) { \
584 mod = rsnd_##type##_mod_get(priv, id); \
585 ret = rsnd_dai_connect(mod, io); \
586 } \
587 } \
588 ret; \
589})
590
591#define rsnd_path_remove(priv, io, type) \
592{ \
593 struct rsnd_mod *mod; \
594 int id = -1; \
595 \
596 if (rsnd_is_enable_path(io, type)) { \
597 id = rsnd_info_id(priv, io, type); \
598 if (id >= 0) { \
599 mod = rsnd_##type##_mod_get(priv, id); \
600 rsnd_dai_disconnect(mod, io); \
601 } \
602 } \
603}
604
605void rsnd_path_parse(struct rsnd_priv *priv,
606 struct rsnd_dai_stream *io)
607{ 592{
608 struct rsnd_mod *dvc = rsnd_io_to_mod_dvc(io); 593 struct rsnd_priv *priv = rsnd_dai_to_priv(dai);
609 struct rsnd_mod *mix = rsnd_io_to_mod_mix(io); 594 struct rsnd_dai *rdai = rsnd_dai_to_rdai(dai);
610 struct rsnd_mod *src = rsnd_io_to_mod_src(io);
611 struct rsnd_mod *cmd;
612 struct device *dev = rsnd_priv_to_dev(priv); 595 struct device *dev = rsnd_priv_to_dev(priv);
613 u32 data;
614 596
615 /* Gen1 is not supported */ 597 switch (slots) {
616 if (rsnd_is_gen1(priv)) 598 case 6:
617 return; 599 /* TDM Extend Mode */
618 600 rsnd_set_slot(rdai, slots, 1);
619 if (!mix && !dvc) 601 break;
620 return; 602 default:
621 603 dev_err(dev, "unsupported TDM slots (%d)\n", slots);
622 if (mix) { 604 return -EINVAL;
623 struct rsnd_dai *rdai;
624 int i;
625 u32 path[] = {
626 [0] = 0,
627 [1] = 1 << 0,
628 [2] = 0,
629 [3] = 0,
630 [4] = 0,
631 [5] = 1 << 8
632 };
633
634 /*
635 * it is assuming that integrater is well understanding about
636 * data path. Here doesn't check impossible connection,
637 * like src2 + src5
638 */
639 data = 0;
640 for_each_rsnd_dai(rdai, priv, i) {
641 io = &rdai->playback;
642 if (mix == rsnd_io_to_mod_mix(io))
643 data |= path[rsnd_mod_id(src)];
644
645 io = &rdai->capture;
646 if (mix == rsnd_io_to_mod_mix(io))
647 data |= path[rsnd_mod_id(src)];
648 }
649
650 /*
651 * We can't use ctu = rsnd_io_ctu() here.
652 * Since, ID of dvc/mix are 0 or 1 (= same as CMD number)
653 * but ctu IDs are 0 - 7 (= CTU00 - CTU13)
654 */
655 cmd = mix;
656 } else {
657 u32 path[] = {
658 [0] = 0x30000,
659 [1] = 0x30001,
660 [2] = 0x40000,
661 [3] = 0x10000,
662 [4] = 0x20000,
663 [5] = 0x40100
664 };
665
666 data = path[rsnd_mod_id(src)];
667
668 cmd = dvc;
669 } 605 }
670 606
671 dev_dbg(dev, "ctu/mix path = 0x%08x", data); 607 return 0;
672
673 rsnd_mod_write(cmd, CMD_ROUTE_SLCT, data);
674
675 rsnd_mod_write(cmd, CMD_CTRL, 0x10);
676} 608}
677 609
678static int rsnd_path_init(struct rsnd_priv *priv, 610static const struct snd_soc_dai_ops rsnd_soc_dai_ops = {
679 struct rsnd_dai *rdai, 611 .trigger = rsnd_soc_dai_trigger,
680 struct rsnd_dai_stream *io) 612 .set_fmt = rsnd_soc_dai_set_fmt,
681{ 613 .set_tdm_slot = rsnd_soc_set_dai_tdm_slot,
682 int ret; 614};
683
684 /*
685 * Gen1 is created by SRU/SSI, and this SRU is base module of
686 * Gen2's SCU/SSIU/SSI. (Gen2 SCU/SSIU came from SRU)
687 *
688 * Easy image is..
689 * Gen1 SRU = Gen2 SCU + SSIU + etc
690 *
691 * Gen2 SCU path is very flexible, but, Gen1 SRU (SCU parts) is
692 * using fixed path.
693 */
694
695 /* SSI */
696 ret = rsnd_path_add(priv, io, ssi);
697 if (ret < 0)
698 return ret;
699
700 /* SRC */
701 ret = rsnd_path_add(priv, io, src);
702 if (ret < 0)
703 return ret;
704 615
705 /* CTU */ 616void rsnd_parse_connect_common(struct rsnd_dai *rdai,
706 ret = rsnd_path_add(priv, io, ctu); 617 struct rsnd_mod* (*mod_get)(struct rsnd_priv *priv, int id),
707 if (ret < 0) 618 struct device_node *node,
708 return ret; 619 struct device_node *playback,
620 struct device_node *capture)
621{
622 struct rsnd_priv *priv = rsnd_rdai_to_priv(rdai);
623 struct device_node *np;
624 struct rsnd_mod *mod;
625 int i;
709 626
710 /* MIX */ 627 if (!node)
711 ret = rsnd_path_add(priv, io, mix); 628 return;
712 if (ret < 0)
713 return ret;
714 629
715 /* DVC */ 630 i = 0;
716 ret = rsnd_path_add(priv, io, dvc); 631 for_each_child_of_node(node, np) {
717 if (ret < 0) 632 mod = mod_get(priv, i);
718 return ret; 633 if (np == playback)
634 rsnd_dai_connect(mod, &rdai->playback, mod->type);
635 if (np == capture)
636 rsnd_dai_connect(mod, &rdai->capture, mod->type);
637 i++;
638 }
719 639
720 return ret; 640 of_node_put(node);
721} 641}
722 642
723static void rsnd_of_parse_dai(struct platform_device *pdev, 643static int rsnd_dai_probe(struct rsnd_priv *priv)
724 const struct rsnd_of_data *of_data,
725 struct rsnd_priv *priv)
726{ 644{
727 struct device_node *dai_node, *dai_np; 645 struct device_node *dai_node;
728 struct device_node *ssi_node, *ssi_np; 646 struct device_node *dai_np;
729 struct device_node *src_node, *src_np;
730 struct device_node *ctu_node, *ctu_np;
731 struct device_node *mix_node, *mix_np;
732 struct device_node *dvc_node, *dvc_np;
733 struct device_node *playback, *capture; 647 struct device_node *playback, *capture;
734 struct rsnd_dai_platform_info *dai_info; 648 struct rsnd_dai_stream *io_playback;
735 struct rcar_snd_info *info = rsnd_priv_to_info(priv); 649 struct rsnd_dai_stream *io_capture;
736 struct device *dev = &pdev->dev; 650 struct snd_soc_dai_driver *rdrv, *drv;
737 int nr, i; 651 struct rsnd_dai *rdai;
738 int dai_i, ssi_i, src_i, ctu_i, mix_i, dvc_i; 652 struct device *dev = rsnd_priv_to_dev(priv);
739 653 int nr, dai_i, io_i;
740 if (!of_data) 654 int ret;
741 return;
742
743 dai_node = of_get_child_by_name(dev->of_node, "rcar_sound,dai");
744 if (!dai_node)
745 return;
746 655
656 dai_node = rsnd_dai_of_node(priv);
747 nr = of_get_child_count(dai_node); 657 nr = of_get_child_count(dai_node);
748 if (!nr) 658 if (!nr) {
749 return; 659 ret = -EINVAL;
660 goto rsnd_dai_probe_done;
661 }
750 662
751 dai_info = devm_kzalloc(dev, 663 rdrv = devm_kzalloc(dev, sizeof(*rdrv) * nr, GFP_KERNEL);
752 sizeof(struct rsnd_dai_platform_info) * nr, 664 rdai = devm_kzalloc(dev, sizeof(*rdai) * nr, GFP_KERNEL);
753 GFP_KERNEL); 665 if (!rdrv || !rdai) {
754 if (!dai_info) { 666 ret = -ENOMEM;
755 dev_err(dev, "dai info allocation error\n"); 667 goto rsnd_dai_probe_done;
756 return;
757 } 668 }
758 669
759 info->dai_info_nr = nr; 670 priv->rdai_nr = nr;
760 info->dai_info = dai_info; 671 priv->daidrv = rdrv;
761 672 priv->rdai = rdai;
762 ssi_node = of_get_child_by_name(dev->of_node, "rcar_sound,ssi");
763 src_node = of_get_child_by_name(dev->of_node, "rcar_sound,src");
764 ctu_node = of_get_child_by_name(dev->of_node, "rcar_sound,ctu");
765 mix_node = of_get_child_by_name(dev->of_node, "rcar_sound,mix");
766 dvc_node = of_get_child_by_name(dev->of_node, "rcar_sound,dvc");
767
768#define mod_parse(name) \
769if (name##_node) { \
770 struct rsnd_##name##_platform_info *name##_info; \
771 \
772 name##_i = 0; \
773 for_each_child_of_node(name##_node, name##_np) { \
774 name##_info = info->name##_info + name##_i; \
775 \
776 if (name##_np == playback) \
777 dai_info->playback.name = name##_info; \
778 if (name##_np == capture) \
779 dai_info->capture.name = name##_info; \
780 \
781 name##_i++; \
782 } \
783}
784 673
785 /* 674 /*
786 * parse all dai 675 * parse all dai
787 */ 676 */
788 dai_i = 0; 677 dai_i = 0;
789 for_each_child_of_node(dai_node, dai_np) { 678 for_each_child_of_node(dai_node, dai_np) {
790 dai_info = info->dai_info + dai_i; 679 rdai = rsnd_rdai_get(priv, dai_i);
791 680 drv = rdrv + dai_i;
792 for (i = 0;; i++) { 681 io_playback = &rdai->playback;
793 682 io_capture = &rdai->capture;
794 playback = of_parse_phandle(dai_np, "playback", i); 683
795 capture = of_parse_phandle(dai_np, "capture", i); 684 snprintf(rdai->name, RSND_DAI_NAME_SIZE, "rsnd-dai.%d", dai_i);
685
686 rdai->priv = priv;
687 drv->name = rdai->name;
688 drv->ops = &rsnd_soc_dai_ops;
689
690 snprintf(rdai->playback.name, RSND_DAI_NAME_SIZE,
691 "DAI%d Playback", dai_i);
692 drv->playback.rates = RSND_RATES;
693 drv->playback.formats = RSND_FMTS;
694 drv->playback.channels_min = 2;
695 drv->playback.channels_max = 6;
696 drv->playback.stream_name = rdai->playback.name;
697
698 snprintf(rdai->capture.name, RSND_DAI_NAME_SIZE,
699 "DAI%d Capture", dai_i);
700 drv->capture.rates = RSND_RATES;
701 drv->capture.formats = RSND_FMTS;
702 drv->capture.channels_min = 2;
703 drv->capture.channels_max = 6;
704 drv->capture.stream_name = rdai->capture.name;
705
706 rdai->playback.rdai = rdai;
707 rdai->capture.rdai = rdai;
708 rsnd_set_slot(rdai, 2, 1); /* default */
709
710 for (io_i = 0;; io_i++) {
711 playback = of_parse_phandle(dai_np, "playback", io_i);
712 capture = of_parse_phandle(dai_np, "capture", io_i);
796 713
797 if (!playback && !capture) 714 if (!playback && !capture)
798 break; 715 break;
799 716
800 mod_parse(ssi); 717 rsnd_parse_connect_ssi(rdai, playback, capture);
801 mod_parse(src); 718 rsnd_parse_connect_src(rdai, playback, capture);
802 mod_parse(ctu); 719 rsnd_parse_connect_ctu(rdai, playback, capture);
803 mod_parse(mix); 720 rsnd_parse_connect_mix(rdai, playback, capture);
804 mod_parse(dvc); 721 rsnd_parse_connect_dvc(rdai, playback, capture);
805 722
806 of_node_put(playback); 723 of_node_put(playback);
807 of_node_put(capture); 724 of_node_put(capture);
808 } 725 }
809 726
810 dai_i++; 727 dai_i++;
811 }
812}
813
814static int rsnd_dai_probe(struct platform_device *pdev,
815 const struct rsnd_of_data *of_data,
816 struct rsnd_priv *priv)
817{
818 struct snd_soc_dai_driver *drv;
819 struct rcar_snd_info *info = rsnd_priv_to_info(priv);
820 struct rsnd_dai *rdai;
821 struct rsnd_ssi_platform_info *pmod, *cmod;
822 struct device *dev = rsnd_priv_to_dev(priv);
823 int dai_nr;
824 int i;
825
826 rsnd_of_parse_dai(pdev, of_data, priv);
827 728
828 dai_nr = info->dai_info_nr; 729 dev_dbg(dev, "%s (%s/%s)\n", rdai->name,
829 if (!dai_nr) { 730 rsnd_io_to_mod_ssi(io_playback) ? "play" : " -- ",
830 dev_err(dev, "no dai\n"); 731 rsnd_io_to_mod_ssi(io_capture) ? "capture" : " -- ");
831 return -EIO;
832 } 732 }
833 733
834 drv = devm_kzalloc(dev, sizeof(*drv) * dai_nr, GFP_KERNEL); 734 ret = 0;
835 rdai = devm_kzalloc(dev, sizeof(*rdai) * dai_nr, GFP_KERNEL);
836 if (!drv || !rdai) {
837 dev_err(dev, "dai allocate failed\n");
838 return -ENOMEM;
839 }
840
841 priv->rdai_nr = dai_nr;
842 priv->daidrv = drv;
843 priv->rdai = rdai;
844 735
845 for (i = 0; i < dai_nr; i++) { 736rsnd_dai_probe_done:
737 of_node_put(dai_node);
846 738
847 pmod = info->dai_info[i].playback.ssi; 739 return ret;
848 cmod = info->dai_info[i].capture.ssi;
849
850 /*
851 * init rsnd_dai
852 */
853 snprintf(rdai[i].name, RSND_DAI_NAME_SIZE, "rsnd-dai.%d", i);
854 rdai[i].priv = priv;
855
856 /*
857 * init snd_soc_dai_driver
858 */
859 drv[i].name = rdai[i].name;
860 drv[i].ops = &rsnd_soc_dai_ops;
861 if (pmod) {
862 snprintf(rdai[i].playback.name, RSND_DAI_NAME_SIZE,
863 "DAI%d Playback", i);
864
865 drv[i].playback.rates = RSND_RATES;
866 drv[i].playback.formats = RSND_FMTS;
867 drv[i].playback.channels_min = 2;
868 drv[i].playback.channels_max = 2;
869 drv[i].playback.stream_name = rdai[i].playback.name;
870
871 rdai[i].playback.info = &info->dai_info[i].playback;
872 rdai[i].playback.rdai = rdai + i;
873 rsnd_path_init(priv, &rdai[i], &rdai[i].playback);
874 }
875 if (cmod) {
876 snprintf(rdai[i].capture.name, RSND_DAI_NAME_SIZE,
877 "DAI%d Capture", i);
878
879 drv[i].capture.rates = RSND_RATES;
880 drv[i].capture.formats = RSND_FMTS;
881 drv[i].capture.channels_min = 2;
882 drv[i].capture.channels_max = 2;
883 drv[i].capture.stream_name = rdai[i].capture.name;
884
885 rdai[i].capture.info = &info->dai_info[i].capture;
886 rdai[i].capture.rdai = rdai + i;
887 rsnd_path_init(priv, &rdai[i], &rdai[i].capture);
888 }
889
890 dev_dbg(dev, "%s (%s/%s)\n", rdai[i].name,
891 pmod ? "play" : " -- ",
892 cmod ? "capture" : " -- ");
893 }
894
895 return 0;
896} 740}
897 741
898/* 742/*
@@ -1033,14 +877,13 @@ static int __rsnd_kctrl_new(struct rsnd_mod *mod,
1033 void (*update)(struct rsnd_dai_stream *io, 877 void (*update)(struct rsnd_dai_stream *io,
1034 struct rsnd_mod *mod)) 878 struct rsnd_mod *mod))
1035{ 879{
1036 struct snd_soc_card *soc_card = rtd->card;
1037 struct snd_card *card = rtd->card->snd_card; 880 struct snd_card *card = rtd->card->snd_card;
1038 struct snd_kcontrol *kctrl; 881 struct snd_kcontrol *kctrl;
1039 struct snd_kcontrol_new knew = { 882 struct snd_kcontrol_new knew = {
1040 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 883 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1041 .name = name, 884 .name = name,
1042 .info = rsnd_kctrl_info, 885 .info = rsnd_kctrl_info,
1043 .index = rtd - soc_card->rtd, 886 .index = rtd->num,
1044 .get = rsnd_kctrl_get, 887 .get = rsnd_kctrl_get,
1045 .put = rsnd_kctrl_put, 888 .put = rsnd_kctrl_put,
1046 .private_value = (unsigned long)cfg, 889 .private_value = (unsigned long)cfg,
@@ -1077,10 +920,14 @@ int rsnd_kctrl_new_m(struct rsnd_mod *mod,
1077 void (*update)(struct rsnd_dai_stream *io, 920 void (*update)(struct rsnd_dai_stream *io,
1078 struct rsnd_mod *mod), 921 struct rsnd_mod *mod),
1079 struct rsnd_kctrl_cfg_m *_cfg, 922 struct rsnd_kctrl_cfg_m *_cfg,
923 int ch_size,
1080 u32 max) 924 u32 max)
1081{ 925{
926 if (ch_size > RSND_DVC_CHANNELS)
927 return -EINVAL;
928
1082 _cfg->cfg.max = max; 929 _cfg->cfg.max = max;
1083 _cfg->cfg.size = RSND_DVC_CHANNELS; 930 _cfg->cfg.size = ch_size;
1084 _cfg->cfg.val = _cfg->val; 931 _cfg->cfg.val = _cfg->val;
1085 return __rsnd_kctrl_new(mod, io, rtd, name, &_cfg->cfg, update); 932 return __rsnd_kctrl_new(mod, io, rtd, name, &_cfg->cfg, update);
1086} 933}
@@ -1161,6 +1008,9 @@ static int rsnd_rdai_continuance_probe(struct rsnd_priv *priv,
1161 1008
1162 ret = rsnd_dai_call(probe, io, priv); 1009 ret = rsnd_dai_call(probe, io, priv);
1163 if (ret == -EAGAIN) { 1010 if (ret == -EAGAIN) {
1011 struct rsnd_mod *ssi_mod = rsnd_io_to_mod_ssi(io);
1012 int i;
1013
1164 /* 1014 /*
1165 * Fallback to PIO mode 1015 * Fallback to PIO mode
1166 */ 1016 */
@@ -1175,10 +1025,12 @@ static int rsnd_rdai_continuance_probe(struct rsnd_priv *priv,
1175 rsnd_dai_call(remove, io, priv); 1025 rsnd_dai_call(remove, io, priv);
1176 1026
1177 /* 1027 /*
1178 * remove SRC/DVC from DAI, 1028 * remove all mod from io
1029 * and, re connect ssi
1179 */ 1030 */
1180 rsnd_path_remove(priv, io, src); 1031 for (i = 0; i < RSND_MOD_MAX; i++)
1181 rsnd_path_remove(priv, io, dvc); 1032 rsnd_dai_disconnect((io)->mod[i], io, i);
1033 rsnd_dai_connect(ssi_mod, io, RSND_MOD_SSI);
1182 1034
1183 /* 1035 /*
1184 * fallback 1036 * fallback
@@ -1200,33 +1052,25 @@ static int rsnd_rdai_continuance_probe(struct rsnd_priv *priv,
1200 */ 1052 */
1201static int rsnd_probe(struct platform_device *pdev) 1053static int rsnd_probe(struct platform_device *pdev)
1202{ 1054{
1203 struct rcar_snd_info *info;
1204 struct rsnd_priv *priv; 1055 struct rsnd_priv *priv;
1205 struct device *dev = &pdev->dev; 1056 struct device *dev = &pdev->dev;
1206 struct rsnd_dai *rdai; 1057 struct rsnd_dai *rdai;
1207 const struct of_device_id *of_id = of_match_device(rsnd_of_match, dev); 1058 const struct of_device_id *of_id = of_match_device(rsnd_of_match, dev);
1208 const struct rsnd_of_data *of_data; 1059 int (*probe_func[])(struct rsnd_priv *priv) = {
1209 int (*probe_func[])(struct platform_device *pdev,
1210 const struct rsnd_of_data *of_data,
1211 struct rsnd_priv *priv) = {
1212 rsnd_gen_probe, 1060 rsnd_gen_probe,
1213 rsnd_dma_probe, 1061 rsnd_dma_probe,
1214 rsnd_ssi_probe, 1062 rsnd_ssi_probe,
1063 rsnd_ssiu_probe,
1215 rsnd_src_probe, 1064 rsnd_src_probe,
1216 rsnd_ctu_probe, 1065 rsnd_ctu_probe,
1217 rsnd_mix_probe, 1066 rsnd_mix_probe,
1218 rsnd_dvc_probe, 1067 rsnd_dvc_probe,
1068 rsnd_cmd_probe,
1219 rsnd_adg_probe, 1069 rsnd_adg_probe,
1220 rsnd_dai_probe, 1070 rsnd_dai_probe,
1221 }; 1071 };
1222 int ret, i; 1072 int ret, i;
1223 1073
1224 info = devm_kzalloc(&pdev->dev, sizeof(struct rcar_snd_info),
1225 GFP_KERNEL);
1226 if (!info)
1227 return -ENOMEM;
1228 of_data = of_id->data;
1229
1230 /* 1074 /*
1231 * init priv data 1075 * init priv data
1232 */ 1076 */
@@ -1237,14 +1081,14 @@ static int rsnd_probe(struct platform_device *pdev)
1237 } 1081 }
1238 1082
1239 priv->pdev = pdev; 1083 priv->pdev = pdev;
1240 priv->info = info; 1084 priv->flags = (unsigned long)of_id->data;
1241 spin_lock_init(&priv->lock); 1085 spin_lock_init(&priv->lock);
1242 1086
1243 /* 1087 /*
1244 * init each module 1088 * init each module
1245 */ 1089 */
1246 for (i = 0; i < ARRAY_SIZE(probe_func); i++) { 1090 for (i = 0; i < ARRAY_SIZE(probe_func); i++) {
1247 ret = probe_func[i](pdev, of_data, priv); 1091 ret = probe_func[i](priv);
1248 if (ret) 1092 if (ret)
1249 return ret; 1093 return ret;
1250 } 1094 }
@@ -1297,13 +1141,15 @@ static int rsnd_remove(struct platform_device *pdev)
1297{ 1141{
1298 struct rsnd_priv *priv = dev_get_drvdata(&pdev->dev); 1142 struct rsnd_priv *priv = dev_get_drvdata(&pdev->dev);
1299 struct rsnd_dai *rdai; 1143 struct rsnd_dai *rdai;
1300 void (*remove_func[])(struct platform_device *pdev, 1144 void (*remove_func[])(struct rsnd_priv *priv) = {
1301 struct rsnd_priv *priv) = {
1302 rsnd_ssi_remove, 1145 rsnd_ssi_remove,
1146 rsnd_ssiu_remove,
1303 rsnd_src_remove, 1147 rsnd_src_remove,
1304 rsnd_ctu_remove, 1148 rsnd_ctu_remove,
1305 rsnd_mix_remove, 1149 rsnd_mix_remove,
1306 rsnd_dvc_remove, 1150 rsnd_dvc_remove,
1151 rsnd_cmd_remove,
1152 rsnd_adg_remove,
1307 }; 1153 };
1308 int ret = 0, i; 1154 int ret = 0, i;
1309 1155
@@ -1315,7 +1161,7 @@ static int rsnd_remove(struct platform_device *pdev)
1315 } 1161 }
1316 1162
1317 for (i = 0; i < ARRAY_SIZE(remove_func); i++) 1163 for (i = 0; i < ARRAY_SIZE(remove_func); i++)
1318 remove_func[i](pdev, priv); 1164 remove_func[i](priv);
1319 1165
1320 snd_soc_unregister_component(&pdev->dev); 1166 snd_soc_unregister_component(&pdev->dev);
1321 snd_soc_unregister_platform(&pdev->dev); 1167 snd_soc_unregister_platform(&pdev->dev);
diff --git a/sound/soc/sh/rcar/ctu.c b/sound/soc/sh/rcar/ctu.c
index 3cb214ab848b..d53a225d19e9 100644
--- a/sound/soc/sh/rcar/ctu.c
+++ b/sound/soc/sh/rcar/ctu.c
@@ -13,7 +13,6 @@
13#define CTU_NAME "ctu" 13#define CTU_NAME "ctu"
14 14
15struct rsnd_ctu { 15struct rsnd_ctu {
16 struct rsnd_ctu_platform_info *info; /* rcar_snd.h */
17 struct rsnd_mod mod; 16 struct rsnd_mod mod;
18}; 17};
19 18
@@ -24,6 +23,7 @@ struct rsnd_ctu {
24 ((pos) = (struct rsnd_ctu *)(priv)->ctu + i); \ 23 ((pos) = (struct rsnd_ctu *)(priv)->ctu + i); \
25 i++) 24 i++)
26 25
26#define rsnd_ctu_get(priv, id) ((struct rsnd_ctu *)(priv->ctu) + id)
27#define rsnd_ctu_initialize_lock(mod) __rsnd_ctu_initialize_lock(mod, 1) 27#define rsnd_ctu_initialize_lock(mod) __rsnd_ctu_initialize_lock(mod, 1)
28#define rsnd_ctu_initialize_unlock(mod) __rsnd_ctu_initialize_lock(mod, 0) 28#define rsnd_ctu_initialize_unlock(mod) __rsnd_ctu_initialize_lock(mod, 0)
29static void __rsnd_ctu_initialize_lock(struct rsnd_mod *mod, u32 enable) 29static void __rsnd_ctu_initialize_lock(struct rsnd_mod *mod, u32 enable)
@@ -31,6 +31,13 @@ static void __rsnd_ctu_initialize_lock(struct rsnd_mod *mod, u32 enable)
31 rsnd_mod_write(mod, CTU_CTUIR, enable); 31 rsnd_mod_write(mod, CTU_CTUIR, enable);
32} 32}
33 33
34static int rsnd_ctu_probe_(struct rsnd_mod *mod,
35 struct rsnd_dai_stream *io,
36 struct rsnd_priv *priv)
37{
38 return rsnd_cmd_attach(io, rsnd_mod_id(mod) / 4);
39}
40
34static int rsnd_ctu_init(struct rsnd_mod *mod, 41static int rsnd_ctu_init(struct rsnd_mod *mod,
35 struct rsnd_dai_stream *io, 42 struct rsnd_dai_stream *io,
36 struct rsnd_priv *priv) 43 struct rsnd_priv *priv)
@@ -57,6 +64,7 @@ static int rsnd_ctu_quit(struct rsnd_mod *mod,
57 64
58static struct rsnd_mod_ops rsnd_ctu_ops = { 65static struct rsnd_mod_ops rsnd_ctu_ops = {
59 .name = CTU_NAME, 66 .name = CTU_NAME,
67 .probe = rsnd_ctu_probe_,
60 .init = rsnd_ctu_init, 68 .init = rsnd_ctu_init,
61 .quit = rsnd_ctu_quit, 69 .quit = rsnd_ctu_quit,
62}; 70};
@@ -66,51 +74,13 @@ struct rsnd_mod *rsnd_ctu_mod_get(struct rsnd_priv *priv, int id)
66 if (WARN_ON(id < 0 || id >= rsnd_ctu_nr(priv))) 74 if (WARN_ON(id < 0 || id >= rsnd_ctu_nr(priv)))
67 id = 0; 75 id = 0;
68 76
69 return rsnd_mod_get((struct rsnd_ctu *)(priv->ctu) + id); 77 return rsnd_mod_get(rsnd_ctu_get(priv, id));
70} 78}
71 79
72static void rsnd_of_parse_ctu(struct platform_device *pdev, 80int rsnd_ctu_probe(struct rsnd_priv *priv)
73 const struct rsnd_of_data *of_data,
74 struct rsnd_priv *priv)
75{ 81{
76 struct device_node *node; 82 struct device_node *node;
77 struct rsnd_ctu_platform_info *ctu_info; 83 struct device_node *np;
78 struct rcar_snd_info *info = rsnd_priv_to_info(priv);
79 struct device *dev = &pdev->dev;
80 int nr;
81
82 if (!of_data)
83 return;
84
85 node = of_get_child_by_name(dev->of_node, "rcar_sound,ctu");
86 if (!node)
87 return;
88
89 nr = of_get_child_count(node);
90 if (!nr)
91 goto rsnd_of_parse_ctu_end;
92
93 ctu_info = devm_kzalloc(dev,
94 sizeof(struct rsnd_ctu_platform_info) * nr,
95 GFP_KERNEL);
96 if (!ctu_info) {
97 dev_err(dev, "ctu info allocation error\n");
98 goto rsnd_of_parse_ctu_end;
99 }
100
101 info->ctu_info = ctu_info;
102 info->ctu_info_nr = nr;
103
104rsnd_of_parse_ctu_end:
105 of_node_put(node);
106
107}
108
109int rsnd_ctu_probe(struct platform_device *pdev,
110 const struct rsnd_of_data *of_data,
111 struct rsnd_priv *priv)
112{
113 struct rcar_snd_info *info = rsnd_priv_to_info(priv);
114 struct device *dev = rsnd_priv_to_dev(priv); 84 struct device *dev = rsnd_priv_to_dev(priv);
115 struct rsnd_ctu *ctu; 85 struct rsnd_ctu *ctu;
116 struct clk *clk; 86 struct clk *clk;
@@ -121,20 +91,30 @@ int rsnd_ctu_probe(struct platform_device *pdev,
121 if (rsnd_is_gen1(priv)) 91 if (rsnd_is_gen1(priv))
122 return 0; 92 return 0;
123 93
124 rsnd_of_parse_ctu(pdev, of_data, priv); 94 node = rsnd_ctu_of_node(priv);
95 if (!node)
96 return 0; /* not used is not error */
125 97
126 nr = info->ctu_info_nr; 98 nr = of_get_child_count(node);
127 if (!nr) 99 if (!nr) {
128 return 0; 100 ret = -EINVAL;
101 goto rsnd_ctu_probe_done;
102 }
129 103
130 ctu = devm_kzalloc(dev, sizeof(*ctu) * nr, GFP_KERNEL); 104 ctu = devm_kzalloc(dev, sizeof(*ctu) * nr, GFP_KERNEL);
131 if (!ctu) 105 if (!ctu) {
132 return -ENOMEM; 106 ret = -ENOMEM;
107 goto rsnd_ctu_probe_done;
108 }
133 109
134 priv->ctu_nr = nr; 110 priv->ctu_nr = nr;
135 priv->ctu = ctu; 111 priv->ctu = ctu;
136 112
137 for_each_rsnd_ctu(ctu, priv, i) { 113 i = 0;
114 ret = 0;
115 for_each_child_of_node(node, np) {
116 ctu = rsnd_ctu_get(priv, i);
117
138 /* 118 /*
139 * CTU00, CTU01, CTU02, CTU03 => CTU0 119 * CTU00, CTU01, CTU02, CTU03 => CTU0
140 * CTU10, CTU11, CTU12, CTU13 => CTU1 120 * CTU10, CTU11, CTU12, CTU13 => CTU1
@@ -143,22 +123,27 @@ int rsnd_ctu_probe(struct platform_device *pdev,
143 CTU_NAME, i / 4); 123 CTU_NAME, i / 4);
144 124
145 clk = devm_clk_get(dev, name); 125 clk = devm_clk_get(dev, name);
146 if (IS_ERR(clk)) 126 if (IS_ERR(clk)) {
147 return PTR_ERR(clk); 127 ret = PTR_ERR(clk);
148 128 goto rsnd_ctu_probe_done;
149 ctu->info = &info->ctu_info[i]; 129 }
150 130
151 ret = rsnd_mod_init(priv, rsnd_mod_get(ctu), &rsnd_ctu_ops, 131 ret = rsnd_mod_init(priv, rsnd_mod_get(ctu), &rsnd_ctu_ops,
152 clk, RSND_MOD_CTU, i); 132 clk, RSND_MOD_CTU, i);
153 if (ret) 133 if (ret)
154 return ret; 134 goto rsnd_ctu_probe_done;
135
136 i++;
155 } 137 }
156 138
157 return 0; 139
140rsnd_ctu_probe_done:
141 of_node_put(node);
142
143 return ret;
158} 144}
159 145
160void rsnd_ctu_remove(struct platform_device *pdev, 146void rsnd_ctu_remove(struct rsnd_priv *priv)
161 struct rsnd_priv *priv)
162{ 147{
163 struct rsnd_ctu *ctu; 148 struct rsnd_ctu *ctu;
164 int i; 149 int i;
diff --git a/sound/soc/sh/rcar/dma.c b/sound/soc/sh/rcar/dma.c
index 5d084d040961..418e6fdd06a3 100644
--- a/sound/soc/sh/rcar/dma.c
+++ b/sound/soc/sh/rcar/dma.c
@@ -22,21 +22,36 @@
22/* PDMACHCR */ 22/* PDMACHCR */
23#define PDMACHCR_DE (1 << 0) 23#define PDMACHCR_DE (1 << 0)
24 24
25
26struct rsnd_dmaen {
27 struct dma_chan *chan;
28};
29
30struct rsnd_dmapp {
31 int dmapp_id;
32 u32 chcr;
33};
34
35struct rsnd_dma {
36 struct rsnd_mod mod;
37 dma_addr_t src_addr;
38 dma_addr_t dst_addr;
39 union {
40 struct rsnd_dmaen en;
41 struct rsnd_dmapp pp;
42 } dma;
43};
44
25struct rsnd_dma_ctrl { 45struct rsnd_dma_ctrl {
26 void __iomem *base; 46 void __iomem *base;
47 int dmaen_num;
27 int dmapp_num; 48 int dmapp_num;
28}; 49};
29 50
30struct rsnd_dma_ops {
31 char *name;
32 void (*start)(struct rsnd_dai_stream *io, struct rsnd_dma *dma);
33 void (*stop)(struct rsnd_dai_stream *io, struct rsnd_dma *dma);
34 int (*init)(struct rsnd_dai_stream *io, struct rsnd_dma *dma, int id,
35 struct rsnd_mod *mod_from, struct rsnd_mod *mod_to);
36 void (*quit)(struct rsnd_dai_stream *io, struct rsnd_dma *dma);
37};
38
39#define rsnd_priv_to_dmac(p) ((struct rsnd_dma_ctrl *)(p)->dma) 51#define rsnd_priv_to_dmac(p) ((struct rsnd_dma_ctrl *)(p)->dma)
52#define rsnd_mod_to_dma(_mod) container_of((_mod), struct rsnd_dma, mod)
53#define rsnd_dma_to_dmaen(dma) (&(dma)->dma.en)
54#define rsnd_dma_to_dmapp(dma) (&(dma)->dma.pp)
40 55
41/* 56/*
42 * Audio DMAC 57 * Audio DMAC
@@ -77,18 +92,24 @@ static void rsnd_dmaen_complete(void *data)
77 rsnd_mod_interrupt(mod, __rsnd_dmaen_complete); 92 rsnd_mod_interrupt(mod, __rsnd_dmaen_complete);
78} 93}
79 94
80static void rsnd_dmaen_stop(struct rsnd_dai_stream *io, struct rsnd_dma *dma) 95static int rsnd_dmaen_stop(struct rsnd_mod *mod,
96 struct rsnd_dai_stream *io,
97 struct rsnd_priv *priv)
81{ 98{
99 struct rsnd_dma *dma = rsnd_mod_to_dma(mod);
82 struct rsnd_dmaen *dmaen = rsnd_dma_to_dmaen(dma); 100 struct rsnd_dmaen *dmaen = rsnd_dma_to_dmaen(dma);
83 101
84 dmaengine_terminate_all(dmaen->chan); 102 dmaengine_terminate_all(dmaen->chan);
103
104 return 0;
85} 105}
86 106
87static void rsnd_dmaen_start(struct rsnd_dai_stream *io, struct rsnd_dma *dma) 107static int rsnd_dmaen_start(struct rsnd_mod *mod,
108 struct rsnd_dai_stream *io,
109 struct rsnd_priv *priv)
88{ 110{
111 struct rsnd_dma *dma = rsnd_mod_to_dma(mod);
89 struct rsnd_dmaen *dmaen = rsnd_dma_to_dmaen(dma); 112 struct rsnd_dmaen *dmaen = rsnd_dma_to_dmaen(dma);
90 struct rsnd_mod *mod = rsnd_dma_to_mod(dma);
91 struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
92 struct snd_pcm_substream *substream = io->substream; 113 struct snd_pcm_substream *substream = io->substream;
93 struct device *dev = rsnd_priv_to_dev(priv); 114 struct device *dev = rsnd_priv_to_dev(priv);
94 struct dma_async_tx_descriptor *desc; 115 struct dma_async_tx_descriptor *desc;
@@ -103,18 +124,20 @@ static void rsnd_dmaen_start(struct rsnd_dai_stream *io, struct rsnd_dma *dma)
103 124
104 if (!desc) { 125 if (!desc) {
105 dev_err(dev, "dmaengine_prep_slave_sg() fail\n"); 126 dev_err(dev, "dmaengine_prep_slave_sg() fail\n");
106 return; 127 return -EIO;
107 } 128 }
108 129
109 desc->callback = rsnd_dmaen_complete; 130 desc->callback = rsnd_dmaen_complete;
110 desc->callback_param = mod; 131 desc->callback_param = rsnd_mod_get(dma);
111 132
112 if (dmaengine_submit(desc) < 0) { 133 if (dmaengine_submit(desc) < 0) {
113 dev_err(dev, "dmaengine_submit() fail\n"); 134 dev_err(dev, "dmaengine_submit() fail\n");
114 return; 135 return -EIO;
115 } 136 }
116 137
117 dma_async_issue_pending(dmaen->chan); 138 dma_async_issue_pending(dmaen->chan);
139
140 return 0;
118} 141}
119 142
120struct dma_chan *rsnd_dma_request_channel(struct device_node *of_node, 143struct dma_chan *rsnd_dma_request_channel(struct device_node *of_node,
@@ -152,12 +175,29 @@ static struct dma_chan *rsnd_dmaen_request_channel(struct rsnd_dai_stream *io,
152 return rsnd_mod_dma_req(io, mod_to); 175 return rsnd_mod_dma_req(io, mod_to);
153} 176}
154 177
155static int rsnd_dmaen_init(struct rsnd_dai_stream *io, 178static int rsnd_dmaen_remove(struct rsnd_mod *mod,
179 struct rsnd_dai_stream *io,
180 struct rsnd_priv *priv)
181{
182 struct rsnd_dma *dma = rsnd_mod_to_dma(mod);
183 struct rsnd_dmaen *dmaen = rsnd_dma_to_dmaen(dma);
184
185 if (dmaen->chan)
186 dma_release_channel(dmaen->chan);
187
188 dmaen->chan = NULL;
189
190 return 0;
191}
192
193static int rsnd_dmaen_attach(struct rsnd_dai_stream *io,
156 struct rsnd_dma *dma, int id, 194 struct rsnd_dma *dma, int id,
157 struct rsnd_mod *mod_from, struct rsnd_mod *mod_to) 195 struct rsnd_mod *mod_from, struct rsnd_mod *mod_to)
158{ 196{
197 struct rsnd_mod *mod = rsnd_mod_get(dma);
159 struct rsnd_dmaen *dmaen = rsnd_dma_to_dmaen(dma); 198 struct rsnd_dmaen *dmaen = rsnd_dma_to_dmaen(dma);
160 struct rsnd_priv *priv = rsnd_io_to_priv(io); 199 struct rsnd_priv *priv = rsnd_io_to_priv(io);
200 struct rsnd_dma_ctrl *dmac = rsnd_priv_to_dmac(priv);
161 struct device *dev = rsnd_priv_to_dev(priv); 201 struct device *dev = rsnd_priv_to_dev(priv);
162 struct dma_slave_config cfg = {}; 202 struct dma_slave_config cfg = {};
163 int is_play = rsnd_io_is_play(io); 203 int is_play = rsnd_io_is_play(io);
@@ -191,18 +231,20 @@ static int rsnd_dmaen_init(struct rsnd_dai_stream *io,
191 cfg.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; 231 cfg.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
192 cfg.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; 232 cfg.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
193 233
194 dev_dbg(dev, "%s %pad -> %pad\n", 234 dev_dbg(dev, "%s[%d] %pad -> %pad\n",
195 dma->ops->name, 235 rsnd_mod_name(mod), rsnd_mod_id(mod),
196 &cfg.src_addr, &cfg.dst_addr); 236 &cfg.src_addr, &cfg.dst_addr);
197 237
198 ret = dmaengine_slave_config(dmaen->chan, &cfg); 238 ret = dmaengine_slave_config(dmaen->chan, &cfg);
199 if (ret < 0) 239 if (ret < 0)
200 goto rsnd_dma_init_err; 240 goto rsnd_dma_attach_err;
241
242 dmac->dmaen_num++;
201 243
202 return 0; 244 return 0;
203 245
204rsnd_dma_init_err: 246rsnd_dma_attach_err:
205 rsnd_dma_quit(io, dma); 247 rsnd_dmaen_remove(mod, io, priv);
206rsnd_dma_channel_err: 248rsnd_dma_channel_err:
207 249
208 /* 250 /*
@@ -214,22 +256,11 @@ rsnd_dma_channel_err:
214 return -EAGAIN; 256 return -EAGAIN;
215} 257}
216 258
217static void rsnd_dmaen_quit(struct rsnd_dai_stream *io, struct rsnd_dma *dma) 259static struct rsnd_mod_ops rsnd_dmaen_ops = {
218{
219 struct rsnd_dmaen *dmaen = rsnd_dma_to_dmaen(dma);
220
221 if (dmaen->chan)
222 dma_release_channel(dmaen->chan);
223
224 dmaen->chan = NULL;
225}
226
227static struct rsnd_dma_ops rsnd_dmaen_ops = {
228 .name = "audmac", 260 .name = "audmac",
229 .start = rsnd_dmaen_start, 261 .start = rsnd_dmaen_start,
230 .stop = rsnd_dmaen_stop, 262 .stop = rsnd_dmaen_stop,
231 .init = rsnd_dmaen_init, 263 .remove = rsnd_dmaen_remove,
232 .quit = rsnd_dmaen_quit,
233}; 264};
234 265
235/* 266/*
@@ -307,7 +338,7 @@ static u32 rsnd_dmapp_get_chcr(struct rsnd_dai_stream *io,
307 (0x10 * rsnd_dma_to_dmapp(dma)->dmapp_id)) 338 (0x10 * rsnd_dma_to_dmapp(dma)->dmapp_id))
308static void rsnd_dmapp_write(struct rsnd_dma *dma, u32 data, u32 reg) 339static void rsnd_dmapp_write(struct rsnd_dma *dma, u32 data, u32 reg)
309{ 340{
310 struct rsnd_mod *mod = rsnd_dma_to_mod(dma); 341 struct rsnd_mod *mod = rsnd_mod_get(dma);
311 struct rsnd_priv *priv = rsnd_mod_to_priv(mod); 342 struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
312 struct rsnd_dma_ctrl *dmac = rsnd_priv_to_dmac(priv); 343 struct rsnd_dma_ctrl *dmac = rsnd_priv_to_dmac(priv);
313 struct device *dev = rsnd_priv_to_dev(priv); 344 struct device *dev = rsnd_priv_to_dev(priv);
@@ -319,38 +350,48 @@ static void rsnd_dmapp_write(struct rsnd_dma *dma, u32 data, u32 reg)
319 350
320static u32 rsnd_dmapp_read(struct rsnd_dma *dma, u32 reg) 351static u32 rsnd_dmapp_read(struct rsnd_dma *dma, u32 reg)
321{ 352{
322 struct rsnd_mod *mod = rsnd_dma_to_mod(dma); 353 struct rsnd_mod *mod = rsnd_mod_get(dma);
323 struct rsnd_priv *priv = rsnd_mod_to_priv(mod); 354 struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
324 struct rsnd_dma_ctrl *dmac = rsnd_priv_to_dmac(priv); 355 struct rsnd_dma_ctrl *dmac = rsnd_priv_to_dmac(priv);
325 356
326 return ioread32(rsnd_dmapp_addr(dmac, dma, reg)); 357 return ioread32(rsnd_dmapp_addr(dmac, dma, reg));
327} 358}
328 359
329static void rsnd_dmapp_stop(struct rsnd_dai_stream *io, struct rsnd_dma *dma) 360static int rsnd_dmapp_stop(struct rsnd_mod *mod,
361 struct rsnd_dai_stream *io,
362 struct rsnd_priv *priv)
330{ 363{
364 struct rsnd_dma *dma = rsnd_mod_to_dma(mod);
331 int i; 365 int i;
332 366
333 rsnd_dmapp_write(dma, 0, PDMACHCR); 367 rsnd_dmapp_write(dma, 0, PDMACHCR);
334 368
335 for (i = 0; i < 1024; i++) { 369 for (i = 0; i < 1024; i++) {
336 if (0 == rsnd_dmapp_read(dma, PDMACHCR)) 370 if (0 == rsnd_dmapp_read(dma, PDMACHCR))
337 return; 371 return 0;
338 udelay(1); 372 udelay(1);
339 } 373 }
374
375 return -EIO;
340} 376}
341 377
342static void rsnd_dmapp_start(struct rsnd_dai_stream *io, struct rsnd_dma *dma) 378static int rsnd_dmapp_start(struct rsnd_mod *mod,
379 struct rsnd_dai_stream *io,
380 struct rsnd_priv *priv)
343{ 381{
382 struct rsnd_dma *dma = rsnd_mod_to_dma(mod);
344 struct rsnd_dmapp *dmapp = rsnd_dma_to_dmapp(dma); 383 struct rsnd_dmapp *dmapp = rsnd_dma_to_dmapp(dma);
345 384
346 rsnd_dmapp_write(dma, dma->src_addr, PDMASAR); 385 rsnd_dmapp_write(dma, dma->src_addr, PDMASAR);
347 rsnd_dmapp_write(dma, dma->dst_addr, PDMADAR); 386 rsnd_dmapp_write(dma, dma->dst_addr, PDMADAR);
348 rsnd_dmapp_write(dma, dmapp->chcr, PDMACHCR); 387 rsnd_dmapp_write(dma, dmapp->chcr, PDMACHCR);
388
389 return 0;
349} 390}
350 391
351static int rsnd_dmapp_init(struct rsnd_dai_stream *io, 392static int rsnd_dmapp_attach(struct rsnd_dai_stream *io,
352 struct rsnd_dma *dma, int id, 393 struct rsnd_dma *dma, int id,
353 struct rsnd_mod *mod_from, struct rsnd_mod *mod_to) 394 struct rsnd_mod *mod_from, struct rsnd_mod *mod_to)
354{ 395{
355 struct rsnd_dmapp *dmapp = rsnd_dma_to_dmapp(dma); 396 struct rsnd_dmapp *dmapp = rsnd_dma_to_dmapp(dma);
356 struct rsnd_priv *priv = rsnd_io_to_priv(io); 397 struct rsnd_priv *priv = rsnd_io_to_priv(io);
@@ -362,19 +403,16 @@ static int rsnd_dmapp_init(struct rsnd_dai_stream *io,
362 403
363 dmac->dmapp_num++; 404 dmac->dmapp_num++;
364 405
365 rsnd_dmapp_stop(io, dma);
366
367 dev_dbg(dev, "id/src/dst/chcr = %d/%pad/%pad/%08x\n", 406 dev_dbg(dev, "id/src/dst/chcr = %d/%pad/%pad/%08x\n",
368 dmapp->dmapp_id, &dma->src_addr, &dma->dst_addr, dmapp->chcr); 407 dmapp->dmapp_id, &dma->src_addr, &dma->dst_addr, dmapp->chcr);
369 408
370 return 0; 409 return 0;
371} 410}
372 411
373static struct rsnd_dma_ops rsnd_dmapp_ops = { 412static struct rsnd_mod_ops rsnd_dmapp_ops = {
374 .name = "audmac-pp", 413 .name = "audmac-pp",
375 .start = rsnd_dmapp_start, 414 .start = rsnd_dmapp_start,
376 .stop = rsnd_dmapp_stop, 415 .stop = rsnd_dmapp_stop,
377 .init = rsnd_dmapp_init,
378 .quit = rsnd_dmapp_stop, 416 .quit = rsnd_dmapp_stop,
379}; 417};
380 418
@@ -497,13 +535,12 @@ static dma_addr_t rsnd_dma_addr(struct rsnd_dai_stream *io,
497} 535}
498 536
499#define MOD_MAX (RSND_MOD_MAX + 1) /* +Memory */ 537#define MOD_MAX (RSND_MOD_MAX + 1) /* +Memory */
500static void rsnd_dma_of_path(struct rsnd_dma *dma, 538static void rsnd_dma_of_path(struct rsnd_mod *this,
501 struct rsnd_dai_stream *io, 539 struct rsnd_dai_stream *io,
502 int is_play, 540 int is_play,
503 struct rsnd_mod **mod_from, 541 struct rsnd_mod **mod_from,
504 struct rsnd_mod **mod_to) 542 struct rsnd_mod **mod_to)
505{ 543{
506 struct rsnd_mod *this = rsnd_dma_to_mod(dma);
507 struct rsnd_mod *ssi = rsnd_io_to_mod_ssi(io); 544 struct rsnd_mod *ssi = rsnd_io_to_mod_ssi(io);
508 struct rsnd_mod *src = rsnd_io_to_mod_src(io); 545 struct rsnd_mod *src = rsnd_io_to_mod_src(io);
509 struct rsnd_mod *ctu = rsnd_io_to_mod_ctu(io); 546 struct rsnd_mod *ctu = rsnd_io_to_mod_ctu(io);
@@ -513,7 +550,7 @@ static void rsnd_dma_of_path(struct rsnd_dma *dma,
513 struct rsnd_mod *mod_start, *mod_end; 550 struct rsnd_mod *mod_start, *mod_end;
514 struct rsnd_priv *priv = rsnd_mod_to_priv(this); 551 struct rsnd_priv *priv = rsnd_mod_to_priv(this);
515 struct device *dev = rsnd_priv_to_dev(priv); 552 struct device *dev = rsnd_priv_to_dev(priv);
516 int nr, i; 553 int nr, i, idx;
517 554
518 if (!ssi) 555 if (!ssi)
519 return; 556 return;
@@ -542,23 +579,24 @@ static void rsnd_dma_of_path(struct rsnd_dma *dma,
542 mod_start = (is_play) ? NULL : ssi; 579 mod_start = (is_play) ? NULL : ssi;
543 mod_end = (is_play) ? ssi : NULL; 580 mod_end = (is_play) ? ssi : NULL;
544 581
545 mod[0] = mod_start; 582 idx = 0;
583 mod[idx++] = mod_start;
546 for (i = 1; i < nr; i++) { 584 for (i = 1; i < nr; i++) {
547 if (src) { 585 if (src) {
548 mod[i] = src; 586 mod[idx++] = src;
549 src = NULL; 587 src = NULL;
550 } else if (ctu) { 588 } else if (ctu) {
551 mod[i] = ctu; 589 mod[idx++] = ctu;
552 ctu = NULL; 590 ctu = NULL;
553 } else if (mix) { 591 } else if (mix) {
554 mod[i] = mix; 592 mod[idx++] = mix;
555 mix = NULL; 593 mix = NULL;
556 } else if (dvc) { 594 } else if (dvc) {
557 mod[i] = dvc; 595 mod[idx++] = dvc;
558 dvc = NULL; 596 dvc = NULL;
559 } 597 }
560 } 598 }
561 mod[i] = mod_end; 599 mod[idx] = mod_end;
562 600
563 /* 601 /*
564 * | SSI | SRC | 602 * | SSI | SRC |
@@ -567,8 +605,8 @@ static void rsnd_dma_of_path(struct rsnd_dma *dma,
567 * !is_play | * | o | 605 * !is_play | * | o |
568 */ 606 */
569 if ((this == ssi) == (is_play)) { 607 if ((this == ssi) == (is_play)) {
570 *mod_from = mod[nr - 1]; 608 *mod_from = mod[idx - 1];
571 *mod_to = mod[nr]; 609 *mod_to = mod[idx];
572 } else { 610 } else {
573 *mod_from = mod[0]; 611 *mod_from = mod[0];
574 *mod_to = mod[1]; 612 *mod_to = mod[1];
@@ -576,7 +614,7 @@ static void rsnd_dma_of_path(struct rsnd_dma *dma,
576 614
577 dev_dbg(dev, "module connection (this is %s[%d])\n", 615 dev_dbg(dev, "module connection (this is %s[%d])\n",
578 rsnd_mod_name(this), rsnd_mod_id(this)); 616 rsnd_mod_name(this), rsnd_mod_id(this));
579 for (i = 0; i <= nr; i++) { 617 for (i = 0; i <= idx; i++) {
580 dev_dbg(dev, " %s[%d]%s\n", 618 dev_dbg(dev, " %s[%d]%s\n",
581 rsnd_mod_name(mod[i]), rsnd_mod_id(mod[i]), 619 rsnd_mod_name(mod[i]), rsnd_mod_id(mod[i]),
582 (mod[i] == *mod_from) ? " from" : 620 (mod[i] == *mod_from) ? " from" :
@@ -584,36 +622,22 @@ static void rsnd_dma_of_path(struct rsnd_dma *dma,
584 } 622 }
585} 623}
586 624
587void rsnd_dma_stop(struct rsnd_dai_stream *io, struct rsnd_dma *dma) 625struct rsnd_mod *rsnd_dma_attach(struct rsnd_dai_stream *io,
588{ 626 struct rsnd_mod *mod, int id)
589 dma->ops->stop(io, dma);
590}
591
592void rsnd_dma_start(struct rsnd_dai_stream *io, struct rsnd_dma *dma)
593{
594 dma->ops->start(io, dma);
595}
596
597void rsnd_dma_quit(struct rsnd_dai_stream *io, struct rsnd_dma *dma)
598{
599 struct rsnd_mod *mod = rsnd_dma_to_mod(dma);
600 struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
601 struct rsnd_dma_ctrl *dmac = rsnd_priv_to_dmac(priv);
602
603 if (!dmac)
604 return;
605
606 dma->ops->quit(io, dma);
607}
608
609int rsnd_dma_init(struct rsnd_dai_stream *io, struct rsnd_dma *dma, int id)
610{ 627{
628 struct rsnd_mod *dma_mod;
611 struct rsnd_mod *mod_from = NULL; 629 struct rsnd_mod *mod_from = NULL;
612 struct rsnd_mod *mod_to = NULL; 630 struct rsnd_mod *mod_to = NULL;
613 struct rsnd_priv *priv = rsnd_io_to_priv(io); 631 struct rsnd_priv *priv = rsnd_io_to_priv(io);
614 struct rsnd_dma_ctrl *dmac = rsnd_priv_to_dmac(priv); 632 struct rsnd_dma_ctrl *dmac = rsnd_priv_to_dmac(priv);
633 struct rsnd_dma *dma;
615 struct device *dev = rsnd_priv_to_dev(priv); 634 struct device *dev = rsnd_priv_to_dev(priv);
635 struct rsnd_mod_ops *ops;
636 enum rsnd_mod_type type;
637 int (*attach)(struct rsnd_dai_stream *io, struct rsnd_dma *dma, int id,
638 struct rsnd_mod *mod_from, struct rsnd_mod *mod_to);
616 int is_play = rsnd_io_is_play(io); 639 int is_play = rsnd_io_is_play(io);
640 int ret, dma_id;
617 641
618 /* 642 /*
619 * DMA failed. try to PIO mode 643 * DMA failed. try to PIO mode
@@ -622,35 +646,64 @@ int rsnd_dma_init(struct rsnd_dai_stream *io, struct rsnd_dma *dma, int id)
622 * rsnd_rdai_continuance_probe() 646 * rsnd_rdai_continuance_probe()
623 */ 647 */
624 if (!dmac) 648 if (!dmac)
625 return -EAGAIN; 649 return ERR_PTR(-EAGAIN);
626 650
627 rsnd_dma_of_path(dma, io, is_play, &mod_from, &mod_to); 651 dma = devm_kzalloc(dev, sizeof(*dma), GFP_KERNEL);
652 if (!dma)
653 return ERR_PTR(-ENOMEM);
654
655 rsnd_dma_of_path(mod, io, is_play, &mod_from, &mod_to);
628 656
629 dma->src_addr = rsnd_dma_addr(io, mod_from, is_play, 1); 657 dma->src_addr = rsnd_dma_addr(io, mod_from, is_play, 1);
630 dma->dst_addr = rsnd_dma_addr(io, mod_to, is_play, 0); 658 dma->dst_addr = rsnd_dma_addr(io, mod_to, is_play, 0);
631 659
632 /* for Gen2 */ 660 /* for Gen2 */
633 if (mod_from && mod_to) 661 if (mod_from && mod_to) {
634 dma->ops = &rsnd_dmapp_ops; 662 ops = &rsnd_dmapp_ops;
635 else 663 attach = rsnd_dmapp_attach;
636 dma->ops = &rsnd_dmaen_ops; 664 dma_id = dmac->dmapp_num;
665 type = RSND_MOD_AUDMAPP;
666 } else {
667 ops = &rsnd_dmaen_ops;
668 attach = rsnd_dmaen_attach;
669 dma_id = dmac->dmaen_num;
670 type = RSND_MOD_AUDMA;
671 }
637 672
638 /* for Gen1, overwrite */ 673 /* for Gen1, overwrite */
639 if (rsnd_is_gen1(priv)) 674 if (rsnd_is_gen1(priv)) {
640 dma->ops = &rsnd_dmaen_ops; 675 ops = &rsnd_dmaen_ops;
676 attach = rsnd_dmaen_attach;
677 dma_id = dmac->dmaen_num;
678 type = RSND_MOD_AUDMA;
679 }
680
681 dma_mod = rsnd_mod_get(dma);
682
683 ret = rsnd_mod_init(priv, dma_mod,
684 ops, NULL, type, dma_id);
685 if (ret < 0)
686 return ERR_PTR(ret);
641 687
642 dev_dbg(dev, "%s %s[%d] -> %s[%d]\n", 688 dev_dbg(dev, "%s[%d] %s[%d] -> %s[%d]\n",
643 dma->ops->name, 689 rsnd_mod_name(dma_mod), rsnd_mod_id(dma_mod),
644 rsnd_mod_name(mod_from), rsnd_mod_id(mod_from), 690 rsnd_mod_name(mod_from), rsnd_mod_id(mod_from),
645 rsnd_mod_name(mod_to), rsnd_mod_id(mod_to)); 691 rsnd_mod_name(mod_to), rsnd_mod_id(mod_to));
646 692
647 return dma->ops->init(io, dma, id, mod_from, mod_to); 693 ret = attach(io, dma, id, mod_from, mod_to);
694 if (ret < 0)
695 return ERR_PTR(ret);
696
697 ret = rsnd_dai_connect(dma_mod, io, type);
698 if (ret < 0)
699 return ERR_PTR(ret);
700
701 return rsnd_mod_get(dma);
648} 702}
649 703
650int rsnd_dma_probe(struct platform_device *pdev, 704int rsnd_dma_probe(struct rsnd_priv *priv)
651 const struct rsnd_of_data *of_data,
652 struct rsnd_priv *priv)
653{ 705{
706 struct platform_device *pdev = rsnd_priv_to_pdev(priv);
654 struct device *dev = rsnd_priv_to_dev(priv); 707 struct device *dev = rsnd_priv_to_dev(priv);
655 struct rsnd_dma_ctrl *dmac; 708 struct rsnd_dma_ctrl *dmac;
656 struct resource *res; 709 struct resource *res;
diff --git a/sound/soc/sh/rcar/dvc.c b/sound/soc/sh/rcar/dvc.c
index 58f690900e6d..d45ffe496397 100644
--- a/sound/soc/sh/rcar/dvc.c
+++ b/sound/soc/sh/rcar/dvc.c
@@ -15,7 +15,6 @@
15#define DVC_NAME "dvc" 15#define DVC_NAME "dvc"
16 16
17struct rsnd_dvc { 17struct rsnd_dvc {
18 struct rsnd_dvc_platform_info *info; /* rcar_snd.h */
19 struct rsnd_mod mod; 18 struct rsnd_mod mod;
20 struct rsnd_kctrl_cfg_m volume; 19 struct rsnd_kctrl_cfg_m volume;
21 struct rsnd_kctrl_cfg_m mute; 20 struct rsnd_kctrl_cfg_m mute;
@@ -24,6 +23,7 @@ struct rsnd_dvc {
24 struct rsnd_kctrl_cfg_s rdown; /* Ramp Rate Down */ 23 struct rsnd_kctrl_cfg_s rdown; /* Ramp Rate Down */
25}; 24};
26 25
26#define rsnd_dvc_get(priv, id) ((struct rsnd_dvc *)(priv->dvc) + id)
27#define rsnd_dvc_nr(priv) ((priv)->dvc_nr) 27#define rsnd_dvc_nr(priv) ((priv)->dvc_nr)
28#define rsnd_dvc_of_node(priv) \ 28#define rsnd_dvc_of_node(priv) \
29 of_get_child_by_name(rsnd_priv_to_dev(priv)->of_node, "rcar_sound,dvc") 29 of_get_child_by_name(rsnd_priv_to_dev(priv)->of_node, "rcar_sound,dvc")
@@ -64,79 +64,142 @@ static const char * const dvc_ramp_rate[] = {
64 "0.125 dB/8192 steps", /* 10111 */ 64 "0.125 dB/8192 steps", /* 10111 */
65}; 65};
66 66
67static void rsnd_dvc_soft_reset(struct rsnd_mod *mod) 67static void rsnd_dvc_activation(struct rsnd_mod *mod)
68{ 68{
69 rsnd_mod_write(mod, DVC_SWRSR, 0); 69 rsnd_mod_write(mod, DVC_SWRSR, 0);
70 rsnd_mod_write(mod, DVC_SWRSR, 1); 70 rsnd_mod_write(mod, DVC_SWRSR, 1);
71} 71}
72 72
73#define rsnd_dvc_initialize_lock(mod) __rsnd_dvc_initialize_lock(mod, 1) 73static void rsnd_dvc_halt(struct rsnd_mod *mod)
74#define rsnd_dvc_initialize_unlock(mod) __rsnd_dvc_initialize_lock(mod, 0)
75static void __rsnd_dvc_initialize_lock(struct rsnd_mod *mod, u32 enable)
76{ 74{
77 rsnd_mod_write(mod, DVC_DVUIR, enable); 75 rsnd_mod_write(mod, DVC_DVUIR, 1);
76 rsnd_mod_write(mod, DVC_SWRSR, 0);
78} 77}
79 78
80static void rsnd_dvc_volume_update(struct rsnd_dai_stream *io, 79#define rsnd_dvc_get_vrpdr(dvc) (dvc->rup.val << 8 | dvc->rdown.val)
81 struct rsnd_mod *mod) 80#define rsnd_dvc_get_vrdbr(dvc) (0x3ff - (dvc->volume.val[0] >> 13))
81
82static void rsnd_dvc_volume_parameter(struct rsnd_dai_stream *io,
83 struct rsnd_mod *mod)
82{ 84{
83 struct rsnd_dvc *dvc = rsnd_mod_to_dvc(mod); 85 struct rsnd_dvc *dvc = rsnd_mod_to_dvc(mod);
84 u32 val[RSND_DVC_CHANNELS]; 86 u32 val[RSND_DVC_CHANNELS];
85 u32 dvucr = 0;
86 u32 mute = 0;
87 int i; 87 int i;
88 88
89 for (i = 0; i < dvc->mute.cfg.size; i++) 89 /* Enable Ramp */
90 mute |= (!!dvc->mute.cfg.val[i]) << i; 90 if (dvc->ren.val)
91 for (i = 0; i < RSND_DVC_CHANNELS; i++)
92 val[i] = dvc->volume.cfg.max;
93 else
94 for (i = 0; i < RSND_DVC_CHANNELS; i++)
95 val[i] = dvc->volume.val[i];
91 96
92 /* Disable DVC Register access */ 97 /* Enable Digital Volume */
93 rsnd_mod_write(mod, DVC_DVUER, 0); 98 rsnd_mod_write(mod, DVC_VOL0R, val[0]);
99 rsnd_mod_write(mod, DVC_VOL1R, val[1]);
100 rsnd_mod_write(mod, DVC_VOL2R, val[2]);
101 rsnd_mod_write(mod, DVC_VOL3R, val[3]);
102 rsnd_mod_write(mod, DVC_VOL4R, val[4]);
103 rsnd_mod_write(mod, DVC_VOL5R, val[5]);
104 rsnd_mod_write(mod, DVC_VOL6R, val[6]);
105 rsnd_mod_write(mod, DVC_VOL7R, val[7]);
106}
107
108static void rsnd_dvc_volume_init(struct rsnd_dai_stream *io,
109 struct rsnd_mod *mod)
110{
111 struct rsnd_dvc *dvc = rsnd_mod_to_dvc(mod);
112 u32 adinr = 0;
113 u32 dvucr = 0;
114 u32 vrctr = 0;
115 u32 vrpdr = 0;
116 u32 vrdbr = 0;
117
118 adinr = rsnd_get_adinr_bit(mod, io) |
119 rsnd_get_adinr_chan(mod, io);
120
121 /* Enable Digital Volume, Zero Cross Mute Mode */
122 dvucr |= 0x101;
94 123
95 /* Enable Ramp */ 124 /* Enable Ramp */
96 if (dvc->ren.val) { 125 if (dvc->ren.val) {
97 dvucr |= 0x10; 126 dvucr |= 0x10;
98 127
99 /* Digital Volume Max */
100 for (i = 0; i < RSND_DVC_CHANNELS; i++)
101 val[i] = dvc->volume.cfg.max;
102
103 rsnd_mod_write(mod, DVC_VRCTR, 0xff);
104 rsnd_mod_write(mod, DVC_VRPDR, dvc->rup.val << 8 |
105 dvc->rdown.val);
106 /* 128 /*
107 * FIXME !! 129 * FIXME !!
108 * use scale-downed Digital Volume 130 * use scale-downed Digital Volume
109 * as Volume Ramp 131 * as Volume Ramp
110 * 7F FFFF -> 3FF 132 * 7F FFFF -> 3FF
111 */ 133 */
112 rsnd_mod_write(mod, DVC_VRDBR, 134 vrctr = 0xff;
113 0x3ff - (dvc->volume.val[0] >> 13)); 135 vrpdr = rsnd_dvc_get_vrpdr(dvc);
114 136 vrdbr = rsnd_dvc_get_vrdbr(dvc);
115 } else {
116 for (i = 0; i < RSND_DVC_CHANNELS; i++)
117 val[i] = dvc->volume.val[i];
118 } 137 }
119 138
120 /* Enable Digital Volume */ 139 /* Initialize operation */
121 dvucr |= 0x100; 140 rsnd_mod_write(mod, DVC_DVUIR, 1);
122 rsnd_mod_write(mod, DVC_VOL0R, val[0]); 141
123 rsnd_mod_write(mod, DVC_VOL1R, val[1]); 142 /* General Information */
143 rsnd_mod_write(mod, DVC_ADINR, adinr);
144 rsnd_mod_write(mod, DVC_DVUCR, dvucr);
145
146 /* Volume Ramp Parameter */
147 rsnd_mod_write(mod, DVC_VRCTR, vrctr);
148 rsnd_mod_write(mod, DVC_VRPDR, vrpdr);
149 rsnd_mod_write(mod, DVC_VRDBR, vrdbr);
150
151 /* Digital Volume Function Parameter */
152 rsnd_dvc_volume_parameter(io, mod);
153
154 /* cancel operation */
155 rsnd_mod_write(mod, DVC_DVUIR, 0);
156}
157
158static void rsnd_dvc_volume_update(struct rsnd_dai_stream *io,
159 struct rsnd_mod *mod)
160{
161 struct rsnd_dvc *dvc = rsnd_mod_to_dvc(mod);
162 u32 zcmcr = 0;
163 u32 vrpdr = 0;
164 u32 vrdbr = 0;
165 int i;
166
167 for (i = 0; i < dvc->mute.cfg.size; i++)
168 zcmcr |= (!!dvc->mute.cfg.val[i]) << i;
124 169
125 /* Enable Mute */ 170 if (dvc->ren.val) {
126 if (mute) { 171 vrpdr = rsnd_dvc_get_vrpdr(dvc);
127 dvucr |= 0x1; 172 vrdbr = rsnd_dvc_get_vrdbr(dvc);
128 rsnd_mod_write(mod, DVC_ZCMCR, mute);
129 } 173 }
130 174
131 rsnd_mod_write(mod, DVC_DVUCR, dvucr); 175 /* Disable DVC Register access */
176 rsnd_mod_write(mod, DVC_DVUER, 0);
177
178 /* Zero Cross Mute Function */
179 rsnd_mod_write(mod, DVC_ZCMCR, zcmcr);
180
181 /* Volume Ramp Function */
182 rsnd_mod_write(mod, DVC_VRPDR, vrpdr);
183 rsnd_mod_write(mod, DVC_VRDBR, vrdbr);
184 /* add DVC_VRWTR here */
185
186 /* Digital Volume Function Parameter */
187 rsnd_dvc_volume_parameter(io, mod);
132 188
133 /* Enable DVC Register access */ 189 /* Enable DVC Register access */
134 rsnd_mod_write(mod, DVC_DVUER, 1); 190 rsnd_mod_write(mod, DVC_DVUER, 1);
135} 191}
136 192
137static int rsnd_dvc_remove_gen2(struct rsnd_mod *mod, 193static int rsnd_dvc_probe_(struct rsnd_mod *mod,
138 struct rsnd_dai_stream *io, 194 struct rsnd_dai_stream *io,
139 struct rsnd_priv *priv) 195 struct rsnd_priv *priv)
196{
197 return rsnd_cmd_attach(io, rsnd_mod_id(mod));
198}
199
200static int rsnd_dvc_remove_(struct rsnd_mod *mod,
201 struct rsnd_dai_stream *io,
202 struct rsnd_priv *priv)
140{ 203{
141 struct rsnd_dvc *dvc = rsnd_mod_to_dvc(mod); 204 struct rsnd_dvc *dvc = rsnd_mod_to_dvc(mod);
142 205
@@ -155,19 +218,12 @@ static int rsnd_dvc_init(struct rsnd_mod *mod,
155{ 218{
156 rsnd_mod_power_on(mod); 219 rsnd_mod_power_on(mod);
157 220
158 rsnd_dvc_soft_reset(mod); 221 rsnd_dvc_activation(mod);
159
160 rsnd_dvc_initialize_lock(mod);
161
162 rsnd_path_parse(priv, io);
163 222
164 rsnd_mod_write(mod, DVC_ADINR, rsnd_get_adinr_bit(mod, io)); 223 rsnd_dvc_volume_init(io, mod);
165 224
166 /* ch0/ch1 Volume */
167 rsnd_dvc_volume_update(io, mod); 225 rsnd_dvc_volume_update(io, mod);
168 226
169 rsnd_adg_set_cmd_timsel_gen2(mod, io);
170
171 return 0; 227 return 0;
172} 228}
173 229
@@ -175,27 +231,9 @@ static int rsnd_dvc_quit(struct rsnd_mod *mod,
175 struct rsnd_dai_stream *io, 231 struct rsnd_dai_stream *io,
176 struct rsnd_priv *priv) 232 struct rsnd_priv *priv)
177{ 233{
178 rsnd_mod_power_off(mod); 234 rsnd_dvc_halt(mod);
179 235
180 return 0; 236 rsnd_mod_power_off(mod);
181}
182
183static int rsnd_dvc_start(struct rsnd_mod *mod,
184 struct rsnd_dai_stream *io,
185 struct rsnd_priv *priv)
186{
187 rsnd_dvc_initialize_unlock(mod);
188
189 rsnd_mod_write(mod, CMD_CTRL, 0x10);
190
191 return 0;
192}
193
194static int rsnd_dvc_stop(struct rsnd_mod *mod,
195 struct rsnd_dai_stream *io,
196 struct rsnd_priv *priv)
197{
198 rsnd_mod_write(mod, CMD_CTRL, 0);
199 237
200 return 0; 238 return 0;
201} 239}
@@ -206,6 +244,7 @@ static int rsnd_dvc_pcm_new(struct rsnd_mod *mod,
206{ 244{
207 struct rsnd_dvc *dvc = rsnd_mod_to_dvc(mod); 245 struct rsnd_dvc *dvc = rsnd_mod_to_dvc(mod);
208 int is_play = rsnd_io_is_play(io); 246 int is_play = rsnd_io_is_play(io);
247 int slots = rsnd_get_slot(io);
209 int ret; 248 int ret;
210 249
211 /* Volume */ 250 /* Volume */
@@ -213,7 +252,8 @@ static int rsnd_dvc_pcm_new(struct rsnd_mod *mod,
213 is_play ? 252 is_play ?
214 "DVC Out Playback Volume" : "DVC In Capture Volume", 253 "DVC Out Playback Volume" : "DVC In Capture Volume",
215 rsnd_dvc_volume_update, 254 rsnd_dvc_volume_update,
216 &dvc->volume, 0x00800000 - 1); 255 &dvc->volume, slots,
256 0x00800000 - 1);
217 if (ret < 0) 257 if (ret < 0)
218 return ret; 258 return ret;
219 259
@@ -222,7 +262,8 @@ static int rsnd_dvc_pcm_new(struct rsnd_mod *mod,
222 is_play ? 262 is_play ?
223 "DVC Out Mute Switch" : "DVC In Mute Switch", 263 "DVC Out Mute Switch" : "DVC In Mute Switch",
224 rsnd_dvc_volume_update, 264 rsnd_dvc_volume_update,
225 &dvc->mute, 1); 265 &dvc->mute, slots,
266 1);
226 if (ret < 0) 267 if (ret < 0)
227 return ret; 268 return ret;
228 269
@@ -269,11 +310,10 @@ static struct dma_chan *rsnd_dvc_dma_req(struct rsnd_dai_stream *io,
269static struct rsnd_mod_ops rsnd_dvc_ops = { 310static struct rsnd_mod_ops rsnd_dvc_ops = {
270 .name = DVC_NAME, 311 .name = DVC_NAME,
271 .dma_req = rsnd_dvc_dma_req, 312 .dma_req = rsnd_dvc_dma_req,
272 .remove = rsnd_dvc_remove_gen2, 313 .probe = rsnd_dvc_probe_,
314 .remove = rsnd_dvc_remove_,
273 .init = rsnd_dvc_init, 315 .init = rsnd_dvc_init,
274 .quit = rsnd_dvc_quit, 316 .quit = rsnd_dvc_quit,
275 .start = rsnd_dvc_start,
276 .stop = rsnd_dvc_stop,
277 .pcm_new = rsnd_dvc_pcm_new, 317 .pcm_new = rsnd_dvc_pcm_new,
278}; 318};
279 319
@@ -282,50 +322,13 @@ struct rsnd_mod *rsnd_dvc_mod_get(struct rsnd_priv *priv, int id)
282 if (WARN_ON(id < 0 || id >= rsnd_dvc_nr(priv))) 322 if (WARN_ON(id < 0 || id >= rsnd_dvc_nr(priv)))
283 id = 0; 323 id = 0;
284 324
285 return rsnd_mod_get((struct rsnd_dvc *)(priv->dvc) + id); 325 return rsnd_mod_get(rsnd_dvc_get(priv, id));
286} 326}
287 327
288static void rsnd_of_parse_dvc(struct platform_device *pdev, 328int rsnd_dvc_probe(struct rsnd_priv *priv)
289 const struct rsnd_of_data *of_data,
290 struct rsnd_priv *priv)
291{ 329{
292 struct device_node *node; 330 struct device_node *node;
293 struct rsnd_dvc_platform_info *dvc_info; 331 struct device_node *np;
294 struct rcar_snd_info *info = rsnd_priv_to_info(priv);
295 struct device *dev = &pdev->dev;
296 int nr;
297
298 if (!of_data)
299 return;
300
301 node = of_get_child_by_name(dev->of_node, "rcar_sound,dvc");
302 if (!node)
303 return;
304
305 nr = of_get_child_count(node);
306 if (!nr)
307 goto rsnd_of_parse_dvc_end;
308
309 dvc_info = devm_kzalloc(dev,
310 sizeof(struct rsnd_dvc_platform_info) * nr,
311 GFP_KERNEL);
312 if (!dvc_info) {
313 dev_err(dev, "dvc info allocation error\n");
314 goto rsnd_of_parse_dvc_end;
315 }
316
317 info->dvc_info = dvc_info;
318 info->dvc_info_nr = nr;
319
320rsnd_of_parse_dvc_end:
321 of_node_put(node);
322}
323
324int rsnd_dvc_probe(struct platform_device *pdev,
325 const struct rsnd_of_data *of_data,
326 struct rsnd_priv *priv)
327{
328 struct rcar_snd_info *info = rsnd_priv_to_info(priv);
329 struct device *dev = rsnd_priv_to_dev(priv); 332 struct device *dev = rsnd_priv_to_dev(priv);
330 struct rsnd_dvc *dvc; 333 struct rsnd_dvc *dvc;
331 struct clk *clk; 334 struct clk *clk;
@@ -336,40 +339,54 @@ int rsnd_dvc_probe(struct platform_device *pdev,
336 if (rsnd_is_gen1(priv)) 339 if (rsnd_is_gen1(priv))
337 return 0; 340 return 0;
338 341
339 rsnd_of_parse_dvc(pdev, of_data, priv); 342 node = rsnd_dvc_of_node(priv);
343 if (!node)
344 return 0; /* not used is not error */
340 345
341 nr = info->dvc_info_nr; 346 nr = of_get_child_count(node);
342 if (!nr) 347 if (!nr) {
343 return 0; 348 ret = -EINVAL;
349 goto rsnd_dvc_probe_done;
350 }
344 351
345 dvc = devm_kzalloc(dev, sizeof(*dvc) * nr, GFP_KERNEL); 352 dvc = devm_kzalloc(dev, sizeof(*dvc) * nr, GFP_KERNEL);
346 if (!dvc) 353 if (!dvc) {
347 return -ENOMEM; 354 ret = -ENOMEM;
355 goto rsnd_dvc_probe_done;
356 }
348 357
349 priv->dvc_nr = nr; 358 priv->dvc_nr = nr;
350 priv->dvc = dvc; 359 priv->dvc = dvc;
351 360
352 for_each_rsnd_dvc(dvc, priv, i) { 361 i = 0;
362 ret = 0;
363 for_each_child_of_node(node, np) {
364 dvc = rsnd_dvc_get(priv, i);
365
353 snprintf(name, RSND_DVC_NAME_SIZE, "%s.%d", 366 snprintf(name, RSND_DVC_NAME_SIZE, "%s.%d",
354 DVC_NAME, i); 367 DVC_NAME, i);
355 368
356 clk = devm_clk_get(dev, name); 369 clk = devm_clk_get(dev, name);
357 if (IS_ERR(clk)) 370 if (IS_ERR(clk)) {
358 return PTR_ERR(clk); 371 ret = PTR_ERR(clk);
359 372 goto rsnd_dvc_probe_done;
360 dvc->info = &info->dvc_info[i]; 373 }
361 374
362 ret = rsnd_mod_init(priv, rsnd_mod_get(dvc), &rsnd_dvc_ops, 375 ret = rsnd_mod_init(priv, rsnd_mod_get(dvc), &rsnd_dvc_ops,
363 clk, RSND_MOD_DVC, i); 376 clk, RSND_MOD_DVC, i);
364 if (ret) 377 if (ret)
365 return ret; 378 goto rsnd_dvc_probe_done;
379
380 i++;
366 } 381 }
367 382
368 return 0; 383rsnd_dvc_probe_done:
384 of_node_put(node);
385
386 return ret;
369} 387}
370 388
371void rsnd_dvc_remove(struct platform_device *pdev, 389void rsnd_dvc_remove(struct rsnd_priv *priv)
372 struct rsnd_priv *priv)
373{ 390{
374 struct rsnd_dvc *dvc; 391 struct rsnd_dvc *dvc;
375 int i; 392 int i;
diff --git a/sound/soc/sh/rcar/gen.c b/sound/soc/sh/rcar/gen.c
index edcf4cc2e84f..ea24247eba73 100644
--- a/sound/soc/sh/rcar/gen.c
+++ b/sound/soc/sh/rcar/gen.c
@@ -31,29 +31,33 @@ struct rsnd_gen {
31 31
32 /* RSND_REG_MAX base */ 32 /* RSND_REG_MAX base */
33 struct regmap_field *regs[RSND_REG_MAX]; 33 struct regmap_field *regs[RSND_REG_MAX];
34 const char *reg_name[RSND_REG_MAX];
34}; 35};
35 36
36#define rsnd_priv_to_gen(p) ((struct rsnd_gen *)(p)->gen) 37#define rsnd_priv_to_gen(p) ((struct rsnd_gen *)(p)->gen)
38#define rsnd_reg_name(gen, id) ((gen)->reg_name[id])
37 39
38struct rsnd_regmap_field_conf { 40struct rsnd_regmap_field_conf {
39 int idx; 41 int idx;
40 unsigned int reg_offset; 42 unsigned int reg_offset;
41 unsigned int id_offset; 43 unsigned int id_offset;
44 const char *reg_name;
42}; 45};
43 46
44#define RSND_REG_SET(id, offset, _id_offset) \ 47#define RSND_REG_SET(id, offset, _id_offset, n) \
45{ \ 48{ \
46 .idx = id, \ 49 .idx = id, \
47 .reg_offset = offset, \ 50 .reg_offset = offset, \
48 .id_offset = _id_offset, \ 51 .id_offset = _id_offset, \
52 .reg_name = n, \
49} 53}
50/* single address mapping */ 54/* single address mapping */
51#define RSND_GEN_S_REG(id, offset) \ 55#define RSND_GEN_S_REG(id, offset) \
52 RSND_REG_SET(RSND_REG_##id, offset, 0) 56 RSND_REG_SET(RSND_REG_##id, offset, 0, #id)
53 57
54/* multi address mapping */ 58/* multi address mapping */
55#define RSND_GEN_M_REG(id, offset, _id_offset) \ 59#define RSND_GEN_M_REG(id, offset, _id_offset) \
56 RSND_REG_SET(RSND_REG_##id, offset, _id_offset) 60 RSND_REG_SET(RSND_REG_##id, offset, _id_offset, #id)
57 61
58/* 62/*
59 * basic function 63 * basic function
@@ -83,8 +87,9 @@ u32 rsnd_read(struct rsnd_priv *priv,
83 87
84 regmap_fields_read(gen->regs[reg], rsnd_mod_id(mod), &val); 88 regmap_fields_read(gen->regs[reg], rsnd_mod_id(mod), &val);
85 89
86 dev_dbg(dev, "r %s[%d] - %4d : %08x\n", 90 dev_dbg(dev, "r %s[%d] - %-18s (%4d) : %08x\n",
87 rsnd_mod_name(mod), rsnd_mod_id(mod), reg, val); 91 rsnd_mod_name(mod), rsnd_mod_id(mod),
92 rsnd_reg_name(gen, reg), reg, val);
88 93
89 return val; 94 return val;
90} 95}
@@ -99,10 +104,11 @@ void rsnd_write(struct rsnd_priv *priv,
99 if (!rsnd_is_accessible_reg(priv, gen, reg)) 104 if (!rsnd_is_accessible_reg(priv, gen, reg))
100 return; 105 return;
101 106
102 dev_dbg(dev, "w %s[%d] - %4d : %08x\n",
103 rsnd_mod_name(mod), rsnd_mod_id(mod), reg, data);
104
105 regmap_fields_write(gen->regs[reg], rsnd_mod_id(mod), data); 107 regmap_fields_write(gen->regs[reg], rsnd_mod_id(mod), data);
108
109 dev_dbg(dev, "w %s[%d] - %-18s (%4d) : %08x\n",
110 rsnd_mod_name(mod), rsnd_mod_id(mod),
111 rsnd_reg_name(gen, reg), reg, data);
106} 112}
107 113
108void rsnd_force_write(struct rsnd_priv *priv, 114void rsnd_force_write(struct rsnd_priv *priv,
@@ -115,10 +121,11 @@ void rsnd_force_write(struct rsnd_priv *priv,
115 if (!rsnd_is_accessible_reg(priv, gen, reg)) 121 if (!rsnd_is_accessible_reg(priv, gen, reg))
116 return; 122 return;
117 123
118 dev_dbg(dev, "w %s[%d] - %4d : %08x\n",
119 rsnd_mod_name(mod), rsnd_mod_id(mod), reg, data);
120
121 regmap_fields_force_write(gen->regs[reg], rsnd_mod_id(mod), data); 124 regmap_fields_force_write(gen->regs[reg], rsnd_mod_id(mod), data);
125
126 dev_dbg(dev, "w %s[%d] - %-18s (%4d) : %08x\n",
127 rsnd_mod_name(mod), rsnd_mod_id(mod),
128 rsnd_reg_name(gen, reg), reg, data);
122} 129}
123 130
124void rsnd_bset(struct rsnd_priv *priv, struct rsnd_mod *mod, 131void rsnd_bset(struct rsnd_priv *priv, struct rsnd_mod *mod,
@@ -130,11 +137,13 @@ void rsnd_bset(struct rsnd_priv *priv, struct rsnd_mod *mod,
130 if (!rsnd_is_accessible_reg(priv, gen, reg)) 137 if (!rsnd_is_accessible_reg(priv, gen, reg))
131 return; 138 return;
132 139
133 dev_dbg(dev, "b %s[%d] - %4d : %08x/%08x\n",
134 rsnd_mod_name(mod), rsnd_mod_id(mod), reg, data, mask);
135
136 regmap_fields_update_bits(gen->regs[reg], rsnd_mod_id(mod), 140 regmap_fields_update_bits(gen->regs[reg], rsnd_mod_id(mod),
137 mask, data); 141 mask, data);
142
143 dev_dbg(dev, "b %s[%d] - %-18s (%4d) : %08x/%08x\n",
144 rsnd_mod_name(mod), rsnd_mod_id(mod),
145 rsnd_reg_name(gen, reg), reg, data, mask);
146
138} 147}
139 148
140phys_addr_t rsnd_gen_get_phy_addr(struct rsnd_priv *priv, int reg_id) 149phys_addr_t rsnd_gen_get_phy_addr(struct rsnd_priv *priv, int reg_id)
@@ -150,7 +159,7 @@ static int _rsnd_gen_regmap_init(struct rsnd_priv *priv,
150 int id_size, 159 int id_size,
151 int reg_id, 160 int reg_id,
152 const char *name, 161 const char *name,
153 struct rsnd_regmap_field_conf *conf, 162 const struct rsnd_regmap_field_conf *conf,
154 int conf_size) 163 int conf_size)
155{ 164{
156 struct platform_device *pdev = rsnd_priv_to_pdev(priv); 165 struct platform_device *pdev = rsnd_priv_to_pdev(priv);
@@ -203,6 +212,7 @@ static int _rsnd_gen_regmap_init(struct rsnd_priv *priv,
203 212
204 /* RSND_REG_MAX base */ 213 /* RSND_REG_MAX base */
205 gen->regs[conf[i].idx] = regs; 214 gen->regs[conf[i].idx] = regs;
215 gen->reg_name[conf[i].idx] = conf[i].reg_name;
206 } 216 }
207 217
208 return 0; 218 return 0;
@@ -211,25 +221,31 @@ static int _rsnd_gen_regmap_init(struct rsnd_priv *priv,
211/* 221/*
212 * Gen2 222 * Gen2
213 */ 223 */
214static int rsnd_gen2_probe(struct platform_device *pdev, 224static int rsnd_gen2_probe(struct rsnd_priv *priv)
215 struct rsnd_priv *priv)
216{ 225{
217 struct rsnd_regmap_field_conf conf_ssiu[] = { 226 const static struct rsnd_regmap_field_conf conf_ssiu[] = {
218 RSND_GEN_S_REG(SSI_MODE0, 0x800), 227 RSND_GEN_S_REG(SSI_MODE0, 0x800),
219 RSND_GEN_S_REG(SSI_MODE1, 0x804), 228 RSND_GEN_S_REG(SSI_MODE1, 0x804),
229 RSND_GEN_S_REG(SSI_MODE2, 0x808),
230 RSND_GEN_S_REG(SSI_CONTROL, 0x810),
231
220 /* FIXME: it needs SSI_MODE2/3 in the future */ 232 /* FIXME: it needs SSI_MODE2/3 in the future */
221 RSND_GEN_M_REG(SSI_BUSIF_MODE, 0x0, 0x80), 233 RSND_GEN_M_REG(SSI_BUSIF_MODE, 0x0, 0x80),
222 RSND_GEN_M_REG(SSI_BUSIF_ADINR, 0x4, 0x80), 234 RSND_GEN_M_REG(SSI_BUSIF_ADINR, 0x4, 0x80),
223 RSND_GEN_M_REG(SSI_BUSIF_DALIGN,0x8, 0x80), 235 RSND_GEN_M_REG(SSI_BUSIF_DALIGN,0x8, 0x80),
236 RSND_GEN_M_REG(SSI_MODE, 0xc, 0x80),
224 RSND_GEN_M_REG(SSI_CTRL, 0x10, 0x80), 237 RSND_GEN_M_REG(SSI_CTRL, 0x10, 0x80),
225 RSND_GEN_M_REG(SSI_INT_ENABLE, 0x18, 0x80), 238 RSND_GEN_M_REG(SSI_INT_ENABLE, 0x18, 0x80),
226 }; 239 };
227 struct rsnd_regmap_field_conf conf_scu[] = { 240
228 RSND_GEN_M_REG(SRC_BUSIF_MODE, 0x0, 0x20), 241 const static struct rsnd_regmap_field_conf conf_scu[] = {
242 RSND_GEN_M_REG(SRC_I_BUSIF_MODE,0x0, 0x20),
243 RSND_GEN_M_REG(SRC_O_BUSIF_MODE,0x4, 0x20),
229 RSND_GEN_M_REG(SRC_BUSIF_DALIGN,0x8, 0x20), 244 RSND_GEN_M_REG(SRC_BUSIF_DALIGN,0x8, 0x20),
230 RSND_GEN_M_REG(SRC_ROUTE_MODE0, 0xc, 0x20), 245 RSND_GEN_M_REG(SRC_ROUTE_MODE0, 0xc, 0x20),
231 RSND_GEN_M_REG(SRC_CTRL, 0x10, 0x20), 246 RSND_GEN_M_REG(SRC_CTRL, 0x10, 0x20),
232 RSND_GEN_M_REG(SRC_INT_ENABLE0, 0x18, 0x20), 247 RSND_GEN_M_REG(SRC_INT_ENABLE0, 0x18, 0x20),
248 RSND_GEN_M_REG(CMD_BUSIF_DALIGN,0x188, 0x20),
233 RSND_GEN_M_REG(CMD_ROUTE_SLCT, 0x18c, 0x20), 249 RSND_GEN_M_REG(CMD_ROUTE_SLCT, 0x18c, 0x20),
234 RSND_GEN_M_REG(CMD_CTRL, 0x190, 0x20), 250 RSND_GEN_M_REG(CMD_CTRL, 0x190, 0x20),
235 RSND_GEN_S_REG(SCU_SYS_STATUS0, 0x1c8), 251 RSND_GEN_S_REG(SCU_SYS_STATUS0, 0x1c8),
@@ -266,9 +282,15 @@ static int rsnd_gen2_probe(struct platform_device *pdev,
266 RSND_GEN_M_REG(DVC_VRDBR, 0xe20, 0x100), 282 RSND_GEN_M_REG(DVC_VRDBR, 0xe20, 0x100),
267 RSND_GEN_M_REG(DVC_VOL0R, 0xe28, 0x100), 283 RSND_GEN_M_REG(DVC_VOL0R, 0xe28, 0x100),
268 RSND_GEN_M_REG(DVC_VOL1R, 0xe2c, 0x100), 284 RSND_GEN_M_REG(DVC_VOL1R, 0xe2c, 0x100),
285 RSND_GEN_M_REG(DVC_VOL2R, 0xe30, 0x100),
286 RSND_GEN_M_REG(DVC_VOL3R, 0xe34, 0x100),
287 RSND_GEN_M_REG(DVC_VOL4R, 0xe38, 0x100),
288 RSND_GEN_M_REG(DVC_VOL5R, 0xe3c, 0x100),
289 RSND_GEN_M_REG(DVC_VOL6R, 0xe40, 0x100),
290 RSND_GEN_M_REG(DVC_VOL7R, 0xe44, 0x100),
269 RSND_GEN_M_REG(DVC_DVUER, 0xe48, 0x100), 291 RSND_GEN_M_REG(DVC_DVUER, 0xe48, 0x100),
270 }; 292 };
271 struct rsnd_regmap_field_conf conf_adg[] = { 293 const static struct rsnd_regmap_field_conf conf_adg[] = {
272 RSND_GEN_S_REG(BRRA, 0x00), 294 RSND_GEN_S_REG(BRRA, 0x00),
273 RSND_GEN_S_REG(BRRB, 0x04), 295 RSND_GEN_S_REG(BRRB, 0x04),
274 RSND_GEN_S_REG(SSICKR, 0x08), 296 RSND_GEN_S_REG(SSICKR, 0x08),
@@ -288,7 +310,7 @@ static int rsnd_gen2_probe(struct platform_device *pdev,
288 RSND_GEN_S_REG(SRCOUT_TIMSEL4, 0x58), 310 RSND_GEN_S_REG(SRCOUT_TIMSEL4, 0x58),
289 RSND_GEN_S_REG(CMDOUT_TIMSEL, 0x5c), 311 RSND_GEN_S_REG(CMDOUT_TIMSEL, 0x5c),
290 }; 312 };
291 struct rsnd_regmap_field_conf conf_ssi[] = { 313 const static struct rsnd_regmap_field_conf conf_ssi[] = {
292 RSND_GEN_M_REG(SSICR, 0x00, 0x40), 314 RSND_GEN_M_REG(SSICR, 0x00, 0x40),
293 RSND_GEN_M_REG(SSISR, 0x04, 0x40), 315 RSND_GEN_M_REG(SSISR, 0x04, 0x40),
294 RSND_GEN_M_REG(SSITDR, 0x08, 0x40), 316 RSND_GEN_M_REG(SSITDR, 0x08, 0x40),
@@ -317,65 +339,30 @@ static int rsnd_gen2_probe(struct platform_device *pdev,
317 * Gen1 339 * Gen1
318 */ 340 */
319 341
320static int rsnd_gen1_probe(struct platform_device *pdev, 342static int rsnd_gen1_probe(struct rsnd_priv *priv)
321 struct rsnd_priv *priv)
322{ 343{
323 struct rsnd_regmap_field_conf conf_sru[] = { 344 const static struct rsnd_regmap_field_conf conf_adg[] = {
324 RSND_GEN_S_REG(SRC_ROUTE_SEL, 0x00),
325 RSND_GEN_S_REG(SRC_TMG_SEL0, 0x08),
326 RSND_GEN_S_REG(SRC_TMG_SEL1, 0x0c),
327 RSND_GEN_S_REG(SRC_TMG_SEL2, 0x10),
328 RSND_GEN_S_REG(SRC_ROUTE_CTRL, 0xc0),
329 RSND_GEN_S_REG(SSI_MODE0, 0xD0),
330 RSND_GEN_S_REG(SSI_MODE1, 0xD4),
331 RSND_GEN_M_REG(SRC_BUSIF_MODE, 0x20, 0x4),
332 RSND_GEN_M_REG(SRC_ROUTE_MODE0, 0x50, 0x8),
333 RSND_GEN_M_REG(SRC_SWRSR, 0x200, 0x40),
334 RSND_GEN_M_REG(SRC_SRCIR, 0x204, 0x40),
335 RSND_GEN_M_REG(SRC_ADINR, 0x214, 0x40),
336 RSND_GEN_M_REG(SRC_IFSCR, 0x21c, 0x40),
337 RSND_GEN_M_REG(SRC_IFSVR, 0x220, 0x40),
338 RSND_GEN_M_REG(SRC_SRCCR, 0x224, 0x40),
339 RSND_GEN_M_REG(SRC_MNFSR, 0x228, 0x40),
340 /*
341 * ADD US
342 *
343 * SRC_STATUS
344 * SRC_INT_EN
345 * SCU_SYS_STATUS0
346 * SCU_SYS_STATUS1
347 * SCU_SYS_INT_EN0
348 * SCU_SYS_INT_EN1
349 */
350 };
351 struct rsnd_regmap_field_conf conf_adg[] = {
352 RSND_GEN_S_REG(BRRA, 0x00), 345 RSND_GEN_S_REG(BRRA, 0x00),
353 RSND_GEN_S_REG(BRRB, 0x04), 346 RSND_GEN_S_REG(BRRB, 0x04),
354 RSND_GEN_S_REG(SSICKR, 0x08), 347 RSND_GEN_S_REG(SSICKR, 0x08),
355 RSND_GEN_S_REG(AUDIO_CLK_SEL0, 0x0c), 348 RSND_GEN_S_REG(AUDIO_CLK_SEL0, 0x0c),
356 RSND_GEN_S_REG(AUDIO_CLK_SEL1, 0x10), 349 RSND_GEN_S_REG(AUDIO_CLK_SEL1, 0x10),
357 RSND_GEN_S_REG(AUDIO_CLK_SEL3, 0x18),
358 RSND_GEN_S_REG(AUDIO_CLK_SEL4, 0x1c),
359 RSND_GEN_S_REG(AUDIO_CLK_SEL5, 0x20),
360 }; 350 };
361 struct rsnd_regmap_field_conf conf_ssi[] = { 351 const static struct rsnd_regmap_field_conf conf_ssi[] = {
362 RSND_GEN_M_REG(SSICR, 0x00, 0x40), 352 RSND_GEN_M_REG(SSICR, 0x00, 0x40),
363 RSND_GEN_M_REG(SSISR, 0x04, 0x40), 353 RSND_GEN_M_REG(SSISR, 0x04, 0x40),
364 RSND_GEN_M_REG(SSITDR, 0x08, 0x40), 354 RSND_GEN_M_REG(SSITDR, 0x08, 0x40),
365 RSND_GEN_M_REG(SSIRDR, 0x0c, 0x40), 355 RSND_GEN_M_REG(SSIRDR, 0x0c, 0x40),
366 RSND_GEN_M_REG(SSIWSR, 0x20, 0x40), 356 RSND_GEN_M_REG(SSIWSR, 0x20, 0x40),
367 }; 357 };
368 int ret_sru;
369 int ret_adg; 358 int ret_adg;
370 int ret_ssi; 359 int ret_ssi;
371 360
372 ret_sru = rsnd_gen_regmap_init(priv, 9, RSND_GEN1_SRU, "sru", conf_sru);
373 ret_adg = rsnd_gen_regmap_init(priv, 9, RSND_GEN1_ADG, "adg", conf_adg); 361 ret_adg = rsnd_gen_regmap_init(priv, 9, RSND_GEN1_ADG, "adg", conf_adg);
374 ret_ssi = rsnd_gen_regmap_init(priv, 9, RSND_GEN1_SSI, "ssi", conf_ssi); 362 ret_ssi = rsnd_gen_regmap_init(priv, 9, RSND_GEN1_SSI, "ssi", conf_ssi);
375 if (ret_sru < 0 || 363 if (ret_adg < 0 ||
376 ret_adg < 0 ||
377 ret_ssi < 0) 364 ret_ssi < 0)
378 return ret_sru | ret_adg | ret_ssi; 365 return ret_adg | ret_ssi;
379 366
380 return 0; 367 return 0;
381} 368}
@@ -383,28 +370,12 @@ static int rsnd_gen1_probe(struct platform_device *pdev,
383/* 370/*
384 * Gen 371 * Gen
385 */ 372 */
386static void rsnd_of_parse_gen(struct platform_device *pdev, 373int rsnd_gen_probe(struct rsnd_priv *priv)
387 const struct rsnd_of_data *of_data,
388 struct rsnd_priv *priv)
389{
390 struct rcar_snd_info *info = priv->info;
391
392 if (!of_data)
393 return;
394
395 info->flags = of_data->flags;
396}
397
398int rsnd_gen_probe(struct platform_device *pdev,
399 const struct rsnd_of_data *of_data,
400 struct rsnd_priv *priv)
401{ 374{
402 struct device *dev = rsnd_priv_to_dev(priv); 375 struct device *dev = rsnd_priv_to_dev(priv);
403 struct rsnd_gen *gen; 376 struct rsnd_gen *gen;
404 int ret; 377 int ret;
405 378
406 rsnd_of_parse_gen(pdev, of_data, priv);
407
408 gen = devm_kzalloc(dev, sizeof(*gen), GFP_KERNEL); 379 gen = devm_kzalloc(dev, sizeof(*gen), GFP_KERNEL);
409 if (!gen) { 380 if (!gen) {
410 dev_err(dev, "GEN allocate failed\n"); 381 dev_err(dev, "GEN allocate failed\n");
@@ -415,9 +386,9 @@ int rsnd_gen_probe(struct platform_device *pdev,
415 386
416 ret = -ENODEV; 387 ret = -ENODEV;
417 if (rsnd_is_gen1(priv)) 388 if (rsnd_is_gen1(priv))
418 ret = rsnd_gen1_probe(pdev, priv); 389 ret = rsnd_gen1_probe(priv);
419 else if (rsnd_is_gen2(priv)) 390 else if (rsnd_is_gen2(priv))
420 ret = rsnd_gen2_probe(pdev, priv); 391 ret = rsnd_gen2_probe(priv);
421 392
422 if (ret < 0) 393 if (ret < 0)
423 dev_err(dev, "unknown generation R-Car sound device\n"); 394 dev_err(dev, "unknown generation R-Car sound device\n");
diff --git a/sound/soc/sh/rcar/mix.c b/sound/soc/sh/rcar/mix.c
index 953dd0be9b60..65542b6a89e9 100644
--- a/sound/soc/sh/rcar/mix.c
+++ b/sound/soc/sh/rcar/mix.c
@@ -13,10 +13,10 @@
13#define MIX_NAME "mix" 13#define MIX_NAME "mix"
14 14
15struct rsnd_mix { 15struct rsnd_mix {
16 struct rsnd_mix_platform_info *info; /* rcar_snd.h */
17 struct rsnd_mod mod; 16 struct rsnd_mod mod;
18}; 17};
19 18
19#define rsnd_mix_get(priv, id) ((struct rsnd_mix *)(priv->mix) + id)
20#define rsnd_mix_nr(priv) ((priv)->mix_nr) 20#define rsnd_mix_nr(priv) ((priv)->mix_nr)
21#define for_each_rsnd_mix(pos, priv, i) \ 21#define for_each_rsnd_mix(pos, priv, i) \
22 for ((i) = 0; \ 22 for ((i) = 0; \
@@ -24,58 +24,77 @@ struct rsnd_mix {
24 ((pos) = (struct rsnd_mix *)(priv)->mix + i); \ 24 ((pos) = (struct rsnd_mix *)(priv)->mix + i); \
25 i++) 25 i++)
26 26
27 27static void rsnd_mix_activation(struct rsnd_mod *mod)
28static void rsnd_mix_soft_reset(struct rsnd_mod *mod)
29{ 28{
30 rsnd_mod_write(mod, MIX_SWRSR, 0); 29 rsnd_mod_write(mod, MIX_SWRSR, 0);
31 rsnd_mod_write(mod, MIX_SWRSR, 1); 30 rsnd_mod_write(mod, MIX_SWRSR, 1);
32} 31}
33 32
34#define rsnd_mix_initialize_lock(mod) __rsnd_mix_initialize_lock(mod, 1) 33static void rsnd_mix_halt(struct rsnd_mod *mod)
35#define rsnd_mix_initialize_unlock(mod) __rsnd_mix_initialize_lock(mod, 0) 34{
36static void __rsnd_mix_initialize_lock(struct rsnd_mod *mod, u32 enable) 35 rsnd_mod_write(mod, MIX_MIXIR, 1);
36 rsnd_mod_write(mod, MIX_SWRSR, 0);
37}
38
39static void rsnd_mix_volume_parameter(struct rsnd_dai_stream *io,
40 struct rsnd_mod *mod)
37{ 41{
38 rsnd_mod_write(mod, MIX_MIXIR, enable); 42 rsnd_mod_write(mod, MIX_MDBAR, 0);
43 rsnd_mod_write(mod, MIX_MDBBR, 0);
44 rsnd_mod_write(mod, MIX_MDBCR, 0);
45 rsnd_mod_write(mod, MIX_MDBDR, 0);
46}
47
48static void rsnd_mix_volume_init(struct rsnd_dai_stream *io,
49 struct rsnd_mod *mod)
50{
51 rsnd_mod_write(mod, MIX_MIXIR, 1);
52
53 /* General Information */
54 rsnd_mod_write(mod, MIX_ADINR, rsnd_get_adinr_chan(mod, io));
55
56 /* volume step */
57 rsnd_mod_write(mod, MIX_MIXMR, 0);
58 rsnd_mod_write(mod, MIX_MVPDR, 0);
59
60 /* common volume parameter */
61 rsnd_mix_volume_parameter(io, mod);
62
63 rsnd_mod_write(mod, MIX_MIXIR, 0);
39} 64}
40 65
41static void rsnd_mix_volume_update(struct rsnd_dai_stream *io, 66static void rsnd_mix_volume_update(struct rsnd_dai_stream *io,
42 struct rsnd_mod *mod) 67 struct rsnd_mod *mod)
43{ 68{
44
45 /* Disable MIX dB setting */ 69 /* Disable MIX dB setting */
46 rsnd_mod_write(mod, MIX_MDBER, 0); 70 rsnd_mod_write(mod, MIX_MDBER, 0);
47 71
48 rsnd_mod_write(mod, MIX_MDBAR, 0); 72 /* common volume parameter */
49 rsnd_mod_write(mod, MIX_MDBBR, 0); 73 rsnd_mix_volume_parameter(io, mod);
50 rsnd_mod_write(mod, MIX_MDBCR, 0);
51 rsnd_mod_write(mod, MIX_MDBDR, 0);
52 74
53 /* Enable MIX dB setting */ 75 /* Enable MIX dB setting */
54 rsnd_mod_write(mod, MIX_MDBER, 1); 76 rsnd_mod_write(mod, MIX_MDBER, 1);
55} 77}
56 78
79static int rsnd_mix_probe_(struct rsnd_mod *mod,
80 struct rsnd_dai_stream *io,
81 struct rsnd_priv *priv)
82{
83 return rsnd_cmd_attach(io, rsnd_mod_id(mod));
84}
85
57static int rsnd_mix_init(struct rsnd_mod *mod, 86static int rsnd_mix_init(struct rsnd_mod *mod,
58 struct rsnd_dai_stream *io, 87 struct rsnd_dai_stream *io,
59 struct rsnd_priv *priv) 88 struct rsnd_priv *priv)
60{ 89{
61 rsnd_mod_power_on(mod); 90 rsnd_mod_power_on(mod);
62 91
63 rsnd_mix_soft_reset(mod); 92 rsnd_mix_activation(mod);
64
65 rsnd_mix_initialize_lock(mod);
66
67 rsnd_mod_write(mod, MIX_ADINR, rsnd_get_adinr_chan(mod, io));
68
69 rsnd_path_parse(priv, io);
70 93
71 /* volume step */ 94 rsnd_mix_volume_init(io, mod);
72 rsnd_mod_write(mod, MIX_MIXMR, 0);
73 rsnd_mod_write(mod, MIX_MVPDR, 0);
74 95
75 rsnd_mix_volume_update(io, mod); 96 rsnd_mix_volume_update(io, mod);
76 97
77 rsnd_mix_initialize_unlock(mod);
78
79 return 0; 98 return 0;
80} 99}
81 100
@@ -83,6 +102,8 @@ static int rsnd_mix_quit(struct rsnd_mod *mod,
83 struct rsnd_dai_stream *io, 102 struct rsnd_dai_stream *io,
84 struct rsnd_priv *priv) 103 struct rsnd_priv *priv)
85{ 104{
105 rsnd_mix_halt(mod);
106
86 rsnd_mod_power_off(mod); 107 rsnd_mod_power_off(mod);
87 108
88 return 0; 109 return 0;
@@ -90,6 +111,7 @@ static int rsnd_mix_quit(struct rsnd_mod *mod,
90 111
91static struct rsnd_mod_ops rsnd_mix_ops = { 112static struct rsnd_mod_ops rsnd_mix_ops = {
92 .name = MIX_NAME, 113 .name = MIX_NAME,
114 .probe = rsnd_mix_probe_,
93 .init = rsnd_mix_init, 115 .init = rsnd_mix_init,
94 .quit = rsnd_mix_quit, 116 .quit = rsnd_mix_quit,
95}; 117};
@@ -99,51 +121,13 @@ struct rsnd_mod *rsnd_mix_mod_get(struct rsnd_priv *priv, int id)
99 if (WARN_ON(id < 0 || id >= rsnd_mix_nr(priv))) 121 if (WARN_ON(id < 0 || id >= rsnd_mix_nr(priv)))
100 id = 0; 122 id = 0;
101 123
102 return rsnd_mod_get((struct rsnd_mix *)(priv->mix) + id); 124 return rsnd_mod_get(rsnd_mix_get(priv, id));
103} 125}
104 126
105static void rsnd_of_parse_mix(struct platform_device *pdev, 127int rsnd_mix_probe(struct rsnd_priv *priv)
106 const struct rsnd_of_data *of_data,
107 struct rsnd_priv *priv)
108{ 128{
109 struct device_node *node; 129 struct device_node *node;
110 struct rsnd_mix_platform_info *mix_info; 130 struct device_node *np;
111 struct rcar_snd_info *info = rsnd_priv_to_info(priv);
112 struct device *dev = &pdev->dev;
113 int nr;
114
115 if (!of_data)
116 return;
117
118 node = of_get_child_by_name(dev->of_node, "rcar_sound,mix");
119 if (!node)
120 return;
121
122 nr = of_get_child_count(node);
123 if (!nr)
124 goto rsnd_of_parse_mix_end;
125
126 mix_info = devm_kzalloc(dev,
127 sizeof(struct rsnd_mix_platform_info) * nr,
128 GFP_KERNEL);
129 if (!mix_info) {
130 dev_err(dev, "mix info allocation error\n");
131 goto rsnd_of_parse_mix_end;
132 }
133
134 info->mix_info = mix_info;
135 info->mix_info_nr = nr;
136
137rsnd_of_parse_mix_end:
138 of_node_put(node);
139
140}
141
142int rsnd_mix_probe(struct platform_device *pdev,
143 const struct rsnd_of_data *of_data,
144 struct rsnd_priv *priv)
145{
146 struct rcar_snd_info *info = rsnd_priv_to_info(priv);
147 struct device *dev = rsnd_priv_to_dev(priv); 131 struct device *dev = rsnd_priv_to_dev(priv);
148 struct rsnd_mix *mix; 132 struct rsnd_mix *mix;
149 struct clk *clk; 133 struct clk *clk;
@@ -154,40 +138,54 @@ int rsnd_mix_probe(struct platform_device *pdev,
154 if (rsnd_is_gen1(priv)) 138 if (rsnd_is_gen1(priv))
155 return 0; 139 return 0;
156 140
157 rsnd_of_parse_mix(pdev, of_data, priv); 141 node = rsnd_mix_of_node(priv);
142 if (!node)
143 return 0; /* not used is not error */
158 144
159 nr = info->mix_info_nr; 145 nr = of_get_child_count(node);
160 if (!nr) 146 if (!nr) {
161 return 0; 147 ret = -EINVAL;
148 goto rsnd_mix_probe_done;
149 }
162 150
163 mix = devm_kzalloc(dev, sizeof(*mix) * nr, GFP_KERNEL); 151 mix = devm_kzalloc(dev, sizeof(*mix) * nr, GFP_KERNEL);
164 if (!mix) 152 if (!mix) {
165 return -ENOMEM; 153 ret = -ENOMEM;
154 goto rsnd_mix_probe_done;
155 }
166 156
167 priv->mix_nr = nr; 157 priv->mix_nr = nr;
168 priv->mix = mix; 158 priv->mix = mix;
169 159
170 for_each_rsnd_mix(mix, priv, i) { 160 i = 0;
161 ret = 0;
162 for_each_child_of_node(node, np) {
163 mix = rsnd_mix_get(priv, i);
164
171 snprintf(name, MIX_NAME_SIZE, "%s.%d", 165 snprintf(name, MIX_NAME_SIZE, "%s.%d",
172 MIX_NAME, i); 166 MIX_NAME, i);
173 167
174 clk = devm_clk_get(dev, name); 168 clk = devm_clk_get(dev, name);
175 if (IS_ERR(clk)) 169 if (IS_ERR(clk)) {
176 return PTR_ERR(clk); 170 ret = PTR_ERR(clk);
177 171 goto rsnd_mix_probe_done;
178 mix->info = &info->mix_info[i]; 172 }
179 173
180 ret = rsnd_mod_init(priv, rsnd_mod_get(mix), &rsnd_mix_ops, 174 ret = rsnd_mod_init(priv, rsnd_mod_get(mix), &rsnd_mix_ops,
181 clk, RSND_MOD_MIX, i); 175 clk, RSND_MOD_MIX, i);
182 if (ret) 176 if (ret)
183 return ret; 177 goto rsnd_mix_probe_done;
178
179 i++;
184 } 180 }
185 181
186 return 0; 182rsnd_mix_probe_done:
183 of_node_put(node);
184
185 return ret;
187} 186}
188 187
189void rsnd_mix_remove(struct platform_device *pdev, 188void rsnd_mix_remove(struct rsnd_priv *priv)
190 struct rsnd_priv *priv)
191{ 189{
192 struct rsnd_mix *mix; 190 struct rsnd_mix *mix;
193 int i; 191 int i;
diff --git a/sound/soc/sh/rcar/rcar_snd.h b/sound/soc/sh/rcar/rcar_snd.h
deleted file mode 100644
index d8e33d38da43..000000000000
--- a/sound/soc/sh/rcar/rcar_snd.h
+++ /dev/null
@@ -1,117 +0,0 @@
1/*
2 * Renesas R-Car SRU/SCU/SSIU/SSI support
3 *
4 * Copyright (C) 2013 Renesas Solutions Corp.
5 * Kuninori Morimoto <kuninori.morimoto.gx@renesas.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 RCAR_SND_H
13#define RCAR_SND_H
14
15
16#define RSND_GEN1_SRU 0
17#define RSND_GEN1_ADG 1
18#define RSND_GEN1_SSI 2
19
20#define RSND_GEN2_SCU 0
21#define RSND_GEN2_ADG 1
22#define RSND_GEN2_SSIU 2
23#define RSND_GEN2_SSI 3
24
25#define RSND_BASE_MAX 4
26
27/*
28 * flags
29 *
30 * 0xAB000000
31 *
32 * A : clock sharing settings
33 * B : SSI direction
34 */
35#define RSND_SSI_CLK_PIN_SHARE (1 << 31)
36#define RSND_SSI_NO_BUSIF (1 << 30) /* SSI+DMA without BUSIF */
37
38#define RSND_SSI(_dma_id, _irq, _flags) \
39{ .dma_id = _dma_id, .irq = _irq, .flags = _flags }
40#define RSND_SSI_UNUSED \
41{ .dma_id = -1, .irq = -1, .flags = 0 }
42
43struct rsnd_ssi_platform_info {
44 int dma_id;
45 int irq;
46 u32 flags;
47};
48
49#define RSND_SRC(rate, _dma_id) \
50{ .convert_rate = rate, .dma_id = _dma_id, }
51#define RSND_SRC_UNUSED \
52{ .convert_rate = 0, .dma_id = -1, }
53
54struct rsnd_src_platform_info {
55 u32 convert_rate; /* sampling rate convert */
56 int dma_id; /* for Gen2 SCU */
57 int irq;
58};
59
60/*
61 * flags
62 */
63struct rsnd_ctu_platform_info {
64 u32 flags;
65};
66
67struct rsnd_mix_platform_info {
68 u32 flags;
69};
70
71struct rsnd_dvc_platform_info {
72 u32 flags;
73};
74
75struct rsnd_dai_path_info {
76 struct rsnd_ssi_platform_info *ssi;
77 struct rsnd_src_platform_info *src;
78 struct rsnd_ctu_platform_info *ctu;
79 struct rsnd_mix_platform_info *mix;
80 struct rsnd_dvc_platform_info *dvc;
81};
82
83struct rsnd_dai_platform_info {
84 struct rsnd_dai_path_info playback;
85 struct rsnd_dai_path_info capture;
86};
87
88/*
89 * flags
90 *
91 * 0x0000000A
92 *
93 * A : generation
94 */
95#define RSND_GEN_MASK (0xF << 0)
96#define RSND_GEN1 (1 << 0) /* fixme */
97#define RSND_GEN2 (2 << 0) /* fixme */
98
99struct rcar_snd_info {
100 u32 flags;
101 struct rsnd_ssi_platform_info *ssi_info;
102 int ssi_info_nr;
103 struct rsnd_src_platform_info *src_info;
104 int src_info_nr;
105 struct rsnd_ctu_platform_info *ctu_info;
106 int ctu_info_nr;
107 struct rsnd_mix_platform_info *mix_info;
108 int mix_info_nr;
109 struct rsnd_dvc_platform_info *dvc_info;
110 int dvc_info_nr;
111 struct rsnd_dai_platform_info *dai_info;
112 int dai_info_nr;
113 int (*start)(int id);
114 int (*stop)(int id);
115};
116
117#endif
diff --git a/sound/soc/sh/rcar/rsnd.h b/sound/soc/sh/rcar/rsnd.h
index 085329878525..317dd793149a 100644
--- a/sound/soc/sh/rcar/rsnd.h
+++ b/sound/soc/sh/rcar/rsnd.h
@@ -24,7 +24,16 @@
24#include <sound/soc.h> 24#include <sound/soc.h>
25#include <sound/pcm_params.h> 25#include <sound/pcm_params.h>
26 26
27#include "rcar_snd.h" 27#define RSND_GEN1_SRU 0
28#define RSND_GEN1_ADG 1
29#define RSND_GEN1_SSI 2
30
31#define RSND_GEN2_SCU 0
32#define RSND_GEN2_ADG 1
33#define RSND_GEN2_SSIU 2
34#define RSND_GEN2_SSI 3
35
36#define RSND_BASE_MAX 4
28 37
29/* 38/*
30 * pseudo register 39 * pseudo register
@@ -34,10 +43,19 @@
34 * see gen1/gen2 for detail 43 * see gen1/gen2 for detail
35 */ 44 */
36enum rsnd_reg { 45enum rsnd_reg {
37 /* SRU/SCU/SSIU */ 46 /* SCU (SRC/SSIU/MIX/CTU/DVC) */
47 RSND_REG_SSI_MODE, /* Gen2 only */
38 RSND_REG_SSI_MODE0, 48 RSND_REG_SSI_MODE0,
39 RSND_REG_SSI_MODE1, 49 RSND_REG_SSI_MODE1,
40 RSND_REG_SRC_BUSIF_MODE, 50 RSND_REG_SSI_MODE2,
51 RSND_REG_SSI_CONTROL,
52 RSND_REG_SSI_CTRL, /* Gen2 only */
53 RSND_REG_SSI_BUSIF_MODE, /* Gen2 only */
54 RSND_REG_SSI_BUSIF_ADINR, /* Gen2 only */
55 RSND_REG_SSI_BUSIF_DALIGN, /* Gen2 only */
56 RSND_REG_SSI_INT_ENABLE, /* Gen2 only */
57 RSND_REG_SRC_I_BUSIF_MODE,
58 RSND_REG_SRC_O_BUSIF_MODE,
41 RSND_REG_SRC_ROUTE_MODE0, 59 RSND_REG_SRC_ROUTE_MODE0,
42 RSND_REG_SRC_SWRSR, 60 RSND_REG_SRC_SWRSR,
43 RSND_REG_SRC_SRCIR, 61 RSND_REG_SRC_SRCIR,
@@ -45,9 +63,29 @@ enum rsnd_reg {
45 RSND_REG_SRC_IFSCR, 63 RSND_REG_SRC_IFSCR,
46 RSND_REG_SRC_IFSVR, 64 RSND_REG_SRC_IFSVR,
47 RSND_REG_SRC_SRCCR, 65 RSND_REG_SRC_SRCCR,
66 RSND_REG_SRC_CTRL, /* Gen2 only */
67 RSND_REG_SRC_BSDSR, /* Gen2 only */
68 RSND_REG_SRC_BSISR, /* Gen2 only */
69 RSND_REG_SRC_INT_ENABLE0, /* Gen2 only */
70 RSND_REG_SRC_BUSIF_DALIGN, /* Gen2 only */
71 RSND_REG_SRCIN_TIMSEL0, /* Gen2 only */
72 RSND_REG_SRCIN_TIMSEL1, /* Gen2 only */
73 RSND_REG_SRCIN_TIMSEL2, /* Gen2 only */
74 RSND_REG_SRCIN_TIMSEL3, /* Gen2 only */
75 RSND_REG_SRCIN_TIMSEL4, /* Gen2 only */
76 RSND_REG_SRCOUT_TIMSEL0, /* Gen2 only */
77 RSND_REG_SRCOUT_TIMSEL1, /* Gen2 only */
78 RSND_REG_SRCOUT_TIMSEL2, /* Gen2 only */
79 RSND_REG_SRCOUT_TIMSEL3, /* Gen2 only */
80 RSND_REG_SRCOUT_TIMSEL4, /* Gen2 only */
48 RSND_REG_SCU_SYS_STATUS0, 81 RSND_REG_SCU_SYS_STATUS0,
82 RSND_REG_SCU_SYS_STATUS1, /* Gen2 only */
49 RSND_REG_SCU_SYS_INT_EN0, 83 RSND_REG_SCU_SYS_INT_EN0,
84 RSND_REG_SCU_SYS_INT_EN1, /* Gen2 only */
85 RSND_REG_CMD_CTRL, /* Gen2 only */
86 RSND_REG_CMD_BUSIF_DALIGN, /* Gen2 only */
50 RSND_REG_CMD_ROUTE_SLCT, 87 RSND_REG_CMD_ROUTE_SLCT,
88 RSND_REG_CMDOUT_TIMSEL, /* Gen2 only */
51 RSND_REG_CTU_CTUIR, 89 RSND_REG_CTU_CTUIR,
52 RSND_REG_CTU_ADINR, 90 RSND_REG_CTU_ADINR,
53 RSND_REG_MIX_SWRSR, 91 RSND_REG_MIX_SWRSR,
@@ -67,14 +105,25 @@ enum rsnd_reg {
67 RSND_REG_DVC_ZCMCR, 105 RSND_REG_DVC_ZCMCR,
68 RSND_REG_DVC_VOL0R, 106 RSND_REG_DVC_VOL0R,
69 RSND_REG_DVC_VOL1R, 107 RSND_REG_DVC_VOL1R,
108 RSND_REG_DVC_VOL2R,
109 RSND_REG_DVC_VOL3R,
110 RSND_REG_DVC_VOL4R,
111 RSND_REG_DVC_VOL5R,
112 RSND_REG_DVC_VOL6R,
113 RSND_REG_DVC_VOL7R,
70 RSND_REG_DVC_DVUER, 114 RSND_REG_DVC_DVUER,
115 RSND_REG_DVC_VRCTR, /* Gen2 only */
116 RSND_REG_DVC_VRPDR, /* Gen2 only */
117 RSND_REG_DVC_VRDBR, /* Gen2 only */
71 118
72 /* ADG */ 119 /* ADG */
73 RSND_REG_BRRA, 120 RSND_REG_BRRA,
74 RSND_REG_BRRB, 121 RSND_REG_BRRB,
75 RSND_REG_SSICKR, 122 RSND_REG_SSICKR,
123 RSND_REG_DIV_EN, /* Gen2 only */
76 RSND_REG_AUDIO_CLK_SEL0, 124 RSND_REG_AUDIO_CLK_SEL0,
77 RSND_REG_AUDIO_CLK_SEL1, 125 RSND_REG_AUDIO_CLK_SEL1,
126 RSND_REG_AUDIO_CLK_SEL2, /* Gen2 only */
78 127
79 /* SSI */ 128 /* SSI */
80 RSND_REG_SSICR, 129 RSND_REG_SSICR,
@@ -83,83 +132,9 @@ enum rsnd_reg {
83 RSND_REG_SSIRDR, 132 RSND_REG_SSIRDR,
84 RSND_REG_SSIWSR, 133 RSND_REG_SSIWSR,
85 134
86 /* SHARE see below */
87 RSND_REG_SHARE01,
88 RSND_REG_SHARE02,
89 RSND_REG_SHARE03,
90 RSND_REG_SHARE04,
91 RSND_REG_SHARE05,
92 RSND_REG_SHARE06,
93 RSND_REG_SHARE07,
94 RSND_REG_SHARE08,
95 RSND_REG_SHARE09,
96 RSND_REG_SHARE10,
97 RSND_REG_SHARE11,
98 RSND_REG_SHARE12,
99 RSND_REG_SHARE13,
100 RSND_REG_SHARE14,
101 RSND_REG_SHARE15,
102 RSND_REG_SHARE16,
103 RSND_REG_SHARE17,
104 RSND_REG_SHARE18,
105 RSND_REG_SHARE19,
106 RSND_REG_SHARE20,
107 RSND_REG_SHARE21,
108 RSND_REG_SHARE22,
109 RSND_REG_SHARE23,
110 RSND_REG_SHARE24,
111 RSND_REG_SHARE25,
112 RSND_REG_SHARE26,
113 RSND_REG_SHARE27,
114 RSND_REG_SHARE28,
115 RSND_REG_SHARE29,
116
117 RSND_REG_MAX, 135 RSND_REG_MAX,
118}; 136};
119 137
120/* Gen1 only */
121#define RSND_REG_SRC_ROUTE_SEL RSND_REG_SHARE01
122#define RSND_REG_SRC_TMG_SEL0 RSND_REG_SHARE02
123#define RSND_REG_SRC_TMG_SEL1 RSND_REG_SHARE03
124#define RSND_REG_SRC_TMG_SEL2 RSND_REG_SHARE04
125#define RSND_REG_SRC_ROUTE_CTRL RSND_REG_SHARE05
126#define RSND_REG_SRC_MNFSR RSND_REG_SHARE06
127#define RSND_REG_AUDIO_CLK_SEL3 RSND_REG_SHARE07
128#define RSND_REG_AUDIO_CLK_SEL4 RSND_REG_SHARE08
129#define RSND_REG_AUDIO_CLK_SEL5 RSND_REG_SHARE09
130
131/* Gen2 only */
132#define RSND_REG_SRC_CTRL RSND_REG_SHARE01
133#define RSND_REG_SSI_CTRL RSND_REG_SHARE02
134#define RSND_REG_SSI_BUSIF_MODE RSND_REG_SHARE03
135#define RSND_REG_SSI_BUSIF_ADINR RSND_REG_SHARE04
136#define RSND_REG_SSI_INT_ENABLE RSND_REG_SHARE05
137#define RSND_REG_SRC_BSDSR RSND_REG_SHARE06
138#define RSND_REG_SRC_BSISR RSND_REG_SHARE07
139#define RSND_REG_DIV_EN RSND_REG_SHARE08
140#define RSND_REG_SRCIN_TIMSEL0 RSND_REG_SHARE09
141#define RSND_REG_SRCIN_TIMSEL1 RSND_REG_SHARE10
142#define RSND_REG_SRCIN_TIMSEL2 RSND_REG_SHARE11
143#define RSND_REG_SRCIN_TIMSEL3 RSND_REG_SHARE12
144#define RSND_REG_SRCIN_TIMSEL4 RSND_REG_SHARE13
145#define RSND_REG_SRCOUT_TIMSEL0 RSND_REG_SHARE14
146#define RSND_REG_SRCOUT_TIMSEL1 RSND_REG_SHARE15
147#define RSND_REG_SRCOUT_TIMSEL2 RSND_REG_SHARE16
148#define RSND_REG_SRCOUT_TIMSEL3 RSND_REG_SHARE17
149#define RSND_REG_SRCOUT_TIMSEL4 RSND_REG_SHARE18
150#define RSND_REG_AUDIO_CLK_SEL2 RSND_REG_SHARE19
151#define RSND_REG_CMD_CTRL RSND_REG_SHARE20
152#define RSND_REG_CMDOUT_TIMSEL RSND_REG_SHARE21
153#define RSND_REG_SSI_BUSIF_DALIGN RSND_REG_SHARE22
154#define RSND_REG_DVC_VRCTR RSND_REG_SHARE23
155#define RSND_REG_DVC_VRPDR RSND_REG_SHARE24
156#define RSND_REG_DVC_VRDBR RSND_REG_SHARE25
157#define RSND_REG_SCU_SYS_STATUS1 RSND_REG_SHARE26
158#define RSND_REG_SCU_SYS_INT_EN1 RSND_REG_SHARE27
159#define RSND_REG_SRC_INT_ENABLE0 RSND_REG_SHARE28
160#define RSND_REG_SRC_BUSIF_DALIGN RSND_REG_SHARE29
161
162struct rsnd_of_data;
163struct rsnd_priv; 138struct rsnd_priv;
164struct rsnd_mod; 139struct rsnd_mod;
165struct rsnd_dai; 140struct rsnd_dai;
@@ -187,43 +162,13 @@ void rsnd_bset(struct rsnd_priv *priv, struct rsnd_mod *mod, enum rsnd_reg reg,
187u32 rsnd_get_adinr_bit(struct rsnd_mod *mod, struct rsnd_dai_stream *io); 162u32 rsnd_get_adinr_bit(struct rsnd_mod *mod, struct rsnd_dai_stream *io);
188u32 rsnd_get_adinr_chan(struct rsnd_mod *mod, struct rsnd_dai_stream *io); 163u32 rsnd_get_adinr_chan(struct rsnd_mod *mod, struct rsnd_dai_stream *io);
189u32 rsnd_get_dalign(struct rsnd_mod *mod, struct rsnd_dai_stream *io); 164u32 rsnd_get_dalign(struct rsnd_mod *mod, struct rsnd_dai_stream *io);
190void rsnd_path_parse(struct rsnd_priv *priv,
191 struct rsnd_dai_stream *io);
192 165
193/* 166/*
194 * R-Car DMA 167 * R-Car DMA
195 */ 168 */
196struct rsnd_dma; 169struct rsnd_mod *rsnd_dma_attach(struct rsnd_dai_stream *io,
197 170 struct rsnd_mod *mod, int id);
198struct rsnd_dmaen { 171int rsnd_dma_probe(struct rsnd_priv *priv);
199 struct dma_chan *chan;
200};
201
202struct rsnd_dmapp {
203 int dmapp_id;
204 u32 chcr;
205};
206
207struct rsnd_dma {
208 struct rsnd_dma_ops *ops;
209 dma_addr_t src_addr;
210 dma_addr_t dst_addr;
211 union {
212 struct rsnd_dmaen en;
213 struct rsnd_dmapp pp;
214 } dma;
215};
216#define rsnd_dma_to_dmaen(dma) (&(dma)->dma.en)
217#define rsnd_dma_to_dmapp(dma) (&(dma)->dma.pp)
218#define rsnd_dma_to_mod(_dma) container_of((_dma), struct rsnd_mod, dma)
219
220void rsnd_dma_start(struct rsnd_dai_stream *io, struct rsnd_dma *dma);
221void rsnd_dma_stop(struct rsnd_dai_stream *io, struct rsnd_dma *dma);
222int rsnd_dma_init(struct rsnd_dai_stream *io, struct rsnd_dma *dma, int id);
223void rsnd_dma_quit(struct rsnd_dai_stream *io, struct rsnd_dma *dma);
224int rsnd_dma_probe(struct platform_device *pdev,
225 const struct rsnd_of_data *of_data,
226 struct rsnd_priv *priv);
227struct dma_chan *rsnd_dma_request_channel(struct device_node *of_node, 172struct dma_chan *rsnd_dma_request_channel(struct device_node *of_node,
228 struct rsnd_mod *mod, char *name); 173 struct rsnd_mod *mod, char *name);
229 174
@@ -231,11 +176,19 @@ struct dma_chan *rsnd_dma_request_channel(struct device_node *of_node,
231 * R-Car sound mod 176 * R-Car sound mod
232 */ 177 */
233enum rsnd_mod_type { 178enum rsnd_mod_type {
234 RSND_MOD_DVC = 0, 179 RSND_MOD_AUDMAPP,
180 RSND_MOD_AUDMA,
181 RSND_MOD_DVC,
235 RSND_MOD_MIX, 182 RSND_MOD_MIX,
236 RSND_MOD_CTU, 183 RSND_MOD_CTU,
184 RSND_MOD_CMD,
237 RSND_MOD_SRC, 185 RSND_MOD_SRC,
186 RSND_MOD_SSIM3, /* SSI multi 3 */
187 RSND_MOD_SSIM2, /* SSI multi 2 */
188 RSND_MOD_SSIM1, /* SSI multi 1 */
189 RSND_MOD_SSIP, /* SSI parent */
238 RSND_MOD_SSI, 190 RSND_MOD_SSI,
191 RSND_MOD_SSIU,
239 RSND_MOD_MAX, 192 RSND_MOD_MAX,
240}; 193};
241 194
@@ -278,10 +231,8 @@ struct rsnd_mod {
278 int id; 231 int id;
279 enum rsnd_mod_type type; 232 enum rsnd_mod_type type;
280 struct rsnd_mod_ops *ops; 233 struct rsnd_mod_ops *ops;
281 struct rsnd_dma dma;
282 struct rsnd_priv *priv; 234 struct rsnd_priv *priv;
283 struct clk *clk; 235 struct clk *clk;
284 u32 status;
285}; 236};
286/* 237/*
287 * status 238 * status
@@ -328,7 +279,6 @@ struct rsnd_mod {
328#define __rsnd_mod_call_hw_params 0 279#define __rsnd_mod_call_hw_params 0
329 280
330#define rsnd_mod_to_priv(mod) ((mod)->priv) 281#define rsnd_mod_to_priv(mod) ((mod)->priv)
331#define rsnd_mod_to_dma(mod) (&(mod)->dma)
332#define rsnd_mod_id(mod) ((mod) ? (mod)->id : -1) 282#define rsnd_mod_id(mod) ((mod) ? (mod)->id : -1)
333#define rsnd_mod_power_on(mod) clk_enable((mod)->clk) 283#define rsnd_mod_power_on(mod) clk_enable((mod)->clk)
334#define rsnd_mod_power_off(mod) clk_disable((mod)->clk) 284#define rsnd_mod_power_off(mod) clk_disable((mod)->clk)
@@ -347,6 +297,17 @@ struct dma_chan *rsnd_mod_dma_req(struct rsnd_dai_stream *io,
347void rsnd_mod_interrupt(struct rsnd_mod *mod, 297void rsnd_mod_interrupt(struct rsnd_mod *mod,
348 void (*callback)(struct rsnd_mod *mod, 298 void (*callback)(struct rsnd_mod *mod,
349 struct rsnd_dai_stream *io)); 299 struct rsnd_dai_stream *io));
300void rsnd_parse_connect_common(struct rsnd_dai *rdai,
301 struct rsnd_mod* (*mod_get)(struct rsnd_priv *priv, int id),
302 struct device_node *node,
303 struct device_node *playback,
304 struct device_node *capture);
305
306void rsnd_set_slot(struct rsnd_dai *rdai,
307 int slots, int slots_total);
308int rsnd_get_slot(struct rsnd_dai_stream *io);
309int rsnd_get_slot_width(struct rsnd_dai_stream *io);
310int rsnd_get_slot_num(struct rsnd_dai_stream *io);
350 311
351/* 312/*
352 * R-Car sound DAI 313 * R-Car sound DAI
@@ -358,6 +319,7 @@ struct rsnd_dai_stream {
358 struct rsnd_mod *mod[RSND_MOD_MAX]; 319 struct rsnd_mod *mod[RSND_MOD_MAX];
359 struct rsnd_dai_path_info *info; /* rcar_snd.h */ 320 struct rsnd_dai_path_info *info; /* rcar_snd.h */
360 struct rsnd_dai *rdai; 321 struct rsnd_dai *rdai;
322 u32 mod_status[RSND_MOD_MAX];
361 int byte_pos; 323 int byte_pos;
362 int period_pos; 324 int period_pos;
363 int byte_per_period; 325 int byte_per_period;
@@ -365,10 +327,12 @@ struct rsnd_dai_stream {
365}; 327};
366#define rsnd_io_to_mod(io, i) ((i) < RSND_MOD_MAX ? (io)->mod[(i)] : NULL) 328#define rsnd_io_to_mod(io, i) ((i) < RSND_MOD_MAX ? (io)->mod[(i)] : NULL)
367#define rsnd_io_to_mod_ssi(io) rsnd_io_to_mod((io), RSND_MOD_SSI) 329#define rsnd_io_to_mod_ssi(io) rsnd_io_to_mod((io), RSND_MOD_SSI)
330#define rsnd_io_to_mod_ssip(io) rsnd_io_to_mod((io), RSND_MOD_SSIP)
368#define rsnd_io_to_mod_src(io) rsnd_io_to_mod((io), RSND_MOD_SRC) 331#define rsnd_io_to_mod_src(io) rsnd_io_to_mod((io), RSND_MOD_SRC)
369#define rsnd_io_to_mod_ctu(io) rsnd_io_to_mod((io), RSND_MOD_CTU) 332#define rsnd_io_to_mod_ctu(io) rsnd_io_to_mod((io), RSND_MOD_CTU)
370#define rsnd_io_to_mod_mix(io) rsnd_io_to_mod((io), RSND_MOD_MIX) 333#define rsnd_io_to_mod_mix(io) rsnd_io_to_mod((io), RSND_MOD_MIX)
371#define rsnd_io_to_mod_dvc(io) rsnd_io_to_mod((io), RSND_MOD_DVC) 334#define rsnd_io_to_mod_dvc(io) rsnd_io_to_mod((io), RSND_MOD_DVC)
335#define rsnd_io_to_mod_cmd(io) rsnd_io_to_mod((io), RSND_MOD_CMD)
372#define rsnd_io_to_rdai(io) ((io)->rdai) 336#define rsnd_io_to_rdai(io) ((io)->rdai)
373#define rsnd_io_to_priv(io) (rsnd_rdai_to_priv(rsnd_io_to_rdai(io))) 337#define rsnd_io_to_priv(io) (rsnd_rdai_to_priv(rsnd_io_to_rdai(io)))
374#define rsnd_io_is_play(io) (&rsnd_io_to_rdai(io)->playback == io) 338#define rsnd_io_is_play(io) (&rsnd_io_to_rdai(io)->playback == io)
@@ -382,6 +346,9 @@ struct rsnd_dai {
382 struct rsnd_dai_stream capture; 346 struct rsnd_dai_stream capture;
383 struct rsnd_priv *priv; 347 struct rsnd_priv *priv;
384 348
349 int slots;
350 int slots_num;
351
385 unsigned int clk_master:1; 352 unsigned int clk_master:1;
386 unsigned int bit_clk_inv:1; 353 unsigned int bit_clk_inv:1;
387 unsigned int frm_clk_inv:1; 354 unsigned int frm_clk_inv:1;
@@ -403,33 +370,28 @@ struct rsnd_dai *rsnd_rdai_get(struct rsnd_priv *priv, int id);
403bool rsnd_dai_pointer_update(struct rsnd_dai_stream *io, int cnt); 370bool rsnd_dai_pointer_update(struct rsnd_dai_stream *io, int cnt);
404void rsnd_dai_period_elapsed(struct rsnd_dai_stream *io); 371void rsnd_dai_period_elapsed(struct rsnd_dai_stream *io);
405int rsnd_dai_pointer_offset(struct rsnd_dai_stream *io, int additional); 372int rsnd_dai_pointer_offset(struct rsnd_dai_stream *io, int additional);
373int rsnd_dai_connect(struct rsnd_mod *mod,
374 struct rsnd_dai_stream *io,
375 enum rsnd_mod_type type);
376#define rsnd_dai_of_node(priv) \
377 of_get_child_by_name(rsnd_priv_to_dev(priv)->of_node, "rcar_sound,dai")
406 378
407/* 379/*
408 * R-Car Gen1/Gen2 380 * R-Car Gen1/Gen2
409 */ 381 */
410int rsnd_gen_probe(struct platform_device *pdev, 382int rsnd_gen_probe(struct rsnd_priv *priv);
411 const struct rsnd_of_data *of_data,
412 struct rsnd_priv *priv);
413void __iomem *rsnd_gen_reg_get(struct rsnd_priv *priv, 383void __iomem *rsnd_gen_reg_get(struct rsnd_priv *priv,
414 struct rsnd_mod *mod, 384 struct rsnd_mod *mod,
415 enum rsnd_reg reg); 385 enum rsnd_reg reg);
416phys_addr_t rsnd_gen_get_phy_addr(struct rsnd_priv *priv, int reg_id); 386phys_addr_t rsnd_gen_get_phy_addr(struct rsnd_priv *priv, int reg_id);
417 387
418#define rsnd_is_gen1(s) (((s)->info->flags & RSND_GEN_MASK) == RSND_GEN1)
419#define rsnd_is_gen2(s) (((s)->info->flags & RSND_GEN_MASK) == RSND_GEN2)
420
421/* 388/*
422 * R-Car ADG 389 * R-Car ADG
423 */ 390 */
424int rsnd_adg_ssi_clk_stop(struct rsnd_mod *mod); 391int rsnd_adg_ssi_clk_stop(struct rsnd_mod *mod);
425int rsnd_adg_ssi_clk_try_start(struct rsnd_mod *mod, unsigned int rate); 392int rsnd_adg_ssi_clk_try_start(struct rsnd_mod *mod, unsigned int rate);
426int rsnd_adg_probe(struct platform_device *pdev, 393int rsnd_adg_probe(struct rsnd_priv *priv);
427 const struct rsnd_of_data *of_data, 394void rsnd_adg_remove(struct rsnd_priv *priv);
428 struct rsnd_priv *priv);
429int rsnd_adg_set_convert_clk_gen1(struct rsnd_priv *priv,
430 struct rsnd_mod *mod,
431 unsigned int src_rate,
432 unsigned int dst_rate);
433int rsnd_adg_set_convert_clk_gen2(struct rsnd_mod *mod, 395int rsnd_adg_set_convert_clk_gen2(struct rsnd_mod *mod,
434 struct rsnd_dai_stream *io, 396 struct rsnd_dai_stream *io,
435 unsigned int src_rate, 397 unsigned int src_rate,
@@ -442,15 +404,14 @@ int rsnd_adg_set_cmd_timsel_gen2(struct rsnd_mod *mod,
442/* 404/*
443 * R-Car sound priv 405 * R-Car sound priv
444 */ 406 */
445struct rsnd_of_data {
446 u32 flags;
447};
448
449struct rsnd_priv { 407struct rsnd_priv {
450 408
451 struct platform_device *pdev; 409 struct platform_device *pdev;
452 struct rcar_snd_info *info;
453 spinlock_t lock; 410 spinlock_t lock;
411 unsigned long flags;
412#define RSND_GEN_MASK (0xF << 0)
413#define RSND_GEN1 (1 << 0)
414#define RSND_GEN2 (2 << 0)
454 415
455 /* 416 /*
456 * below value will be filled on rsnd_gen_probe() 417 * below value will be filled on rsnd_gen_probe()
@@ -474,6 +435,12 @@ struct rsnd_priv {
474 int ssi_nr; 435 int ssi_nr;
475 436
476 /* 437 /*
438 * below value will be filled on rsnd_ssiu_probe()
439 */
440 void *ssiu;
441 int ssiu_nr;
442
443 /*
477 * below value will be filled on rsnd_src_probe() 444 * below value will be filled on rsnd_src_probe()
478 */ 445 */
479 void *src; 446 void *src;
@@ -498,6 +465,12 @@ struct rsnd_priv {
498 int dvc_nr; 465 int dvc_nr;
499 466
500 /* 467 /*
468 * below value will be filled on rsnd_cmd_probe()
469 */
470 void *cmd;
471 int cmd_nr;
472
473 /*
501 * below value will be filled on rsnd_dai_probe() 474 * below value will be filled on rsnd_dai_probe()
502 */ 475 */
503 struct snd_soc_dai_driver *daidrv; 476 struct snd_soc_dai_driver *daidrv;
@@ -507,7 +480,9 @@ struct rsnd_priv {
507 480
508#define rsnd_priv_to_pdev(priv) ((priv)->pdev) 481#define rsnd_priv_to_pdev(priv) ((priv)->pdev)
509#define rsnd_priv_to_dev(priv) (&(rsnd_priv_to_pdev(priv)->dev)) 482#define rsnd_priv_to_dev(priv) (&(rsnd_priv_to_pdev(priv)->dev))
510#define rsnd_priv_to_info(priv) ((priv)->info) 483
484#define rsnd_is_gen1(priv) (((priv)->flags & RSND_GEN_MASK) == RSND_GEN1)
485#define rsnd_is_gen2(priv) (((priv)->flags & RSND_GEN_MASK) == RSND_GEN2)
511 486
512/* 487/*
513 * rsnd_kctrl 488 * rsnd_kctrl
@@ -523,7 +498,7 @@ struct rsnd_kctrl_cfg {
523 struct snd_kcontrol *kctrl; 498 struct snd_kcontrol *kctrl;
524}; 499};
525 500
526#define RSND_DVC_CHANNELS 2 501#define RSND_DVC_CHANNELS 8
527struct rsnd_kctrl_cfg_m { 502struct rsnd_kctrl_cfg_m {
528 struct rsnd_kctrl_cfg cfg; 503 struct rsnd_kctrl_cfg cfg;
529 u32 val[RSND_DVC_CHANNELS]; 504 u32 val[RSND_DVC_CHANNELS];
@@ -544,6 +519,7 @@ int rsnd_kctrl_new_m(struct rsnd_mod *mod,
544 void (*update)(struct rsnd_dai_stream *io, 519 void (*update)(struct rsnd_dai_stream *io,
545 struct rsnd_mod *mod), 520 struct rsnd_mod *mod),
546 struct rsnd_kctrl_cfg_m *_cfg, 521 struct rsnd_kctrl_cfg_m *_cfg,
522 int ch_size,
547 u32 max); 523 u32 max);
548int rsnd_kctrl_new_s(struct rsnd_mod *mod, 524int rsnd_kctrl_new_s(struct rsnd_mod *mod,
549 struct rsnd_dai_stream *io, 525 struct rsnd_dai_stream *io,
@@ -566,70 +542,93 @@ int rsnd_kctrl_new_e(struct rsnd_mod *mod,
566/* 542/*
567 * R-Car SSI 543 * R-Car SSI
568 */ 544 */
569int rsnd_ssi_probe(struct platform_device *pdev, 545int rsnd_ssi_probe(struct rsnd_priv *priv);
570 const struct rsnd_of_data *of_data, 546void rsnd_ssi_remove(struct rsnd_priv *priv);
571 struct rsnd_priv *priv);
572void rsnd_ssi_remove(struct platform_device *pdev,
573 struct rsnd_priv *priv);
574struct rsnd_mod *rsnd_ssi_mod_get(struct rsnd_priv *priv, int id); 547struct rsnd_mod *rsnd_ssi_mod_get(struct rsnd_priv *priv, int id);
575int rsnd_ssi_is_dma_mode(struct rsnd_mod *mod); 548int rsnd_ssi_is_dma_mode(struct rsnd_mod *mod);
576int rsnd_ssi_use_busif(struct rsnd_dai_stream *io); 549int rsnd_ssi_use_busif(struct rsnd_dai_stream *io);
550u32 rsnd_ssi_multi_slaves(struct rsnd_dai_stream *io);
577 551
578#define rsnd_ssi_is_pin_sharing(io) \ 552#define rsnd_ssi_is_pin_sharing(io) \
579 __rsnd_ssi_is_pin_sharing(rsnd_io_to_mod_ssi(io)) 553 __rsnd_ssi_is_pin_sharing(rsnd_io_to_mod_ssi(io))
580int __rsnd_ssi_is_pin_sharing(struct rsnd_mod *mod); 554int __rsnd_ssi_is_pin_sharing(struct rsnd_mod *mod);
581 555
556#define rsnd_ssi_of_node(priv) \
557 of_get_child_by_name(rsnd_priv_to_dev(priv)->of_node, "rcar_sound,ssi")
558void rsnd_parse_connect_ssi(struct rsnd_dai *rdai,
559 struct device_node *playback,
560 struct device_node *capture);
561
562/*
563 * R-Car SSIU
564 */
565int rsnd_ssiu_attach(struct rsnd_dai_stream *io,
566 struct rsnd_mod *mod);
567int rsnd_ssiu_probe(struct rsnd_priv *priv);
568void rsnd_ssiu_remove(struct rsnd_priv *priv);
569
582/* 570/*
583 * R-Car SRC 571 * R-Car SRC
584 */ 572 */
585int rsnd_src_probe(struct platform_device *pdev, 573int rsnd_src_probe(struct rsnd_priv *priv);
586 const struct rsnd_of_data *of_data, 574void rsnd_src_remove(struct rsnd_priv *priv);
587 struct rsnd_priv *priv);
588void rsnd_src_remove(struct platform_device *pdev,
589 struct rsnd_priv *priv);
590struct rsnd_mod *rsnd_src_mod_get(struct rsnd_priv *priv, int id); 575struct rsnd_mod *rsnd_src_mod_get(struct rsnd_priv *priv, int id);
591unsigned int rsnd_src_get_ssi_rate(struct rsnd_priv *priv, 576unsigned int rsnd_src_get_ssi_rate(struct rsnd_priv *priv,
592 struct rsnd_dai_stream *io, 577 struct rsnd_dai_stream *io,
593 struct snd_pcm_runtime *runtime); 578 struct snd_pcm_runtime *runtime);
594int rsnd_src_ssiu_start(struct rsnd_mod *ssi_mod, 579#define rsnd_src_of_node(priv) \
595 struct rsnd_dai_stream *io, 580 of_get_child_by_name(rsnd_priv_to_dev(priv)->of_node, "rcar_sound,src")
596 int use_busif); 581#define rsnd_parse_connect_src(rdai, playback, capture) \
597int rsnd_src_ssiu_stop(struct rsnd_mod *ssi_mod, 582 rsnd_parse_connect_common(rdai, rsnd_src_mod_get, \
598 struct rsnd_dai_stream *io); 583 rsnd_src_of_node(rsnd_rdai_to_priv(rdai)), \
599int rsnd_src_ssi_irq_enable(struct rsnd_mod *ssi_mod); 584 playback, capture)
600int rsnd_src_ssi_irq_disable(struct rsnd_mod *ssi_mod);
601 585
602/* 586/*
603 * R-Car CTU 587 * R-Car CTU
604 */ 588 */
605int rsnd_ctu_probe(struct platform_device *pdev, 589int rsnd_ctu_probe(struct rsnd_priv *priv);
606 const struct rsnd_of_data *of_data, 590void rsnd_ctu_remove(struct rsnd_priv *priv);
607 struct rsnd_priv *priv);
608
609void rsnd_ctu_remove(struct platform_device *pdev,
610 struct rsnd_priv *priv);
611struct rsnd_mod *rsnd_ctu_mod_get(struct rsnd_priv *priv, int id); 591struct rsnd_mod *rsnd_ctu_mod_get(struct rsnd_priv *priv, int id);
592#define rsnd_ctu_of_node(priv) \
593 of_get_child_by_name(rsnd_priv_to_dev(priv)->of_node, "rcar_sound,ctu")
594#define rsnd_parse_connect_ctu(rdai, playback, capture) \
595 rsnd_parse_connect_common(rdai, rsnd_ctu_mod_get, \
596 rsnd_ctu_of_node(rsnd_rdai_to_priv(rdai)), \
597 playback, capture)
612 598
613/* 599/*
614 * R-Car MIX 600 * R-Car MIX
615 */ 601 */
616int rsnd_mix_probe(struct platform_device *pdev, 602int rsnd_mix_probe(struct rsnd_priv *priv);
617 const struct rsnd_of_data *of_data, 603void rsnd_mix_remove(struct rsnd_priv *priv);
618 struct rsnd_priv *priv);
619
620void rsnd_mix_remove(struct platform_device *pdev,
621 struct rsnd_priv *priv);
622struct rsnd_mod *rsnd_mix_mod_get(struct rsnd_priv *priv, int id); 604struct rsnd_mod *rsnd_mix_mod_get(struct rsnd_priv *priv, int id);
605#define rsnd_mix_of_node(priv) \
606 of_get_child_by_name(rsnd_priv_to_dev(priv)->of_node, "rcar_sound,mix")
607#define rsnd_parse_connect_mix(rdai, playback, capture) \
608 rsnd_parse_connect_common(rdai, rsnd_mix_mod_get, \
609 rsnd_mix_of_node(rsnd_rdai_to_priv(rdai)), \
610 playback, capture)
623 611
624/* 612/*
625 * R-Car DVC 613 * R-Car DVC
626 */ 614 */
627int rsnd_dvc_probe(struct platform_device *pdev, 615int rsnd_dvc_probe(struct rsnd_priv *priv);
628 const struct rsnd_of_data *of_data, 616void rsnd_dvc_remove(struct rsnd_priv *priv);
629 struct rsnd_priv *priv);
630void rsnd_dvc_remove(struct platform_device *pdev,
631 struct rsnd_priv *priv);
632struct rsnd_mod *rsnd_dvc_mod_get(struct rsnd_priv *priv, int id); 617struct rsnd_mod *rsnd_dvc_mod_get(struct rsnd_priv *priv, int id);
618#define rsnd_dvc_of_node(priv) \
619 of_get_child_by_name(rsnd_priv_to_dev(priv)->of_node, "rcar_sound,dvc")
620#define rsnd_parse_connect_dvc(rdai, playback, capture) \
621 rsnd_parse_connect_common(rdai, rsnd_dvc_mod_get, \
622 rsnd_dvc_of_node(rsnd_rdai_to_priv(rdai)), \
623 playback, capture)
624
625/*
626 * R-Car CMD
627 */
628int rsnd_cmd_probe(struct rsnd_priv *priv);
629void rsnd_cmd_remove(struct rsnd_priv *priv);
630int rsnd_cmd_attach(struct rsnd_dai_stream *io, int id);
631struct rsnd_mod *rsnd_cmd_mod_get(struct rsnd_priv *priv, int id);
633 632
634#ifdef DEBUG 633#ifdef DEBUG
635void rsnd_mod_make_sure(struct rsnd_mod *mod, enum rsnd_mod_type type); 634void rsnd_mod_make_sure(struct rsnd_mod *mod, enum rsnd_mod_type type);
diff --git a/sound/soc/sh/rcar/rsrc-card.c b/sound/soc/sh/rcar/rsrc-card.c
index d61db9c385ea..8a357fdf1077 100644
--- a/sound/soc/sh/rcar/rsrc-card.c
+++ b/sound/soc/sh/rcar/rsrc-card.c
@@ -48,8 +48,11 @@ MODULE_DEVICE_TABLE(of, rsrc_card_of_match);
48 48
49#define DAI_NAME_NUM 32 49#define DAI_NAME_NUM 32
50struct rsrc_card_dai { 50struct rsrc_card_dai {
51 unsigned int fmt;
52 unsigned int sysclk; 51 unsigned int sysclk;
52 unsigned int tx_slot_mask;
53 unsigned int rx_slot_mask;
54 int slots;
55 int slot_width;
53 struct clk *clk; 56 struct clk *clk;
54 char dai_name[DAI_NAME_NUM]; 57 char dai_name[DAI_NAME_NUM];
55}; 58};
@@ -75,7 +78,7 @@ static int rsrc_card_startup(struct snd_pcm_substream *substream)
75 struct snd_soc_pcm_runtime *rtd = substream->private_data; 78 struct snd_soc_pcm_runtime *rtd = substream->private_data;
76 struct rsrc_card_priv *priv = snd_soc_card_get_drvdata(rtd->card); 79 struct rsrc_card_priv *priv = snd_soc_card_get_drvdata(rtd->card);
77 struct rsrc_card_dai *dai_props = 80 struct rsrc_card_dai *dai_props =
78 rsrc_priv_to_props(priv, rtd - rtd->card->rtd); 81 rsrc_priv_to_props(priv, rtd->num);
79 82
80 return clk_prepare_enable(dai_props->clk); 83 return clk_prepare_enable(dai_props->clk);
81} 84}
@@ -85,7 +88,7 @@ static void rsrc_card_shutdown(struct snd_pcm_substream *substream)
85 struct snd_soc_pcm_runtime *rtd = substream->private_data; 88 struct snd_soc_pcm_runtime *rtd = substream->private_data;
86 struct rsrc_card_priv *priv = snd_soc_card_get_drvdata(rtd->card); 89 struct rsrc_card_priv *priv = snd_soc_card_get_drvdata(rtd->card);
87 struct rsrc_card_dai *dai_props = 90 struct rsrc_card_dai *dai_props =
88 rsrc_priv_to_props(priv, rtd - rtd->card->rtd); 91 rsrc_priv_to_props(priv, rtd->num);
89 92
90 clk_disable_unprepare(dai_props->clk); 93 clk_disable_unprepare(dai_props->clk);
91} 94}
@@ -101,7 +104,7 @@ static int rsrc_card_dai_init(struct snd_soc_pcm_runtime *rtd)
101 struct snd_soc_dai *dai; 104 struct snd_soc_dai *dai;
102 struct snd_soc_dai_link *dai_link; 105 struct snd_soc_dai_link *dai_link;
103 struct rsrc_card_dai *dai_props; 106 struct rsrc_card_dai *dai_props;
104 int num = rtd - rtd->card->rtd; 107 int num = rtd->num;
105 int ret; 108 int ret;
106 109
107 dai_link = rsrc_priv_to_link(priv, num); 110 dai_link = rsrc_priv_to_link(priv, num);
@@ -110,18 +113,22 @@ static int rsrc_card_dai_init(struct snd_soc_pcm_runtime *rtd)
110 rtd->cpu_dai : 113 rtd->cpu_dai :
111 rtd->codec_dai; 114 rtd->codec_dai;
112 115
113 if (dai_props->fmt) { 116 if (dai_props->sysclk) {
114 ret = snd_soc_dai_set_fmt(dai, dai_props->fmt); 117 ret = snd_soc_dai_set_sysclk(dai, 0, dai_props->sysclk, 0);
115 if (ret && ret != -ENOTSUPP) { 118 if (ret && ret != -ENOTSUPP) {
116 dev_err(dai->dev, "set_fmt error\n"); 119 dev_err(dai->dev, "set_sysclk error\n");
117 goto err; 120 goto err;
118 } 121 }
119 } 122 }
120 123
121 if (dai_props->sysclk) { 124 if (dai_props->slots) {
122 ret = snd_soc_dai_set_sysclk(dai, 0, dai_props->sysclk, 0); 125 ret = snd_soc_dai_set_tdm_slot(dai,
126 dai_props->tx_slot_mask,
127 dai_props->rx_slot_mask,
128 dai_props->slots,
129 dai_props->slot_width);
123 if (ret && ret != -ENOTSUPP) { 130 if (ret && ret != -ENOTSUPP) {
124 dev_err(dai->dev, "set_sysclk error\n"); 131 dev_err(dai->dev, "set_tdm_slot error\n");
125 goto err; 132 goto err;
126 } 133 }
127 } 134 }
@@ -148,14 +155,13 @@ static int rsrc_card_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
148} 155}
149 156
150static int rsrc_card_parse_daifmt(struct device_node *node, 157static int rsrc_card_parse_daifmt(struct device_node *node,
151 struct device_node *np, 158 struct device_node *codec,
152 struct rsrc_card_priv *priv, 159 struct rsrc_card_priv *priv,
153 int idx, bool is_fe) 160 struct snd_soc_dai_link *dai_link,
161 unsigned int *retfmt)
154{ 162{
155 struct rsrc_card_dai *dai_props = rsrc_priv_to_props(priv, idx);
156 struct device_node *bitclkmaster = NULL; 163 struct device_node *bitclkmaster = NULL;
157 struct device_node *framemaster = NULL; 164 struct device_node *framemaster = NULL;
158 struct device_node *codec = is_fe ? NULL : np;
159 unsigned int daifmt; 165 unsigned int daifmt;
160 166
161 daifmt = snd_soc_of_parse_daifmt(node, NULL, 167 daifmt = snd_soc_of_parse_daifmt(node, NULL,
@@ -172,11 +178,11 @@ static int rsrc_card_parse_daifmt(struct device_node *node,
172 daifmt |= (codec == framemaster) ? 178 daifmt |= (codec == framemaster) ?
173 SND_SOC_DAIFMT_CBS_CFM : SND_SOC_DAIFMT_CBS_CFS; 179 SND_SOC_DAIFMT_CBS_CFM : SND_SOC_DAIFMT_CBS_CFS;
174 180
175 dai_props->fmt = daifmt;
176
177 of_node_put(bitclkmaster); 181 of_node_put(bitclkmaster);
178 of_node_put(framemaster); 182 of_node_put(framemaster);
179 183
184 *retfmt = daifmt;
185
180 return 0; 186 return 0;
181} 187}
182 188
@@ -198,6 +204,15 @@ static int rsrc_card_parse_links(struct device_node *np,
198 if (ret) 204 if (ret)
199 return ret; 205 return ret;
200 206
207 /* Parse TDM slot */
208 ret = snd_soc_of_parse_tdm_slot(np,
209 &dai_props->tx_slot_mask,
210 &dai_props->rx_slot_mask,
211 &dai_props->slots,
212 &dai_props->slot_width);
213 if (ret)
214 return ret;
215
201 if (is_fe) { 216 if (is_fe) {
202 /* BE is dummy */ 217 /* BE is dummy */
203 dai_link->codec_of_node = NULL; 218 dai_link->codec_of_node = NULL;
@@ -208,7 +223,9 @@ static int rsrc_card_parse_links(struct device_node *np,
208 dai_link->dynamic = 1; 223 dai_link->dynamic = 1;
209 dai_link->dpcm_merged_format = 1; 224 dai_link->dpcm_merged_format = 1;
210 dai_link->cpu_of_node = args.np; 225 dai_link->cpu_of_node = args.np;
211 snd_soc_of_get_dai_name(np, &dai_link->cpu_dai_name); 226 ret = snd_soc_of_get_dai_name(np, &dai_link->cpu_dai_name);
227 if (ret < 0)
228 return ret;
212 229
213 /* set dai_name */ 230 /* set dai_name */
214 snprintf(dai_props->dai_name, DAI_NAME_NUM, "fe.%s", 231 snprintf(dai_props->dai_name, DAI_NAME_NUM, "fe.%s",
@@ -240,7 +257,9 @@ static int rsrc_card_parse_links(struct device_node *np,
240 dai_link->no_pcm = 1; 257 dai_link->no_pcm = 1;
241 dai_link->be_hw_params_fixup = rsrc_card_be_hw_params_fixup; 258 dai_link->be_hw_params_fixup = rsrc_card_be_hw_params_fixup;
242 dai_link->codec_of_node = args.np; 259 dai_link->codec_of_node = args.np;
243 snd_soc_of_get_dai_name(np, &dai_link->codec_dai_name); 260 ret = snd_soc_of_get_dai_name(np, &dai_link->codec_dai_name);
261 if (ret < 0)
262 return ret;
244 263
245 /* additional name prefix */ 264 /* additional name prefix */
246 if (of_data) { 265 if (of_data) {
@@ -305,23 +324,16 @@ static int rsrc_card_parse_clk(struct device_node *np,
305 return 0; 324 return 0;
306} 325}
307 326
308static int rsrc_card_dai_link_of(struct device_node *node, 327static int rsrc_card_dai_sub_link_of(struct device_node *node,
309 struct device_node *np, 328 struct device_node *np,
310 struct rsrc_card_priv *priv, 329 struct rsrc_card_priv *priv,
311 int idx) 330 int idx, bool is_fe)
312{ 331{
313 struct device *dev = rsrc_priv_to_dev(priv); 332 struct device *dev = rsrc_priv_to_dev(priv);
333 struct snd_soc_dai_link *dai_link = rsrc_priv_to_link(priv, idx);
314 struct rsrc_card_dai *dai_props = rsrc_priv_to_props(priv, idx); 334 struct rsrc_card_dai *dai_props = rsrc_priv_to_props(priv, idx);
315 bool is_fe = false;
316 int ret; 335 int ret;
317 336
318 if (0 == strcmp(np->name, "cpu"))
319 is_fe = true;
320
321 ret = rsrc_card_parse_daifmt(node, np, priv, idx, is_fe);
322 if (ret < 0)
323 return ret;
324
325 ret = rsrc_card_parse_links(np, priv, idx, is_fe); 337 ret = rsrc_card_parse_links(np, priv, idx, is_fe);
326 if (ret < 0) 338 if (ret < 0)
327 return ret; 339 return ret;
@@ -332,12 +344,54 @@ static int rsrc_card_dai_link_of(struct device_node *node,
332 344
333 dev_dbg(dev, "\t%s / %04x / %d\n", 345 dev_dbg(dev, "\t%s / %04x / %d\n",
334 dai_props->dai_name, 346 dai_props->dai_name,
335 dai_props->fmt, 347 dai_link->dai_fmt,
336 dai_props->sysclk); 348 dai_props->sysclk);
337 349
338 return ret; 350 return ret;
339} 351}
340 352
353static int rsrc_card_dai_link_of(struct device_node *node,
354 struct rsrc_card_priv *priv)
355{
356 struct snd_soc_dai_link *dai_link;
357 struct device_node *np;
358 unsigned int daifmt = 0;
359 int ret, i;
360 bool is_fe;
361
362 /* find 1st codec */
363 i = 0;
364 for_each_child_of_node(node, np) {
365 dai_link = rsrc_priv_to_link(priv, i);
366
367 if (strcmp(np->name, "codec") == 0) {
368 ret = rsrc_card_parse_daifmt(node, np, priv,
369 dai_link, &daifmt);
370 if (ret < 0)
371 return ret;
372 break;
373 }
374 i++;
375 }
376
377 i = 0;
378 for_each_child_of_node(node, np) {
379 dai_link = rsrc_priv_to_link(priv, i);
380 dai_link->dai_fmt = daifmt;
381
382 is_fe = false;
383 if (strcmp(np->name, "cpu") == 0)
384 is_fe = true;
385
386 ret = rsrc_card_dai_sub_link_of(node, np, priv, i, is_fe);
387 if (ret < 0)
388 return ret;
389 i++;
390 }
391
392 return 0;
393}
394
341static int rsrc_card_parse_of(struct device_node *node, 395static int rsrc_card_parse_of(struct device_node *node,
342 struct rsrc_card_priv *priv, 396 struct rsrc_card_priv *priv,
343 struct device *dev) 397 struct device *dev)
@@ -345,9 +399,8 @@ static int rsrc_card_parse_of(struct device_node *node,
345 const struct rsrc_card_of_data *of_data = rsrc_dev_to_of_data(dev); 399 const struct rsrc_card_of_data *of_data = rsrc_dev_to_of_data(dev);
346 struct rsrc_card_dai *props; 400 struct rsrc_card_dai *props;
347 struct snd_soc_dai_link *links; 401 struct snd_soc_dai_link *links;
348 struct device_node *np;
349 int ret; 402 int ret;
350 int i, num; 403 int num;
351 404
352 if (!node) 405 if (!node)
353 return -EINVAL; 406 return -EINVAL;
@@ -388,13 +441,9 @@ static int rsrc_card_parse_of(struct device_node *node,
388 priv->snd_card.name ? priv->snd_card.name : "", 441 priv->snd_card.name ? priv->snd_card.name : "",
389 priv->convert_rate); 442 priv->convert_rate);
390 443
391 i = 0; 444 ret = rsrc_card_dai_link_of(node, priv);
392 for_each_child_of_node(node, np) { 445 if (ret < 0)
393 ret = rsrc_card_dai_link_of(node, np, priv, i); 446 return ret;
394 if (ret < 0)
395 return ret;
396 i++;
397 }
398 447
399 if (!priv->snd_card.name) 448 if (!priv->snd_card.name)
400 priv->snd_card.name = priv->snd_card.dai_link->name; 449 priv->snd_card.name = priv->snd_card.dai_link->name;
diff --git a/sound/soc/sh/rcar/src.c b/sound/soc/sh/rcar/src.c
index 68b439ed22d7..5eda056d9f20 100644
--- a/sound/soc/sh/rcar/src.c
+++ b/sound/soc/sh/rcar/src.c
@@ -20,20 +20,21 @@
20#define OUF_SRC(id) ((1 << (id + 16)) | (1 << id)) 20#define OUF_SRC(id) ((1 << (id + 16)) | (1 << id))
21 21
22struct rsnd_src { 22struct rsnd_src {
23 struct rsnd_src_platform_info *info; /* rcar_snd.h */
24 struct rsnd_mod mod; 23 struct rsnd_mod mod;
24 struct rsnd_mod *dma;
25 struct rsnd_kctrl_cfg_s sen; /* sync convert enable */ 25 struct rsnd_kctrl_cfg_s sen; /* sync convert enable */
26 struct rsnd_kctrl_cfg_s sync; /* sync convert */ 26 struct rsnd_kctrl_cfg_s sync; /* sync convert */
27 u32 convert_rate; /* sampling rate convert */ 27 u32 convert_rate; /* sampling rate convert */
28 int err; 28 int err;
29 int irq;
29}; 30};
30 31
31#define RSND_SRC_NAME_SIZE 16 32#define RSND_SRC_NAME_SIZE 16
32 33
34#define rsnd_src_get(priv, id) ((struct rsnd_src *)(priv->src) + id)
35#define rsnd_src_to_dma(src) ((src)->dma)
33#define rsnd_src_nr(priv) ((priv)->src_nr) 36#define rsnd_src_nr(priv) ((priv)->src_nr)
34#define rsnd_enable_sync_convert(src) ((src)->sen.val) 37#define rsnd_enable_sync_convert(src) ((src)->sen.val)
35#define rsnd_src_of_node(priv) \
36 of_get_child_by_name(rsnd_priv_to_dev(priv)->of_node, "rcar_sound,src")
37 38
38#define rsnd_mod_to_src(_mod) \ 39#define rsnd_mod_to_src(_mod) \
39 container_of((_mod), struct rsnd_src, mod) 40 container_of((_mod), struct rsnd_src, mod)
@@ -69,67 +70,16 @@ struct rsnd_src {
69 * |-----------------| 70 * |-----------------|
70 */ 71 */
71 72
72/* 73static void rsnd_src_activation(struct rsnd_mod *mod)
73 * How to use SRC bypass mode for debugging
74 *
75 * SRC has bypass mode, and it is useful for debugging.
76 * In Gen2 case,
77 * SRCm_MODE controls whether SRC is used or not
78 * SSI_MODE0 controls whether SSIU which receives SRC data
79 * is used or not.
80 * Both SRCm_MODE/SSI_MODE0 settings are needed if you use SRC,
81 * but SRC bypass mode needs SSI_MODE0 only.
82 *
83 * This driver request
84 * struct rsnd_src_platform_info {
85 * u32 convert_rate;
86 * int dma_id;
87 * }
88 *
89 * rsnd_src_convert_rate() indicates
90 * above convert_rate, and it controls
91 * whether SRC is used or not.
92 *
93 * ex) doesn't use SRC
94 * static struct rsnd_dai_platform_info rsnd_dai = {
95 * .playback = { .ssi = &rsnd_ssi[0], },
96 * };
97 *
98 * ex) uses SRC
99 * static struct rsnd_src_platform_info rsnd_src[] = {
100 * RSND_SCU(48000, 0),
101 * ...
102 * };
103 * static struct rsnd_dai_platform_info rsnd_dai = {
104 * .playback = { .ssi = &rsnd_ssi[0], .src = &rsnd_src[0] },
105 * };
106 *
107 * ex) uses SRC bypass mode
108 * static struct rsnd_src_platform_info rsnd_src[] = {
109 * RSND_SCU(0, 0),
110 * ...
111 * };
112 * static struct rsnd_dai_platform_info rsnd_dai = {
113 * .playback = { .ssi = &rsnd_ssi[0], .src = &rsnd_src[0] },
114 * };
115 *
116 */
117
118/*
119 * Gen1/Gen2 common functions
120 */
121static void rsnd_src_soft_reset(struct rsnd_mod *mod)
122{ 74{
123 rsnd_mod_write(mod, SRC_SWRSR, 0); 75 rsnd_mod_write(mod, SRC_SWRSR, 0);
124 rsnd_mod_write(mod, SRC_SWRSR, 1); 76 rsnd_mod_write(mod, SRC_SWRSR, 1);
125} 77}
126 78
127 79static void rsnd_src_halt(struct rsnd_mod *mod)
128#define rsnd_src_initialize_lock(mod) __rsnd_src_initialize_lock(mod, 1)
129#define rsnd_src_initialize_unlock(mod) __rsnd_src_initialize_lock(mod, 0)
130static void __rsnd_src_initialize_lock(struct rsnd_mod *mod, u32 enable)
131{ 80{
132 rsnd_mod_write(mod, SRC_SRCIR, enable); 81 rsnd_mod_write(mod, SRC_SRCIR, 1);
82 rsnd_mod_write(mod, SRC_SWRSR, 0);
133} 83}
134 84
135static struct dma_chan *rsnd_src_dma_req(struct rsnd_dai_stream *io, 85static struct dma_chan *rsnd_src_dma_req(struct rsnd_dai_stream *io,
@@ -143,99 +93,6 @@ static struct dma_chan *rsnd_src_dma_req(struct rsnd_dai_stream *io,
143 is_play ? "rx" : "tx"); 93 is_play ? "rx" : "tx");
144} 94}
145 95
146int rsnd_src_ssiu_start(struct rsnd_mod *ssi_mod,
147 struct rsnd_dai_stream *io,
148 int use_busif)
149{
150 struct rsnd_dai *rdai = rsnd_io_to_rdai(io);
151 int ssi_id = rsnd_mod_id(ssi_mod);
152
153 /*
154 * SSI_MODE0
155 */
156 rsnd_mod_bset(ssi_mod, SSI_MODE0, (1 << ssi_id),
157 !use_busif << ssi_id);
158
159 /*
160 * SSI_MODE1
161 */
162 if (rsnd_ssi_is_pin_sharing(io)) {
163 int shift = -1;
164 switch (ssi_id) {
165 case 1:
166 shift = 0;
167 break;
168 case 2:
169 shift = 2;
170 break;
171 case 4:
172 shift = 16;
173 break;
174 }
175
176 if (shift >= 0)
177 rsnd_mod_bset(ssi_mod, SSI_MODE1,
178 0x3 << shift,
179 rsnd_rdai_is_clk_master(rdai) ?
180 0x2 << shift : 0x1 << shift);
181 }
182
183 /*
184 * DMA settings for SSIU
185 */
186 if (use_busif) {
187 u32 val = rsnd_get_dalign(ssi_mod, io);
188
189 rsnd_mod_write(ssi_mod, SSI_BUSIF_ADINR,
190 rsnd_get_adinr_bit(ssi_mod, io));
191 rsnd_mod_write(ssi_mod, SSI_BUSIF_MODE, 1);
192 rsnd_mod_write(ssi_mod, SSI_CTRL, 0x1);
193
194 rsnd_mod_write(ssi_mod, SSI_BUSIF_DALIGN, val);
195 }
196
197 return 0;
198}
199
200int rsnd_src_ssiu_stop(struct rsnd_mod *ssi_mod,
201 struct rsnd_dai_stream *io)
202{
203 /*
204 * DMA settings for SSIU
205 */
206 rsnd_mod_write(ssi_mod, SSI_CTRL, 0);
207
208 return 0;
209}
210
211int rsnd_src_ssi_irq_enable(struct rsnd_mod *ssi_mod)
212{
213 struct rsnd_priv *priv = rsnd_mod_to_priv(ssi_mod);
214
215 if (rsnd_is_gen1(priv))
216 return 0;
217
218 /* enable SSI interrupt if Gen2 */
219 rsnd_mod_write(ssi_mod, SSI_INT_ENABLE,
220 rsnd_ssi_is_dma_mode(ssi_mod) ?
221 0x0e000000 : 0x0f000000);
222
223 return 0;
224}
225
226int rsnd_src_ssi_irq_disable(struct rsnd_mod *ssi_mod)
227{
228 struct rsnd_priv *priv = rsnd_mod_to_priv(ssi_mod);
229
230 if (rsnd_is_gen1(priv))
231 return 0;
232
233 /* disable SSI interrupt if Gen2 */
234 rsnd_mod_write(ssi_mod, SSI_INT_ENABLE, 0x00000000);
235
236 return 0;
237}
238
239static u32 rsnd_src_convert_rate(struct rsnd_dai_stream *io, 96static u32 rsnd_src_convert_rate(struct rsnd_dai_stream *io,
240 struct rsnd_src *src) 97 struct rsnd_src *src)
241{ 98{
@@ -283,34 +140,6 @@ unsigned int rsnd_src_get_ssi_rate(struct rsnd_priv *priv,
283 return rate; 140 return rate;
284} 141}
285 142
286static int rsnd_src_set_convert_rate(struct rsnd_mod *mod,
287 struct rsnd_dai_stream *io)
288{
289 struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io);
290 struct rsnd_src *src = rsnd_mod_to_src(mod);
291 u32 convert_rate = rsnd_src_convert_rate(io, src);
292 u32 fsrate = 0;
293
294 if (convert_rate)
295 fsrate = 0x0400000 / convert_rate * runtime->rate;
296
297 /* Set channel number and output bit length */
298 rsnd_mod_write(mod, SRC_ADINR, rsnd_get_adinr_bit(mod, io));
299
300 /* Enable the initial value of IFS */
301 if (fsrate) {
302 rsnd_mod_write(mod, SRC_IFSCR, 1);
303
304 /* Set initial value of IFS */
305 rsnd_mod_write(mod, SRC_IFSVR, fsrate);
306 }
307
308 /* use DMA transfer */
309 rsnd_mod_write(mod, SRC_BUSIF_MODE, 1);
310
311 return 0;
312}
313
314static int rsnd_src_hw_params(struct rsnd_mod *mod, 143static int rsnd_src_hw_params(struct rsnd_mod *mod,
315 struct rsnd_dai_stream *io, 144 struct rsnd_dai_stream *io,
316 struct snd_pcm_substream *substream, 145 struct snd_pcm_substream *substream,
@@ -319,9 +148,6 @@ static int rsnd_src_hw_params(struct rsnd_mod *mod,
319 struct rsnd_src *src = rsnd_mod_to_src(mod); 148 struct rsnd_src *src = rsnd_mod_to_src(mod);
320 struct snd_soc_pcm_runtime *fe = substream->private_data; 149 struct snd_soc_pcm_runtime *fe = substream->private_data;
321 150
322 /* default value (mainly for non-DT) */
323 src->convert_rate = src->info->convert_rate;
324
325 /* 151 /*
326 * SRC assumes that it is used under DPCM if user want to use 152 * SRC assumes that it is used under DPCM if user want to use
327 * sampling rate convert. Then, SRC should be FE. 153 * sampling rate convert. Then, SRC should be FE.
@@ -347,250 +173,112 @@ static int rsnd_src_hw_params(struct rsnd_mod *mod,
347 return 0; 173 return 0;
348} 174}
349 175
350static int rsnd_src_init(struct rsnd_mod *mod, 176static void rsnd_src_set_convert_rate(struct rsnd_dai_stream *io,
351 struct rsnd_priv *priv) 177 struct rsnd_mod *mod)
352{
353 struct rsnd_src *src = rsnd_mod_to_src(mod);
354
355 rsnd_mod_power_on(mod);
356
357 rsnd_src_soft_reset(mod);
358
359 rsnd_src_initialize_lock(mod);
360
361 src->err = 0;
362
363 /* reset sync convert_rate */
364 src->sync.val = 0;
365
366 return 0;
367}
368
369static int rsnd_src_quit(struct rsnd_mod *mod,
370 struct rsnd_dai_stream *io,
371 struct rsnd_priv *priv)
372{ 178{
373 struct rsnd_src *src = rsnd_mod_to_src(mod); 179 struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
374 struct device *dev = rsnd_priv_to_dev(priv); 180 struct device *dev = rsnd_priv_to_dev(priv);
181 struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io);
182 struct rsnd_src *src = rsnd_mod_to_src(mod);
183 u32 convert_rate = rsnd_src_convert_rate(io, src);
184 u32 ifscr, fsrate, adinr;
185 u32 cr, route;
186 u32 bsdsr, bsisr;
187 uint ratio;
375 188
376 rsnd_mod_power_off(mod); 189 if (!runtime)
377 190 return;
378 if (src->err)
379 dev_warn(dev, "%s[%d] under/over flow err = %d\n",
380 rsnd_mod_name(mod), rsnd_mod_id(mod), src->err);
381
382 src->convert_rate = 0;
383
384 /* reset sync convert_rate */
385 src->sync.val = 0;
386
387 return 0;
388}
389
390static int rsnd_src_start(struct rsnd_mod *mod)
391{
392 rsnd_src_initialize_unlock(mod);
393
394 return 0;
395}
396
397static int rsnd_src_stop(struct rsnd_mod *mod)
398{
399 /* nothing to do */
400 return 0;
401}
402 191
403/* 192 /* 6 - 1/6 are very enough ratio for SRC_BSDSR */
404 * Gen1 functions 193 if (!convert_rate)
405 */ 194 ratio = 0;
406static int rsnd_src_set_route_gen1(struct rsnd_dai_stream *io, 195 else if (convert_rate > runtime->rate)
407 struct rsnd_mod *mod) 196 ratio = 100 * convert_rate / runtime->rate;
408{ 197 else
409 struct src_route_config { 198 ratio = 100 * runtime->rate / convert_rate;
410 u32 mask;
411 int shift;
412 } routes[] = {
413 { 0xF, 0, }, /* 0 */
414 { 0xF, 4, }, /* 1 */
415 { 0xF, 8, }, /* 2 */
416 { 0x7, 12, }, /* 3 */
417 { 0x7, 16, }, /* 4 */
418 { 0x7, 20, }, /* 5 */
419 { 0x7, 24, }, /* 6 */
420 { 0x3, 28, }, /* 7 */
421 { 0x3, 30, }, /* 8 */
422 };
423 u32 mask;
424 u32 val;
425 int id;
426 199
427 id = rsnd_mod_id(mod); 200 if (ratio > 600) {
428 if (id < 0 || id >= ARRAY_SIZE(routes)) 201 dev_err(dev, "FSO/FSI ratio error\n");
429 return -EIO; 202 return;
203 }
430 204
431 /* 205 /*
432 * SRC_ROUTE_SELECT 206 * SRC_ADINR
433 */ 207 */
434 val = rsnd_io_is_play(io) ? 0x1 : 0x2; 208 adinr = rsnd_get_adinr_bit(mod, io) |
435 val = val << routes[id].shift; 209 rsnd_get_adinr_chan(mod, io);
436 mask = routes[id].mask << routes[id].shift;
437
438 rsnd_mod_bset(mod, SRC_ROUTE_SEL, mask, val);
439
440 return 0;
441}
442
443static int rsnd_src_set_convert_timing_gen1(struct rsnd_dai_stream *io,
444 struct rsnd_mod *mod)
445{
446 struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
447 struct rsnd_src *src = rsnd_mod_to_src(mod);
448 struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io);
449 u32 convert_rate = rsnd_src_convert_rate(io, src);
450 u32 mask;
451 u32 val;
452 int shift;
453 int id = rsnd_mod_id(mod);
454 int ret;
455 210
456 /* 211 /*
457 * SRC_TIMING_SELECT 212 * SRC_IFSCR / SRC_IFSVR
458 */ 213 */
459 shift = (id % 4) * 8; 214 ifscr = 0;
460 mask = 0x1F << shift; 215 fsrate = 0;
216 if (convert_rate) {
217 ifscr = 1;
218 fsrate = 0x0400000 / convert_rate * runtime->rate;
219 }
461 220
462 /* 221 /*
463 * ADG is used as source clock if SRC was used, 222 * SRC_SRCCR / SRC_ROUTE_MODE0
464 * then, SSI WS is used as destination clock.
465 * SSI WS is used as source clock if SRC is not used
466 * (when playback, source/destination become reverse when capture)
467 */ 223 */
468 ret = 0; 224 cr = 0x00011110;
225 route = 0x0;
469 if (convert_rate) { 226 if (convert_rate) {
470 /* use ADG */ 227 route = 0x1;
471 val = 0;
472 ret = rsnd_adg_set_convert_clk_gen1(priv, mod,
473 runtime->rate,
474 convert_rate);
475 } else if (8 == id) {
476 /* use SSI WS, but SRU8 is special */
477 val = id << shift;
478 } else {
479 /* use SSI WS */
480 val = (id + 1) << shift;
481 }
482 228
483 if (ret < 0) 229 if (rsnd_enable_sync_convert(src)) {
484 return ret; 230 cr |= 0x1;
231 route |= rsnd_io_is_play(io) ?
232 (0x1 << 24) : (0x1 << 25);
233 }
234 }
485 235
486 switch (id / 4) { 236 /*
487 case 0: 237 * SRC_BSDSR / SRC_BSISR
488 rsnd_mod_bset(mod, SRC_TMG_SEL0, mask, val); 238 */
489 break; 239 switch (rsnd_mod_id(mod)) {
490 case 1: 240 case 5:
491 rsnd_mod_bset(mod, SRC_TMG_SEL1, mask, val); 241 case 6:
242 case 7:
243 case 8:
244 bsdsr = 0x02400000; /* 6 - 1/6 */
245 bsisr = 0x00100060; /* 6 - 1/6 */
492 break; 246 break;
493 case 2: 247 default:
494 rsnd_mod_bset(mod, SRC_TMG_SEL2, mask, val); 248 bsdsr = 0x01800000; /* 6 - 1/6 */
249 bsisr = 0x00100060 ;/* 6 - 1/6 */
495 break; 250 break;
496 } 251 }
497 252
498 return 0; 253 rsnd_mod_write(mod, SRC_SRCIR, 1); /* initialize */
499} 254 rsnd_mod_write(mod, SRC_ADINR, adinr);
500 255 rsnd_mod_write(mod, SRC_IFSCR, ifscr);
501static int rsnd_src_set_convert_rate_gen1(struct rsnd_mod *mod, 256 rsnd_mod_write(mod, SRC_IFSVR, fsrate);
502 struct rsnd_dai_stream *io) 257 rsnd_mod_write(mod, SRC_SRCCR, cr);
503{ 258 rsnd_mod_write(mod, SRC_BSDSR, bsdsr);
504 struct rsnd_src *src = rsnd_mod_to_src(mod); 259 rsnd_mod_write(mod, SRC_BSISR, bsisr);
505 int ret; 260 rsnd_mod_write(mod, SRC_SRCIR, 0); /* cancel initialize */
506
507 ret = rsnd_src_set_convert_rate(mod, io);
508 if (ret < 0)
509 return ret;
510
511 /* Select SRC mode (fixed value) */
512 rsnd_mod_write(mod, SRC_SRCCR, 0x00010110);
513
514 /* Set the restriction value of the FS ratio (98%) */
515 rsnd_mod_write(mod, SRC_MNFSR,
516 rsnd_mod_read(mod, SRC_IFSVR) / 100 * 98);
517
518 /* Gen1/Gen2 are not compatible */
519 if (rsnd_src_convert_rate(io, src))
520 rsnd_mod_write(mod, SRC_ROUTE_MODE0, 1);
521
522 /* no SRC_BFSSR settings, since SRC_SRCCR::BUFMD is 0 */
523
524 return 0;
525}
526
527static int rsnd_src_init_gen1(struct rsnd_mod *mod,
528 struct rsnd_dai_stream *io,
529 struct rsnd_priv *priv)
530{
531 int ret;
532
533 ret = rsnd_src_init(mod, priv);
534 if (ret < 0)
535 return ret;
536
537 ret = rsnd_src_set_route_gen1(io, mod);
538 if (ret < 0)
539 return ret;
540
541 ret = rsnd_src_set_convert_rate_gen1(mod, io);
542 if (ret < 0)
543 return ret;
544
545 ret = rsnd_src_set_convert_timing_gen1(io, mod);
546 if (ret < 0)
547 return ret;
548
549 return 0;
550}
551
552static int rsnd_src_start_gen1(struct rsnd_mod *mod,
553 struct rsnd_dai_stream *io,
554 struct rsnd_priv *priv)
555{
556 int id = rsnd_mod_id(mod);
557
558 rsnd_mod_bset(mod, SRC_ROUTE_CTRL, (1 << id), (1 << id));
559
560 return rsnd_src_start(mod);
561}
562
563static int rsnd_src_stop_gen1(struct rsnd_mod *mod,
564 struct rsnd_dai_stream *io,
565 struct rsnd_priv *priv)
566{
567 int id = rsnd_mod_id(mod);
568 261
569 rsnd_mod_bset(mod, SRC_ROUTE_CTRL, (1 << id), 0); 262 rsnd_mod_write(mod, SRC_ROUTE_MODE0, route);
263 rsnd_mod_write(mod, SRC_I_BUSIF_MODE, 1);
264 rsnd_mod_write(mod, SRC_O_BUSIF_MODE, 1);
265 rsnd_mod_write(mod, SRC_BUSIF_DALIGN, rsnd_get_dalign(mod, io));
570 266
571 return rsnd_src_stop(mod); 267 if (convert_rate)
268 rsnd_adg_set_convert_clk_gen2(mod, io,
269 runtime->rate,
270 convert_rate);
271 else
272 rsnd_adg_set_convert_timing_gen2(mod, io);
572} 273}
573 274
574static struct rsnd_mod_ops rsnd_src_gen1_ops = { 275#define rsnd_src_irq_enable(mod) rsnd_src_irq_ctrol(mod, 1)
575 .name = SRC_NAME, 276#define rsnd_src_irq_disable(mod) rsnd_src_irq_ctrol(mod, 0)
576 .dma_req = rsnd_src_dma_req, 277static void rsnd_src_irq_ctrol(struct rsnd_mod *mod, int enable)
577 .init = rsnd_src_init_gen1,
578 .quit = rsnd_src_quit,
579 .start = rsnd_src_start_gen1,
580 .stop = rsnd_src_stop_gen1,
581 .hw_params = rsnd_src_hw_params,
582};
583
584/*
585 * Gen2 functions
586 */
587#define rsnd_src_irq_enable_gen2(mod) rsnd_src_irq_ctrol_gen2(mod, 1)
588#define rsnd_src_irq_disable_gen2(mod) rsnd_src_irq_ctrol_gen2(mod, 0)
589static void rsnd_src_irq_ctrol_gen2(struct rsnd_mod *mod, int enable)
590{ 278{
591 struct rsnd_src *src = rsnd_mod_to_src(mod); 279 struct rsnd_src *src = rsnd_mod_to_src(mod);
592 u32 sys_int_val, int_val, sys_int_mask; 280 u32 sys_int_val, int_val, sys_int_mask;
593 int irq = src->info->irq; 281 int irq = src->irq;
594 int id = rsnd_mod_id(mod); 282 int id = rsnd_mod_id(mod);
595 283
596 sys_int_val = 284 sys_int_val =
@@ -600,7 +288,7 @@ static void rsnd_src_irq_ctrol_gen2(struct rsnd_mod *mod, int enable)
600 /* 288 /*
601 * IRQ is not supported on non-DT 289 * IRQ is not supported on non-DT
602 * see 290 * see
603 * rsnd_src_probe_gen2() 291 * rsnd_src_probe_()
604 */ 292 */
605 if ((irq <= 0) || !enable) { 293 if ((irq <= 0) || !enable) {
606 sys_int_val = 0; 294 sys_int_val = 0;
@@ -620,7 +308,7 @@ static void rsnd_src_irq_ctrol_gen2(struct rsnd_mod *mod, int enable)
620 rsnd_mod_bset(mod, SCU_SYS_INT_EN1, sys_int_mask, sys_int_val); 308 rsnd_mod_bset(mod, SCU_SYS_INT_EN1, sys_int_mask, sys_int_val);
621} 309}
622 310
623static void rsnd_src_error_clear_gen2(struct rsnd_mod *mod) 311static void rsnd_src_status_clear(struct rsnd_mod *mod)
624{ 312{
625 u32 val = OUF_SRC(rsnd_mod_id(mod)); 313 u32 val = OUF_SRC(rsnd_mod_id(mod));
626 314
@@ -628,7 +316,7 @@ static void rsnd_src_error_clear_gen2(struct rsnd_mod *mod)
628 rsnd_mod_bset(mod, SCU_SYS_STATUS1, val, val); 316 rsnd_mod_bset(mod, SCU_SYS_STATUS1, val, val);
629} 317}
630 318
631static bool rsnd_src_error_record_gen2(struct rsnd_mod *mod) 319static bool rsnd_src_record_error(struct rsnd_mod *mod)
632{ 320{
633 struct rsnd_src *src = rsnd_mod_to_src(mod); 321 struct rsnd_src *src = rsnd_mod_to_src(mod);
634 u32 val0, val1; 322 u32 val0, val1;
@@ -652,22 +340,16 @@ static bool rsnd_src_error_record_gen2(struct rsnd_mod *mod)
652 ret = true; 340 ret = true;
653 } 341 }
654 342
655 /* clear error static */
656 rsnd_src_error_clear_gen2(mod);
657
658 return ret; 343 return ret;
659} 344}
660 345
661static int _rsnd_src_start_gen2(struct rsnd_mod *mod, 346static int rsnd_src_start(struct rsnd_mod *mod,
662 struct rsnd_dai_stream *io) 347 struct rsnd_dai_stream *io,
348 struct rsnd_priv *priv)
663{ 349{
664 struct rsnd_src *src = rsnd_mod_to_src(mod); 350 struct rsnd_src *src = rsnd_mod_to_src(mod);
665 u32 val; 351 u32 val;
666 352
667 val = rsnd_get_dalign(mod, io);
668
669 rsnd_mod_write(mod, SRC_BUSIF_DALIGN, val);
670
671 /* 353 /*
672 * WORKAROUND 354 * WORKAROUND
673 * 355 *
@@ -678,247 +360,149 @@ static int _rsnd_src_start_gen2(struct rsnd_mod *mod,
678 360
679 rsnd_mod_write(mod, SRC_CTRL, val); 361 rsnd_mod_write(mod, SRC_CTRL, val);
680 362
681 rsnd_src_error_clear_gen2(mod); 363 return 0;
682 364}
683 rsnd_src_start(mod);
684 365
685 rsnd_src_irq_enable_gen2(mod); 366static int rsnd_src_stop(struct rsnd_mod *mod,
367 struct rsnd_dai_stream *io,
368 struct rsnd_priv *priv)
369{
370 /*
371 * stop SRC output only
372 * see rsnd_src_quit
373 */
374 rsnd_mod_write(mod, SRC_CTRL, 0x01);
686 375
687 return 0; 376 return 0;
688} 377}
689 378
690static int _rsnd_src_stop_gen2(struct rsnd_mod *mod) 379static int rsnd_src_init(struct rsnd_mod *mod,
380 struct rsnd_dai_stream *io,
381 struct rsnd_priv *priv)
691{ 382{
692 rsnd_src_irq_disable_gen2(mod); 383 struct rsnd_src *src = rsnd_mod_to_src(mod);
693 384
694 rsnd_mod_write(mod, SRC_CTRL, 0); 385 rsnd_mod_power_on(mod);
386
387 rsnd_src_activation(mod);
388
389 rsnd_src_set_convert_rate(io, mod);
695 390
696 rsnd_src_error_record_gen2(mod); 391 rsnd_src_status_clear(mod);
392
393 rsnd_src_irq_enable(mod);
394
395 src->err = 0;
697 396
698 return rsnd_src_stop(mod); 397 /* reset sync convert_rate */
398 src->sync.val = 0;
399
400 return 0;
699} 401}
700 402
701static void __rsnd_src_interrupt_gen2(struct rsnd_mod *mod, 403static int rsnd_src_quit(struct rsnd_mod *mod,
702 struct rsnd_dai_stream *io) 404 struct rsnd_dai_stream *io,
405 struct rsnd_priv *priv)
703{ 406{
704 struct rsnd_priv *priv = rsnd_mod_to_priv(mod); 407 struct rsnd_src *src = rsnd_mod_to_src(mod);
705 408 struct device *dev = rsnd_priv_to_dev(priv);
706 spin_lock(&priv->lock);
707 409
708 /* ignore all cases if not working */ 410 rsnd_src_irq_disable(mod);
709 if (!rsnd_io_is_working(io))
710 goto rsnd_src_interrupt_gen2_out;
711 411
712 if (rsnd_src_error_record_gen2(mod)) { 412 /* stop both out/in */
713 struct rsnd_priv *priv = rsnd_mod_to_priv(mod); 413 rsnd_mod_write(mod, SRC_CTRL, 0);
714 struct rsnd_src *src = rsnd_mod_to_src(mod);
715 struct device *dev = rsnd_priv_to_dev(priv);
716 414
717 dev_dbg(dev, "%s[%d] restart\n", 415 rsnd_src_halt(mod);
718 rsnd_mod_name(mod), rsnd_mod_id(mod));
719 416
720 _rsnd_src_stop_gen2(mod); 417 rsnd_mod_power_off(mod);
721 if (src->err < 1024)
722 _rsnd_src_start_gen2(mod, io);
723 else
724 dev_warn(dev, "no more SRC restart\n");
725 }
726 418
727rsnd_src_interrupt_gen2_out: 419 if (src->err)
728 spin_unlock(&priv->lock); 420 dev_warn(dev, "%s[%d] under/over flow err = %d\n",
729} 421 rsnd_mod_name(mod), rsnd_mod_id(mod), src->err);
730 422
731static irqreturn_t rsnd_src_interrupt_gen2(int irq, void *data) 423 src->convert_rate = 0;
732{
733 struct rsnd_mod *mod = data;
734 424
735 rsnd_mod_interrupt(mod, __rsnd_src_interrupt_gen2); 425 /* reset sync convert_rate */
426 src->sync.val = 0;
736 427
737 return IRQ_HANDLED; 428 return 0;
738} 429}
739 430
740static int rsnd_src_set_convert_rate_gen2(struct rsnd_mod *mod, 431static void __rsnd_src_interrupt(struct rsnd_mod *mod,
741 struct rsnd_dai_stream *io) 432 struct rsnd_dai_stream *io)
742{ 433{
743 struct rsnd_priv *priv = rsnd_mod_to_priv(mod); 434 struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
744 struct device *dev = rsnd_priv_to_dev(priv);
745 struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io);
746 struct rsnd_src *src = rsnd_mod_to_src(mod); 435 struct rsnd_src *src = rsnd_mod_to_src(mod);
747 u32 convert_rate = rsnd_src_convert_rate(io, src); 436 struct device *dev = rsnd_priv_to_dev(priv);
748 u32 cr, route;
749 uint ratio;
750 int ret;
751 437
752 /* 6 - 1/6 are very enough ratio for SRC_BSDSR */ 438 spin_lock(&priv->lock);
753 if (!convert_rate)
754 ratio = 0;
755 else if (convert_rate > runtime->rate)
756 ratio = 100 * convert_rate / runtime->rate;
757 else
758 ratio = 100 * runtime->rate / convert_rate;
759 439
760 if (ratio > 600) { 440 /* ignore all cases if not working */
761 dev_err(dev, "FSO/FSI ratio error\n"); 441 if (!rsnd_io_is_working(io))
762 return -EINVAL; 442 goto rsnd_src_interrupt_out;
763 }
764 443
765 ret = rsnd_src_set_convert_rate(mod, io); 444 if (rsnd_src_record_error(mod)) {
766 if (ret < 0)
767 return ret;
768 445
769 cr = 0x00011110; 446 dev_dbg(dev, "%s[%d] restart\n",
770 route = 0x0; 447 rsnd_mod_name(mod), rsnd_mod_id(mod));
771 if (convert_rate) {
772 route = 0x1;
773 448
774 if (rsnd_enable_sync_convert(src)) { 449 rsnd_src_stop(mod, io, priv);
775 cr |= 0x1; 450 rsnd_src_start(mod, io, priv);
776 route |= rsnd_io_is_play(io) ?
777 (0x1 << 24) : (0x1 << 25);
778 }
779 } 451 }
780 452
781 rsnd_mod_write(mod, SRC_SRCCR, cr); 453 if (src->err > 1024) {
782 rsnd_mod_write(mod, SRC_ROUTE_MODE0, route); 454 rsnd_src_irq_disable(mod);
783 455
784 switch (rsnd_mod_id(mod)) { 456 dev_warn(dev, "no more %s[%d] restart\n",
785 case 5: 457 rsnd_mod_name(mod), rsnd_mod_id(mod));
786 case 6:
787 case 7:
788 case 8:
789 rsnd_mod_write(mod, SRC_BSDSR, 0x02400000);
790 break;
791 default:
792 rsnd_mod_write(mod, SRC_BSDSR, 0x01800000);
793 break;
794 } 458 }
795 459
796 rsnd_mod_write(mod, SRC_BSISR, 0x00100060); 460 rsnd_src_status_clear(mod);
461rsnd_src_interrupt_out:
797 462
798 return 0; 463 spin_unlock(&priv->lock);
799} 464}
800 465
801static int rsnd_src_set_convert_timing_gen2(struct rsnd_dai_stream *io, 466static irqreturn_t rsnd_src_interrupt(int irq, void *data)
802 struct rsnd_mod *mod)
803{ 467{
804 struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io); 468 struct rsnd_mod *mod = data;
805 struct rsnd_src *src = rsnd_mod_to_src(mod);
806 u32 convert_rate = rsnd_src_convert_rate(io, src);
807 int ret;
808 469
809 if (convert_rate) 470 rsnd_mod_interrupt(mod, __rsnd_src_interrupt);
810 ret = rsnd_adg_set_convert_clk_gen2(mod, io,
811 runtime->rate,
812 convert_rate);
813 else
814 ret = rsnd_adg_set_convert_timing_gen2(mod, io);
815 471
816 return ret; 472 return IRQ_HANDLED;
817} 473}
818 474
819static int rsnd_src_probe_gen2(struct rsnd_mod *mod, 475static int rsnd_src_probe_(struct rsnd_mod *mod,
820 struct rsnd_dai_stream *io, 476 struct rsnd_dai_stream *io,
821 struct rsnd_priv *priv) 477 struct rsnd_priv *priv)
822{ 478{
823 struct rsnd_src *src = rsnd_mod_to_src(mod); 479 struct rsnd_src *src = rsnd_mod_to_src(mod);
824 struct device *dev = rsnd_priv_to_dev(priv); 480 struct device *dev = rsnd_priv_to_dev(priv);
825 int irq = src->info->irq; 481 int irq = src->irq;
826 int ret; 482 int ret;
827 483
828 if (irq > 0) { 484 if (irq > 0) {
829 /* 485 /*
830 * IRQ is not supported on non-DT 486 * IRQ is not supported on non-DT
831 * see 487 * see
832 * rsnd_src_irq_enable_gen2() 488 * rsnd_src_irq_enable()
833 */ 489 */
834 ret = devm_request_irq(dev, irq, 490 ret = devm_request_irq(dev, irq,
835 rsnd_src_interrupt_gen2, 491 rsnd_src_interrupt,
836 IRQF_SHARED, 492 IRQF_SHARED,
837 dev_name(dev), mod); 493 dev_name(dev), mod);
838 if (ret) 494 if (ret)
839 return ret; 495 return ret;
840 } 496 }
841 497
842 ret = rsnd_dma_init(io, 498 src->dma = rsnd_dma_attach(io, mod, 0);
843 rsnd_mod_to_dma(mod), 499 if (IS_ERR(src->dma))
844 src->info->dma_id); 500 return PTR_ERR(src->dma);
845 501
846 return ret; 502 return ret;
847} 503}
848 504
849static int rsnd_src_remove_gen2(struct rsnd_mod *mod, 505static int rsnd_src_pcm_new(struct rsnd_mod *mod,
850 struct rsnd_dai_stream *io,
851 struct rsnd_priv *priv)
852{
853 rsnd_dma_quit(io, rsnd_mod_to_dma(mod));
854
855 return 0;
856}
857
858static int rsnd_src_init_gen2(struct rsnd_mod *mod,
859 struct rsnd_dai_stream *io,
860 struct rsnd_priv *priv)
861{
862 int ret;
863
864 ret = rsnd_src_init(mod, priv);
865 if (ret < 0)
866 return ret;
867
868 ret = rsnd_src_set_convert_rate_gen2(mod, io);
869 if (ret < 0)
870 return ret;
871
872 ret = rsnd_src_set_convert_timing_gen2(io, mod);
873 if (ret < 0)
874 return ret;
875
876 return 0;
877}
878
879static int rsnd_src_start_gen2(struct rsnd_mod *mod,
880 struct rsnd_dai_stream *io,
881 struct rsnd_priv *priv)
882{
883 rsnd_dma_start(io, rsnd_mod_to_dma(mod));
884
885 return _rsnd_src_start_gen2(mod, io);
886}
887
888static int rsnd_src_stop_gen2(struct rsnd_mod *mod,
889 struct rsnd_dai_stream *io,
890 struct rsnd_priv *priv)
891{
892 int ret;
893
894 ret = _rsnd_src_stop_gen2(mod);
895
896 rsnd_dma_stop(io, rsnd_mod_to_dma(mod));
897
898 return ret;
899}
900
901static void rsnd_src_reconvert_update(struct rsnd_dai_stream *io,
902 struct rsnd_mod *mod)
903{
904 struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io);
905 struct rsnd_src *src = rsnd_mod_to_src(mod);
906 u32 convert_rate = rsnd_src_convert_rate(io, src);
907 u32 fsrate;
908
909 if (!runtime)
910 return;
911
912 if (!convert_rate)
913 convert_rate = runtime->rate;
914
915 fsrate = 0x0400000 / convert_rate * runtime->rate;
916
917 /* update IFS */
918 rsnd_mod_write(mod, SRC_IFSVR, fsrate);
919}
920
921static int rsnd_src_pcm_new_gen2(struct rsnd_mod *mod,
922 struct rsnd_dai_stream *io, 506 struct rsnd_dai_stream *io,
923 struct snd_soc_pcm_runtime *rtd) 507 struct snd_soc_pcm_runtime *rtd)
924{ 508{
@@ -950,7 +534,7 @@ static int rsnd_src_pcm_new_gen2(struct rsnd_mod *mod,
950 rsnd_io_is_play(io) ? 534 rsnd_io_is_play(io) ?
951 "SRC Out Rate Switch" : 535 "SRC Out Rate Switch" :
952 "SRC In Rate Switch", 536 "SRC In Rate Switch",
953 rsnd_src_reconvert_update, 537 rsnd_src_set_convert_rate,
954 &src->sen, 1); 538 &src->sen, 1);
955 if (ret < 0) 539 if (ret < 0)
956 return ret; 540 return ret;
@@ -959,23 +543,22 @@ static int rsnd_src_pcm_new_gen2(struct rsnd_mod *mod,
959 rsnd_io_is_play(io) ? 543 rsnd_io_is_play(io) ?
960 "SRC Out Rate" : 544 "SRC Out Rate" :
961 "SRC In Rate", 545 "SRC In Rate",
962 rsnd_src_reconvert_update, 546 rsnd_src_set_convert_rate,
963 &src->sync, 192000); 547 &src->sync, 192000);
964 548
965 return ret; 549 return ret;
966} 550}
967 551
968static struct rsnd_mod_ops rsnd_src_gen2_ops = { 552static struct rsnd_mod_ops rsnd_src_ops = {
969 .name = SRC_NAME, 553 .name = SRC_NAME,
970 .dma_req = rsnd_src_dma_req, 554 .dma_req = rsnd_src_dma_req,
971 .probe = rsnd_src_probe_gen2, 555 .probe = rsnd_src_probe_,
972 .remove = rsnd_src_remove_gen2, 556 .init = rsnd_src_init,
973 .init = rsnd_src_init_gen2,
974 .quit = rsnd_src_quit, 557 .quit = rsnd_src_quit,
975 .start = rsnd_src_start_gen2, 558 .start = rsnd_src_start,
976 .stop = rsnd_src_stop_gen2, 559 .stop = rsnd_src_stop,
977 .hw_params = rsnd_src_hw_params, 560 .hw_params = rsnd_src_hw_params,
978 .pcm_new = rsnd_src_pcm_new_gen2, 561 .pcm_new = rsnd_src_pcm_new,
979}; 562};
980 563
981struct rsnd_mod *rsnd_src_mod_get(struct rsnd_priv *priv, int id) 564struct rsnd_mod *rsnd_src_mod_get(struct rsnd_priv *priv, int id)
@@ -983,113 +566,78 @@ struct rsnd_mod *rsnd_src_mod_get(struct rsnd_priv *priv, int id)
983 if (WARN_ON(id < 0 || id >= rsnd_src_nr(priv))) 566 if (WARN_ON(id < 0 || id >= rsnd_src_nr(priv)))
984 id = 0; 567 id = 0;
985 568
986 return rsnd_mod_get((struct rsnd_src *)(priv->src) + id); 569 return rsnd_mod_get(rsnd_src_get(priv, id));
987} 570}
988 571
989static void rsnd_of_parse_src(struct platform_device *pdev, 572int rsnd_src_probe(struct rsnd_priv *priv)
990 const struct rsnd_of_data *of_data,
991 struct rsnd_priv *priv)
992{ 573{
993 struct device_node *src_node; 574 struct device_node *node;
994 struct device_node *np; 575 struct device_node *np;
995 struct rcar_snd_info *info = rsnd_priv_to_info(priv);
996 struct rsnd_src_platform_info *src_info;
997 struct device *dev = &pdev->dev;
998 int nr, i;
999
1000 if (!of_data)
1001 return;
1002
1003 src_node = rsnd_src_of_node(priv);
1004 if (!src_node)
1005 return;
1006
1007 nr = of_get_child_count(src_node);
1008 if (!nr)
1009 goto rsnd_of_parse_src_end;
1010
1011 src_info = devm_kzalloc(dev,
1012 sizeof(struct rsnd_src_platform_info) * nr,
1013 GFP_KERNEL);
1014 if (!src_info) {
1015 dev_err(dev, "src info allocation error\n");
1016 goto rsnd_of_parse_src_end;
1017 }
1018
1019 info->src_info = src_info;
1020 info->src_info_nr = nr;
1021
1022 i = 0;
1023 for_each_child_of_node(src_node, np) {
1024 src_info[i].irq = irq_of_parse_and_map(np, 0);
1025
1026 i++;
1027 }
1028
1029rsnd_of_parse_src_end:
1030 of_node_put(src_node);
1031}
1032
1033int rsnd_src_probe(struct platform_device *pdev,
1034 const struct rsnd_of_data *of_data,
1035 struct rsnd_priv *priv)
1036{
1037 struct rcar_snd_info *info = rsnd_priv_to_info(priv);
1038 struct device *dev = rsnd_priv_to_dev(priv); 576 struct device *dev = rsnd_priv_to_dev(priv);
1039 struct rsnd_src *src; 577 struct rsnd_src *src;
1040 struct rsnd_mod_ops *ops;
1041 struct clk *clk; 578 struct clk *clk;
1042 char name[RSND_SRC_NAME_SIZE]; 579 char name[RSND_SRC_NAME_SIZE];
1043 int i, nr, ret; 580 int i, nr, ret;
1044 581
1045 ops = NULL; 582 /* This driver doesn't support Gen1 at this point */
1046 if (rsnd_is_gen1(priv)) { 583 if (rsnd_is_gen1(priv))
1047 ops = &rsnd_src_gen1_ops; 584 return 0;
1048 dev_warn(dev, "Gen1 support will be removed soon\n");
1049 }
1050 if (rsnd_is_gen2(priv))
1051 ops = &rsnd_src_gen2_ops;
1052 if (!ops) {
1053 dev_err(dev, "unknown Generation\n");
1054 return -EIO;
1055 }
1056 585
1057 rsnd_of_parse_src(pdev, of_data, priv); 586 node = rsnd_src_of_node(priv);
587 if (!node)
588 return 0; /* not used is not error */
1058 589
1059 /* 590 nr = of_get_child_count(node);
1060 * init SRC 591 if (!nr) {
1061 */ 592 ret = -EINVAL;
1062 nr = info->src_info_nr; 593 goto rsnd_src_probe_done;
1063 if (!nr) 594 }
1064 return 0;
1065 595
1066 src = devm_kzalloc(dev, sizeof(*src) * nr, GFP_KERNEL); 596 src = devm_kzalloc(dev, sizeof(*src) * nr, GFP_KERNEL);
1067 if (!src) 597 if (!src) {
1068 return -ENOMEM; 598 ret = -ENOMEM;
599 goto rsnd_src_probe_done;
600 }
1069 601
1070 priv->src_nr = nr; 602 priv->src_nr = nr;
1071 priv->src = src; 603 priv->src = src;
1072 604
1073 for_each_rsnd_src(src, priv, i) { 605 i = 0;
606 for_each_child_of_node(node, np) {
607 src = rsnd_src_get(priv, i);
608
1074 snprintf(name, RSND_SRC_NAME_SIZE, "%s.%d", 609 snprintf(name, RSND_SRC_NAME_SIZE, "%s.%d",
1075 SRC_NAME, i); 610 SRC_NAME, i);
1076 611
1077 clk = devm_clk_get(dev, name); 612 src->irq = irq_of_parse_and_map(np, 0);
1078 if (IS_ERR(clk)) 613 if (!src->irq) {
1079 return PTR_ERR(clk); 614 ret = -EINVAL;
615 goto rsnd_src_probe_done;
616 }
1080 617
1081 src->info = &info->src_info[i]; 618 clk = devm_clk_get(dev, name);
619 if (IS_ERR(clk)) {
620 ret = PTR_ERR(clk);
621 goto rsnd_src_probe_done;
622 }
1082 623
1083 ret = rsnd_mod_init(priv, rsnd_mod_get(src), ops, clk, RSND_MOD_SRC, i); 624 ret = rsnd_mod_init(priv, rsnd_mod_get(src),
625 &rsnd_src_ops, clk, RSND_MOD_SRC, i);
1084 if (ret) 626 if (ret)
1085 return ret; 627 goto rsnd_src_probe_done;
628
629 i++;
1086 } 630 }
1087 631
1088 return 0; 632 ret = 0;
633
634rsnd_src_probe_done:
635 of_node_put(node);
636
637 return ret;
1089} 638}
1090 639
1091void rsnd_src_remove(struct platform_device *pdev, 640void rsnd_src_remove(struct rsnd_priv *priv)
1092 struct rsnd_priv *priv)
1093{ 641{
1094 struct rsnd_src *src; 642 struct rsnd_src *src;
1095 int i; 643 int i;
diff --git a/sound/soc/sh/rcar/ssi.c b/sound/soc/sh/rcar/ssi.c
index 1427ec21bd7e..7ee89da4dd5f 100644
--- a/sound/soc/sh/rcar/ssi.c
+++ b/sound/soc/sh/rcar/ssi.c
@@ -24,7 +24,9 @@
24#define OIEN (1 << 26) /* Overflow Interrupt Enable */ 24#define OIEN (1 << 26) /* Overflow Interrupt Enable */
25#define IIEN (1 << 25) /* Idle Mode Interrupt Enable */ 25#define IIEN (1 << 25) /* Idle Mode Interrupt Enable */
26#define DIEN (1 << 24) /* Data Interrupt Enable */ 26#define DIEN (1 << 24) /* Data Interrupt Enable */
27 27#define CHNL_4 (1 << 22) /* Channels */
28#define CHNL_6 (2 << 22) /* Channels */
29#define CHNL_8 (3 << 22) /* Channels */
28#define DWL_8 (0 << 19) /* Data Word Length */ 30#define DWL_8 (0 << 19) /* Data Word Length */
29#define DWL_16 (1 << 19) /* Data Word Length */ 31#define DWL_16 (1 << 19) /* Data Word Length */
30#define DWL_18 (2 << 19) /* Data Word Length */ 32#define DWL_18 (2 << 19) /* Data Word Length */
@@ -39,6 +41,7 @@
39#define SCKP (1 << 13) /* Serial Bit Clock Polarity */ 41#define SCKP (1 << 13) /* Serial Bit Clock Polarity */
40#define SWSP (1 << 12) /* Serial WS Polarity */ 42#define SWSP (1 << 12) /* Serial WS Polarity */
41#define SDTA (1 << 10) /* Serial Data Alignment */ 43#define SDTA (1 << 10) /* Serial Data Alignment */
44#define PDTA (1 << 9) /* Parallel Data Alignment */
42#define DEL (1 << 8) /* Serial Data Delay */ 45#define DEL (1 << 8) /* Serial Data Delay */
43#define CKDV(v) (v << 4) /* Serial Clock Division Ratio */ 46#define CKDV(v) (v << 4) /* Serial Clock Division Ratio */
44#define TRMD (1 << 1) /* Transmit/Receive Mode Select */ 47#define TRMD (1 << 1) /* Transmit/Receive Mode Select */
@@ -56,35 +59,44 @@
56 * SSIWSR 59 * SSIWSR
57 */ 60 */
58#define CONT (1 << 8) /* WS Continue Function */ 61#define CONT (1 << 8) /* WS Continue Function */
62#define WS_MODE (1 << 0) /* WS Mode */
59 63
60#define SSI_NAME "ssi" 64#define SSI_NAME "ssi"
61 65
62struct rsnd_ssi { 66struct rsnd_ssi {
63 struct rsnd_ssi_platform_info *info; /* rcar_snd.h */
64 struct rsnd_ssi *parent; 67 struct rsnd_ssi *parent;
65 struct rsnd_mod mod; 68 struct rsnd_mod mod;
69 struct rsnd_mod *dma;
66 70
71 u32 flags;
67 u32 cr_own; 72 u32 cr_own;
68 u32 cr_clk; 73 u32 cr_clk;
74 u32 cr_mode;
75 u32 wsr;
69 int chan; 76 int chan;
77 int rate;
70 int err; 78 int err;
79 int irq;
71 unsigned int usrcnt; 80 unsigned int usrcnt;
72}; 81};
73 82
83/* flags */
84#define RSND_SSI_CLK_PIN_SHARE (1 << 0)
85#define RSND_SSI_NO_BUSIF (1 << 1) /* SSI+DMA without BUSIF */
86
74#define for_each_rsnd_ssi(pos, priv, i) \ 87#define for_each_rsnd_ssi(pos, priv, i) \
75 for (i = 0; \ 88 for (i = 0; \
76 (i < rsnd_ssi_nr(priv)) && \ 89 (i < rsnd_ssi_nr(priv)) && \
77 ((pos) = ((struct rsnd_ssi *)(priv)->ssi + i)); \ 90 ((pos) = ((struct rsnd_ssi *)(priv)->ssi + i)); \
78 i++) 91 i++)
79 92
93#define rsnd_ssi_get(priv, id) ((struct rsnd_ssi *)(priv->ssi) + id)
94#define rsnd_ssi_to_dma(mod) ((ssi)->dma)
80#define rsnd_ssi_nr(priv) ((priv)->ssi_nr) 95#define rsnd_ssi_nr(priv) ((priv)->ssi_nr)
81#define rsnd_mod_to_ssi(_mod) container_of((_mod), struct rsnd_ssi, mod) 96#define rsnd_mod_to_ssi(_mod) container_of((_mod), struct rsnd_ssi, mod)
82#define rsnd_ssi_pio_available(ssi) ((ssi)->info->irq > 0) 97#define rsnd_ssi_mode_flags(p) ((p)->flags)
83#define rsnd_ssi_parent(ssi) ((ssi)->parent) 98#define rsnd_ssi_is_parent(ssi, io) ((ssi) == rsnd_io_to_mod_ssip(io))
84#define rsnd_ssi_mode_flags(p) ((p)->info->flags) 99#define rsnd_ssi_is_multi_slave(ssi, io) ((mod) != rsnd_io_to_mod_ssi(io))
85#define rsnd_ssi_dai_id(ssi) ((ssi)->info->dai_id)
86#define rsnd_ssi_of_node(priv) \
87 of_get_child_by_name(rsnd_priv_to_dev(priv)->of_node, "rcar_sound,ssi")
88 100
89int rsnd_ssi_use_busif(struct rsnd_dai_stream *io) 101int rsnd_ssi_use_busif(struct rsnd_dai_stream *io)
90{ 102{
@@ -103,6 +115,16 @@ int rsnd_ssi_use_busif(struct rsnd_dai_stream *io)
103 return use_busif; 115 return use_busif;
104} 116}
105 117
118static void rsnd_ssi_status_clear(struct rsnd_mod *mod)
119{
120 rsnd_mod_write(mod, SSISR, 0);
121}
122
123static u32 rsnd_ssi_status_get(struct rsnd_mod *mod)
124{
125 return rsnd_mod_read(mod, SSISR);
126}
127
106static void rsnd_ssi_status_check(struct rsnd_mod *mod, 128static void rsnd_ssi_status_check(struct rsnd_mod *mod,
107 u32 bit) 129 u32 bit)
108{ 130{
@@ -112,7 +134,7 @@ static void rsnd_ssi_status_check(struct rsnd_mod *mod,
112 int i; 134 int i;
113 135
114 for (i = 0; i < 1024; i++) { 136 for (i = 0; i < 1024; i++) {
115 status = rsnd_mod_read(mod, SSISR); 137 status = rsnd_ssi_status_get(mod);
116 if (status & bit) 138 if (status & bit)
117 return; 139 return;
118 140
@@ -122,13 +144,79 @@ static void rsnd_ssi_status_check(struct rsnd_mod *mod,
122 dev_warn(dev, "status check failed\n"); 144 dev_warn(dev, "status check failed\n");
123} 145}
124 146
147static int rsnd_ssi_irq_enable(struct rsnd_mod *ssi_mod)
148{
149 struct rsnd_priv *priv = rsnd_mod_to_priv(ssi_mod);
150
151 if (rsnd_is_gen1(priv))
152 return 0;
153
154 /* enable SSI interrupt if Gen2 */
155 rsnd_mod_write(ssi_mod, SSI_INT_ENABLE,
156 rsnd_ssi_is_dma_mode(ssi_mod) ?
157 0x0e000000 : 0x0f000000);
158
159 return 0;
160}
161
162static int rsnd_ssi_irq_disable(struct rsnd_mod *ssi_mod)
163{
164 struct rsnd_priv *priv = rsnd_mod_to_priv(ssi_mod);
165
166 if (rsnd_is_gen1(priv))
167 return 0;
168
169 /* disable SSI interrupt if Gen2 */
170 rsnd_mod_write(ssi_mod, SSI_INT_ENABLE, 0x00000000);
171
172 return 0;
173}
174
175u32 rsnd_ssi_multi_slaves(struct rsnd_dai_stream *io)
176{
177 struct rsnd_mod *mod;
178 struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io);
179 struct rsnd_priv *priv = rsnd_io_to_priv(io);
180 struct device *dev = rsnd_priv_to_dev(priv);
181 enum rsnd_mod_type types[] = {
182 RSND_MOD_SSIM1,
183 RSND_MOD_SSIM2,
184 RSND_MOD_SSIM3,
185 };
186 int i, mask;
187
188 switch (runtime->channels) {
189 case 2: /* Multi channel is not needed for Stereo */
190 return 0;
191 case 6:
192 break;
193 default:
194 dev_err(dev, "unsupported channel\n");
195 return 0;
196 }
197
198 mask = 0;
199 for (i = 0; i < ARRAY_SIZE(types); i++) {
200 mod = rsnd_io_to_mod(io, types[i]);
201 if (!mod)
202 continue;
203
204 mask |= 1 << rsnd_mod_id(mod);
205 }
206
207 return mask;
208}
209
125static int rsnd_ssi_master_clk_start(struct rsnd_ssi *ssi, 210static int rsnd_ssi_master_clk_start(struct rsnd_ssi *ssi,
126 struct rsnd_dai_stream *io) 211 struct rsnd_dai_stream *io)
127{ 212{
128 struct rsnd_priv *priv = rsnd_io_to_priv(io); 213 struct rsnd_priv *priv = rsnd_io_to_priv(io);
129 struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io); 214 struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io);
130 struct device *dev = rsnd_priv_to_dev(priv); 215 struct device *dev = rsnd_priv_to_dev(priv);
216 struct rsnd_dai *rdai = rsnd_io_to_rdai(io);
131 struct rsnd_mod *mod = rsnd_mod_get(ssi); 217 struct rsnd_mod *mod = rsnd_mod_get(ssi);
218 struct rsnd_mod *ssi_parent_mod = rsnd_io_to_mod_ssip(io);
219 int slots = rsnd_get_slot_width(io);
132 int j, ret; 220 int j, ret;
133 int ssi_clk_mul_table[] = { 221 int ssi_clk_mul_table[] = {
134 1, 2, 4, 8, 16, 6, 12, 222 1, 2, 4, 8, 16, 6, 12,
@@ -136,6 +224,24 @@ static int rsnd_ssi_master_clk_start(struct rsnd_ssi *ssi,
136 unsigned int main_rate; 224 unsigned int main_rate;
137 unsigned int rate = rsnd_src_get_ssi_rate(priv, io, runtime); 225 unsigned int rate = rsnd_src_get_ssi_rate(priv, io, runtime);
138 226
227 if (!rsnd_rdai_is_clk_master(rdai))
228 return 0;
229
230 if (ssi_parent_mod && !rsnd_ssi_is_parent(mod, io))
231 return 0;
232
233 if (rsnd_ssi_is_multi_slave(mod, io))
234 return 0;
235
236 if (ssi->usrcnt > 1) {
237 if (ssi->rate != rate) {
238 dev_err(dev, "SSI parent/child should use same rate\n");
239 return -EINVAL;
240 }
241
242 return 0;
243 }
244
139 /* 245 /*
140 * Find best clock, and try to start ADG 246 * Find best clock, and try to start ADG
141 */ 247 */
@@ -143,15 +249,18 @@ static int rsnd_ssi_master_clk_start(struct rsnd_ssi *ssi,
143 249
144 /* 250 /*
145 * this driver is assuming that 251 * this driver is assuming that
146 * system word is 64fs (= 2 x 32bit) 252 * system word is 32bit x slots
147 * see rsnd_ssi_init() 253 * see rsnd_ssi_init()
148 */ 254 */
149 main_rate = rate * 32 * 2 * ssi_clk_mul_table[j]; 255 main_rate = rate * 32 * slots * ssi_clk_mul_table[j];
150 256
151 ret = rsnd_adg_ssi_clk_try_start(mod, main_rate); 257 ret = rsnd_adg_ssi_clk_try_start(mod, main_rate);
152 if (0 == ret) { 258 if (0 == ret) {
153 ssi->cr_clk = FORCE | SWL_32 | 259 ssi->cr_clk = FORCE | SWL_32 |
154 SCKD | SWSD | CKDV(j); 260 SCKD | SWSD | CKDV(j);
261 ssi->wsr = CONT;
262
263 ssi->rate = rate;
155 264
156 dev_dbg(dev, "%s[%d] outputs %u Hz\n", 265 dev_dbg(dev, "%s[%d] outputs %u Hz\n",
157 rsnd_mod_name(mod), 266 rsnd_mod_name(mod),
@@ -165,113 +274,91 @@ static int rsnd_ssi_master_clk_start(struct rsnd_ssi *ssi,
165 return -EIO; 274 return -EIO;
166} 275}
167 276
168static void rsnd_ssi_master_clk_stop(struct rsnd_ssi *ssi) 277static void rsnd_ssi_master_clk_stop(struct rsnd_ssi *ssi,
278 struct rsnd_dai_stream *io)
169{ 279{
280 struct rsnd_dai *rdai = rsnd_io_to_rdai(io);
170 struct rsnd_mod *mod = rsnd_mod_get(ssi); 281 struct rsnd_mod *mod = rsnd_mod_get(ssi);
282 struct rsnd_mod *ssi_parent_mod = rsnd_io_to_mod_ssip(io);
283
284 if (!rsnd_rdai_is_clk_master(rdai))
285 return;
286
287 if (ssi_parent_mod && !rsnd_ssi_is_parent(mod, io))
288 return;
289
290 if (ssi->usrcnt > 1)
291 return;
292
293 ssi->cr_clk = 0;
294 ssi->rate = 0;
171 295
172 ssi->cr_clk = 0;
173 rsnd_adg_ssi_clk_stop(mod); 296 rsnd_adg_ssi_clk_stop(mod);
174} 297}
175 298
176static void rsnd_ssi_hw_start(struct rsnd_ssi *ssi, 299static int rsnd_ssi_config_init(struct rsnd_ssi *ssi,
177 struct rsnd_dai_stream *io) 300 struct rsnd_dai_stream *io)
178{ 301{
179 struct rsnd_priv *priv = rsnd_io_to_priv(io);
180 struct rsnd_dai *rdai = rsnd_io_to_rdai(io); 302 struct rsnd_dai *rdai = rsnd_io_to_rdai(io);
181 struct device *dev = rsnd_priv_to_dev(priv); 303 struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io);
182 struct rsnd_mod *mod = rsnd_mod_get(ssi); 304 u32 cr_own;
183 u32 cr_mode; 305 u32 cr_mode;
184 u32 cr; 306 u32 wsr;
307 int is_tdm;
185 308
186 if (0 == ssi->usrcnt) { 309 is_tdm = (rsnd_get_slot_width(io) >= 6) ? 1 : 0;
187 rsnd_mod_power_on(mod);
188 310
189 if (rsnd_rdai_is_clk_master(rdai)) { 311 /*
190 struct rsnd_ssi *ssi_parent = rsnd_ssi_parent(ssi); 312 * always use 32bit system word.
313 * see also rsnd_ssi_master_clk_enable()
314 */
315 cr_own = FORCE | SWL_32 | PDTA;
191 316
192 if (ssi_parent) 317 if (rdai->bit_clk_inv)
193 rsnd_ssi_hw_start(ssi_parent, io); 318 cr_own |= SCKP;
194 else 319 if (rdai->frm_clk_inv ^ is_tdm)
195 rsnd_ssi_master_clk_start(ssi, io); 320 cr_own |= SWSP;
196 } 321 if (rdai->data_alignment)
322 cr_own |= SDTA;
323 if (rdai->sys_delay)
324 cr_own |= DEL;
325 if (rsnd_io_is_play(io))
326 cr_own |= TRMD;
327
328 switch (runtime->sample_bits) {
329 case 16:
330 cr_own |= DWL_16;
331 break;
332 case 32:
333 cr_own |= DWL_24;
334 break;
335 default:
336 return -EINVAL;
197 } 337 }
198 338
199 if (rsnd_ssi_is_dma_mode(mod)) { 339 if (rsnd_ssi_is_dma_mode(rsnd_mod_get(ssi))) {
200 cr_mode = UIEN | OIEN | /* over/under run */ 340 cr_mode = UIEN | OIEN | /* over/under run */
201 DMEN; /* DMA : enable DMA */ 341 DMEN; /* DMA : enable DMA */
202 } else { 342 } else {
203 cr_mode = DIEN; /* PIO : enable Data interrupt */ 343 cr_mode = DIEN; /* PIO : enable Data interrupt */
204 } 344 }
205 345
206 cr = ssi->cr_own | 346 /*
207 ssi->cr_clk | 347 * TDM Extend Mode
208 cr_mode | 348 * see
209 EN; 349 * rsnd_ssiu_init_gen2()
210 350 */
211 rsnd_mod_write(mod, SSICR, cr); 351 wsr = ssi->wsr;
212 352 if (is_tdm) {
213 /* enable WS continue */ 353 wsr |= WS_MODE;
214 if (rsnd_rdai_is_clk_master(rdai)) 354 cr_own |= CHNL_8;
215 rsnd_mod_write(mod, SSIWSR, CONT);
216
217 /* clear error status */
218 rsnd_mod_write(mod, SSISR, 0);
219
220 ssi->usrcnt++;
221
222 dev_dbg(dev, "%s[%d] hw started\n",
223 rsnd_mod_name(mod), rsnd_mod_id(mod));
224}
225
226static void rsnd_ssi_hw_stop(struct rsnd_dai_stream *io, struct rsnd_ssi *ssi)
227{
228 struct rsnd_mod *mod = rsnd_mod_get(ssi);
229 struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
230 struct rsnd_dai *rdai = rsnd_io_to_rdai(io);
231 struct device *dev = rsnd_priv_to_dev(priv);
232 u32 cr;
233
234 if (0 == ssi->usrcnt) {
235 dev_err(dev, "%s called without starting\n", __func__);
236 return;
237 } 355 }
238 356
239 ssi->usrcnt--; 357 ssi->cr_own = cr_own;
240 358 ssi->cr_mode = cr_mode;
241 if (0 == ssi->usrcnt) { 359 ssi->wsr = wsr;
242 /*
243 * disable all IRQ,
244 * and, wait all data was sent
245 */
246 cr = ssi->cr_own |
247 ssi->cr_clk;
248
249 rsnd_mod_write(mod, SSICR, cr | EN);
250 rsnd_ssi_status_check(mod, DIRQ);
251 360
252 /* 361 return 0;
253 * disable SSI,
254 * and, wait idle state
255 */
256 rsnd_mod_write(mod, SSICR, cr); /* disabled all */
257 rsnd_ssi_status_check(mod, IIRQ);
258
259 if (rsnd_rdai_is_clk_master(rdai)) {
260 struct rsnd_ssi *ssi_parent = rsnd_ssi_parent(ssi);
261
262 if (ssi_parent)
263 rsnd_ssi_hw_stop(io, ssi_parent);
264 else
265 rsnd_ssi_master_clk_stop(ssi);
266 }
267
268 rsnd_mod_power_off(mod);
269
270 ssi->chan = 0;
271 }
272
273 dev_dbg(dev, "%s[%d] hw stopped\n",
274 rsnd_mod_name(mod), rsnd_mod_id(mod));
275} 362}
276 363
277/* 364/*
@@ -282,49 +369,30 @@ static int rsnd_ssi_init(struct rsnd_mod *mod,
282 struct rsnd_priv *priv) 369 struct rsnd_priv *priv)
283{ 370{
284 struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod); 371 struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod);
285 struct rsnd_dai *rdai = rsnd_io_to_rdai(io); 372 int ret;
286 struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io); 373
287 u32 cr; 374 ssi->usrcnt++;
288 375
289 cr = FORCE; 376 rsnd_mod_power_on(mod);
290 377
291 /* 378 ret = rsnd_ssi_master_clk_start(ssi, io);
292 * always use 32bit system word for easy clock calculation. 379 if (ret < 0)
293 * see also rsnd_ssi_master_clk_enable() 380 return ret;
294 */
295 cr |= SWL_32;
296 381
297 /* 382 if (rsnd_ssi_is_parent(mod, io))
298 * init clock settings for SSICR 383 return 0;
299 */
300 switch (runtime->sample_bits) {
301 case 16:
302 cr |= DWL_16;
303 break;
304 case 32:
305 cr |= DWL_24;
306 break;
307 default:
308 return -EIO;
309 }
310 384
311 if (rdai->bit_clk_inv) 385 ret = rsnd_ssi_config_init(ssi, io);
312 cr |= SCKP; 386 if (ret < 0)
313 if (rdai->frm_clk_inv) 387 return ret;
314 cr |= SWSP;
315 if (rdai->data_alignment)
316 cr |= SDTA;
317 if (rdai->sys_delay)
318 cr |= DEL;
319 if (rsnd_io_is_play(io))
320 cr |= TRMD;
321 388
322 /*
323 * set ssi parameter
324 */
325 ssi->cr_own = cr;
326 ssi->err = -1; /* ignore 1st error */ 389 ssi->err = -1; /* ignore 1st error */
327 390
391 /* clear error status */
392 rsnd_ssi_status_clear(mod);
393
394 rsnd_ssi_irq_enable(mod);
395
328 return 0; 396 return 0;
329} 397}
330 398
@@ -335,12 +403,29 @@ static int rsnd_ssi_quit(struct rsnd_mod *mod,
335 struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod); 403 struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod);
336 struct device *dev = rsnd_priv_to_dev(priv); 404 struct device *dev = rsnd_priv_to_dev(priv);
337 405
338 if (ssi->err > 0) 406 if (!ssi->usrcnt) {
339 dev_warn(dev, "%s[%d] under/over flow err = %d\n", 407 dev_err(dev, "%s[%d] usrcnt error\n",
340 rsnd_mod_name(mod), rsnd_mod_id(mod), ssi->err); 408 rsnd_mod_name(mod), rsnd_mod_id(mod));
409 return -EIO;
410 }
411
412 if (!rsnd_ssi_is_parent(mod, io)) {
413 if (ssi->err > 0)
414 dev_warn(dev, "%s[%d] under/over flow err = %d\n",
415 rsnd_mod_name(mod), rsnd_mod_id(mod),
416 ssi->err);
417
418 ssi->cr_own = 0;
419 ssi->err = 0;
420
421 rsnd_ssi_irq_disable(mod);
422 }
341 423
342 ssi->cr_own = 0; 424 rsnd_ssi_master_clk_stop(ssi, io);
343 ssi->err = 0; 425
426 rsnd_mod_power_off(mod);
427
428 ssi->usrcnt--;
344 429
345 return 0; 430 return 0;
346} 431}
@@ -351,14 +436,13 @@ static int rsnd_ssi_hw_params(struct rsnd_mod *mod,
351 struct snd_pcm_hw_params *params) 436 struct snd_pcm_hw_params *params)
352{ 437{
353 struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod); 438 struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod);
354 struct rsnd_ssi *ssi_parent = rsnd_ssi_parent(ssi);
355 int chan = params_channels(params); 439 int chan = params_channels(params);
356 440
357 /* 441 /*
358 * Already working. 442 * Already working.
359 * It will happen if SSI has parent/child connection. 443 * It will happen if SSI has parent/child connection.
360 */ 444 */
361 if (ssi->usrcnt) { 445 if (ssi->usrcnt > 1) {
362 /* 446 /*
363 * it is error if child <-> parent SSI uses 447 * it is error if child <-> parent SSI uses
364 * different channels. 448 * different channels.
@@ -367,39 +451,83 @@ static int rsnd_ssi_hw_params(struct rsnd_mod *mod,
367 return -EIO; 451 return -EIO;
368 } 452 }
369 453
370 /* It will be removed on rsnd_ssi_hw_stop */
371 ssi->chan = chan; 454 ssi->chan = chan;
372 if (ssi_parent)
373 return rsnd_ssi_hw_params(rsnd_mod_get(ssi_parent), io,
374 substream, params);
375 455
376 return 0; 456 return 0;
377} 457}
378 458
379static void rsnd_ssi_record_error(struct rsnd_ssi *ssi, u32 status) 459static u32 rsnd_ssi_record_error(struct rsnd_ssi *ssi)
380{ 460{
381 struct rsnd_mod *mod = rsnd_mod_get(ssi); 461 struct rsnd_mod *mod = rsnd_mod_get(ssi);
462 u32 status = rsnd_ssi_status_get(mod);
382 463
383 /* under/over flow error */ 464 /* under/over flow error */
384 if (status & (UIRQ | OIRQ)) { 465 if (status & (UIRQ | OIRQ))
385 ssi->err++; 466 ssi->err++;
386 467
387 /* clear error status */ 468 return status;
388 rsnd_mod_write(mod, SSISR, 0); 469}
389 } 470
471static int __rsnd_ssi_start(struct rsnd_mod *mod,
472 struct rsnd_dai_stream *io,
473 struct rsnd_priv *priv)
474{
475 struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod);
476 u32 cr;
477
478 cr = ssi->cr_own |
479 ssi->cr_clk |
480 ssi->cr_mode;
481
482 /*
483 * EN will be set via SSIU :: SSI_CONTROL
484 * if Multi channel mode
485 */
486 if (!rsnd_ssi_multi_slaves(io))
487 cr |= EN;
488
489 rsnd_mod_write(mod, SSICR, cr);
490 rsnd_mod_write(mod, SSIWSR, ssi->wsr);
491
492 return 0;
390} 493}
391 494
392static int rsnd_ssi_start(struct rsnd_mod *mod, 495static int rsnd_ssi_start(struct rsnd_mod *mod,
393 struct rsnd_dai_stream *io, 496 struct rsnd_dai_stream *io,
394 struct rsnd_priv *priv) 497 struct rsnd_priv *priv)
395{ 498{
499 /*
500 * no limit to start
501 * see also
502 * rsnd_ssi_stop
503 * rsnd_ssi_interrupt
504 */
505 return __rsnd_ssi_start(mod, io, priv);
506}
507
508static int __rsnd_ssi_stop(struct rsnd_mod *mod,
509 struct rsnd_dai_stream *io,
510 struct rsnd_priv *priv)
511{
396 struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod); 512 struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod);
513 u32 cr;
397 514
398 rsnd_src_ssiu_start(mod, io, rsnd_ssi_use_busif(io)); 515 /*
516 * disable all IRQ,
517 * and, wait all data was sent
518 */
519 cr = ssi->cr_own |
520 ssi->cr_clk;
399 521
400 rsnd_ssi_hw_start(ssi, io); 522 rsnd_mod_write(mod, SSICR, cr | EN);
523 rsnd_ssi_status_check(mod, DIRQ);
401 524
402 rsnd_src_ssi_irq_enable(mod); 525 /*
526 * disable SSI,
527 * and, wait idle state
528 */
529 rsnd_mod_write(mod, SSICR, cr); /* disabled all */
530 rsnd_ssi_status_check(mod, IIRQ);
403 531
404 return 0; 532 return 0;
405} 533}
@@ -410,15 +538,16 @@ static int rsnd_ssi_stop(struct rsnd_mod *mod,
410{ 538{
411 struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod); 539 struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod);
412 540
413 rsnd_src_ssi_irq_disable(mod); 541 /*
414 542 * don't stop if not last user
415 rsnd_ssi_record_error(ssi, rsnd_mod_read(mod, SSISR)); 543 * see also
416 544 * rsnd_ssi_start
417 rsnd_ssi_hw_stop(io, ssi); 545 * rsnd_ssi_interrupt
418 546 */
419 rsnd_src_ssiu_stop(mod, io); 547 if (ssi->usrcnt > 1)
548 return 0;
420 549
421 return 0; 550 return __rsnd_ssi_stop(mod, io, priv);
422} 551}
423 552
424static void __rsnd_ssi_interrupt(struct rsnd_mod *mod, 553static void __rsnd_ssi_interrupt(struct rsnd_mod *mod,
@@ -426,6 +555,7 @@ static void __rsnd_ssi_interrupt(struct rsnd_mod *mod,
426{ 555{
427 struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod); 556 struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod);
428 struct rsnd_priv *priv = rsnd_mod_to_priv(mod); 557 struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
558 struct device *dev = rsnd_priv_to_dev(priv);
429 int is_dma = rsnd_ssi_is_dma_mode(mod); 559 int is_dma = rsnd_ssi_is_dma_mode(mod);
430 u32 status; 560 u32 status;
431 bool elapsed = false; 561 bool elapsed = false;
@@ -436,7 +566,7 @@ static void __rsnd_ssi_interrupt(struct rsnd_mod *mod,
436 if (!rsnd_io_is_working(io)) 566 if (!rsnd_io_is_working(io))
437 goto rsnd_ssi_interrupt_out; 567 goto rsnd_ssi_interrupt_out;
438 568
439 status = rsnd_mod_read(mod, SSISR); 569 status = rsnd_ssi_record_error(ssi);
440 570
441 /* PIO only */ 571 /* PIO only */
442 if (!is_dma && (status & DIRQ)) { 572 if (!is_dma && (status & DIRQ)) {
@@ -459,23 +589,24 @@ static void __rsnd_ssi_interrupt(struct rsnd_mod *mod,
459 589
460 /* DMA only */ 590 /* DMA only */
461 if (is_dma && (status & (UIRQ | OIRQ))) { 591 if (is_dma && (status & (UIRQ | OIRQ))) {
462 struct device *dev = rsnd_priv_to_dev(priv);
463
464 /* 592 /*
465 * restart SSI 593 * restart SSI
466 */ 594 */
467 dev_dbg(dev, "%s[%d] restart\n", 595 dev_dbg(dev, "%s[%d] restart\n",
468 rsnd_mod_name(mod), rsnd_mod_id(mod)); 596 rsnd_mod_name(mod), rsnd_mod_id(mod));
469 597
470 rsnd_ssi_stop(mod, io, priv); 598 __rsnd_ssi_stop(mod, io, priv);
471 if (ssi->err < 1024) 599 __rsnd_ssi_start(mod, io, priv);
472 rsnd_ssi_start(mod, io, priv);
473 else
474 dev_warn(dev, "no more SSI restart\n");
475 } 600 }
476 601
477 rsnd_ssi_record_error(ssi, status); 602 if (ssi->err > 1024) {
603 rsnd_ssi_irq_disable(mod);
478 604
605 dev_warn(dev, "no more %s[%d] restart\n",
606 rsnd_mod_name(mod), rsnd_mod_id(mod));
607 }
608
609 rsnd_ssi_status_clear(mod);
479rsnd_ssi_interrupt_out: 610rsnd_ssi_interrupt_out:
480 spin_unlock(&priv->lock); 611 spin_unlock(&priv->lock);
481 612
@@ -495,15 +626,49 @@ static irqreturn_t rsnd_ssi_interrupt(int irq, void *data)
495/* 626/*
496 * SSI PIO 627 * SSI PIO
497 */ 628 */
498static int rsnd_ssi_pio_probe(struct rsnd_mod *mod, 629static void rsnd_ssi_parent_attach(struct rsnd_mod *mod,
499 struct rsnd_dai_stream *io, 630 struct rsnd_dai_stream *io,
500 struct rsnd_priv *priv) 631 struct rsnd_priv *priv)
632{
633 if (!__rsnd_ssi_is_pin_sharing(mod))
634 return;
635
636 switch (rsnd_mod_id(mod)) {
637 case 1:
638 case 2:
639 rsnd_dai_connect(rsnd_ssi_mod_get(priv, 0), io, RSND_MOD_SSIP);
640 break;
641 case 4:
642 rsnd_dai_connect(rsnd_ssi_mod_get(priv, 3), io, RSND_MOD_SSIP);
643 break;
644 case 8:
645 rsnd_dai_connect(rsnd_ssi_mod_get(priv, 7), io, RSND_MOD_SSIP);
646 break;
647 }
648}
649
650static int rsnd_ssi_common_probe(struct rsnd_mod *mod,
651 struct rsnd_dai_stream *io,
652 struct rsnd_priv *priv)
501{ 653{
502 struct device *dev = rsnd_priv_to_dev(priv); 654 struct device *dev = rsnd_priv_to_dev(priv);
503 struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod); 655 struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod);
504 int ret; 656 int ret;
505 657
506 ret = devm_request_irq(dev, ssi->info->irq, 658 /*
659 * SSIP/SSIU/IRQ are not needed on
660 * SSI Multi slaves
661 */
662 if (rsnd_ssi_is_multi_slave(mod, io))
663 return 0;
664
665 rsnd_ssi_parent_attach(mod, io, priv);
666
667 ret = rsnd_ssiu_attach(io, mod);
668 if (ret < 0)
669 return ret;
670
671 ret = devm_request_irq(dev, ssi->irq,
507 rsnd_ssi_interrupt, 672 rsnd_ssi_interrupt,
508 IRQF_SHARED, 673 IRQF_SHARED,
509 dev_name(dev), mod); 674 dev_name(dev), mod);
@@ -513,7 +678,7 @@ static int rsnd_ssi_pio_probe(struct rsnd_mod *mod,
513 678
514static struct rsnd_mod_ops rsnd_ssi_pio_ops = { 679static struct rsnd_mod_ops rsnd_ssi_pio_ops = {
515 .name = SSI_NAME, 680 .name = SSI_NAME,
516 .probe = rsnd_ssi_pio_probe, 681 .probe = rsnd_ssi_common_probe,
517 .init = rsnd_ssi_init, 682 .init = rsnd_ssi_init,
518 .quit = rsnd_ssi_quit, 683 .quit = rsnd_ssi_quit,
519 .start = rsnd_ssi_start, 684 .start = rsnd_ssi_start,
@@ -526,20 +691,23 @@ static int rsnd_ssi_dma_probe(struct rsnd_mod *mod,
526 struct rsnd_priv *priv) 691 struct rsnd_priv *priv)
527{ 692{
528 struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod); 693 struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod);
529 struct device *dev = rsnd_priv_to_dev(priv); 694 int dma_id = 0; /* not needed */
530 int dma_id = ssi->info->dma_id;
531 int ret; 695 int ret;
532 696
533 ret = devm_request_irq(dev, ssi->info->irq, 697 /*
534 rsnd_ssi_interrupt, 698 * SSIP/SSIU/IRQ/DMA are not needed on
535 IRQF_SHARED, 699 * SSI Multi slaves
536 dev_name(dev), mod); 700 */
701 if (rsnd_ssi_is_multi_slave(mod, io))
702 return 0;
703
704 ret = rsnd_ssi_common_probe(mod, io, priv);
537 if (ret) 705 if (ret)
538 return ret; 706 return ret;
539 707
540 ret = rsnd_dma_init( 708 ssi->dma = rsnd_dma_attach(io, mod, dma_id);
541 io, rsnd_mod_to_dma(mod), 709 if (IS_ERR(ssi->dma))
542 dma_id); 710 return PTR_ERR(ssi->dma);
543 711
544 return ret; 712 return ret;
545} 713}
@@ -550,9 +718,7 @@ static int rsnd_ssi_dma_remove(struct rsnd_mod *mod,
550{ 718{
551 struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod); 719 struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod);
552 struct device *dev = rsnd_priv_to_dev(priv); 720 struct device *dev = rsnd_priv_to_dev(priv);
553 int irq = ssi->info->irq; 721 int irq = ssi->irq;
554
555 rsnd_dma_quit(io, rsnd_mod_to_dma(mod));
556 722
557 /* PIO will request IRQ again */ 723 /* PIO will request IRQ again */
558 devm_free_irq(dev, irq, mod); 724 devm_free_irq(dev, irq, mod);
@@ -581,32 +747,6 @@ static int rsnd_ssi_fallback(struct rsnd_mod *mod,
581 return 0; 747 return 0;
582} 748}
583 749
584static int rsnd_ssi_dma_start(struct rsnd_mod *mod,
585 struct rsnd_dai_stream *io,
586 struct rsnd_priv *priv)
587{
588 struct rsnd_dma *dma = rsnd_mod_to_dma(mod);
589
590 rsnd_dma_start(io, dma);
591
592 rsnd_ssi_start(mod, io, priv);
593
594 return 0;
595}
596
597static int rsnd_ssi_dma_stop(struct rsnd_mod *mod,
598 struct rsnd_dai_stream *io,
599 struct rsnd_priv *priv)
600{
601 struct rsnd_dma *dma = rsnd_mod_to_dma(mod);
602
603 rsnd_ssi_stop(mod, io, priv);
604
605 rsnd_dma_stop(io, dma);
606
607 return 0;
608}
609
610static struct dma_chan *rsnd_ssi_dma_req(struct rsnd_dai_stream *io, 750static struct dma_chan *rsnd_ssi_dma_req(struct rsnd_dai_stream *io,
611 struct rsnd_mod *mod) 751 struct rsnd_mod *mod)
612{ 752{
@@ -630,8 +770,8 @@ static struct rsnd_mod_ops rsnd_ssi_dma_ops = {
630 .remove = rsnd_ssi_dma_remove, 770 .remove = rsnd_ssi_dma_remove,
631 .init = rsnd_ssi_init, 771 .init = rsnd_ssi_init,
632 .quit = rsnd_ssi_quit, 772 .quit = rsnd_ssi_quit,
633 .start = rsnd_ssi_dma_start, 773 .start = rsnd_ssi_start,
634 .stop = rsnd_ssi_dma_stop, 774 .stop = rsnd_ssi_stop,
635 .fallback = rsnd_ssi_fallback, 775 .fallback = rsnd_ssi_fallback,
636 .hw_params = rsnd_ssi_hw_params, 776 .hw_params = rsnd_ssi_hw_params,
637}; 777};
@@ -652,110 +792,76 @@ static struct rsnd_mod_ops rsnd_ssi_non_ops = {
652/* 792/*
653 * ssi mod function 793 * ssi mod function
654 */ 794 */
655struct rsnd_mod *rsnd_ssi_mod_get(struct rsnd_priv *priv, int id) 795static void rsnd_ssi_connect(struct rsnd_mod *mod,
796 struct rsnd_dai_stream *io)
656{ 797{
657 if (WARN_ON(id < 0 || id >= rsnd_ssi_nr(priv))) 798 struct rsnd_dai *rdai = rsnd_io_to_rdai(io);
658 id = 0; 799 enum rsnd_mod_type types[] = {
659 800 RSND_MOD_SSI,
660 return rsnd_mod_get((struct rsnd_ssi *)(priv->ssi) + id); 801 RSND_MOD_SSIM1,
661} 802 RSND_MOD_SSIM2,
662 803 RSND_MOD_SSIM3,
663int __rsnd_ssi_is_pin_sharing(struct rsnd_mod *mod) 804 };
664{ 805 enum rsnd_mod_type type;
665 struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod); 806 int i;
666
667 return !!(rsnd_ssi_mode_flags(ssi) & RSND_SSI_CLK_PIN_SHARE);
668}
669
670static void rsnd_ssi_parent_setup(struct rsnd_priv *priv, struct rsnd_ssi *ssi)
671{
672 struct rsnd_mod *mod = rsnd_mod_get(ssi);
673
674 if (!__rsnd_ssi_is_pin_sharing(mod))
675 return;
676 807
677 switch (rsnd_mod_id(mod)) { 808 /* try SSI -> SSIM1 -> SSIM2 -> SSIM3 */
678 case 1: 809 for (i = 0; i < ARRAY_SIZE(types); i++) {
679 case 2: 810 type = types[i];
680 ssi->parent = rsnd_mod_to_ssi(rsnd_ssi_mod_get(priv, 0)); 811 if (!rsnd_io_to_mod(io, type)) {
681 break; 812 rsnd_dai_connect(mod, io, type);
682 case 4: 813 rsnd_set_slot(rdai, 2 * (i + 1), (i + 1));
683 ssi->parent = rsnd_mod_to_ssi(rsnd_ssi_mod_get(priv, 3)); 814 return;
684 break; 815 }
685 case 8:
686 ssi->parent = rsnd_mod_to_ssi(rsnd_ssi_mod_get(priv, 7));
687 break;
688 } 816 }
689} 817}
690 818
691 819void rsnd_parse_connect_ssi(struct rsnd_dai *rdai,
692static void rsnd_of_parse_ssi(struct platform_device *pdev, 820 struct device_node *playback,
693 const struct rsnd_of_data *of_data, 821 struct device_node *capture)
694 struct rsnd_priv *priv)
695{ 822{
823 struct rsnd_priv *priv = rsnd_rdai_to_priv(rdai);
696 struct device_node *node; 824 struct device_node *node;
697 struct device_node *np; 825 struct device_node *np;
698 struct rsnd_ssi_platform_info *ssi_info; 826 struct rsnd_mod *mod;
699 struct rcar_snd_info *info = rsnd_priv_to_info(priv); 827 int i;
700 struct device *dev = &pdev->dev;
701 int nr, i;
702 828
703 node = rsnd_ssi_of_node(priv); 829 node = rsnd_ssi_of_node(priv);
704 if (!node) 830 if (!node)
705 return; 831 return;
706 832
707 nr = of_get_child_count(node); 833 i = 0;
708 if (!nr)
709 goto rsnd_of_parse_ssi_end;
710
711 ssi_info = devm_kzalloc(dev,
712 sizeof(struct rsnd_ssi_platform_info) * nr,
713 GFP_KERNEL);
714 if (!ssi_info) {
715 dev_err(dev, "ssi info allocation error\n");
716 goto rsnd_of_parse_ssi_end;
717 }
718
719 info->ssi_info = ssi_info;
720 info->ssi_info_nr = nr;
721
722 i = -1;
723 for_each_child_of_node(node, np) { 834 for_each_child_of_node(node, np) {
835 mod = rsnd_ssi_mod_get(priv, i);
836 if (np == playback)
837 rsnd_ssi_connect(mod, &rdai->playback);
838 if (np == capture)
839 rsnd_ssi_connect(mod, &rdai->capture);
724 i++; 840 i++;
841 }
725 842
726 ssi_info = info->ssi_info + i; 843 of_node_put(node);
727 844}
728 /*
729 * pin settings
730 */
731 if (of_get_property(np, "shared-pin", NULL))
732 ssi_info->flags |= RSND_SSI_CLK_PIN_SHARE;
733 845
734 /* 846struct rsnd_mod *rsnd_ssi_mod_get(struct rsnd_priv *priv, int id)
735 * irq 847{
736 */ 848 if (WARN_ON(id < 0 || id >= rsnd_ssi_nr(priv)))
737 ssi_info->irq = irq_of_parse_and_map(np, 0); 849 id = 0;
738 850
739 /* 851 return rsnd_mod_get(rsnd_ssi_get(priv, id));
740 * DMA 852}
741 */
742 ssi_info->dma_id = of_get_property(np, "pio-transfer", NULL) ?
743 0 : 1;
744 853
745 if (of_get_property(np, "no-busif", NULL)) 854int __rsnd_ssi_is_pin_sharing(struct rsnd_mod *mod)
746 ssi_info->flags |= RSND_SSI_NO_BUSIF; 855{
747 } 856 struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod);
748 857
749rsnd_of_parse_ssi_end: 858 return !!(rsnd_ssi_mode_flags(ssi) & RSND_SSI_CLK_PIN_SHARE);
750 of_node_put(node);
751} 859}
752 860
753int rsnd_ssi_probe(struct platform_device *pdev, 861int rsnd_ssi_probe(struct rsnd_priv *priv)
754 const struct rsnd_of_data *of_data,
755 struct rsnd_priv *priv)
756{ 862{
757 struct rcar_snd_info *info = rsnd_priv_to_info(priv); 863 struct device_node *node;
758 struct rsnd_ssi_platform_info *pinfo; 864 struct device_node *np;
759 struct device *dev = rsnd_priv_to_dev(priv); 865 struct device *dev = rsnd_priv_to_dev(priv);
760 struct rsnd_mod_ops *ops; 866 struct rsnd_mod_ops *ops;
761 struct clk *clk; 867 struct clk *clk;
@@ -763,50 +869,73 @@ int rsnd_ssi_probe(struct platform_device *pdev,
763 char name[RSND_SSI_NAME_SIZE]; 869 char name[RSND_SSI_NAME_SIZE];
764 int i, nr, ret; 870 int i, nr, ret;
765 871
766 rsnd_of_parse_ssi(pdev, of_data, priv); 872 node = rsnd_ssi_of_node(priv);
873 if (!node)
874 return -EINVAL;
875
876 nr = of_get_child_count(node);
877 if (!nr) {
878 ret = -EINVAL;
879 goto rsnd_ssi_probe_done;
880 }
767 881
768 /*
769 * init SSI
770 */
771 nr = info->ssi_info_nr;
772 ssi = devm_kzalloc(dev, sizeof(*ssi) * nr, GFP_KERNEL); 882 ssi = devm_kzalloc(dev, sizeof(*ssi) * nr, GFP_KERNEL);
773 if (!ssi) 883 if (!ssi) {
774 return -ENOMEM; 884 ret = -ENOMEM;
885 goto rsnd_ssi_probe_done;
886 }
775 887
776 priv->ssi = ssi; 888 priv->ssi = ssi;
777 priv->ssi_nr = nr; 889 priv->ssi_nr = nr;
778 890
779 for_each_rsnd_ssi(ssi, priv, i) { 891 i = 0;
780 pinfo = &info->ssi_info[i]; 892 for_each_child_of_node(node, np) {
893 ssi = rsnd_ssi_get(priv, i);
781 894
782 snprintf(name, RSND_SSI_NAME_SIZE, "%s.%d", 895 snprintf(name, RSND_SSI_NAME_SIZE, "%s.%d",
783 SSI_NAME, i); 896 SSI_NAME, i);
784 897
785 clk = devm_clk_get(dev, name); 898 clk = devm_clk_get(dev, name);
786 if (IS_ERR(clk)) 899 if (IS_ERR(clk)) {
787 return PTR_ERR(clk); 900 ret = PTR_ERR(clk);
901 goto rsnd_ssi_probe_done;
902 }
788 903
789 ssi->info = pinfo; 904 if (of_get_property(np, "shared-pin", NULL))
905 ssi->flags |= RSND_SSI_CLK_PIN_SHARE;
906
907 if (of_get_property(np, "no-busif", NULL))
908 ssi->flags |= RSND_SSI_NO_BUSIF;
909
910 ssi->irq = irq_of_parse_and_map(np, 0);
911 if (!ssi->irq) {
912 ret = -EINVAL;
913 goto rsnd_ssi_probe_done;
914 }
790 915
791 ops = &rsnd_ssi_non_ops; 916 ops = &rsnd_ssi_non_ops;
792 if (pinfo->dma_id > 0) 917 if (of_get_property(np, "pio-transfer", NULL))
793 ops = &rsnd_ssi_dma_ops;
794 else if (rsnd_ssi_pio_available(ssi))
795 ops = &rsnd_ssi_pio_ops; 918 ops = &rsnd_ssi_pio_ops;
919 else
920 ops = &rsnd_ssi_dma_ops;
796 921
797 ret = rsnd_mod_init(priv, rsnd_mod_get(ssi), ops, clk, 922 ret = rsnd_mod_init(priv, rsnd_mod_get(ssi), ops, clk,
798 RSND_MOD_SSI, i); 923 RSND_MOD_SSI, i);
799 if (ret) 924 if (ret)
800 return ret; 925 goto rsnd_ssi_probe_done;
801 926
802 rsnd_ssi_parent_setup(priv, ssi); 927 i++;
803 } 928 }
804 929
805 return 0; 930 ret = 0;
931
932rsnd_ssi_probe_done:
933 of_node_put(node);
934
935 return ret;
806} 936}
807 937
808void rsnd_ssi_remove(struct platform_device *pdev, 938void rsnd_ssi_remove(struct rsnd_priv *priv)
809 struct rsnd_priv *priv)
810{ 939{
811 struct rsnd_ssi *ssi; 940 struct rsnd_ssi *ssi;
812 int i; 941 int i;
diff --git a/sound/soc/sh/rcar/ssiu.c b/sound/soc/sh/rcar/ssiu.c
new file mode 100644
index 000000000000..06d72828e5bc
--- /dev/null
+++ b/sound/soc/sh/rcar/ssiu.c
@@ -0,0 +1,225 @@
1/*
2 * Renesas R-Car SSIU support
3 *
4 * Copyright (c) 2015 Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 */
10#include "rsnd.h"
11
12#define SSIU_NAME "ssiu"
13
14struct rsnd_ssiu {
15 struct rsnd_mod mod;
16};
17
18#define rsnd_ssiu_nr(priv) ((priv)->ssiu_nr)
19#define for_each_rsnd_ssiu(pos, priv, i) \
20 for (i = 0; \
21 (i < rsnd_ssiu_nr(priv)) && \
22 ((pos) = ((struct rsnd_ssiu *)(priv)->ssiu + i)); \
23 i++)
24
25static int rsnd_ssiu_init(struct rsnd_mod *mod,
26 struct rsnd_dai_stream *io,
27 struct rsnd_priv *priv)
28{
29 struct rsnd_dai *rdai = rsnd_io_to_rdai(io);
30 u32 multi_ssi_slaves = rsnd_ssi_multi_slaves(io);
31 int use_busif = rsnd_ssi_use_busif(io);
32 int id = rsnd_mod_id(mod);
33 u32 mask1, val1;
34 u32 mask2, val2;
35
36 /*
37 * SSI_MODE0
38 */
39 rsnd_mod_bset(mod, SSI_MODE0, (1 << id), !use_busif << id);
40
41 /*
42 * SSI_MODE1
43 */
44 mask1 = (1 << 4) | (1 << 20); /* mask sync bit */
45 mask2 = (1 << 4); /* mask sync bit */
46 val1 = val2 = 0;
47 if (rsnd_ssi_is_pin_sharing(io)) {
48 int shift = -1;
49
50 switch (id) {
51 case 1:
52 shift = 0;
53 break;
54 case 2:
55 shift = 2;
56 break;
57 case 4:
58 shift = 16;
59 break;
60 default:
61 return -EINVAL;
62 }
63
64 mask1 |= 0x3 << shift;
65 val1 = rsnd_rdai_is_clk_master(rdai) ?
66 0x2 << shift : 0x1 << shift;
67
68 } else if (multi_ssi_slaves) {
69
70 mask2 |= 0x00000007;
71 mask1 |= 0x0000000f;
72
73 switch (multi_ssi_slaves) {
74 case 0x0206: /* SSI0/1/2/9 */
75 val2 = (1 << 4) | /* SSI0129 sync */
76 (rsnd_rdai_is_clk_master(rdai) ? 0x2 : 0x1);
77 /* fall through */
78 case 0x0006: /* SSI0/1/2 */
79 val1 = rsnd_rdai_is_clk_master(rdai) ?
80 0xa : 0x5;
81
82 if (!val2) /* SSI012 sync */
83 val1 |= (1 << 4);
84 }
85 }
86
87 rsnd_mod_bset(mod, SSI_MODE1, mask1, val1);
88 rsnd_mod_bset(mod, SSI_MODE2, mask2, val2);
89
90 return 0;
91}
92
93static struct rsnd_mod_ops rsnd_ssiu_ops_gen1 = {
94 .name = SSIU_NAME,
95 .init = rsnd_ssiu_init,
96};
97
98static int rsnd_ssiu_init_gen2(struct rsnd_mod *mod,
99 struct rsnd_dai_stream *io,
100 struct rsnd_priv *priv)
101{
102 int ret;
103
104 ret = rsnd_ssiu_init(mod, io, priv);
105 if (ret < 0)
106 return ret;
107
108 if (rsnd_get_slot_width(io) >= 6) {
109 /*
110 * TDM Extend Mode
111 * see
112 * rsnd_ssi_config_init()
113 */
114 rsnd_mod_write(mod, SSI_MODE, 0x1);
115 }
116
117 if (rsnd_ssi_use_busif(io)) {
118 u32 val = rsnd_get_dalign(mod, io);
119
120 rsnd_mod_write(mod, SSI_BUSIF_ADINR,
121 rsnd_get_adinr_bit(mod, io) |
122 rsnd_get_adinr_chan(mod, io));
123 rsnd_mod_write(mod, SSI_BUSIF_MODE, 1);
124 rsnd_mod_write(mod, SSI_BUSIF_DALIGN, val);
125 }
126
127 return 0;
128}
129
130static int rsnd_ssiu_start_gen2(struct rsnd_mod *mod,
131 struct rsnd_dai_stream *io,
132 struct rsnd_priv *priv)
133{
134 if (!rsnd_ssi_use_busif(io))
135 return 0;
136
137 rsnd_mod_write(mod, SSI_CTRL, 0x1);
138
139 if (rsnd_ssi_multi_slaves(io))
140 rsnd_mod_write(mod, SSI_CONTROL, 0x1);
141
142 return 0;
143}
144
145static int rsnd_ssiu_stop_gen2(struct rsnd_mod *mod,
146 struct rsnd_dai_stream *io,
147 struct rsnd_priv *priv)
148{
149 if (!rsnd_ssi_use_busif(io))
150 return 0;
151
152 rsnd_mod_write(mod, SSI_CTRL, 0);
153
154 if (rsnd_ssi_multi_slaves(io))
155 rsnd_mod_write(mod, SSI_CONTROL, 0);
156
157 return 0;
158}
159
160static struct rsnd_mod_ops rsnd_ssiu_ops_gen2 = {
161 .name = SSIU_NAME,
162 .init = rsnd_ssiu_init_gen2,
163 .start = rsnd_ssiu_start_gen2,
164 .stop = rsnd_ssiu_stop_gen2,
165};
166
167static struct rsnd_mod *rsnd_ssiu_mod_get(struct rsnd_priv *priv, int id)
168{
169 if (WARN_ON(id < 0 || id >= rsnd_ssiu_nr(priv)))
170 id = 0;
171
172 return rsnd_mod_get((struct rsnd_ssiu *)(priv->ssiu) + id);
173}
174
175int rsnd_ssiu_attach(struct rsnd_dai_stream *io,
176 struct rsnd_mod *ssi_mod)
177{
178 struct rsnd_priv *priv = rsnd_io_to_priv(io);
179 struct rsnd_mod *mod = rsnd_ssiu_mod_get(priv, rsnd_mod_id(ssi_mod));
180
181 rsnd_mod_confirm_ssi(ssi_mod);
182
183 return rsnd_dai_connect(mod, io, mod->type);
184}
185
186int rsnd_ssiu_probe(struct rsnd_priv *priv)
187{
188 struct device *dev = rsnd_priv_to_dev(priv);
189 struct rsnd_ssiu *ssiu;
190 static struct rsnd_mod_ops *ops;
191 int i, nr, ret;
192
193 /* same number to SSI */
194 nr = priv->ssi_nr;
195 ssiu = devm_kzalloc(dev, sizeof(*ssiu) * nr, GFP_KERNEL);
196 if (!ssiu)
197 return -ENOMEM;
198
199 priv->ssiu = ssiu;
200 priv->ssiu_nr = nr;
201
202 if (rsnd_is_gen1(priv))
203 ops = &rsnd_ssiu_ops_gen1;
204 else
205 ops = &rsnd_ssiu_ops_gen2;
206
207 for_each_rsnd_ssiu(ssiu, priv, i) {
208 ret = rsnd_mod_init(priv, rsnd_mod_get(ssiu),
209 ops, NULL, RSND_MOD_SSIU, i);
210 if (ret)
211 return ret;
212 }
213
214 return 0;
215}
216
217void rsnd_ssiu_remove(struct rsnd_priv *priv)
218{
219 struct rsnd_ssiu *ssiu;
220 int i;
221
222 for_each_rsnd_ssiu(ssiu, priv, i) {
223 rsnd_mod_quit(rsnd_mod_get(ssiu));
224 }
225}
diff --git a/sound/soc/soc-ac97.c b/sound/soc/soc-ac97.c
index d40efc9fe0a9..733f5128eeff 100644
--- a/sound/soc/soc-ac97.c
+++ b/sound/soc/soc-ac97.c
@@ -20,6 +20,7 @@
20#include <linux/delay.h> 20#include <linux/delay.h>
21#include <linux/export.h> 21#include <linux/export.h>
22#include <linux/gpio.h> 22#include <linux/gpio.h>
23#include <linux/gpio/driver.h>
23#include <linux/init.h> 24#include <linux/init.h>
24#include <linux/of_gpio.h> 25#include <linux/of_gpio.h>
25#include <linux/of.h> 26#include <linux/of.h>
@@ -38,6 +39,14 @@ struct snd_ac97_reset_cfg {
38 int gpio_reset; 39 int gpio_reset;
39}; 40};
40 41
42struct snd_ac97_gpio_priv {
43#ifdef CONFIG_GPIOLIB
44 struct gpio_chip gpio_chip;
45#endif
46 unsigned int gpios_set;
47 struct snd_soc_codec *codec;
48};
49
41static struct snd_ac97_bus soc_ac97_bus = { 50static struct snd_ac97_bus soc_ac97_bus = {
42 .ops = NULL, /* Gets initialized in snd_soc_set_ac97_ops() */ 51 .ops = NULL, /* Gets initialized in snd_soc_set_ac97_ops() */
43}; 52};
@@ -47,6 +56,117 @@ static void soc_ac97_device_release(struct device *dev)
47 kfree(to_ac97_t(dev)); 56 kfree(to_ac97_t(dev));
48} 57}
49 58
59#ifdef CONFIG_GPIOLIB
60static inline struct snd_soc_codec *gpio_to_codec(struct gpio_chip *chip)
61{
62 struct snd_ac97_gpio_priv *gpio_priv =
63 container_of(chip, struct snd_ac97_gpio_priv, gpio_chip);
64
65 return gpio_priv->codec;
66}
67
68static int snd_soc_ac97_gpio_request(struct gpio_chip *chip, unsigned offset)
69{
70 if (offset >= AC97_NUM_GPIOS)
71 return -EINVAL;
72
73 return 0;
74}
75
76static int snd_soc_ac97_gpio_direction_in(struct gpio_chip *chip,
77 unsigned offset)
78{
79 struct snd_soc_codec *codec = gpio_to_codec(chip);
80
81 dev_dbg(codec->dev, "set gpio %d to output\n", offset);
82 return snd_soc_update_bits(codec, AC97_GPIO_CFG,
83 1 << offset, 1 << offset);
84}
85
86static int snd_soc_ac97_gpio_get(struct gpio_chip *chip, unsigned offset)
87{
88 struct snd_soc_codec *codec = gpio_to_codec(chip);
89 int ret;
90
91 ret = snd_soc_read(codec, AC97_GPIO_STATUS);
92 dev_dbg(codec->dev, "get gpio %d : %d\n", offset,
93 ret < 0 ? ret : ret & (1 << offset));
94
95 return ret < 0 ? ret : !!(ret & (1 << offset));
96}
97
98static void snd_soc_ac97_gpio_set(struct gpio_chip *chip, unsigned offset,
99 int value)
100{
101 struct snd_ac97_gpio_priv *gpio_priv =
102 container_of(chip, struct snd_ac97_gpio_priv, gpio_chip);
103 struct snd_soc_codec *codec = gpio_to_codec(chip);
104
105 gpio_priv->gpios_set &= ~(1 << offset);
106 gpio_priv->gpios_set |= (!!value) << offset;
107 snd_soc_write(codec, AC97_GPIO_STATUS, gpio_priv->gpios_set);
108 dev_dbg(codec->dev, "set gpio %d to %d\n", offset, !!value);
109}
110
111static int snd_soc_ac97_gpio_direction_out(struct gpio_chip *chip,
112 unsigned offset, int value)
113{
114 struct snd_soc_codec *codec = gpio_to_codec(chip);
115
116 dev_dbg(codec->dev, "set gpio %d to output\n", offset);
117 snd_soc_ac97_gpio_set(chip, offset, value);
118 return snd_soc_update_bits(codec, AC97_GPIO_CFG, 1 << offset, 0);
119}
120
121static struct gpio_chip snd_soc_ac97_gpio_chip = {
122 .label = "snd_soc_ac97",
123 .owner = THIS_MODULE,
124 .request = snd_soc_ac97_gpio_request,
125 .direction_input = snd_soc_ac97_gpio_direction_in,
126 .get = snd_soc_ac97_gpio_get,
127 .direction_output = snd_soc_ac97_gpio_direction_out,
128 .set = snd_soc_ac97_gpio_set,
129 .can_sleep = 1,
130};
131
132static int snd_soc_ac97_init_gpio(struct snd_ac97 *ac97,
133 struct snd_soc_codec *codec)
134{
135 struct snd_ac97_gpio_priv *gpio_priv;
136 int ret;
137
138 gpio_priv = devm_kzalloc(codec->dev, sizeof(*gpio_priv), GFP_KERNEL);
139 if (!gpio_priv)
140 return -ENOMEM;
141 ac97->gpio_priv = gpio_priv;
142 gpio_priv->codec = codec;
143 gpio_priv->gpio_chip = snd_soc_ac97_gpio_chip;
144 gpio_priv->gpio_chip.ngpio = AC97_NUM_GPIOS;
145 gpio_priv->gpio_chip.dev = codec->dev;
146 gpio_priv->gpio_chip.base = -1;
147
148 ret = gpiochip_add(&gpio_priv->gpio_chip);
149 if (ret != 0)
150 dev_err(codec->dev, "Failed to add GPIOs: %d\n", ret);
151 return ret;
152}
153
154static void snd_soc_ac97_free_gpio(struct snd_ac97 *ac97)
155{
156 gpiochip_remove(&ac97->gpio_priv->gpio_chip);
157}
158#else
159static int snd_soc_ac97_init_gpio(struct snd_ac97 *ac97,
160 struct snd_soc_codec *codec)
161{
162 return 0;
163}
164
165static void snd_soc_ac97_free_gpio(struct snd_ac97 *ac97)
166{
167}
168#endif
169
50/** 170/**
51 * snd_soc_alloc_ac97_codec() - Allocate new a AC'97 device 171 * snd_soc_alloc_ac97_codec() - Allocate new a AC'97 device
52 * @codec: The CODEC for which to create the AC'97 device 172 * @codec: The CODEC for which to create the AC'97 device
@@ -119,6 +239,10 @@ struct snd_ac97 *snd_soc_new_ac97_codec(struct snd_soc_codec *codec,
119 if (ret) 239 if (ret)
120 goto err_put_device; 240 goto err_put_device;
121 241
242 ret = snd_soc_ac97_init_gpio(ac97, codec);
243 if (ret)
244 goto err_put_device;
245
122 return ac97; 246 return ac97;
123 247
124err_put_device: 248err_put_device:
@@ -135,6 +259,7 @@ EXPORT_SYMBOL_GPL(snd_soc_new_ac97_codec);
135 */ 259 */
136void snd_soc_free_ac97_codec(struct snd_ac97 *ac97) 260void snd_soc_free_ac97_codec(struct snd_ac97 *ac97)
137{ 261{
262 snd_soc_ac97_free_gpio(ac97);
138 device_del(&ac97->dev); 263 device_del(&ac97->dev);
139 ac97->bus = NULL; 264 ac97->bus = NULL;
140 put_device(&ac97->dev); 265 put_device(&ac97->dev);
diff --git a/sound/soc/soc-compress.c b/sound/soc/soc-compress.c
index 12a9820feac1..875733c52953 100644
--- a/sound/soc/soc-compress.c
+++ b/sound/soc/soc-compress.c
@@ -630,6 +630,7 @@ int snd_soc_new_compress(struct snd_soc_pcm_runtime *rtd, int num)
630 struct snd_pcm *be_pcm; 630 struct snd_pcm *be_pcm;
631 char new_name[64]; 631 char new_name[64];
632 int ret = 0, direction = 0; 632 int ret = 0, direction = 0;
633 int playback = 0, capture = 0;
633 634
634 if (rtd->num_codecs > 1) { 635 if (rtd->num_codecs > 1) {
635 dev_err(rtd->card->dev, "Multicodec not supported for compressed stream\n"); 636 dev_err(rtd->card->dev, "Multicodec not supported for compressed stream\n");
@@ -641,11 +642,27 @@ int snd_soc_new_compress(struct snd_soc_pcm_runtime *rtd, int num)
641 rtd->dai_link->stream_name, codec_dai->name, num); 642 rtd->dai_link->stream_name, codec_dai->name, num);
642 643
643 if (codec_dai->driver->playback.channels_min) 644 if (codec_dai->driver->playback.channels_min)
645 playback = 1;
646 if (codec_dai->driver->capture.channels_min)
647 capture = 1;
648
649 capture = capture && cpu_dai->driver->capture.channels_min;
650 playback = playback && cpu_dai->driver->playback.channels_min;
651
652 /*
653 * Compress devices are unidirectional so only one of the directions
654 * should be set, check for that (xor)
655 */
656 if (playback + capture != 1) {
657 dev_err(rtd->card->dev, "Invalid direction for compress P %d, C %d\n",
658 playback, capture);
659 return -EINVAL;
660 }
661
662 if(playback)
644 direction = SND_COMPRESS_PLAYBACK; 663 direction = SND_COMPRESS_PLAYBACK;
645 else if (codec_dai->driver->capture.channels_min)
646 direction = SND_COMPRESS_CAPTURE;
647 else 664 else
648 return -EINVAL; 665 direction = SND_COMPRESS_CAPTURE;
649 666
650 compr = kzalloc(sizeof(*compr), GFP_KERNEL); 667 compr = kzalloc(sizeof(*compr), GFP_KERNEL);
651 if (compr == NULL) { 668 if (compr == NULL) {
@@ -689,7 +706,13 @@ int snd_soc_new_compress(struct snd_soc_pcm_runtime *rtd, int num)
689 compr->ops->copy = soc_compr_copy; 706 compr->ops->copy = soc_compr_copy;
690 707
691 mutex_init(&compr->lock); 708 mutex_init(&compr->lock);
692 ret = snd_compress_new(rtd->card->snd_card, num, direction, compr); 709
710 snprintf(new_name, sizeof(new_name), "%s %s-%d",
711 rtd->dai_link->stream_name,
712 rtd->codec_dai->name, num);
713
714 ret = snd_compress_new(rtd->card->snd_card, num, direction,
715 new_name, compr);
693 if (ret < 0) { 716 if (ret < 0) {
694 pr_err("compress asoc: can't create compress for codec %s\n", 717 pr_err("compress asoc: can't create compress for codec %s\n",
695 codec->component.name); 718 codec->component.name);
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index a1305f827a98..790ee2bf1a47 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -537,26 +537,75 @@ static inline void snd_soc_debugfs_exit(void)
537struct snd_pcm_substream *snd_soc_get_dai_substream(struct snd_soc_card *card, 537struct snd_pcm_substream *snd_soc_get_dai_substream(struct snd_soc_card *card,
538 const char *dai_link, int stream) 538 const char *dai_link, int stream)
539{ 539{
540 int i; 540 struct snd_soc_pcm_runtime *rtd;
541 541
542 for (i = 0; i < card->num_links; i++) { 542 list_for_each_entry(rtd, &card->rtd_list, list) {
543 if (card->rtd[i].dai_link->no_pcm && 543 if (rtd->dai_link->no_pcm &&
544 !strcmp(card->rtd[i].dai_link->name, dai_link)) 544 !strcmp(rtd->dai_link->name, dai_link))
545 return card->rtd[i].pcm->streams[stream].substream; 545 return rtd->pcm->streams[stream].substream;
546 } 546 }
547 dev_dbg(card->dev, "ASoC: failed to find dai link %s\n", dai_link); 547 dev_dbg(card->dev, "ASoC: failed to find dai link %s\n", dai_link);
548 return NULL; 548 return NULL;
549} 549}
550EXPORT_SYMBOL_GPL(snd_soc_get_dai_substream); 550EXPORT_SYMBOL_GPL(snd_soc_get_dai_substream);
551 551
552static struct snd_soc_pcm_runtime *soc_new_pcm_runtime(
553 struct snd_soc_card *card, struct snd_soc_dai_link *dai_link)
554{
555 struct snd_soc_pcm_runtime *rtd;
556
557 rtd = kzalloc(sizeof(struct snd_soc_pcm_runtime), GFP_KERNEL);
558 if (!rtd)
559 return NULL;
560
561 rtd->card = card;
562 rtd->dai_link = dai_link;
563 rtd->codec_dais = kzalloc(sizeof(struct snd_soc_dai *) *
564 dai_link->num_codecs,
565 GFP_KERNEL);
566 if (!rtd->codec_dais) {
567 kfree(rtd);
568 return NULL;
569 }
570
571 return rtd;
572}
573
574static void soc_free_pcm_runtime(struct snd_soc_pcm_runtime *rtd)
575{
576 if (rtd && rtd->codec_dais)
577 kfree(rtd->codec_dais);
578 kfree(rtd);
579}
580
581static void soc_add_pcm_runtime(struct snd_soc_card *card,
582 struct snd_soc_pcm_runtime *rtd)
583{
584 list_add_tail(&rtd->list, &card->rtd_list);
585 rtd->num = card->num_rtd;
586 card->num_rtd++;
587}
588
589static void soc_remove_pcm_runtimes(struct snd_soc_card *card)
590{
591 struct snd_soc_pcm_runtime *rtd, *_rtd;
592
593 list_for_each_entry_safe(rtd, _rtd, &card->rtd_list, list) {
594 list_del(&rtd->list);
595 soc_free_pcm_runtime(rtd);
596 }
597
598 card->num_rtd = 0;
599}
600
552struct snd_soc_pcm_runtime *snd_soc_get_pcm_runtime(struct snd_soc_card *card, 601struct snd_soc_pcm_runtime *snd_soc_get_pcm_runtime(struct snd_soc_card *card,
553 const char *dai_link) 602 const char *dai_link)
554{ 603{
555 int i; 604 struct snd_soc_pcm_runtime *rtd;
556 605
557 for (i = 0; i < card->num_links; i++) { 606 list_for_each_entry(rtd, &card->rtd_list, list) {
558 if (!strcmp(card->rtd[i].dai_link->name, dai_link)) 607 if (!strcmp(rtd->dai_link->name, dai_link))
559 return &card->rtd[i]; 608 return rtd;
560 } 609 }
561 dev_dbg(card->dev, "ASoC: failed to find rtd %s\n", dai_link); 610 dev_dbg(card->dev, "ASoC: failed to find rtd %s\n", dai_link);
562 return NULL; 611 return NULL;
@@ -578,7 +627,8 @@ int snd_soc_suspend(struct device *dev)
578{ 627{
579 struct snd_soc_card *card = dev_get_drvdata(dev); 628 struct snd_soc_card *card = dev_get_drvdata(dev);
580 struct snd_soc_codec *codec; 629 struct snd_soc_codec *codec;
581 int i, j; 630 struct snd_soc_pcm_runtime *rtd;
631 int i;
582 632
583 /* If the card is not initialized yet there is nothing to do */ 633 /* If the card is not initialized yet there is nothing to do */
584 if (!card->instantiated) 634 if (!card->instantiated)
@@ -595,13 +645,13 @@ int snd_soc_suspend(struct device *dev)
595 snd_power_change_state(card->snd_card, SNDRV_CTL_POWER_D3hot); 645 snd_power_change_state(card->snd_card, SNDRV_CTL_POWER_D3hot);
596 646
597 /* mute any active DACs */ 647 /* mute any active DACs */
598 for (i = 0; i < card->num_rtd; i++) { 648 list_for_each_entry(rtd, &card->rtd_list, list) {
599 649
600 if (card->rtd[i].dai_link->ignore_suspend) 650 if (rtd->dai_link->ignore_suspend)
601 continue; 651 continue;
602 652
603 for (j = 0; j < card->rtd[i].num_codecs; j++) { 653 for (i = 0; i < rtd->num_codecs; i++) {
604 struct snd_soc_dai *dai = card->rtd[i].codec_dais[j]; 654 struct snd_soc_dai *dai = rtd->codec_dais[i];
605 struct snd_soc_dai_driver *drv = dai->driver; 655 struct snd_soc_dai_driver *drv = dai->driver;
606 656
607 if (drv->ops->digital_mute && dai->playback_active) 657 if (drv->ops->digital_mute && dai->playback_active)
@@ -610,20 +660,20 @@ int snd_soc_suspend(struct device *dev)
610 } 660 }
611 661
612 /* suspend all pcms */ 662 /* suspend all pcms */
613 for (i = 0; i < card->num_rtd; i++) { 663 list_for_each_entry(rtd, &card->rtd_list, list) {
614 if (card->rtd[i].dai_link->ignore_suspend) 664 if (rtd->dai_link->ignore_suspend)
615 continue; 665 continue;
616 666
617 snd_pcm_suspend_all(card->rtd[i].pcm); 667 snd_pcm_suspend_all(rtd->pcm);
618 } 668 }
619 669
620 if (card->suspend_pre) 670 if (card->suspend_pre)
621 card->suspend_pre(card); 671 card->suspend_pre(card);
622 672
623 for (i = 0; i < card->num_rtd; i++) { 673 list_for_each_entry(rtd, &card->rtd_list, list) {
624 struct snd_soc_dai *cpu_dai = card->rtd[i].cpu_dai; 674 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
625 675
626 if (card->rtd[i].dai_link->ignore_suspend) 676 if (rtd->dai_link->ignore_suspend)
627 continue; 677 continue;
628 678
629 if (cpu_dai->driver->suspend && !cpu_dai->driver->bus_control) 679 if (cpu_dai->driver->suspend && !cpu_dai->driver->bus_control)
@@ -631,19 +681,19 @@ int snd_soc_suspend(struct device *dev)
631 } 681 }
632 682
633 /* close any waiting streams */ 683 /* close any waiting streams */
634 for (i = 0; i < card->num_rtd; i++) 684 list_for_each_entry(rtd, &card->rtd_list, list)
635 flush_delayed_work(&card->rtd[i].delayed_work); 685 flush_delayed_work(&rtd->delayed_work);
636 686
637 for (i = 0; i < card->num_rtd; i++) { 687 list_for_each_entry(rtd, &card->rtd_list, list) {
638 688
639 if (card->rtd[i].dai_link->ignore_suspend) 689 if (rtd->dai_link->ignore_suspend)
640 continue; 690 continue;
641 691
642 snd_soc_dapm_stream_event(&card->rtd[i], 692 snd_soc_dapm_stream_event(rtd,
643 SNDRV_PCM_STREAM_PLAYBACK, 693 SNDRV_PCM_STREAM_PLAYBACK,
644 SND_SOC_DAPM_STREAM_SUSPEND); 694 SND_SOC_DAPM_STREAM_SUSPEND);
645 695
646 snd_soc_dapm_stream_event(&card->rtd[i], 696 snd_soc_dapm_stream_event(rtd,
647 SNDRV_PCM_STREAM_CAPTURE, 697 SNDRV_PCM_STREAM_CAPTURE,
648 SND_SOC_DAPM_STREAM_SUSPEND); 698 SND_SOC_DAPM_STREAM_SUSPEND);
649 } 699 }
@@ -690,10 +740,10 @@ int snd_soc_suspend(struct device *dev)
690 } 740 }
691 } 741 }
692 742
693 for (i = 0; i < card->num_rtd; i++) { 743 list_for_each_entry(rtd, &card->rtd_list, list) {
694 struct snd_soc_dai *cpu_dai = card->rtd[i].cpu_dai; 744 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
695 745
696 if (card->rtd[i].dai_link->ignore_suspend) 746 if (rtd->dai_link->ignore_suspend)
697 continue; 747 continue;
698 748
699 if (cpu_dai->driver->suspend && cpu_dai->driver->bus_control) 749 if (cpu_dai->driver->suspend && cpu_dai->driver->bus_control)
@@ -717,8 +767,9 @@ static void soc_resume_deferred(struct work_struct *work)
717{ 767{
718 struct snd_soc_card *card = 768 struct snd_soc_card *card =
719 container_of(work, struct snd_soc_card, deferred_resume_work); 769 container_of(work, struct snd_soc_card, deferred_resume_work);
770 struct snd_soc_pcm_runtime *rtd;
720 struct snd_soc_codec *codec; 771 struct snd_soc_codec *codec;
721 int i, j; 772 int i;
722 773
723 /* our power state is still SNDRV_CTL_POWER_D3hot from suspend time, 774 /* our power state is still SNDRV_CTL_POWER_D3hot from suspend time,
724 * so userspace apps are blocked from touching us 775 * so userspace apps are blocked from touching us
@@ -733,10 +784,10 @@ static void soc_resume_deferred(struct work_struct *work)
733 card->resume_pre(card); 784 card->resume_pre(card);
734 785
735 /* resume control bus DAIs */ 786 /* resume control bus DAIs */
736 for (i = 0; i < card->num_rtd; i++) { 787 list_for_each_entry(rtd, &card->rtd_list, list) {
737 struct snd_soc_dai *cpu_dai = card->rtd[i].cpu_dai; 788 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
738 789
739 if (card->rtd[i].dai_link->ignore_suspend) 790 if (rtd->dai_link->ignore_suspend)
740 continue; 791 continue;
741 792
742 if (cpu_dai->driver->resume && cpu_dai->driver->bus_control) 793 if (cpu_dai->driver->resume && cpu_dai->driver->bus_control)
@@ -751,28 +802,28 @@ static void soc_resume_deferred(struct work_struct *work)
751 } 802 }
752 } 803 }
753 804
754 for (i = 0; i < card->num_rtd; i++) { 805 list_for_each_entry(rtd, &card->rtd_list, list) {
755 806
756 if (card->rtd[i].dai_link->ignore_suspend) 807 if (rtd->dai_link->ignore_suspend)
757 continue; 808 continue;
758 809
759 snd_soc_dapm_stream_event(&card->rtd[i], 810 snd_soc_dapm_stream_event(rtd,
760 SNDRV_PCM_STREAM_PLAYBACK, 811 SNDRV_PCM_STREAM_PLAYBACK,
761 SND_SOC_DAPM_STREAM_RESUME); 812 SND_SOC_DAPM_STREAM_RESUME);
762 813
763 snd_soc_dapm_stream_event(&card->rtd[i], 814 snd_soc_dapm_stream_event(rtd,
764 SNDRV_PCM_STREAM_CAPTURE, 815 SNDRV_PCM_STREAM_CAPTURE,
765 SND_SOC_DAPM_STREAM_RESUME); 816 SND_SOC_DAPM_STREAM_RESUME);
766 } 817 }
767 818
768 /* unmute any active DACs */ 819 /* unmute any active DACs */
769 for (i = 0; i < card->num_rtd; i++) { 820 list_for_each_entry(rtd, &card->rtd_list, list) {
770 821
771 if (card->rtd[i].dai_link->ignore_suspend) 822 if (rtd->dai_link->ignore_suspend)
772 continue; 823 continue;
773 824
774 for (j = 0; j < card->rtd[i].num_codecs; j++) { 825 for (i = 0; i < rtd->num_codecs; i++) {
775 struct snd_soc_dai *dai = card->rtd[i].codec_dais[j]; 826 struct snd_soc_dai *dai = rtd->codec_dais[i];
776 struct snd_soc_dai_driver *drv = dai->driver; 827 struct snd_soc_dai_driver *drv = dai->driver;
777 828
778 if (drv->ops->digital_mute && dai->playback_active) 829 if (drv->ops->digital_mute && dai->playback_active)
@@ -780,10 +831,10 @@ static void soc_resume_deferred(struct work_struct *work)
780 } 831 }
781 } 832 }
782 833
783 for (i = 0; i < card->num_rtd; i++) { 834 list_for_each_entry(rtd, &card->rtd_list, list) {
784 struct snd_soc_dai *cpu_dai = card->rtd[i].cpu_dai; 835 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
785 836
786 if (card->rtd[i].dai_link->ignore_suspend) 837 if (rtd->dai_link->ignore_suspend)
787 continue; 838 continue;
788 839
789 if (cpu_dai->driver->resume && !cpu_dai->driver->bus_control) 840 if (cpu_dai->driver->resume && !cpu_dai->driver->bus_control)
@@ -808,15 +859,14 @@ int snd_soc_resume(struct device *dev)
808{ 859{
809 struct snd_soc_card *card = dev_get_drvdata(dev); 860 struct snd_soc_card *card = dev_get_drvdata(dev);
810 bool bus_control = false; 861 bool bus_control = false;
811 int i; 862 struct snd_soc_pcm_runtime *rtd;
812 863
813 /* If the card is not initialized yet there is nothing to do */ 864 /* If the card is not initialized yet there is nothing to do */
814 if (!card->instantiated) 865 if (!card->instantiated)
815 return 0; 866 return 0;
816 867
817 /* activate pins from sleep state */ 868 /* activate pins from sleep state */
818 for (i = 0; i < card->num_rtd; i++) { 869 list_for_each_entry(rtd, &card->rtd_list, list) {
819 struct snd_soc_pcm_runtime *rtd = &card->rtd[i];
820 struct snd_soc_dai **codec_dais = rtd->codec_dais; 870 struct snd_soc_dai **codec_dais = rtd->codec_dais;
821 struct snd_soc_dai *cpu_dai = rtd->cpu_dai; 871 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
822 int j; 872 int j;
@@ -837,8 +887,8 @@ int snd_soc_resume(struct device *dev)
837 * have that problem and may take a substantial amount of time to resume 887 * have that problem and may take a substantial amount of time to resume
838 * due to I/O costs and anti-pop so handle them out of line. 888 * due to I/O costs and anti-pop so handle them out of line.
839 */ 889 */
840 for (i = 0; i < card->num_rtd; i++) { 890 list_for_each_entry(rtd, &card->rtd_list, list) {
841 struct snd_soc_dai *cpu_dai = card->rtd[i].cpu_dai; 891 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
842 bus_control |= cpu_dai->driver->bus_control; 892 bus_control |= cpu_dai->driver->bus_control;
843 } 893 }
844 if (bus_control) { 894 if (bus_control) {
@@ -910,18 +960,41 @@ static struct snd_soc_dai *snd_soc_find_dai(
910 return NULL; 960 return NULL;
911} 961}
912 962
913static int soc_bind_dai_link(struct snd_soc_card *card, int num) 963static bool soc_is_dai_link_bound(struct snd_soc_card *card,
964 struct snd_soc_dai_link *dai_link)
914{ 965{
915 struct snd_soc_dai_link *dai_link = &card->dai_link[num]; 966 struct snd_soc_pcm_runtime *rtd;
916 struct snd_soc_pcm_runtime *rtd = &card->rtd[num]; 967
968 list_for_each_entry(rtd, &card->rtd_list, list) {
969 if (rtd->dai_link == dai_link)
970 return true;
971 }
972
973 return false;
974}
975
976static int soc_bind_dai_link(struct snd_soc_card *card,
977 struct snd_soc_dai_link *dai_link)
978{
979 struct snd_soc_pcm_runtime *rtd;
917 struct snd_soc_dai_link_component *codecs = dai_link->codecs; 980 struct snd_soc_dai_link_component *codecs = dai_link->codecs;
918 struct snd_soc_dai_link_component cpu_dai_component; 981 struct snd_soc_dai_link_component cpu_dai_component;
919 struct snd_soc_dai **codec_dais = rtd->codec_dais; 982 struct snd_soc_dai **codec_dais;
920 struct snd_soc_platform *platform; 983 struct snd_soc_platform *platform;
921 const char *platform_name; 984 const char *platform_name;
922 int i; 985 int i;
923 986
924 dev_dbg(card->dev, "ASoC: binding %s at idx %d\n", dai_link->name, num); 987 dev_dbg(card->dev, "ASoC: binding %s\n", dai_link->name);
988
989 rtd = soc_new_pcm_runtime(card, dai_link);
990 if (!rtd)
991 return -ENOMEM;
992
993 if (soc_is_dai_link_bound(card, dai_link)) {
994 dev_dbg(card->dev, "ASoC: dai link %s already bound\n",
995 dai_link->name);
996 return 0;
997 }
925 998
926 cpu_dai_component.name = dai_link->cpu_name; 999 cpu_dai_component.name = dai_link->cpu_name;
927 cpu_dai_component.of_node = dai_link->cpu_of_node; 1000 cpu_dai_component.of_node = dai_link->cpu_of_node;
@@ -930,18 +1003,19 @@ static int soc_bind_dai_link(struct snd_soc_card *card, int num)
930 if (!rtd->cpu_dai) { 1003 if (!rtd->cpu_dai) {
931 dev_err(card->dev, "ASoC: CPU DAI %s not registered\n", 1004 dev_err(card->dev, "ASoC: CPU DAI %s not registered\n",
932 dai_link->cpu_dai_name); 1005 dai_link->cpu_dai_name);
933 return -EPROBE_DEFER; 1006 goto _err_defer;
934 } 1007 }
935 1008
936 rtd->num_codecs = dai_link->num_codecs; 1009 rtd->num_codecs = dai_link->num_codecs;
937 1010
938 /* Find CODEC from registered CODECs */ 1011 /* Find CODEC from registered CODECs */
1012 codec_dais = rtd->codec_dais;
939 for (i = 0; i < rtd->num_codecs; i++) { 1013 for (i = 0; i < rtd->num_codecs; i++) {
940 codec_dais[i] = snd_soc_find_dai(&codecs[i]); 1014 codec_dais[i] = snd_soc_find_dai(&codecs[i]);
941 if (!codec_dais[i]) { 1015 if (!codec_dais[i]) {
942 dev_err(card->dev, "ASoC: CODEC DAI %s not registered\n", 1016 dev_err(card->dev, "ASoC: CODEC DAI %s not registered\n",
943 codecs[i].dai_name); 1017 codecs[i].dai_name);
944 return -EPROBE_DEFER; 1018 goto _err_defer;
945 } 1019 }
946 } 1020 }
947 1021
@@ -973,9 +1047,12 @@ static int soc_bind_dai_link(struct snd_soc_card *card, int num)
973 return -EPROBE_DEFER; 1047 return -EPROBE_DEFER;
974 } 1048 }
975 1049
976 card->num_rtd++; 1050 soc_add_pcm_runtime(card, rtd);
977
978 return 0; 1051 return 0;
1052
1053_err_defer:
1054 soc_free_pcm_runtime(rtd);
1055 return -EPROBE_DEFER;
979} 1056}
980 1057
981static void soc_remove_component(struct snd_soc_component *component) 1058static void soc_remove_component(struct snd_soc_component *component)
@@ -1014,9 +1091,9 @@ static void soc_remove_dai(struct snd_soc_dai *dai, int order)
1014 } 1091 }
1015} 1092}
1016 1093
1017static void soc_remove_link_dais(struct snd_soc_card *card, int num, int order) 1094static void soc_remove_link_dais(struct snd_soc_card *card,
1095 struct snd_soc_pcm_runtime *rtd, int order)
1018{ 1096{
1019 struct snd_soc_pcm_runtime *rtd = &card->rtd[num];
1020 int i; 1097 int i;
1021 1098
1022 /* unregister the rtd device */ 1099 /* unregister the rtd device */
@@ -1032,10 +1109,9 @@ static void soc_remove_link_dais(struct snd_soc_card *card, int num, int order)
1032 soc_remove_dai(rtd->cpu_dai, order); 1109 soc_remove_dai(rtd->cpu_dai, order);
1033} 1110}
1034 1111
1035static void soc_remove_link_components(struct snd_soc_card *card, int num, 1112static void soc_remove_link_components(struct snd_soc_card *card,
1036 int order) 1113 struct snd_soc_pcm_runtime *rtd, int order)
1037{ 1114{
1038 struct snd_soc_pcm_runtime *rtd = &card->rtd[num];
1039 struct snd_soc_dai *cpu_dai = rtd->cpu_dai; 1115 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
1040 struct snd_soc_platform *platform = rtd->platform; 1116 struct snd_soc_platform *platform = rtd->platform;
1041 struct snd_soc_component *component; 1117 struct snd_soc_component *component;
@@ -1061,23 +1137,200 @@ static void soc_remove_link_components(struct snd_soc_card *card, int num,
1061 1137
1062static void soc_remove_dai_links(struct snd_soc_card *card) 1138static void soc_remove_dai_links(struct snd_soc_card *card)
1063{ 1139{
1064 int dai, order; 1140 int order;
1141 struct snd_soc_pcm_runtime *rtd;
1142 struct snd_soc_dai_link *link, *_link;
1065 1143
1066 for (order = SND_SOC_COMP_ORDER_FIRST; order <= SND_SOC_COMP_ORDER_LAST; 1144 for (order = SND_SOC_COMP_ORDER_FIRST; order <= SND_SOC_COMP_ORDER_LAST;
1067 order++) { 1145 order++) {
1068 for (dai = 0; dai < card->num_rtd; dai++) 1146 list_for_each_entry(rtd, &card->rtd_list, list)
1069 soc_remove_link_dais(card, dai, order); 1147 soc_remove_link_dais(card, rtd, order);
1070 } 1148 }
1071 1149
1072 for (order = SND_SOC_COMP_ORDER_FIRST; order <= SND_SOC_COMP_ORDER_LAST; 1150 for (order = SND_SOC_COMP_ORDER_FIRST; order <= SND_SOC_COMP_ORDER_LAST;
1073 order++) { 1151 order++) {
1074 for (dai = 0; dai < card->num_rtd; dai++) 1152 list_for_each_entry(rtd, &card->rtd_list, list)
1075 soc_remove_link_components(card, dai, order); 1153 soc_remove_link_components(card, rtd, order);
1076 } 1154 }
1077 1155
1078 card->num_rtd = 0; 1156 list_for_each_entry_safe(link, _link, &card->dai_link_list, list) {
1157 if (link->dobj.type == SND_SOC_DOBJ_DAI_LINK)
1158 dev_warn(card->dev, "Topology forgot to remove link %s?\n",
1159 link->name);
1160
1161 list_del(&link->list);
1162 card->num_dai_links--;
1163 }
1079} 1164}
1080 1165
1166static int snd_soc_init_multicodec(struct snd_soc_card *card,
1167 struct snd_soc_dai_link *dai_link)
1168{
1169 /* Legacy codec/codec_dai link is a single entry in multicodec */
1170 if (dai_link->codec_name || dai_link->codec_of_node ||
1171 dai_link->codec_dai_name) {
1172 dai_link->num_codecs = 1;
1173
1174 dai_link->codecs = devm_kzalloc(card->dev,
1175 sizeof(struct snd_soc_dai_link_component),
1176 GFP_KERNEL);
1177 if (!dai_link->codecs)
1178 return -ENOMEM;
1179
1180 dai_link->codecs[0].name = dai_link->codec_name;
1181 dai_link->codecs[0].of_node = dai_link->codec_of_node;
1182 dai_link->codecs[0].dai_name = dai_link->codec_dai_name;
1183 }
1184
1185 if (!dai_link->codecs) {
1186 dev_err(card->dev, "ASoC: DAI link has no CODECs\n");
1187 return -EINVAL;
1188 }
1189
1190 return 0;
1191}
1192
1193static int soc_init_dai_link(struct snd_soc_card *card,
1194 struct snd_soc_dai_link *link)
1195{
1196 int i, ret;
1197
1198 ret = snd_soc_init_multicodec(card, link);
1199 if (ret) {
1200 dev_err(card->dev, "ASoC: failed to init multicodec\n");
1201 return ret;
1202 }
1203
1204 for (i = 0; i < link->num_codecs; i++) {
1205 /*
1206 * Codec must be specified by 1 of name or OF node,
1207 * not both or neither.
1208 */
1209 if (!!link->codecs[i].name ==
1210 !!link->codecs[i].of_node) {
1211 dev_err(card->dev, "ASoC: Neither/both codec name/of_node are set for %s\n",
1212 link->name);
1213 return -EINVAL;
1214 }
1215 /* Codec DAI name must be specified */
1216 if (!link->codecs[i].dai_name) {
1217 dev_err(card->dev, "ASoC: codec_dai_name not set for %s\n",
1218 link->name);
1219 return -EINVAL;
1220 }
1221 }
1222
1223 /*
1224 * Platform may be specified by either name or OF node, but
1225 * can be left unspecified, and a dummy platform will be used.
1226 */
1227 if (link->platform_name && link->platform_of_node) {
1228 dev_err(card->dev,
1229 "ASoC: Both platform name/of_node are set for %s\n",
1230 link->name);
1231 return -EINVAL;
1232 }
1233
1234 /*
1235 * CPU device may be specified by either name or OF node, but
1236 * can be left unspecified, and will be matched based on DAI
1237 * name alone..
1238 */
1239 if (link->cpu_name && link->cpu_of_node) {
1240 dev_err(card->dev,
1241 "ASoC: Neither/both cpu name/of_node are set for %s\n",
1242 link->name);
1243 return -EINVAL;
1244 }
1245 /*
1246 * At least one of CPU DAI name or CPU device name/node must be
1247 * specified
1248 */
1249 if (!link->cpu_dai_name &&
1250 !(link->cpu_name || link->cpu_of_node)) {
1251 dev_err(card->dev,
1252 "ASoC: Neither cpu_dai_name nor cpu_name/of_node are set for %s\n",
1253 link->name);
1254 return -EINVAL;
1255 }
1256
1257 return 0;
1258}
1259
1260/**
1261 * snd_soc_add_dai_link - Add a DAI link dynamically
1262 * @card: The ASoC card to which the DAI link is added
1263 * @dai_link: The new DAI link to add
1264 *
1265 * This function adds a DAI link to the ASoC card's link list.
1266 *
1267 * Note: Topology can use this API to add DAI links when probing the
1268 * topology component. And machine drivers can still define static
1269 * DAI links in dai_link array.
1270 */
1271int snd_soc_add_dai_link(struct snd_soc_card *card,
1272 struct snd_soc_dai_link *dai_link)
1273{
1274 if (dai_link->dobj.type
1275 && dai_link->dobj.type != SND_SOC_DOBJ_DAI_LINK) {
1276 dev_err(card->dev, "Invalid dai link type %d\n",
1277 dai_link->dobj.type);
1278 return -EINVAL;
1279 }
1280
1281 lockdep_assert_held(&client_mutex);
1282 /* Notify the machine driver for extra initialization
1283 * on the link created by topology.
1284 */
1285 if (dai_link->dobj.type && card->add_dai_link)
1286 card->add_dai_link(card, dai_link);
1287
1288 list_add_tail(&dai_link->list, &card->dai_link_list);
1289 card->num_dai_links++;
1290
1291 return 0;
1292}
1293EXPORT_SYMBOL_GPL(snd_soc_add_dai_link);
1294
1295/**
1296 * snd_soc_remove_dai_link - Remove a DAI link from the list
1297 * @card: The ASoC card that owns the link
1298 * @dai_link: The DAI link to remove
1299 *
1300 * This function removes a DAI link from the ASoC card's link list.
1301 *
1302 * For DAI links previously added by topology, topology should
1303 * remove them by using the dobj embedded in the link.
1304 */
1305void snd_soc_remove_dai_link(struct snd_soc_card *card,
1306 struct snd_soc_dai_link *dai_link)
1307{
1308 struct snd_soc_dai_link *link, *_link;
1309
1310 if (dai_link->dobj.type
1311 && dai_link->dobj.type != SND_SOC_DOBJ_DAI_LINK) {
1312 dev_err(card->dev, "Invalid dai link type %d\n",
1313 dai_link->dobj.type);
1314 return;
1315 }
1316
1317 lockdep_assert_held(&client_mutex);
1318 /* Notify the machine driver for extra destruction
1319 * on the link created by topology.
1320 */
1321 if (dai_link->dobj.type && card->remove_dai_link)
1322 card->remove_dai_link(card, dai_link);
1323
1324 list_for_each_entry_safe(link, _link, &card->dai_link_list, list) {
1325 if (link == dai_link) {
1326 list_del(&link->list);
1327 card->num_dai_links--;
1328 return;
1329 }
1330 }
1331}
1332EXPORT_SYMBOL_GPL(snd_soc_remove_dai_link);
1333
1081static void soc_set_name_prefix(struct snd_soc_card *card, 1334static void soc_set_name_prefix(struct snd_soc_card *card,
1082 struct snd_soc_component *component) 1335 struct snd_soc_component *component)
1083{ 1336{
@@ -1160,6 +1413,16 @@ static int soc_probe_component(struct snd_soc_card *card,
1160 component->name); 1413 component->name);
1161 } 1414 }
1162 1415
1416 /* machine specific init */
1417 if (component->init) {
1418 ret = component->init(component);
1419 if (ret < 0) {
1420 dev_err(component->dev,
1421 "Failed to do machine specific init %d\n", ret);
1422 goto err_probe;
1423 }
1424 }
1425
1163 if (component->controls) 1426 if (component->controls)
1164 snd_soc_add_component_controls(component, component->controls, 1427 snd_soc_add_component_controls(component, component->controls,
1165 component->num_controls); 1428 component->num_controls);
@@ -1220,10 +1483,10 @@ static int soc_post_component_init(struct snd_soc_pcm_runtime *rtd,
1220 return 0; 1483 return 0;
1221} 1484}
1222 1485
1223static int soc_probe_link_components(struct snd_soc_card *card, int num, 1486static int soc_probe_link_components(struct snd_soc_card *card,
1487 struct snd_soc_pcm_runtime *rtd,
1224 int order) 1488 int order)
1225{ 1489{
1226 struct snd_soc_pcm_runtime *rtd = &card->rtd[num];
1227 struct snd_soc_platform *platform = rtd->platform; 1490 struct snd_soc_platform *platform = rtd->platform;
1228 struct snd_soc_component *component; 1491 struct snd_soc_component *component;
1229 int i, ret; 1492 int i, ret;
@@ -1283,35 +1546,35 @@ static int soc_link_dai_widgets(struct snd_soc_card *card,
1283{ 1546{
1284 struct snd_soc_dai *cpu_dai = rtd->cpu_dai; 1547 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
1285 struct snd_soc_dai *codec_dai = rtd->codec_dai; 1548 struct snd_soc_dai *codec_dai = rtd->codec_dai;
1286 struct snd_soc_dapm_widget *play_w, *capture_w; 1549 struct snd_soc_dapm_widget *sink, *source;
1287 int ret; 1550 int ret;
1288 1551
1289 if (rtd->num_codecs > 1) 1552 if (rtd->num_codecs > 1)
1290 dev_warn(card->dev, "ASoC: Multiple codecs not supported yet\n"); 1553 dev_warn(card->dev, "ASoC: Multiple codecs not supported yet\n");
1291 1554
1292 /* link the DAI widgets */ 1555 /* link the DAI widgets */
1293 play_w = codec_dai->playback_widget; 1556 sink = codec_dai->playback_widget;
1294 capture_w = cpu_dai->capture_widget; 1557 source = cpu_dai->capture_widget;
1295 if (play_w && capture_w) { 1558 if (sink && source) {
1296 ret = snd_soc_dapm_new_pcm(card, dai_link->params, 1559 ret = snd_soc_dapm_new_pcm(card, dai_link->params,
1297 dai_link->num_params, capture_w, 1560 dai_link->num_params,
1298 play_w); 1561 source, sink);
1299 if (ret != 0) { 1562 if (ret != 0) {
1300 dev_err(card->dev, "ASoC: Can't link %s to %s: %d\n", 1563 dev_err(card->dev, "ASoC: Can't link %s to %s: %d\n",
1301 play_w->name, capture_w->name, ret); 1564 sink->name, source->name, ret);
1302 return ret; 1565 return ret;
1303 } 1566 }
1304 } 1567 }
1305 1568
1306 play_w = cpu_dai->playback_widget; 1569 sink = cpu_dai->playback_widget;
1307 capture_w = codec_dai->capture_widget; 1570 source = codec_dai->capture_widget;
1308 if (play_w && capture_w) { 1571 if (sink && source) {
1309 ret = snd_soc_dapm_new_pcm(card, dai_link->params, 1572 ret = snd_soc_dapm_new_pcm(card, dai_link->params,
1310 dai_link->num_params, capture_w, 1573 dai_link->num_params,
1311 play_w); 1574 source, sink);
1312 if (ret != 0) { 1575 if (ret != 0) {
1313 dev_err(card->dev, "ASoC: Can't link %s to %s: %d\n", 1576 dev_err(card->dev, "ASoC: Can't link %s to %s: %d\n",
1314 play_w->name, capture_w->name, ret); 1577 sink->name, source->name, ret);
1315 return ret; 1578 return ret;
1316 } 1579 }
1317 } 1580 }
@@ -1319,15 +1582,15 @@ static int soc_link_dai_widgets(struct snd_soc_card *card,
1319 return 0; 1582 return 0;
1320} 1583}
1321 1584
1322static int soc_probe_link_dais(struct snd_soc_card *card, int num, int order) 1585static int soc_probe_link_dais(struct snd_soc_card *card,
1586 struct snd_soc_pcm_runtime *rtd, int order)
1323{ 1587{
1324 struct snd_soc_dai_link *dai_link = &card->dai_link[num]; 1588 struct snd_soc_dai_link *dai_link = rtd->dai_link;
1325 struct snd_soc_pcm_runtime *rtd = &card->rtd[num];
1326 struct snd_soc_dai *cpu_dai = rtd->cpu_dai; 1589 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
1327 int i, ret; 1590 int i, ret;
1328 1591
1329 dev_dbg(card->dev, "ASoC: probe %s dai link %d late %d\n", 1592 dev_dbg(card->dev, "ASoC: probe %s dai link %d late %d\n",
1330 card->name, num, order); 1593 card->name, rtd->num, order);
1331 1594
1332 /* set default power off timeout */ 1595 /* set default power off timeout */
1333 rtd->pmdown_time = pmdown_time; 1596 rtd->pmdown_time = pmdown_time;
@@ -1372,7 +1635,7 @@ static int soc_probe_link_dais(struct snd_soc_card *card, int num, int order)
1372 1635
1373 if (cpu_dai->driver->compress_new) { 1636 if (cpu_dai->driver->compress_new) {
1374 /*create compress_device"*/ 1637 /*create compress_device"*/
1375 ret = cpu_dai->driver->compress_new(rtd, num); 1638 ret = cpu_dai->driver->compress_new(rtd, rtd->num);
1376 if (ret < 0) { 1639 if (ret < 0) {
1377 dev_err(card->dev, "ASoC: can't create compress %s\n", 1640 dev_err(card->dev, "ASoC: can't create compress %s\n",
1378 dai_link->stream_name); 1641 dai_link->stream_name);
@@ -1382,7 +1645,7 @@ static int soc_probe_link_dais(struct snd_soc_card *card, int num, int order)
1382 1645
1383 if (!dai_link->params) { 1646 if (!dai_link->params) {
1384 /* create the pcm */ 1647 /* create the pcm */
1385 ret = soc_new_pcm(rtd, num); 1648 ret = soc_new_pcm(rtd, rtd->num);
1386 if (ret < 0) { 1649 if (ret < 0) {
1387 dev_err(card->dev, "ASoC: can't create pcm %s :%d\n", 1650 dev_err(card->dev, "ASoC: can't create pcm %s :%d\n",
1388 dai_link->stream_name, ret); 1651 dai_link->stream_name, ret);
@@ -1404,65 +1667,81 @@ static int soc_probe_link_dais(struct snd_soc_card *card, int num, int order)
1404 1667
1405static int soc_bind_aux_dev(struct snd_soc_card *card, int num) 1668static int soc_bind_aux_dev(struct snd_soc_card *card, int num)
1406{ 1669{
1407 struct snd_soc_pcm_runtime *rtd = &card->rtd_aux[num];
1408 struct snd_soc_aux_dev *aux_dev = &card->aux_dev[num]; 1670 struct snd_soc_aux_dev *aux_dev = &card->aux_dev[num];
1409 const char *name = aux_dev->codec_name; 1671 struct snd_soc_component *component;
1410 1672 const char *name;
1411 rtd->component = soc_find_component(aux_dev->codec_of_node, name); 1673 struct device_node *codec_of_node;
1412 if (!rtd->component) { 1674
1413 if (aux_dev->codec_of_node) 1675 if (aux_dev->codec_of_node || aux_dev->codec_name) {
1414 name = of_node_full_name(aux_dev->codec_of_node); 1676 /* codecs, usually analog devices */
1415 1677 name = aux_dev->codec_name;
1416 dev_err(card->dev, "ASoC: %s not registered\n", name); 1678 codec_of_node = aux_dev->codec_of_node;
1417 return -EPROBE_DEFER; 1679 component = soc_find_component(codec_of_node, name);
1680 if (!component) {
1681 if (codec_of_node)
1682 name = of_node_full_name(codec_of_node);
1683 goto err_defer;
1684 }
1685 } else if (aux_dev->name) {
1686 /* generic components */
1687 name = aux_dev->name;
1688 component = soc_find_component(NULL, name);
1689 if (!component)
1690 goto err_defer;
1691 } else {
1692 dev_err(card->dev, "ASoC: Invalid auxiliary device\n");
1693 return -EINVAL;
1418 } 1694 }
1419 1695
1420 /* 1696 component->init = aux_dev->init;
1421 * Some places still reference rtd->codec, so we have to keep that 1697 list_add(&component->list_aux, &card->aux_comp_list);
1422 * initialized if the component is a CODEC. Once all those references
1423 * have been removed, this code can be removed as well.
1424 */
1425 rtd->codec = rtd->component->codec;
1426
1427 return 0; 1698 return 0;
1699
1700err_defer:
1701 dev_err(card->dev, "ASoC: %s not registered\n", name);
1702 return -EPROBE_DEFER;
1428} 1703}
1429 1704
1430static int soc_probe_aux_dev(struct snd_soc_card *card, int num) 1705static int soc_probe_aux_devices(struct snd_soc_card *card)
1431{ 1706{
1432 struct snd_soc_pcm_runtime *rtd = &card->rtd_aux[num]; 1707 struct snd_soc_component *comp;
1433 struct snd_soc_aux_dev *aux_dev = &card->aux_dev[num]; 1708 int order;
1434 int ret; 1709 int ret;
1435 1710
1436 ret = soc_probe_component(card, rtd->component); 1711 for (order = SND_SOC_COMP_ORDER_FIRST; order <= SND_SOC_COMP_ORDER_LAST;
1437 if (ret < 0) 1712 order++) {
1438 return ret; 1713 list_for_each_entry(comp, &card->aux_comp_list, list_aux) {
1439 1714 if (comp->driver->probe_order == order) {
1440 /* do machine specific initialization */ 1715 ret = soc_probe_component(card, comp);
1441 if (aux_dev->init) { 1716 if (ret < 0) {
1442 ret = aux_dev->init(rtd->component); 1717 dev_err(card->dev,
1443 if (ret < 0) { 1718 "ASoC: failed to probe aux component %s %d\n",
1444 dev_err(card->dev, "ASoC: failed to init %s: %d\n", 1719 comp->name, ret);
1445 aux_dev->name, ret); 1720 return ret;
1446 return ret; 1721 }
1722 }
1447 } 1723 }
1448 } 1724 }
1449 1725
1450 return soc_post_component_init(rtd, aux_dev->name); 1726 return 0;
1451} 1727}
1452 1728
1453static void soc_remove_aux_dev(struct snd_soc_card *card, int num) 1729static void soc_remove_aux_devices(struct snd_soc_card *card)
1454{ 1730{
1455 struct snd_soc_pcm_runtime *rtd = &card->rtd_aux[num]; 1731 struct snd_soc_component *comp, *_comp;
1456 struct snd_soc_component *component = rtd->component; 1732 int order;
1457 1733
1458 /* unregister the rtd device */ 1734 for (order = SND_SOC_COMP_ORDER_FIRST; order <= SND_SOC_COMP_ORDER_LAST;
1459 if (rtd->dev_registered) { 1735 order++) {
1460 device_unregister(rtd->dev); 1736 list_for_each_entry_safe(comp, _comp,
1461 rtd->dev_registered = 0; 1737 &card->aux_comp_list, list_aux) {
1738 if (comp->driver->remove_order == order) {
1739 soc_remove_component(comp);
1740 /* remove it from the card's aux_comp_list */
1741 list_del(&comp->list_aux);
1742 }
1743 }
1462 } 1744 }
1463
1464 if (component)
1465 soc_remove_component(component);
1466} 1745}
1467 1746
1468static int snd_soc_init_codec_cache(struct snd_soc_codec *codec) 1747static int snd_soc_init_codec_cache(struct snd_soc_codec *codec)
@@ -1552,6 +1831,8 @@ EXPORT_SYMBOL_GPL(snd_soc_runtime_set_dai_fmt);
1552static int snd_soc_instantiate_card(struct snd_soc_card *card) 1831static int snd_soc_instantiate_card(struct snd_soc_card *card)
1553{ 1832{
1554 struct snd_soc_codec *codec; 1833 struct snd_soc_codec *codec;
1834 struct snd_soc_pcm_runtime *rtd;
1835 struct snd_soc_dai_link *dai_link;
1555 int ret, i, order; 1836 int ret, i, order;
1556 1837
1557 mutex_lock(&client_mutex); 1838 mutex_lock(&client_mutex);
@@ -1559,7 +1840,7 @@ static int snd_soc_instantiate_card(struct snd_soc_card *card)
1559 1840
1560 /* bind DAIs */ 1841 /* bind DAIs */
1561 for (i = 0; i < card->num_links; i++) { 1842 for (i = 0; i < card->num_links; i++) {
1562 ret = soc_bind_dai_link(card, i); 1843 ret = soc_bind_dai_link(card, &card->dai_link[i]);
1563 if (ret != 0) 1844 if (ret != 0)
1564 goto base_error; 1845 goto base_error;
1565 } 1846 }
@@ -1571,6 +1852,10 @@ static int snd_soc_instantiate_card(struct snd_soc_card *card)
1571 goto base_error; 1852 goto base_error;
1572 } 1853 }
1573 1854
1855 /* add predefined DAI links to the list */
1856 for (i = 0; i < card->num_links; i++)
1857 snd_soc_add_dai_link(card, card->dai_link+i);
1858
1574 /* initialize the register cache for each available codec */ 1859 /* initialize the register cache for each available codec */
1575 list_for_each_entry(codec, &codec_list, list) { 1860 list_for_each_entry(codec, &codec_list, list) {
1576 if (codec->cache_init) 1861 if (codec->cache_init)
@@ -1624,8 +1909,8 @@ static int snd_soc_instantiate_card(struct snd_soc_card *card)
1624 /* probe all components used by DAI links on this card */ 1909 /* probe all components used by DAI links on this card */
1625 for (order = SND_SOC_COMP_ORDER_FIRST; order <= SND_SOC_COMP_ORDER_LAST; 1910 for (order = SND_SOC_COMP_ORDER_FIRST; order <= SND_SOC_COMP_ORDER_LAST;
1626 order++) { 1911 order++) {
1627 for (i = 0; i < card->num_links; i++) { 1912 list_for_each_entry(rtd, &card->rtd_list, list) {
1628 ret = soc_probe_link_components(card, i, order); 1913 ret = soc_probe_link_components(card, rtd, order);
1629 if (ret < 0) { 1914 if (ret < 0) {
1630 dev_err(card->dev, 1915 dev_err(card->dev,
1631 "ASoC: failed to instantiate card %d\n", 1916 "ASoC: failed to instantiate card %d\n",
@@ -1635,11 +1920,31 @@ static int snd_soc_instantiate_card(struct snd_soc_card *card)
1635 } 1920 }
1636 } 1921 }
1637 1922
1923 /* probe auxiliary components */
1924 ret = soc_probe_aux_devices(card);
1925 if (ret < 0)
1926 goto probe_dai_err;
1927
1928 /* Find new DAI links added during probing components and bind them.
1929 * Components with topology may bring new DAIs and DAI links.
1930 */
1931 list_for_each_entry(dai_link, &card->dai_link_list, list) {
1932 if (soc_is_dai_link_bound(card, dai_link))
1933 continue;
1934
1935 ret = soc_init_dai_link(card, dai_link);
1936 if (ret)
1937 goto probe_dai_err;
1938 ret = soc_bind_dai_link(card, dai_link);
1939 if (ret)
1940 goto probe_dai_err;
1941 }
1942
1638 /* probe all DAI links on this card */ 1943 /* probe all DAI links on this card */
1639 for (order = SND_SOC_COMP_ORDER_FIRST; order <= SND_SOC_COMP_ORDER_LAST; 1944 for (order = SND_SOC_COMP_ORDER_FIRST; order <= SND_SOC_COMP_ORDER_LAST;
1640 order++) { 1945 order++) {
1641 for (i = 0; i < card->num_links; i++) { 1946 list_for_each_entry(rtd, &card->rtd_list, list) {
1642 ret = soc_probe_link_dais(card, i, order); 1947 ret = soc_probe_link_dais(card, rtd, order);
1643 if (ret < 0) { 1948 if (ret < 0) {
1644 dev_err(card->dev, 1949 dev_err(card->dev,
1645 "ASoC: failed to instantiate card %d\n", 1950 "ASoC: failed to instantiate card %d\n",
@@ -1649,16 +1954,6 @@ static int snd_soc_instantiate_card(struct snd_soc_card *card)
1649 } 1954 }
1650 } 1955 }
1651 1956
1652 for (i = 0; i < card->num_aux_devs; i++) {
1653 ret = soc_probe_aux_dev(card, i);
1654 if (ret < 0) {
1655 dev_err(card->dev,
1656 "ASoC: failed to add auxiliary devices %d\n",
1657 ret);
1658 goto probe_aux_dev_err;
1659 }
1660 }
1661
1662 snd_soc_dapm_link_dai_widgets(card); 1957 snd_soc_dapm_link_dai_widgets(card);
1663 snd_soc_dapm_connect_dai_link_widgets(card); 1958 snd_soc_dapm_connect_dai_link_widgets(card);
1664 1959
@@ -1718,8 +2013,7 @@ static int snd_soc_instantiate_card(struct snd_soc_card *card)
1718 return 0; 2013 return 0;
1719 2014
1720probe_aux_dev_err: 2015probe_aux_dev_err:
1721 for (i = 0; i < card->num_aux_devs; i++) 2016 soc_remove_aux_devices(card);
1722 soc_remove_aux_dev(card, i);
1723 2017
1724probe_dai_err: 2018probe_dai_err:
1725 soc_remove_dai_links(card); 2019 soc_remove_dai_links(card);
@@ -1733,6 +2027,7 @@ card_probe_error:
1733 snd_card_free(card->snd_card); 2027 snd_card_free(card->snd_card);
1734 2028
1735base_error: 2029base_error:
2030 soc_remove_pcm_runtimes(card);
1736 mutex_unlock(&card->mutex); 2031 mutex_unlock(&card->mutex);
1737 mutex_unlock(&client_mutex); 2032 mutex_unlock(&client_mutex);
1738 2033
@@ -1763,20 +2058,18 @@ static int soc_probe(struct platform_device *pdev)
1763 2058
1764static int soc_cleanup_card_resources(struct snd_soc_card *card) 2059static int soc_cleanup_card_resources(struct snd_soc_card *card)
1765{ 2060{
1766 int i; 2061 struct snd_soc_pcm_runtime *rtd;
1767 2062
1768 /* make sure any delayed work runs */ 2063 /* make sure any delayed work runs */
1769 for (i = 0; i < card->num_rtd; i++) { 2064 list_for_each_entry(rtd, &card->rtd_list, list)
1770 struct snd_soc_pcm_runtime *rtd = &card->rtd[i];
1771 flush_delayed_work(&rtd->delayed_work); 2065 flush_delayed_work(&rtd->delayed_work);
1772 }
1773
1774 /* remove auxiliary devices */
1775 for (i = 0; i < card->num_aux_devs; i++)
1776 soc_remove_aux_dev(card, i);
1777 2066
1778 /* remove and free each DAI */ 2067 /* remove and free each DAI */
1779 soc_remove_dai_links(card); 2068 soc_remove_dai_links(card);
2069 soc_remove_pcm_runtimes(card);
2070
2071 /* remove auxiliary devices */
2072 soc_remove_aux_devices(card);
1780 2073
1781 soc_cleanup_card_debugfs(card); 2074 soc_cleanup_card_debugfs(card);
1782 2075
@@ -1803,29 +2096,26 @@ static int soc_remove(struct platform_device *pdev)
1803int snd_soc_poweroff(struct device *dev) 2096int snd_soc_poweroff(struct device *dev)
1804{ 2097{
1805 struct snd_soc_card *card = dev_get_drvdata(dev); 2098 struct snd_soc_card *card = dev_get_drvdata(dev);
1806 int i; 2099 struct snd_soc_pcm_runtime *rtd;
1807 2100
1808 if (!card->instantiated) 2101 if (!card->instantiated)
1809 return 0; 2102 return 0;
1810 2103
1811 /* Flush out pmdown_time work - we actually do want to run it 2104 /* Flush out pmdown_time work - we actually do want to run it
1812 * now, we're shutting down so no imminent restart. */ 2105 * now, we're shutting down so no imminent restart. */
1813 for (i = 0; i < card->num_rtd; i++) { 2106 list_for_each_entry(rtd, &card->rtd_list, list)
1814 struct snd_soc_pcm_runtime *rtd = &card->rtd[i];
1815 flush_delayed_work(&rtd->delayed_work); 2107 flush_delayed_work(&rtd->delayed_work);
1816 }
1817 2108
1818 snd_soc_dapm_shutdown(card); 2109 snd_soc_dapm_shutdown(card);
1819 2110
1820 /* deactivate pins to sleep state */ 2111 /* deactivate pins to sleep state */
1821 for (i = 0; i < card->num_rtd; i++) { 2112 list_for_each_entry(rtd, &card->rtd_list, list) {
1822 struct snd_soc_pcm_runtime *rtd = &card->rtd[i];
1823 struct snd_soc_dai *cpu_dai = rtd->cpu_dai; 2113 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
1824 int j; 2114 int i;
1825 2115
1826 pinctrl_pm_select_sleep_state(cpu_dai->dev); 2116 pinctrl_pm_select_sleep_state(cpu_dai->dev);
1827 for (j = 0; j < rtd->num_codecs; j++) { 2117 for (i = 0; i < rtd->num_codecs; i++) {
1828 struct snd_soc_dai *codec_dai = rtd->codec_dais[j]; 2118 struct snd_soc_dai *codec_dai = rtd->codec_dais[i];
1829 pinctrl_pm_select_sleep_state(codec_dai->dev); 2119 pinctrl_pm_select_sleep_state(codec_dai->dev);
1830 } 2120 }
1831 } 2121 }
@@ -2301,33 +2591,6 @@ int snd_soc_dai_digital_mute(struct snd_soc_dai *dai, int mute,
2301} 2591}
2302EXPORT_SYMBOL_GPL(snd_soc_dai_digital_mute); 2592EXPORT_SYMBOL_GPL(snd_soc_dai_digital_mute);
2303 2593
2304static int snd_soc_init_multicodec(struct snd_soc_card *card,
2305 struct snd_soc_dai_link *dai_link)
2306{
2307 /* Legacy codec/codec_dai link is a single entry in multicodec */
2308 if (dai_link->codec_name || dai_link->codec_of_node ||
2309 dai_link->codec_dai_name) {
2310 dai_link->num_codecs = 1;
2311
2312 dai_link->codecs = devm_kzalloc(card->dev,
2313 sizeof(struct snd_soc_dai_link_component),
2314 GFP_KERNEL);
2315 if (!dai_link->codecs)
2316 return -ENOMEM;
2317
2318 dai_link->codecs[0].name = dai_link->codec_name;
2319 dai_link->codecs[0].of_node = dai_link->codec_of_node;
2320 dai_link->codecs[0].dai_name = dai_link->codec_dai_name;
2321 }
2322
2323 if (!dai_link->codecs) {
2324 dev_err(card->dev, "ASoC: DAI link has no CODECs\n");
2325 return -EINVAL;
2326 }
2327
2328 return 0;
2329}
2330
2331/** 2594/**
2332 * snd_soc_register_card - Register a card with the ASoC core 2595 * snd_soc_register_card - Register a card with the ASoC core
2333 * 2596 *
@@ -2336,7 +2599,8 @@ static int snd_soc_init_multicodec(struct snd_soc_card *card,
2336 */ 2599 */
2337int snd_soc_register_card(struct snd_soc_card *card) 2600int snd_soc_register_card(struct snd_soc_card *card)
2338{ 2601{
2339 int i, j, ret; 2602 int i, ret;
2603 struct snd_soc_pcm_runtime *rtd;
2340 2604
2341 if (!card->name || !card->dev) 2605 if (!card->name || !card->dev)
2342 return -EINVAL; 2606 return -EINVAL;
@@ -2344,63 +2608,11 @@ int snd_soc_register_card(struct snd_soc_card *card)
2344 for (i = 0; i < card->num_links; i++) { 2608 for (i = 0; i < card->num_links; i++) {
2345 struct snd_soc_dai_link *link = &card->dai_link[i]; 2609 struct snd_soc_dai_link *link = &card->dai_link[i];
2346 2610
2347 ret = snd_soc_init_multicodec(card, link); 2611 ret = soc_init_dai_link(card, link);
2348 if (ret) { 2612 if (ret) {
2349 dev_err(card->dev, "ASoC: failed to init multicodec\n"); 2613 dev_err(card->dev, "ASoC: failed to init link %s\n",
2350 return ret;
2351 }
2352
2353 for (j = 0; j < link->num_codecs; j++) {
2354 /*
2355 * Codec must be specified by 1 of name or OF node,
2356 * not both or neither.
2357 */
2358 if (!!link->codecs[j].name ==
2359 !!link->codecs[j].of_node) {
2360 dev_err(card->dev, "ASoC: Neither/both codec name/of_node are set for %s\n",
2361 link->name);
2362 return -EINVAL;
2363 }
2364 /* Codec DAI name must be specified */
2365 if (!link->codecs[j].dai_name) {
2366 dev_err(card->dev, "ASoC: codec_dai_name not set for %s\n",
2367 link->name);
2368 return -EINVAL;
2369 }
2370 }
2371
2372 /*
2373 * Platform may be specified by either name or OF node, but
2374 * can be left unspecified, and a dummy platform will be used.
2375 */
2376 if (link->platform_name && link->platform_of_node) {
2377 dev_err(card->dev,
2378 "ASoC: Both platform name/of_node are set for %s\n",
2379 link->name); 2614 link->name);
2380 return -EINVAL; 2615 return ret;
2381 }
2382
2383 /*
2384 * CPU device may be specified by either name or OF node, but
2385 * can be left unspecified, and will be matched based on DAI
2386 * name alone..
2387 */
2388 if (link->cpu_name && link->cpu_of_node) {
2389 dev_err(card->dev,
2390 "ASoC: Neither/both cpu name/of_node are set for %s\n",
2391 link->name);
2392 return -EINVAL;
2393 }
2394 /*
2395 * At least one of CPU DAI name or CPU device name/node must be
2396 * specified
2397 */
2398 if (!link->cpu_dai_name &&
2399 !(link->cpu_name || link->cpu_of_node)) {
2400 dev_err(card->dev,
2401 "ASoC: Neither cpu_dai_name nor cpu_name/of_node are set for %s\n",
2402 link->name);
2403 return -EINVAL;
2404 } 2616 }
2405 } 2617 }
2406 2618
@@ -2408,28 +2620,11 @@ int snd_soc_register_card(struct snd_soc_card *card)
2408 2620
2409 snd_soc_initialize_card_lists(card); 2621 snd_soc_initialize_card_lists(card);
2410 2622
2411 card->rtd = devm_kzalloc(card->dev, 2623 INIT_LIST_HEAD(&card->dai_link_list);
2412 sizeof(struct snd_soc_pcm_runtime) * 2624 card->num_dai_links = 0;
2413 (card->num_links + card->num_aux_devs),
2414 GFP_KERNEL);
2415 if (card->rtd == NULL)
2416 return -ENOMEM;
2417 card->num_rtd = 0;
2418 card->rtd_aux = &card->rtd[card->num_links];
2419
2420 for (i = 0; i < card->num_links; i++) {
2421 card->rtd[i].card = card;
2422 card->rtd[i].dai_link = &card->dai_link[i];
2423 card->rtd[i].codec_dais = devm_kzalloc(card->dev,
2424 sizeof(struct snd_soc_dai *) *
2425 (card->rtd[i].dai_link->num_codecs),
2426 GFP_KERNEL);
2427 if (card->rtd[i].codec_dais == NULL)
2428 return -ENOMEM;
2429 }
2430 2625
2431 for (i = 0; i < card->num_aux_devs; i++) 2626 INIT_LIST_HEAD(&card->rtd_list);
2432 card->rtd_aux[i].card = card; 2627 card->num_rtd = 0;
2433 2628
2434 INIT_LIST_HEAD(&card->dapm_dirty); 2629 INIT_LIST_HEAD(&card->dapm_dirty);
2435 INIT_LIST_HEAD(&card->dobj_list); 2630 INIT_LIST_HEAD(&card->dobj_list);
@@ -2442,8 +2637,7 @@ int snd_soc_register_card(struct snd_soc_card *card)
2442 return ret; 2637 return ret;
2443 2638
2444 /* deactivate pins to sleep state */ 2639 /* deactivate pins to sleep state */
2445 for (i = 0; i < card->num_rtd; i++) { 2640 list_for_each_entry(rtd, &card->rtd_list, list) {
2446 struct snd_soc_pcm_runtime *rtd = &card->rtd[i];
2447 struct snd_soc_dai *cpu_dai = rtd->cpu_dai; 2641 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
2448 int j; 2642 int j;
2449 2643
@@ -2558,6 +2752,56 @@ static void snd_soc_unregister_dais(struct snd_soc_component *component)
2558 } 2752 }
2559} 2753}
2560 2754
2755/* Create a DAI and add it to the component's DAI list */
2756static struct snd_soc_dai *soc_add_dai(struct snd_soc_component *component,
2757 struct snd_soc_dai_driver *dai_drv,
2758 bool legacy_dai_naming)
2759{
2760 struct device *dev = component->dev;
2761 struct snd_soc_dai *dai;
2762
2763 dev_dbg(dev, "ASoC: dynamically register DAI %s\n", dev_name(dev));
2764
2765 dai = kzalloc(sizeof(struct snd_soc_dai), GFP_KERNEL);
2766 if (dai == NULL)
2767 return NULL;
2768
2769 /*
2770 * Back in the old days when we still had component-less DAIs,
2771 * instead of having a static name, component-less DAIs would
2772 * inherit the name of the parent device so it is possible to
2773 * register multiple instances of the DAI. We still need to keep
2774 * the same naming style even though those DAIs are not
2775 * component-less anymore.
2776 */
2777 if (legacy_dai_naming &&
2778 (dai_drv->id == 0 || dai_drv->name == NULL)) {
2779 dai->name = fmt_single_name(dev, &dai->id);
2780 } else {
2781 dai->name = fmt_multiple_name(dev, dai_drv);
2782 if (dai_drv->id)
2783 dai->id = dai_drv->id;
2784 else
2785 dai->id = component->num_dai;
2786 }
2787 if (dai->name == NULL) {
2788 kfree(dai);
2789 return NULL;
2790 }
2791
2792 dai->component = component;
2793 dai->dev = dev;
2794 dai->driver = dai_drv;
2795 if (!dai->driver->ops)
2796 dai->driver->ops = &null_dai_ops;
2797
2798 list_add(&dai->list, &component->dai_list);
2799 component->num_dai++;
2800
2801 dev_dbg(dev, "ASoC: Registered DAI '%s'\n", dai->name);
2802 return dai;
2803}
2804
2561/** 2805/**
2562 * snd_soc_register_dais - Register a DAI with the ASoC core 2806 * snd_soc_register_dais - Register a DAI with the ASoC core
2563 * 2807 *
@@ -2579,58 +2823,66 @@ static int snd_soc_register_dais(struct snd_soc_component *component,
2579 dev_dbg(dev, "ASoC: dai register %s #%Zu\n", dev_name(dev), count); 2823 dev_dbg(dev, "ASoC: dai register %s #%Zu\n", dev_name(dev), count);
2580 2824
2581 component->dai_drv = dai_drv; 2825 component->dai_drv = dai_drv;
2582 component->num_dai = count;
2583 2826
2584 for (i = 0; i < count; i++) { 2827 for (i = 0; i < count; i++) {
2585 2828
2586 dai = kzalloc(sizeof(struct snd_soc_dai), GFP_KERNEL); 2829 dai = soc_add_dai(component, dai_drv + i,
2830 count == 1 && legacy_dai_naming);
2587 if (dai == NULL) { 2831 if (dai == NULL) {
2588 ret = -ENOMEM; 2832 ret = -ENOMEM;
2589 goto err; 2833 goto err;
2590 } 2834 }
2835 }
2591 2836
2592 /* 2837 return 0;
2593 * Back in the old days when we still had component-less DAIs,
2594 * instead of having a static name, component-less DAIs would
2595 * inherit the name of the parent device so it is possible to
2596 * register multiple instances of the DAI. We still need to keep
2597 * the same naming style even though those DAIs are not
2598 * component-less anymore.
2599 */
2600 if (count == 1 && legacy_dai_naming &&
2601 (dai_drv[i].id == 0 || dai_drv[i].name == NULL)) {
2602 dai->name = fmt_single_name(dev, &dai->id);
2603 } else {
2604 dai->name = fmt_multiple_name(dev, &dai_drv[i]);
2605 if (dai_drv[i].id)
2606 dai->id = dai_drv[i].id;
2607 else
2608 dai->id = i;
2609 }
2610 if (dai->name == NULL) {
2611 kfree(dai);
2612 ret = -ENOMEM;
2613 goto err;
2614 }
2615 2838
2616 dai->component = component; 2839err:
2617 dai->dev = dev; 2840 snd_soc_unregister_dais(component);
2618 dai->driver = &dai_drv[i];
2619 if (!dai->driver->ops)
2620 dai->driver->ops = &null_dai_ops;
2621 2841
2622 list_add(&dai->list, &component->dai_list); 2842 return ret;
2843}
2844
2845/**
2846 * snd_soc_register_dai - Register a DAI dynamically & create its widgets
2847 *
2848 * @component: The component the DAIs are registered for
2849 * @dai_drv: DAI driver to use for the DAI
2850 *
2851 * Topology can use this API to register DAIs when probing a component.
2852 * These DAIs's widgets will be freed in the card cleanup and the DAIs
2853 * will be freed in the component cleanup.
2854 */
2855int snd_soc_register_dai(struct snd_soc_component *component,
2856 struct snd_soc_dai_driver *dai_drv)
2857{
2858 struct snd_soc_dapm_context *dapm =
2859 snd_soc_component_get_dapm(component);
2860 struct snd_soc_dai *dai;
2861 int ret;
2623 2862
2624 dev_dbg(dev, "ASoC: Registered DAI '%s'\n", dai->name); 2863 if (dai_drv->dobj.type != SND_SOC_DOBJ_PCM) {
2864 dev_err(component->dev, "Invalid dai type %d\n",
2865 dai_drv->dobj.type);
2866 return -EINVAL;
2625 } 2867 }
2626 2868
2627 return 0; 2869 lockdep_assert_held(&client_mutex);
2870 dai = soc_add_dai(component, dai_drv, false);
2871 if (!dai)
2872 return -ENOMEM;
2628 2873
2629err: 2874 /* Create the DAI widgets here. After adding DAIs, topology may
2630 snd_soc_unregister_dais(component); 2875 * also add routes that need these widgets as source or sink.
2876 */
2877 ret = snd_soc_dapm_new_dai_widgets(dapm, dai);
2878 if (ret != 0) {
2879 dev_err(component->dev,
2880 "Failed to create DAI widgets %d\n", ret);
2881 }
2631 2882
2632 return ret; 2883 return ret;
2633} 2884}
2885EXPORT_SYMBOL_GPL(snd_soc_register_dai);
2634 2886
2635static void snd_soc_component_seq_notifier(struct snd_soc_dapm_context *dapm, 2887static void snd_soc_component_seq_notifier(struct snd_soc_dapm_context *dapm,
2636 enum snd_soc_dapm_type type, int subseq) 2888 enum snd_soc_dapm_type type, int subseq)
diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c
index 7d009428934a..5a2812fa8946 100644
--- a/sound/soc/soc-dapm.c
+++ b/sound/soc/soc-dapm.c
@@ -1300,7 +1300,7 @@ static int dapm_supply_check_power(struct snd_soc_dapm_widget *w)
1300 1300
1301static int dapm_always_on_check_power(struct snd_soc_dapm_widget *w) 1301static int dapm_always_on_check_power(struct snd_soc_dapm_widget *w)
1302{ 1302{
1303 return 1; 1303 return w->connected;
1304} 1304}
1305 1305
1306static int dapm_seq_compare(struct snd_soc_dapm_widget *a, 1306static int dapm_seq_compare(struct snd_soc_dapm_widget *a,
@@ -3358,6 +3358,11 @@ snd_soc_dapm_new_control_unlocked(struct snd_soc_dapm_context *dapm,
3358 w->is_ep = SND_SOC_DAPM_EP_SOURCE; 3358 w->is_ep = SND_SOC_DAPM_EP_SOURCE;
3359 w->power_check = dapm_always_on_check_power; 3359 w->power_check = dapm_always_on_check_power;
3360 break; 3360 break;
3361 case snd_soc_dapm_sink:
3362 w->is_ep = SND_SOC_DAPM_EP_SINK;
3363 w->power_check = dapm_always_on_check_power;
3364 break;
3365
3361 case snd_soc_dapm_mux: 3366 case snd_soc_dapm_mux:
3362 case snd_soc_dapm_demux: 3367 case snd_soc_dapm_demux:
3363 case snd_soc_dapm_switch: 3368 case snd_soc_dapm_switch:
@@ -3900,13 +3905,10 @@ static void soc_dapm_dai_stream_event(struct snd_soc_dai *dai, int stream,
3900 3905
3901void snd_soc_dapm_connect_dai_link_widgets(struct snd_soc_card *card) 3906void snd_soc_dapm_connect_dai_link_widgets(struct snd_soc_card *card)
3902{ 3907{
3903 struct snd_soc_pcm_runtime *rtd = card->rtd; 3908 struct snd_soc_pcm_runtime *rtd;
3904 int i;
3905 3909
3906 /* for each BE DAI link... */ 3910 /* for each BE DAI link... */
3907 for (i = 0; i < card->num_rtd; i++) { 3911 list_for_each_entry(rtd, &card->rtd_list, list) {
3908 rtd = &card->rtd[i];
3909
3910 /* 3912 /*
3911 * dynamic FE links have no fixed DAI mapping. 3913 * dynamic FE links have no fixed DAI mapping.
3912 * CODEC<->CODEC links have no direct connection. 3914 * CODEC<->CODEC links have no direct connection.
diff --git a/sound/soc/soc-ops.c b/sound/soc/soc-ops.c
index 2f67ba6d7a8f..a513a34a51d2 100644
--- a/sound/soc/soc-ops.c
+++ b/sound/soc/soc-ops.c
@@ -779,11 +779,11 @@ int snd_soc_bytes_tlv_callback(struct snd_kcontrol *kcontrol, int op_flag,
779 switch (op_flag) { 779 switch (op_flag) {
780 case SNDRV_CTL_TLV_OP_READ: 780 case SNDRV_CTL_TLV_OP_READ:
781 if (params->get) 781 if (params->get)
782 ret = params->get(tlv, count); 782 ret = params->get(kcontrol, tlv, count);
783 break; 783 break;
784 case SNDRV_CTL_TLV_OP_WRITE: 784 case SNDRV_CTL_TLV_OP_WRITE:
785 if (params->put) 785 if (params->put)
786 ret = params->put(tlv, count); 786 ret = params->put(kcontrol, tlv, count);
787 break; 787 break;
788 } 788 }
789 return ret; 789 return ret;
diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c
index c86dc96e8986..e898b427be7e 100644
--- a/sound/soc/soc-pcm.c
+++ b/sound/soc/soc-pcm.c
@@ -599,10 +599,15 @@ platform_err:
599out: 599out:
600 mutex_unlock(&rtd->pcm_mutex); 600 mutex_unlock(&rtd->pcm_mutex);
601 601
602 pm_runtime_put(platform->dev); 602 pm_runtime_mark_last_busy(platform->dev);
603 for (i = 0; i < rtd->num_codecs; i++) 603 pm_runtime_put_autosuspend(platform->dev);
604 pm_runtime_put(rtd->codec_dais[i]->dev); 604 for (i = 0; i < rtd->num_codecs; i++) {
605 pm_runtime_put(cpu_dai->dev); 605 pm_runtime_mark_last_busy(rtd->codec_dais[i]->dev);
606 pm_runtime_put_autosuspend(rtd->codec_dais[i]->dev);
607 }
608
609 pm_runtime_mark_last_busy(cpu_dai->dev);
610 pm_runtime_put_autosuspend(cpu_dai->dev);
606 for (i = 0; i < rtd->num_codecs; i++) { 611 for (i = 0; i < rtd->num_codecs; i++) {
607 if (!rtd->codec_dais[i]->active) 612 if (!rtd->codec_dais[i]->active)
608 pinctrl_pm_select_sleep_state(rtd->codec_dais[i]->dev); 613 pinctrl_pm_select_sleep_state(rtd->codec_dais[i]->dev);
@@ -706,10 +711,17 @@ static int soc_pcm_close(struct snd_pcm_substream *substream)
706 711
707 mutex_unlock(&rtd->pcm_mutex); 712 mutex_unlock(&rtd->pcm_mutex);
708 713
709 pm_runtime_put(platform->dev); 714 pm_runtime_mark_last_busy(platform->dev);
710 for (i = 0; i < rtd->num_codecs; i++) 715 pm_runtime_put_autosuspend(platform->dev);
711 pm_runtime_put(rtd->codec_dais[i]->dev); 716
712 pm_runtime_put(cpu_dai->dev); 717 for (i = 0; i < rtd->num_codecs; i++) {
718 pm_runtime_mark_last_busy(rtd->codec_dais[i]->dev);
719 pm_runtime_put_autosuspend(rtd->codec_dais[i]->dev);
720 }
721
722 pm_runtime_mark_last_busy(cpu_dai->dev);
723 pm_runtime_put_autosuspend(cpu_dai->dev);
724
713 for (i = 0; i < rtd->num_codecs; i++) { 725 for (i = 0; i < rtd->num_codecs; i++) {
714 if (!rtd->codec_dais[i]->active) 726 if (!rtd->codec_dais[i]->active)
715 pinctrl_pm_select_sleep_state(rtd->codec_dais[i]->dev); 727 pinctrl_pm_select_sleep_state(rtd->codec_dais[i]->dev);
@@ -1213,11 +1225,10 @@ static struct snd_soc_pcm_runtime *dpcm_get_be(struct snd_soc_card *card,
1213 struct snd_soc_dapm_widget *widget, int stream) 1225 struct snd_soc_dapm_widget *widget, int stream)
1214{ 1226{
1215 struct snd_soc_pcm_runtime *be; 1227 struct snd_soc_pcm_runtime *be;
1216 int i, j; 1228 int i;
1217 1229
1218 if (stream == SNDRV_PCM_STREAM_PLAYBACK) { 1230 if (stream == SNDRV_PCM_STREAM_PLAYBACK) {
1219 for (i = 0; i < card->num_links; i++) { 1231 list_for_each_entry(be, &card->rtd_list, list) {
1220 be = &card->rtd[i];
1221 1232
1222 if (!be->dai_link->no_pcm) 1233 if (!be->dai_link->no_pcm)
1223 continue; 1234 continue;
@@ -1225,16 +1236,15 @@ static struct snd_soc_pcm_runtime *dpcm_get_be(struct snd_soc_card *card,
1225 if (be->cpu_dai->playback_widget == widget) 1236 if (be->cpu_dai->playback_widget == widget)
1226 return be; 1237 return be;
1227 1238
1228 for (j = 0; j < be->num_codecs; j++) { 1239 for (i = 0; i < be->num_codecs; i++) {
1229 struct snd_soc_dai *dai = be->codec_dais[j]; 1240 struct snd_soc_dai *dai = be->codec_dais[i];
1230 if (dai->playback_widget == widget) 1241 if (dai->playback_widget == widget)
1231 return be; 1242 return be;
1232 } 1243 }
1233 } 1244 }
1234 } else { 1245 } else {
1235 1246
1236 for (i = 0; i < card->num_links; i++) { 1247 list_for_each_entry(be, &card->rtd_list, list) {
1237 be = &card->rtd[i];
1238 1248
1239 if (!be->dai_link->no_pcm) 1249 if (!be->dai_link->no_pcm)
1240 continue; 1250 continue;
@@ -1242,8 +1252,8 @@ static struct snd_soc_pcm_runtime *dpcm_get_be(struct snd_soc_card *card,
1242 if (be->cpu_dai->capture_widget == widget) 1252 if (be->cpu_dai->capture_widget == widget)
1243 return be; 1253 return be;
1244 1254
1245 for (j = 0; j < be->num_codecs; j++) { 1255 for (i = 0; i < be->num_codecs; i++) {
1246 struct snd_soc_dai *dai = be->codec_dais[j]; 1256 struct snd_soc_dai *dai = be->codec_dais[i];
1247 if (dai->capture_widget == widget) 1257 if (dai->capture_widget == widget)
1248 return be; 1258 return be;
1249 } 1259 }
@@ -1616,6 +1626,56 @@ static void dpcm_set_fe_update_state(struct snd_soc_pcm_runtime *fe,
1616 snd_pcm_stream_unlock_irq(substream); 1626 snd_pcm_stream_unlock_irq(substream);
1617} 1627}
1618 1628
1629static int dpcm_apply_symmetry(struct snd_pcm_substream *fe_substream,
1630 int stream)
1631{
1632 struct snd_soc_dpcm *dpcm;
1633 struct snd_soc_pcm_runtime *fe = fe_substream->private_data;
1634 struct snd_soc_dai *fe_cpu_dai = fe->cpu_dai;
1635 int err;
1636
1637 /* apply symmetry for FE */
1638 if (soc_pcm_has_symmetry(fe_substream))
1639 fe_substream->runtime->hw.info |= SNDRV_PCM_INFO_JOINT_DUPLEX;
1640
1641 /* Symmetry only applies if we've got an active stream. */
1642 if (fe_cpu_dai->active) {
1643 err = soc_pcm_apply_symmetry(fe_substream, fe_cpu_dai);
1644 if (err < 0)
1645 return err;
1646 }
1647
1648 /* apply symmetry for BE */
1649 list_for_each_entry(dpcm, &fe->dpcm[stream].be_clients, list_be) {
1650 struct snd_soc_pcm_runtime *be = dpcm->be;
1651 struct snd_pcm_substream *be_substream =
1652 snd_soc_dpcm_get_substream(be, stream);
1653 struct snd_soc_pcm_runtime *rtd = be_substream->private_data;
1654 int i;
1655
1656 if (soc_pcm_has_symmetry(be_substream))
1657 be_substream->runtime->hw.info |= SNDRV_PCM_INFO_JOINT_DUPLEX;
1658
1659 /* Symmetry only applies if we've got an active stream. */
1660 if (rtd->cpu_dai->active) {
1661 err = soc_pcm_apply_symmetry(be_substream, rtd->cpu_dai);
1662 if (err < 0)
1663 return err;
1664 }
1665
1666 for (i = 0; i < rtd->num_codecs; i++) {
1667 if (rtd->codec_dais[i]->active) {
1668 err = soc_pcm_apply_symmetry(be_substream,
1669 rtd->codec_dais[i]);
1670 if (err < 0)
1671 return err;
1672 }
1673 }
1674 }
1675
1676 return 0;
1677}
1678
1619static int dpcm_fe_dai_startup(struct snd_pcm_substream *fe_substream) 1679static int dpcm_fe_dai_startup(struct snd_pcm_substream *fe_substream)
1620{ 1680{
1621 struct snd_soc_pcm_runtime *fe = fe_substream->private_data; 1681 struct snd_soc_pcm_runtime *fe = fe_substream->private_data;
@@ -1644,6 +1704,13 @@ static int dpcm_fe_dai_startup(struct snd_pcm_substream *fe_substream)
1644 dpcm_set_fe_runtime(fe_substream); 1704 dpcm_set_fe_runtime(fe_substream);
1645 snd_pcm_limit_hw_rates(runtime); 1705 snd_pcm_limit_hw_rates(runtime);
1646 1706
1707 ret = dpcm_apply_symmetry(fe_substream, stream);
1708 if (ret < 0) {
1709 dev_err(fe->dev, "ASoC: failed to apply dpcm symmetry %d\n",
1710 ret);
1711 goto unwind;
1712 }
1713
1647 dpcm_set_fe_update_state(fe, stream, SND_SOC_DPCM_UPDATE_NO); 1714 dpcm_set_fe_update_state(fe, stream, SND_SOC_DPCM_UPDATE_NO);
1648 return 0; 1715 return 0;
1649 1716
@@ -2115,7 +2182,8 @@ int dpcm_be_dai_prepare(struct snd_soc_pcm_runtime *fe, int stream)
2115 continue; 2182 continue;
2116 2183
2117 if ((be->dpcm[stream].state != SND_SOC_DPCM_STATE_HW_PARAMS) && 2184 if ((be->dpcm[stream].state != SND_SOC_DPCM_STATE_HW_PARAMS) &&
2118 (be->dpcm[stream].state != SND_SOC_DPCM_STATE_STOP)) 2185 (be->dpcm[stream].state != SND_SOC_DPCM_STATE_STOP) &&
2186 (be->dpcm[stream].state != SND_SOC_DPCM_STATE_SUSPEND))
2119 continue; 2187 continue;
2120 2188
2121 dev_dbg(be->dev, "ASoC: prepare BE %s\n", 2189 dev_dbg(be->dev, "ASoC: prepare BE %s\n",
@@ -2343,12 +2411,12 @@ static int dpcm_run_old_update(struct snd_soc_pcm_runtime *fe, int stream)
2343 */ 2411 */
2344int soc_dpcm_runtime_update(struct snd_soc_card *card) 2412int soc_dpcm_runtime_update(struct snd_soc_card *card)
2345{ 2413{
2346 int i, old, new, paths; 2414 struct snd_soc_pcm_runtime *fe;
2415 int old, new, paths;
2347 2416
2348 mutex_lock_nested(&card->mutex, SND_SOC_CARD_CLASS_RUNTIME); 2417 mutex_lock_nested(&card->mutex, SND_SOC_CARD_CLASS_RUNTIME);
2349 for (i = 0; i < card->num_rtd; i++) { 2418 list_for_each_entry(fe, &card->rtd_list, list) {
2350 struct snd_soc_dapm_widget_list *list; 2419 struct snd_soc_dapm_widget_list *list;
2351 struct snd_soc_pcm_runtime *fe = &card->rtd[i];
2352 2420
2353 /* make sure link is FE */ 2421 /* make sure link is FE */
2354 if (!fe->dai_link->dynamic) 2422 if (!fe->dai_link->dynamic)
diff --git a/sound/soc/sti/uniperif_player.c b/sound/soc/sti/uniperif_player.c
index 5c2bc53f0a9b..7aca6b92f718 100644
--- a/sound/soc/sti/uniperif_player.c
+++ b/sound/soc/sti/uniperif_player.c
@@ -251,8 +251,7 @@ static void uni_player_set_channel_status(struct uniperif *player,
251 * set one. 251 * set one.
252 */ 252 */
253 mutex_lock(&player->ctrl_lock); 253 mutex_lock(&player->ctrl_lock);
254 if (runtime && (player->stream_settings.iec958.status[3] 254 if (runtime) {
255 == IEC958_AES3_CON_FS_NOTID)) {
256 switch (runtime->rate) { 255 switch (runtime->rate) {
257 case 22050: 256 case 22050:
258 player->stream_settings.iec958.status[3] = 257 player->stream_settings.iec958.status[3] =
diff --git a/sound/soc/sunxi/sun4i-codec.c b/sound/soc/sunxi/sun4i-codec.c
index 1bb896d78d09..44f170c73b06 100644
--- a/sound/soc/sunxi/sun4i-codec.c
+++ b/sound/soc/sunxi/sun4i-codec.c
@@ -28,6 +28,7 @@
28#include <linux/of_address.h> 28#include <linux/of_address.h>
29#include <linux/clk.h> 29#include <linux/clk.h>
30#include <linux/regmap.h> 30#include <linux/regmap.h>
31#include <linux/gpio/consumer.h>
31 32
32#include <sound/core.h> 33#include <sound/core.h>
33#include <sound/pcm.h> 34#include <sound/pcm.h>
@@ -70,6 +71,7 @@
70 71
71/* Codec ADC register offsets and bit fields */ 72/* Codec ADC register offsets and bit fields */
72#define SUN4I_CODEC_ADC_FIFOC (0x1c) 73#define SUN4I_CODEC_ADC_FIFOC (0x1c)
74#define SUN4I_CODEC_ADC_FIFOC_ADC_FS (29)
73#define SUN4I_CODEC_ADC_FIFOC_EN_AD (28) 75#define SUN4I_CODEC_ADC_FIFOC_EN_AD (28)
74#define SUN4I_CODEC_ADC_FIFOC_RX_FIFO_MODE (24) 76#define SUN4I_CODEC_ADC_FIFOC_RX_FIFO_MODE (24)
75#define SUN4I_CODEC_ADC_FIFOC_RX_TRIG_LEVEL (8) 77#define SUN4I_CODEC_ADC_FIFOC_RX_TRIG_LEVEL (8)
@@ -102,17 +104,14 @@ struct sun4i_codec {
102 struct regmap *regmap; 104 struct regmap *regmap;
103 struct clk *clk_apb; 105 struct clk *clk_apb;
104 struct clk *clk_module; 106 struct clk *clk_module;
107 struct gpio_desc *gpio_pa;
105 108
109 struct snd_dmaengine_dai_dma_data capture_dma_data;
106 struct snd_dmaengine_dai_dma_data playback_dma_data; 110 struct snd_dmaengine_dai_dma_data playback_dma_data;
107}; 111};
108 112
109static void sun4i_codec_start_playback(struct sun4i_codec *scodec) 113static void sun4i_codec_start_playback(struct sun4i_codec *scodec)
110{ 114{
111 /*
112 * FIXME: according to the BSP, we might need to drive a PA
113 * GPIO high here on some boards
114 */
115
116 /* Flush TX FIFO */ 115 /* Flush TX FIFO */
117 regmap_update_bits(scodec->regmap, SUN4I_CODEC_DAC_FIFOC, 116 regmap_update_bits(scodec->regmap, SUN4I_CODEC_DAC_FIFOC,
118 BIT(SUN4I_CODEC_DAC_FIFOC_FIFO_FLUSH), 117 BIT(SUN4I_CODEC_DAC_FIFOC_FIFO_FLUSH),
@@ -126,37 +125,50 @@ static void sun4i_codec_start_playback(struct sun4i_codec *scodec)
126 125
127static void sun4i_codec_stop_playback(struct sun4i_codec *scodec) 126static void sun4i_codec_stop_playback(struct sun4i_codec *scodec)
128{ 127{
129 /*
130 * FIXME: according to the BSP, we might need to drive a PA
131 * GPIO low here on some boards
132 */
133
134 /* Disable DAC DRQ */ 128 /* Disable DAC DRQ */
135 regmap_update_bits(scodec->regmap, SUN4I_CODEC_DAC_FIFOC, 129 regmap_update_bits(scodec->regmap, SUN4I_CODEC_DAC_FIFOC,
136 BIT(SUN4I_CODEC_DAC_FIFOC_DAC_DRQ_EN), 130 BIT(SUN4I_CODEC_DAC_FIFOC_DAC_DRQ_EN),
137 0); 131 0);
138} 132}
139 133
134static void sun4i_codec_start_capture(struct sun4i_codec *scodec)
135{
136 /* Enable ADC DRQ */
137 regmap_update_bits(scodec->regmap, SUN4I_CODEC_ADC_FIFOC,
138 BIT(SUN4I_CODEC_ADC_FIFOC_ADC_DRQ_EN),
139 BIT(SUN4I_CODEC_ADC_FIFOC_ADC_DRQ_EN));
140}
141
142static void sun4i_codec_stop_capture(struct sun4i_codec *scodec)
143{
144 /* Disable ADC DRQ */
145 regmap_update_bits(scodec->regmap, SUN4I_CODEC_ADC_FIFOC,
146 BIT(SUN4I_CODEC_ADC_FIFOC_ADC_DRQ_EN), 0);
147}
148
140static int sun4i_codec_trigger(struct snd_pcm_substream *substream, int cmd, 149static int sun4i_codec_trigger(struct snd_pcm_substream *substream, int cmd,
141 struct snd_soc_dai *dai) 150 struct snd_soc_dai *dai)
142{ 151{
143 struct snd_soc_pcm_runtime *rtd = substream->private_data; 152 struct snd_soc_pcm_runtime *rtd = substream->private_data;
144 struct sun4i_codec *scodec = snd_soc_card_get_drvdata(rtd->card); 153 struct sun4i_codec *scodec = snd_soc_card_get_drvdata(rtd->card);
145 154
146 if (substream->stream != SNDRV_PCM_STREAM_PLAYBACK)
147 return -ENOTSUPP;
148
149 switch (cmd) { 155 switch (cmd) {
150 case SNDRV_PCM_TRIGGER_START: 156 case SNDRV_PCM_TRIGGER_START:
151 case SNDRV_PCM_TRIGGER_RESUME: 157 case SNDRV_PCM_TRIGGER_RESUME:
152 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: 158 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
153 sun4i_codec_start_playback(scodec); 159 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
160 sun4i_codec_start_playback(scodec);
161 else
162 sun4i_codec_start_capture(scodec);
154 break; 163 break;
155 164
156 case SNDRV_PCM_TRIGGER_STOP: 165 case SNDRV_PCM_TRIGGER_STOP:
157 case SNDRV_PCM_TRIGGER_SUSPEND: 166 case SNDRV_PCM_TRIGGER_SUSPEND:
158 case SNDRV_PCM_TRIGGER_PAUSE_PUSH: 167 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
159 sun4i_codec_stop_playback(scodec); 168 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
169 sun4i_codec_stop_playback(scodec);
170 else
171 sun4i_codec_stop_capture(scodec);
160 break; 172 break;
161 173
162 default: 174 default:
@@ -166,15 +178,54 @@ static int sun4i_codec_trigger(struct snd_pcm_substream *substream, int cmd,
166 return 0; 178 return 0;
167} 179}
168 180
169static int sun4i_codec_prepare(struct snd_pcm_substream *substream, 181static int sun4i_codec_prepare_capture(struct snd_pcm_substream *substream,
170 struct snd_soc_dai *dai) 182 struct snd_soc_dai *dai)
171{ 183{
172 struct snd_soc_pcm_runtime *rtd = substream->private_data; 184 struct snd_soc_pcm_runtime *rtd = substream->private_data;
173 struct sun4i_codec *scodec = snd_soc_card_get_drvdata(rtd->card); 185 struct sun4i_codec *scodec = snd_soc_card_get_drvdata(rtd->card);
174 u32 val;
175 186
176 if (substream->stream != SNDRV_PCM_STREAM_PLAYBACK) 187
177 return -ENOTSUPP; 188 /* Flush RX FIFO */
189 regmap_update_bits(scodec->regmap, SUN4I_CODEC_ADC_FIFOC,
190 BIT(SUN4I_CODEC_ADC_FIFOC_FIFO_FLUSH),
191 BIT(SUN4I_CODEC_ADC_FIFOC_FIFO_FLUSH));
192
193
194 /* Set RX FIFO trigger level */
195 regmap_update_bits(scodec->regmap, SUN4I_CODEC_ADC_FIFOC,
196 0xf << SUN4I_CODEC_ADC_FIFOC_RX_TRIG_LEVEL,
197 0x7 << SUN4I_CODEC_ADC_FIFOC_RX_TRIG_LEVEL);
198
199 /*
200 * FIXME: Undocumented in the datasheet, but
201 * Allwinner's code mentions that it is related
202 * related to microphone gain
203 */
204 regmap_update_bits(scodec->regmap, SUN4I_CODEC_ADC_ACTL,
205 0x3 << 25,
206 0x1 << 25);
207
208 if (of_device_is_compatible(scodec->dev->of_node,
209 "allwinner,sun7i-a20-codec"))
210 /* FIXME: Undocumented bits */
211 regmap_update_bits(scodec->regmap, SUN4I_CODEC_DAC_TUNE,
212 0x3 << 8,
213 0x1 << 8);
214
215 /* Fill most significant bits with valid data MSB */
216 regmap_update_bits(scodec->regmap, SUN4I_CODEC_ADC_FIFOC,
217 BIT(SUN4I_CODEC_ADC_FIFOC_RX_FIFO_MODE),
218 BIT(SUN4I_CODEC_ADC_FIFOC_RX_FIFO_MODE));
219
220 return 0;
221}
222
223static int sun4i_codec_prepare_playback(struct snd_pcm_substream *substream,
224 struct snd_soc_dai *dai)
225{
226 struct snd_soc_pcm_runtime *rtd = substream->private_data;
227 struct sun4i_codec *scodec = snd_soc_card_get_drvdata(rtd->card);
228 u32 val;
178 229
179 /* Flush the TX FIFO */ 230 /* Flush the TX FIFO */
180 regmap_update_bits(scodec->regmap, SUN4I_CODEC_DAC_FIFOC, 231 regmap_update_bits(scodec->regmap, SUN4I_CODEC_DAC_FIFOC,
@@ -203,6 +254,15 @@ static int sun4i_codec_prepare(struct snd_pcm_substream *substream,
203 0); 254 0);
204 255
205 return 0; 256 return 0;
257};
258
259static int sun4i_codec_prepare(struct snd_pcm_substream *substream,
260 struct snd_soc_dai *dai)
261{
262 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
263 return sun4i_codec_prepare_playback(substream, dai);
264
265 return sun4i_codec_prepare_capture(substream, dai);
206} 266}
207 267
208static unsigned long sun4i_codec_get_mod_freq(struct snd_pcm_hw_params *params) 268static unsigned long sun4i_codec_get_mod_freq(struct snd_pcm_hw_params *params)
@@ -277,30 +337,32 @@ static int sun4i_codec_get_hw_rate(struct snd_pcm_hw_params *params)
277 } 337 }
278} 338}
279 339
280static int sun4i_codec_hw_params(struct snd_pcm_substream *substream, 340static int sun4i_codec_hw_params_capture(struct sun4i_codec *scodec,
281 struct snd_pcm_hw_params *params, 341 struct snd_pcm_hw_params *params,
282 struct snd_soc_dai *dai) 342 unsigned int hwrate)
283{ 343{
284 struct snd_soc_pcm_runtime *rtd = substream->private_data; 344 /* Set ADC sample rate */
285 struct sun4i_codec *scodec = snd_soc_card_get_drvdata(rtd->card); 345 regmap_update_bits(scodec->regmap, SUN4I_CODEC_ADC_FIFOC,
286 unsigned long clk_freq; 346 7 << SUN4I_CODEC_ADC_FIFOC_ADC_FS,
287 int ret, hwrate; 347 hwrate << SUN4I_CODEC_ADC_FIFOC_ADC_FS);
288 u32 val;
289
290 if (substream->stream != SNDRV_PCM_STREAM_PLAYBACK)
291 return -ENOTSUPP;
292 348
293 clk_freq = sun4i_codec_get_mod_freq(params); 349 /* Set the number of channels we want to use */
294 if (!clk_freq) 350 if (params_channels(params) == 1)
295 return -EINVAL; 351 regmap_update_bits(scodec->regmap, SUN4I_CODEC_ADC_FIFOC,
352 BIT(SUN4I_CODEC_ADC_FIFOC_MONO_EN),
353 BIT(SUN4I_CODEC_ADC_FIFOC_MONO_EN));
354 else
355 regmap_update_bits(scodec->regmap, SUN4I_CODEC_ADC_FIFOC,
356 BIT(SUN4I_CODEC_ADC_FIFOC_MONO_EN), 0);
296 357
297 ret = clk_set_rate(scodec->clk_module, clk_freq); 358 return 0;
298 if (ret) 359}
299 return ret;
300 360
301 hwrate = sun4i_codec_get_hw_rate(params); 361static int sun4i_codec_hw_params_playback(struct sun4i_codec *scodec,
302 if (hwrate < 0) 362 struct snd_pcm_hw_params *params,
303 return hwrate; 363 unsigned int hwrate)
364{
365 u32 val;
304 366
305 /* Set DAC sample rate */ 367 /* Set DAC sample rate */
306 regmap_update_bits(scodec->regmap, SUN4I_CODEC_DAC_FIFOC, 368 regmap_update_bits(scodec->regmap, SUN4I_CODEC_DAC_FIFOC,
@@ -345,6 +407,35 @@ static int sun4i_codec_hw_params(struct snd_pcm_substream *substream,
345 return 0; 407 return 0;
346} 408}
347 409
410static int sun4i_codec_hw_params(struct snd_pcm_substream *substream,
411 struct snd_pcm_hw_params *params,
412 struct snd_soc_dai *dai)
413{
414 struct snd_soc_pcm_runtime *rtd = substream->private_data;
415 struct sun4i_codec *scodec = snd_soc_card_get_drvdata(rtd->card);
416 unsigned long clk_freq;
417 int ret, hwrate;
418
419 clk_freq = sun4i_codec_get_mod_freq(params);
420 if (!clk_freq)
421 return -EINVAL;
422
423 ret = clk_set_rate(scodec->clk_module, clk_freq);
424 if (ret)
425 return ret;
426
427 hwrate = sun4i_codec_get_hw_rate(params);
428 if (hwrate < 0)
429 return hwrate;
430
431 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
432 return sun4i_codec_hw_params_playback(scodec, params,
433 hwrate);
434
435 return sun4i_codec_hw_params_capture(scodec, params,
436 hwrate);
437}
438
348static int sun4i_codec_startup(struct snd_pcm_substream *substream, 439static int sun4i_codec_startup(struct snd_pcm_substream *substream,
349 struct snd_soc_dai *dai) 440 struct snd_soc_dai *dai)
350{ 441{
@@ -395,6 +486,20 @@ static struct snd_soc_dai_driver sun4i_codec_dai = {
395 SNDRV_PCM_FMTBIT_S32_LE, 486 SNDRV_PCM_FMTBIT_S32_LE,
396 .sig_bits = 24, 487 .sig_bits = 24,
397 }, 488 },
489 .capture = {
490 .stream_name = "Codec Capture",
491 .channels_min = 1,
492 .channels_max = 2,
493 .rate_min = 8000,
494 .rate_max = 192000,
495 .rates = SNDRV_PCM_RATE_8000_48000 |
496 SNDRV_PCM_RATE_96000 |
497 SNDRV_PCM_RATE_192000 |
498 SNDRV_PCM_RATE_KNOT,
499 .formats = SNDRV_PCM_FMTBIT_S16_LE |
500 SNDRV_PCM_FMTBIT_S32_LE,
501 .sig_bits = 24,
502 },
398}; 503};
399 504
400/*** Codec ***/ 505/*** Codec ***/
@@ -429,12 +534,23 @@ static const struct snd_kcontrol_new sun4i_codec_pa_mixer_controls[] = {
429 SUN4I_CODEC_DAC_ACTL_MIXPAS, 1, 0), 534 SUN4I_CODEC_DAC_ACTL_MIXPAS, 1, 0),
430}; 535};
431 536
432static const struct snd_soc_dapm_widget sun4i_codec_dapm_widgets[] = { 537static const struct snd_soc_dapm_widget sun4i_codec_codec_dapm_widgets[] = {
538 /* Digital parts of the ADCs */
539 SND_SOC_DAPM_SUPPLY("ADC", SUN4I_CODEC_ADC_FIFOC,
540 SUN4I_CODEC_ADC_FIFOC_EN_AD, 0,
541 NULL, 0),
542
433 /* Digital parts of the DACs */ 543 /* Digital parts of the DACs */
434 SND_SOC_DAPM_SUPPLY("DAC", SUN4I_CODEC_DAC_DPC, 544 SND_SOC_DAPM_SUPPLY("DAC", SUN4I_CODEC_DAC_DPC,
435 SUN4I_CODEC_DAC_DPC_EN_DA, 0, 545 SUN4I_CODEC_DAC_DPC_EN_DA, 0,
436 NULL, 0), 546 NULL, 0),
437 547
548 /* Analog parts of the ADCs */
549 SND_SOC_DAPM_ADC("Left ADC", "Codec Capture", SUN4I_CODEC_ADC_ACTL,
550 SUN4I_CODEC_ADC_ACTL_ADC_L_EN, 0),
551 SND_SOC_DAPM_ADC("Right ADC", "Codec Capture", SUN4I_CODEC_ADC_ACTL,
552 SUN4I_CODEC_ADC_ACTL_ADC_R_EN, 0),
553
438 /* Analog parts of the DACs */ 554 /* Analog parts of the DACs */
439 SND_SOC_DAPM_DAC("Left DAC", "Codec Playback", SUN4I_CODEC_DAC_ACTL, 555 SND_SOC_DAPM_DAC("Left DAC", "Codec Playback", SUN4I_CODEC_DAC_ACTL,
440 SUN4I_CODEC_DAC_ACTL_DACAENL, 0), 556 SUN4I_CODEC_DAC_ACTL_DACAENL, 0),
@@ -453,6 +569,14 @@ static const struct snd_soc_dapm_widget sun4i_codec_dapm_widgets[] = {
453 SND_SOC_DAPM_SUPPLY("Mixer Enable", SUN4I_CODEC_DAC_ACTL, 569 SND_SOC_DAPM_SUPPLY("Mixer Enable", SUN4I_CODEC_DAC_ACTL,
454 SUN4I_CODEC_DAC_ACTL_MIXEN, 0, NULL, 0), 570 SUN4I_CODEC_DAC_ACTL_MIXEN, 0, NULL, 0),
455 571
572 /* VMIC */
573 SND_SOC_DAPM_SUPPLY("VMIC", SUN4I_CODEC_ADC_ACTL,
574 SUN4I_CODEC_ADC_ACTL_VMICEN, 0, NULL, 0),
575
576 /* Mic Pre-Amplifiers */
577 SND_SOC_DAPM_PGA("MIC1 Pre-Amplifier", SUN4I_CODEC_ADC_ACTL,
578 SUN4I_CODEC_ADC_ACTL_PREG1EN, 0, NULL, 0),
579
456 /* Power Amplifier */ 580 /* Power Amplifier */
457 SND_SOC_DAPM_MIXER("Power Amplifier", SUN4I_CODEC_ADC_ACTL, 581 SND_SOC_DAPM_MIXER("Power Amplifier", SUN4I_CODEC_ADC_ACTL,
458 SUN4I_CODEC_ADC_ACTL_PA_EN, 0, 582 SUN4I_CODEC_ADC_ACTL_PA_EN, 0,
@@ -461,15 +585,19 @@ static const struct snd_soc_dapm_widget sun4i_codec_dapm_widgets[] = {
461 SND_SOC_DAPM_SWITCH("Power Amplifier Mute", SND_SOC_NOPM, 0, 0, 585 SND_SOC_DAPM_SWITCH("Power Amplifier Mute", SND_SOC_NOPM, 0, 0,
462 &sun4i_codec_pa_mute), 586 &sun4i_codec_pa_mute),
463 587
588 SND_SOC_DAPM_INPUT("Mic1"),
589
464 SND_SOC_DAPM_OUTPUT("HP Right"), 590 SND_SOC_DAPM_OUTPUT("HP Right"),
465 SND_SOC_DAPM_OUTPUT("HP Left"), 591 SND_SOC_DAPM_OUTPUT("HP Left"),
466}; 592};
467 593
468static const struct snd_soc_dapm_route sun4i_codec_dapm_routes[] = { 594static const struct snd_soc_dapm_route sun4i_codec_codec_dapm_routes[] = {
469 /* Left DAC Routes */ 595 /* Left ADC / DAC Routes */
596 { "Left ADC", NULL, "ADC" },
470 { "Left DAC", NULL, "DAC" }, 597 { "Left DAC", NULL, "DAC" },
471 598
472 /* Right DAC Routes */ 599 /* Right ADC / DAC Routes */
600 { "Right ADC", NULL, "ADC" },
473 { "Right DAC", NULL, "DAC" }, 601 { "Right DAC", NULL, "DAC" },
474 602
475 /* Right Mixer Routes */ 603 /* Right Mixer Routes */
@@ -491,15 +619,21 @@ static const struct snd_soc_dapm_route sun4i_codec_dapm_routes[] = {
491 { "Power Amplifier Mute", "Switch", "Power Amplifier" }, 619 { "Power Amplifier Mute", "Switch", "Power Amplifier" },
492 { "HP Right", NULL, "Power Amplifier Mute" }, 620 { "HP Right", NULL, "Power Amplifier Mute" },
493 { "HP Left", NULL, "Power Amplifier Mute" }, 621 { "HP Left", NULL, "Power Amplifier Mute" },
622
623 /* Mic1 Routes */
624 { "Left ADC", NULL, "MIC1 Pre-Amplifier" },
625 { "Right ADC", NULL, "MIC1 Pre-Amplifier" },
626 { "MIC1 Pre-Amplifier", NULL, "Mic1"},
627 { "Mic1", NULL, "VMIC" },
494}; 628};
495 629
496static struct snd_soc_codec_driver sun4i_codec_codec = { 630static struct snd_soc_codec_driver sun4i_codec_codec = {
497 .controls = sun4i_codec_widgets, 631 .controls = sun4i_codec_widgets,
498 .num_controls = ARRAY_SIZE(sun4i_codec_widgets), 632 .num_controls = ARRAY_SIZE(sun4i_codec_widgets),
499 .dapm_widgets = sun4i_codec_dapm_widgets, 633 .dapm_widgets = sun4i_codec_codec_dapm_widgets,
500 .num_dapm_widgets = ARRAY_SIZE(sun4i_codec_dapm_widgets), 634 .num_dapm_widgets = ARRAY_SIZE(sun4i_codec_codec_dapm_widgets),
501 .dapm_routes = sun4i_codec_dapm_routes, 635 .dapm_routes = sun4i_codec_codec_dapm_routes,
502 .num_dapm_routes = ARRAY_SIZE(sun4i_codec_dapm_routes), 636 .num_dapm_routes = ARRAY_SIZE(sun4i_codec_codec_dapm_routes),
503}; 637};
504 638
505static const struct snd_soc_component_driver sun4i_codec_component = { 639static const struct snd_soc_component_driver sun4i_codec_component = {
@@ -516,7 +650,7 @@ static int sun4i_codec_dai_probe(struct snd_soc_dai *dai)
516 struct sun4i_codec *scodec = snd_soc_card_get_drvdata(card); 650 struct sun4i_codec *scodec = snd_soc_card_get_drvdata(card);
517 651
518 snd_soc_dai_init_dma_data(dai, &scodec->playback_dma_data, 652 snd_soc_dai_init_dma_data(dai, &scodec->playback_dma_data,
519 NULL); 653 &scodec->capture_dma_data);
520 654
521 return 0; 655 return 0;
522} 656}
@@ -532,6 +666,14 @@ static struct snd_soc_dai_driver dummy_cpu_dai = {
532 .formats = SUN4I_CODEC_FORMATS, 666 .formats = SUN4I_CODEC_FORMATS,
533 .sig_bits = 24, 667 .sig_bits = 24,
534 }, 668 },
669 .capture = {
670 .stream_name = "Capture",
671 .channels_min = 1,
672 .channels_max = 2,
673 .rates = SUN4I_CODEC_RATES,
674 .formats = SUN4I_CODEC_FORMATS,
675 .sig_bits = 24,
676 },
535}; 677};
536 678
537static const struct regmap_config sun4i_codec_regmap_config = { 679static const struct regmap_config sun4i_codec_regmap_config = {
@@ -569,6 +711,27 @@ static struct snd_soc_dai_link *sun4i_codec_create_link(struct device *dev,
569 return link; 711 return link;
570}; 712};
571 713
714static int sun4i_codec_spk_event(struct snd_soc_dapm_widget *w,
715 struct snd_kcontrol *k, int event)
716{
717 struct sun4i_codec *scodec = snd_soc_card_get_drvdata(w->dapm->card);
718
719 if (scodec->gpio_pa)
720 gpiod_set_value_cansleep(scodec->gpio_pa,
721 !!SND_SOC_DAPM_EVENT_ON(event));
722
723 return 0;
724}
725
726static const struct snd_soc_dapm_widget sun4i_codec_card_dapm_widgets[] = {
727 SND_SOC_DAPM_SPK("Speaker", sun4i_codec_spk_event),
728};
729
730static const struct snd_soc_dapm_route sun4i_codec_card_dapm_routes[] = {
731 { "Speaker", NULL, "HP Right" },
732 { "Speaker", NULL, "HP Left" },
733};
734
572static struct snd_soc_card *sun4i_codec_create_card(struct device *dev) 735static struct snd_soc_card *sun4i_codec_create_card(struct device *dev)
573{ 736{
574 struct snd_soc_card *card; 737 struct snd_soc_card *card;
@@ -583,6 +746,10 @@ static struct snd_soc_card *sun4i_codec_create_card(struct device *dev)
583 746
584 card->dev = dev; 747 card->dev = dev;
585 card->name = "sun4i-codec"; 748 card->name = "sun4i-codec";
749 card->dapm_widgets = sun4i_codec_card_dapm_widgets;
750 card->num_dapm_widgets = ARRAY_SIZE(sun4i_codec_card_dapm_widgets);
751 card->dapm_routes = sun4i_codec_card_dapm_routes;
752 card->num_dapm_routes = ARRAY_SIZE(sun4i_codec_card_dapm_routes);
586 753
587 return card; 754 return card;
588}; 755};
@@ -634,11 +801,25 @@ static int sun4i_codec_probe(struct platform_device *pdev)
634 return -EINVAL; 801 return -EINVAL;
635 } 802 }
636 803
804 scodec->gpio_pa = devm_gpiod_get_optional(&pdev->dev, "allwinner,pa",
805 GPIOD_OUT_LOW);
806 if (IS_ERR(scodec->gpio_pa)) {
807 ret = PTR_ERR(scodec->gpio_pa);
808 if (ret != -EPROBE_DEFER)
809 dev_err(&pdev->dev, "Failed to get pa gpio: %d\n", ret);
810 return ret;
811 }
812
637 /* DMA configuration for TX FIFO */ 813 /* DMA configuration for TX FIFO */
638 scodec->playback_dma_data.addr = res->start + SUN4I_CODEC_DAC_TXDATA; 814 scodec->playback_dma_data.addr = res->start + SUN4I_CODEC_DAC_TXDATA;
639 scodec->playback_dma_data.maxburst = 4; 815 scodec->playback_dma_data.maxburst = 4;
640 scodec->playback_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES; 816 scodec->playback_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES;
641 817
818 /* DMA configuration for RX FIFO */
819 scodec->capture_dma_data.addr = res->start + SUN4I_CODEC_ADC_RXDATA;
820 scodec->capture_dma_data.maxburst = 4;
821 scodec->capture_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES;
822
642 ret = snd_soc_register_codec(&pdev->dev, &sun4i_codec_codec, 823 ret = snd_soc_register_codec(&pdev->dev, &sun4i_codec_codec,
643 &sun4i_codec_dai, 1); 824 &sun4i_codec_dai, 1);
644 if (ret) { 825 if (ret) {
diff --git a/sound/soc/tegra/tegra_alc5632.c b/sound/soc/tegra/tegra_alc5632.c
index ba272e21a6fa..deb597f7c302 100644
--- a/sound/soc/tegra/tegra_alc5632.c
+++ b/sound/soc/tegra/tegra_alc5632.c
@@ -101,12 +101,16 @@ static const struct snd_kcontrol_new tegra_alc5632_controls[] = {
101 101
102static int tegra_alc5632_asoc_init(struct snd_soc_pcm_runtime *rtd) 102static int tegra_alc5632_asoc_init(struct snd_soc_pcm_runtime *rtd)
103{ 103{
104 int ret;
104 struct tegra_alc5632 *machine = snd_soc_card_get_drvdata(rtd->card); 105 struct tegra_alc5632 *machine = snd_soc_card_get_drvdata(rtd->card);
105 106
106 snd_soc_card_jack_new(rtd->card, "Headset Jack", SND_JACK_HEADSET, 107 ret = snd_soc_card_jack_new(rtd->card, "Headset Jack",
107 &tegra_alc5632_hs_jack, 108 SND_JACK_HEADSET,
108 tegra_alc5632_hs_jack_pins, 109 &tegra_alc5632_hs_jack,
109 ARRAY_SIZE(tegra_alc5632_hs_jack_pins)); 110 tegra_alc5632_hs_jack_pins,
111 ARRAY_SIZE(tegra_alc5632_hs_jack_pins));
112 if (ret)
113 return ret;
110 114
111 if (gpio_is_valid(machine->gpio_hp_det)) { 115 if (gpio_is_valid(machine->gpio_hp_det)) {
112 tegra_alc5632_hp_jack_gpio.gpio = machine->gpio_hp_det; 116 tegra_alc5632_hp_jack_gpio.gpio = machine->gpio_hp_det;
diff --git a/sound/soc/tegra/tegra_wm8903.c b/sound/soc/tegra/tegra_wm8903.c
index 21604009bc1a..e485278e027a 100644
--- a/sound/soc/tegra/tegra_wm8903.c
+++ b/sound/soc/tegra/tegra_wm8903.c
@@ -199,7 +199,8 @@ static int tegra_wm8903_init(struct snd_soc_pcm_runtime *rtd)
199 199
200static int tegra_wm8903_remove(struct snd_soc_card *card) 200static int tegra_wm8903_remove(struct snd_soc_card *card)
201{ 201{
202 struct snd_soc_pcm_runtime *rtd = &(card->rtd[0]); 202 struct snd_soc_pcm_runtime *rtd =
203 snd_soc_get_pcm_runtime(card, card->dai_link[0].name);
203 struct snd_soc_dai *codec_dai = rtd->codec_dai; 204 struct snd_soc_dai *codec_dai = rtd->codec_dai;
204 struct snd_soc_codec *codec = codec_dai->codec; 205 struct snd_soc_codec *codec = codec_dai->codec;
205 struct tegra_wm8903 *machine = snd_soc_card_get_drvdata(card); 206 struct tegra_wm8903 *machine = snd_soc_card_get_drvdata(card);
diff --git a/sound/synth/emux/emux_nrpn.c b/sound/synth/emux/emux_nrpn.c
index 00fc005ecf6e..9729a15b6ae6 100644
--- a/sound/synth/emux/emux_nrpn.c
+++ b/sound/synth/emux/emux_nrpn.c
@@ -48,7 +48,8 @@ struct nrpn_conv_table {
48 * convert NRPN/control values 48 * convert NRPN/control values
49 */ 49 */
50 50
51static int send_converted_effect(struct nrpn_conv_table *table, int num_tables, 51static int send_converted_effect(const struct nrpn_conv_table *table,
52 int num_tables,
52 struct snd_emux_port *port, 53 struct snd_emux_port *port,
53 struct snd_midi_channel *chan, 54 struct snd_midi_channel *chan,
54 int type, int val, int mode) 55 int type, int val, int mode)
@@ -179,7 +180,7 @@ static int fx_conv_Q(int val)
179} 180}
180 181
181 182
182static struct nrpn_conv_table awe_effects[] = 183static const struct nrpn_conv_table awe_effects[] =
183{ 184{
184 { 0, EMUX_FX_LFO1_DELAY, fx_lfo1_delay}, 185 { 0, EMUX_FX_LFO1_DELAY, fx_lfo1_delay},
185 { 1, EMUX_FX_LFO1_FREQ, fx_lfo1_freq}, 186 { 1, EMUX_FX_LFO1_FREQ, fx_lfo1_freq},
@@ -266,7 +267,7 @@ static int gs_vib_delay(int val)
266 return -(val - 64) * gs_sense[FX_VIBDELAY] / 50; 267 return -(val - 64) * gs_sense[FX_VIBDELAY] / 50;
267} 268}
268 269
269static struct nrpn_conv_table gs_effects[] = 270static const struct nrpn_conv_table gs_effects[] =
270{ 271{
271 {32, EMUX_FX_CUTOFF, gs_cutoff}, 272 {32, EMUX_FX_CUTOFF, gs_cutoff},
272 {33, EMUX_FX_FILTERQ, gs_filterQ}, 273 {33, EMUX_FX_FILTERQ, gs_filterQ},
@@ -350,7 +351,7 @@ static int xg_release(int val)
350 return -(val - 64) * xg_sense[FX_RELEASE] / 64; 351 return -(val - 64) * xg_sense[FX_RELEASE] / 64;
351} 352}
352 353
353static struct nrpn_conv_table xg_effects[] = 354static const struct nrpn_conv_table xg_effects[] =
354{ 355{
355 {71, EMUX_FX_CUTOFF, xg_cutoff}, 356 {71, EMUX_FX_CUTOFF, xg_cutoff},
356 {74, EMUX_FX_FILTERQ, xg_filterQ}, 357 {74, EMUX_FX_FILTERQ, xg_filterQ},
diff --git a/sound/usb/card.c b/sound/usb/card.c
index 18f56646ce86..1f09d9591276 100644
--- a/sound/usb/card.c
+++ b/sound/usb/card.c
@@ -675,6 +675,8 @@ int snd_usb_autoresume(struct snd_usb_audio *chip)
675 675
676void snd_usb_autosuspend(struct snd_usb_audio *chip) 676void snd_usb_autosuspend(struct snd_usb_audio *chip)
677{ 677{
678 if (atomic_read(&chip->shutdown))
679 return;
678 if (atomic_dec_and_test(&chip->active)) 680 if (atomic_dec_and_test(&chip->active))
679 usb_autopm_put_interface(chip->pm_intf); 681 usb_autopm_put_interface(chip->pm_intf);
680} 682}
diff --git a/sound/usb/midi.c b/sound/usb/midi.c
index 5b4c58c3e2c5..cc39f63299ef 100644
--- a/sound/usb/midi.c
+++ b/sound/usb/midi.c
@@ -112,7 +112,7 @@ struct snd_usb_midi {
112 struct usb_interface *iface; 112 struct usb_interface *iface;
113 const struct snd_usb_audio_quirk *quirk; 113 const struct snd_usb_audio_quirk *quirk;
114 struct snd_rawmidi *rmidi; 114 struct snd_rawmidi *rmidi;
115 struct usb_protocol_ops *usb_protocol_ops; 115 const struct usb_protocol_ops *usb_protocol_ops;
116 struct list_head list; 116 struct list_head list;
117 struct timer_list error_timer; 117 struct timer_list error_timer;
118 spinlock_t disc_lock; 118 spinlock_t disc_lock;
@@ -671,31 +671,32 @@ static void snd_usbmidi_standard_output(struct snd_usb_midi_out_endpoint *ep,
671 } 671 }
672} 672}
673 673
674static struct usb_protocol_ops snd_usbmidi_standard_ops = { 674static const struct usb_protocol_ops snd_usbmidi_standard_ops = {
675 .input = snd_usbmidi_standard_input, 675 .input = snd_usbmidi_standard_input,
676 .output = snd_usbmidi_standard_output, 676 .output = snd_usbmidi_standard_output,
677 .output_packet = snd_usbmidi_output_standard_packet, 677 .output_packet = snd_usbmidi_output_standard_packet,
678}; 678};
679 679
680static struct usb_protocol_ops snd_usbmidi_midiman_ops = { 680static const struct usb_protocol_ops snd_usbmidi_midiman_ops = {
681 .input = snd_usbmidi_midiman_input, 681 .input = snd_usbmidi_midiman_input,
682 .output = snd_usbmidi_standard_output, 682 .output = snd_usbmidi_standard_output,
683 .output_packet = snd_usbmidi_output_midiman_packet, 683 .output_packet = snd_usbmidi_output_midiman_packet,
684}; 684};
685 685
686static struct usb_protocol_ops snd_usbmidi_maudio_broken_running_status_ops = { 686static const
687struct usb_protocol_ops snd_usbmidi_maudio_broken_running_status_ops = {
687 .input = snd_usbmidi_maudio_broken_running_status_input, 688 .input = snd_usbmidi_maudio_broken_running_status_input,
688 .output = snd_usbmidi_standard_output, 689 .output = snd_usbmidi_standard_output,
689 .output_packet = snd_usbmidi_output_standard_packet, 690 .output_packet = snd_usbmidi_output_standard_packet,
690}; 691};
691 692
692static struct usb_protocol_ops snd_usbmidi_cme_ops = { 693static const struct usb_protocol_ops snd_usbmidi_cme_ops = {
693 .input = snd_usbmidi_cme_input, 694 .input = snd_usbmidi_cme_input,
694 .output = snd_usbmidi_standard_output, 695 .output = snd_usbmidi_standard_output,
695 .output_packet = snd_usbmidi_output_standard_packet, 696 .output_packet = snd_usbmidi_output_standard_packet,
696}; 697};
697 698
698static struct usb_protocol_ops snd_usbmidi_ch345_broken_sysex_ops = { 699static const struct usb_protocol_ops snd_usbmidi_ch345_broken_sysex_ops = {
699 .input = ch345_broken_sysex_input, 700 .input = ch345_broken_sysex_input,
700 .output = snd_usbmidi_standard_output, 701 .output = snd_usbmidi_standard_output,
701 .output_packet = snd_usbmidi_output_standard_packet, 702 .output_packet = snd_usbmidi_output_standard_packet,
@@ -795,7 +796,7 @@ static void snd_usbmidi_akai_output(struct snd_usb_midi_out_endpoint *ep,
795 } 796 }
796} 797}
797 798
798static struct usb_protocol_ops snd_usbmidi_akai_ops = { 799static const struct usb_protocol_ops snd_usbmidi_akai_ops = {
799 .input = snd_usbmidi_akai_input, 800 .input = snd_usbmidi_akai_input,
800 .output = snd_usbmidi_akai_output, 801 .output = snd_usbmidi_akai_output,
801}; 802};
@@ -835,7 +836,7 @@ static void snd_usbmidi_novation_output(struct snd_usb_midi_out_endpoint *ep,
835 urb->transfer_buffer_length = 2 + count; 836 urb->transfer_buffer_length = 2 + count;
836} 837}
837 838
838static struct usb_protocol_ops snd_usbmidi_novation_ops = { 839static const struct usb_protocol_ops snd_usbmidi_novation_ops = {
839 .input = snd_usbmidi_novation_input, 840 .input = snd_usbmidi_novation_input,
840 .output = snd_usbmidi_novation_output, 841 .output = snd_usbmidi_novation_output,
841}; 842};
@@ -867,7 +868,7 @@ static void snd_usbmidi_raw_output(struct snd_usb_midi_out_endpoint *ep,
867 urb->transfer_buffer_length = count; 868 urb->transfer_buffer_length = count;
868} 869}
869 870
870static struct usb_protocol_ops snd_usbmidi_raw_ops = { 871static const struct usb_protocol_ops snd_usbmidi_raw_ops = {
871 .input = snd_usbmidi_raw_input, 872 .input = snd_usbmidi_raw_input,
872 .output = snd_usbmidi_raw_output, 873 .output = snd_usbmidi_raw_output,
873}; 874};
@@ -883,7 +884,7 @@ static void snd_usbmidi_ftdi_input(struct snd_usb_midi_in_endpoint *ep,
883 snd_usbmidi_input_data(ep, 0, buffer + 2, buffer_length - 2); 884 snd_usbmidi_input_data(ep, 0, buffer + 2, buffer_length - 2);
884} 885}
885 886
886static struct usb_protocol_ops snd_usbmidi_ftdi_ops = { 887static const struct usb_protocol_ops snd_usbmidi_ftdi_ops = {
887 .input = snd_usbmidi_ftdi_input, 888 .input = snd_usbmidi_ftdi_input,
888 .output = snd_usbmidi_raw_output, 889 .output = snd_usbmidi_raw_output,
889}; 890};
@@ -927,7 +928,7 @@ static void snd_usbmidi_us122l_output(struct snd_usb_midi_out_endpoint *ep,
927 urb->transfer_buffer_length = ep->max_transfer; 928 urb->transfer_buffer_length = ep->max_transfer;
928} 929}
929 930
930static struct usb_protocol_ops snd_usbmidi_122l_ops = { 931static const struct usb_protocol_ops snd_usbmidi_122l_ops = {
931 .input = snd_usbmidi_us122l_input, 932 .input = snd_usbmidi_us122l_input,
932 .output = snd_usbmidi_us122l_output, 933 .output = snd_usbmidi_us122l_output,
933}; 934};
@@ -1060,7 +1061,7 @@ static void snd_usbmidi_emagic_output(struct snd_usb_midi_out_endpoint *ep,
1060 urb->transfer_buffer_length = ep->max_transfer - buf_free; 1061 urb->transfer_buffer_length = ep->max_transfer - buf_free;
1061} 1062}
1062 1063
1063static struct usb_protocol_ops snd_usbmidi_emagic_ops = { 1064static const struct usb_protocol_ops snd_usbmidi_emagic_ops = {
1064 .input = snd_usbmidi_emagic_input, 1065 .input = snd_usbmidi_emagic_input,
1065 .output = snd_usbmidi_emagic_output, 1066 .output = snd_usbmidi_emagic_output,
1066 .init_out_endpoint = snd_usbmidi_emagic_init_out, 1067 .init_out_endpoint = snd_usbmidi_emagic_init_out,
@@ -2206,7 +2207,7 @@ static int snd_usbmidi_create_endpoints_midiman(struct snd_usb_midi *umidi,
2206 return 0; 2207 return 0;
2207} 2208}
2208 2209
2209static struct snd_rawmidi_global_ops snd_usbmidi_ops = { 2210static const struct snd_rawmidi_global_ops snd_usbmidi_ops = {
2210 .get_port_info = snd_usbmidi_get_port_info, 2211 .get_port_info = snd_usbmidi_get_port_info,
2211}; 2212};
2212 2213
diff --git a/sound/usb/misc/ua101.c b/sound/usb/misc/ua101.c
index 9581089c28c5..c19a5dd05631 100644
--- a/sound/usb/misc/ua101.c
+++ b/sound/usb/misc/ua101.c
@@ -1037,7 +1037,7 @@ static int detect_usb_format(struct ua101 *ua)
1037 return -ENXIO; 1037 return -ENXIO;
1038 } 1038 }
1039 ua->capture.usb_pipe = usb_rcvisocpipe(ua->dev, usb_endpoint_num(epd)); 1039 ua->capture.usb_pipe = usb_rcvisocpipe(ua->dev, usb_endpoint_num(epd));
1040 ua->capture.max_packet_bytes = le16_to_cpu(epd->wMaxPacketSize); 1040 ua->capture.max_packet_bytes = usb_endpoint_maxp(epd);
1041 1041
1042 epd = &ua->intf[INTF_PLAYBACK]->altsetting[1].endpoint[0].desc; 1042 epd = &ua->intf[INTF_PLAYBACK]->altsetting[1].endpoint[0].desc;
1043 if (!usb_endpoint_is_isoc_out(epd)) { 1043 if (!usb_endpoint_is_isoc_out(epd)) {
@@ -1045,7 +1045,7 @@ static int detect_usb_format(struct ua101 *ua)
1045 return -ENXIO; 1045 return -ENXIO;
1046 } 1046 }
1047 ua->playback.usb_pipe = usb_sndisocpipe(ua->dev, usb_endpoint_num(epd)); 1047 ua->playback.usb_pipe = usb_sndisocpipe(ua->dev, usb_endpoint_num(epd));
1048 ua->playback.max_packet_bytes = le16_to_cpu(epd->wMaxPacketSize); 1048 ua->playback.max_packet_bytes = usb_endpoint_maxp(epd);
1049 return 0; 1049 return 0;
1050} 1050}
1051 1051
diff --git a/sound/usb/mixer_quirks.c b/sound/usb/mixer_quirks.c
index 0ce888dceed0..279025650568 100644
--- a/sound/usb/mixer_quirks.c
+++ b/sound/usb/mixer_quirks.c
@@ -793,7 +793,7 @@ static int snd_nativeinstruments_control_put(struct snd_kcontrol *kcontrol,
793 return 0; 793 return 0;
794 794
795 kcontrol->private_value &= ~(0xff << 24); 795 kcontrol->private_value &= ~(0xff << 24);
796 kcontrol->private_value |= newval; 796 kcontrol->private_value |= (unsigned int)newval << 24;
797 err = snd_ni_update_cur_val(list); 797 err = snd_ni_update_cur_val(list);
798 return err < 0 ? err : 1; 798 return err < 0 ? err : 1;
799} 799}
diff --git a/sound/usb/quirks.c b/sound/usb/quirks.c
index b6c0c8e3b450..23ea6d800c4c 100644
--- a/sound/usb/quirks.c
+++ b/sound/usb/quirks.c
@@ -1269,6 +1269,7 @@ u64 snd_usb_interface_dsd_format_quirks(struct snd_usb_audio *chip,
1269 case USB_ID(0x20b1, 0x3008): /* iFi Audio micro/nano iDSD */ 1269 case USB_ID(0x20b1, 0x3008): /* iFi Audio micro/nano iDSD */
1270 case USB_ID(0x20b1, 0x2008): /* Matrix Audio X-Sabre */ 1270 case USB_ID(0x20b1, 0x2008): /* Matrix Audio X-Sabre */
1271 case USB_ID(0x20b1, 0x300a): /* Matrix Audio Mini-i Pro */ 1271 case USB_ID(0x20b1, 0x300a): /* Matrix Audio Mini-i Pro */
1272 case USB_ID(0x22d8, 0x0416): /* OPPO HA-1*/
1272 if (fp->altsetting == 2) 1273 if (fp->altsetting == 2)
1273 return SNDRV_PCM_FMTBIT_DSD_U32_BE; 1274 return SNDRV_PCM_FMTBIT_DSD_U32_BE;
1274 break; 1275 break;
diff --git a/sound/usb/stream.c b/sound/usb/stream.c
index 8ee14f2365e7..c4dc577ab1bd 100644
--- a/sound/usb/stream.c
+++ b/sound/usb/stream.c
@@ -125,11 +125,9 @@ static int usb_chmap_ctl_info(struct snd_kcontrol *kcontrol,
125static bool have_dup_chmap(struct snd_usb_substream *subs, 125static bool have_dup_chmap(struct snd_usb_substream *subs,
126 struct audioformat *fp) 126 struct audioformat *fp)
127{ 127{
128 struct list_head *p; 128 struct audioformat *prev = fp;
129 129
130 for (p = fp->list.prev; p != &subs->fmt_list; p = p->prev) { 130 list_for_each_entry_continue_reverse(prev, &subs->fmt_list, list) {
131 struct audioformat *prev;
132 prev = list_entry(p, struct audioformat, list);
133 if (prev->chmap && 131 if (prev->chmap &&
134 !memcmp(prev->chmap, fp->chmap, sizeof(*fp->chmap))) 132 !memcmp(prev->chmap, fp->chmap, sizeof(*fp->chmap)))
135 return true; 133 return true;
diff --git a/sound/usb/usx2y/usbusx2yaudio.c b/sound/usb/usx2y/usbusx2yaudio.c
index 61d5dc2a3421..dd40ca9d858a 100644
--- a/sound/usb/usx2y/usbusx2yaudio.c
+++ b/sound/usb/usx2y/usbusx2yaudio.c
@@ -166,7 +166,7 @@ static int usX2Y_urb_play_prepare(struct snd_usX2Y_substream *subs,
166 /* set the buffer pointer */ 166 /* set the buffer pointer */
167 urb->transfer_buffer = runtime->dma_area + subs->hwptr * usX2Y->stride; 167 urb->transfer_buffer = runtime->dma_area + subs->hwptr * usX2Y->stride;
168 if ((subs->hwptr += count) >= runtime->buffer_size) 168 if ((subs->hwptr += count) >= runtime->buffer_size)
169 subs->hwptr -= runtime->buffer_size; 169 subs->hwptr -= runtime->buffer_size;
170 } 170 }
171 else 171 else
172 urb->transfer_buffer = subs->tmpbuf; 172 urb->transfer_buffer = subs->tmpbuf;